@op-engineering/op-sqlite 15.0.7 → 15.1.1

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.
Files changed (45) hide show
  1. package/android/CMakeLists.txt +1 -1
  2. package/android/build.gradle +1 -1
  3. package/android/cpp-adapter.cpp +1 -1
  4. package/android/src/main/java/com/op/sqlite/OPSQLiteModule.kt +7 -9
  5. package/cpp/DBHostObject.cpp +469 -677
  6. package/cpp/DBHostObject.h +56 -58
  7. package/cpp/DumbHostObject.cpp +1 -1
  8. package/cpp/DumbHostObject.h +12 -13
  9. package/cpp/OPSqlite.cpp +207 -0
  10. package/cpp/OPThreadPool.cpp +79 -79
  11. package/cpp/OPThreadPool.h +28 -28
  12. package/cpp/PreparedStatementHostObject.cpp +87 -136
  13. package/cpp/PreparedStatementHostObject.h +16 -28
  14. package/cpp/SmartHostObject.cpp +1 -1
  15. package/cpp/SmartHostObject.h +6 -7
  16. package/cpp/bridge.cpp +639 -633
  17. package/cpp/bridge.h +2 -2
  18. package/cpp/libsql/LICENSE.txt +9 -0
  19. package/cpp/libsql/bridge.cpp +2 -2
  20. package/cpp/libsql/{bridge.h → bridge.hpp} +4 -4
  21. package/cpp/macros.hpp +21 -0
  22. package/cpp/sqlcipher/LICENSE.txt +24 -0
  23. package/cpp/types.hpp +42 -0
  24. package/cpp/utils.cpp +320 -255
  25. package/cpp/{utils.h → utils.hpp} +9 -1
  26. package/ios/OPSQLite.mm +104 -106
  27. package/lib/module/functions.js +52 -44
  28. package/lib/module/functions.js.map +1 -1
  29. package/lib/module/index.js +1 -1
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/typescript/src/functions.d.ts +5 -1
  32. package/lib/typescript/src/functions.d.ts.map +1 -1
  33. package/lib/typescript/src/index.d.ts +1 -1
  34. package/lib/typescript/src/index.d.ts.map +1 -1
  35. package/lib/typescript/src/types.d.ts +12 -1
  36. package/lib/typescript/src/types.d.ts.map +1 -1
  37. package/op-sqlite.podspec +1 -1
  38. package/package.json +10 -8
  39. package/src/functions.ts +64 -54
  40. package/src/index.ts +1 -12
  41. package/src/types.ts +9 -1
  42. package/cpp/bindings.cpp +0 -202
  43. package/cpp/macros.h +0 -15
  44. package/cpp/types.h +0 -33
  45. /package/cpp/{bindings.h → OPSqlite.hpp} +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@op-engineering/op-sqlite",
3
- "version": "15.0.7",
4
- "description": "Next generation SQLite for React Native",
3
+ "version": "15.1.1",
4
+ "description": "Fastest SQLite for React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
7
7
  "react-native": "src/index",
@@ -48,7 +48,7 @@
48
48
  "sqlite"
49
49
  ],
50
50
  "repository": "https://github.com/OP-Engineering/op-sqlite",
51
- "author": "Oscar Franco <ospfranco@protonmail.com> (https://github.com/ospfranco)",
51
+ "author": "Oscar Franco <ospfranco@gmail.com> (https://github.com/ospfranco)",
52
52
  "license": "MIT",
53
53
  "bugs": {
54
54
  "url": "https://github.com/OP-Engineering/op-sqlite/issues"
@@ -59,11 +59,10 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "clang-format": "^1.8.0",
62
- "lefthook": "^1.5.5",
63
62
  "react": "19.1.1",
64
- "react-native": "0.81.0",
65
- "react-native-builder-bob": "^0.40.13",
66
- "typescript": "5.8.3"
63
+ "react-native": "0.82.1",
64
+ "react-native-builder-bob": "^0.40.15",
65
+ "typescript": "5.0.4"
67
66
  },
68
67
  "peerDependencies": {
69
68
  "react": "*",
@@ -110,5 +109,8 @@
110
109
  "type": "turbo-module",
111
110
  "version": "0.52.1"
112
111
  },
113
- "packageManager": "yarn@4.3.1"
112
+ "packageManager": "yarn@4.11.0",
113
+ "dependencies": {
114
+ "react-native-safe-area-context": "^5.6.2"
115
+ }
114
116
  }
package/src/functions.ts CHANGED
@@ -94,6 +94,18 @@ function enhanceDB(db: _InternalDB, options: DBParams): DB {
94
94
  delete: db.delete,
95
95
  attach: db.attach,
96
96
  detach: db.detach,
97
+ loadFile: db.loadFile,
98
+ updateHook: db.updateHook,
99
+ commitHook: db.commitHook,
100
+ rollbackHook: db.rollbackHook,
101
+ loadExtension: db.loadExtension,
102
+ getDbPath: db.getDbPath,
103
+ reactiveExecute: db.reactiveExecute,
104
+ sync: db.sync,
105
+ setReservedBytes: db.setReservedBytes,
106
+ getReservedBytes: db.getReservedBytes,
107
+ close: db.close,
108
+ flushPendingReactiveQueries: db.flushPendingReactiveQueries,
97
109
  executeBatch: async (
98
110
  commands: SQLBatchTuple[]
99
111
  ): Promise<BatchQueryResult> => {
@@ -141,17 +153,6 @@ function enhanceDB(db: _InternalDB, options: DBParams): DB {
141
153
  startNextTransaction();
142
154
  });
143
155
  },
144
- loadFile: db.loadFile,
145
- updateHook: db.updateHook,
146
- commitHook: db.commitHook,
147
- rollbackHook: db.rollbackHook,
148
- loadExtension: db.loadExtension,
149
- getDbPath: db.getDbPath,
150
- reactiveExecute: db.reactiveExecute,
151
- sync: db.sync,
152
- setReservedBytes: db.setReservedBytes,
153
- getReservedBytes: db.getReservedBytes,
154
- close: db.close,
155
156
  executeWithHostObjects: async (
156
157
  query: string,
157
158
  params?: Scalar[]
@@ -180,31 +181,31 @@ function enhanceDB(db: _InternalDB, options: DBParams): DB {
180
181
  return db.executeRaw(query, sanitizedParams as Scalar[]);
181
182
  },
182
183
  executeSync: (query: string, params?: Scalar[]): QueryResult => {
183
- const sanitizedParams = sanitizeArrayBuffersInArray(params);
184
-
185
- let intermediateResult = sanitizedParams
186
- ? db.executeSync(query, sanitizedParams as Scalar[])
184
+ let res = params
185
+ ? db.executeSync(query, sanitizeArrayBuffersInArray(params) as Scalar[])
187
186
  : db.executeSync(query);
188
187
 
189
- let rows: Record<string, Scalar>[] = [];
190
- for (let i = 0; i < (intermediateResult.rawRows?.length ?? 0); i++) {
191
- let row: Record<string, Scalar> = {};
192
- let rawRow = intermediateResult.rawRows![i]!;
193
- for (let j = 0; j < intermediateResult.columnNames!.length; j++) {
194
- let columnName = intermediateResult.columnNames![j]!;
195
- let value = rawRow[j]!;
188
+ if (!res.rows) {
189
+ let rows: Record<string, Scalar>[] = [];
190
+ for (let i = 0; i < (res.rawRows?.length ?? 0); i++) {
191
+ let row: Record<string, Scalar> = {};
192
+ let rawRow = res.rawRows![i]!;
193
+ for (let j = 0; j < res.columnNames!.length; j++) {
194
+ let columnName = res.columnNames![j]!;
195
+ let value = rawRow[j]!;
196
196
 
197
- row[columnName] = value;
197
+ row[columnName] = value;
198
+ }
199
+ rows.push(row);
198
200
  }
199
- rows.push(row);
200
- }
201
201
 
202
- let res = {
203
- ...intermediateResult,
204
- rows,
205
- };
202
+ delete res.rawRows;
206
203
 
207
- delete res.rawRows;
204
+ res = {
205
+ ...res,
206
+ rows,
207
+ };
208
+ }
208
209
 
209
210
  return res;
210
211
  },
@@ -218,32 +219,34 @@ function enhanceDB(db: _InternalDB, options: DBParams): DB {
218
219
  query: string,
219
220
  params?: Scalar[] | undefined
220
221
  ): Promise<QueryResult> => {
221
- const sanitizedParams = sanitizeArrayBuffersInArray(params);
222
-
223
- let intermediateResult = await db.execute(
224
- query,
225
- sanitizedParams as Scalar[]
226
- );
227
-
228
- let rows: Record<string, Scalar>[] = [];
229
- for (let i = 0; i < (intermediateResult.rawRows?.length ?? 0); i++) {
230
- let row: Record<string, Scalar> = {};
231
- let rawRow = intermediateResult.rawRows![i]!;
232
- for (let j = 0; j < intermediateResult.columnNames!.length; j++) {
233
- let columnName = intermediateResult.columnNames![j]!;
234
- let value = rawRow[j]!;
235
-
236
- row[columnName] = value;
222
+ let res = params
223
+ ? await db.execute(
224
+ query,
225
+ sanitizeArrayBuffersInArray(params) as Scalar[]
226
+ )
227
+ : await db.execute(query);
228
+
229
+ if (!res.rows) {
230
+ let rows: Record<string, Scalar>[] = [];
231
+ for (let i = 0; i < (res.rawRows?.length ?? 0); i++) {
232
+ let row: Record<string, Scalar> = {};
233
+ let rawRow = res.rawRows![i]!;
234
+ for (let j = 0; j < res.columnNames!.length; j++) {
235
+ let columnName = res.columnNames![j]!;
236
+ let value = rawRow[j]!;
237
+
238
+ row[columnName] = value;
239
+ }
240
+ rows.push(row);
237
241
  }
238
- rows.push(row);
239
- }
240
242
 
241
- let res = {
242
- ...intermediateResult,
243
- rows,
244
- };
243
+ delete res.rawRows;
245
244
 
246
- delete res.rawRows;
245
+ res = {
246
+ ...res,
247
+ rows,
248
+ };
249
+ }
247
250
 
248
251
  return res;
249
252
  },
@@ -416,11 +419,18 @@ export const open = (params: {
416
419
  return enhancedDb;
417
420
  };
418
421
 
422
+ export function openV2(params: { path: string; encryptionKey?: string }) {
423
+ const db = OPSQLite.openV2(params);
424
+ const enhancedDb = enhanceDB(db, params as any);
425
+
426
+ return enhancedDb;
427
+ }
428
+
419
429
  /**
420
430
  * Moves the database from the assets folder to the default path (check the docs) or to a custom path
421
431
  * It DOES NOT OVERWRITE the database if it already exists in the destination path
422
432
  * if you want to overwrite the database, you need to pass the overwrite flag as true
423
- * @param args object with the parameters for the operaiton
433
+ * @param args object with the parameters for the operation
424
434
  * @returns promise, rejects if failed to move the database, resolves if the operation was successful
425
435
  */
426
436
  export const moveAssetsDatabase = async (args: {
package/src/index.ts CHANGED
@@ -1,17 +1,6 @@
1
1
  import { NativeModules } from 'react-native';
2
2
 
3
- export {
4
- OPSQLite,
5
- open,
6
- openRemote,
7
- openSync,
8
- moveAssetsDatabase,
9
- getDylibPath,
10
- isSQLCipher,
11
- isLibsql,
12
- isIOSEmbedded,
13
- isIOSEmbeeded,
14
- } from './functions';
3
+ export * from './functions';
15
4
  export { Storage } from './Storage';
16
5
  export type {
17
6
  Scalar,
package/src/types.ts CHANGED
@@ -269,7 +269,7 @@ export type DB = {
269
269
  */
270
270
  executeRawSync: (query: string, params?: Scalar[]) => any[];
271
271
  /**
272
- * Get's the absolute path to the db file. Useful for debugging on local builds and for attaching the DB from users devices
272
+ * Gets the absolute path to the db file. Useful for debugging on local builds and for attaching the DB from users devices
273
273
  */
274
274
  getDbPath: (location?: string) => string;
275
275
  /**
@@ -294,6 +294,13 @@ export type DB = {
294
294
  sync: () => void;
295
295
  setReservedBytes: (reservedBytes: number) => void;
296
296
  getReservedBytes: () => number;
297
+ /**
298
+ * If you have changed any of the tables outside of a transaction then the reactive queries will not fire on their own
299
+ * This method allows to flush the pending queue of changes. Useful when using Drizzle or other ORM that do not
300
+ * use the db.transaction method internally
301
+ * @returns void
302
+ */
303
+ flushPendingReactiveQueries: () => Promise<void>;
297
304
  };
298
305
 
299
306
  export type DBParams = {
@@ -310,6 +317,7 @@ export type OPSQLiteProxy = {
310
317
  location?: string;
311
318
  encryptionKey?: string;
312
319
  }) => _InternalDB;
320
+ openV2: (options: { path: string; encryptionKey?: string }) => _InternalDB;
313
321
  openRemote: (options: { url: string; authToken: string }) => _InternalDB;
314
322
  openSync: (options: DBParams) => _InternalDB;
315
323
  isSQLCipher: () => boolean;
package/cpp/bindings.cpp DELETED
@@ -1,202 +0,0 @@
1
- #include "bindings.h"
2
- #include "DBHostObject.h"
3
- #include "DumbHostObject.h"
4
- #include "OPThreadPool.h"
5
- #ifdef OP_SQLITE_USE_LIBSQL
6
- #include "libsql/bridge.h"
7
- #else
8
- #include "bridge.h"
9
- #endif
10
- #include "logs.h"
11
- #include "macros.h"
12
- #include "utils.h"
13
- #include <iostream>
14
- #include <string>
15
- #include <unordered_map>
16
- #include <vector>
17
-
18
- namespace opsqlite {
19
-
20
- namespace jsi = facebook::jsi;
21
-
22
- std::string _base_path;
23
- std::string _crsqlite_path;
24
- std::string _sqlite_vec_path;
25
- std::vector<std::shared_ptr<DBHostObject>> dbs;
26
-
27
- // React native will try to clean the module on JS context invalidation
28
- // (CodePush/Hot Reload) The clearState function is called
29
- void invalidate() {
30
- for (const auto &db : dbs) {
31
- db->invalidate();
32
- }
33
-
34
- // Clear our existing vector of shared pointers so they can be garbage
35
- // collected
36
- dbs.clear();
37
- }
38
-
39
- void install(jsi::Runtime &rt,
40
- const std::shared_ptr<react::CallInvoker> &invoker,
41
- const char *base_path, const char *crsqlite_path,
42
- const char *sqlite_vec_path) {
43
- _base_path = std::string(base_path);
44
- _crsqlite_path = std::string(crsqlite_path);
45
- _sqlite_vec_path = std::string(sqlite_vec_path);
46
-
47
- auto open = HOST_STATIC_FN("open") {
48
- jsi::Object options = args[0].asObject(rt);
49
- std::string name =
50
- options.getProperty(rt, "name").asString(rt).utf8(rt);
51
- std::string path = std::string(_base_path);
52
- std::string location;
53
- std::string encryption_key;
54
-
55
- if (options.hasProperty(rt, "location")) {
56
- location =
57
- options.getProperty(rt, "location").asString(rt).utf8(rt);
58
- }
59
-
60
- if (options.hasProperty(rt, "encryptionKey")) {
61
- encryption_key =
62
- options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
63
- }
64
-
65
- #ifdef OP_SQLITE_USE_SQLCIPHER
66
- if (encryption_key.empty()) {
67
- log_to_console(rt, "Encryption key is missing for SQLCipher");
68
- }
69
- #endif
70
-
71
- if (!location.empty()) {
72
- if (location == ":memory:") {
73
- path = ":memory:";
74
- } else if (location.rfind('/', 0) == 0) {
75
- path = location;
76
- } else {
77
- path = path + "/" + location;
78
- }
79
- }
80
-
81
- std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
82
- rt, path, invoker, name, path, _crsqlite_path, _sqlite_vec_path,
83
- encryption_key);
84
- dbs.emplace_back(db);
85
- return jsi::Object::createFromHostObject(rt, db);
86
- });
87
-
88
- auto is_sqlcipher = HOST_STATIC_FN("isSQLCipher") {
89
- #ifdef OP_SQLITE_USE_SQLCIPHER
90
- return true;
91
- #else
92
- return false;
93
- #endif
94
- });
95
-
96
- auto is_ios_embedded = HOST_STATIC_FN("isIOSEmbedded") {
97
- #ifdef OP_SQLITE_USE_PHONE_VERSION
98
- return true;
99
- #else
100
- return false;
101
- #endif
102
- });
103
-
104
- auto is_libsql = HOST_STATIC_FN("isLibsql") {
105
- #ifdef OP_SQLITE_USE_LIBSQL
106
- return true;
107
- #else
108
- return false;
109
- #endif
110
- });
111
-
112
- #ifdef OP_SQLITE_USE_LIBSQL
113
- auto open_remote = HOST_STATIC_FN("openRemote") {
114
- jsi::Object options = args[0].asObject(rt);
115
-
116
- std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
117
-
118
- std::string auth_token =
119
- options.getProperty(rt, "authToken").asString(rt).utf8(rt);
120
-
121
- std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
122
- rt, url, auth_token, invoker);
123
-
124
- return jsi::Object::createFromHostObject(rt, db);
125
- });
126
-
127
- auto open_sync = HOST_STATIC_FN("openSync") {
128
- jsi::Object options = args[0].asObject(rt);
129
- std::string name =
130
- options.getProperty(rt, "name").asString(rt).utf8(rt);
131
- std::string path = std::string(_base_path);
132
- std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
133
- std::string auth_token =
134
- options.getProperty(rt, "authToken").asString(rt).utf8(rt);
135
-
136
- int sync_interval = 0;
137
- if (options.hasProperty(rt, "libsqlSyncInterval")) {
138
- sync_interval = static_cast<int>(
139
- options.getProperty(rt, "libsqlSyncInterval").asNumber());
140
- }
141
-
142
- bool offline = false;
143
- if (options.hasProperty(rt, "libsqlOffline")) {
144
- offline = options.getProperty(rt, "libsqlOffline").asBool();
145
- }
146
-
147
- std::string encryption_key;
148
- if (options.hasProperty(rt, "encryptionKey")) {
149
- encryption_key =
150
- options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
151
- }
152
-
153
- std::string remote_encryption_key;
154
- if (options.hasProperty(rt, "remoteEncryptionKey")) {
155
- remote_encryption_key =
156
- options.getProperty(rt, "remoteEncryptionKey").asString(rt).utf8(rt);
157
- }
158
-
159
- std::string location;
160
- if (options.hasProperty(rt, "location")) {
161
- location =
162
- options.getProperty(rt, "location").asString(rt).utf8(rt);
163
- }
164
- if (!location.empty()) {
165
- if (location == ":memory:") {
166
- path = ":memory:";
167
- } else if (location.rfind("/", 0) == 0) {
168
- path = location;
169
- } else {
170
- path = path + "/" + location;
171
- }
172
- }
173
-
174
- std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
175
- rt, invoker, name, path, url, auth_token, sync_interval, offline, encryption_key, remote_encryption_key);
176
- return jsi::Object::createFromHostObject(rt, db);
177
- });
178
- #endif
179
-
180
- jsi::Object module = jsi::Object(rt);
181
- module.setProperty(rt, "open", std::move(open));
182
- module.setProperty(rt, "isSQLCipher", std::move(is_sqlcipher));
183
- module.setProperty(rt, "isLibsql", std::move(is_libsql));
184
- module.setProperty(rt, "isIOSEmbedded", std::move(is_ios_embedded));
185
- #ifdef OP_SQLITE_USE_LIBSQL
186
- module.setProperty(rt, "openRemote", std::move(open_remote));
187
- module.setProperty(rt, "openSync", std::move(open_sync));
188
- #endif
189
-
190
- rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
191
- }
192
-
193
- void expoUpdatesWorkaround(const char *base_path) {
194
- #ifdef OP_SQLITE_USE_LIBSQL
195
- std::string path = std::string(base_path);
196
- // Open a DB before anything else so that expo-updates does not mess up the
197
- // configuration
198
- opsqlite_libsql_open("__dummy", path, "");
199
- #endif
200
- }
201
-
202
- } // namespace opsqlite
package/cpp/macros.h DELETED
@@ -1,15 +0,0 @@
1
- #pragma once
2
-
3
- #define HOSTFN(name) \
4
- jsi::Function::createFromHostFunction( \
5
- rt, \
6
- jsi::PropNameID::forAscii(rt, name), \
7
- 0, \
8
- [=, this](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value
9
-
10
- #define HOST_STATIC_FN(name) \
11
- jsi::Function::createFromHostFunction( \
12
- rt, \
13
- jsi::PropNameID::forAscii(rt, name), \
14
- 0, \
15
- [=](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value
package/cpp/types.h DELETED
@@ -1,33 +0,0 @@
1
- #pragma once
2
-
3
- #include <memory>
4
- #include <string>
5
- #include <variant>
6
- #include <vector>
7
-
8
- struct ArrayBuffer {
9
- std::shared_ptr<uint8_t> data;
10
- size_t size;
11
- };
12
-
13
- using JSVariant = std::variant<nullptr_t, bool, int, double, long, long long,
14
- std::string, ArrayBuffer>;
15
-
16
- struct BridgeResult {
17
- std::string message;
18
- int affectedRows;
19
- double insertId;
20
- std::vector<std::vector<JSVariant>> rows;
21
- std::vector<std::string> column_names;
22
- };
23
-
24
- struct BatchResult {
25
- std::string message;
26
- int affectedRows;
27
- int commands;
28
- };
29
-
30
- struct BatchArguments {
31
- std::string sql;
32
- std::vector<JSVariant> params;
33
- };
File without changes