@op-engineering/op-sqlite 2.0.22 → 3.0.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.
- package/android/CMakeLists.txt +25 -5
- package/android/build.gradle +14 -6
- package/cpp/bindings.cpp +59 -17
- package/cpp/bridge.cpp +29 -18
- package/cpp/bridge.h +8 -0
- package/cpp/sqlcipher/sqlite3.c +253047 -0
- package/cpp/sqlcipher/sqlite3.h +13029 -0
- package/lib/commonjs/index.js +6 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +6 -5
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +8 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/op-sqlite.podspec +20 -8
- package/package.json +1 -1
- package/src/index.ts +17 -5
package/android/CMakeLists.txt
CHANGED
|
@@ -6,9 +6,10 @@ set (CMAKE_VERBOSE_MAKEFILE ON)
|
|
|
6
6
|
set (CMAKE_CXX_STANDARD 17)
|
|
7
7
|
set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
|
|
8
8
|
|
|
9
|
-
include_directories(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
include_directories(
|
|
10
|
+
../cpp
|
|
11
|
+
../cpp/sqlcipher
|
|
12
|
+
)
|
|
12
13
|
|
|
13
14
|
add_definitions(
|
|
14
15
|
${SQLITE_FLAGS}
|
|
@@ -21,8 +22,6 @@ add_library(
|
|
|
21
22
|
../cpp/bridge.h
|
|
22
23
|
../cpp/bindings.cpp
|
|
23
24
|
../cpp/bindings.h
|
|
24
|
-
../cpp/sqlite3.h
|
|
25
|
-
../cpp/sqlite3.c
|
|
26
25
|
../cpp/utils.h
|
|
27
26
|
../cpp/utils.cpp
|
|
28
27
|
../cpp/ThreadPool.h
|
|
@@ -40,6 +39,20 @@ add_library(
|
|
|
40
39
|
cpp-adapter.cpp
|
|
41
40
|
)
|
|
42
41
|
|
|
42
|
+
if (OP_SQLITE_USE_SQLCIPHER)
|
|
43
|
+
target_sources(${PACKAGE_NAME} PRIVATE ../cpp/sqlcipher/sqlite3.h ../cpp/sqlcipher/sqlite3.c)
|
|
44
|
+
|
|
45
|
+
add_definitions(
|
|
46
|
+
-DOP_SQLITE_USE_SQLCIPHER
|
|
47
|
+
-DSQLITE_HAS_CODEC
|
|
48
|
+
-DSQLITE_TEMP_STORE=2
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
find_package(openssl REQUIRED CONFIG)
|
|
52
|
+
else()
|
|
53
|
+
target_sources(${PACKAGE_NAME} PRIVATE ../cpp/sqlite3.h ../cpp/sqlite3.c)
|
|
54
|
+
endif()
|
|
55
|
+
|
|
43
56
|
set_target_properties(
|
|
44
57
|
${PACKAGE_NAME} PROPERTIES
|
|
45
58
|
CXX_STANDARD 17
|
|
@@ -49,12 +62,19 @@ set_target_properties(
|
|
|
49
62
|
|
|
50
63
|
find_package(ReactAndroid REQUIRED CONFIG)
|
|
51
64
|
find_package(fbjni REQUIRED CONFIG)
|
|
65
|
+
find_library(LOG_LIB log)
|
|
66
|
+
|
|
52
67
|
|
|
53
68
|
target_link_libraries(
|
|
54
69
|
${PACKAGE_NAME}
|
|
70
|
+
${LOG_LIB}
|
|
55
71
|
fbjni::fbjni
|
|
56
72
|
ReactAndroid::jsi
|
|
57
73
|
ReactAndroid::turbomodulejsijni
|
|
58
74
|
ReactAndroid::react_nativemodule_core
|
|
59
75
|
android
|
|
60
76
|
)
|
|
77
|
+
|
|
78
|
+
if (OP_SQLITE_USE_SQLCIPHER)
|
|
79
|
+
target_link_libraries(${PACKAGE_NAME} PRIVATE openssl::crypto)
|
|
80
|
+
endif()
|
package/android/build.gradle
CHANGED
|
@@ -78,17 +78,23 @@ android {
|
|
|
78
78
|
cmake {
|
|
79
79
|
if(System.getenv("OP_SQLITE_PERF") == '1') {
|
|
80
80
|
println "OP-SQLITE performance mode enabled! 🚀"
|
|
81
|
-
cFlags "-DSQLITE_DQS=0", "-DSQLITE_THREADSAFE=0", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1"
|
|
81
|
+
cFlags += ["-DSQLITE_DQS=0", "-DSQLITE_THREADSAFE=0", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1"]
|
|
82
82
|
}
|
|
83
83
|
if(System.getenv("OP_SQLITE_PERF") == '2') {
|
|
84
84
|
println "OP-SQLITE (thread safe) performance mode enabled! 🚀"
|
|
85
|
-
cFlags "-DSQLITE_DQS=0", "-DSQLITE_THREADSAFE=1", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1"
|
|
85
|
+
cFlags += ["-DSQLITE_DQS=0", "-DSQLITE_THREADSAFE=1", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1"]
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
if(System.getenv("OP_SQLITE_USE_SQLCIPHER") == '1') {
|
|
89
|
+
println "OP-SQLITE using SQLCipher! 🔒"
|
|
90
|
+
cFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
cppFlags "-O2", "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
|
88
94
|
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
|
89
|
-
arguments
|
|
90
|
-
"-DSQLITE_FLAGS='${SQLITE_FLAGS ? SQLITE_FLAGS : ''}'"
|
|
91
|
-
"-
|
|
95
|
+
arguments "-DANDROID_STL=c++_shared",
|
|
96
|
+
"-DSQLITE_FLAGS='${SQLITE_FLAGS ? SQLITE_FLAGS : ''}'"
|
|
97
|
+
"-DOP_SQLITE_USE_SQLCIPHER='${System.getenv("OP_SQLITE_USE_SQLCIPHER") == '1'? 1 : 0}'"
|
|
92
98
|
abiFilters (*reactNativeArchitectures())
|
|
93
99
|
}
|
|
94
100
|
}
|
|
@@ -134,10 +140,12 @@ repositories {
|
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
137
|
-
|
|
138
143
|
dependencies {
|
|
139
144
|
implementation 'com.facebook.react:react-native'
|
|
140
145
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
146
|
+
if (System.getenv("OP_SQLITE_USE_SQLCIPHER") == '1') {
|
|
147
|
+
implementation('com.android.ndk.thirdparty:openssl:1.1.1q-beta-1')
|
|
148
|
+
}
|
|
141
149
|
}
|
|
142
150
|
|
|
143
151
|
// Resolves "LOCAL_SRC_FILES points to a missing file, Check that libfb.so exists or that its path is correct".
|
package/cpp/bindings.cpp
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
#include "sqlbatchexecutor.h"
|
|
9
9
|
#include "utils.h"
|
|
10
10
|
#include <iostream>
|
|
11
|
-
#include <sqlite3.h>
|
|
12
11
|
#include <string>
|
|
13
12
|
#include <unordered_map>
|
|
14
13
|
#include <vector>
|
|
@@ -55,32 +54,50 @@ void install(jsi::Runtime &rt,
|
|
|
55
54
|
throw std::runtime_error("[op-sqlite][open] database name is required");
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"[op-sqlite][open] database name must be a string");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
57
|
+
jsi::Object options = args[0].asObject(rt);
|
|
58
|
+
std::string dbName = options.getProperty(rt, "name").asString(rt).utf8(rt);
|
|
64
59
|
std::string path = std::string(basePath);
|
|
60
|
+
std::string location;
|
|
61
|
+
std::string encryptionKey;
|
|
65
62
|
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"[op-sqlite][open] database location must be a string");
|
|
70
|
-
}
|
|
63
|
+
if (options.hasProperty(rt, "location")) {
|
|
64
|
+
location = options.getProperty(rt, "location").asString(rt).utf8(rt);
|
|
65
|
+
}
|
|
71
66
|
|
|
72
|
-
|
|
67
|
+
if (options.hasProperty(rt, "encryptionKey")) {
|
|
68
|
+
encryptionKey =
|
|
69
|
+
options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
|
|
70
|
+
}
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
73
|
+
if (encryptionKey.empty()) {
|
|
74
|
+
throw std::runtime_error(
|
|
75
|
+
"[OP SQLite] using SQLCipher encryption key is required");
|
|
76
|
+
}
|
|
77
|
+
// TODO(osp) find a way to display the yellow box from c++
|
|
78
|
+
#else
|
|
79
|
+
// if (!encryptionKey.empty()) {
|
|
80
|
+
// // RCTLogWarn(@"Your message")
|
|
81
|
+
// throw std::runtime_error("[OP SQLite] SQLCipher is not enabled, "
|
|
82
|
+
// "encryption key is not allowed");
|
|
83
|
+
// }
|
|
84
|
+
#endif
|
|
85
|
+
|
|
86
|
+
if (!location.empty()) {
|
|
87
|
+
if (location == ":memory:") {
|
|
75
88
|
path = ":memory:";
|
|
76
|
-
} else if (
|
|
77
|
-
path =
|
|
89
|
+
} else if (location.rfind("/", 0) == 0) {
|
|
90
|
+
path = location;
|
|
78
91
|
} else {
|
|
79
|
-
path = path + "/" +
|
|
92
|
+
path = path + "/" + location;
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
97
|
+
BridgeResult result = opsqlite_open(dbName, path, encryptionKey);
|
|
98
|
+
#else
|
|
83
99
|
BridgeResult result = opsqlite_open(dbName, path);
|
|
100
|
+
#endif
|
|
84
101
|
|
|
85
102
|
if (result.type == SQLiteError) {
|
|
86
103
|
throw std::runtime_error(result.message);
|
|
@@ -618,6 +635,30 @@ void install(jsi::Runtime &rt,
|
|
|
618
635
|
return {};
|
|
619
636
|
});
|
|
620
637
|
|
|
638
|
+
auto get_db_path = HOSTFN("getDbPath", 2) {
|
|
639
|
+
std::string db_name = args[0].asString(rt).utf8(rt);
|
|
640
|
+
std::string path = std::string(basePath);
|
|
641
|
+
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
642
|
+
if (!args[1].isString()) {
|
|
643
|
+
throw std::runtime_error(
|
|
644
|
+
"[op-sqlite][open] database location must be a string");
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
std::string lastPath = args[1].asString(rt).utf8(rt);
|
|
648
|
+
|
|
649
|
+
if (lastPath == ":memory:") {
|
|
650
|
+
path = ":memory:";
|
|
651
|
+
} else if (lastPath.rfind("/", 0) == 0) {
|
|
652
|
+
path = lastPath;
|
|
653
|
+
} else {
|
|
654
|
+
path = path + "/" + lastPath;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
auto result = opsqlite_get_db_path(db_name, path);
|
|
659
|
+
return jsi::String::createFromUtf8(rt, result);
|
|
660
|
+
});
|
|
661
|
+
|
|
621
662
|
jsi::Object module = jsi::Object(rt);
|
|
622
663
|
|
|
623
664
|
module.setProperty(rt, "open", std::move(open));
|
|
@@ -636,6 +677,7 @@ void install(jsi::Runtime &rt,
|
|
|
636
677
|
module.setProperty(rt, "prepareStatement", std::move(prepare_statement));
|
|
637
678
|
module.setProperty(rt, "loadExtension", std::move(load_extension));
|
|
638
679
|
module.setProperty(rt, "executeRawAsync", std::move(execute_raw_async));
|
|
680
|
+
module.setProperty(rt, "getDbPath", std::move(get_db_path));
|
|
639
681
|
|
|
640
682
|
rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
|
|
641
683
|
}
|
package/cpp/bridge.cpp
CHANGED
|
@@ -30,8 +30,8 @@ inline void check_db_open(std::string const &db_name) {
|
|
|
30
30
|
|
|
31
31
|
/// Returns the completely formed db path, but it also creates any sub-folders
|
|
32
32
|
/// along the way
|
|
33
|
-
std::string
|
|
34
|
-
|
|
33
|
+
std::string opsqlite_get_db_path(std::string const &db_name,
|
|
34
|
+
std::string const &location) {
|
|
35
35
|
|
|
36
36
|
if (location == ":memory:") {
|
|
37
37
|
return location;
|
|
@@ -41,9 +41,15 @@ std::string get_db_path(std::string const &db_name,
|
|
|
41
41
|
return location + "/" + db_name;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
44
45
|
BridgeResult opsqlite_open(std::string const &dbName,
|
|
45
|
-
std::string const &
|
|
46
|
-
|
|
46
|
+
std::string const &last_path,
|
|
47
|
+
std::string const &encryptionKey) {
|
|
48
|
+
#else
|
|
49
|
+
BridgeResult opsqlite_open(std::string const &dbName,
|
|
50
|
+
std::string const &last_path) {
|
|
51
|
+
#endif
|
|
52
|
+
std::string dbPath = opsqlite_get_db_path(dbName, last_path);
|
|
47
53
|
|
|
48
54
|
int sqlOpenFlags =
|
|
49
55
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
|
|
@@ -58,6 +64,11 @@ BridgeResult opsqlite_open(std::string const &dbName,
|
|
|
58
64
|
|
|
59
65
|
dbMap[dbName] = db;
|
|
60
66
|
|
|
67
|
+
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
68
|
+
opsqlite_execute(dbName, "PRAGMA key = '" + encryptionKey + "'", nullptr,
|
|
69
|
+
nullptr, nullptr);
|
|
70
|
+
#endif
|
|
71
|
+
|
|
61
72
|
return BridgeResult{.type = SQLiteOk, .affectedRows = 0};
|
|
62
73
|
}
|
|
63
74
|
|
|
@@ -80,7 +91,7 @@ BridgeResult opsqlite_attach(std::string const &mainDBName,
|
|
|
80
91
|
std::string const &docPath,
|
|
81
92
|
std::string const &databaseToAttach,
|
|
82
93
|
std::string const &alias) {
|
|
83
|
-
std::string dbPath =
|
|
94
|
+
std::string dbPath = opsqlite_get_db_path(databaseToAttach, docPath);
|
|
84
95
|
std::string statement = "ATTACH DATABASE '" + dbPath + "' AS " + alias;
|
|
85
96
|
|
|
86
97
|
BridgeResult result =
|
|
@@ -124,7 +135,7 @@ BridgeResult opsqlite_remove(std::string const &dbName,
|
|
|
124
135
|
}
|
|
125
136
|
}
|
|
126
137
|
|
|
127
|
-
std::string dbPath =
|
|
138
|
+
std::string dbPath = opsqlite_get_db_path(dbName, docPath);
|
|
128
139
|
|
|
129
140
|
if (!file_exists(dbPath)) {
|
|
130
141
|
return {.type = SQLiteError,
|
|
@@ -321,7 +332,7 @@ sqlite3_stmt *opsqlite_prepare_statement(std::string const &dbName,
|
|
|
321
332
|
|
|
322
333
|
if (statementStatus == SQLITE_ERROR) {
|
|
323
334
|
const char *message = sqlite3_errmsg(db);
|
|
324
|
-
throw std::runtime_error("[op-sqlite] SQL statement error: " +
|
|
335
|
+
throw std::runtime_error("[op-sqlite] SQL prepare statement error: " +
|
|
325
336
|
std::string(message));
|
|
326
337
|
}
|
|
327
338
|
|
|
@@ -359,15 +370,15 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
|
|
|
359
370
|
const char *message = sqlite3_errmsg(db);
|
|
360
371
|
return {
|
|
361
372
|
.type = SQLiteError,
|
|
362
|
-
.message = "[op-sqlite] SQL statement error
|
|
363
|
-
std::to_string(statementStatus) +
|
|
364
|
-
|
|
373
|
+
.message = "[op-sqlite] SQL statement error on opsqlite_execute:\n" +
|
|
374
|
+
std::to_string(statementStatus) + " description:\n" +
|
|
375
|
+
std::string(message) +
|
|
365
376
|
". See error codes: https://www.sqlite.org/rescode.html",
|
|
366
377
|
};
|
|
367
378
|
}
|
|
368
379
|
|
|
369
|
-
// The statement did not fail to parse but there is nothing to do, just
|
|
370
|
-
// to the end
|
|
380
|
+
// The statement did not fail to parse but there is nothing to do, just
|
|
381
|
+
// skip to the end
|
|
371
382
|
if (statement == NULL) {
|
|
372
383
|
continue;
|
|
373
384
|
}
|
|
@@ -502,8 +513,8 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
|
|
|
502
513
|
.insertId = static_cast<double>(latestInsertRowId)};
|
|
503
514
|
}
|
|
504
515
|
|
|
505
|
-
/// Executes returning data in raw arrays, a small performance optimization
|
|
506
|
-
/// certain use cases
|
|
516
|
+
/// Executes returning data in raw arrays, a small performance optimization
|
|
517
|
+
/// for certain use cases
|
|
507
518
|
BridgeResult
|
|
508
519
|
opsqlite_execute_raw(std::string const &dbName, std::string const &query,
|
|
509
520
|
const std::vector<JSVariant> *params,
|
|
@@ -540,8 +551,8 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
|
|
|
540
551
|
};
|
|
541
552
|
}
|
|
542
553
|
|
|
543
|
-
// The statement did not fail to parse but there is nothing to do, just
|
|
544
|
-
// to the end
|
|
554
|
+
// The statement did not fail to parse but there is nothing to do, just
|
|
555
|
+
// skip to the end
|
|
545
556
|
if (statement == NULL) {
|
|
546
557
|
continue;
|
|
547
558
|
}
|
|
@@ -661,8 +672,8 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
|
|
|
661
672
|
|
|
662
673
|
void opsqlite_close_all() {
|
|
663
674
|
for (auto const &x : dbMap) {
|
|
664
|
-
// Interrupt will make all pending operations to fail with
|
|
665
|
-
// The ongoing work from threads will then fail ASAP
|
|
675
|
+
// Interrupt will make all pending operations to fail with
|
|
676
|
+
// SQLITE_INTERRUPT The ongoing work from threads will then fail ASAP
|
|
666
677
|
sqlite3_interrupt(x.second);
|
|
667
678
|
// Each DB connection can then be safely interrupted
|
|
668
679
|
sqlite3_close_v2(x.second);
|
package/cpp/bridge.h
CHANGED
|
@@ -19,8 +19,16 @@ typedef std::function<void(std::string dbName, std::string tableName,
|
|
|
19
19
|
typedef std::function<void(std::string dbName)> CommitCallback;
|
|
20
20
|
typedef std::function<void(std::string dbName)> RollbackCallback;
|
|
21
21
|
|
|
22
|
+
std::string opsqlite_get_db_path(std::string const &db_name,
|
|
23
|
+
std::string const &location);
|
|
24
|
+
|
|
25
|
+
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
26
|
+
BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
|
|
27
|
+
std::string const &encryptionKey);
|
|
28
|
+
#else
|
|
22
29
|
BridgeResult opsqlite_open(std::string const &dbName,
|
|
23
30
|
std::string const &dbPath);
|
|
31
|
+
#endif
|
|
24
32
|
|
|
25
33
|
BridgeResult opsqlite_close(std::string const &dbName);
|
|
26
34
|
|