@op-engineering/op-sqlite 6.0.2-beta1 → 6.0.2-beta4

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 (38) hide show
  1. package/android/CMakeLists.txt +26 -15
  2. package/android/build.gradle +10 -1
  3. package/android/cpp-adapter.cpp +4 -0
  4. package/android/jniLibs/arm64-v8a/libsql_experimental.a +0 -0
  5. package/android/jniLibs/armeabi-v7a/libsql_experimental.a +0 -0
  6. package/android/jniLibs/x86/libsql_experimental.a +0 -0
  7. package/android/jniLibs/x86_64/libsql_experimental.a +0 -0
  8. package/cpp/DBHostObject.cpp +234 -87
  9. package/cpp/DBHostObject.h +19 -10
  10. package/cpp/PreparedStatementHostObject.cpp +28 -14
  11. package/cpp/PreparedStatementHostObject.h +18 -14
  12. package/cpp/bindings.cpp +49 -32
  13. package/cpp/bindings.h +4 -3
  14. package/cpp/bridge.cpp +45 -0
  15. package/cpp/bridge.h +3 -0
  16. package/cpp/libsql/bridge.cpp +660 -0
  17. package/cpp/libsql/bridge.h +76 -0
  18. package/cpp/libsql/libsql.h +133 -0
  19. package/cpp/sqlite3.h +0 -1
  20. package/cpp/types.h +5 -0
  21. package/cpp/utils.cpp +45 -3
  22. package/cpp/utils.h +2 -3
  23. package/ios/libsql.xcframework/Info.plist +48 -0
  24. package/ios/libsql.xcframework/ios-arm64/Headers/libsql.h +133 -0
  25. package/ios/libsql.xcframework/ios-arm64/libsql_experimental.a +0 -0
  26. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/Headers/libsql.h +133 -0
  27. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/libsql_experimental.a +0 -0
  28. package/lib/commonjs/index.js +167 -2
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/module/index.js +164 -1
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/typescript/src/index.d.ts +14 -2
  33. package/lib/typescript/src/index.d.ts.map +1 -1
  34. package/op-sqlite.podspec +20 -3
  35. package/package.json +1 -1
  36. package/src/index.ts +209 -3
  37. package/cpp/sqlbatchexecutor.cpp +0 -93
  38. package/cpp/sqlbatchexecutor.h +0 -30
@@ -1,5 +1,9 @@
1
1
  #include "PreparedStatementHostObject.h"
2
+ #if OP_SQLITE_USE_LIBSQL
3
+ #include "libsql/bridge.h"
4
+ #else
2
5
  #include "bridge.h"
6
+ #endif
3
7
  #include "macros.h"
4
8
  #include "utils.h"
5
9
 
@@ -7,10 +11,6 @@ namespace opsqlite {
7
11
 
8
12
  namespace jsi = facebook::jsi;
9
13
 
10
- PreparedStatementHostObject::PreparedStatementHostObject(
11
- std::string dbName, sqlite3_stmt *statementPtr)
12
- : _dbName(dbName), _statement(statementPtr) {}
13
-
14
14
  std::vector<jsi::PropNameID>
15
15
  PreparedStatementHostObject::getPropertyNames(jsi::Runtime &rt) {
16
16
  std::vector<jsi::PropNameID> keys;
@@ -24,14 +24,17 @@ jsi::Value PreparedStatementHostObject::get(jsi::Runtime &rt,
24
24
 
25
25
  if (name == "bind") {
26
26
  return HOSTFN("bind", 1) {
27
- if (_statement == nullptr) {
27
+ if (_stmt == nullptr) {
28
28
  throw std::runtime_error("statement has been freed");
29
29
  }
30
30
 
31
31
  const jsi::Value &js_params = args[0];
32
32
  std::vector<JSVariant> params = to_variant_vec(rt, js_params);
33
-
34
- opsqlite_bind_statement(_statement, &params);
33
+ #ifdef OP_SQLITE_USE_LIBSQL
34
+ opsqlite_libsql_bind_statement(_stmt, &params);
35
+ #else
36
+ opsqlite_bind_statement(_stmt, &params);
37
+ #endif
35
38
 
36
39
  return {};
37
40
  });
@@ -39,16 +42,20 @@ jsi::Value PreparedStatementHostObject::get(jsi::Runtime &rt,
39
42
 
40
43
  if (name == "execute") {
41
44
  return HOSTFN("execute", 1) {
42
- if (_statement == nullptr) {
45
+ if (_stmt == nullptr) {
43
46
  throw std::runtime_error("statement has been freed");
44
47
  }
45
48
 
46
49
  std::vector<DumbHostObject> results;
47
50
  std::shared_ptr<std::vector<SmartHostObject>> metadata =
48
51
  std::make_shared<std::vector<SmartHostObject>>();
49
-
50
- auto status = opsqlite_execute_prepared_statement(_dbName, _statement,
51
- &results, metadata);
52
+ #ifdef OP_SQLITE_USE_LIBSQL
53
+ auto status = opsqlite_libsql_execute_prepared_statement(
54
+ _name, _stmt, &results, metadata);
55
+ #else
56
+ auto status =
57
+ opsqlite_execute_prepared_statement(_name, _stmt, &results, metadata);
58
+ #endif
52
59
 
53
60
  if (status.type == SQLiteError) {
54
61
  throw std::runtime_error(status.message);
@@ -63,10 +70,17 @@ jsi::Value PreparedStatementHostObject::get(jsi::Runtime &rt,
63
70
  }
64
71
 
65
72
  PreparedStatementHostObject::~PreparedStatementHostObject() {
66
- if (_statement != nullptr) {
67
- sqlite3_finalize(_statement);
68
- _statement = nullptr;
73
+ #ifdef OP_SQLITE_USE_LIBSQL
74
+ if (_stmt != nullptr) {
75
+ libsql_free_stmt(_stmt);
76
+ _stmt = nullptr;
77
+ }
78
+ #else
79
+ if (_stmt != nullptr) {
80
+ sqlite3_finalize(_stmt);
81
+ _stmt = nullptr;
69
82
  }
83
+ #endif
70
84
  }
71
85
 
72
86
  } // namespace opsqlite
@@ -1,16 +1,12 @@
1
- //
2
- // PreparedStatementHostObject.hpp
3
- // op-sqlite
4
- //
5
- // Created by Oscar Franco on 5/12/23.
6
- //
7
-
8
- #ifndef PreparedStatementHostObject_h
9
- #define PreparedStatementHostObject_h
1
+ #pragma once
10
2
 
11
3
  #include <jsi/jsi.h>
12
4
  #include <memory>
5
+ #ifdef OP_SQLITE_USE_LIBSQL
6
+ #include "libsql.h"
7
+ #else
13
8
  #include <sqlite3.h>
9
+ #endif
14
10
  #include <string>
15
11
 
16
12
  namespace opsqlite {
@@ -18,7 +14,13 @@ namespace jsi = facebook::jsi;
18
14
 
19
15
  class PreparedStatementHostObject : public jsi::HostObject {
20
16
  public:
21
- PreparedStatementHostObject(std::string dbName, sqlite3_stmt *statement);
17
+ #ifdef OP_SQLITE_USE_LIBSQL
18
+ PreparedStatementHostObject(std::string name, libsql_stmt_t stmt)
19
+ : _name(name), _stmt(stmt){};
20
+ #else
21
+ PreparedStatementHostObject(std::string name, sqlite3_stmt *stmt)
22
+ : _name(name), _stmt(stmt){};
23
+ #endif
22
24
  virtual ~PreparedStatementHostObject();
23
25
 
24
26
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt);
@@ -26,11 +28,13 @@ public:
26
28
  jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
27
29
 
28
30
  private:
29
- std::string _dbName;
31
+ std::string _name;
32
+ #ifdef OP_SQLITE_USE_LIBSQL
33
+ libsql_stmt_t _stmt;
34
+ #else
30
35
  // This shouldn't be de-allocated until sqlite3_finalize is called on it
31
- sqlite3_stmt *_statement;
36
+ sqlite3_stmt *_stmt;
37
+ #endif
32
38
  };
33
39
 
34
40
  } // namespace opsqlite
35
-
36
- #endif /* PreparedStatementHostObject_hpp */
package/cpp/bindings.cpp CHANGED
@@ -1,12 +1,14 @@
1
1
  #include "bindings.h"
2
2
  #include "DBHostObject.h"
3
3
  #include "DumbHostObject.h"
4
- #include "PreparedStatementHostObject.h"
5
4
  #include "ThreadPool.h"
5
+ #ifdef OP_SQLITE_USE_LIBSQL
6
+ #include "libsql/bridge.h"
7
+ #else
6
8
  #include "bridge.h"
9
+ #endif
7
10
  #include "logs.h"
8
11
  #include "macros.h"
9
- #include "sqlbatchexecutor.h"
10
12
  #include "utils.h"
11
13
  #include <iostream>
12
14
  #include <string>
@@ -17,16 +19,10 @@ namespace opsqlite {
17
19
 
18
20
  namespace jsi = facebook::jsi;
19
21
 
20
- std::string basePath;
21
- std::string crsqlitePath;
22
- std::shared_ptr<react::CallInvoker> invoker;
22
+ std::string _base_path;
23
+ std::string _crsqlite_path;
24
+ std::shared_ptr<react::CallInvoker> _invoker;
23
25
  std::shared_ptr<ThreadPool> thread_pool = std::make_shared<ThreadPool>();
24
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>> updateHooks =
25
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
26
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>> commitHooks =
27
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
28
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>> rollbackHooks =
29
- // std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
30
26
 
31
27
  // React native will try to clean the module on JS context invalidation
32
28
  // (CodePush/Hot Reload) The clearState function is called and we use this flag
@@ -35,32 +31,28 @@ bool invalidated = false;
35
31
 
36
32
  void clearState() {
37
33
  invalidated = true;
38
- // Will terminate all operations and database connections
34
+
35
+ #ifdef OP_SQLITE_USE_LIBSQL
36
+ opsqlite_libsql_close_all();
37
+ #else
39
38
  opsqlite_close_all();
39
+ #endif
40
+
40
41
  // We then join all the threads before the context gets invalidated
41
42
  thread_pool->restartPool();
42
- // updateHooks.clear();
43
- // commitHooks.clear();
44
- // rollbackHooks.clear();
45
43
  }
46
44
 
47
- void install(jsi::Runtime &rt,
48
- std::shared_ptr<react::CallInvoker> js_call_invoker,
49
- const char *doc_path, const char *_crsqlitePath) {
50
-
45
+ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
46
+ const char *base_path, const char *crsqlite_path) {
51
47
  invalidated = false;
52
- basePath = std::string(doc_path);
53
- crsqlitePath = std::string(_crsqlitePath);
54
- invoker = js_call_invoker;
55
-
56
- auto open = HOSTFN("open", 3) {
57
- if (count == 0) {
58
- throw std::runtime_error("[op-sqlite][open] database name is required");
59
- }
48
+ _base_path = std::string(base_path);
49
+ _crsqlite_path = std::string(crsqlite_path);
50
+ _invoker = invoker;
60
51
 
52
+ auto open = HOSTFN("open", 1) {
61
53
  jsi::Object options = args[0].asObject(rt);
62
- std::string dbName = options.getProperty(rt, "name").asString(rt).utf8(rt);
63
- std::string path = std::string(basePath);
54
+ std::string name = options.getProperty(rt, "name").asString(rt).utf8(rt);
55
+ std::string path = std::string(_base_path);
64
56
  std::string location;
65
57
  std::string encryptionKey;
66
58
 
@@ -90,9 +82,9 @@ void install(jsi::Runtime &rt,
90
82
  }
91
83
  }
92
84
 
93
- std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
94
- rt, basePath, invoker, thread_pool, dbName, path, crsqlitePath,
95
- encryptionKey);
85
+ std::shared_ptr<DBHostObject> db =
86
+ std::make_shared<DBHostObject>(rt, path, invoker, thread_pool, name,
87
+ path, _crsqlite_path, encryptionKey);
96
88
  return jsi::Object::createFromHostObject(rt, db);
97
89
  });
98
90
 
@@ -104,9 +96,34 @@ void install(jsi::Runtime &rt,
104
96
  #endif
105
97
  });
106
98
 
99
+ auto is_libsql = HOSTFN("isLibsql", 0) {
100
+ #ifdef OP_SQLITE_USE_LIBSQL
101
+ return true;
102
+ #else
103
+ return false;
104
+ #endif
105
+ });
106
+
107
+ #ifdef OP_SQLITE_USE_LIBSQL
108
+ auto open_remote = HOSTFN("openRemote", 1) {
109
+ jsi::Object options = args[0].asObject(rt);
110
+ std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
111
+ std::string auth_token =
112
+ options.getProperty(rt, "authToken").asString(rt).utf8(rt);
113
+
114
+ std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
115
+ rt, url, auth_token, invoker, thread_pool);
116
+ return jsi::Object::createFromHostObject(rt, db);
117
+ });
118
+ #endif
119
+
107
120
  jsi::Object module = jsi::Object(rt);
108
121
  module.setProperty(rt, "open", std::move(open));
109
122
  module.setProperty(rt, "isSQLCipher", std::move(is_sqlcipher));
123
+ module.setProperty(rt, "isLibsql", std::move(is_libsql));
124
+ #ifdef OP_SQLITE_USE_LIBSQL
125
+ module.setProperty(rt, "openRemote", std::move(open_remote));
126
+ #endif
110
127
 
111
128
  rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
112
129
  }
package/cpp/bindings.h CHANGED
@@ -1,3 +1,5 @@
1
+ #pragma once
2
+
1
3
  #include <ReactCommon/CallInvoker.h>
2
4
  #include <jsi/jsi.h>
3
5
  #include <jsi/jsilib.h>
@@ -7,9 +9,8 @@ namespace opsqlite {
7
9
  namespace jsi = facebook::jsi;
8
10
  namespace react = facebook::react;
9
11
 
10
- void install(jsi::Runtime &rt,
11
- std::shared_ptr<react::CallInvoker> jsCallInvoker,
12
- const char *docPath, const char *crsqlitePath);
12
+ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
13
+ const char *base_path, const char *crsqlite_path);
13
14
  void clearState();
14
15
 
15
16
  } // namespace opsqlite
package/cpp/bridge.cpp CHANGED
@@ -867,4 +867,49 @@ BridgeResult opsqlite_load_extension(std::string const &db_name,
867
867
  #endif
868
868
  }
869
869
 
870
+ BatchResult opsqlite_execute_batch(std::string dbName,
871
+ std::vector<BatchArguments> *commands) {
872
+ size_t commandCount = commands->size();
873
+ if (commandCount <= 0) {
874
+ return BatchResult{
875
+ .type = SQLiteError,
876
+ .message = "No SQL commands provided",
877
+ };
878
+ }
879
+
880
+ try {
881
+ int affectedRows = 0;
882
+ opsqlite_execute(dbName, "BEGIN EXCLUSIVE TRANSACTION", nullptr, nullptr,
883
+ nullptr);
884
+ for (int i = 0; i < commandCount; i++) {
885
+ auto command = commands->at(i);
886
+ // We do not provide a datastructure to receive query data because we
887
+ // don't need/want to handle this results in a batch execution
888
+ auto result = opsqlite_execute(dbName, command.sql, command.params.get(),
889
+ nullptr, nullptr);
890
+ if (result.type == SQLiteError) {
891
+ opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
892
+ return BatchResult{
893
+ .type = SQLiteError,
894
+ .message = result.message,
895
+ };
896
+ } else {
897
+ affectedRows += result.affectedRows;
898
+ }
899
+ }
900
+ opsqlite_execute(dbName, "COMMIT", nullptr, nullptr, nullptr);
901
+ return BatchResult{
902
+ .type = SQLiteOk,
903
+ .affectedRows = affectedRows,
904
+ .commands = static_cast<int>(commandCount),
905
+ };
906
+ } catch (std::exception &exc) {
907
+ opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
908
+ return BatchResult{
909
+ .type = SQLiteError,
910
+ .message = exc.what(),
911
+ };
912
+ }
913
+ }
914
+
870
915
  } // namespace opsqlite
package/cpp/bridge.h CHANGED
@@ -50,6 +50,9 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
50
50
  std::vector<DumbHostObject> *results,
51
51
  std::shared_ptr<std::vector<SmartHostObject>> metadatas);
52
52
 
53
+ BatchResult opsqlite_execute_batch(std::string dbName,
54
+ std::vector<BatchArguments> *commands);
55
+
53
56
  BridgeResult opsqlite_execute_raw(std::string const &dbName,
54
57
  std::string const &query,
55
58
  const std::vector<JSVariant> *params,