expo-sqlite 11.7.1 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/android/CMakeLists.txt +35 -0
- package/android/build.gradle +114 -29
- package/android/src/main/cpp/NativeDatabaseBinding.cpp +142 -0
- package/android/src/main/cpp/NativeDatabaseBinding.h +75 -0
- package/android/src/main/cpp/NativeStatementBinding.cpp +146 -0
- package/android/src/main/cpp/NativeStatementBinding.h +95 -0
- package/android/src/main/cpp/SQLite3Main.cpp +15 -0
- package/android/src/main/cpp/SQLite3Wrapper.cpp +223 -0
- package/android/src/main/cpp/SQLite3Wrapper.h +55 -0
- package/android/src/main/java/expo/modules/sqlite/NativeDatabase.kt +11 -0
- package/android/src/main/java/expo/modules/sqlite/NativeDatabaseBinding.kt +79 -0
- package/android/src/main/java/expo/modules/sqlite/NativeStatement.kt +11 -0
- package/android/src/main/java/expo/modules/sqlite/NativeStatementBinding.kt +40 -0
- package/android/src/main/java/expo/modules/sqlite/SQLExceptions.kt +17 -6
- package/android/src/main/java/expo/modules/sqlite/SQLRecords.kt +16 -3
- package/android/src/main/java/expo/modules/sqlite/SQLite3Wrapper.kt +51 -0
- package/android/src/main/java/expo/modules/sqlite/SQLiteHelpers.kt +0 -79
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +31 -222
- package/android/src/main/java/expo/modules/sqlite/SQLiteModuleNext.kt +447 -0
- package/android/src/main/java/expo/modules/sqlite/SQLiteOptions.kt +20 -0
- package/build/next/Database.d.ts +254 -0
- package/build/next/Database.d.ts.map +1 -0
- package/build/next/Database.js +324 -0
- package/build/next/Database.js.map +1 -0
- package/build/next/ExpoSQLiteNext.d.ts +12 -0
- package/build/next/ExpoSQLiteNext.d.ts.map +1 -0
- package/build/next/ExpoSQLiteNext.js +26 -0
- package/build/next/ExpoSQLiteNext.js.map +1 -0
- package/build/next/ExpoSQLiteNext.native.d.ts +3 -0
- package/build/next/ExpoSQLiteNext.native.d.ts.map +1 -0
- package/build/next/ExpoSQLiteNext.native.js +3 -0
- package/build/next/ExpoSQLiteNext.native.js.map +1 -0
- package/build/next/NativeDatabase.d.ts +44 -0
- package/build/next/NativeDatabase.d.ts.map +1 -0
- package/build/next/NativeDatabase.js +2 -0
- package/build/next/NativeDatabase.js.map +1 -0
- package/build/next/NativeStatement.d.ts +68 -0
- package/build/next/NativeStatement.d.ts.map +1 -0
- package/build/next/NativeStatement.js +2 -0
- package/build/next/NativeStatement.js.map +1 -0
- package/build/next/Statement.d.ts +120 -0
- package/build/next/Statement.d.ts.map +1 -0
- package/build/next/Statement.js +135 -0
- package/build/next/Statement.js.map +1 -0
- package/build/next/hooks.d.ts +35 -0
- package/build/next/hooks.d.ts.map +1 -0
- package/build/next/hooks.js +57 -0
- package/build/next/hooks.js.map +1 -0
- package/build/next/index.d.ts +4 -0
- package/build/next/index.d.ts.map +1 -0
- package/build/next/index.js +4 -0
- package/build/next/index.js.map +1 -0
- package/expo-module.config.json +2 -2
- package/ios/CRSQLiteLoader.h +3 -1
- package/ios/CRSQLiteLoader.m +11 -6
- package/ios/Exceptions.swift +13 -0
- package/ios/ExpoSQLite.podspec +2 -2
- package/ios/NativeDatabase.swift +26 -0
- package/ios/NativeStatement.swift +13 -0
- package/ios/SQLAction.swift +23 -0
- package/ios/SQLiteModule.swift +0 -53
- package/ios/SQLiteModuleNext.swift +538 -0
- package/ios/SQLiteOptions.swift +26 -0
- package/next.d.ts +1 -0
- package/next.js +1 -0
- package/package.json +4 -2
- package/src/next/Database.ts +446 -0
- package/src/next/ExpoSQLiteNext.native.ts +2 -0
- package/src/next/ExpoSQLiteNext.ts +34 -0
- package/src/next/NativeDatabase.ts +58 -0
- package/src/next/NativeStatement.ts +85 -0
- package/src/next/Statement.ts +243 -0
- package/src/next/hooks.tsx +108 -0
- package/src/next/index.ts +3 -0
|
@@ -22,82 +22,3 @@ internal fun ensureDirExists(dir: File): File {
|
|
|
22
22
|
}
|
|
23
23
|
return dir
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
internal fun pluginResultsToPrimitiveData(results: List<SQLiteModule.SQLitePluginResult>): List<Any> {
|
|
27
|
-
return results.map { convertPluginResultToArray(it) }
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private fun convertPluginResultToArray(result: SQLiteModule.SQLitePluginResult): List<Any?> {
|
|
31
|
-
val rowsContent = result.rows.map { row ->
|
|
32
|
-
row.map { value ->
|
|
33
|
-
when (value) {
|
|
34
|
-
null -> null
|
|
35
|
-
is String -> value
|
|
36
|
-
is Boolean -> value
|
|
37
|
-
else -> (value as Number).toDouble()
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return arrayListOf(
|
|
43
|
-
result.error?.message,
|
|
44
|
-
result.insertId.toInt(),
|
|
45
|
-
result.rowsAffected,
|
|
46
|
-
result.columns,
|
|
47
|
-
rowsContent
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private fun isPragma(str: String): Boolean {
|
|
52
|
-
return startsWithCaseInsensitive(str, "pragma")
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private fun isSelectCTE(str: String): Boolean {
|
|
56
|
-
return startsWithCaseInsensitive(str, "with") && containsCaseInsensitive(str, "select")
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private fun isPragmaReadOnly(str: String): Boolean {
|
|
60
|
-
return isPragma(str) && !str.contains('=')
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
internal fun isSelect(str: String): Boolean {
|
|
64
|
-
return startsWithCaseInsensitive(str, "select") || isSelectCTE(str) || isPragmaReadOnly(str)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
internal fun isInsert(str: String): Boolean {
|
|
68
|
-
return startsWithCaseInsensitive(str, "insert")
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
internal fun isUpdate(str: String): Boolean {
|
|
72
|
-
return startsWithCaseInsensitive(str, "update")
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
internal fun isDelete(str: String): Boolean {
|
|
76
|
-
return startsWithCaseInsensitive(str, "delete")
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private fun startsWithCaseInsensitive(str: String, substr: String): Boolean {
|
|
80
|
-
return str.trimStart().startsWith(substr, true)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private fun containsCaseInsensitive(str: String, substr: String): Boolean {
|
|
84
|
-
return str.trimStart().contains(substr, true)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
internal fun convertParamsToStringArray(paramArrayArg: List<Any?>): Array<String?> {
|
|
88
|
-
return paramArrayArg.map { param ->
|
|
89
|
-
when (param) {
|
|
90
|
-
is String -> unescapeBlob(param)
|
|
91
|
-
is Boolean -> if (param) "1" else "0"
|
|
92
|
-
is Double -> param.toString()
|
|
93
|
-
null -> null
|
|
94
|
-
else -> throw ClassCastException("Could not find proper SQLite data type for argument: $")
|
|
95
|
-
}
|
|
96
|
-
}.toTypedArray()
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private fun unescapeBlob(str: String): String {
|
|
100
|
-
return str.replace("\u0001\u0001", "\u0000")
|
|
101
|
-
.replace("\u0001\u0002", "\u0001")
|
|
102
|
-
.replace("\u0002\u0002", "\u0002")
|
|
103
|
-
}
|
|
@@ -2,237 +2,63 @@
|
|
|
2
2
|
package expo.modules.sqlite
|
|
3
3
|
|
|
4
4
|
import android.content.Context
|
|
5
|
-
import
|
|
6
|
-
import androidx.core.os.bundleOf
|
|
5
|
+
import androidx.collection.ArrayMap
|
|
7
6
|
import expo.modules.kotlin.exception.Exceptions
|
|
8
7
|
import expo.modules.kotlin.modules.Module
|
|
9
8
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
10
|
-
import io.expo.android.database.sqlite.SQLiteCustomExtension
|
|
11
|
-
import io.expo.android.database.sqlite.SQLiteDatabase
|
|
12
|
-
import io.expo.android.database.sqlite.SQLiteDatabaseConfiguration
|
|
13
9
|
import java.io.File
|
|
14
10
|
import java.io.IOException
|
|
15
11
|
import java.util.*
|
|
16
12
|
|
|
17
|
-
private val EMPTY_ROWS = emptyArray<Array<Any?>>()
|
|
18
|
-
private val EMPTY_COLUMNS = emptyArray<String?>()
|
|
19
|
-
private val EMPTY_RESULT = SQLiteModule.SQLitePluginResult(EMPTY_ROWS, EMPTY_COLUMNS, 0, 0, null)
|
|
20
|
-
private val DATABASES: MutableMap<String, SQLiteDatabase?> = HashMap()
|
|
21
|
-
|
|
22
13
|
class SQLiteModule : Module() {
|
|
14
|
+
private val cachedDatabase = ArrayMap<String, SQLite3Wrapper>()
|
|
15
|
+
|
|
23
16
|
private val context: Context
|
|
24
17
|
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
25
18
|
|
|
26
19
|
override fun definition() = ModuleDefinition {
|
|
27
20
|
Name("ExpoSQLite")
|
|
28
21
|
|
|
29
|
-
Events("onDatabaseChange")
|
|
30
|
-
|
|
31
22
|
AsyncFunction("exec") { dbName: String, queries: List<Query>, readOnly: Boolean ->
|
|
32
23
|
return@AsyncFunction execute(dbName, queries, readOnly)
|
|
33
24
|
}
|
|
34
25
|
|
|
35
26
|
AsyncFunction("execRawQuery") { dbName: String, queries: List<Query>, readOnly: Boolean ->
|
|
36
|
-
return@AsyncFunction execute(dbName, queries, readOnly
|
|
27
|
+
return@AsyncFunction execute(dbName, queries, readOnly)
|
|
37
28
|
}
|
|
38
29
|
|
|
39
30
|
AsyncFunction("close") { dbName: String ->
|
|
40
|
-
|
|
31
|
+
cachedDatabase
|
|
41
32
|
.remove(dbName)
|
|
42
|
-
?.
|
|
33
|
+
?.sqlite3_close()
|
|
43
34
|
}
|
|
44
35
|
|
|
45
36
|
Function("closeSync") { dbName: String ->
|
|
46
|
-
|
|
37
|
+
cachedDatabase
|
|
47
38
|
.remove(dbName)
|
|
48
|
-
?.
|
|
39
|
+
?.sqlite3_close()
|
|
49
40
|
}
|
|
50
41
|
|
|
51
42
|
AsyncFunction("deleteAsync") { dbName: String ->
|
|
52
|
-
if (
|
|
53
|
-
throw
|
|
43
|
+
if (cachedDatabase[dbName] != null) {
|
|
44
|
+
throw DeleteDatabaseException(dbName)
|
|
54
45
|
}
|
|
55
46
|
val dbFile = File(pathForDatabaseName(dbName))
|
|
56
47
|
if (!dbFile.exists()) {
|
|
57
48
|
throw DatabaseNotFoundException(dbName)
|
|
58
49
|
}
|
|
59
50
|
if (!dbFile.delete()) {
|
|
60
|
-
throw
|
|
51
|
+
throw DeleteDatabaseFileException(dbName)
|
|
61
52
|
}
|
|
62
53
|
}
|
|
63
54
|
|
|
64
55
|
OnDestroy {
|
|
65
|
-
|
|
66
|
-
it
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private fun execute(dbName: String, queries: List<Query>, readOnly: Boolean, raw: Boolean = false): List<Any> {
|
|
72
|
-
val db = getDatabase(dbName)
|
|
73
|
-
val results = queries.map { sqlQuery ->
|
|
74
|
-
val sql = sqlQuery.sql
|
|
75
|
-
val bindArgs = convertParamsToStringArray(sqlQuery.args)
|
|
76
|
-
try {
|
|
77
|
-
if (isSelect(sql)) {
|
|
78
|
-
doSelectInBackgroundAndPossiblyThrow(sql, bindArgs, db)
|
|
79
|
-
} else { // update/insert/delete
|
|
80
|
-
if (readOnly) {
|
|
81
|
-
SQLitePluginResult(EMPTY_ROWS, EMPTY_COLUMNS, 0, 0, ReadOnlyException())
|
|
82
|
-
} else {
|
|
83
|
-
if (raw) {
|
|
84
|
-
doRawUpdate(sql, bindArgs, db)
|
|
85
|
-
} else {
|
|
86
|
-
doUpdateInBackgroundAndPossiblyThrow(sql, bindArgs, db)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} catch (e: Throwable) {
|
|
91
|
-
SQLitePluginResult(EMPTY_ROWS, EMPTY_COLUMNS, 0, 0, e)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return pluginResultsToPrimitiveData(results)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// do a update/delete/insert operation
|
|
98
|
-
private fun doUpdateInBackgroundAndPossiblyThrow(
|
|
99
|
-
sql: String,
|
|
100
|
-
bindArgs: Array<String?>?,
|
|
101
|
-
db: SQLiteDatabase
|
|
102
|
-
): SQLitePluginResult {
|
|
103
|
-
return db.compileStatement(sql).use { statement ->
|
|
104
|
-
if (bindArgs != null) {
|
|
105
|
-
for (i in bindArgs.size downTo 1) {
|
|
106
|
-
val args = bindArgs[i - 1]
|
|
107
|
-
if (args != null) {
|
|
108
|
-
statement.bindString(i, args)
|
|
109
|
-
} else {
|
|
110
|
-
statement.bindNull(i)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (isInsert(sql)) {
|
|
115
|
-
val insertId = statement.executeInsert()
|
|
116
|
-
val rowsAffected = if (insertId >= 0) 1 else 0
|
|
117
|
-
SQLitePluginResult(EMPTY_ROWS, EMPTY_COLUMNS, rowsAffected, insertId, null)
|
|
118
|
-
} else if (isDelete(sql) || isUpdate(sql)) {
|
|
119
|
-
val rowsAffected = statement.executeUpdateDelete()
|
|
120
|
-
SQLitePluginResult(EMPTY_ROWS, EMPTY_COLUMNS, rowsAffected, 0, null)
|
|
121
|
-
} else {
|
|
122
|
-
// in this case, we don't need rowsAffected or insertId, so we can have a slight
|
|
123
|
-
// perf boost by just executing the query
|
|
124
|
-
statement.execute()
|
|
125
|
-
EMPTY_RESULT
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private fun doRawUpdate(
|
|
131
|
-
sql: String,
|
|
132
|
-
bindArgs: Array<String?>,
|
|
133
|
-
db: SQLiteDatabase
|
|
134
|
-
): SQLitePluginResult {
|
|
135
|
-
return db.rawQuery(sql, bindArgs).use { cursor ->
|
|
136
|
-
val numRows = cursor.count
|
|
137
|
-
if (numRows == 0) {
|
|
138
|
-
return EMPTY_RESULT
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
val numColumns = cursor.columnCount
|
|
142
|
-
val columnNames = cursor.columnNames
|
|
143
|
-
val rows: Array<Array<Any?>> = Array(numRows) { arrayOfNulls(numColumns) }
|
|
144
|
-
var i = 0
|
|
145
|
-
while (cursor.moveToNext()) {
|
|
146
|
-
val row = rows[i]
|
|
147
|
-
for (j in 0 until numColumns) {
|
|
148
|
-
row[j] = getValueFromCursor(cursor, j, cursor.getType(j))
|
|
149
|
-
}
|
|
150
|
-
rows[i] = row
|
|
151
|
-
i++
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (isInsert(sql)) {
|
|
155
|
-
val rowsAffected = getRowsAffected(db)
|
|
156
|
-
val insertId = getInsertId(db)
|
|
157
|
-
SQLitePluginResult(rows, columnNames, rowsAffected, insertId, null)
|
|
158
|
-
} else if (isDelete(sql) || isUpdate(sql)) {
|
|
159
|
-
val rowsAffected = getRowsAffected(db)
|
|
160
|
-
SQLitePluginResult(rows, columnNames, rowsAffected, 0, null)
|
|
161
|
-
} else {
|
|
162
|
-
EMPTY_RESULT
|
|
56
|
+
cachedDatabase.values.forEach {
|
|
57
|
+
it.sqlite3_close()
|
|
163
58
|
}
|
|
164
59
|
}
|
|
165
60
|
}
|
|
166
61
|
|
|
167
|
-
private fun getRowsAffected(
|
|
168
|
-
db: SQLiteDatabase,
|
|
169
|
-
): Int {
|
|
170
|
-
val cursor = db.rawQuery("SELECT changes() AS numRowsAffected", null)
|
|
171
|
-
val rowsAffected = if (cursor.moveToFirst()) {
|
|
172
|
-
val index = cursor.getColumnIndex("numRowsAffected")
|
|
173
|
-
cursor.getInt(index)
|
|
174
|
-
} else {
|
|
175
|
-
-1
|
|
176
|
-
}
|
|
177
|
-
cursor.close()
|
|
178
|
-
return rowsAffected
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private fun getInsertId(
|
|
182
|
-
db: SQLiteDatabase,
|
|
183
|
-
): Long {
|
|
184
|
-
val cursor = db.rawQuery("SELECT last_insert_rowid() AS insertId", null)
|
|
185
|
-
val insertId = if (cursor.moveToFirst()) {
|
|
186
|
-
val index = cursor.getColumnIndex("insertId")
|
|
187
|
-
cursor.getLong(index)
|
|
188
|
-
} else {
|
|
189
|
-
-1
|
|
190
|
-
}
|
|
191
|
-
cursor.close()
|
|
192
|
-
return insertId
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// do a select operation
|
|
196
|
-
private fun doSelectInBackgroundAndPossiblyThrow(
|
|
197
|
-
sql: String,
|
|
198
|
-
bindArgs: Array<String?>,
|
|
199
|
-
db: SQLiteDatabase
|
|
200
|
-
): SQLitePluginResult {
|
|
201
|
-
return db.rawQuery(sql, bindArgs).use { cursor ->
|
|
202
|
-
val numRows = cursor.count
|
|
203
|
-
if (numRows == 0) {
|
|
204
|
-
return EMPTY_RESULT
|
|
205
|
-
}
|
|
206
|
-
val numColumns = cursor.columnCount
|
|
207
|
-
val columnNames = cursor.columnNames
|
|
208
|
-
val rows: Array<Array<Any?>> = Array(numRows) { arrayOfNulls(numColumns) }
|
|
209
|
-
var i = 0
|
|
210
|
-
while (cursor.moveToNext()) {
|
|
211
|
-
val row = rows[i]
|
|
212
|
-
for (j in 0 until numColumns) {
|
|
213
|
-
row[j] = getValueFromCursor(cursor, j, cursor.getType(j))
|
|
214
|
-
}
|
|
215
|
-
rows[i] = row
|
|
216
|
-
i++
|
|
217
|
-
}
|
|
218
|
-
SQLitePluginResult(rows, columnNames, 0, 0, null)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
private fun getValueFromCursor(cursor: Cursor, index: Int, columnType: Int): Any? {
|
|
223
|
-
return when (columnType) {
|
|
224
|
-
Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(index)
|
|
225
|
-
Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(index)
|
|
226
|
-
Cursor.FIELD_TYPE_BLOB ->
|
|
227
|
-
// convert byte[] to binary string; it's good enough, because
|
|
228
|
-
// WebSQL doesn't support blobs anyway
|
|
229
|
-
String(cursor.getBlob(index))
|
|
230
|
-
|
|
231
|
-
Cursor.FIELD_TYPE_STRING -> cursor.getString(index)
|
|
232
|
-
else -> null
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
62
|
@Throws(IOException::class)
|
|
237
63
|
private fun pathForDatabaseName(name: String): String {
|
|
238
64
|
val directory = File("${context.filesDir}${File.separator}SQLite")
|
|
@@ -240,44 +66,29 @@ class SQLiteModule : Module() {
|
|
|
240
66
|
return "$directory${File.separator}$name"
|
|
241
67
|
}
|
|
242
68
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
69
|
+
private fun openDatabase(dbName: String): SQLite3Wrapper? {
|
|
70
|
+
val path: String
|
|
71
|
+
try {
|
|
72
|
+
path = pathForDatabaseName(dbName)
|
|
73
|
+
} catch (_: IOException) {
|
|
74
|
+
return null
|
|
249
75
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
DATABASES[name] = database
|
|
76
|
+
|
|
77
|
+
if (File(path).exists()) {
|
|
78
|
+
cachedDatabase[dbName]?.let {
|
|
79
|
+
return it
|
|
80
|
+
}
|
|
256
81
|
}
|
|
257
|
-
return database!!
|
|
258
|
-
}
|
|
259
82
|
|
|
260
|
-
|
|
261
|
-
val
|
|
262
|
-
|
|
83
|
+
cachedDatabase.remove(dbName)
|
|
84
|
+
val db = SQLite3Wrapper.open(path) ?: return null
|
|
85
|
+
cachedDatabase[dbName] = db
|
|
86
|
+
return db
|
|
263
87
|
}
|
|
264
88
|
|
|
265
|
-
private fun
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
"onDatabaseChange",
|
|
269
|
-
bundleOf(
|
|
270
|
-
"tableName" to tableName,
|
|
271
|
-
"rowId" to rowID,
|
|
272
|
-
"typeId" to when (operationType) {
|
|
273
|
-
9 -> SqlAction.DELETE.value
|
|
274
|
-
18 -> SqlAction.INSERT.value
|
|
275
|
-
23 -> SqlAction.UPDATE.value
|
|
276
|
-
else -> SqlAction.UNKNOWN.value
|
|
277
|
-
}
|
|
278
|
-
)
|
|
279
|
-
)
|
|
280
|
-
}
|
|
89
|
+
private fun execute(dbName: String, queries: List<Query>, readOnly: Boolean): List<Any> {
|
|
90
|
+
val db = openDatabase(dbName) ?: throw OpenDatabaseException(dbName)
|
|
91
|
+
return queries.map { db.executeSql(it.sql, it.args, readOnly) }
|
|
281
92
|
}
|
|
282
93
|
|
|
283
94
|
internal class SQLitePluginResult(
|
|
@@ -287,6 +98,4 @@ class SQLiteModule : Module() {
|
|
|
287
98
|
val insertId: Long,
|
|
288
99
|
val error: Throwable?
|
|
289
100
|
)
|
|
290
|
-
|
|
291
|
-
private class ReadOnlyException : Exception("could not prepare statement (23 not authorized)")
|
|
292
101
|
}
|