Migrations. Fixing the ordering.

This commit is contained in:
aminecmi 2022-08-12 21:38:15 +02:00
parent 24242377b9
commit 3dc988573d
5 changed files with 114 additions and 27 deletions

View File

@ -0,0 +1,72 @@
import dao.*
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
class MigrationsController {
private val migrations: Map<String, () -> Boolean> = mapOf(
"update-checked-null-position" to {updateNullPositionForChecked()},
"update-unchecked-position" to {updatePositionForUnchecked()}
)
fun checkMigrationsToDo() {
this.migrations.forEach {
transaction {
val migrationWithName = Migration.find { Migrations.identifier eq it.key }.firstOrNull()
if (migrationWithName == null) {
Migration.new {
identifier = it.key
}
println("Migration ${it.key} will start now.")
it.value()
Migrations.update({Migrations.identifier eq it.key}) {
it[done] = true
}
println("Migration ${it.key} done.")
} else if (!migrationWithName.done) {
println("Migration ${it.key} not done yet. Redoing.")
it.value()
Migrations.update({Migrations.identifier eq it.key}) {
it[done] = true
}
println("Migration ${it.key} done.")
} else {
println("Migration ${it.key} done.")
}
}
}
}
private fun updateNullPositionForChecked() : Boolean {
try {
transaction {
Items.update({ Items.checked eq true }) {
it[position] = null
}
}
} catch (e: Exception) {
return false
}
return true
}
private fun updatePositionForUnchecked() : Boolean {
try {
transaction {
Lists.selectAll().forEach {
var i = 0
Item.find { Items.list eq it[Lists.id].value and (Items.checked eq false) }
.sortedBy { it.position }
.forEach {
it.position = i
i++
}
}
}
} catch (e: Exception) {
return false
}
return true
}
}

View File

@ -81,17 +81,15 @@ class DB {
fun createItem(listId: Int, c: ItemView, ctx: Context) {
transaction {
val allITems = Item.find { Items.list eq listId }.sortedBy { it.position }
val firstChecked = allITems.firstOrNull { it.checked }
val p = firstChecked?.position ?: ((allITems.lastOrNull()?.position ?: - 1) + 1)
val listOpt = List.findById(listId)
if (listOpt != null) {
reorderElements(listId, p)
val count = Item.find { Items.list eq listId and (Items.checked eq false) }.count()
val p = (count + 1)
var i = Item.new {
list = listId
content = c.content
position = p
position = p.toInt()
checked = false
}
@ -106,7 +104,7 @@ class DB {
private fun reorderElements(listId: Int, position: Int, itemId: Int? = null) {
transaction {
var i = 0
Item.find { Items.list eq listId and (Items.id neq itemId) }
Item.find { Items.list eq listId and (Items.id neq itemId and (Items.checked eq false)) }
.sortedBy { it.position }
.forEach {
if (i == position) {
@ -147,25 +145,18 @@ class DB {
if (listOpt != null) {
val item = Item.find { Items.list eq listId and (Items.id eq itemId) }.limit(1).firstOrNull()
if (item != null) {
var p = body.position
if (body.position != null) {
reorderElements(listId, body.position, itemId)
item.position = body.position
}
if (body.checked != null) {
val allITems = Item.find { Items.list eq listId }.sortedBy { it.position }
val firstChecked = allITems.firstOrNull { it.checked }
p = if (body.checked) {
if (firstChecked != null) {
firstChecked.position - 1
} else {
allITems.lastOrNull()?.position
}
var p: Int? = if (body.checked) {
(Item.find { Items.list eq listId and (Items.checked eq false) }.count() + 1).toInt()
} else {
firstChecked?.position ?: allITems.lastOrNull()?.position
}
item.checked = body.checked
}
if (p != null) {
reorderElements(listId, p, itemId)
null
}
item.position = p
item.checked = body.checked
}
if (body.content != null) {
item.content = body.content

View File

@ -8,7 +8,7 @@ import org.jetbrains.exposed.dao.id.IntIdTable
object Items : IntIdTable() {
val list = integer("list")
val content = varchar("content", 256)
val position = integer("position")
val position = integer("position").nullable()
val checked = bool("checked").default(false)
}

View File

@ -0,0 +1,24 @@
package dao
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
object Migrations : IntIdTable() {
val identifier = varchar("identifier", 256)
val done = bool("done").default(false)
}
class Migration(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Migration>(Migrations)
var identifier by Migrations.identifier
var done by Migrations.done
}
fun Migration.toView(): MigrationView {
return MigrationView(this.id.value, this.identifier, this.done)
}
data class MigrationView(val id: Int, val identifier: String, val done: Boolean = false)

View File

@ -1,7 +1,4 @@
import dao.Items
import dao.Key
import dao.Keys
import dao.Lists
import dao.*
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.*
import io.javalin.core.security.Role
@ -15,6 +12,7 @@ import org.jetbrains.exposed.sql.transactions.transaction
enum class ApiRole : Role { PUBLIC, BASIC_AUTHED, API_AUTHED }
fun main() {
var migrationsController = MigrationsController()
val app = Javalin.create {
it.accessManager { handler, ctx, permittedRoles ->
transaction {
@ -36,6 +34,8 @@ fun main() {
Database.connect("jdbc:sqlite:data.db", "org.sqlite.JDBC")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Migrations)
migrationsController.checkMigrationsToDo()
SchemaUtils.create (Lists)
SchemaUtils.create (Items)
SchemaUtils.create (Keys)