Add extension functions to improve writability of database queries.

This commit is contained in:
Greyson Parrelli
2022-04-01 10:04:05 -04:00
committed by Cody Henthorne
parent 3e42c044b8
commit 98b9cc23e4
2 changed files with 317 additions and 2 deletions

View File

@@ -1,6 +1,11 @@
package org.signal.core.util
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import androidx.core.content.contentValuesOf
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQueryBuilder
fun SupportSQLiteDatabase.getTableRowCount(table: String): Int {
return this.query("SELECT COUNT(*) FROM $table").use {
@@ -10,4 +15,212 @@ fun SupportSQLiteDatabase.getTableRowCount(table: String): Int {
0
}
}
}
}
/**
* Begins a SELECT statement with a helpful builder pattern.
*/
fun SupportSQLiteDatabase.select(vararg columns: String): SelectBuilderPart1 {
return SelectBuilderPart1(this, arrayOf(*columns))
}
/**
* Begins an UPDATE statement with a helpful builder pattern.
*/
fun SupportSQLiteDatabase.update(tableName: String): UpdateBuilderPart1 {
return UpdateBuilderPart1(this, tableName)
}
/**
* Begins a DELETE statement with a helpful builder pattern.
*/
fun SupportSQLiteDatabase.delete(tableName: String): DeleteBuilderPart1 {
return DeleteBuilderPart1(this, tableName)
}
class SelectBuilderPart1(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>
) {
fun from(tableName: String): SelectBuilderPart2 {
return SelectBuilderPart2(db, columns, tableName)
}
}
class SelectBuilderPart2(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>,
private val tableName: String
) {
fun where(where: String, vararg whereArgs: Any): SelectBuilderPart3 {
return SelectBuilderPart3(db, columns, tableName, where, SqlUtil.buildArgs(whereArgs))
}
fun run(): Cursor {
return db.query(
SupportSQLiteQueryBuilder
.builder(tableName)
.columns(columns)
.create()
)
}
}
class SelectBuilderPart3(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>,
private val tableName: String,
private val where: String,
private val whereArgs: Array<String>
) {
fun orderBy(orderBy: String): SelectBuilderPart4a {
return SelectBuilderPart4a(db, columns, tableName, where, whereArgs, orderBy)
}
fun limit(limit: Int): SelectBuilderPart4b {
return SelectBuilderPart4b(db, columns, tableName, where, whereArgs, limit.toString())
}
fun run(): Cursor {
return db.query(
SupportSQLiteQueryBuilder
.builder(tableName)
.columns(columns)
.selection(where, whereArgs)
.create()
)
}
}
class SelectBuilderPart4a(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>,
private val tableName: String,
private val where: String,
private val whereArgs: Array<String>,
private val orderBy: String
) {
fun limit(limit: Int): SelectBuilderPart5 {
return SelectBuilderPart5(db, columns, tableName, where, whereArgs, orderBy, limit.toString())
}
fun run(): Cursor {
return db.query(
SupportSQLiteQueryBuilder
.builder(tableName)
.columns(columns)
.selection(where, whereArgs)
.orderBy(orderBy)
.create()
)
}
}
class SelectBuilderPart4b(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>,
private val tableName: String,
private val where: String,
private val whereArgs: Array<String>,
private val limit: String
) {
fun orderBy(orderBy: String): SelectBuilderPart5 {
return SelectBuilderPart5(db, columns, tableName, where, whereArgs, orderBy, limit)
}
fun run(): Cursor {
return db.query(
SupportSQLiteQueryBuilder
.builder(tableName)
.columns(columns)
.selection(where, whereArgs)
.limit(limit)
.create()
)
}
}
class SelectBuilderPart5(
private val db: SupportSQLiteDatabase,
private val columns: Array<String>,
private val tableName: String,
private val where: String,
private val whereArgs: Array<String>,
private val orderBy: String,
private val limit: String
) {
fun run(): Cursor {
return db.query(
SupportSQLiteQueryBuilder
.builder(tableName)
.columns(columns)
.selection(where, whereArgs)
.orderBy(orderBy)
.limit(limit)
.create()
)
}
}
class UpdateBuilderPart1(
private val db: SupportSQLiteDatabase,
private val tableName: String
) {
fun values(values: ContentValues): UpdateBuilderPart2 {
return UpdateBuilderPart2(db, tableName, values)
}
fun values(vararg values: Pair<String, Any?>): UpdateBuilderPart2 {
return UpdateBuilderPart2(db, tableName, contentValuesOf(*values))
}
}
class UpdateBuilderPart2(
private val db: SupportSQLiteDatabase,
private val tableName: String,
private val values: ContentValues
) {
fun where(where: String, vararg whereArgs: Any): UpdateBuilderPart3 {
return UpdateBuilderPart3(db, tableName, values, where, SqlUtil.buildArgs(whereArgs))
}
fun run(conflictStrategy: Int = SQLiteDatabase.CONFLICT_NONE): Int {
return db.update(tableName, conflictStrategy, values, null, null)
}
}
class UpdateBuilderPart3(
private val db: SupportSQLiteDatabase,
private val tableName: String,
private val values: ContentValues,
private val where: String,
private val whereArgs: Array<String>
) {
fun run(conflictStrategy: Int = SQLiteDatabase.CONFLICT_NONE): Int {
return db.update(tableName, conflictStrategy, values, where, whereArgs)
}
}
class DeleteBuilderPart1(
private val db: SupportSQLiteDatabase,
private val tableName: String
) {
fun where(where: String, vararg whereArgs: Any): DeleteBuilderPart2 {
return DeleteBuilderPart2(db, tableName, where, SqlUtil.buildArgs(whereArgs))
}
fun run(): Int {
return db.delete(tableName, null, null)
}
}
class DeleteBuilderPart2(
private val db: SupportSQLiteDatabase,
private val tableName: String,
private val where: String,
private val whereArgs: Array<String>
) {
fun run(): Int {
return db.delete(tableName, where, whereArgs)
}
}