Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle crsqlite extension #80

Merged
merged 7 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .yarnrc

This file was deleted.

2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
nmHoistingLimits: workspaces

nodeLinker: node-modules
7 changes: 6 additions & 1 deletion android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ else()
target_sources(${PACKAGE_NAME} PRIVATE ../cpp/sqlite3.h ../cpp/sqlite3.c)
endif()

if (OP_SQLITE_USE_CRSQLITE)
add_definitions(
-DOP_SQLITE_USE_CRSQLITE
)
endif()

set_target_properties(
${PACKAGE_NAME} PROPERTIES
CXX_STANDARD 20
Expand All @@ -64,7 +70,6 @@ find_package(ReactAndroid REQUIRED CONFIG)
find_package(fbjni REQUIRED CONFIG)
find_library(LOG_LIB log)


target_link_libraries(
${PACKAGE_NAME}
${LOG_LIB}
Expand Down
8 changes: 7 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,20 @@ android {

if(System.getenv("OP_SQLITE_USE_SQLCIPHER") == '1') {
println "OP-SQLITE using SQLCipher! 🔒"
cFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
cppFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
}

if(System.getenv("OP_SQLITE_USE_CRSQLITE") == '1') {
println "OP-SQLITE using CR-SQLite! 🤖"
cppFlags += "-DOP_SQLITE_USE_CRSQLITE=1"
}

cppFlags "-O2", "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DANDROID_STL=c++_shared",
"-DSQLITE_FLAGS='${SQLITE_FLAGS ? SQLITE_FLAGS : ''}'"
"-DOP_SQLITE_USE_SQLCIPHER='${System.getenv("OP_SQLITE_USE_SQLCIPHER") == '1'? 1 : 0}'"
"-DOP_SQLITE_USE_CRSQLITE='${System.getenv("OP_SQLITE_USE_CRSQLITE") == '1'? 1 : 0}'"
abiFilters (*reactNativeArchitectures())
}
}
Expand Down
6 changes: 4 additions & 2 deletions android/cpp-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#include <jsi/jsi.h>
#include <typeinfo>

// This file is not using raw jni but rather fbjni, do not change how the native functions are registered
// This file is not using raw jni but rather fbjni, do not change how the native
// functions are registered
// https://github.com/facebookincubator/fbjni/blob/main/docs/quickref.md
struct OPSQLiteBridge : jni::JavaClass<OPSQLiteBridge> {
static constexpr auto kJavaDescriptor = "Lcom/op/sqlite/OPSQLiteBridge;";
Expand All @@ -27,7 +28,8 @@ struct OPSQLiteBridge : jni::JavaClass<OPSQLiteBridge> {
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
std::string dbPathStr = dbPath->toStdString();

opsqlite::install(*jsiRuntime, jsCallInvoker, dbPathStr.c_str());
opsqlite::install(*jsiRuntime, jsCallInvoker, dbPathStr.c_str(),
"libcrsqlite");
}

static void clearStateNativeJsi(jni::alias_ref<jni::JObject> thiz) {
Expand Down
Binary file added android/src/main/jniLibs/arm64-v8a/libcrsqlite.so
Binary file not shown.
Binary file not shown.
Binary file added android/src/main/jniLibs/x86/libcrsqlite.so
Binary file not shown.
Binary file added android/src/main/jniLibs/x86_64/libcrsqlite.so
Binary file not shown.
10 changes: 7 additions & 3 deletions cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace opsqlite {
namespace jsi = facebook::jsi;

std::string basePath;
std::string crsqlitePath;
std::shared_ptr<react::CallInvoker> invoker;
ThreadPool pool;
std::unordered_map<std::string, std::shared_ptr<jsi::Value>> updateHooks =
Expand Down Expand Up @@ -44,9 +45,11 @@ void clearState() {

void install(jsi::Runtime &rt,
std::shared_ptr<react::CallInvoker> jsCallInvoker,
const char *docPath) {
const char *docPath, const char *_crsqlitePath) {

invalidated = false;
basePath = std::string(docPath);
crsqlitePath = std::string(_crsqlitePath);
invoker = jsCallInvoker;

auto open = HOSTFN("open", 3) {
Expand Down Expand Up @@ -94,9 +97,10 @@ void install(jsi::Runtime &rt,
}

#ifdef OP_SQLITE_USE_SQLCIPHER
BridgeResult result = opsqlite_open(dbName, path, encryptionKey);
BridgeResult result =
opsqlite_open(dbName, path, crsqlitePath, encryptionKey);
#else
BridgeResult result = opsqlite_open(dbName, path);
BridgeResult result = opsqlite_open(dbName, path, crsqlitePath);
#endif

if (result.type == SQLiteError) {
Expand Down
2 changes: 1 addition & 1 deletion cpp/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace opsqlite {

void install(jsi::Runtime &rt,
std::shared_ptr<react::CallInvoker> jsCallInvoker,
const char *docPath);
const char *docPath, const char *crsqlitePath);
void clearState();

} // namespace opsqlite
34 changes: 31 additions & 3 deletions cpp/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "SmartHostObject.h"
#include "logs.h"
#include "utils.h"
#include <iostream>
#include <unordered_map>
#include <variant>

Expand All @@ -27,7 +28,12 @@ inline void check_db_open(std::string const &db_name) {
}
}

/// Start of api
// _____ _____
// /\ | __ \_ _|
// / \ | |__) || |
// / /\ \ | ___/ | |
// / ____ \| | _| |_
// /_/ \_\_| |_____|

/// Returns the completely formed db path, but it also creates any sub-folders
/// along the way
Expand All @@ -45,10 +51,12 @@ std::string opsqlite_get_db_path(std::string const &db_name,
#ifdef OP_SQLITE_USE_SQLCIPHER
BridgeResult opsqlite_open(std::string const &dbName,
std::string const &last_path,
std::string const &crsqlitePath,
std::string const &encryptionKey) {
#else
BridgeResult opsqlite_open(std::string const &dbName,
std::string const &last_path) {
std::string const &last_path,
std::string const &crsqlitePath) {
#endif
std::string dbPath = opsqlite_get_db_path(dbName, last_path);

Expand All @@ -70,7 +78,22 @@ BridgeResult opsqlite_open(std::string const &dbName,
nullptr, nullptr);
#endif

return BridgeResult{.type = SQLiteOk, .affectedRows = 0};
#ifdef OP_SQLITE_USE_CRSQLITE
char *errMsg;
const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";

sqlite3_enable_load_extension(db, 1);

sqlite3_load_extension(db, crsqlitePath.c_str(), crsqliteEntryPoint, &errMsg);

if (errMsg != nullptr) {
return {.type = SQLiteError, .message = errMsg};
} else {
LOGI("Loaded CRSQlite successfully");
}
#endif

return {.type = SQLiteOk, .affectedRows = 0};
}

BridgeResult opsqlite_close(std::string const &dbName) {
Expand All @@ -79,6 +102,11 @@ BridgeResult opsqlite_close(std::string const &dbName) {

sqlite3 *db = dbMap[dbName];

#ifdef OP_SQLITE_USE_CRSQLITE
opsqlite_execute(dbName, "select crsql_finalize();", nullptr, nullptr,
nullptr);
#endif

sqlite3_close_v2(db);

dbMap.erase(dbName);
Expand Down
5 changes: 3 additions & 2 deletions cpp/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ std::string opsqlite_get_db_path(std::string const &db_name,

#ifdef OP_SQLITE_USE_SQLCIPHER
BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
std::string const &crsqlitePath,
std::string const &encryptionKey);
#else
BridgeResult opsqlite_open(std::string const &dbName,
std::string const &dbPath);
BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
std::string const &crsqlitePath);
#endif

BridgeResult opsqlite_close(std::string const &dbName);
Expand Down
Binary file removed example/.yarn/install-state.gz
Binary file not shown.
15 changes: 11 additions & 4 deletions example/ios/OPSQLiteExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
6EE3066EB7AAB7E17B1CAB50 /* libPods-OPSQLiteExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OPSQLiteExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = OPSQLiteExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig"; path = "Target Support Files/Pods-OPSQLiteExample-OPSQLiteExampleTests/Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig"; sourceTree = "<group>"; };
96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = sample.sqlite; path = ../assets/sample.sqlite; sourceTree = "<group>"; };
96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = sample.sqlite; path = ../assets/sample.sqlite; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -104,7 +104,6 @@
96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */,
);
name = Resources;
path = "";
sourceTree = "<group>";
};
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
Expand Down Expand Up @@ -316,8 +315,13 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.op.sqlite.example;
PRODUCT_NAME = OPSQLiteExample;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
Expand All @@ -343,7 +347,12 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.op.sqlite.example;
PRODUCT_NAME = OPSQLiteExample;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
Expand Down Expand Up @@ -430,7 +439,6 @@
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
" ",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
Expand Down Expand Up @@ -516,7 +524,6 @@
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
" ",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
Expand Down
10 changes: 7 additions & 3 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ PODS:
- hermes-engine (0.74.0-rc.6):
- hermes-engine/Pre-built (= 0.74.0-rc.6)
- hermes-engine/Pre-built (0.74.0-rc.6)
- op-sqlite (3.0.7):
- op-sqlite (4.0.1):
- OpenSSL-Universal
- React
- React-callinvoker
- React-Core
- OpenSSL-Universal (3.1.5001)
- RCT-Folly (2024.01.01.00):
- boost
- DoubleConversion
Expand Down Expand Up @@ -1234,6 +1236,7 @@ DEPENDENCIES:

SPEC REPOS:
trunk:
- OpenSSL-Universal
- SocketRocket

EXTERNAL SOURCES:
Expand Down Expand Up @@ -1358,7 +1361,8 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
hermes-engine: 1a846a8f620a08c60f5f89aa65b8664f769f742f
op-sqlite: af2411e57364db634729dbd4d4b24d0a9d973ab7
op-sqlite: db0f4b35d0966f75b5722f1b42315faa7d1b78e2
OpenSSL-Universal: 29a9c9d4baf23f5fcd1294b657e4cc275e605bc3
RCT-Folly: 045d6ecaa59d826c5736dfba0b2f4083ff8d79df
RCTDeprecation: 82b53c4f460b7a5b27c6be8310a71bc84df583f5
RCTRequired: d1a99a9f78fcc4acca99ab397822f4e58601b134
Expand Down Expand Up @@ -1412,4 +1416,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 0ab74fecad6ac2e35f8eab32fe5772c19d2015b2

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios --simulator='iPhone 15' --scheme='debug'",
"ios": "react-native run-ios --scheme='debug'",
"start": "react-native start",
"pods": "cd ios && rm -rf Pods && rm -rf Podfile.lock && bundle exec pod install",
"build:android": "cd android && ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a",
Expand Down
21 changes: 1 addition & 20 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import {
View,
} from 'react-native';
import 'reflect-metadata';
import {
createLargeDB,
queryLargeDB,
querySingleRecordOnLargeDB,
} from './Database';
import {createLargeDB, queryLargeDB} from './Database';
import {dbSetupTests, queriesTests, runTests, blobTests} from './tests/index';
import {styled} from 'nativewind';
import {registerHooksTests} from './tests/hooks.spec';
Expand All @@ -37,7 +33,6 @@ export default function App() {
const [prepareExecutionTimes, setPrepareExecutionTimes] = useState<number[]>(
[],
);
const [singleRecordTime, setSingleRecordTime] = useState<number>(0);
const [rawExecutionTimes, setRawExecutionTimes] = useState<number[]>([]);
useEffect(() => {
setResults([]);
Expand All @@ -51,14 +46,6 @@ export default function App() {
).then(setResults);
}, []);

const querySingleRecord = async () => {
// let start = performance.now();
await querySingleRecordOnLargeDB();
// let end = performance.now();

// setSingleRecordTime(end - start);
};

const createLargeDb = async () => {
setIsLoading(true);
await createLargeDB();
Expand Down Expand Up @@ -119,12 +106,6 @@ export default function App() {
<Button title="Query 300k Records" onPress={queryLargeDb} />
{isLoading && <ActivityIndicator color={'white'} size="large" />}

{!!singleRecordTime && (
<Text className="text-lg text-white self-center">
Query single record time: {singleRecordTime.toFixed(2)}ms
</Text>
)}

{!!times.length && (
<Text className="text-lg text-white self-center">
Normal query{' '}
Expand Down
2 changes: 1 addition & 1 deletion example/src/UpdateHook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, {
useRef,
} from 'react';
import {ActivityIndicator, Text, View} from 'react-native';
import {OPSQLiteConnection, open} from '@op-engineering/op-sqlite';
import {type OPSQLiteConnection, open} from '@op-engineering/op-sqlite';

interface IDbContext {
db: OPSQLiteConnection;
Expand Down
2 changes: 1 addition & 1 deletion example/src/tests/MochaSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function runTests(...registrators: Array<() => void>) {
EVENT_TEST_FAIL,
EVENT_TEST_PASS,
EVENT_SUITE_BEGIN,
EVENT_SUITE_END,
// EVENT_SUITE_END,
} = Mocha.Runner.constants;

clearTests();
Expand Down
12 changes: 1 addition & 11 deletions example/src/tests/blob.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import {OPSQLiteConnection, open} from '@op-engineering/op-sqlite';
import {type OPSQLiteConnection, open} from '@op-engineering/op-sqlite';
import chai from 'chai';
import {beforeEach, describe, it} from './MochaRNAdapter';

let expect = chai.expect;

let db: OPSQLiteConnection;

function areBuffersEqual(buf1: ArrayBuffer, buf2: ArrayBuffer) {
if (buf1.byteLength != buf2.byteLength) return false;
var dv1 = new Uint8Array(buf1);
var dv2 = new Uint8Array(buf2);
for (var i = 0; i != buf1.byteLength; i++) {
if (dv1[i] != dv2[i]) return false;
}
return true;
}

export function blobTests() {
beforeEach(() => {
try {
Expand Down
Loading
Loading