Outbox.kt
| 1 | package org.opentracker |
| 2 | |
| 3 | import android.content.Context |
| 4 | import android.database.sqlite.SQLiteDatabase |
| 5 | import android.database.sqlite.SQLiteOpenHelper |
| 6 | |
| 7 | /** |
| 8 | * Points waiting for upload. It survives process death. |
| 9 | * The server ignores a point it already has, so resending after a lost reply is safe. |
| 10 | */ |
| 11 | class Outbox(context: Context) : SQLiteOpenHelper(context, "outbox.db", null, 1) { |
| 12 | |
| 13 | override fun onCreate(db: SQLiteDatabase) { |
| 14 | db.execSQL("CREATE TABLE points (ts INTEGER PRIMARY KEY, json TEXT NOT NULL)") |
| 15 | } |
| 16 | |
| 17 | override fun onUpgrade(db: SQLiteDatabase, old: Int, new: Int) = Unit |
| 18 | |
| 19 | /** Drops the oldest points beyond [MAX], so a long offline time cannot fill the disk. */ |
| 20 | fun add(ts: Long, json: String) { |
| 21 | val db = writableDatabase |
| 22 | db.execSQL("INSERT OR REPLACE INTO points (ts, json) VALUES (?, ?)", arrayOf(ts, json)) |
| 23 | db.execSQL("DELETE FROM points WHERE ts < (SELECT ts FROM points ORDER BY ts DESC LIMIT 1 OFFSET $MAX)") |
| 24 | } |
| 25 | |
| 26 | /** The oldest points, as (ts, json). */ |
| 27 | fun peek(limit: Int): List<Pair<Long, String>> = |
| 28 | readableDatabase.rawQuery("SELECT ts, json FROM points ORDER BY ts LIMIT $limit", null).use { c -> |
| 29 | buildList { while (c.moveToNext()) add(c.getLong(0) to c.getString(1)) } |
| 30 | } |
| 31 | |
| 32 | fun removeUpTo(ts: Long) { |
| 33 | writableDatabase.execSQL("DELETE FROM points WHERE ts <= ?", arrayOf(ts)) |
| 34 | } |
| 35 | |
| 36 | fun count(): Long = readableDatabase.compileStatement("SELECT COUNT(*) FROM points").simpleQueryForLong() |
| 37 | |
| 38 | /** Unix seconds of the oldest waiting point, or null. */ |
| 39 | fun oldest(): Long? = |
| 40 | readableDatabase.rawQuery("SELECT MIN(ts) FROM points", null).use { c -> |
| 41 | if (c.moveToFirst() && !c.isNull(0)) c.getLong(0) else null |
| 42 | } |
| 43 | |
| 44 | companion object { |
| 45 | const val MAX = 50_000 |
| 46 | } |
| 47 | } |
| 48 |