Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.appdevforall.localwebserver

import android.database.sqlite.SQLiteDatabase
import com.aayushatharva.brotli4j.decoder.BrotliInputStream
import com.itsaky.androidide.utils.DatabaseVersionResolver
import org.slf4j.LoggerFactory
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
Expand Down Expand Up @@ -75,22 +76,7 @@ class WebServer(private val config: ServerConfig) {

fun logDatabaseLastChanged() {
try {
val query = """
SELECT changeTime, who
FROM LastChange
"""
val cursor = database.rawQuery(query, arrayOf())

try {
if (cursor.count > 0) {
cursor.moveToFirst()
log.debug("Database last change: {} {}.", cursor.getString(0), cursor.getString(1))
}

} finally {
cursor.close()
}

log.debug("Database last change: {}.", DatabaseVersionResolver.resolveDatabaseVersion(database))
} catch (e: Exception) {
log.error("Could not retrieve database last change info: {}", e.message)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.itsaky.androidide.utils

import android.database.sqlite.SQLiteDatabase
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class DatabaseVersionResolverTest {

private lateinit var db: SQLiteDatabase

@Before
fun setUp() {
db = SQLiteDatabase.openOrCreateDatabase(":memory:", null)
}

@After
fun tearDown() {
db.close()
}

private fun createTable() {
db.execSQL(
"CREATE TABLE LastChange (" +
"documentationSet TEXT, " +
"changeTime TEXT, " +
"who TEXT)"
)
}

private fun insertRow(documentationSet: String, changeTime: String, who: String?) {
db.execSQL(
"INSERT INTO LastChange (documentationSet, changeTime, who) VALUES (?, ?, ?)",
arrayOf<Any?>(documentationSet, changeTime, who),
)
}

@Test
fun returnsWholedbRow_whenPresent() {
createTable()
insertRow("wholedb", "2026-05-09 02:00:20", "hal")
insertRow("tooltips-ide", "2026-05-09 02:00:20", "hal")

assertEquals(
"2026-05-09 02:00:20 hal",
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}

@Test
fun fallsBackToLatestRow_whenWholedbMissing() {
createTable()
insertRow("tooltips-ide", "2026-05-09 02:00:20", "hal")
insertRow("content-y", "2026-05-01 17:42:29", "hal")
insertRow("tooltips-java", "2026-05-09 01:58:37", "hal")

assertEquals(
"2026-05-09 02:00:20 (tooltips-ide) hal",
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}

@Test
fun returnsVersionUnknown_whenTableEmpty() {
createTable()

assertEquals(
DatabaseVersionResolver.VERSION_UNKNOWN,
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}

@Test
fun returnsVersionUnknown_whenTableMissing() {
// Intentionally do not create the LastChange table.
assertEquals(
DatabaseVersionResolver.VERSION_UNKNOWN,
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}

@Test
fun handlesNullWho_onWholedbRow() {
createTable()
insertRow("wholedb", "2026-05-09 02:00:20", null)

assertEquals(
"2026-05-09 02:00:20",
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}

@Test
fun handlesNullWho_onFallbackRow() {
createTable()
insertRow("tooltips-ide", "2026-05-09 02:00:20", null)

assertEquals(
"2026-05-09 02:00:20 (tooltips-ide)",
DatabaseVersionResolver.resolveDatabaseVersion(db),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.itsaky.androidide.utils

import android.database.sqlite.SQLiteDatabase
import android.util.Log

object DatabaseVersionResolver {

const val VERSION_UNKNOWN = "Version Unknown"

private const val TAG = "DatabaseVersionResolver"

private const val QUERY_WHOLEDB = """
SELECT changeTime, who
FROM LastChange
WHERE documentationSet = 'wholedb'
LIMIT 1
"""
Comment thread
hal-eisen-adfa marked this conversation as resolved.

private const val QUERY_FALLBACK_LATEST = """
SELECT changeTime, documentationSet, who
FROM LastChange
ORDER BY changeTime DESC
LIMIT 1
"""

fun resolveDatabaseVersion(db: SQLiteDatabase): String {
return try {
db.rawQuery(QUERY_WHOLEDB, arrayOf()).use { c ->
if (c.moveToFirst()) {
return formatVersion(
changeTime = c.getString(0),
who = c.getString(1),
)
}
}

db.rawQuery(QUERY_FALLBACK_LATEST, arrayOf()).use { c ->
if (c.moveToFirst()) {
val result = formatVersion(
changeTime = c.getString(0),
who = c.getString(2),
documentationSet = c.getString(1),
)
Log.e(
TAG,
"Missing 'wholedb' record in LastChange table; falling back to $result",
)
return result
}
}

Log.e(TAG, "No versioning information available")
VERSION_UNKNOWN
} catch (e: Exception) {
Log.e(TAG, "No versioning information available", e)
VERSION_UNKNOWN
}
}

private fun formatVersion(
changeTime: String?,
who: String?,
documentationSet: String? = null,
): String {
val parts = mutableListOf<String>()
if (!changeTime.isNullOrBlank()) parts += changeTime
if (!documentationSet.isNullOrBlank()) parts += "($documentationSet)"
if (!who.isNullOrBlank()) parts += who
return parts.joinToString(separator = " ")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import android.view.MotionEvent
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat.getColor
import com.itsaky.androidide.activities.editor.HelpActivity
import com.itsaky.androidide.utils.DatabaseVersionResolver
import com.itsaky.androidide.utils.Environment
import com.itsaky.androidide.utils.FeedbackManager
import com.itsaky.androidide.utils.isSystemInDarkMode
Expand Down Expand Up @@ -66,12 +67,6 @@ object TooltipManager {
ORDER BY buttonNumberId
"""

private const val QUERY_LAST_CHANGE = """
SELECT changeTime, who
FROM LastChange
WHERE documentationSet = 'wholedb'
"""

suspend fun getTooltip(context: Context, category: String, tag: String): IDETooltipItem? {
Log.d(TAG, "In getTooltip() for category='$category', tag='$tag'.")

Expand All @@ -98,9 +93,10 @@ object TooltipManager {
val db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY)

db.use { database ->
database.rawQuery(QUERY_LAST_CHANGE, arrayOf()).use { c ->
c.moveToFirst()
lastChange = "${c.getString(0)} ${c.getString(1)}"
try {
lastChange = DatabaseVersionResolver.resolveDatabaseVersion(database)
} catch (e: Exception) {
Log.e(TAG, "Version resolution failed: ${e.message}")
}

Log.d(TAG, "last change is '${lastChange}'.")
Expand Down
Loading