Remove SQL versions repo (#6242)

close #6232

Changelog:
- remove: `SqlVersionsRepo`
- update: `SuggestionsDatabaseModuleUpdateNotification` message removing the version
- update: cleanup versions repo usages in the language server
This commit is contained in:
Dmitry Bushev 2023-04-11 22:22:30 +03:00 committed by GitHub
parent fe1798c9e3
commit b97fc39214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 60 additions and 701 deletions

View File

@ -85,15 +85,6 @@ is updated on every change in the suggestions table.
| ------ | --------- | --------------------------------------------------------------- |
| `id` | `INTEGER` | the unique identifier representing the currend database version |
#### File Versions Table
Keeps track of SHA versions of the opened files.
| Column | Type | Description |
| -------- | ------ | --------------------------------- |
| `path` | `TEXT` | the unique identifier of the file |
| `digest` | `BLOB` | the SHA hash of the file contents |
#### Schema Version Table
Schema version table has a single row with the current database schema version.
@ -195,7 +186,7 @@ The searcher primarily consists of:
+--------------------------------+
| SuggestionsDB |
+-----------------+--------------+
| SuggestionsRepo | VersionsRepo |
| SuggestionsRepo |
+----+------------+---------+----+
^ ^
| |

View File

@ -45,7 +45,7 @@ import org.enso.lockmanager.server.LockManagerService
import org.enso.logger.masking.{MaskedPath, Masking}
import org.enso.loggingservice.{JavaLoggingLogHandler, LogLevel}
import org.enso.polyglot.{HostAccessFactory, RuntimeOptions, RuntimeServerInfo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo}
import org.enso.text.{ContentBasedVersioning, Sha3_224VersionCalculator}
import org.graalvm.polyglot.Context
import org.graalvm.polyglot.io.MessageEndpoint
@ -126,8 +126,7 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
val sqlDatabase = SqlDatabase.inmem("memdb")
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)(system.dispatcher)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)(system.dispatcher)
log.trace("Created SQL repos: [{}. {}].", suggestionsRepo, versionsRepo)
log.trace("Created SQL suggestions repo: [{}].", suggestionsRepo)
val idlenessMonitor =
system.actorOf(IdlenessMonitor.props(utcClock))
@ -244,7 +243,6 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
languageServerConfig,
contentRootManagerWrapper,
suggestionsRepo,
versionsRepo,
sessionRouter,
runtimeConnector
),
@ -402,7 +400,6 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
jsonRpcProtocolFactory,
sqlDatabase,
suggestionsRepo,
versionsRepo,
context,
zioRuntime
)(system.dispatcher)
@ -460,7 +457,6 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
/** Close the main module releasing all resources. */
def close(): Unit = {
suggestionsRepo.close()
versionsRepo.close()
context.close()
log.info("Closed Language Server main module.")
}

View File

@ -13,7 +13,7 @@ import org.enso.languageserver.boot.resource.{
}
import org.enso.languageserver.data.ProjectDirectoriesConfig
import org.enso.languageserver.effect
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo}
import org.graalvm.polyglot.Context
import scala.concurrent.ExecutionContext
@ -30,7 +30,6 @@ object ResourcesInitialization {
* @param protocolFactory the JSON-RPC protocol factory
* @param suggestionsRepo the suggestions repo
* @param sqlDatabase the sql database
* @param versionsRepo the file versions repo
* @param truffleContext the runtime context
* @param runtime the runtime to run effects
* @return the initialization component
@ -41,7 +40,6 @@ object ResourcesInitialization {
protocolFactory: ProtocolFactory,
sqlDatabase: SqlDatabase,
suggestionsRepo: SqlSuggestionsRepo,
versionsRepo: SqlVersionsRepo,
truffleContext: Context,
runtime: effect.Runtime
)(implicit ec: ExecutionContext): InitializationComponent = {
@ -53,8 +51,7 @@ object ResourcesInitialization {
directoriesConfig,
eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
),
new TruffleContextInitialization(eventStream, truffleContext)
)

View File

@ -9,7 +9,7 @@ import org.apache.commons.io.FileUtils
import org.enso.languageserver.data.ProjectDirectoriesConfig
import org.enso.languageserver.event.InitializedEvent
import org.enso.logger.masking.MaskedPath
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal
@ -21,14 +21,12 @@ import scala.util.{Failure, Success}
* @param eventStream akka events stream
* @param sqlDatabase the sql database
* @param suggestionsRepo the suggestions repo
* @param versionsRepo the versions repo
*/
class RepoInitialization(
directoriesConfig: ProjectDirectoriesConfig,
eventStream: EventStream,
sqlDatabase: SqlDatabase,
suggestionsRepo: SqlSuggestionsRepo,
versionsRepo: SqlVersionsRepo
suggestionsRepo: SqlSuggestionsRepo
)(implicit ec: ExecutionContext)
extends InitializationComponent
with LazyLogging {
@ -38,7 +36,6 @@ class RepoInitialization(
for {
_ <- sqlDatabaseInit
_ <- suggestionsRepoInit
_ <- versionsRepoInit
} yield InitializationComponent.Initialized
private def sqlDatabaseInit: Future[Unit] = {
@ -87,36 +84,6 @@ class RepoInitialization(
initAction
}
private def versionsRepoInit: Future[Unit] = {
val initAction =
for {
_ <- Future {
logger.info(
"Initializing versions repo [{}]...",
MaskedPath(directoriesConfig.suggestionsDatabaseFile.toPath)
)
}
_ <- versionsRepo.init
_ <- Future {
logger.info(
"Initialized Versions repo [{}].",
MaskedPath(directoriesConfig.suggestionsDatabaseFile.toPath)
)
}
} yield ()
initAction.onComplete {
case Success(()) =>
eventStream.publish(InitializedEvent.VersionsRepoInitialized)
case Failure(ex) =>
logger.error(
"Failed to initialize SQL versions repo [{}].",
MaskedPath(directoriesConfig.suggestionsDatabaseFile.toPath),
ex
)
}
initAction
}
private def recoverInitError(
error: Throwable,
db: SqlDatabase

View File

@ -6,7 +6,6 @@ sealed trait InitializedEvent extends Event
object InitializedEvent {
case object SuggestionsRepoInitialized extends InitializedEvent
case object VersionsRepoInitialized extends InitializedEvent
case object TruffleContextInitialized extends InitializedEvent
case object InitializationFinished extends InitializedEvent
case object InitializationFailed extends InitializedEvent

View File

@ -34,7 +34,7 @@ import org.enso.polyglot.Suggestion
import org.enso.polyglot.data.TypeGraph
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.searcher.data.QueryResult
import org.enso.searcher.{SuggestionsRepo, VersionsRepo}
import org.enso.searcher.SuggestionsRepo
import org.enso.text.editing.model.Position
import scala.collection.mutable
@ -76,7 +76,6 @@ import scala.util.{Failure, Success}
* @param config the server configuration
* @param contentRootManager the content root manager
* @param suggestionsRepo the suggestions repo
* @param versionsRepo the versions repo
* @param sessionRouter the session router
* @param runtimeConnector the runtime connector
*/
@ -84,7 +83,6 @@ final class SuggestionsHandler(
config: Config,
contentRootManager: ContentRootManager,
suggestionsRepo: SuggestionsRepo[Future],
versionsRepo: VersionsRepo[Future],
sessionRouter: ActorRef,
runtimeConnector: ActorRef
) extends Actor
@ -98,10 +96,9 @@ final class SuggestionsHandler(
override def preStart(): Unit = {
logger.info(
"Starting suggestions handler from [{}, {}, {}].",
"Starting suggestions handler from [{}, {}].",
config,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
context.system.eventStream
.subscribe(self, classOf[Api.ExpressionUpdates])
@ -286,9 +283,8 @@ final class SuggestionsHandler(
self ! SuggestionsHandler.SuggestionUpdatesCompleted
case Failure(ex) =>
logger.error(
"Error applying suggestion database updates [{}, {}].",
"Error applying suggestion database updates [{}].",
msg.module,
msg.version,
ex
)
self ! SuggestionsHandler.SuggestionUpdatesCompleted
@ -418,7 +414,6 @@ final class SuggestionsHandler(
case InvalidateSuggestionsDatabase =>
val action = for {
_ <- suggestionsRepo.clean
_ <- versionsRepo.clean
} yield SearchProtocol.InvalidateModulesIndex
val runtimeFailureMapper = RuntimeFailureMapper(contentRootManager)
@ -520,7 +515,6 @@ final class SuggestionsHandler(
treeResults <- suggestionsRepo.applyTree(msg.updates.toVector)
exportResults <- suggestionsRepo.applyExports(msg.exports)
version <- suggestionsRepo.currentVersion
_ <- versionsRepo.setVersion(msg.module, msg.version.toDigest)
} yield {
val actionUpdates = actionResults.flatMap {
case QueryResult(ids, Api.SuggestionsDatabaseAction.Clean(_)) =>
@ -758,7 +752,6 @@ object SuggestionsHandler {
* @param config the server configuration
* @param contentRootManager the content root manager
* @param suggestionsRepo the suggestions repo
* @param versionsRepo the versions repo
* @param sessionRouter the session router
* @param runtimeConnector the runtime connector
*/
@ -766,7 +759,6 @@ object SuggestionsHandler {
config: Config,
contentRootManager: ContentRootManager,
suggestionsRepo: SuggestionsRepo[Future],
versionsRepo: VersionsRepo[Future],
sessionRouter: ActorRef,
runtimeConnector: ActorRef
): Props =
@ -775,7 +767,6 @@ object SuggestionsHandler {
config,
contentRootManager,
suggestionsRepo,
versionsRepo,
sessionRouter,
runtimeConnector
)

View File

@ -10,7 +10,6 @@ import org.enso.languageserver.capability.CapabilityProtocol.{
ReleaseCapability
}
import org.enso.languageserver.data.{CanEdit, CapabilityRegistration, ClientId}
import org.enso.languageserver.event.InitializedEvent
import org.enso.languageserver.filemanager.Path
import org.enso.languageserver.monitoring.MonitoringProtocol.{Ping, Pong}
import org.enso.languageserver.session.JsonSession
@ -99,23 +98,7 @@ class BufferRegistry(
import context.dispatcher
override def preStart(): Unit = {
logger.info("Starting initialization.")
context.system.eventStream
.subscribe(self, InitializedEvent.VersionsRepoInitialized.getClass)
}
override def receive: Receive = initializing
private def initializing: Receive = {
case InitializedEvent.VersionsRepoInitialized =>
logger.info("Initiaized.")
context.become(running(Map.empty))
unstashAll()
case _ =>
stash()
}
override def receive: Receive = running(Map.empty)
private def running(registry: Map[Path, ActorRef]): Receive = {
case Ping =>

View File

@ -7,12 +7,7 @@ import org.enso.languageserver.boot.{ProfilingConfig, StartupConfig}
import org.enso.languageserver.data._
import org.enso.languageserver.event.InitializedEvent
import org.enso.languageserver.filemanager.{ContentRoot, ContentRootWithFile}
import org.enso.searcher.sql.{
SchemaVersion,
SqlDatabase,
SqlSuggestionsRepo,
SqlVersionsRepo
}
import org.enso.searcher.sql.{SchemaVersion, SqlDatabase, SqlSuggestionsRepo}
import org.enso.testkit.FlakySpec
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
@ -43,7 +38,7 @@ class RepoInitializationSpec
"RepoInitialization" should {
"initialize repositories" in withDb {
(config, sqlDatabase, suggestionsRepo, versionsRepo) =>
(config, sqlDatabase, suggestionsRepo) =>
system.eventStream.subscribe(self, classOf[InitializedEvent])
val component =
@ -51,8 +46,7 @@ class RepoInitializationSpec
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
val action =
@ -64,14 +58,11 @@ class RepoInitializationSpec
val version = Await.result(action, Timeout)
version shouldEqual SchemaVersion.CurrentVersion
expectMsgAllOf(
InitializedEvent.SuggestionsRepoInitialized,
InitializedEvent.VersionsRepoInitialized
)
expectMsg(InitializedEvent.SuggestionsRepoInitialized)
}
"recreate suggestion database when schema version is incorrect" in withDb {
(config, sqlDatabase, suggestionsRepo, versionsRepo) =>
(config, sqlDatabase, suggestionsRepo) =>
system.eventStream.subscribe(self, classOf[InitializedEvent])
val testSchemaVersion = Long.MaxValue
@ -80,8 +71,7 @@ class RepoInitializationSpec
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
sqlDatabase.open()
@ -97,14 +87,11 @@ class RepoInitializationSpec
val version = Await.result(action, Timeout)
version shouldEqual SchemaVersion.CurrentVersion
expectMsgAllOf(
InitializedEvent.SuggestionsRepoInitialized,
InitializedEvent.VersionsRepoInitialized
)
expectMsg(InitializedEvent.SuggestionsRepoInitialized)
}
"recreate suggestion database when schema version is empty" in withDb {
(config, sqlDatabase, suggestionsRepo, versionsRepo) =>
(config, sqlDatabase, suggestionsRepo) =>
system.eventStream.subscribe(self, classOf[InitializedEvent])
val component =
@ -112,8 +99,7 @@ class RepoInitializationSpec
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
// initialize
@ -125,10 +111,7 @@ class RepoInitializationSpec
val version1 = Await.result(init, Timeout)
version1 shouldEqual SchemaVersion.CurrentVersion
expectMsgAllOf(
InitializedEvent.SuggestionsRepoInitialized,
InitializedEvent.VersionsRepoInitialized
)
expectMsg(InitializedEvent.SuggestionsRepoInitialized)
// remove schema and re-initialize
val action =
@ -140,23 +123,19 @@ class RepoInitializationSpec
val version2 = Await.result(action, Timeout)
version2 shouldEqual SchemaVersion.CurrentVersion
expectMsgAllOf(
InitializedEvent.SuggestionsRepoInitialized,
InitializedEvent.VersionsRepoInitialized
)
expectMsg(InitializedEvent.SuggestionsRepoInitialized)
}
"recreate corrupted suggestion database file" taggedAs Flaky in withConfig {
config =>
// initialize
withRepos(config) { (sqlDatabase, suggestionsRepo, versionsRepo) =>
withRepos(config) { (sqlDatabase, suggestionsRepo) =>
val component =
new RepoInitialization(
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
val init =
@ -177,7 +156,7 @@ class RepoInitializationSpec
bytes,
StandardOpenOption.CREATE
)
withRepos(config) { (sqlDatabase, suggestionsRepo, _) =>
withRepos(config) { (sqlDatabase, suggestionsRepo) =>
sqlDatabase.open()
an[SQLiteException] should be thrownBy Await.result(
suggestionsRepo.getSchemaVersion,
@ -186,14 +165,13 @@ class RepoInitializationSpec
}
// re-initialize
withRepos(config) { (sqlDatabase, suggestionsRepo, versionsRepo) =>
withRepos(config) { (sqlDatabase, suggestionsRepo) =>
val component =
new RepoInitialization(
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
val action =
@ -204,10 +182,7 @@ class RepoInitializationSpec
val version2 = Await.result(action, Timeout)
version2 shouldEqual SchemaVersion.CurrentVersion
expectMsgAllOf(
InitializedEvent.SuggestionsRepoInitialized,
InitializedEvent.VersionsRepoInitialized
)
expectMsg(InitializedEvent.SuggestionsRepoInitialized)
}
}
@ -241,12 +216,11 @@ class RepoInitializationSpec
def withRepos(
config: Config
)(test: (SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo) => Any): Unit = {
)(test: (SqlDatabase, SqlSuggestionsRepo) => Any): Unit = {
val sqlDatabase = SqlDatabase(config.directories.suggestionsDatabaseFile)
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)
try test(sqlDatabase, suggestionsRepo, versionsRepo)
try test(sqlDatabase, suggestionsRepo)
finally {
sqlDatabase.close()
}
@ -256,13 +230,12 @@ class RepoInitializationSpec
test: (
Config,
SqlDatabase,
SqlSuggestionsRepo,
SqlVersionsRepo
SqlSuggestionsRepo
) => Any
): Unit = {
withConfig { config =>
withRepos(config) { (sqlDatabase, suggestionsRepo, versionsRepo) =>
test(config, sqlDatabase, suggestionsRepo, versionsRepo)
withRepos(config) { (sqlDatabase, suggestionsRepo) =>
test(config, sqlDatabase, suggestionsRepo)
}
}
}

View File

@ -16,11 +16,10 @@ import org.enso.languageserver.session.SessionRouter.DeliverToJsonController
import org.enso.polyglot.data.{Tree, TypeGraph}
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.polyglot.{ExportedSymbol, ModuleExports, Suggestion}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.{SuggestionsRepo, VersionsRepo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo}
import org.enso.searcher.SuggestionsRepo
import org.enso.testkit.RetrySpec
import org.enso.text.editing.model.Position
import org.enso.text.{ContentVersion, Sha3_224VersionCalculator}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
@ -45,9 +44,6 @@ class SuggestionsHandlerSpec
val Timeout: FiniteDuration = 10.seconds
def contentsVersion(text: String): ContentVersion =
Sha3_224VersionCalculator.evalVersion(text)
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
@ -79,7 +75,6 @@ class SuggestionsHandlerSpec
// receive updates
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
Tree.Root(Suggestions.all.toVector.map { suggestion =>
@ -125,7 +120,6 @@ class SuggestionsHandlerSpec
// receive updates
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
Tree.Root(
@ -227,7 +221,6 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
tree1
@ -302,7 +295,6 @@ class SuggestionsHandlerSpec
// update tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion("1"),
Vector(),
Vector(),
tree2
@ -394,7 +386,6 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
tree
@ -473,7 +464,6 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
tree1
@ -498,7 +488,6 @@ class SuggestionsHandlerSpec
// clean module
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion("1"),
Vector(
Api.SuggestionsDatabaseAction.Clean(Suggestions.constructor.module)
),
@ -580,7 +569,6 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion(""),
Vector(),
Vector(),
tree1
@ -625,7 +613,6 @@ class SuggestionsHandlerSpec
// apply updates1
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion("1"),
Vector(),
Vector(exportUpdateAdd),
Tree.Root(Vector())
@ -670,7 +657,6 @@ class SuggestionsHandlerSpec
// apply updates2
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
contentsVersion("2"),
Vector(),
Vector(exportUpdateRemove),
Tree.Root(Vector())
@ -923,8 +909,7 @@ class SuggestionsHandlerSpec
config: Config,
sessionRouter: TestProbe,
runtimeConnector: TestProbe,
suggestionsRepo: SuggestionsRepo[Future],
versionsRepo: VersionsRepo[Future]
suggestionsRepo: SuggestionsRepo[Future]
): ActorRef = {
val contentRootManagerActor =
system.actorOf(ContentRootManagerActor.props(config))
@ -935,7 +920,6 @@ class SuggestionsHandlerSpec
config,
contentRootManagerWrapper,
suggestionsRepo,
versionsRepo,
sessionRouter.ref,
runtimeConnector.ref
)
@ -946,16 +930,14 @@ class SuggestionsHandlerSpec
config: Config,
sessionRouter: TestProbe,
runtimeConnector: TestProbe,
suggestionsRepo: SuggestionsRepo[Future],
versionsRepo: VersionsRepo[Future]
suggestionsRepo: SuggestionsRepo[Future]
): ActorRef = {
val handler =
newSuggestionsHandler(
config,
sessionRouter,
runtimeConnector,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
handler ! SuggestionsHandler.ProjectNameUpdated("Test")
@ -968,22 +950,14 @@ class SuggestionsHandlerSpec
)
val suggestionsInit = suggestionsRepo.init
val versionsInit = versionsRepo.init
suggestionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.SuggestionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize Suggestions repo")
}
versionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.VersionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize FileVersions repo")
}
Await.ready(suggestionsInit, Timeout)
Await.ready(versionsInit, Timeout)
handler
}
@ -1017,7 +991,7 @@ class SuggestionsHandlerSpec
JsonSession(clientId, TestProbe().ref)
def withDbs(
test: (Config, SuggestionsRepo[Future], VersionsRepo[Future]) => Any
test: (Config, SuggestionsRepo[Future]) => Any
): Unit = {
val testContentRoot = Files.createTempDirectory(null).toRealPath()
sys.addShutdownHook(FileUtils.deleteQuietly(testContentRoot.toFile))
@ -1029,29 +1003,19 @@ class SuggestionsHandlerSpec
)
val sqlDatabase = SqlDatabase(config.directories.suggestionsDatabaseFile)
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)
val suggestionsInit = suggestionsRepo.init
val versionsInit = versionsRepo.init
suggestionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.SuggestionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize Suggestions repo")
}
versionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.VersionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize FileVersions repo")
}
Await.ready(suggestionsInit, Timeout)
Await.ready(versionsInit, Timeout)
try test(config, suggestionsRepo, versionsRepo)
try test(config, suggestionsRepo)
finally {
versionsRepo.close()
suggestionsRepo.close()
}
}
@ -1078,13 +1042,11 @@ class SuggestionsHandlerSpec
val sqlDatabase = SqlDatabase.inmem("testdb")
sqlDatabase.open()
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)
val handler = newInitializedSuggestionsHandler(
config,
router,
connector,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
try test(config, suggestionsRepo, router, connector, handler)

View File

@ -51,7 +51,7 @@ import org.enso.runtimeversionmanager.test.{
FakeEnvironment,
TestableThreadSafeFileLockManager
}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo}
import org.enso.testkit.{EitherValue, WithTemporaryDirectory}
import org.enso.text.Sha3_224VersionCalculator
import org.scalatest.OptionValues
@ -135,7 +135,6 @@ class BaseServerTest
val zioExec = ZioExec(new TestRuntime)
val sqlDatabase = SqlDatabase(config.directories.suggestionsDatabaseFile)
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)(system.dispatcher)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)(system.dispatcher)
val initializationComponent = SequentialResourcesInitialization(
new DirectoriesInitialization(config.directories),
@ -143,8 +142,7 @@ class BaseServerTest
config.directories,
system.eventStream,
sqlDatabase,
suggestionsRepo,
versionsRepo
suggestionsRepo
)
)
@ -230,7 +228,6 @@ class BaseServerTest
config,
contentRootManagerWrapper,
suggestionsRepo,
versionsRepo,
sessionRouter,
runtimeConnectorProbe.ref
),

View File

@ -24,7 +24,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("1"),
Vector(),
Vector(),
Tree.Root(
@ -75,7 +74,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("2"),
Vector(),
Vector(),
Tree.Root(
@ -127,7 +125,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("3"),
Vector(),
Vector(),
Tree.Root(
@ -198,7 +195,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("4"),
Vector(),
Vector(),
Tree.Root(
@ -293,7 +289,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("5"),
Vector(),
Vector(),
Tree.Root(
@ -380,7 +375,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("6"),
Vector(),
Vector(),
Tree.Root(
@ -500,7 +494,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("7"),
Vector(),
Vector(
Api.ExportsUpdate(
@ -544,7 +537,6 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
"Foo.Main",
versionCalculator.evalVersion("8"),
Vector(
Api.SuggestionsDatabaseAction.Clean(Suggestions.constructor.module)
),

View File

@ -12,7 +12,6 @@ import org.enso.logger.masking.{MaskedPath, MaskedString, ToLogString}
import org.enso.pkg.{ComponentGroups, QualifiedName}
import org.enso.polyglot.{ModuleExports, Suggestion}
import org.enso.polyglot.data.{Tree, TypeGraph}
import org.enso.text.ContentVersion
import org.enso.text.editing.model
import org.enso.text.editing.model.{Range, TextEdit}
@ -1545,14 +1544,12 @@ object Runtime {
/** A notification about the changes in the suggestions database.
*
* @param module the module name
* @param version the version of the module
* @param actions the list of actions to apply to the suggestions database
* @param exports the list of re-exported symbols
* @param updates the list of suggestions extracted from module
*/
final case class SuggestionsDatabaseModuleUpdateNotification(
module: String,
version: ContentVersion,
actions: Vector[SuggestionsDatabaseAction],
exports: Vector[ExportsUpdate],
updates: Tree[SuggestionUpdate]
@ -1563,7 +1560,6 @@ object Runtime {
override def toLogString(shouldMask: Boolean): String =
"SuggestionsDatabaseModuleUpdateNotification(" +
s"module=$module," +
s"version=$version," +
s"actions=$actions," +
s"exports=$exports" +
s"updates=${updates.map(_.toLogString(shouldMask))}" +

View File

@ -252,7 +252,6 @@ class RuntimeStdlibTest
None,
Api.SuggestionsDatabaseModuleUpdateNotification(
module,
_,
actions,
_,
updates

View File

@ -9,7 +9,6 @@ import org.enso.polyglot.data.Tree
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.text.editing.model
import org.enso.text.editing.model.TextEdit
import org.enso.text.{ContentVersion, Sha3_224VersionCalculator}
import org.graalvm.polyglot.Context
import org.scalatest.BeforeAndAfterEach
import org.scalatest.flatspec.AnyFlatSpec
@ -90,9 +89,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(Api.ExecutionComplete(contextId))
}
def contentsVersion(content: String): ContentVersion =
Sha3_224VersionCalculator.evalVersion(content)
override protected def beforeEach(): Unit = {
context = new TestContext("Test")
val Some(Api.Response(_, Api.InitializedNotification())) = context.receive
@ -108,7 +104,6 @@ class RuntimeSuggestionUpdatesTest
|
|main = IO.println "Hello World!"
|""".stripMargin.linesIterator.mkString("\n")
val version = contentsVersion(code)
val mainFile = context.writeMain(code)
// create context
@ -145,7 +140,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
exports = Vector(),
updates = Tree.Root(
@ -204,15 +198,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|main =
| x = 42
| IO.println x
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(),
updates = Tree.Root(
@ -283,16 +269,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|main =
| x = 42
| y = 9
| IO.println x+y
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(),
updates = Tree.Root(
@ -383,17 +360,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|main =
| x = 42
| y : Number
| y = 9
| IO.println x+y
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(),
updates = Tree.Root(
@ -492,19 +459,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|foo x = x * 10
|
|main =
| x = 42
| y : Number
| y = 9
| IO.println x+y
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(),
updates = Tree.Root(
@ -629,19 +584,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|foo a b = a * b
|
|main =
| x = 42
| y : Number
| y = 9
| IO.println x+y
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(),
updates = Tree.Root(
@ -708,7 +651,6 @@ class RuntimeSuggestionUpdatesTest
|
|main = IO.println "Hello World!"
|""".stripMargin.linesIterator.mkString("\n")
val version = contentsVersion(code)
val mainFile = context.writeMain(code)
// create context
@ -745,7 +687,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
exports = Vector(),
updates = Tree.Root(
@ -794,7 +735,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
exports = Vector(),
updates = Tree.empty
@ -802,8 +742,7 @@ class RuntimeSuggestionUpdatesTest
),
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = "Enso_Test.Foo.Main",
version = version,
module = "Enso_Test.Foo.Main",
actions =
Vector(Api.SuggestionsDatabaseAction.Clean("Enso_Test.Foo.Main")),
exports = Vector(),
@ -866,7 +805,6 @@ class RuntimeSuggestionUpdatesTest
|Text.Text.overloaded self arg = arg + 1
|Number.overloaded self arg = arg + 2
|""".stripMargin.linesIterator.mkString("\n")
val version = contentsVersion(contents)
val mainFile = context.writeMain(contents)
// create context
@ -903,7 +841,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
exports = Vector(),
updates = Tree.Root(
@ -1038,10 +975,8 @@ class RuntimeSuggestionUpdatesTest
|hello = "Hello World!"
|""".stripMargin.linesIterator.mkString("\n")
val mainVersion = contentsVersion(mainCode)
val mainFile = context.writeMain(mainCode)
val aVersion = contentsVersion(aCode)
val aFile = context.writeInSrcDir("A", aCode)
val mainFile = context.writeMain(mainCode)
val aFile = context.writeInSrcDir("A", aCode)
// create context
context.send(Api.Request(requestId, Api.CreateContextRequest(contextId)))
@ -1080,8 +1015,7 @@ class RuntimeSuggestionUpdatesTest
Api.Response(requestId, Api.PushContextResponse(contextId)),
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = "Enso_Test.Test.A",
version = aVersion,
module = "Enso_Test.Test.A",
actions =
Vector(Api.SuggestionsDatabaseAction.Clean("Enso_Test.Test.A")),
exports = Vector(),
@ -1206,7 +1140,6 @@ class RuntimeSuggestionUpdatesTest
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = mainVersion,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
exports = Vector(
Api.ExportsUpdate(
@ -1276,18 +1209,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|import Enso_Test.Test.A
|from Enso_Test.Test.A export all hiding hello
|import Enso_Test.Test.A.MyType
|from Enso_Test.Test.A.MyType export all
|
|main = IO.println "Hello World!"
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(
Api.ExportsUpdate(
@ -1326,13 +1248,7 @@ class RuntimeSuggestionUpdatesTest
) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,
version = contentsVersion(
"""from Standard.Base import all
|
|main = IO.println "Hello World!"
|""".stripMargin.linesIterator.mkString("\n")
),
module = moduleName,
actions = Vector(),
exports = Vector(
Api.ExportsUpdate(

View File

@ -47,8 +47,6 @@ class RenameProjectCmd(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = module.getName.toString,
version =
ctx.versioning.evalVersion(module.getSource.getCharacters),
actions = Vector(
Api.SuggestionsDatabaseAction.Clean(module.getName.toString)
),

View File

@ -5,7 +5,6 @@ import org.enso.interpreter.instrument.command.Command
import org.enso.interpreter.instrument.execution.Completion.{Done, Interrupted}
import org.enso.interpreter.runtime.control.ThreadInterruptedException
import org.enso.polyglot.RuntimeOptions
import org.enso.text.Sha3_224VersionCalculator
import java.util.logging.Level
@ -60,8 +59,7 @@ class CommandExecutionEngine(interpreterContext: InterpreterContext)
jobProcessor = jobExecutionEngine,
jobControlPlane = jobExecutionEngine,
locking = locking,
state = executionState,
versioning = Sha3_224VersionCalculator
state = executionState
)
/** @inheritdoc */

View File

@ -2,7 +2,6 @@ package org.enso.interpreter.instrument.execution
import org.enso.interpreter.instrument.InterpreterContext
import org.enso.interpreter.instrument.job.{BackgroundJob, Job, UniqueJob}
import org.enso.text.Sha3_224VersionCalculator
import java.util
import java.util.{Collections, UUID}
@ -58,8 +57,7 @@ final class JobExecutionEngine(
jobProcessor = this,
jobControlPlane = this,
locking = locking,
state = executionState,
versioning = Sha3_224VersionCalculator
state = executionState
)
/** @inheritdoc */

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.instrument.execution
import com.oracle.truffle.api.TruffleContext
import org.enso.interpreter.instrument.{Endpoint, ExecutionContextManager}
import org.enso.interpreter.service.ExecutionService
import org.enso.text.ContentBasedVersioning
/** Contains suppliers of services that provide application specific
* functionality.
@ -17,7 +16,6 @@ import org.enso.text.ContentBasedVersioning
* @param jobControlPlane a job control plane
* @param locking a locking service
* @param state a state of the runtime
* @param versioning a version calculator
*/
case class RuntimeContext(
executionService: ExecutionService,
@ -27,6 +25,5 @@ case class RuntimeContext(
jobProcessor: JobProcessor,
jobControlPlane: JobControlPlane,
locking: Locking,
state: ExecutionState,
versioning: ContentBasedVersioning
state: ExecutionState
)

View File

@ -47,12 +47,10 @@ final class AnalyzeModuleInScopeJob(
val newSuggestions = SuggestionBuilder(module.getSource.getCharacters)
.build(moduleName, module.getIr)
.filter(Suggestion.isGlobal)
val version = ctx.versioning.evalVersion(module.getSource.getCharacters)
val prevExports = ModuleExports(moduleName.toString, Set())
val newExports = exportsBuilder.build(module.getName, module.getIr)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName.toString,
version = version,
module = moduleName.toString,
actions =
Vector(Api.SuggestionsDatabaseAction.Clean(moduleName.toString)),
exports = ModuleExportsDiff.compute(prevExports, newExports),

View File

@ -51,7 +51,6 @@ object AnalyzeModuleJob {
changeset: Changeset[Rope]
)(implicit ctx: RuntimeContext): Unit = {
val moduleName = module.getName
val version = ctx.versioning.evalVersion(module.getSource.getCharacters)
if (module.isIndexed) {
ctx.executionService.getLogger
.log(Level.FINEST, s"Analyzing indexed module $moduleName")
@ -67,7 +66,6 @@ object AnalyzeModuleJob {
val exportsDiff = ModuleExportsDiff.compute(prevExports, newExports)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName.toString,
version = version,
actions = Vector(),
exports = exportsDiff,
updates = diff
@ -82,8 +80,7 @@ object AnalyzeModuleJob {
val prevExports = ModuleExports(moduleName.toString, Set())
val newExports = exportsBuilder.build(moduleName, module.getIr)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName.toString,
version = version,
module = moduleName.toString,
actions =
Vector(Api.SuggestionsDatabaseAction.Clean(moduleName.toString)),
exports = ModuleExportsDiff.compute(prevExports, newExports),

View File

@ -1,52 +0,0 @@
package org.enso.searcher
/** The object for accessing the database containing the module versions. */
trait VersionsRepo[F[_]] {
/** Initialize the repo. */
def init: F[Unit]
/** Get the module version.
*
* @param module the module name
* @return the version digest
*/
def getVersion(module: String): F[Option[Array[Byte]]]
/** Set the module version.
*
* @param module the module name
* @param digest the version digest
* @return previously recorded version
*/
def setVersion(module: String, digest: Array[Byte]): F[Option[Array[Byte]]]
/** Update the version if it differs from the recorded version.
*
* @param module the module name
* @param digest the version digest
* @return `true` if the version has been updated
*/
def updateVersion(module: String, digest: Array[Byte]): F[Boolean]
/** Update the versions in batch.
*
* @param versions files with corresponding digests
*/
def updateVersions(versions: Seq[(String, Array[Byte])]): F[Unit]
/** Remove the version record.
*
* @param module the module name
*/
def remove(module: String): F[Unit]
/** Remove a list of version records.
*
* @param modules the list of modules to remove
*/
def remove(modules: Seq[String]): F[Unit]
/** Clean the repo. */
def clean: F[Unit]
}

View File

@ -1,164 +0,0 @@
package org.enso.searcher.sql
import java.util
import org.enso.searcher.VersionsRepo
import slick.jdbc.SQLiteProfile.api._
import slick.jdbc.meta.MTable
import scala.concurrent.{ExecutionContext, Future}
final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
extends VersionsRepo[Future] {
/** Initialize the repo. */
override def init: Future[Unit] =
db.run(initQuery.transactionally)
/** @inheritdoc */
override def getVersion(module: String): Future[Option[Array[Byte]]] =
db.run(getVersionQuery(module))
/** @inheritdoc */
override def setVersion(
module: String,
digest: Array[Byte]
): Future[Option[Array[Byte]]] =
db.run(setVersionQuery(module, digest))
/** @inheritdoc */
override def updateVersion(
module: String,
digest: Array[Byte]
): Future[Boolean] =
db.run(updateVersionQuery(module, digest))
/** @inheritdoc */
override def updateVersions(
versions: Seq[(String, Array[Byte])]
): Future[Unit] =
db.run(updateVersionsQuery(versions).transactionally)
/** @inheritdoc */
override def remove(module: String): Future[Unit] =
db.run(removeQuery(module))
/** @inheritdoc */
override def remove(modules: Seq[String]): Future[Unit] =
db.run(removeModulesQuery(modules))
/** @inheritdoc */
override def clean: Future[Unit] =
db.run(cleanQuery)
/** Close the database. */
def close(): Unit =
db.close()
/** The query to initialize the repo. */
private def initQuery: DBIO[Unit] = {
val table = ModuleVersions
for {
tables <- MTable.getTables(table.shaped.value.tableName)
_ <- if (tables.isEmpty) table.schema.create else DBIO.successful(())
} yield ()
}
/** The query to clean the repo. */
private def cleanQuery: DBIO[Unit] =
ModuleVersions.delete >> DBIO.successful(())
/** The query to get the version digest of the file.
*
* @param module the module name
* @return the version digest
*/
private def getVersionQuery(module: String): DBIO[Option[Array[Byte]]] = {
val query = for {
row <- ModuleVersions
if row.module === module
} yield row.digest
query.result.headOption
}
/** The query to set the version digest of the file.
*
* @param module the module name
* @param version the version digest
* @return the previously recorded vile version
*/
private def setVersionQuery(
module: String,
version: Array[Byte]
): DBIO[Option[Array[Byte]]] = {
val upsertQuery =
ModuleVersions.insertOrUpdate(ModuleVersionRow(module, version))
for {
version <- getVersionQuery(module)
_ <- upsertQuery
} yield version
}
/** The query to update the version if it differs from the recorded version.
*
* @param module the module name
* @param version the version digest
* @return `true` if the version has been updated
*/
private def updateVersionQuery(
module: String,
version: Array[Byte]
): DBIO[Boolean] =
for {
moduleVersion <- getVersionQuery(module)
versionsEquals = moduleVersion.fold(false)(compareVersions(_, version))
_ <-
if (!versionsEquals) setVersionQuery(module, version)
else DBIO.successful(None)
} yield !versionsEquals
/** The query to update the versions in batch.
*
* @param versions files with corresponding digests
*/
private def updateVersionsQuery(
versions: Seq[(String, Array[Byte])]
): DBIO[Unit] =
if (versions.nonEmpty) {
def upsertQuery(module: String, version: Array[Byte]) =
ModuleVersions.insertOrUpdate(ModuleVersionRow(module, version))
DBIO.sequence(versions.map(Function.tupled(upsertQuery))) >>
DBIO.successful(())
} else {
DBIO.successful(())
}
/** The query to remove the version record.
*
* @param module the module name
*/
private def removeQuery(module: String): DBIO[Unit] = {
val query = for {
row <- ModuleVersions
if row.module === module
} yield row
query.delete >> DBIO.successful(())
}
/** The query to remove multiple module versions.
*
* @param modules the list of module names
*/
private def removeModulesQuery(modules: Seq[String]): DBIO[Unit] = {
val deleteQuery = ModuleVersions
.filter(_.module.inSet(modules))
.delete
for {
_ <- deleteQuery
} yield ()
}
private def compareVersions(v1: Array[Byte], v2: Array[Byte]): Boolean =
util.Arrays.equals(v1, v2)
}

View File

@ -54,13 +54,6 @@ case class SuggestionsVersionRow(id: Option[Long])
*/
case class SchemaVersionRow(id: Option[Long])
/** A row in the file_versions table
*
* @param module the module name
* @param digest the file version
*/
case class ModuleVersionRow(module: String, digest: Array[Byte])
/** The type of a suggestion. */
object SuggestionKind {
@ -265,18 +258,6 @@ object SuggestionRowUniqueIndex {
)
}
/** The schema of the module_versions table. */
@nowarn("msg=multiarg infix syntax")
final class ModuleVersionsTable(tag: Tag)
extends Table[ModuleVersionRow](tag, "module_versions") {
def module = column[String]("module", O.PrimaryKey)
def digest = column[Array[Byte]]("digest")
def * =
(module, digest) <> (ModuleVersionRow.tupled, ModuleVersionRow.unapply)
}
/** The schema of the suggestions_version table. */
@nowarn("msg=multiarg infix syntax")
final class SuggestionsVersionTable(tag: Tag)
@ -299,8 +280,6 @@ final class SchemaVersionTable(tag: Tag)
object Suggestions extends TableQuery(new SuggestionsTable(_))
object ModuleVersions extends TableQuery(new ModuleVersionsTable(_))
object SuggestionsVersion extends TableQuery(new SuggestionsVersionTable(_))
object SchemaVersion extends TableQuery(new SchemaVersionTable(_)) {

View File

@ -1,149 +0,0 @@
package org.enso.searcher.sql
import java.nio.file.{Files, Path}
import java.util
import org.enso.testkit.RetrySpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.Random
class VersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
val Timeout: FiniteDuration = 20.seconds
val tmpdir: Path = {
val tmp = Files.createTempDirectory("versions-repo-test")
sys.addShutdownHook {
Files.list(tmp).forEach { path =>
path.toFile.delete()
}
tmp.toFile.delete()
}
tmp
}
def withRepo(test: SqlVersionsRepo => Any): Any = {
val tmpdb = Files.createTempFile(tmpdir, "versions-repo", ".db")
val sqlDatabase = SqlDatabase(tmpdb.toFile)
sqlDatabase.open()
val repo = new SqlVersionsRepo(sqlDatabase)
Await.ready(repo.init, Timeout)
try test(repo)
finally {
Await.ready(repo.clean, Timeout)
repo.close()
}
}
def nextDigest(): Array[Byte] =
Random.nextBytes(28)
"FileVersionsRepo" should {
"init idempotent" in withRepo { repo =>
Await.result(repo.init, Timeout)
}
"insert digest" taggedAs Retry in withRepo { repo =>
val module = "Foo.Bar"
val digest = nextDigest()
val action =
for {
v1 <- repo.setVersion(module, digest)
v2 <- repo.getVersion(module)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)
v1 shouldBe None
v2 shouldBe a[Some[_]]
util.Arrays.equals(v2.get, digest) shouldBe true
}
"set digest" taggedAs Retry in withRepo { repo =>
val module = "Foo.Bar"
val digest1 = nextDigest()
val digest2 = nextDigest()
val action =
for {
v1 <- repo.setVersion(module, digest1)
v2 <- repo.setVersion(module, digest2)
v3 <- repo.getVersion(module)
} yield (v1, v2, v3)
val (v1, v2, v3) = Await.result(action, Timeout)
v1 shouldBe None
v2 shouldBe a[Some[_]]
v3 shouldBe a[Some[_]]
util.Arrays.equals(v2.get, digest1) shouldBe true
util.Arrays.equals(v3.get, digest2) shouldBe true
}
"update digest" taggedAs Retry in withRepo { repo =>
val module = "Foo.Bar"
val digest1 = nextDigest()
val digest2 = nextDigest()
val digest3 = nextDigest()
val action =
for {
b1 <- repo.updateVersion(module, digest1)
v2 <- repo.setVersion(module, digest2)
b2 <- repo.updateVersion(module, digest2)
b3 <- repo.updateVersion(module, digest3)
b4 <- repo.updateVersion(module, digest3)
v3 <- repo.getVersion(module)
} yield (v2, v3, b1, b2, b3, b4)
val (v2, v3, b1, b2, b3, b4) = Await.result(action, Timeout)
v2 shouldBe a[Some[_]]
v3 shouldBe a[Some[_]]
util.Arrays.equals(v2.get, digest1) shouldBe true
util.Arrays.equals(v3.get, digest3) shouldBe true
b1 shouldBe true
b2 shouldBe false
b3 shouldBe true
b4 shouldBe false
}
"batch update digest" taggedAs Retry in withRepo { repo =>
val module1 = "Foo.Bar"
val module2 = "Foo.Baz"
val digest0 = nextDigest()
val digest1 = nextDigest()
val digest2 = nextDigest()
val input = Seq(module1 -> digest1, module2 -> digest2)
val action =
for {
_ <- repo.setVersion(module1, digest0)
_ <- repo.updateVersions(input)
v1 <- repo.getVersion(module1)
v2 <- repo.getVersion(module2)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)
v1 shouldBe a[Some[_]]
v2 shouldBe a[Some[_]]
util.Arrays.equals(v1.get, digest1) shouldBe true
util.Arrays.equals(v2.get, digest2) shouldBe true
}
"delete digest" taggedAs Retry in withRepo { repo =>
val module = "Foo.Bar"
val digest = nextDigest()
val action =
for {
v1 <- repo.setVersion(module, digest)
_ <- repo.remove(module)
v2 <- repo.getVersion(module)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)
v1 shouldEqual None
v2 shouldEqual None
}
}
}