From 226061288aa5795ad0a8449e446f698604c03440 Mon Sep 17 00:00:00 2001 From: Igor Bubelov Date: Thu, 17 Oct 2024 22:13:37 +0700 Subject: [PATCH] Bump deps and remove connection mutex --- app/src/androidMain/kotlin/app/AppModule.kt | 2 +- .../androidMain/kotlin/area/AreaQueries.kt | 107 +++---- .../androidMain/kotlin/conf/ConfQueries.kt | 43 ++- app/src/androidMain/kotlin/db/Database.kt | 33 +-- .../kotlin/element/ElementQueries.kt | 279 ++++++++---------- .../androidMain/kotlin/event/EventQueries.kt | 139 ++++----- .../kotlin/reports/ReportQueries.kt | 95 +++--- app/src/androidMain/kotlin/sync/Sync.kt | 6 + .../androidMain/kotlin/user/UserQueries.kt | 91 +++--- gradle/libs.versions.toml | 4 +- 10 files changed, 365 insertions(+), 434 deletions(-) diff --git a/app/src/androidMain/kotlin/app/AppModule.kt b/app/src/androidMain/kotlin/app/AppModule.kt index 185798f0..1a7ec4b4 100644 --- a/app/src/androidMain/kotlin/app/AppModule.kt +++ b/app/src/androidMain/kotlin/app/AppModule.kt @@ -37,7 +37,7 @@ import user.UsersModel import user.UsersRepo val appModule = module { - single { Database(get().getDatabasePath("btcmap-2024-05-15.db").absolutePath) } + single { Database(get().getDatabasePath("btcmap-2024-05-15.db").absolutePath).conn } single { ApiImpl() }.bind(Api::class) diff --git a/app/src/androidMain/kotlin/area/AreaQueries.kt b/app/src/androidMain/kotlin/area/AreaQueries.kt index b4b3b5be..ad0c1791 100644 --- a/app/src/androidMain/kotlin/area/AreaQueries.kt +++ b/app/src/androidMain/kotlin/area/AreaQueries.kt @@ -1,13 +1,14 @@ package area +import androidx.sqlite.SQLiteConnection import androidx.sqlite.use -import db.Database import db.getInstant import db.getJsonObject import db.getZonedDateTime +import db.transaction import java.time.ZonedDateTime -class AreaQueries(private val db: Database) { +class AreaQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -20,7 +21,7 @@ class AreaQueries(private val db: Database) { } fun insertOrReplace(areas: List) { - db.transaction { conn -> + conn.transaction { conn -> areas.forEach { area -> conn.prepare("INSERT OR REPLACE INTO area(id, tags, updated_at) VALUES(?1, ?2, ?3)") .use { @@ -34,65 +35,58 @@ class AreaQueries(private val db: Database) { } fun selectById(id: Long): Area? { - return db.withConn { conn -> - conn.prepare("SELECT id, tags, updated_at FROM area WHERE id = ?1").use { - it.bindLong(1, id) + return conn.prepare("SELECT id, tags, updated_at FROM area WHERE id = ?1").use { + it.bindLong(1, id) - if (it.step()) { - Area( - id = it.getLong(0), - tags = it.getJsonObject(1), - updatedAt = it.getInstant(2), - ) - } else { - null - } + if (it.step()) { + Area( + id = it.getLong(0), + tags = it.getJsonObject(1), + updatedAt = it.getInstant(2), + ) + } else { + null } } } fun selectByType(type: String): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, tags, updated_at FROM area WHERE json_extract(tags, '$.type') = ?1 """ - ).use { - it.bindText(1, type) + ).use { + it.bindText(1, type) - buildList { - while (it.step()) { - add( - Area( - id = it.getLong(0), - tags = it.getJsonObject(1), - updatedAt = it.getInstant(2), - ) + buildList { + while (it.step()) { + add( + Area( + id = it.getLong(0), + tags = it.getJsonObject(1), + updatedAt = it.getInstant(2), ) - } + ) } } } } fun selectMaxUpdatedAt(): ZonedDateTime? { - return db.withConn { conn -> - conn.prepare("SELECT max(updated_at) FROM area").use { - if (it.step()) { - it.getZonedDateTime(0) - } else { - null - } + return conn.prepare("SELECT max(updated_at) FROM area").use { + if (it.step()) { + it.getZonedDateTime(0) + } else { + null } } } fun selectMeetups(): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT json_extract(tags, '$.meetup_lat') AS lat, json_extract(tags, '$.meetup_lon') AS lon, @@ -102,37 +96,32 @@ class AreaQueries(private val db: Database) { lat IS NOT NULL AND lon IS NOT NULL """ - ).use { - buildList { - while (it.step()) { - add( - Meetup( - lat = it.getDouble(0), - lon = it.getDouble(1), - areaId = it.getLong(2), - ) + ).use { + buildList { + while (it.step()) { + add( + Meetup( + lat = it.getDouble(0), + lon = it.getDouble(1), + areaId = it.getLong(2), ) - } + ) } } } } fun selectCount(): Long { - return db.withConn { conn -> - conn.prepare("SELECT count(*) FROM area").use { - it.step() - it.getLong(0) - } + return conn.prepare("SELECT count(*) FROM area").use { + it.step() + it.getLong(0) } } fun deleteById(id: Long) { - db.withConn { conn -> - conn.prepare("DELETE FROM area WHERE id = ?1").use { - it.bindLong(1, id) - it.step() - } + return conn.prepare("DELETE FROM area WHERE id = ?1").use { + it.bindLong(1, id) + it.step() } } } \ No newline at end of file diff --git a/app/src/androidMain/kotlin/conf/ConfQueries.kt b/app/src/androidMain/kotlin/conf/ConfQueries.kt index f7238299..9f5ee436 100644 --- a/app/src/androidMain/kotlin/conf/ConfQueries.kt +++ b/app/src/androidMain/kotlin/conf/ConfQueries.kt @@ -1,11 +1,12 @@ package conf +import androidx.sqlite.SQLiteConnection import androidx.sqlite.execSQL import androidx.sqlite.use -import db.Database import db.getZonedDateTime +import db.transaction -class ConfQueries(private val db: Database) { +class ConfQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -24,7 +25,7 @@ class ConfQueries(private val db: Database) { } fun insertOrReplace(conf: Conf) { - db.transaction { conn -> + conn.transaction { conn -> conn.execSQL("DELETE FROM conf") conn.prepare( @@ -58,9 +59,8 @@ class ConfQueries(private val db: Database) { } fun select(): Conf? { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT last_sync_date, viewport_north_lat, @@ -73,22 +73,21 @@ class ConfQueries(private val db: Database) { show_all_new_elements FROM conf """ - ).use { - if (it.step()) { - Conf( - lastSyncDate = it.getZonedDateTime(0), - viewportNorthLat = it.getDouble(1), - viewportEastLon = it.getDouble(2), - viewportSouthLat = it.getDouble(3), - viewportWestLon = it.getDouble(4), - showAtms = it.getBoolean(5), - showOsmAttribution = it.getBoolean(6), - showSyncSummary = it.getBoolean(7), - showAllNewElements = it.getBoolean(8), - ) - } else { - null - } + ).use { + if (it.step()) { + Conf( + lastSyncDate = it.getZonedDateTime(0), + viewportNorthLat = it.getDouble(1), + viewportEastLon = it.getDouble(2), + viewportSouthLat = it.getDouble(3), + viewportWestLon = it.getDouble(4), + showAtms = it.getBoolean(5), + showOsmAttribution = it.getBoolean(6), + showSyncSummary = it.getBoolean(7), + showAllNewElements = it.getBoolean(8), + ) + } else { + null } } } diff --git a/app/src/androidMain/kotlin/db/Database.kt b/app/src/androidMain/kotlin/db/Database.kt index 06e8d140..a6e864b5 100644 --- a/app/src/androidMain/kotlin/db/Database.kt +++ b/app/src/androidMain/kotlin/db/Database.kt @@ -15,11 +15,9 @@ import kotlinx.coroutines.flow.MutableStateFlow import reports.ReportQueries import user.UserQueries import java.time.LocalDateTime -import java.util.concurrent.locks.ReentrantLock class Database(path: String) { - - private val conn: SQLiteConnection = + val conn: SQLiteConnection = BundledSQLiteDriver().open( path, SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE or SQLITE_OPEN_FULLMUTEX @@ -46,29 +44,16 @@ class Database(path: String) { execSQL("PRAGMA user_version=1") } } +} - private val connLock = ReentrantLock() - - fun withConn(action: (conn: SQLiteConnection) -> T): T { - connLock.lock() - return try { - action(conn) - } finally { - connLock.unlock() - } - } - - fun transaction(action: (conn: SQLiteConnection) -> T) { - return withConn { conn -> - conn.execSQL("BEGIN TRANSACTION") +fun SQLiteConnection.transaction(action: (conn: SQLiteConnection) -> T) { + this.execSQL("BEGIN TRANSACTION") - try { - action(conn) - conn.execSQL("END TRANSACTION") - } catch (t: Throwable) { - conn.execSQL("ROLLBACK TRANSACTION") - } - } + try { + action(this) + this.execSQL("END TRANSACTION") + } catch (t: Throwable) { + this.execSQL("ROLLBACK TRANSACTION") } } diff --git a/app/src/androidMain/kotlin/element/ElementQueries.kt b/app/src/androidMain/kotlin/element/ElementQueries.kt index 006280a6..81027899 100644 --- a/app/src/androidMain/kotlin/element/ElementQueries.kt +++ b/app/src/androidMain/kotlin/element/ElementQueries.kt @@ -1,15 +1,16 @@ package element +import androidx.sqlite.SQLiteConnection import androidx.sqlite.use -import db.Database import db.getJsonArray import db.getJsonObjectOld import db.getText import db.getZonedDateTime import db.getZonedDateTimeOrNull +import db.transaction import java.time.ZonedDateTime -class ElementQueries(private val db: Database) { +class ElementQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -25,7 +26,7 @@ class ElementQueries(private val db: Database) { } fun insertOrReplace(elements: List) { - db.transaction { conn -> + conn.transaction { conn -> elements.forEach { element -> conn.prepare( """ @@ -53,9 +54,8 @@ class ElementQueries(private val db: Database) { } fun selectById(id: Long): Element? { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, overpass_data, @@ -66,29 +66,27 @@ class ElementQueries(private val db: Database) { FROM element WHERE id = ?1 """ - ).use { - it.bindLong(1, id) + ).use { + it.bindLong(1, id) - if (it.step()) { - Element( - id = it.getLong(0), - overpassData = it.getJsonObjectOld(1), - tags = it.getJsonObjectOld(2), - updatedAt = it.getText(3), - lat = it.getDouble(4), - lon = it.getDouble(5), - ) - } else { - null - } + if (it.step()) { + Element( + id = it.getLong(0), + overpassData = it.getJsonObjectOld(1), + tags = it.getJsonObjectOld(2), + updatedAt = it.getText(3), + lat = it.getDouble(4), + lon = it.getDouble(5), + ) + } else { + null } } } fun selectBySearchString(searchString: String): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, overpass_data, @@ -99,31 +97,29 @@ class ElementQueries(private val db: Database) { FROM element WHERE UPPER(overpass_data) LIKE '%' || UPPER(?1) || '%' """ - ).use { - it.bindText(1, searchString) + ).use { + it.bindText(1, searchString) - buildList { - while (it.step()) { - add( - Element( - id = it.getLong(0), - overpassData = it.getJsonObjectOld(1), - tags = it.getJsonObjectOld(2), - updatedAt = it.getText(3), - lat = it.getDouble(4), - lon = it.getDouble(5), - ) + buildList { + while (it.step()) { + add( + Element( + id = it.getLong(0), + overpassData = it.getJsonObjectOld(1), + tags = it.getJsonObjectOld(2), + updatedAt = it.getText(3), + lat = it.getDouble(4), + lon = it.getDouble(5), ) - } + ) } } } } fun selectByOsmTagValue(tagName: String, tagValue: String): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, overpass_data, @@ -134,31 +130,29 @@ class ElementQueries(private val db: Database) { FROM element WHERE json_extract(overpass_data, '$.tags.$tagName') = ?1 """ - ).use { - it.bindText(1, tagValue) + ).use { + it.bindText(1, tagValue) - buildList { - while (it.step()) { - add( - Element( - id = it.getLong(0), - overpassData = it.getJsonObjectOld(1), - tags = it.getJsonObjectOld(2), - updatedAt = it.getText(3), - lat = it.getDouble(4), - lon = it.getDouble(5), - ) + buildList { + while (it.step()) { + add( + Element( + id = it.getLong(0), + overpassData = it.getJsonObjectOld(1), + tags = it.getJsonObjectOld(2), + updatedAt = it.getText(3), + lat = it.getDouble(4), + lon = it.getDouble(5), ) - } + ) } } } } fun selectByBtcMapTagValue(tagName: String, tagValue: String): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, overpass_data, @@ -169,22 +163,21 @@ class ElementQueries(private val db: Database) { FROM element WHERE json_extract(tags, '$.$tagName') = ?1 """ - ).use { - it.bindText(1, tagValue) + ).use { + it.bindText(1, tagValue) - buildList { - while (it.step()) { - add( - Element( - id = it.getLong(0), - overpassData = it.getJsonObjectOld(1), - tags = it.getJsonObjectOld(2), - updatedAt = it.getText(3), - lat = it.getDouble(4), - lon = it.getDouble(5), - ) + buildList { + while (it.step()) { + add( + Element( + id = it.getLong(0), + overpassData = it.getJsonObjectOld(1), + tags = it.getJsonObjectOld(2), + updatedAt = it.getText(3), + lat = it.getDouble(4), + lon = it.getDouble(5), ) - } + ) } } } @@ -197,9 +190,8 @@ class ElementQueries(private val db: Database) { maxLon: Double, excludedCategories: List, ): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, ext_lat, @@ -216,26 +208,25 @@ class ElementQueries(private val db: Database) { AND ext_lon < ?4 ORDER BY ext_lat DESC """ - ).use { - it.bindDouble(1, minLat) - it.bindDouble(2, maxLat) - it.bindDouble(3, minLon) - it.bindDouble(4, maxLon) + ).use { + it.bindDouble(1, minLat) + it.bindDouble(2, maxLat) + it.bindDouble(3, minLon) + it.bindDouble(4, maxLon) - buildList { - while (it.step()) { - add( - ElementsCluster( - count = 1, - id = it.getLong(0), - lat = it.getDouble(1), - lon = it.getDouble(2), - iconId = it.getText(3), - boostExpires = it.getZonedDateTimeOrNull(4), - requiresCompanionApp = it.getText(5, defaultValue = "no") == "yes", - ) + buildList { + while (it.step()) { + add( + ElementsCluster( + count = 1, + id = it.getLong(0), + lat = it.getDouble(1), + lon = it.getDouble(2), + iconId = it.getText(3), + boostExpires = it.getZonedDateTimeOrNull(4), + requiresCompanionApp = it.getText(5, defaultValue = "no") == "yes", ) - } + ) } } } @@ -245,9 +236,8 @@ class ElementQueries(private val db: Database) { step: Double, excludedCategories: List, ): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT count(*), e.id, @@ -261,23 +251,22 @@ class ElementQueries(private val db: Database) { GROUP BY round(ext_lat / ?1) * ?1, round(ext_lon / ?1) * ?1 ORDER BY e.ext_lat DESC """ - ).use { - it.bindDouble(1, step) + ).use { + it.bindDouble(1, step) - buildList { - while (it.step()) { - add( - ElementsCluster( - count = it.getLong(0), - id = it.getLong(1), - lat = it.getDouble(2), - lon = it.getDouble(3), - iconId = it.getText(4), - boostExpires = it.getZonedDateTimeOrNull(5), - requiresCompanionApp = it.getText(6, defaultValue = "no") == "yes", - ) + buildList { + while (it.step()) { + add( + ElementsCluster( + count = it.getLong(0), + id = it.getLong(1), + lat = it.getDouble(2), + lon = it.getDouble(3), + iconId = it.getText(4), + boostExpires = it.getZonedDateTimeOrNull(5), + requiresCompanionApp = it.getText(6, defaultValue = "no") == "yes", ) - } + ) } } } @@ -289,9 +278,8 @@ class ElementQueries(private val db: Database) { minLon: Double, maxLon: Double, ): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, ext_lat, @@ -304,59 +292,52 @@ class ElementQueries(private val db: Database) { FROM element WHERE ext_lat > ?1 AND ext_lat < ?2 AND ext_lon > ?3 AND ext_lon < ?4 """ - ).use { - it.bindDouble(1, minLat) - it.bindDouble(2, maxLat) - it.bindDouble(3, minLon) - it.bindDouble(4, maxLon) + ).use { + it.bindDouble(1, minLat) + it.bindDouble(2, maxLat) + it.bindDouble(3, minLon) + it.bindDouble(4, maxLon) - buildList { - while (it.step()) { - add( - AreaElement( - id = it.getLong(0), - lat = it.getDouble(1), - lon = it.getDouble(2), - icon = it.getText(3), - osmTags = it.getJsonObjectOld(4), - issues = it.getJsonArray(5), - osmType = it.getText(6), - osmId = it.getLong(7), - ) + buildList { + while (it.step()) { + add( + AreaElement( + id = it.getLong(0), + lat = it.getDouble(1), + lon = it.getDouble(2), + icon = it.getText(3), + osmTags = it.getJsonObjectOld(4), + issues = it.getJsonArray(5), + osmType = it.getText(6), + osmId = it.getLong(7), ) - } + ) } } } } fun selectMaxUpdatedAt(): ZonedDateTime? { - return db.withConn { conn -> - conn.prepare("SELECT max(updated_at) FROM element").use { - if (it.step()) { - it.getZonedDateTime(0) - } else { - null - } + return conn.prepare("SELECT max(updated_at) FROM element").use { + if (it.step()) { + it.getZonedDateTime(0) + } else { + null } } } fun selectCount(): Long { - return db.withConn { conn -> - conn.prepare("SELECT count(*) FROM element").use { - it.step() - it.getLong(0) - } + return conn.prepare("SELECT count(*) FROM element").use { + it.step() + it.getLong(0) } } fun deleteById(id: Long) { - db.withConn { conn -> - conn.prepare("DELETE FROM element WHERE id = ?1").use { - it.bindLong(1, id) - it.step() - } + conn.prepare("DELETE FROM element WHERE id = ?1").use { + it.bindLong(1, id) + it.step() } } } \ No newline at end of file diff --git a/app/src/androidMain/kotlin/event/EventQueries.kt b/app/src/androidMain/kotlin/event/EventQueries.kt index 0a6f65dc..83aa4014 100644 --- a/app/src/androidMain/kotlin/event/EventQueries.kt +++ b/app/src/androidMain/kotlin/event/EventQueries.kt @@ -1,14 +1,15 @@ package event +import androidx.sqlite.SQLiteConnection import androidx.sqlite.use -import db.Database import db.getJsonObjectOld import db.getText import db.getZonedDateTime +import db.transaction import java.time.ZonedDateTime import java.util.regex.Pattern -class EventQueries(private val db: Database) { +class EventQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -25,7 +26,7 @@ class EventQueries(private val db: Database) { } fun insertOrReplace(events: List) { - db.transaction { conn -> + conn.transaction { conn -> events.forEach { event -> conn.prepare( """ @@ -58,9 +59,8 @@ class EventQueries(private val db: Database) { } fun selectById(id: Long): Event? { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, user_id, @@ -72,30 +72,28 @@ class EventQueries(private val db: Database) { FROM event WHERE id = ?1 """ - ).use { - it.bindLong(1, id) - - if (it.step()) { - Event( - id = it.getLong(0), - userId = it.getLong(1), - elementId = it.getLong(2), - type = it.getLong(3), - tags = it.getJsonObjectOld(4), - createdAt = it.getZonedDateTime(5), - updatedAt = it.getZonedDateTime(6), - ) - } else { - null - } + ).use { + it.bindLong(1, id) + + if (it.step()) { + Event( + id = it.getLong(0), + userId = it.getLong(1), + elementId = it.getLong(2), + type = it.getLong(3), + tags = it.getJsonObjectOld(4), + createdAt = it.getZonedDateTime(5), + updatedAt = it.getZonedDateTime(6), + ) + } else { + null } } } fun selectAll(limit: Long): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT ev.type AS event_type, el.id AS element_id, @@ -109,31 +107,29 @@ class EventQueries(private val db: Database) { ORDER BY ev.created_at DESC LIMIT ?1 """ - ).use { - it.bindLong(1, limit) - - buildList { - while (it.step()) { - add( - EventListItem( - eventType = it.getLong(0), - elementId = it.getLong(1), - elementName = it.getText(2, ""), - eventDate = it.getZonedDateTime(3), - userName = it.getText(4), - userTips = getLnUrl(it.getText(5)), - ) + ).use { + it.bindLong(1, limit) + + buildList { + while (it.step()) { + add( + EventListItem( + eventType = it.getLong(0), + elementId = it.getLong(1), + elementName = it.getText(2, ""), + eventDate = it.getZonedDateTime(3), + userName = it.getText(4), + userTips = getLnUrl(it.getText(5)), ) - } + ) } } } } fun selectByUserId(userId: Long): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT ev.type AS event_type, el.id AS element_id, @@ -145,54 +141,47 @@ class EventQueries(private val db: Database) { WHERE ev.user_id = ?1 ORDER BY ev.created_at DESC """ - ).use { - it.bindLong(1, userId) - - buildList { - while (it.step()) { - add( - EventListItem( - eventType = it.getLong(0), - elementId = it.getLong(1), - elementName = it.getText(2, ""), - eventDate = it.getZonedDateTime(3), - userName = "", - userTips = "", - ) + ).use { + it.bindLong(1, userId) + + buildList { + while (it.step()) { + add( + EventListItem( + eventType = it.getLong(0), + elementId = it.getLong(1), + elementName = it.getText(2, ""), + eventDate = it.getZonedDateTime(3), + userName = "", + userTips = "", ) - } + ) } } } } fun selectMaxUpdatedAt(): ZonedDateTime? { - return db.withConn { conn -> - conn.prepare("SELECT max(updated_at) FROM event").use { - if (it.step()) { - it.getZonedDateTime(0) - } else { - null - } + return conn.prepare("SELECT max(updated_at) FROM event").use { + if (it.step()) { + it.getZonedDateTime(0) + } else { + null } } } fun selectCount(): Long { - return db.withConn { conn -> - conn.prepare("SELECT count(*) FROM event").use { - it.step() - it.getLong(0) - } + return conn.prepare("SELECT count(*) FROM event").use { + it.step() + it.getLong(0) } } fun deleteById(id: Long) { - db.withConn { conn -> - conn.prepare("DELETE FROM event WHERE id = ?1").use { - it.bindLong(1, id) - it.step() - } + conn.prepare("DELETE FROM event WHERE id = ?1").use { + it.bindLong(1, id) + it.step() } } diff --git a/app/src/androidMain/kotlin/reports/ReportQueries.kt b/app/src/androidMain/kotlin/reports/ReportQueries.kt index f352df44..f6a02bb9 100644 --- a/app/src/androidMain/kotlin/reports/ReportQueries.kt +++ b/app/src/androidMain/kotlin/reports/ReportQueries.kt @@ -1,13 +1,14 @@ package reports +import androidx.sqlite.SQLiteConnection import androidx.sqlite.use -import db.Database import db.getDate import db.getJsonObjectOld import db.getZonedDateTime +import db.transaction import java.time.ZonedDateTime -class ReportQueries(private val db: Database) { +class ReportQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -22,7 +23,7 @@ class ReportQueries(private val db: Database) { } fun insertOrReplace(reports: List) { - db.transaction { conn -> + conn.transaction { conn -> reports.forEach { report -> conn.prepare( """ @@ -52,9 +53,8 @@ class ReportQueries(private val db: Database) { } fun selectById(id: Long): Report? { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, area_id, @@ -65,28 +65,26 @@ class ReportQueries(private val db: Database) { WHERE id = ?1 ORDER BY date """ - ).use { - it.bindLong(1, id) + ).use { + it.bindLong(1, id) - if (it.step()) { - Report( - id = it.getLong(0), - areaId = it.getLong(1), - date = it.getDate(2), - tags = it.getJsonObjectOld(3), - updatedAt = it.getZonedDateTime(4), - ) - } else { - null - } + if (it.step()) { + Report( + id = it.getLong(0), + areaId = it.getLong(1), + date = it.getDate(2), + tags = it.getJsonObjectOld(3), + updatedAt = it.getZonedDateTime(4), + ) + } else { + null } } } fun selectByAreaId(areaId: Long): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, area_id, @@ -97,53 +95,46 @@ class ReportQueries(private val db: Database) { WHERE area_id = ?1 ORDER BY date """ - ).use { - it.bindLong(1, areaId) + ).use { + it.bindLong(1, areaId) - buildList { - while (it.step()) { - add( - Report( - id = it.getLong(0), - areaId = it.getLong(1), - date = it.getDate(2), - tags = it.getJsonObjectOld(3), - updatedAt = it.getZonedDateTime(4), - ) + buildList { + while (it.step()) { + add( + Report( + id = it.getLong(0), + areaId = it.getLong(1), + date = it.getDate(2), + tags = it.getJsonObjectOld(3), + updatedAt = it.getZonedDateTime(4), ) - } + ) } } } } fun selectMaxUpdatedAt(): ZonedDateTime? { - return db.withConn { conn -> - conn.prepare("SELECT max(updated_at) FROM report").use { - if (it.step()) { - it.getZonedDateTime(0) - } else { - null - } + return conn.prepare("SELECT max(updated_at) FROM report").use { + if (it.step()) { + it.getZonedDateTime(0) + } else { + null } } } fun selectCount(): Long { - return db.withConn { conn -> - conn.prepare("SELECT count(*) FROM report").use { - it.step() - it.getLong(0) - } + return conn.prepare("SELECT count(*) FROM report").use { + it.step() + it.getLong(0) } } fun deleteById(id: Long) { - db.withConn { conn -> - conn.prepare("DELETE FROM report WHERE id = ?1").use { - it.bindLong(1, id) - it.step() - } + conn.prepare("DELETE FROM report WHERE id = ?1").use { + it.bindLong(1, id) + it.step() } } } \ No newline at end of file diff --git a/app/src/androidMain/kotlin/sync/Sync.kt b/app/src/androidMain/kotlin/sync/Sync.kt index 7a539895..ea3a450b 100644 --- a/app/src/androidMain/kotlin/sync/Sync.kt +++ b/app/src/androidMain/kotlin/sync/Sync.kt @@ -62,10 +62,15 @@ class Sync( val syncJobs = mutableListOf>() val elementsReport = async { elementsRepo.sync() }.also { syncJobs += it } + elementsReport.await() val reportsReport = async { reportsRepo.sync() }.also { syncJobs += it } + reportsReport.await() val eventsReport = async { eventsRepo.sync() }.also { syncJobs += it } + eventsReport.await() val areasReport = async { areasRepo.sync() }.also { syncJobs += it } + areasReport.await() val usersReport = async { usersRepo.sync() }.also { syncJobs += it } + usersReport.await() syncJobs.awaitAll() @@ -87,6 +92,7 @@ class Sync( }.onSuccess { conf.update { it.copy(lastSyncDate = now()) } }.onFailure { + it.printStackTrace() syncNotificationController.showSyncFailedNotification(it) } } diff --git a/app/src/androidMain/kotlin/user/UserQueries.kt b/app/src/androidMain/kotlin/user/UserQueries.kt index 7fa8b4cd..987ee828 100644 --- a/app/src/androidMain/kotlin/user/UserQueries.kt +++ b/app/src/androidMain/kotlin/user/UserQueries.kt @@ -1,14 +1,15 @@ package user +import androidx.sqlite.SQLiteConnection import androidx.sqlite.use -import db.Database import db.getHttpUrlOrNull import db.getJsonObjectOld import db.getZonedDateTime +import db.transaction import java.time.ZonedDateTime import java.util.regex.Pattern -data class UserQueries(private val db: Database) { +data class UserQueries(private val conn: SQLiteConnection) { companion object { const val CREATE_TABLE = """ @@ -22,7 +23,7 @@ data class UserQueries(private val db: Database) { } fun insertOrReplace(users: List) { - db.transaction { conn -> + conn.transaction { conn -> users.forEach { user -> conn.prepare( """ @@ -49,9 +50,8 @@ data class UserQueries(private val db: Database) { } fun selectAll(): List { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT u.id AS id, json_extract(u.osm_data, '$.img.href') AS image, @@ -63,28 +63,26 @@ data class UserQueries(private val db: Database) { GROUP BY u.id ORDER BY changes DESC """ - ).use { - buildList { - while (it.step()) { - add( - UserListItem( - id = it.getLong(0), - image = it.getHttpUrlOrNull(1), - name = it.getText(2), - tips = getLnUrl(it.getText(3)), - changes = it.getLong(4), - ) + ).use { + buildList { + while (it.step()) { + add( + UserListItem( + id = it.getLong(0), + image = it.getHttpUrlOrNull(1), + name = it.getText(2), + tips = getLnUrl(it.getText(3)), + changes = it.getLong(4), ) - } + ) } } } } fun selectById(id: Long): User? { - return db.withConn { conn -> - conn.prepare( - """ + return conn.prepare( + """ SELECT id, osm_data, @@ -93,50 +91,43 @@ data class UserQueries(private val db: Database) { FROM user WHERE id = ?1 """ - ).use { - it.bindLong(1, id) + ).use { + it.bindLong(1, id) - if (it.step()) { - User( - id = it.getLong(0), - osmData = it.getJsonObjectOld(1), - tags = it.getJsonObjectOld(2), - updatedAt = it.getZonedDateTime(3), - ) - } else { - null - } + if (it.step()) { + User( + id = it.getLong(0), + osmData = it.getJsonObjectOld(1), + tags = it.getJsonObjectOld(2), + updatedAt = it.getZonedDateTime(3), + ) + } else { + null } } } fun selectMaxUpdatedAt(): ZonedDateTime? { - return db.withConn { conn -> - conn.prepare("SELECT max(updated_at) FROM user").use { - if (it.step()) { - it.getZonedDateTime(0) - } else { - null - } + return conn.prepare("SELECT max(updated_at) FROM user").use { + if (it.step()) { + it.getZonedDateTime(0) + } else { + null } } } fun selectCount(): Long { - return db.withConn { conn -> - conn.prepare("SELECT count(*) FROM user").use { - it.step() - it.getLong(0) - } + return conn.prepare("SELECT count(*) FROM user").use { + it.step() + it.getLong(0) } } fun deleteById(id: Long) { - db.withConn { conn -> - conn.prepare("DELETE FROM user WHERE id = ?1").use { - it.bindLong(1, id) - it.step() - } + conn.prepare("DELETE FROM user WHERE id = ?1").use { + it.bindLong(1, id) + it.step() } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cffdfc64..e9facb27 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # https://developer.android.com/build/releases/gradle-plugin -agp = "8.7.0" +agp = "8.7.1" # https://github.com/JetBrains/kotlin/releases kotlin = "1.9.25" # Allows suspending functions @@ -35,7 +35,7 @@ jts = "1.20.0" mpandroidchart = "v3.1.0" # Used to cache data and store user preferences # https://developer.android.com/jetpack/androidx/releases/sqlite -sqlite = "2.5.0-alpha09" +sqlite = "2.5.0-alpha10" # Used to download, cache and display images # https://github.com/coil-kt/coil/releases coil = "2.7.0"