@op-engineering/op-sqlite 2.0.16 → 2.0.17
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/README.md +20 -2
- package/cpp/PreparedStatementHostObject.cpp +3 -3
- package/cpp/bindings.cpp +18 -19
- package/cpp/bridge.cpp +98 -126
- package/cpp/bridge.h +53 -49
- package/cpp/sqlbatchexecutor.cpp +6 -6
- package/cpp/sqlite3.c +5642 -2573
- package/cpp/sqlite3.h +127 -31
- package/cpp/utils.cpp +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ yarn add @op-engineering/op-sqlite && npx pod-install
|
|
|
6
6
|
|
|
7
7
|
OP-SQLite embeds the latest version of SQLite and provides a low-level API to execute SQL queries.
|
|
8
8
|
|
|
9
|
-
**Current SQLite version: 3.
|
|
9
|
+
**Current SQLite version: 3.45.1**
|
|
10
10
|
|
|
11
11
|
Created by [@ospfranco](https://twitter.com/ospfranco). **Please consider sponsoring!**.
|
|
12
12
|
|
|
@@ -502,7 +502,7 @@ On iOS you can use the embedded SQLite, when running `pod-install` add an enviro
|
|
|
502
502
|
OP_SQLITE_USE_PHONE_VERSION=1 npx pod-install
|
|
503
503
|
```
|
|
504
504
|
|
|
505
|
-
On Android, it is not possible to link the OS SQLite. It is also a bad idea due to vendor changes, old android bugs, etc. Unfortunately, this means this library will add some megabytes to your app size.
|
|
505
|
+
On Android, it is not possible to link the OS SQLite. It is also a bad idea due to vendor changes, old android bugs, etc. Unfortunately, this means this library will add some megabytes to your app size. Take note that the embedded version of SQLite does not support loading runtime extensions due to security concerns from apple.
|
|
506
506
|
|
|
507
507
|
# Enable compile-time options
|
|
508
508
|
|
|
@@ -553,6 +553,24 @@ On iOS, the SQLite database can be placed in an app group, in order to make it a
|
|
|
553
553
|
|
|
554
554
|
To use an app group, add the app group ID as the value for the `OPSQLite_AppGroup` key in your project's `Info.plist` file. You'll also need to configure the app group in your project settings. (Xcode -> Project Settings -> Signing & Capabilities -> Add Capability -> App Groups)
|
|
555
555
|
|
|
556
|
+
## use_frameworks
|
|
557
|
+
|
|
558
|
+
If you are using `use_frameworks` (because one of your dependencies requires e.g. firebase), you might get a linking error since the OS version will try to be linked instead of the version compiled directly from sources. In order to get around this you can add the following into your Podfile:
|
|
559
|
+
|
|
560
|
+
```ruby
|
|
561
|
+
pre_install do |installer|
|
|
562
|
+
installer.pod_targets.each do |pod|
|
|
563
|
+
if pod.name.eql?('op-sqlite')
|
|
564
|
+
def pod.build_type
|
|
565
|
+
Pod::BuildType.static_library
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
It will change the type of library only for op-sqlite only to static. This should be fine as SQLite is compiled from sources, so no missing symbols should be there.
|
|
573
|
+
|
|
556
574
|
# Contribute
|
|
557
575
|
|
|
558
576
|
You need to have clang-format installed (`brew install clang-format`)
|
|
@@ -38,7 +38,7 @@ jsi::Value PreparedStatementHostObject::get(jsi::Runtime &rt,
|
|
|
38
38
|
const jsi::Value &js_params = args[0];
|
|
39
39
|
std::vector<JSVariant> params = toVariantVec(rt, js_params);
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
opsqlite_bind_statement(_statement, ¶ms);
|
|
42
42
|
|
|
43
43
|
return {};
|
|
44
44
|
});
|
|
@@ -53,8 +53,8 @@ jsi::Value PreparedStatementHostObject::get(jsi::Runtime &rt,
|
|
|
53
53
|
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
54
54
|
std::make_shared<std::vector<SmartHostObject>>();
|
|
55
55
|
|
|
56
|
-
auto status =
|
|
57
|
-
|
|
56
|
+
auto status = opsqlite_execute_prepared_statement(_dbName, _statement,
|
|
57
|
+
&results, metadata);
|
|
58
58
|
|
|
59
59
|
if (status.type == SQLiteError) {
|
|
60
60
|
throw std::runtime_error(status.message);
|
package/cpp/bindings.cpp
CHANGED
|
@@ -35,7 +35,7 @@ bool invalidated = false;
|
|
|
35
35
|
void clearState() {
|
|
36
36
|
invalidated = true;
|
|
37
37
|
// Will terminate all operations and database connections
|
|
38
|
-
|
|
38
|
+
opsqlite_close_all();
|
|
39
39
|
// We then join all the threads before the context gets invalidated
|
|
40
40
|
pool.restartPool();
|
|
41
41
|
updateHooks.clear();
|
|
@@ -80,7 +80,7 @@ void install(jsi::Runtime &rt,
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
BridgeResult result =
|
|
83
|
+
BridgeResult result = opsqlite_open(dbName, path);
|
|
84
84
|
|
|
85
85
|
if (result.type == SQLiteError) {
|
|
86
86
|
throw std::runtime_error(result.message);
|
|
@@ -114,7 +114,7 @@ void install(jsi::Runtime &rt,
|
|
|
114
114
|
std::string databaseToAttach = args[1].asString(rt).utf8(rt);
|
|
115
115
|
std::string alias = args[2].asString(rt).utf8(rt);
|
|
116
116
|
BridgeResult result =
|
|
117
|
-
|
|
117
|
+
opsqlite_attach(dbName, tempDocPath, databaseToAttach, alias);
|
|
118
118
|
|
|
119
119
|
if (result.type == SQLiteError) {
|
|
120
120
|
throw std::runtime_error(result.message);
|
|
@@ -136,7 +136,7 @@ void install(jsi::Runtime &rt,
|
|
|
136
136
|
|
|
137
137
|
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
138
138
|
std::string alias = args[1].asString(rt).utf8(rt);
|
|
139
|
-
BridgeResult result =
|
|
139
|
+
BridgeResult result = opsqlite_detach(dbName, alias);
|
|
140
140
|
|
|
141
141
|
if (result.type == SQLiteError) {
|
|
142
142
|
throw jsi::JSError(rt, result.message.c_str());
|
|
@@ -157,7 +157,7 @@ void install(jsi::Runtime &rt,
|
|
|
157
157
|
|
|
158
158
|
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
159
159
|
|
|
160
|
-
BridgeResult result =
|
|
160
|
+
BridgeResult result = opsqlite_close(dbName);
|
|
161
161
|
|
|
162
162
|
if (result.type == SQLiteError) {
|
|
163
163
|
throw jsi::JSError(rt, result.message.c_str());
|
|
@@ -189,7 +189,7 @@ void install(jsi::Runtime &rt,
|
|
|
189
189
|
tempDocPath = tempDocPath + "/" + args[1].asString(rt).utf8(rt);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
BridgeResult result =
|
|
192
|
+
BridgeResult result = opsqlite_remove(dbName, tempDocPath);
|
|
193
193
|
|
|
194
194
|
if (result.type == SQLiteError) {
|
|
195
195
|
throw std::runtime_error(result.message);
|
|
@@ -212,7 +212,7 @@ void install(jsi::Runtime &rt,
|
|
|
212
212
|
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
213
213
|
std::make_shared<std::vector<SmartHostObject>>();
|
|
214
214
|
|
|
215
|
-
auto status =
|
|
215
|
+
auto status = opsqlite_execute(dbName, query, ¶ms, &results, metadata);
|
|
216
216
|
|
|
217
217
|
if (status.type == SQLiteError) {
|
|
218
218
|
throw std::runtime_error(status.message);
|
|
@@ -245,7 +245,7 @@ void install(jsi::Runtime &rt,
|
|
|
245
245
|
try {
|
|
246
246
|
std::vector<std::vector<JSVariant>> results;
|
|
247
247
|
|
|
248
|
-
auto status =
|
|
248
|
+
auto status = opsqlite_execute_raw(dbName, query, ¶ms, &results);
|
|
249
249
|
|
|
250
250
|
if (invalidated) {
|
|
251
251
|
return;
|
|
@@ -309,7 +309,7 @@ void install(jsi::Runtime &rt,
|
|
|
309
309
|
std::make_shared<std::vector<SmartHostObject>>();
|
|
310
310
|
|
|
311
311
|
auto status =
|
|
312
|
-
|
|
312
|
+
opsqlite_execute(dbName, query, ¶ms, &results, metadata);
|
|
313
313
|
|
|
314
314
|
if (invalidated) {
|
|
315
315
|
return;
|
|
@@ -489,7 +489,7 @@ void install(jsi::Runtime &rt,
|
|
|
489
489
|
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
490
490
|
|
|
491
491
|
if (callback->isUndefined() || callback->isNull()) {
|
|
492
|
-
|
|
492
|
+
opsqlite_deregister_update_hook(dbName);
|
|
493
493
|
return {};
|
|
494
494
|
}
|
|
495
495
|
|
|
@@ -501,12 +501,11 @@ void install(jsi::Runtime &rt,
|
|
|
501
501
|
std::vector<DumbHostObject> results;
|
|
502
502
|
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
503
503
|
std::make_shared<std::vector<SmartHostObject>>();
|
|
504
|
-
;
|
|
505
504
|
|
|
506
505
|
if (operation != "DELETE") {
|
|
507
506
|
std::string query = "SELECT * FROM " + tableName +
|
|
508
507
|
" where rowid = " + std::to_string(rowId) + ";";
|
|
509
|
-
|
|
508
|
+
opsqlite_execute(dbName, query, ¶ms, &results, metadata);
|
|
510
509
|
}
|
|
511
510
|
|
|
512
511
|
invoker->invokeAsync(
|
|
@@ -531,7 +530,7 @@ void install(jsi::Runtime &rt,
|
|
|
531
530
|
});
|
|
532
531
|
};
|
|
533
532
|
|
|
534
|
-
|
|
533
|
+
opsqlite_register_update_hook(dbName, std::move(hook));
|
|
535
534
|
|
|
536
535
|
return {};
|
|
537
536
|
});
|
|
@@ -546,7 +545,7 @@ void install(jsi::Runtime &rt,
|
|
|
546
545
|
auto dbName = args[0].asString(rt).utf8(rt);
|
|
547
546
|
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
548
547
|
if (callback->isUndefined() || callback->isNull()) {
|
|
549
|
-
|
|
548
|
+
opsqlite_deregister_commit_hook(dbName);
|
|
550
549
|
return {};
|
|
551
550
|
}
|
|
552
551
|
commitHooks[dbName] = callback;
|
|
@@ -556,7 +555,7 @@ void install(jsi::Runtime &rt,
|
|
|
556
555
|
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
|
|
557
556
|
};
|
|
558
557
|
|
|
559
|
-
|
|
558
|
+
opsqlite_register_commit_hook(dbName, std::move(hook));
|
|
560
559
|
|
|
561
560
|
return {};
|
|
562
561
|
});
|
|
@@ -573,7 +572,7 @@ void install(jsi::Runtime &rt,
|
|
|
573
572
|
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
574
573
|
|
|
575
574
|
if (callback->isUndefined() || callback->isNull()) {
|
|
576
|
-
|
|
575
|
+
opsqlite_deregister_rollback_hook(dbName);
|
|
577
576
|
return {};
|
|
578
577
|
}
|
|
579
578
|
rollbackHooks[dbName] = callback;
|
|
@@ -583,7 +582,7 @@ void install(jsi::Runtime &rt,
|
|
|
583
582
|
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
|
|
584
583
|
};
|
|
585
584
|
|
|
586
|
-
|
|
585
|
+
opsqlite_register_rollback_hook(dbName, std::move(hook));
|
|
587
586
|
return {};
|
|
588
587
|
});
|
|
589
588
|
|
|
@@ -591,7 +590,7 @@ void install(jsi::Runtime &rt,
|
|
|
591
590
|
auto dbName = args[0].asString(rt).utf8(rt);
|
|
592
591
|
auto query = args[1].asString(rt).utf8(rt);
|
|
593
592
|
|
|
594
|
-
sqlite3_stmt *statement =
|
|
593
|
+
sqlite3_stmt *statement = opsqlite_prepare_statement(dbName, query);
|
|
595
594
|
|
|
596
595
|
auto preparedStatementHostObject =
|
|
597
596
|
std::make_shared<PreparedStatementHostObject>(dbName, statement);
|
|
@@ -607,7 +606,7 @@ void install(jsi::Runtime &rt,
|
|
|
607
606
|
entryPoint = args[2].asString(rt).utf8(rt);
|
|
608
607
|
}
|
|
609
608
|
|
|
610
|
-
auto result =
|
|
609
|
+
auto result = opsqlite_load_extension(db_name, path, entryPoint);
|
|
611
610
|
if (result.type == SQLiteError) {
|
|
612
611
|
throw std::runtime_error(result.message);
|
|
613
612
|
}
|
package/cpp/bridge.cpp
CHANGED
|
@@ -3,52 +3,56 @@
|
|
|
3
3
|
#include "SmartHostObject.h"
|
|
4
4
|
#include "logs.h"
|
|
5
5
|
#include "utils.h"
|
|
6
|
-
#include <ctime>
|
|
7
6
|
#include <unordered_map>
|
|
8
7
|
#include <variant>
|
|
9
8
|
|
|
10
9
|
namespace opsqlite {
|
|
11
10
|
|
|
11
|
+
/// Maps to hold the different objects
|
|
12
12
|
std::unordered_map<std::string, sqlite3 *> dbMap =
|
|
13
13
|
std::unordered_map<std::string, sqlite3 *>();
|
|
14
|
-
std::unordered_map<std::string,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
14
|
+
std::unordered_map<std::string, UpdateCallback> updateCallbackMap =
|
|
15
|
+
std::unordered_map<std::string, UpdateCallback>();
|
|
16
|
+
|
|
17
|
+
std::unordered_map<std::string, CommitCallback> commitCallbackMap =
|
|
18
|
+
std::unordered_map<std::string, CommitCallback>();
|
|
19
|
+
|
|
20
|
+
std::unordered_map<std::string, RollbackCallback> rollbackCallbackMap =
|
|
21
|
+
std::unordered_map<std::string, RollbackCallback>();
|
|
22
|
+
|
|
23
|
+
inline void check_db_open(std::string const &db_name) {
|
|
24
|
+
if (dbMap.count(db_name) == 0) {
|
|
25
|
+
throw std::runtime_error("[OP-SQLite] DB is not open");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// Start of api
|
|
30
|
+
|
|
31
|
+
/// Returns the completely formed db path, but it also creates any sub-folders
|
|
32
|
+
/// along the way
|
|
33
|
+
std::string get_db_path(std::string const &db_name,
|
|
34
|
+
std::string const &location) {
|
|
35
|
+
|
|
36
|
+
if (location == ":memory:") {
|
|
37
|
+
return location;
|
|
35
38
|
}
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
|
|
40
|
+
mkdir(location);
|
|
41
|
+
return location + "/" + db_name;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
BridgeResult
|
|
41
|
-
|
|
44
|
+
BridgeResult opsqlite_open(std::string const &dbName,
|
|
45
|
+
std::string const &lastPath) {
|
|
42
46
|
std::string dbPath = get_db_path(dbName, lastPath);
|
|
43
47
|
|
|
44
48
|
int sqlOpenFlags =
|
|
45
49
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
|
|
46
50
|
|
|
47
51
|
sqlite3 *db;
|
|
48
|
-
int exit = 0;
|
|
49
|
-
exit = sqlite3_open_v2(dbPath.c_str(), &db, sqlOpenFlags, nullptr);
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
int status = sqlite3_open_v2(dbPath.c_str(), &db, sqlOpenFlags, nullptr);
|
|
54
|
+
|
|
55
|
+
if (status != SQLITE_OK) {
|
|
52
56
|
return {.type = SQLiteError, .message = sqlite3_errmsg(db)};
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -57,14 +61,9 @@ BridgeResult sqlite_open(std::string const &dbName,
|
|
|
57
61
|
return BridgeResult{.type = SQLiteOk, .affectedRows = 0};
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
BridgeResult
|
|
64
|
+
BridgeResult opsqlite_close(std::string const &dbName) {
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
.type = SQLiteError,
|
|
65
|
-
.message = dbName + " is not open",
|
|
66
|
-
};
|
|
67
|
-
}
|
|
66
|
+
check_db_open(dbName);
|
|
68
67
|
|
|
69
68
|
sqlite3 *db = dbMap[dbName];
|
|
70
69
|
|
|
@@ -77,10 +76,10 @@ BridgeResult sqlite_close(std::string const &dbName) {
|
|
|
77
76
|
};
|
|
78
77
|
}
|
|
79
78
|
|
|
80
|
-
BridgeResult
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
BridgeResult opsqlite_attach(std::string const &mainDBName,
|
|
80
|
+
std::string const &docPath,
|
|
81
|
+
std::string const &databaseToAttach,
|
|
82
|
+
std::string const &alias) {
|
|
84
83
|
/**
|
|
85
84
|
* There is no need to check if mainDBName is opened because
|
|
86
85
|
* sqliteExecuteLiteral will do that.
|
|
@@ -88,7 +87,7 @@ BridgeResult sqlite_attach(std::string const &mainDBName,
|
|
|
88
87
|
std::string dbPath = get_db_path(databaseToAttach, docPath);
|
|
89
88
|
std::string statement = "ATTACH DATABASE '" + dbPath + "' AS " + alias;
|
|
90
89
|
|
|
91
|
-
BridgeResult result =
|
|
90
|
+
BridgeResult result = opsqlite_execute_literal(mainDBName, statement);
|
|
92
91
|
|
|
93
92
|
if (result.type == SQLiteError) {
|
|
94
93
|
return {
|
|
@@ -102,14 +101,14 @@ BridgeResult sqlite_attach(std::string const &mainDBName,
|
|
|
102
101
|
};
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
BridgeResult
|
|
106
|
-
|
|
104
|
+
BridgeResult opsqlite_detach(std::string const &mainDBName,
|
|
105
|
+
std::string const &alias) {
|
|
107
106
|
/**
|
|
108
107
|
* There is no need to check if mainDBName is opened because
|
|
109
108
|
* sqliteExecuteLiteral will do that.
|
|
110
109
|
* */
|
|
111
110
|
std::string statement = "DETACH DATABASE " + alias;
|
|
112
|
-
BridgeResult result =
|
|
111
|
+
BridgeResult result = opsqlite_execute_literal(mainDBName, statement);
|
|
113
112
|
if (result.type == SQLiteError) {
|
|
114
113
|
return BridgeResult{
|
|
115
114
|
.type = SQLiteError,
|
|
@@ -122,10 +121,10 @@ BridgeResult sqlite_detach(std::string const &mainDBName,
|
|
|
122
121
|
};
|
|
123
122
|
}
|
|
124
123
|
|
|
125
|
-
BridgeResult
|
|
126
|
-
|
|
124
|
+
BridgeResult opsqlite_remove(std::string const &dbName,
|
|
125
|
+
std::string const &docPath) {
|
|
127
126
|
if (dbMap.count(dbName) == 1) {
|
|
128
|
-
BridgeResult closeResult =
|
|
127
|
+
BridgeResult closeResult = opsqlite_close(dbName);
|
|
129
128
|
if (closeResult.type == SQLiteError) {
|
|
130
129
|
return closeResult;
|
|
131
130
|
}
|
|
@@ -145,8 +144,8 @@ BridgeResult sqlite_remove(std::string const &dbName,
|
|
|
145
144
|
};
|
|
146
145
|
}
|
|
147
146
|
|
|
148
|
-
inline void
|
|
149
|
-
|
|
147
|
+
inline void opsqlite_bind_statement(sqlite3_stmt *statement,
|
|
148
|
+
const std::vector<JSVariant> *values) {
|
|
150
149
|
size_t size = values->size();
|
|
151
150
|
|
|
152
151
|
for (int ii = 0; ii < size; ii++) {
|
|
@@ -175,19 +174,12 @@ inline void bindStatement(sqlite3_stmt *statement,
|
|
|
175
174
|
}
|
|
176
175
|
}
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
const std::vector<JSVariant> *params) {
|
|
180
|
-
bindStatement(statement, params);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
BridgeResult sqlite_execute_prepared_statement(
|
|
177
|
+
BridgeResult opsqlite_execute_prepared_statement(
|
|
184
178
|
std::string const &dbName, sqlite3_stmt *statement,
|
|
185
179
|
std::vector<DumbHostObject> *results,
|
|
186
180
|
std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
.message = "[op-sqlite]: Database " + dbName + " is not open"};
|
|
190
|
-
}
|
|
181
|
+
|
|
182
|
+
check_db_open(dbName);
|
|
191
183
|
|
|
192
184
|
sqlite3_reset(statement);
|
|
193
185
|
|
|
@@ -319,11 +311,9 @@ BridgeResult sqlite_execute_prepared_statement(
|
|
|
319
311
|
.insertId = static_cast<double>(latestInsertRowId)};
|
|
320
312
|
}
|
|
321
313
|
|
|
322
|
-
sqlite3_stmt *
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
throw std::runtime_error("Database not opened");
|
|
326
|
-
}
|
|
314
|
+
sqlite3_stmt *opsqlite_prepare_statement(std::string const &dbName,
|
|
315
|
+
std::string const &query) {
|
|
316
|
+
check_db_open(dbName);
|
|
327
317
|
|
|
328
318
|
sqlite3 *db = dbMap[dbName];
|
|
329
319
|
|
|
@@ -342,16 +332,14 @@ sqlite3_stmt *sqlite_prepare_statement(std::string const &dbName,
|
|
|
342
332
|
return statement;
|
|
343
333
|
}
|
|
344
334
|
|
|
335
|
+
/// Base execution function, returns HostObjects to the JS environment
|
|
345
336
|
BridgeResult
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
337
|
+
opsqlite_execute(std::string const &dbName, std::string const &query,
|
|
338
|
+
const std::vector<JSVariant> *params,
|
|
339
|
+
std::vector<DumbHostObject> *results,
|
|
340
|
+
std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
|
|
350
341
|
|
|
351
|
-
|
|
352
|
-
return {.type = SQLiteError,
|
|
353
|
-
.message = "[op-sqlite]: Database " + dbName + " is not open"};
|
|
354
|
-
}
|
|
342
|
+
check_db_open(dbName);
|
|
355
343
|
|
|
356
344
|
sqlite3 *db = dbMap[dbName];
|
|
357
345
|
|
|
@@ -389,7 +377,7 @@ sqlite_execute(std::string const &dbName, std::string const &query,
|
|
|
389
377
|
}
|
|
390
378
|
|
|
391
379
|
if (params != nullptr && params->size() > 0) {
|
|
392
|
-
|
|
380
|
+
opsqlite_bind_statement(statement, params);
|
|
393
381
|
}
|
|
394
382
|
|
|
395
383
|
isConsuming = true;
|
|
@@ -518,15 +506,14 @@ sqlite_execute(std::string const &dbName, std::string const &query,
|
|
|
518
506
|
.insertId = static_cast<double>(latestInsertRowId)};
|
|
519
507
|
}
|
|
520
508
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
509
|
+
/// Executes returning data in raw arrays, a small performance optimization for
|
|
510
|
+
/// certain use cases
|
|
511
|
+
BridgeResult
|
|
512
|
+
opsqlite_execute_raw(std::string const &dbName, std::string const &query,
|
|
513
|
+
const std::vector<JSVariant> *params,
|
|
514
|
+
std::vector<std::vector<JSVariant>> *results) {
|
|
525
515
|
|
|
526
|
-
|
|
527
|
-
return {.type = SQLiteError,
|
|
528
|
-
.message = "[op-sqlite]: Database " + dbName + " is not open"};
|
|
529
|
-
}
|
|
516
|
+
check_db_open(dbName);
|
|
530
517
|
|
|
531
518
|
sqlite3 *db = dbMap[dbName];
|
|
532
519
|
|
|
@@ -564,7 +551,7 @@ BridgeResult sqlite_execute_raw(std::string const &dbName,
|
|
|
564
551
|
}
|
|
565
552
|
|
|
566
553
|
if (params != nullptr && params->size() > 0) {
|
|
567
|
-
|
|
554
|
+
opsqlite_bind_statement(statement, params);
|
|
568
555
|
}
|
|
569
556
|
|
|
570
557
|
isConsuming = true;
|
|
@@ -619,8 +606,6 @@ BridgeResult sqlite_execute_raw(std::string const &dbName,
|
|
|
619
606
|
int blob_size = sqlite3_column_bytes(statement, i);
|
|
620
607
|
const void *blob = sqlite3_column_blob(statement, i);
|
|
621
608
|
uint8_t *data = new uint8_t[blob_size];
|
|
622
|
-
// You cannot share raw memory between native and JS
|
|
623
|
-
// always copy the data
|
|
624
609
|
memcpy(data, blob, blob_size);
|
|
625
610
|
row.push_back(
|
|
626
611
|
JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
@@ -676,11 +661,11 @@ BridgeResult sqlite_execute_raw(std::string const &dbName,
|
|
|
676
661
|
.insertId = static_cast<double>(latestInsertRowId)};
|
|
677
662
|
}
|
|
678
663
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
664
|
+
/// Executes without returning any results, Useful for performance critical
|
|
665
|
+
/// operations
|
|
666
|
+
BridgeResult opsqlite_execute_literal(std::string const &dbName,
|
|
667
|
+
std::string const &query) {
|
|
668
|
+
check_db_open(dbName);
|
|
684
669
|
|
|
685
670
|
sqlite3 *db = dbMap[dbName];
|
|
686
671
|
sqlite3_stmt *statement;
|
|
@@ -730,7 +715,7 @@ BridgeResult sqlite_execute_literal(std::string const &dbName,
|
|
|
730
715
|
return {SQLiteOk, "", changedRowCount};
|
|
731
716
|
}
|
|
732
717
|
|
|
733
|
-
void
|
|
718
|
+
void opsqlite_close_all() {
|
|
734
719
|
for (auto const &x : dbMap) {
|
|
735
720
|
// Interrupt will make all pending operations to fail with SQLITE_INTERRUPT
|
|
736
721
|
// The ongoing work from threads will then fail ASAP
|
|
@@ -768,13 +753,9 @@ void update_callback(void *dbName, int operation_type, char const *database,
|
|
|
768
753
|
static_cast<int>(rowid));
|
|
769
754
|
}
|
|
770
755
|
|
|
771
|
-
BridgeResult
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
std::string operation, int rowId)> const callback) {
|
|
775
|
-
if (dbMap.count(dbName) == 0) {
|
|
776
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
777
|
-
}
|
|
756
|
+
BridgeResult opsqlite_register_update_hook(std::string const &dbName,
|
|
757
|
+
UpdateCallback const callback) {
|
|
758
|
+
check_db_open(dbName);
|
|
778
759
|
|
|
779
760
|
sqlite3 *db = dbMap[dbName];
|
|
780
761
|
updateCallbackMap[dbName] = callback;
|
|
@@ -792,10 +773,8 @@ BridgeResult sqlite_register_update_hook(
|
|
|
792
773
|
return {SQLiteOk};
|
|
793
774
|
}
|
|
794
775
|
|
|
795
|
-
BridgeResult
|
|
796
|
-
|
|
797
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
798
|
-
}
|
|
776
|
+
BridgeResult opsqlite_deregister_update_hook(std::string const &dbName) {
|
|
777
|
+
check_db_open(dbName);
|
|
799
778
|
|
|
800
779
|
sqlite3 *db = dbMap[dbName];
|
|
801
780
|
updateCallbackMap.erase(dbName);
|
|
@@ -813,12 +792,9 @@ int commit_callback(void *dbName) {
|
|
|
813
792
|
return 0;
|
|
814
793
|
}
|
|
815
794
|
|
|
816
|
-
BridgeResult
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
if (dbMap.count(dbName) == 0) {
|
|
820
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
821
|
-
}
|
|
795
|
+
BridgeResult opsqlite_register_commit_hook(std::string const &dbName,
|
|
796
|
+
CommitCallback const callback) {
|
|
797
|
+
check_db_open(dbName);
|
|
822
798
|
|
|
823
799
|
sqlite3 *db = dbMap[dbName];
|
|
824
800
|
commitCallbackMap[dbName] = callback;
|
|
@@ -836,10 +812,8 @@ BridgeResult sqlite_register_commit_hook(
|
|
|
836
812
|
return {SQLiteOk};
|
|
837
813
|
}
|
|
838
814
|
|
|
839
|
-
BridgeResult
|
|
840
|
-
|
|
841
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
842
|
-
}
|
|
815
|
+
BridgeResult opsqlite_deregister_commit_hook(std::string const &dbName) {
|
|
816
|
+
check_db_open(dbName);
|
|
843
817
|
|
|
844
818
|
sqlite3 *db = dbMap[dbName];
|
|
845
819
|
commitCallbackMap.erase(dbName);
|
|
@@ -854,12 +828,9 @@ void rollback_callback(void *dbName) {
|
|
|
854
828
|
callback(strDbName);
|
|
855
829
|
}
|
|
856
830
|
|
|
857
|
-
BridgeResult
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
if (dbMap.count(dbName) == 0) {
|
|
861
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
862
|
-
}
|
|
831
|
+
BridgeResult opsqlite_register_rollback_hook(std::string const &dbName,
|
|
832
|
+
RollbackCallback const callback) {
|
|
833
|
+
check_db_open(dbName);
|
|
863
834
|
|
|
864
835
|
sqlite3 *db = dbMap[dbName];
|
|
865
836
|
rollbackCallbackMap[dbName] = callback;
|
|
@@ -877,10 +848,8 @@ BridgeResult sqlite_register_rollback_hook(
|
|
|
877
848
|
return {SQLiteOk};
|
|
878
849
|
}
|
|
879
850
|
|
|
880
|
-
BridgeResult
|
|
881
|
-
|
|
882
|
-
return {SQLiteError, "[op-sqlite] Database not opened: " + dbName};
|
|
883
|
-
}
|
|
851
|
+
BridgeResult opsqlite_deregister_rollback_hook(std::string const &dbName) {
|
|
852
|
+
check_db_open(dbName);
|
|
884
853
|
|
|
885
854
|
sqlite3 *db = dbMap[dbName];
|
|
886
855
|
rollbackCallbackMap.erase(dbName);
|
|
@@ -890,11 +859,13 @@ BridgeResult sqlite_deregister_rollback_hook(std::string const &dbName) {
|
|
|
890
859
|
return {SQLiteOk};
|
|
891
860
|
}
|
|
892
861
|
|
|
893
|
-
BridgeResult
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
862
|
+
BridgeResult opsqlite_load_extension(std::string &db_name, std::string &path,
|
|
863
|
+
std::string &entry_point) {
|
|
864
|
+
#ifdef OP_SQLITE_USE_PHONE_VERSION
|
|
865
|
+
throw std::runtime_error(
|
|
866
|
+
"Embedded version of SQLite does not support loading extensions");
|
|
867
|
+
#else
|
|
868
|
+
check_db_open(db_name);
|
|
898
869
|
|
|
899
870
|
sqlite3 *db = dbMap[db_name];
|
|
900
871
|
int loading_extensions_enabled = sqlite3_enable_load_extension(db, 1);
|
|
@@ -915,6 +886,7 @@ BridgeResult sqlite_load_extension(std::string &db_name, std::string &path,
|
|
|
915
886
|
return {SQLiteError, std::string(error_message)};
|
|
916
887
|
}
|
|
917
888
|
return {SQLiteOk};
|
|
889
|
+
#endif
|
|
918
890
|
}
|
|
919
891
|
|
|
920
892
|
} // namespace opsqlite
|