@op-engineering/op-sqlite 1.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/LICENSE +7 -0
- package/README.md +274 -0
- package/android/.project +17 -0
- package/android/.settings/org.eclipse.buildship.core.prefs +13 -0
- package/android/CMakeLists.txt +57 -0
- package/android/build.gradle +127 -0
- package/android/cpp-adapter.cpp +42 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/op/sqlite/OPSQLiteBridge.java +29 -0
- package/android/src/main/java/com/op/sqlite/OPSQLiteModule.java +46 -0
- package/android/src/main/java/com/op/sqlite/OPSQLitePackage.java +26 -0
- package/cpp/DynamicHostObject.cpp +30 -0
- package/cpp/DynamicHostObject.h +30 -0
- package/cpp/ThreadPool.cpp +95 -0
- package/cpp/ThreadPool.h +46 -0
- package/cpp/bindings.cpp +430 -0
- package/cpp/bindings.h +13 -0
- package/cpp/bridge.cpp +502 -0
- package/cpp/bridge.h +34 -0
- package/cpp/logs.h +38 -0
- package/cpp/macros.h +16 -0
- package/cpp/sqlbatchexecutor.cpp +94 -0
- package/cpp/sqlbatchexecutor.h +28 -0
- package/cpp/sqlite3.c +252611 -0
- package/cpp/sqlite3.h +13257 -0
- package/cpp/utils.cpp +218 -0
- package/cpp/utils.h +55 -0
- package/ios/OPSQLite.h +8 -0
- package/ios/OPSQLite.mm +63 -0
- package/ios/OPSQLite.xcodeproj/project.pbxproj +275 -0
- package/lib/commonjs/index.js +190 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/index.js +183 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/index.d.ts +108 -0
- package/op-sqlite.podspec +39 -0
- package/package.json +79 -0
- package/src/index.ts +374 -0
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@op-engineering/op-sqlite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Next generation SQLite for React Native",
|
|
5
|
+
"main": "lib/commonjs/index",
|
|
6
|
+
"module": "lib/module/index",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index",
|
|
9
|
+
"source": "src/index",
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"lib",
|
|
13
|
+
"android",
|
|
14
|
+
"ios",
|
|
15
|
+
"cpp",
|
|
16
|
+
"op-sqlite.podspec",
|
|
17
|
+
"!lib/typescript/example",
|
|
18
|
+
"!android/build",
|
|
19
|
+
"!android/.cxx",
|
|
20
|
+
"!ios/build",
|
|
21
|
+
"!**/__tests__",
|
|
22
|
+
"!**/__fixtures__",
|
|
23
|
+
"!**/__mocks__"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"typescript": "tsc --noEmit",
|
|
27
|
+
"prepare": "bob build",
|
|
28
|
+
"example": "yarn --cwd example",
|
|
29
|
+
"pods": "cd example && npx pod-install --quiet",
|
|
30
|
+
"bootstrap": "yarn example && yarn && yarn pods",
|
|
31
|
+
"bump": "./bump-version.sh"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"react-native",
|
|
35
|
+
"ios",
|
|
36
|
+
"android"
|
|
37
|
+
],
|
|
38
|
+
"repository": "https://github.com/OP-Engineering/op-sqlite",
|
|
39
|
+
"author": "Oscar Franco <ospfranco@protonmail.com> (https://github.com/ospfranco)",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/OP-Engineering/op-sqlite/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/OP-Engineering/op-sqlite#readme",
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"react": "18.2.0",
|
|
50
|
+
"react-native": "0.72.6",
|
|
51
|
+
"react-native-builder-bob": "^0.18.2",
|
|
52
|
+
"typescript": "^4.8.4"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": "*",
|
|
56
|
+
"react-native": "*"
|
|
57
|
+
},
|
|
58
|
+
"prettier": {
|
|
59
|
+
"quoteProps": "consistent",
|
|
60
|
+
"singleQuote": true,
|
|
61
|
+
"tabWidth": 2,
|
|
62
|
+
"trailingComma": "es5",
|
|
63
|
+
"useTabs": false
|
|
64
|
+
},
|
|
65
|
+
"react-native-builder-bob": {
|
|
66
|
+
"source": "src",
|
|
67
|
+
"output": "lib",
|
|
68
|
+
"targets": [
|
|
69
|
+
"commonjs",
|
|
70
|
+
"module",
|
|
71
|
+
[
|
|
72
|
+
"typescript",
|
|
73
|
+
{
|
|
74
|
+
"project": "tsconfig.build.json"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { NativeModules } from 'react-native';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
function nativeCallSyncHook(): unknown;
|
|
5
|
+
var __OPSQLiteProxy: object | undefined;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (global.__OPSQLiteProxy == null) {
|
|
9
|
+
const OPSQLiteModule = NativeModules.OPSQLite;
|
|
10
|
+
|
|
11
|
+
if (OPSQLiteModule == null) {
|
|
12
|
+
throw new Error('Base module not found. Maybe try rebuilding the app.');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Check if we are running on-device (JSI)
|
|
16
|
+
if (global.nativeCallSyncHook == null || OPSQLiteModule.install == null) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
'Failed to install op-sqlite: React Native is not running on-device. OPSQLite can only be used when synchronous method invocations (JSI) are possible. If you are using a remote debugger (e.g. Chrome), switch to an on-device debugger (e.g. Flipper) instead.'
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Call the synchronous blocking install() function
|
|
23
|
+
const result = OPSQLiteModule.install();
|
|
24
|
+
if (result !== true) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Failed to install op-sqlite: The native OPSQLite Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Check again if the constructor now exists. If not, throw an error.
|
|
31
|
+
if (global.__OPSQLiteProxy == null) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
'Failed to install op-sqlite, the native initializer function does not exist. Are you trying to use OPSQLite from different JS Runtimes?'
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const proxy = global.__OPSQLiteProxy;
|
|
39
|
+
export const OPSQLite = proxy as ISQLite;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Object returned by SQL Query executions {
|
|
43
|
+
* insertId: Represent the auto-generated row id if applicable
|
|
44
|
+
* rowsAffected: Number of affected rows if result of a update query
|
|
45
|
+
* message: if status === 1, here you will find error description
|
|
46
|
+
* rows: if status is undefined or 0 this object will contain the query results
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* @interface QueryResult
|
|
50
|
+
*/
|
|
51
|
+
export type QueryResult = {
|
|
52
|
+
insertId?: number;
|
|
53
|
+
rowsAffected: number;
|
|
54
|
+
rows?: {
|
|
55
|
+
/** Raw array with all dataset */
|
|
56
|
+
_array: any[];
|
|
57
|
+
/** The lengh of the dataset */
|
|
58
|
+
length: number;
|
|
59
|
+
/** A convenience function to acess the index based the row object
|
|
60
|
+
* @param idx the row index
|
|
61
|
+
* @returns the row structure identified by column names
|
|
62
|
+
*/
|
|
63
|
+
item: (idx: number) => any;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Query metadata, avaliable only for select query results
|
|
67
|
+
*/
|
|
68
|
+
metadata?: ColumnMetadata[];
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Column metadata
|
|
73
|
+
* Describes some information about columns fetched by the query
|
|
74
|
+
*/
|
|
75
|
+
export type ColumnMetadata = {
|
|
76
|
+
/** The name used for this column for this resultset */
|
|
77
|
+
name: string;
|
|
78
|
+
/** The declared column type for this column, when fetched directly from a table or a View resulting from a table column. "UNKNOWN" for dynamic values, like function returned ones. */
|
|
79
|
+
type: string;
|
|
80
|
+
/**
|
|
81
|
+
* The index for this column for this resultset*/
|
|
82
|
+
index: number;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Allows the execution of bulk of sql commands
|
|
87
|
+
* inside a transaction
|
|
88
|
+
* If a single query must be executed many times with different arguments, its preferred
|
|
89
|
+
* to declare it a single time, and use an array of array parameters.
|
|
90
|
+
*/
|
|
91
|
+
export type SQLBatchTuple = [string] | [string, Array<any> | Array<Array<any>>];
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* status: 0 or undefined for correct execution, 1 for error
|
|
95
|
+
* message: if status === 1, here you will find error description
|
|
96
|
+
* rowsAffected: Number of affected rows if status == 0
|
|
97
|
+
*/
|
|
98
|
+
export type BatchQueryResult = {
|
|
99
|
+
rowsAffected?: number;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Result of loading a file and executing every line as a SQL command
|
|
104
|
+
* Similar to BatchQueryResult
|
|
105
|
+
*/
|
|
106
|
+
export interface FileLoadResult extends BatchQueryResult {
|
|
107
|
+
commands?: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface Transaction {
|
|
111
|
+
commit: () => QueryResult;
|
|
112
|
+
execute: (query: string, params?: any[]) => QueryResult;
|
|
113
|
+
executeAsync: (
|
|
114
|
+
query: string,
|
|
115
|
+
params?: any[] | undefined
|
|
116
|
+
) => Promise<QueryResult>;
|
|
117
|
+
rollback: () => QueryResult;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface PendingTransaction {
|
|
121
|
+
/*
|
|
122
|
+
* The start function should not throw or return a promise because the
|
|
123
|
+
* queue just calls it and does not monitor for failures or completions.
|
|
124
|
+
*
|
|
125
|
+
* It should catch any errors and call the resolve or reject of the wrapping
|
|
126
|
+
* promise when complete.
|
|
127
|
+
*
|
|
128
|
+
* It should also automatically commit or rollback the transaction if needed
|
|
129
|
+
*/
|
|
130
|
+
start: () => void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface ISQLite {
|
|
134
|
+
open: (dbName: string, location?: string) => void;
|
|
135
|
+
close: (dbName: string) => void;
|
|
136
|
+
delete: (dbName: string, location?: string) => void;
|
|
137
|
+
attach: (
|
|
138
|
+
mainDbName: string,
|
|
139
|
+
dbNameToAttach: string,
|
|
140
|
+
alias: string,
|
|
141
|
+
location?: string
|
|
142
|
+
) => void;
|
|
143
|
+
detach: (mainDbName: string, alias: string) => void;
|
|
144
|
+
transaction: (
|
|
145
|
+
dbName: string,
|
|
146
|
+
fn: (tx: Transaction) => Promise<void> | void
|
|
147
|
+
) => Promise<void>;
|
|
148
|
+
execute: (dbName: string, query: string, params?: any[]) => QueryResult;
|
|
149
|
+
executeAsync: (
|
|
150
|
+
dbName: string,
|
|
151
|
+
query: string,
|
|
152
|
+
params?: any[]
|
|
153
|
+
) => Promise<QueryResult>;
|
|
154
|
+
executeBatch: (dbName: string, commands: SQLBatchTuple[]) => BatchQueryResult;
|
|
155
|
+
executeBatchAsync: (
|
|
156
|
+
dbName: string,
|
|
157
|
+
commands: SQLBatchTuple[]
|
|
158
|
+
) => Promise<BatchQueryResult>;
|
|
159
|
+
loadFile: (dbName: string, location: string) => Promise<FileLoadResult>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const locks: Record<
|
|
163
|
+
string,
|
|
164
|
+
{ queue: PendingTransaction[]; inProgress: boolean }
|
|
165
|
+
> = {};
|
|
166
|
+
|
|
167
|
+
// Enhance some host functions
|
|
168
|
+
|
|
169
|
+
// Add 'item' function to result object to allow the sqlite-storage typeorm driver to work
|
|
170
|
+
const enhanceQueryResult = (result: QueryResult): void => {
|
|
171
|
+
// Add 'item' function to result object to allow the sqlite-storage typeorm driver to work
|
|
172
|
+
if (result.rows == null) {
|
|
173
|
+
result.rows = {
|
|
174
|
+
_array: [],
|
|
175
|
+
length: 0,
|
|
176
|
+
item: (idx: number) => result.rows._array[idx],
|
|
177
|
+
};
|
|
178
|
+
} else {
|
|
179
|
+
result.rows.item = (idx: number) => result.rows._array[idx];
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const _open = OPSQLite.open;
|
|
184
|
+
OPSQLite.open = (dbName: string, location?: string) => {
|
|
185
|
+
_open(dbName, location);
|
|
186
|
+
|
|
187
|
+
locks[dbName] = {
|
|
188
|
+
queue: [],
|
|
189
|
+
inProgress: false,
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const _close = OPSQLite.close;
|
|
194
|
+
OPSQLite.close = (dbName: string) => {
|
|
195
|
+
_close(dbName);
|
|
196
|
+
delete locks[dbName];
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const _execute = OPSQLite.execute;
|
|
200
|
+
OPSQLite.execute = (
|
|
201
|
+
dbName: string,
|
|
202
|
+
query: string,
|
|
203
|
+
params?: any[] | undefined
|
|
204
|
+
): QueryResult => {
|
|
205
|
+
const result = _execute(dbName, query, params);
|
|
206
|
+
enhanceQueryResult(result);
|
|
207
|
+
return result;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const _executeAsync = OPSQLite.executeAsync;
|
|
211
|
+
OPSQLite.executeAsync = async (
|
|
212
|
+
dbName: string,
|
|
213
|
+
query: string,
|
|
214
|
+
params?: any[] | undefined
|
|
215
|
+
): Promise<QueryResult> => {
|
|
216
|
+
const res = await _executeAsync(dbName, query, params);
|
|
217
|
+
enhanceQueryResult(res);
|
|
218
|
+
return res;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
OPSQLite.transaction = async (
|
|
222
|
+
dbName: string,
|
|
223
|
+
fn: (tx: Transaction) => Promise<void>
|
|
224
|
+
): Promise<void> => {
|
|
225
|
+
if (!locks[dbName]) {
|
|
226
|
+
throw Error(`SQLite Error: No lock found on db: ${dbName}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let isFinalized = false;
|
|
230
|
+
|
|
231
|
+
// Local transaction context object implementation
|
|
232
|
+
const execute = (query: string, params?: any[]): QueryResult => {
|
|
233
|
+
if (isFinalized) {
|
|
234
|
+
throw Error(
|
|
235
|
+
`SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return OPSQLite.execute(dbName, query, params);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const executeAsync = (query: string, params?: any[] | undefined) => {
|
|
242
|
+
if (isFinalized) {
|
|
243
|
+
throw Error(
|
|
244
|
+
`SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
return OPSQLite.executeAsync(dbName, query, params);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const commit = () => {
|
|
251
|
+
if (isFinalized) {
|
|
252
|
+
throw Error(
|
|
253
|
+
`SQLite Error: Cannot execute commit on finalized transaction: ${dbName}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
const result = OPSQLite.execute(dbName, 'COMMIT');
|
|
257
|
+
isFinalized = true;
|
|
258
|
+
return result;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const rollback = () => {
|
|
262
|
+
if (isFinalized) {
|
|
263
|
+
throw Error(
|
|
264
|
+
`SQLite Error: Cannot execute rollback on finalized transaction: ${dbName}`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const result = OPSQLite.execute(dbName, 'ROLLBACK');
|
|
268
|
+
isFinalized = true;
|
|
269
|
+
return result;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
async function run() {
|
|
273
|
+
try {
|
|
274
|
+
await OPSQLite.executeAsync(dbName, 'BEGIN TRANSACTION');
|
|
275
|
+
|
|
276
|
+
await fn({
|
|
277
|
+
commit,
|
|
278
|
+
execute,
|
|
279
|
+
executeAsync,
|
|
280
|
+
rollback,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
if (!isFinalized) {
|
|
284
|
+
commit();
|
|
285
|
+
}
|
|
286
|
+
} catch (executionError) {
|
|
287
|
+
if (!isFinalized) {
|
|
288
|
+
try {
|
|
289
|
+
rollback();
|
|
290
|
+
} catch (rollbackError) {
|
|
291
|
+
throw rollbackError;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
throw executionError;
|
|
296
|
+
} finally {
|
|
297
|
+
locks[dbName].inProgress = false;
|
|
298
|
+
isFinalized = false;
|
|
299
|
+
startNextTransaction(dbName);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return await new Promise((resolve, reject) => {
|
|
304
|
+
const tx: PendingTransaction = {
|
|
305
|
+
start: () => {
|
|
306
|
+
run().then(resolve).catch(reject);
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
locks[dbName].queue.push(tx);
|
|
311
|
+
startNextTransaction(dbName);
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const startNextTransaction = (dbName: string) => {
|
|
316
|
+
if (!locks[dbName]) {
|
|
317
|
+
throw Error(`Lock not found for db: ${dbName}`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (locks[dbName].inProgress) {
|
|
321
|
+
// Transaction is already in process bail out
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (locks[dbName].queue.length) {
|
|
326
|
+
locks[dbName].inProgress = true;
|
|
327
|
+
const tx = locks[dbName].queue.shift();
|
|
328
|
+
setImmediate(() => {
|
|
329
|
+
tx.start();
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
export type OPSQLiteConnection = {
|
|
335
|
+
close: () => void;
|
|
336
|
+
delete: () => void;
|
|
337
|
+
attach: (dbNameToAttach: string, alias: string, location?: string) => void;
|
|
338
|
+
detach: (alias: string) => void;
|
|
339
|
+
transaction: (fn: (tx: Transaction) => Promise<void> | void) => Promise<void>;
|
|
340
|
+
execute: (query: string, params?: any[]) => QueryResult;
|
|
341
|
+
executeAsync: (query: string, params?: any[]) => Promise<QueryResult>;
|
|
342
|
+
executeBatch: (commands: SQLBatchTuple[]) => BatchQueryResult;
|
|
343
|
+
executeBatchAsync: (commands: SQLBatchTuple[]) => Promise<BatchQueryResult>;
|
|
344
|
+
loadFile: (location: string) => Promise<FileLoadResult>;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export const open = (options: {
|
|
348
|
+
name: string;
|
|
349
|
+
location?: string;
|
|
350
|
+
}): OPSQLiteConnection => {
|
|
351
|
+
OPSQLite.open(options.name, options.location);
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
close: () => OPSQLite.close(options.name),
|
|
355
|
+
delete: () => OPSQLite.delete(options.name, options.location),
|
|
356
|
+
attach: (dbNameToAttach: string, alias: string, location?: string) =>
|
|
357
|
+
OPSQLite.attach(options.name, dbNameToAttach, alias, location),
|
|
358
|
+
detach: (alias: string) => OPSQLite.detach(options.name, alias),
|
|
359
|
+
transaction: (fn: (tx: Transaction) => Promise<void> | void) =>
|
|
360
|
+
OPSQLite.transaction(options.name, fn),
|
|
361
|
+
execute: (query: string, params?: any[] | undefined): QueryResult =>
|
|
362
|
+
OPSQLite.execute(options.name, query, params),
|
|
363
|
+
executeAsync: (
|
|
364
|
+
query: string,
|
|
365
|
+
params?: any[] | undefined
|
|
366
|
+
): Promise<QueryResult> =>
|
|
367
|
+
OPSQLite.executeAsync(options.name, query, params),
|
|
368
|
+
executeBatch: (commands: SQLBatchTuple[]) =>
|
|
369
|
+
OPSQLite.executeBatch(options.name, commands),
|
|
370
|
+
executeBatchAsync: (commands: SQLBatchTuple[]) =>
|
|
371
|
+
OPSQLite.executeBatchAsync(options.name, commands),
|
|
372
|
+
loadFile: (location: string) => OPSQLite.loadFile(options.name, location),
|
|
373
|
+
};
|
|
374
|
+
};
|