package jp.juggler.subwaytooter.table import android.annotation.SuppressLint import android.content.ContentValues import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.provider.BaseColumns import jp.juggler.subwaytooter.App1 import jp.juggler.util.* class PostDraft { var id: Long = 0 var time_save: Long = 0 var json: JsonObject? = null var hash: String? = null fun delete() { try { App1.database.delete(table, "$COL_ID=?", arrayOf(id.toString())) } catch (ex: Throwable) { log.e(ex, "delete failed.") } } class ColIdx(cursor: Cursor) { val idx_id = cursor.getColumnIndex(COL_ID) val idx_time_save = cursor.getColumnIndex(COL_TIME_SAVE) val idx_json = cursor.getColumnIndex(COL_JSON) val idx_hash = cursor.getColumnIndex(COL_HASH) } companion object : TableCompanion { private val log = LogCategory("PostDraft") override val table = "post_draft" private const val COL_ID = BaseColumns._ID private const val COL_TIME_SAVE = "time_save" private const val COL_JSON = "json" private const val COL_HASH = "hash" override fun onDBCreate(db: SQLiteDatabase) { log.d("onDBCreate!") db.execSQL( """create table if not exists $table ($COL_ID INTEGER PRIMARY KEY ,$COL_TIME_SAVE integer not null ,$COL_JSON text not null ,$COL_HASH text not null )""".trimIndent() ) db.execSQL("create unique index if not exists ${table}_hash on $table($COL_HASH)") db.execSQL("create index if not exists ${table}_time on $table($COL_TIME_SAVE)") } override fun onDBUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { if (oldVersion < 12 && newVersion >= 12) { onDBCreate(db) } } private fun deleteOld(now: Long) { try { // 古いデータを掃除する val expire = now - 86400000L * 30 App1.database.delete(table, "$COL_TIME_SAVE json.keys.sorted().forEach { k -> val v = json[k]?.toString() ?: "(null)" sb.append("&") sb.append(k) sb.append("=") sb.append(v) } }.toString().digestSHA256Hex() // save to db App1.database.replace(table, null, ContentValues().apply { put(COL_TIME_SAVE, now) put(COL_JSON, json.toString()) put(COL_HASH, hash) }) } catch (ex: Throwable) { log.e(ex, "save failed.") } } fun hasDraft(): Boolean { try { App1.database.query(table, arrayOf("count(*)"), null, null, null, null, null) .use { cursor -> if (cursor.moveToNext()) { val count = cursor.getInt(0) return count > 0 } } } catch (ex: Throwable) { log.trace(ex, "hasDraft failed.") } return false } // caller must close the cursor @SuppressLint("Recycle") fun createCursor(): Cursor? = try { App1.database.query( table, null, null, null, null, null, "$COL_TIME_SAVE desc" ) } catch (ex: Throwable) { log.trace(ex, "createCursor failed.") null } fun loadFromCursor(cursor: Cursor, colIdxArg: ColIdx?, position: Int): PostDraft? { return if (!cursor.moveToPosition(position)) { log.d("loadFromCursor: move failed. position=$position") null } else { PostDraft().also { dst -> val colIdx = colIdxArg ?: ColIdx(cursor) dst.id = cursor.getLong(colIdx.idx_id) dst.time_save = cursor.getLong(colIdx.idx_time_save) dst.hash = cursor.getString(colIdx.idx_hash) dst.json = try { cursor.getString(colIdx.idx_json).decodeJsonObject() } catch (ex: Throwable) { log.trace(ex) JsonObject() } } } } } }