2016-03-31 8 views
1

Ich versuche, für SQLite-Datenbank einige grundlegende Abfragen mit Slick zu schreibenSlick3 mit SQLite - autocommit scheint nicht zu funktionieren

Hier ist mein Code:

class MigrationLog(name: String) { 

    val migrationEvents = TableQuery[MigrationEventTable] 

    lazy val db: Future[SQLiteDriver.backend.DatabaseDef] = { 
     val db = Database.forURL(s"jdbc:sqlite:$name.db", driver = "org.sqlite.JDBC") 
     val setup = DBIO.seq(migrationEvents.schema.create) 

     val createFuture = for { 
      tables <- db.run(MTable.getTables) 
      createResult <- if (tables.length == 0) db.run(setup) else Future.successful() 
     } yield createResult 

     createFuture.map(_ => db) 
    } 

    val addEvent: (String, String) => Future[String] = (aggregateId, eventType) => { 
     val id = java.util.UUID.randomUUID().toString 
     val command = DBIO.seq(migrationEvents += (id, aggregateId, None, eventType, "CREATED", System.currentTimeMillis, None)) 
     db.flatMap(_.run(command).map(_ => id)) 
    } 

    val eventSubmitted: (String, String) => Future[Unit] = (id, batchId) => { 
     val q = for { e <- migrationEvents if e.id === id } yield (e.batchId, e.status, e.updatedAt) 
     val updateAction = q.update(Some(batchId), "SUBMITTED", Some(System.currentTimeMillis)) 
     db.map(_.run(updateAction)) 
    } 

    val eventMigrationCompleted: (String, String, String) => Future[Unit] = (batchId, id, status) => { 
     val q = for { e <- migrationEvents if e.batchId === batchId && e.id === id} yield (e.status, e.updatedAt) 
     val updateAction = q.update(status, Some(System.currentTimeMillis)) 
     db.map(_.run(updateAction)) 
    } 

    val allEvents =() => { 
     db.flatMap(_.run(migrationEvents.result)) 
    } 
} 

Hier ist, wie ich bin mit es:

val migrationLog = MigrationLog("test") 
val events = for { 
    id <- migrationLog.addEvent("aggregateUserId", "userAccessControl") 
    _ <- migrationLog.eventSubmitted(id, "batchID_generated_from_idam") 
    _ <- migrationLog.eventMigrationCompleted("batchID_generated_from_idam", id, "Successful") 
    events <- migrationLog.allEvents() 
} yield events 

events.map(_.foreach(event => event match { 
    case (id, aggregateId, batchId, eventType, status, submitted, updatedAt) => println(s"$id $aggregateId $batchId $eventType $status $submitted $updatedAt") 
})) 

die Idee ist, erste Ereignis hinzuzufügen, dann aktualisieren es mit BatchID (die auch Status-Updates) und dann den Status zu aktualisieren, wenn die Arbeit erledigt ist. events sollte Ereignisse mit dem Status Successful enthalten.

Nach dem Ausführen dieses Codes werden Ereignisse mit dem Status SUBMITTED ausgegeben. Wenn ich eine Weile warten und die gleiche allEvents Abfrage oder einfach gehen und überprüfen Sie die db von der Befehlszeile mit sqlite3 dann wird es korrekt aktualisiert. Ich warte richtig darauf, dass Futures vor dem Start der nächsten Operation aufgelöst werden, Auto-Commit sollte standardmäßig aktiviert sein.

Fehle ich etwas?

Antwort

0

Es stellte sich heraus, dass das Problem mit db.map(_.run(updateAction)) war, die Future[Future[Int]] zurückgibt, was bedeutet, dass der Befehl nicht abgeschlossen war, als ich versuchte, eine andere Abfrage auszuführen.

Ersetzt mit db.flatMap(_.run(updateAction)) löste das Problem.

Verwandte Themen