1
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"minSdkVersion": "21",
|
||||
"dependencies":[]
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
import xSqliteHelp from 'uts.sdk.modules.utsXsqliteS.xSqliteHelp';
|
||||
import SQLiteResultByKt from 'uts.sdk.modules.utsXsqliteS.SQLiteResultByKt';
|
||||
import SQLiteConfigByKt from 'uts.sdk.modules.utsXsqliteS.SQLiteConfigByKt';
|
||||
import SQLiteExecuteBatchParamsByKt from 'uts.sdk.modules.utsXsqliteS.SQLiteExecuteBatchParamsByKt';
|
||||
import {SQLiteConfig,SQLiteResult,SQLiteExecuteBatchParams} from '../interface.uts';
|
||||
import Kotlin from 'kotlin.jvm.internal.Intrinsics.Kotlin';
|
||||
|
||||
|
||||
/**
|
||||
* SQLite数据库操作类
|
||||
* 提供SQLite数据库的创建、查询、更新等基本操作,支持加密和事务处理
|
||||
*/
|
||||
export class xSqlite {
|
||||
/** 数据库配置信息 */
|
||||
config : SQLiteConfig;
|
||||
private db : xSqliteHelp|null = null;
|
||||
|
||||
constructor(config : SQLiteConfig = {}) {
|
||||
let realCofing:SQLiteConfig = config;
|
||||
let directory:null|string = realCofing?.defaultDirectory??null
|
||||
if(typeof directory == 'string' && directory !=null){
|
||||
directory = UTSAndroid.convert2AbsFullPath(directory)
|
||||
}
|
||||
realCofing.defaultDirectory = directory
|
||||
this.config = realCofing;
|
||||
this.db = new xSqliteHelp(
|
||||
UTSAndroid.getAppContext()!,
|
||||
SQLiteConfigByKt(
|
||||
password = this.config.password,
|
||||
encryption = (this.config?.encryption??false),
|
||||
defaultDirectory = (this.config?.defaultDirectory??null),
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
private converFormat(result?:SQLiteResultByKt):SQLiteResult{
|
||||
if(result==null){
|
||||
return {
|
||||
rows: [] ,
|
||||
columns: [] ,
|
||||
changes: null,
|
||||
lastInsertRowid: null,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
let rows = [] as any[][];
|
||||
let maps = [] as Map<string,any>[];
|
||||
let columns = [] as string[];
|
||||
if(result?.rows!=null){
|
||||
let cols = result!.columns as ArrayList<string>;
|
||||
columns = Array.fromNative(cols)
|
||||
}
|
||||
if(result?.rows!=null){
|
||||
let crows = result!.rows as ArrayList<ArrayList<any>>;
|
||||
for (col in crows) {
|
||||
rows.push(Array.fromNative(col))
|
||||
}
|
||||
}
|
||||
if(result?.maps!=null){
|
||||
let cmaps = result!.maps as ArrayList<LinkedHashMap<string,any>>;
|
||||
for (col in cmaps) {
|
||||
let item = col as LinkedHashMap<string,any>;
|
||||
let newmap = new Map<string,any>()
|
||||
for(key in columns){
|
||||
newmap.set(key,item.get(key)!)
|
||||
}
|
||||
maps.push(newmap)
|
||||
}
|
||||
}
|
||||
return {
|
||||
rows: rows,
|
||||
columns: columns,
|
||||
maps: maps,
|
||||
changes: result?.changes,
|
||||
lastInsertRowid: result?.lastInsertRowid,
|
||||
error: result?.error,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据库
|
||||
* @param fileName 数据库文件名,如果为null则使用默认名称'sqlite'
|
||||
* @returns 创建成功返回true,失败返回false
|
||||
*/
|
||||
createDb(fileName:string|null = null) : boolean{
|
||||
if (this.db==null){
|
||||
return false;
|
||||
}
|
||||
const result = this.db!.createDb(fileName)
|
||||
|
||||
return result != null;
|
||||
}
|
||||
/**
|
||||
* 执行SQL语句
|
||||
* @param sql SQL语句
|
||||
* @param params SQL参数数组
|
||||
* @returns SQLiteResult 执行结果,包含changes(影响行数)和lastInsertRowid(最后插入行ID)
|
||||
*/
|
||||
run(sql: string, params: any[] = []): SQLiteResult {
|
||||
try {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.run(sql, params);
|
||||
return this.converFormat(result)
|
||||
} catch (error) {
|
||||
return { error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据
|
||||
* @param sql 查询SQL语句
|
||||
* @param params 查询参数数组
|
||||
* @returns SQLiteResult 查询结果,包含rows(数据行)和columns(列名)
|
||||
*/
|
||||
query(sql: string, params: any[] = [] as any[]): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
|
||||
const result = this.db!.query(sql, params.toKotlinList());
|
||||
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入数据
|
||||
* @param table 表名
|
||||
* @param data 要插入的数据对象
|
||||
* @returns SQLiteResult 插入结果
|
||||
*/
|
||||
insert(table: string, data: UTSJSONObject): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.insert(table, new org.json.JSONObject(data.toJSONString()));
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新数据
|
||||
* @param table 表名
|
||||
* @param data 要更新的数据对象
|
||||
* @param where WHERE条件语句
|
||||
* @param params WHERE条件参数数组
|
||||
* @returns SQLiteResult 更新结果
|
||||
*/
|
||||
update(table: string, data: UTSJSONObject, where: string, params: any[] = []): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.update(table,
|
||||
new org.json.JSONObject(data.toJSONString()),
|
||||
where,
|
||||
params.toKotlinList()
|
||||
);
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
* @param table 表名
|
||||
* @param where WHERE条件语句
|
||||
* @param params WHERE条件参数数组
|
||||
* @returns SQLiteResult 删除结果
|
||||
*/
|
||||
delete(table: string, where: string, params: any[] = []): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.delete(table, where ,params.toKotlinList());
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 检查表是否存在
|
||||
* @param tableName 表名
|
||||
* @returns 表存在返回true,不存在返回false
|
||||
*/
|
||||
tableExists(tableName: string): boolean {
|
||||
if (this.db==null){
|
||||
return false
|
||||
}
|
||||
return this.db!.tableExists(tableName);
|
||||
}
|
||||
/**
|
||||
* 创建数据表
|
||||
* @param tableName 表名
|
||||
* @param columns 列定义对象,key为列名,value为列类型定义
|
||||
* @returns SQLiteResult 创建结果
|
||||
*/
|
||||
createTable(tableName: string, columns: UTSJSONObject): SQLiteResult {
|
||||
try {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const dataMap = new Map<string,string>();
|
||||
for(const key in columns){
|
||||
const item = columns.getString(key)!;
|
||||
dataMap.set(key,item)
|
||||
}
|
||||
const result = this.db!.createTable(tableName, dataMap);
|
||||
return this.converFormat(result)
|
||||
} catch (error) {
|
||||
return { error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据表
|
||||
* @param tableName 要删除的表名
|
||||
* @returns SQLiteResult 删除结果
|
||||
*/
|
||||
dropTable(tableName: string): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.dropTable(tableName);
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭数据库连接
|
||||
* 释放数据库资源,关闭后需要重新创建才能使用
|
||||
*/
|
||||
close(): void {
|
||||
if (this.db!=null) {
|
||||
this.db!.close();
|
||||
this.db = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始事务
|
||||
* 开始一个新的事务,在提交或回滚之前,所有操作都在事务内
|
||||
* @returns SQLiteResult 事务开始结果
|
||||
*/
|
||||
beginTransaction(): SQLiteResult{
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.beginTransaction();
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交事务
|
||||
* 提交当前事务的所有操作
|
||||
* @returns SQLiteResult 事务提交结果
|
||||
*/
|
||||
commit(): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.commit();
|
||||
return this.converFormat(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 回滚事务
|
||||
* 撤销当前事务中的所有操作
|
||||
* @returns SQLiteResult 事务回滚结果
|
||||
*/
|
||||
rollback(): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.rollback();
|
||||
return this.converFormat(result)
|
||||
}
|
||||
/**
|
||||
* 批量执行SQL语句
|
||||
* @param statements SQL语句数组,每个元素包含sql和params
|
||||
* @returns SQLiteResult[] 每个语句的执行结果数组
|
||||
*/
|
||||
executeBatch(statements: SQLiteExecuteBatchParams[]): SQLiteResult[] {
|
||||
if (this.db==null){
|
||||
console.error('Database not initialized')
|
||||
return [];
|
||||
}
|
||||
const list = new ArrayList<SQLiteExecuteBatchParamsByKt>()
|
||||
for(const item in statements){
|
||||
list.add(SQLiteExecuteBatchParamsByKt(
|
||||
sql = item.sql,
|
||||
params = (item?.params??[]).toKotlinList()
|
||||
))
|
||||
}
|
||||
const result = this.db!.executeBatch(list);
|
||||
let resultList = [] as SQLiteResult[]
|
||||
for(const item in result){
|
||||
resultList.push(this.converFormat(item))
|
||||
}
|
||||
|
||||
return resultList
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据库到本地文件
|
||||
* @param filename 保存的文件名,可选,默认为'sqlite'
|
||||
* @returns SQLiteResult 保存结果
|
||||
*/
|
||||
saveLocal(filename?: string): SQLiteResult {
|
||||
if (this.db==null){
|
||||
return {error:'Database not initialized'};
|
||||
}
|
||||
const result = this.db!.saveLocal(filename);
|
||||
return this.converFormat(result)
|
||||
}
|
||||
/**
|
||||
* 从本地文件加载数据库
|
||||
* @param filename 要加载的数据库文件名
|
||||
* @returns SQLiteResult 加载结果
|
||||
*/
|
||||
loadLocal(filename:string): SQLiteResult{
|
||||
|
||||
const result = this.db!.loadLocal(filename);
|
||||
return this.converFormat(result)
|
||||
}
|
||||
/**
|
||||
* 获取数据库文件路径
|
||||
* 获取当前数据库文件的完整路径,获取前会备份到缓存目录
|
||||
* @returns string|null 数据库文件路径,如果数据库未初始化则返回null
|
||||
*/
|
||||
getDatabasePath():string|null{
|
||||
if (this.db==null){
|
||||
console.error('Database not initialized')
|
||||
return null
|
||||
}
|
||||
return this.db!.getDatabasePath();
|
||||
}
|
||||
/**
|
||||
* 当前数据库的目录
|
||||
*/
|
||||
setDefaultDirectory(directory: string){
|
||||
if (this.db==null){
|
||||
console.error('Database not initialized')
|
||||
return
|
||||
}
|
||||
let rdirectory = directory;
|
||||
if(rdirectory!=''){
|
||||
rdirectory = UTSAndroid.convert2AbsFullPath(directory)
|
||||
}
|
||||
this.db!.setDefaultDirectory(rdirectory);
|
||||
}
|
||||
/**
|
||||
* 设置数据库密码
|
||||
* 空值或者null即删除密码
|
||||
*/
|
||||
setPassword(password: string|null = null){
|
||||
if (this.db==null){
|
||||
console.error('Database not initialized')
|
||||
return
|
||||
}
|
||||
this.db!.setPassword(password);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
package uts.sdk.modules.utsXsqliteS
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import io.dcloud.uts.console
|
||||
|
||||
data class SQLiteConfigByKt(
|
||||
var password: String? = null,
|
||||
var encryption: Boolean = false,
|
||||
var locateFile: ((String) -> String)? = null,
|
||||
var defaultDirectory: String? = null
|
||||
)
|
||||
|
||||
data class SQLiteResultByKt(
|
||||
val rows: List<List<Any>>? = null,
|
||||
val columns: List<String>? = null,
|
||||
val changes: Int? = null,
|
||||
val lastInsertRowid: Long? = null,
|
||||
val error: String? = null,
|
||||
val maps: List<Map<String, Any>>? = null
|
||||
)
|
||||
|
||||
data class SQLiteExecuteBatchParamsByKt(
|
||||
val sql: String,
|
||||
val params: List<Any>? = null
|
||||
)
|
||||
|
||||
class xSqliteHelp(private val context: Context, private val config: SQLiteConfigByKt = SQLiteConfigByKt()) {
|
||||
private var db: SQLiteDatabase? = null
|
||||
private var isInTransaction: Boolean = false
|
||||
private var fileURLPath: String? = null
|
||||
|
||||
fun createDb(filename: String? = null): SQLiteDatabase? {
|
||||
val fname = filename ?: "sqlite"
|
||||
val dbFile = if (config.defaultDirectory != null) {
|
||||
File(config.defaultDirectory, "$fname.db")
|
||||
} else {
|
||||
context.getDatabasePath("$fname.db")
|
||||
}
|
||||
|
||||
try {
|
||||
if (!dbFile.parentFile?.exists()!!) {
|
||||
dbFile.parentFile?.mkdirs()
|
||||
}
|
||||
|
||||
db = SQLiteDatabase.openOrCreateDatabase(dbFile, null)
|
||||
if (config.encryption && config.password != null) {
|
||||
run("PRAGMA key = ?", listOf(config.password!!))
|
||||
}
|
||||
fileURLPath = dbFile.absolutePath
|
||||
return db
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 执行SQL查询
|
||||
fun run(sql: String, params: List<Any> = emptyList()): SQLiteResultByKt {
|
||||
return try {
|
||||
if (db == null) throw Exception("Database not initialized")
|
||||
val statement = db!!.compileStatement(sql)
|
||||
params.forEachIndexed { index, param ->
|
||||
when (param) {
|
||||
is String -> statement.bindString(index + 1, param)
|
||||
is Int -> statement.bindLong(index + 1, param.toLong())
|
||||
is Long -> statement.bindLong(index + 1, param)
|
||||
is Double -> statement.bindDouble(index + 1, param)
|
||||
is ByteArray -> statement.bindBlob(index + 1, param)
|
||||
null -> statement.bindNull(index + 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据SQL语句类型选择合适的执行方法
|
||||
val sqlUpperCase = sql.trim().uppercase()
|
||||
val result = if (sqlUpperCase.startsWith("INSERT")) {
|
||||
// 对于INSERT语句,使用executeInsert获取lastInsertRowid
|
||||
val lastId = statement.executeInsert()
|
||||
SQLiteResultByKt(changes = 1, lastInsertRowid = lastId)
|
||||
} else {
|
||||
// 对于UPDATE/DELETE/其他语句,使用executeUpdateDelete获取受影响的行数
|
||||
val changes = statement.executeUpdateDelete()
|
||||
SQLiteResultByKt(changes = changes, lastInsertRowid = null)
|
||||
}
|
||||
|
||||
result
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 查询数据
|
||||
fun query(sql: String, params: List<Any> = emptyList()): SQLiteResultByKt {
|
||||
return try {
|
||||
if (db == null) throw Exception("Database not initialized")
|
||||
val args = params.map { it?.toString() ?: "" }.toTypedArray()
|
||||
val cursor = db!!.rawQuery(sql, args)
|
||||
val columns = ArrayList(cursor.columnNames.toList())
|
||||
val rows = mutableListOf<List<Any>>()
|
||||
val maps = mutableListOf<Map<String, Any>>()
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
val row = mutableListOf<Any>()
|
||||
val map = mutableMapOf<String, Any>()
|
||||
for (i in 0 until cursor.columnCount) {
|
||||
val columnName = cursor.getColumnName(i)
|
||||
val value = when (cursor.getType(i)) {
|
||||
android.database.Cursor.FIELD_TYPE_STRING -> cursor.getString(i)
|
||||
android.database.Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(i)
|
||||
android.database.Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(i)
|
||||
android.database.Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(i)
|
||||
else -> ""
|
||||
}
|
||||
row.add(value)
|
||||
map[columnName] = value
|
||||
}
|
||||
rows.add(row)
|
||||
maps.add(map)
|
||||
}
|
||||
cursor.close()
|
||||
SQLiteResultByKt(rows = rows, columns = columns, maps = maps)
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 插入数据
|
||||
fun insert(table: String, data: JSONObject): SQLiteResultByKt {
|
||||
val keys = mutableListOf<String>()
|
||||
val values = mutableListOf<Any>()
|
||||
data.keys().forEach { key ->
|
||||
keys.add(key)
|
||||
values.add(data.get(key))
|
||||
}
|
||||
val sql = "INSERT INTO $table (${keys.joinToString(",")}) VALUES (${keys.map { "?" }.joinToString(",")})"
|
||||
return run(sql, values)
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
fun update(table: String, data: JSONObject, where: String, params: List<Any> = emptyList()): SQLiteResultByKt {
|
||||
val sets = mutableListOf<String>()
|
||||
val values = mutableListOf<Any>()
|
||||
data.keys().forEach { key ->
|
||||
sets.add("$key = ?")
|
||||
values.add(data.get(key))
|
||||
}
|
||||
values.addAll(params)
|
||||
val sql = "UPDATE $table SET ${sets.joinToString(",")} WHERE $where"
|
||||
return run(sql, values)
|
||||
}
|
||||
|
||||
// 删除数据
|
||||
fun delete(table: String, where: String, params: List<Any> = emptyList()): SQLiteResultByKt {
|
||||
val sql = "DELETE FROM $table WHERE $where"
|
||||
return run(sql, params)
|
||||
}
|
||||
|
||||
// 保存数据库到本地
|
||||
fun saveLocal(filename: String? = null): SQLiteResultByKt {
|
||||
return try {
|
||||
if (db == null) throw Exception("Database not initialized")
|
||||
val fname = filename ?: "sqlite"
|
||||
|
||||
// 获取当前数据库文件的实际路径
|
||||
val dbPath = db!!.path
|
||||
val dbFile = if (dbPath.isNotEmpty()) File(dbPath) else context.getDatabasePath("sqlite.db")
|
||||
// 检查源文件是否存在
|
||||
if (!dbFile.exists()) {
|
||||
return SQLiteResultByKt(error = "未能找到数据库文件")
|
||||
}
|
||||
|
||||
// 使用配置的默认目录或系统文件目录
|
||||
val targetDir = if (config.defaultDirectory != null) File(config.defaultDirectory) else context.filesDir
|
||||
val targetFile = File(targetDir, "$fname.db")
|
||||
// 确保目标目录存在
|
||||
targetFile.parentFile?.mkdirs()
|
||||
if(dbFile.absolutePath != targetFile.absolutePath){
|
||||
dbFile.copyTo(targetFile, overwrite = true)
|
||||
}
|
||||
|
||||
SQLiteResultByKt()
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 从本地加载数据库
|
||||
fun loadLocal(filename: String): SQLiteResultByKt {
|
||||
return try {
|
||||
// 使用配置的默认目录或系统文件目录
|
||||
val sourceDir = if (config.defaultDirectory != null) File(config.defaultDirectory!!) else context.filesDir
|
||||
val sourceFile = File(sourceDir, "$filename.db")
|
||||
|
||||
if (!sourceFile.exists()) {
|
||||
return SQLiteResultByKt(error = "没有数据库")
|
||||
}
|
||||
val dbFile = context.getDatabasePath("sqlite.db")
|
||||
sourceFile.copyTo(dbFile, overwrite = true)
|
||||
createDb(filename)
|
||||
SQLiteResultByKt()
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = "数据库损坏")
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认目录
|
||||
fun setDefaultDirectory(directory: String) {
|
||||
config.defaultDirectory = directory
|
||||
}
|
||||
|
||||
// 设置密码
|
||||
fun setPassword(password: String?) {
|
||||
config.password = password
|
||||
config.encryption = password != null && password.isNotEmpty()
|
||||
|
||||
if (db != null) {
|
||||
if (config.encryption && config.password != null) {
|
||||
run("PRAGMA rekey = ?", listOf(config.password!!))
|
||||
} else {
|
||||
run("PRAGMA rekey = ''", emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查表是否存在
|
||||
fun tableExists(tableName: String): Boolean {
|
||||
val result = query("SELECT name FROM sqlite_master WHERE type='table' AND name=?", listOf(tableName))
|
||||
return result.rows?.isNotEmpty() == true
|
||||
}
|
||||
|
||||
// 创建数据表
|
||||
fun createTable(tableName: String, columns: Map<String, String>): SQLiteResultByKt {
|
||||
val columnDefinitions = columns.entries.joinToString(",") { (name, type) -> "$name $type" }
|
||||
val sql = "CREATE TABLE IF NOT EXISTS $tableName ($columnDefinitions)"
|
||||
return run(sql)
|
||||
}
|
||||
|
||||
// 删除数据表
|
||||
fun dropTable(tableName: String): SQLiteResultByKt {
|
||||
val sql = "DROP TABLE IF EXISTS $tableName"
|
||||
return run(sql)
|
||||
}
|
||||
|
||||
// 关闭数据库
|
||||
fun close() {
|
||||
db?.close()
|
||||
db = null
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
fun beginTransaction(): SQLiteResultByKt {
|
||||
return try {
|
||||
if (isInTransaction) {
|
||||
return SQLiteResultByKt(error = "Transaction already in progress")
|
||||
}
|
||||
db?.beginTransaction()
|
||||
isInTransaction = true
|
||||
SQLiteResultByKt()
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
fun commit(): SQLiteResultByKt {
|
||||
return try {
|
||||
if (!isInTransaction) {
|
||||
return SQLiteResultByKt(error = "No transaction in progress")
|
||||
}
|
||||
db?.setTransactionSuccessful()
|
||||
db?.endTransaction()
|
||||
isInTransaction = false
|
||||
SQLiteResultByKt()
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 回滚事务
|
||||
fun rollback(): SQLiteResultByKt {
|
||||
return try {
|
||||
if (!isInTransaction) {
|
||||
return SQLiteResultByKt(error = "No transaction in progress")
|
||||
}
|
||||
db?.endTransaction()
|
||||
isInTransaction = false
|
||||
SQLiteResultByKt()
|
||||
} catch (e: Exception) {
|
||||
SQLiteResultByKt(error = e.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 批量执行SQL
|
||||
fun executeBatch(statements: List<SQLiteExecuteBatchParamsByKt>): List<SQLiteResultByKt> {
|
||||
val results = mutableListOf<SQLiteResultByKt>()
|
||||
var hasError = false
|
||||
|
||||
val wasInTransaction = isInTransaction
|
||||
if (!wasInTransaction) {
|
||||
beginTransaction()
|
||||
}
|
||||
|
||||
try {
|
||||
for (stmt in statements) {
|
||||
val result = run(stmt.sql, stmt.params ?: emptyList())
|
||||
results.add(result)
|
||||
if (result.error != null) {
|
||||
hasError = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (hasError && !wasInTransaction) {
|
||||
rollback()
|
||||
} else if (!wasInTransaction) {
|
||||
commit()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (!wasInTransaction) {
|
||||
rollback()
|
||||
}
|
||||
results.add(SQLiteResultByKt(error = e.message))
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库文件路径获取前会备份到缓存目录
|
||||
*/
|
||||
fun getDatabasePath(): String? {
|
||||
if (db == null) return null
|
||||
|
||||
try {
|
||||
// 获取当前数据库文件
|
||||
// val dbFile = db!!.path
|
||||
val dbFile = File(db!!.path)
|
||||
if (!dbFile.exists() || !dbFile.canRead()) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取缓存目录
|
||||
val cacheDir = context.cacheDir
|
||||
val tempFile = File(cacheDir, "tmui4x_xSqlite_DbackTemp.db")
|
||||
|
||||
// 如果临时文件存在则删除
|
||||
if (tempFile.exists()) {
|
||||
tempFile.delete()
|
||||
}
|
||||
|
||||
// 复制数据库文件到缓存目录
|
||||
dbFile.copyTo(tempFile, overwrite = true)
|
||||
|
||||
return tempFile.absolutePath
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user