jeudi 31 mars 2016

Slick3 with SQLite - autocommit seems to not be working

I'm trying to write some basic queries with Slick for SQLite database

Here is my 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))
    }
}

Here is how I'm using it:

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")
}))

The idea is to add event first, then update it with batchId (which also updates status) and then update the status when the job is done. events should contain events with status Successful.

What happens is that after running this code it prints events with status SUBMITTED. If I wait a while and do the same allEvents query or just go and check the db from command line using sqlite3 then it's updated correctly. I'm properly waiting for futures to be resolved before starting the next operation, auto-commit should be enabled by default.

Am I missing something?

Aucun commentaire:

Enregistrer un commentaire