Skip to content

Commit

Permalink
Migrate to new database API
Browse files Browse the repository at this point in the history
  • Loading branch information
bubelov committed May 14, 2024
1 parent d18c56e commit e4bef9b
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 139 deletions.
4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,10 @@ dependencies {
implementation(libs.androidx.navigation.ui.ktx)
implementation(libs.androidx.preference.ktx)
implementation(libs.androidx.sqlite.ktx)
implementation(libs.androidx.sqlite.bundled)
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.room)

implementation(libs.material)
implementation(libs.okhttp.coroutines)
Expand All @@ -135,7 +137,7 @@ dependencies {
implementation(libs.osmdroid)
implementation(libs.jts)
implementation(libs.mpandroidchart)
implementation(libs.sqlite)
implementation(libs.deprecatedsqlite)
implementation(libs.coil.core)
implementation(libs.coil.svg)

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/kotlin/app/AppModule.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package app

import android.content.Context
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import androidx.sqlite.execSQL
import api.Api
import api.ApiImpl
import area.AreaModel
Expand All @@ -9,6 +12,7 @@ import area.AreasModel
import area.AreasRepo
import conf.ConfQueries
import conf.ConfRepo
import db.DB_FILE_NAME
import db.Database
import delivery.DeliveryModel
import element.ElementQueries
Expand Down Expand Up @@ -38,6 +42,11 @@ import user.UsersRepo

val appModule = module {
singleOf(::Database).bind(SQLiteOpenHelper::class)
single {
val context = get<Context>()
BundledSQLiteDriver().open(context.getDatabasePath(DB_FILE_NAME).absolutePath)
.apply { execSQL(Database.CREATE_AREA_TABLE) }
}

single { ApiImpl() }.bind(Api::class)

Expand Down
122 changes: 57 additions & 65 deletions app/src/main/kotlin/area/AreaQueries.kt
Original file line number Diff line number Diff line change
@@ -1,84 +1,74 @@
package area

import androidx.sqlite.SQLiteConnection
import androidx.sqlite.use
import db.getJsonObject
import db.getZonedDateTime
import io.requery.android.database.sqlite.SQLiteOpenHelper
import java.time.ZonedDateTime

class AreaQueries(val db: SQLiteOpenHelper) {
class AreaQueries(private val conn: SQLiteConnection) {

fun insertOrReplace(area: Area) {
db.writableDatabase.execSQL(
"""
INSERT OR REPLACE
INTO area(id, tags, updated_at)
VALUES(?, ?, ?)
""",
arrayOf(
area.id,
area.tags,
area.updatedAt,
),
)
conn.prepare("INSERT OR REPLACE INTO area(id, tags, updated_at) VALUES(?1, ?2, ?3)").use {
it.bindLong(1, area.id)
it.bindText(2, area.tags.toString())
it.bindText(3, area.updatedAt.toString())
it.step()
}
}

fun selectById(id: Long): Area? {
val cursor = db.readableDatabase.query(
"""
SELECT id, tags, updated_at
FROM area
WHERE id = ?;
""",
arrayOf(id),
)

if (!cursor.moveToNext()) {
return null
conn.prepare("SELECT id, tags, updated_at FROM area WHERE id = ?1").use {
it.bindLong(1, id)

return if (it.step()) {
Area(
id = it.getLong(0),
tags = it.getJsonObject(1),
updatedAt = it.getZonedDateTime(2),
)
} else {
null
}
}

return Area(
id = cursor.getLong(0),
tags = cursor.getJsonObject(1),
updatedAt = cursor.getZonedDateTime(2)!!,
)
}

fun selectByType(type: String): List<Area> {
val cursor = db.readableDatabase.query(
"""
val sql = """
SELECT id, tags, updated_at
FROM area
WHERE json_extract(tags, '$.type') = ?
""",
arrayOf(type),
)
WHERE json_extract(tags, '$.type') = ?1
"""

val rows = mutableListOf<Area>()

while (cursor.moveToNext()) {
rows += Area(
id = cursor.getLong(0),
tags = cursor.getJsonObject(1),
updatedAt = cursor.getZonedDateTime(2)!!,
)
conn.prepare(sql).use {
it.bindText(1, type)

while (it.step()) {
rows += Area(
id = it.getLong(0),
tags = it.getJsonObject(1),
updatedAt = it.getZonedDateTime(2),
)
}
}

return rows
}

fun selectMaxUpdatedAt(): ZonedDateTime? {
val cursor = db.readableDatabase.query("SELECT max(updated_at) FROM area")

if (!cursor.moveToNext()) {
return null
conn.prepare("SELECT max(updated_at) FROM area").use {
return if (it.step()) {
it.getZonedDateTime(0)
} else {
null
}
}

return cursor.getZonedDateTime(0)
}

fun selectMeetups(): List<Meetup> {
val cursor = db.readableDatabase.query(
"""
val sql = """
SELECT
json_extract(tags, '$.meetup_lat') AS lat,
json_extract(tags, '$.meetup_lon') AS lon,
Expand All @@ -88,31 +78,33 @@ class AreaQueries(val db: SQLiteOpenHelper) {
lat IS NOT NULL
AND lon IS NOT NULL
"""
)

val rows = mutableListOf<Meetup>()

while (cursor.moveToNext()) {
rows += Meetup(
lat = cursor.getDouble(0),
lon = cursor.getDouble(1),
areaId = cursor.getString(2),
)
conn.prepare(sql).use {
while (it.step()) {
rows += Meetup(
lat = it.getDouble(0),
lon = it.getDouble(1),
areaId = it.getLong(2),
)
}
}

return rows
}

fun selectCount(): Long {
val cursor = db.readableDatabase.query("SELECT count(*) FROM area")
cursor.moveToNext()
return cursor.getLong(0)
return conn.prepare("SELECT count(*) FROM area").use {
it.step()
it.getLong(0)
}
}

fun deleteById(id: Long) {
db.readableDatabase.query(
"DELETE FROM area WHERE id = ?",
arrayOf(id),
)
conn.prepare("DELETE FROM area WHERE id = ?1").use {
it.bindLong(1, id)
it.step()
}
}
}
39 changes: 17 additions & 22 deletions app/src/main/kotlin/area/AreasRepo.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package area

import android.content.Context
import androidx.sqlite.db.transaction
import api.Api
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -38,9 +37,7 @@ class AreasRepo(
.filter { it.deletedAt == null }
.map { it.toArea() }

queries.db.writableDatabase.transaction {
areas.forEach { queries.insertOrReplace(it) }
}
areas.forEach { queries.insertOrReplace(it) }
}
}
}
Expand All @@ -62,25 +59,23 @@ class AreasRepo(
}

withContext(Dispatchers.IO) {
queries.db.writableDatabase.transaction {
delta.forEach {
val cached = queries.selectById(it.id)

if (it.deletedAt == null) {
if (cached == null) {
newItems++
} else {
updatedItems++
}

queries.insertOrReplace(it.toArea())
delta.forEach {
val cached = queries.selectById(it.id)

if (it.deletedAt == null) {
if (cached == null) {
newItems++
} else {
updatedItems++
}

queries.insertOrReplace(it.toArea())
} else {
if (cached == null) {
// Already evicted from cache, nothing to do here
} else {
if (cached == null) {
// Already evicted from cache, nothing to do here
} else {
queries.deleteById(it.id)
deletedItems++
}
queries.deleteById(it.id)
deletedItems++
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/kotlin/area/Meetup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package area
data class Meetup(
val lat: Double,
val lon: Double,
val areaId: String,
val areaId: Long,
)
9 changes: 9 additions & 0 deletions app/src/main/kotlin/db/CursorExtensions.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package db

import android.database.Cursor
import androidx.sqlite.SQLiteStatement
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.json.JSONArray
Expand All @@ -12,6 +13,10 @@ fun Cursor.getJsonObject(columnIndex: Int): JSONObject {
return JSONObject(getString(columnIndex))
}

fun SQLiteStatement.getJsonObject(columnIndex: Int): JSONObject {
return JSONObject(getText(columnIndex))
}

fun Cursor.getJsonArray(columnIndex: Int): JSONArray {
return if (isNull(columnIndex)) {
JSONArray()
Expand All @@ -24,6 +29,10 @@ fun Cursor.getZonedDateTime(columnIndex: Int): ZonedDateTime? {
return (getString(columnIndex) ?: "").toZonedDateTime()
}

fun SQLiteStatement.getZonedDateTime(columnIndex: Int): ZonedDateTime {
return getText(columnIndex).toZonedDateTime()!!
}

fun Cursor.getDate(columnIndex: Int): LocalDate {
return LocalDate.parse(getString(columnIndex))
}
Expand Down
33 changes: 7 additions & 26 deletions app/src/main/kotlin/db/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class Database(context: Context) : SQLiteOpenHelper(
) {

override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_AREA_TABLE)
db.execSQL(CREATE_CONF_TABLE)
db.execSQL(CREATE_EVENT_TABLE)
db.execSQL(CREATE_ELEMENT_TABLE)
Expand All @@ -28,30 +27,12 @@ class Database(context: Context) : SQLiteOpenHelper(
}

override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (oldVersion == 1 && newVersion == 2) {
db.execSQL("DROP TABLE area;")
db.execSQL(CREATE_AREA_TABLE)

db.execSQL("DROP TABLE element;")
db.execSQL(CREATE_ELEMENT_TABLE)

db.execSQL("DROP TABLE event;")
db.execSQL(CREATE_EVENT_TABLE)

db.execSQL("DROP TABLE report;")
db.execSQL(CREATE_REPORT_TABLE)

db.execSQL("DROP TABLE user;")
db.execSQL(CREATE_USER_TABLE)
} else {
db.execSQL("DROP TABLE area;")
db.execSQL("DROP TABLE conf;")
db.execSQL("DROP TABLE element;")
db.execSQL("DROP TABLE event;")
db.execSQL("DROP TABLE report;")
db.execSQL("DROP TABLE user;")
onCreate(db)
}
db.execSQL("DROP TABLE conf;")
db.execSQL("DROP TABLE element;")
db.execSQL("DROP TABLE event;")
db.execSQL("DROP TABLE report;")
db.execSQL("DROP TABLE user;")
onCreate(db)
}

companion object {
Expand All @@ -67,7 +48,7 @@ class Database(context: Context) : SQLiteOpenHelper(
"""

const val CREATE_AREA_TABLE = """
CREATE TABLE area (
CREATE TABLE IF NOT EXISTS area (
id INTEGER NOT NULL PRIMARY KEY,
tags TEXT NOT NULL,
updated_at TEXT NOT NULL
Expand Down
Loading

0 comments on commit e4bef9b

Please sign in to comment.