session-android/app/src/main/java/org/thoughtcrime/securesms/database/LokiBackupFilesDatabase.kt

117 lines
4.4 KiB
Kotlin

package org.thoughtcrime.securesms.database
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.net.Uri
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import java.lang.IllegalArgumentException
import java.util.*
import kotlin.collections.ArrayList
/**
* Keeps track of the backup files saved by the app.
* Uses [BackupFileRecord] as an entry data projection.
*/
class LokiBackupFilesDatabase(context: Context, databaseHelper: SQLCipherOpenHelper)
: Database(context, databaseHelper) {
companion object {
public const val TABLE_NAME = "backup_files"
private const val COLUMN_ID = "_id"
private const val COLUMN_URI = "uri"
private const val COLUMN_FILE_SIZE = "file_size"
private const val COLUMN_TIMESTAMP = "timestamp"
private val allColumns = arrayOf(COLUMN_ID, COLUMN_URI, COLUMN_FILE_SIZE, COLUMN_TIMESTAMP)
@JvmStatic
val createTableCommand = """
CREATE TABLE $TABLE_NAME (
$COLUMN_ID INTEGER PRIMARY KEY,
$COLUMN_URI TEXT NOT NULL,
$COLUMN_FILE_SIZE INTEGER NOT NULL,
$COLUMN_TIMESTAMP INTEGER NOT NULL
);
""".trimIndent()
private fun mapCursorToRecord(cursor: Cursor): BackupFileRecord {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_ID))
val uriRaw = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_URI))
val fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_FILE_SIZE))
val timestampRaw = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_TIMESTAMP))
return BackupFileRecord(id, Uri.parse(uriRaw), fileSize, Date(timestampRaw))
}
private fun mapRecordToValues(record: BackupFileRecord): ContentValues {
val contentValues = ContentValues()
if (record.id >= 0) { contentValues.put(COLUMN_ID, record.id) }
contentValues.put(COLUMN_URI, record.uri.toString())
contentValues.put(COLUMN_FILE_SIZE, record.fileSize)
contentValues.put(COLUMN_TIMESTAMP, record.timestamp.time)
return contentValues
}
}
fun getBackupFiles(): List<BackupFileRecord> {
databaseHelper.readableDatabase.query(TABLE_NAME, allColumns, null, null, null, null, null).use {
val records = ArrayList<BackupFileRecord>()
while (it != null && it.moveToNext()) {
val record = mapCursorToRecord(it)
records.add(record)
}
return records
}
}
fun insertBackupFile(record: BackupFileRecord): BackupFileRecord {
val contentValues = mapRecordToValues(record)
val id = databaseHelper.writableDatabase.insertOrThrow(TABLE_NAME, null, contentValues)
return BackupFileRecord(id, record.uri, record.fileSize, record.timestamp)
}
fun getLastBackupFileTime(): Date? {
// SELECT $COLUMN_TIMESTAMP FROM $TABLE_NAME ORDER BY $COLUMN_TIMESTAMP DESC LIMIT 1
databaseHelper.readableDatabase.query(
TABLE_NAME,
arrayOf(COLUMN_TIMESTAMP),
null, null, null, null,
"$COLUMN_TIMESTAMP DESC",
"1"
).use {
if (it !== null && it.moveToFirst()) {
return Date(it.getLong(0))
} else {
return null
}
}
}
fun getLastBackupFile(): BackupFileRecord? {
// SELECT * FROM $TABLE_NAME ORDER BY $COLUMN_TIMESTAMP DESC LIMIT 1
databaseHelper.readableDatabase.query(
TABLE_NAME,
allColumns,
null, null, null, null,
"$COLUMN_TIMESTAMP DESC",
"1"
).use {
if (it != null && it.moveToFirst()) {
return mapCursorToRecord(it)
} else {
return null
}
}
}
fun deleteBackupFile(record: BackupFileRecord): Boolean {
return deleteBackupFile(record.id)
}
fun deleteBackupFile(id: Long): Boolean {
if (id < 0) {
throw IllegalArgumentException("ID must be zero or a positive number.")
}
return databaseHelper.writableDatabase.delete(TABLE_NAME, "$COLUMN_ID = $id", null) > 0
}
}