@op-engineering/op-sqlite 0.0.0-resolution-test

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 (99) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +31 -0
  3. package/android/.project +17 -0
  4. package/android/.settings/org.eclipse.buildship.core.prefs +13 -0
  5. package/android/CMakeLists.txt +141 -0
  6. package/android/build.gradle +266 -0
  7. package/android/c_sources/tokenizers.cpp +88 -0
  8. package/android/c_sources/tokenizers.h +15 -0
  9. package/android/cpp-adapter.cpp +46 -0
  10. package/android/gradle.properties +1 -0
  11. package/android/jniLibs/arm64-v8a/libsql_experimental.a +0 -0
  12. package/android/jniLibs/armeabi-v7a/libsql_experimental.a +0 -0
  13. package/android/jniLibs/x86/libsql_experimental.a +0 -0
  14. package/android/jniLibs/x86_64/libsql_experimental.a +0 -0
  15. package/android/src/main/AndroidManifest.xml +1 -0
  16. package/android/src/main/java/com/op/sqlite/OPSQLiteBridge.kt +37 -0
  17. package/android/src/main/java/com/op/sqlite/OPSQLiteModule.kt +119 -0
  18. package/android/src/main/java/com/op/sqlite/OPSQLitePackage.kt +18 -0
  19. package/android/src/main/jniLibs/arm64-v8a/libcrsqlite.so +0 -0
  20. package/android/src/main/jniLibs/arm64-v8a/libsqlite_vec.so +0 -0
  21. package/android/src/main/jniLibs/armeabi-v7a/libcrsqlite.so +0 -0
  22. package/android/src/main/jniLibs/armeabi-v7a/libsqlite_vec.so +0 -0
  23. package/android/src/main/jniLibs/x86/libcrsqlite.so +0 -0
  24. package/android/src/main/jniLibs/x86/libsqlite_vec.so +0 -0
  25. package/android/src/main/jniLibs/x86_64/libcrsqlite.so +0 -0
  26. package/android/src/main/jniLibs/x86_64/libsqlite_vec.so +0 -0
  27. package/android/src/paper/java/com/op/sqlite/NativeOPSQLiteSpec.java +77 -0
  28. package/cpp/DBHostObject.cpp +852 -0
  29. package/cpp/DBHostObject.h +99 -0
  30. package/cpp/DumbHostObject.cpp +72 -0
  31. package/cpp/DumbHostObject.h +36 -0
  32. package/cpp/OPThreadPool.cpp +120 -0
  33. package/cpp/OPThreadPool.h +44 -0
  34. package/cpp/PreparedStatementHostObject.cpp +151 -0
  35. package/cpp/PreparedStatementHostObject.h +59 -0
  36. package/cpp/SmartHostObject.cpp +34 -0
  37. package/cpp/SmartHostObject.h +24 -0
  38. package/cpp/bindings.cpp +182 -0
  39. package/cpp/bindings.h +19 -0
  40. package/cpp/bridge.cpp +873 -0
  41. package/cpp/bridge.h +80 -0
  42. package/cpp/libsql/bridge.cpp +738 -0
  43. package/cpp/libsql/bridge.h +85 -0
  44. package/cpp/libsql/libsql.h +172 -0
  45. package/cpp/logs.h +40 -0
  46. package/cpp/macros.h +15 -0
  47. package/cpp/sqlcipher/sqlite3.c +262970 -0
  48. package/cpp/sqlcipher/sqlite3.h +13485 -0
  49. package/cpp/sqlite3.c +261454 -0
  50. package/cpp/sqlite3.h +13715 -0
  51. package/cpp/types.h +33 -0
  52. package/cpp/utils.cpp +327 -0
  53. package/cpp/utils.h +47 -0
  54. package/generate_tokenizers_header_file.rb +29 -0
  55. package/ios/OPSQLite.h +7 -0
  56. package/ios/OPSQLite.mm +157 -0
  57. package/ios/OPSQLite.xcodeproj/project.pbxproj +275 -0
  58. package/ios/crsqlite.xcframework/Info.plist +46 -0
  59. package/ios/crsqlite.xcframework/ios-arm64/crsqlite.framework/Info.plist +24 -0
  60. package/ios/crsqlite.xcframework/ios-arm64/crsqlite.framework/crsqlite +0 -0
  61. package/ios/crsqlite.xcframework/ios-arm64_x86_64-simulator/crsqlite.framework/Info.plist +24 -0
  62. package/ios/crsqlite.xcframework/ios-arm64_x86_64-simulator/crsqlite.framework/crsqlite +0 -0
  63. package/ios/libsql.xcframework/Info.plist +48 -0
  64. package/ios/libsql.xcframework/ios-arm64/Headers/libsql.h +172 -0
  65. package/ios/libsql.xcframework/ios-arm64/libsql_experimental.a +0 -0
  66. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/Headers/libsql.h +172 -0
  67. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/libsql_experimental.a +0 -0
  68. package/ios/sqlitevec.xcframework/Info.plist +71 -0
  69. package/ios/sqlitevec.xcframework/ios-arm64/sqlitevec.framework/Info.plist +24 -0
  70. package/ios/sqlitevec.xcframework/ios-arm64/sqlitevec.framework/sqlitevec +0 -0
  71. package/ios/sqlitevec.xcframework/ios-arm64_x86_64-simulator/sqlitevec.framework/Info.plist +24 -0
  72. package/ios/sqlitevec.xcframework/ios-arm64_x86_64-simulator/sqlitevec.framework/sqlitevec +0 -0
  73. package/ios/sqlitevec.xcframework/tvos-arm64/sqlitevec.framework/Info.plist +24 -0
  74. package/ios/sqlitevec.xcframework/tvos-arm64/sqlitevec.framework/sqlitevec +0 -0
  75. package/ios/sqlitevec.xcframework/tvos-arm64_x86_64-simulator/sqlitevec.framework/Info.plist +24 -0
  76. package/ios/sqlitevec.xcframework/tvos-arm64_x86_64-simulator/sqlitevec.framework/sqlitevec +0 -0
  77. package/lib/commonjs/NativeOPSQLite.js +9 -0
  78. package/lib/commonjs/NativeOPSQLite.js.map +1 -0
  79. package/lib/commonjs/Storage.js +60 -0
  80. package/lib/commonjs/Storage.js.map +1 -0
  81. package/lib/commonjs/index.js +365 -0
  82. package/lib/commonjs/index.js.map +1 -0
  83. package/lib/module/NativeOPSQLite.js +3 -0
  84. package/lib/module/NativeOPSQLite.js.map +1 -0
  85. package/lib/module/Storage.js +53 -0
  86. package/lib/module/Storage.js.map +1 -0
  87. package/lib/module/index.js +340 -0
  88. package/lib/module/index.js.map +1 -0
  89. package/lib/typescript/src/NativeOPSQLite.d.ts +15 -0
  90. package/lib/typescript/src/NativeOPSQLite.d.ts.map +1 -0
  91. package/lib/typescript/src/Storage.d.ts +23 -0
  92. package/lib/typescript/src/Storage.d.ts.map +1 -0
  93. package/lib/typescript/src/index.d.ts +319 -0
  94. package/lib/typescript/src/index.d.ts.map +1 -0
  95. package/op-sqlite.podspec +212 -0
  96. package/package.json +85 -0
  97. package/src/NativeOPSQLite.ts +17 -0
  98. package/src/Storage.ts +85 -0
  99. package/src/index.ts +722 -0
package/cpp/types.h ADDED
@@ -0,0 +1,33 @@
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
+ };
package/cpp/utils.cpp ADDED
@@ -0,0 +1,327 @@
1
+ #include "utils.h"
2
+ #include "SmartHostObject.h"
3
+ #ifndef OP_SQLITE_USE_LIBSQL
4
+ #include "bridge.h"
5
+ #endif
6
+ #include <fstream>
7
+ #include <sys/stat.h>
8
+
9
+ namespace opsqlite {
10
+
11
+ namespace jsi = facebook::jsi;
12
+
13
+ inline jsi::Value to_jsi(jsi::Runtime &rt, const JSVariant &value) {
14
+ if (std::holds_alternative<bool>(value)) {
15
+ return std::get<bool>(value);
16
+ } else if (std::holds_alternative<int>(value)) {
17
+ return jsi::Value(std::get<int>(value));
18
+ } else if (std::holds_alternative<long long>(value)) {
19
+ return jsi::Value(static_cast<double>(std::get<long long>(value)));
20
+ } else if (std::holds_alternative<double>(value)) {
21
+ return jsi::Value(std::get<double>(value));
22
+ } else if (std::holds_alternative<std::string>(value)) {
23
+ auto str = std::get<std::string>(value);
24
+ return jsi::String::createFromUtf8(rt, str);
25
+ } else if (std::holds_alternative<ArrayBuffer>(value)) {
26
+ auto jsBuffer = std::get<ArrayBuffer>(value);
27
+ jsi::Function array_buffer_ctor =
28
+ rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
29
+ jsi::Object o =
30
+ array_buffer_ctor.callAsConstructor(rt, (int)jsBuffer.size)
31
+ .getObject(rt);
32
+ jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
33
+ memcpy(buf.data(rt), jsBuffer.data.get(), jsBuffer.size);
34
+ return o;
35
+ }
36
+
37
+ return jsi::Value::null();
38
+
39
+ // I wanted to use the visitor pattern here but on the ArrayBuffer case it
40
+ // is somehow throwing a pointer exception Somehow the v.size or
41
+ // v.data.get() is loosing the data when called from the lambda I'm guessing
42
+ // the I created the shared pointer wrong and the memory is being freed
43
+ // before the lambda is called
44
+ // return std::visit(
45
+ // [&](auto &&v) -> jsi::Value {
46
+ // using T = std::decay_t<decltype(v)>;
47
+ // if constexpr (std::is_same_v<T, bool>) {
48
+ // return jsi::Value(v);
49
+ // } else if constexpr (std::is_same_v<T, int>) {
50
+ // return jsi::Value(v);
51
+ // } else if constexpr (std::is_same_v<T, long long>) {
52
+ // return jsi::Value(
53
+ // static_cast<double>(v)); // JSI doesn't support long long
54
+ // } else if constexpr (std::is_same_v<T, double>) {
55
+ // return jsi::Value(v);
56
+ // } else if constexpr (std::is_same_v<T, std::string>) {
57
+ // return jsi::String::createFromUtf8(rt, v);
58
+ // } else if constexpr (std::is_same_v<T, ArrayBuffer>) {
59
+ // static jsi::Function buffer_constructor =
60
+ // rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
61
+ // jsi::Object o =
62
+ // buffer_constructor.callAsConstructor(rt,
63
+ // static_cast<int>(v.size))
64
+ // .getObject(rt);
65
+ // jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
66
+ // memcpy(buf.data(rt), v.data.get(), v.size);
67
+ // return o;
68
+ // } else {
69
+ // return jsi::Value::null();
70
+ // }
71
+ // },
72
+ // value);
73
+ }
74
+
75
+ inline JSVariant to_variant(jsi::Runtime &rt, const jsi::Value &value) {
76
+ if (value.isNull() || value.isUndefined()) {
77
+ return JSVariant(nullptr);
78
+ } else if (value.isBool()) {
79
+ return JSVariant(value.getBool());
80
+ } else if (value.isNumber()) {
81
+ double doubleVal = value.asNumber();
82
+ int intVal = (int)doubleVal;
83
+ long long longVal = (long)doubleVal;
84
+ if (intVal == doubleVal) {
85
+ return JSVariant(intVal);
86
+ } else if (longVal == doubleVal) {
87
+ return JSVariant(longVal);
88
+ } else {
89
+ return JSVariant(doubleVal);
90
+ }
91
+ } else if (value.isString()) {
92
+ std::string strVal = value.asString(rt).utf8(rt);
93
+ return JSVariant(strVal);
94
+ } else if (value.isObject()) {
95
+ auto obj = value.asObject(rt);
96
+
97
+ if (!obj.isArrayBuffer(rt)) {
98
+ throw std::runtime_error(
99
+ "Object is not an ArrayBuffer, cannot bind to SQLite");
100
+ }
101
+
102
+ auto buffer = obj.getArrayBuffer(rt);
103
+ uint8_t *data = new uint8_t[buffer.size(rt)];
104
+ memcpy(data, buffer.data(rt), buffer.size(rt));
105
+
106
+ return JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
107
+ .size = buffer.size(rt)});
108
+ }
109
+
110
+ throw std::runtime_error("Cannot convert JSI value to C++ Variant value");
111
+ }
112
+
113
+ std::vector<std::string> to_string_vec(jsi::Runtime &rt, jsi::Value const &xs) {
114
+ jsi::Array values = xs.asObject(rt).asArray(rt);
115
+ std::vector<std::string> res;
116
+ for (int ii = 0; ii < values.length(rt); ii++) {
117
+ std::string value =
118
+ values.getValueAtIndex(rt, ii).asString(rt).utf8(rt);
119
+ res.emplace_back(value);
120
+ }
121
+ return res;
122
+ }
123
+
124
+ std::vector<int> to_int_vec(jsi::Runtime &rt, jsi::Value const &xs) {
125
+ jsi::Array values = xs.asObject(rt).asArray(rt);
126
+ std::vector<int> res;
127
+ for (int ii = 0; ii < values.length(rt); ii++) {
128
+ int value = static_cast<int>(values.getValueAtIndex(rt, ii).asNumber());
129
+ res.emplace_back(value);
130
+ }
131
+ return res;
132
+ }
133
+
134
+ std::vector<JSVariant> to_variant_vec(jsi::Runtime &rt, jsi::Value const &xs) {
135
+ std::vector<JSVariant> res;
136
+ jsi::Array values = xs.asObject(rt).asArray(rt);
137
+
138
+ for (int ii = 0; ii < values.length(rt); ii++) {
139
+ jsi::Value value = values.getValueAtIndex(rt, ii);
140
+ res.emplace_back(to_variant(rt, value));
141
+ }
142
+
143
+ return res;
144
+ }
145
+
146
+ jsi::Value create_js_rows(jsi::Runtime &rt, const BridgeResult &status) {
147
+ jsi::Object res = jsi::Object(rt);
148
+
149
+ res.setProperty(rt, "rowsAffected", status.affectedRows);
150
+ if (status.affectedRows > 0 && status.insertId != 0) {
151
+ res.setProperty(rt, "insertId", jsi::Value(status.insertId));
152
+ }
153
+
154
+ size_t row_count = status.rows.size();
155
+ auto rows = jsi::Array(rt, row_count);
156
+
157
+ if (row_count > 0) {
158
+ for (int i = 0; i < row_count; i++) {
159
+ auto row = jsi::Array(rt, status.column_names.size());
160
+ std::vector<JSVariant> native_row = status.rows[i];
161
+ for (int j = 0; j < native_row.size(); j++) {
162
+ auto value = to_jsi(rt, native_row[j]);
163
+ row.setValueAtIndex(rt, j, value);
164
+ }
165
+ rows.setValueAtIndex(rt, i, row);
166
+ }
167
+ }
168
+ res.setProperty(rt, "rawRows", rows);
169
+
170
+ size_t column_count = status.column_names.size();
171
+ auto column_array = jsi::Array(rt, column_count);
172
+ for (int i = 0; i < column_count; i++) {
173
+ auto column = status.column_names.at(i);
174
+ column_array.setValueAtIndex(rt, i, to_jsi(rt, column));
175
+ }
176
+ res.setProperty(rt, "columnNames", std::move(column_array));
177
+ return res;
178
+ }
179
+
180
+ jsi::Value
181
+ create_result(jsi::Runtime &rt, const BridgeResult &status,
182
+ std::vector<DumbHostObject> *results,
183
+ std::shared_ptr<std::vector<SmartHostObject>> metadata) {
184
+ jsi::Object res = jsi::Object(rt);
185
+
186
+ res.setProperty(rt, "rowsAffected", status.affectedRows);
187
+ if (status.affectedRows > 0 && status.insertId != 0) {
188
+ res.setProperty(rt, "insertId", jsi::Value(status.insertId));
189
+ }
190
+
191
+ size_t rowCount = results->size();
192
+
193
+ auto array = jsi::Array(rt, rowCount);
194
+ for (int i = 0; i < rowCount; i++) {
195
+ auto obj = results->at(i);
196
+ array.setValueAtIndex(rt, i,
197
+ jsi::Object::createFromHostObject(
198
+ rt, std::make_shared<DumbHostObject>(obj)));
199
+ }
200
+ res.setProperty(rt, "rows", std::move(array));
201
+
202
+ size_t column_count = metadata->size();
203
+ auto column_array = jsi::Array(rt, column_count);
204
+ for (int i = 0; i < column_count; i++) {
205
+ auto column = metadata->at(i);
206
+ column_array.setValueAtIndex(
207
+ rt, i,
208
+ jsi::Object::createFromHostObject(
209
+ rt, std::make_shared<SmartHostObject>(column)));
210
+ }
211
+ res.setProperty(rt, "metadata", std::move(column_array));
212
+
213
+ return std::move(res);
214
+ }
215
+
216
+ jsi::Value
217
+ create_raw_result(jsi::Runtime &rt, const BridgeResult &status,
218
+ const std::vector<std::vector<JSVariant>> *results) {
219
+ size_t row_count = results->size();
220
+ jsi::Array res = jsi::Array(rt, row_count);
221
+ for (int i = 0; i < row_count; i++) {
222
+ auto row = results->at(i);
223
+ auto array = jsi::Array(rt, row.size());
224
+ for (int j = 0; j < row.size(); j++) {
225
+ array.setValueAtIndex(rt, j, to_jsi(rt, row[j]));
226
+ }
227
+ res.setValueAtIndex(rt, i, array);
228
+ }
229
+ return res;
230
+ }
231
+
232
+ void to_batch_arguments(jsi::Runtime &rt, jsi::Array const &tuples,
233
+ std::vector<BatchArguments> *commands) {
234
+ for (int i = 0; i < tuples.length(rt); i++) {
235
+ const jsi::Array &tuple =
236
+ tuples.getValueAtIndex(rt, i).asObject(rt).asArray(rt);
237
+ const size_t length = tuple.length(rt);
238
+ if (length == 0) {
239
+ continue;
240
+ }
241
+
242
+ const std::string query =
243
+ tuple.getValueAtIndex(rt, 0).asString(rt).utf8(rt);
244
+ if (length == 1) {
245
+ commands->push_back({query});
246
+ continue;
247
+ }
248
+
249
+ const jsi::Value &tuple_params = tuple.getValueAtIndex(rt, 1);
250
+
251
+ if (!tuple_params.isUndefined() &&
252
+ tuple_params.asObject(rt).isArray(rt) &&
253
+ tuple_params.asObject(rt).asArray(rt).length(rt) > 0 &&
254
+ tuple_params.asObject(rt)
255
+ .asArray(rt)
256
+ .getValueAtIndex(rt, 0)
257
+ .isObject()) {
258
+ // The params for this tuple is an array itself
259
+ // The query should repeat for each element in the array
260
+ const jsi::Array &params_array =
261
+ tuple_params.asObject(rt).asArray(rt);
262
+ for (int x = 0; x < params_array.length(rt); x++) {
263
+ const jsi::Value &p = params_array.getValueAtIndex(rt, x);
264
+ auto params = std::vector<JSVariant>(to_variant_vec(rt, p));
265
+ commands->push_back({query, params});
266
+ }
267
+ } else {
268
+ auto params =
269
+ std::vector<JSVariant>(to_variant_vec(rt, tuple_params));
270
+ commands->push_back({query, params});
271
+ }
272
+ }
273
+ }
274
+
275
+ #ifndef OP_SQLITE_USE_LIBSQL
276
+ BatchResult import_sql_file(sqlite3 *db, std::string path) {
277
+ std::string line;
278
+ std::ifstream sqFile(path);
279
+ if (!sqFile.is_open()) {
280
+ throw std::runtime_error("Could not open file: " + path);
281
+ }
282
+
283
+ try {
284
+ int affectedRows = 0;
285
+ int commands = 0;
286
+ opsqlite_execute(db, "BEGIN EXCLUSIVE TRANSACTION", nullptr);
287
+ while (std::getline(sqFile, line, '\n')) {
288
+ if (!line.empty()) {
289
+ try {
290
+ auto result = opsqlite_execute(db, line, nullptr);
291
+ affectedRows += result.affectedRows;
292
+ commands++;
293
+ } catch (std::exception &exc) {
294
+ opsqlite_execute(db, "ROLLBACK", nullptr);
295
+ sqFile.close();
296
+ throw exc;
297
+ }
298
+ }
299
+ }
300
+ sqFile.close();
301
+ opsqlite_execute(db, "COMMIT", nullptr);
302
+ return {"", affectedRows, commands};
303
+ } catch (std::exception &exc) {
304
+ sqFile.close();
305
+ opsqlite_execute(db, "ROLLBACK", nullptr);
306
+ throw exc;
307
+ }
308
+ }
309
+ #endif
310
+
311
+ bool folder_exists(const std::string &name) {
312
+ struct stat buffer;
313
+ return (stat(name.c_str(), &buffer) == 0);
314
+ }
315
+
316
+ bool file_exists(const std::string &path) {
317
+ struct stat buffer;
318
+ return (stat(path.c_str(), &buffer) == 0);
319
+ }
320
+
321
+ void log_to_console(jsi::Runtime &runtime, const std::string &message) {
322
+ auto console = runtime.global().getPropertyAsObject(runtime, "console");
323
+ auto log = console.getPropertyAsFunction(runtime, "log");
324
+ log.call(runtime, jsi::String::createFromUtf8(runtime, message));
325
+ }
326
+
327
+ } // namespace opsqlite
package/cpp/utils.h ADDED
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ #include "DumbHostObject.h"
4
+ #include "SmartHostObject.h"
5
+ #include "types.h"
6
+ #include <jsi/jsi.h>
7
+ #include <sqlite3.h>
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ namespace opsqlite {
12
+
13
+ namespace jsi = facebook::jsi;
14
+
15
+ jsi::Value to_jsi(jsi::Runtime &rt, const JSVariant &value);
16
+
17
+ JSVariant to_variant(jsi::Runtime &rt, jsi::Value const &value);
18
+
19
+ std::vector<std::string> to_string_vec(jsi::Runtime &rt, jsi::Value const &xs);
20
+
21
+ std::vector<JSVariant> to_variant_vec(jsi::Runtime &rt, jsi::Value const &xs);
22
+
23
+ std::vector<int> to_int_vec(jsi::Runtime &rt, jsi::Value const &xs);
24
+
25
+ jsi::Value
26
+ create_result(jsi::Runtime &rt, const BridgeResult &status,
27
+ std::vector<DumbHostObject> *results,
28
+ std::shared_ptr<std::vector<SmartHostObject>> metadata);
29
+
30
+ jsi::Value create_js_rows(jsi::Runtime &rt, const BridgeResult &status);
31
+
32
+ jsi::Value
33
+ create_raw_result(jsi::Runtime &rt, const BridgeResult &status,
34
+ const std::vector<std::vector<JSVariant>> *results);
35
+
36
+ void to_batch_arguments(jsi::Runtime &rt, jsi::Array const &batch_params,
37
+ std::vector<BatchArguments> *commands);
38
+
39
+ BatchResult import_sql_file(sqlite3 *db, std::string path);
40
+
41
+ bool folder_exists(const std::string &name);
42
+
43
+ bool file_exists(const std::string &path);
44
+
45
+ void log_to_console(jsi::Runtime &rt, const std::string &message);
46
+
47
+ } // namespace opsqlite
@@ -0,0 +1,29 @@
1
+ require 'fileutils'
2
+
3
+ def generate_tokenizers_header_file(names, file_path)
4
+ # Ensure the directory exists
5
+ dir_path = File.dirname(file_path)
6
+ FileUtils.mkdir_p(dir_path) unless Dir.exist?(dir_path)
7
+ tokenizer_list = names.map { |name| "opsqlite_#{name}_init(db,&errMsg,nullptr);" }.join
8
+
9
+ File.open(file_path, 'w') do |file|
10
+ file.puts "#ifndef TOKENIZERS_H"
11
+ file.puts "#define TOKENIZERS_H"
12
+ file.puts
13
+ file.puts "#define TOKENIZER_LIST #{tokenizer_list}"
14
+ file.puts
15
+ file.puts "#include <sqlite3.h>"
16
+ file.puts
17
+ file.puts "namespace opsqlite {"
18
+ file.puts
19
+
20
+ names.each do |name|
21
+ file.puts "int opsqlite_#{name}_init(sqlite3 *db, char **error, sqlite3_api_routines const *api);"
22
+ end
23
+
24
+ file.puts
25
+ file.puts "} // namespace opsqlite"
26
+ file.puts
27
+ file.puts "#endif // TOKENIZERS_H"
28
+ end
29
+ end
package/ios/OPSQLite.h ADDED
@@ -0,0 +1,7 @@
1
+ #import <React/RCTBridge.h>
2
+
3
+ @interface OPSQLite : NSObject <RCTBridgeModule>
4
+
5
+ @property(nonatomic, assign) BOOL setBridgeOnMainQueue;
6
+ + (void)expoUpdatesWorkaround;
7
+ @end
@@ -0,0 +1,157 @@
1
+ #import "OPSQLite.h"
2
+ #import "../cpp/bindings.h"
3
+ #import <React/RCTBridge+Private.h>
4
+ #import <React/RCTLog.h>
5
+ #import <React/RCTUtils.h>
6
+ #import <ReactCommon/RCTTurboModule.h>
7
+ #import <jsi/jsi.h>
8
+
9
+ @implementation OPSQLite
10
+
11
+ @synthesize bridge = _bridge;
12
+
13
+ RCT_EXPORT_MODULE()
14
+
15
+ + (BOOL)requiresMainQueueSetup {
16
+ return YES;
17
+ }
18
+
19
+ - (NSDictionary *)constantsToExport {
20
+ NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(
21
+ NSLibraryDirectory, NSUserDomainMask, true);
22
+ NSString *libraryPath = [libraryPaths objectAtIndex:0];
23
+
24
+ NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(
25
+ NSDocumentDirectory, NSUserDomainMask, true);
26
+ NSString *documentPath = [documentPaths objectAtIndex:0];
27
+ return @{
28
+ @"IOS_DOCUMENT_PATH" : documentPath,
29
+ @"IOS_LIBRARY_PATH" : libraryPath
30
+ };
31
+ }
32
+
33
+ - (NSDictionary *)getConstants {
34
+ return [self constantsToExport];
35
+ }
36
+
37
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
38
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)_bridge;
39
+ if (cxxBridge == nil) {
40
+ return @false;
41
+ }
42
+
43
+ auto jsiRuntime = (facebook::jsi::Runtime *)cxxBridge.runtime;
44
+ if (jsiRuntime == nil) {
45
+ return @false;
46
+ }
47
+
48
+ auto &runtime = *jsiRuntime;
49
+ auto callInvoker = _bridge.jsCallInvoker;
50
+
51
+ // Get appGroupID value from Info.plist using key "AppGroup"
52
+ NSString *appGroupID =
53
+ [[NSBundle mainBundle] objectForInfoDictionaryKey:@"OPSQLite_AppGroup"];
54
+ NSString *documentPath;
55
+
56
+ if (appGroupID != nil) {
57
+ // Get the app groups container storage url
58
+ NSFileManager *fileManager = [NSFileManager defaultManager];
59
+ NSURL *storeUrl = [fileManager
60
+ containerURLForSecurityApplicationGroupIdentifier:appGroupID];
61
+
62
+ if (storeUrl == nil) {
63
+ NSLog(@"OP-SQLite: Invalid AppGroup ID provided (%@). Check the "
64
+ @"value of "
65
+ @"\"AppGroup\" in your Info.plist file",
66
+ appGroupID);
67
+ return @false;
68
+ }
69
+
70
+ documentPath = [storeUrl path];
71
+ } else {
72
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(
73
+ NSLibraryDirectory, NSUserDomainMask, true);
74
+ documentPath = [paths objectAtIndex:0];
75
+ }
76
+
77
+ NSBundle *crsqlite_bundle =
78
+ [NSBundle bundleWithIdentifier:@"io.vlcn.crsqlite"];
79
+ NSString *crsqlite_path = [crsqlite_bundle pathForResource:@"crsqlite"
80
+ ofType:@""];
81
+ NSBundle *libsqlitevec_bundle =
82
+ [NSBundle bundleWithIdentifier:@"com.ospfranco.sqlitevec"];
83
+ NSString *sqlite_vec_path =
84
+ [libsqlitevec_bundle pathForResource:@"sqlitevec" ofType:@""];
85
+
86
+ if (crsqlite_path == nil) {
87
+ crsqlite_path = @"";
88
+ }
89
+
90
+ if (sqlite_vec_path == nil) {
91
+ sqlite_vec_path = @"";
92
+ }
93
+
94
+ opsqlite::install(runtime, callInvoker, [documentPath UTF8String],
95
+ [crsqlite_path UTF8String], [sqlite_vec_path UTF8String]);
96
+ return @true;
97
+ }
98
+
99
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getDylibPath : (
100
+ NSString *)bundleId andResource : (NSString *)resourceName) {
101
+ NSBundle *bundle = [NSBundle bundleWithIdentifier:bundleId];
102
+ NSString *path = [bundle pathForResource:resourceName ofType:@""];
103
+ return path;
104
+ }
105
+
106
+ RCT_EXPORT_METHOD(moveAssetsDatabase : (NSDictionary *)args resolve : (
107
+ RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
108
+ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(
109
+ NSLibraryDirectory, NSUserDomainMask, true) objectAtIndex:0];
110
+
111
+ NSString *filename = args[@"filename"];
112
+ BOOL overwrite = args[@"overwrite"];
113
+
114
+ NSString *sourcePath = [[NSBundle mainBundle] pathForResource:filename
115
+ ofType:nil];
116
+
117
+ NSString *destinationPath =
118
+ [documentPath stringByAppendingPathComponent:filename];
119
+
120
+ NSError *error;
121
+ NSFileManager *fileManager = [NSFileManager defaultManager];
122
+ if ([fileManager fileExistsAtPath:destinationPath]) {
123
+ if (overwrite) {
124
+ [fileManager removeItemAtPath:destinationPath error:&error];
125
+ if (error) {
126
+ NSLog(@"Error: %@", error);
127
+ resolve(@false);
128
+ return;
129
+ }
130
+ } else {
131
+ resolve(@true);
132
+ return;
133
+ }
134
+ }
135
+
136
+ [fileManager copyItemAtPath:sourcePath toPath:destinationPath error:&error];
137
+ if (error) {
138
+ NSLog(@"Error: %@", error);
139
+ resolve(@false);
140
+ return;
141
+ }
142
+ resolve(@true);
143
+ return;
144
+ }
145
+
146
+ - (void)invalidate {
147
+ opsqlite::invalidate();
148
+ }
149
+
150
+ + (void)expoUpdatesWorkaround {
151
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(
152
+ NSLibraryDirectory, NSUserDomainMask, true);
153
+ NSString *documentPath = [paths objectAtIndex:0];
154
+ opsqlite::expoUpdatesWorkaround([documentPath UTF8String]);
155
+ }
156
+
157
+ @end