Skip to content

Commit

Permalink
Merge pull request #140 from OP-Engineering/oscar/sqlite-vec
Browse files Browse the repository at this point in the history
Oscar/sqlite vec
  • Loading branch information
ospfranco authored Aug 28, 2024
2 parents ab6742c + 4f9fead commit b7ff385
Show file tree
Hide file tree
Showing 25 changed files with 205 additions and 36 deletions.
6 changes: 6 additions & 0 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ if (USE_CRSQLITE)
)
endif()

if (USE_SQLITE_VEC)
add_definitions(
-DOP_SQLITE_USE_SQLITE_VEC=1
)
endif()

set_target_properties(
${PACKAGE_NAME} PROPERTIES
CXX_STANDARD 20
Expand Down
13 changes: 12 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def useCRSQLite = false
def performanceMode = "0"
def sqliteFlags = ""
def enableFTS5 = false
def useSqliteVec = false

def packageJsonFile = new File("$rootDir/../package.json")
def packageJson = new JsonSlurper().parseText(packageJsonFile.text)
Expand All @@ -41,6 +42,7 @@ def opsqliteConfig = packageJson["op-sqlite"]
if(opsqliteConfig) {
useSQLCipher = opsqliteConfig["sqlcipher"]
useCRSQLite = opsqliteConfig["crsqlite"]
useSqliteVec = opsqliteConfig["sqliteVec"]
performanceMode = opsqliteConfig["performanceMode"] ? opsqliteConfig["performanceMode"] : ""
sqliteFlags = opsqliteConfig["sqliteFlags"] ? opsqliteConfig["sqliteFlags"] : ""
enableFTS5 = opsqliteConfig["fts5"]
Expand Down Expand Up @@ -71,6 +73,10 @@ if(enableFTS5) {
println "[OP-SQLITE] FTS5 enabled! 🔎"
}

if(useSqliteVec) {
println "[OP-SQLITE] Sqlite Vec enabled! ↗️"
}

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}
Expand Down Expand Up @@ -138,14 +144,19 @@ android {
if(enableFTS5) {
cFlags += ["-DSQLITE_ENABLE_FTS4=1", "-DSQLITE_ENABLE_FTS3_PARENTHESIS=1", "-DSQLITE_ENABLE_FTS5=1"]
}
if(useSqliteVec) {
cFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
cppFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
}

cppFlags "-O2", "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DANDROID_STL=c++_shared",
"-DSQLITE_FLAGS='$sqliteFlags'",
"-DUSE_SQLCIPHER=${useSQLCipher ? 1 : 0}",
"-DUSE_CRSQLITE=${useCRSQLite ? 1 : 0}",
"-DUSE_LIBSQL=${useLibsql ? 1 : 0}"
"-DUSE_LIBSQL=${useLibsql ? 1 : 0}",
"-DUSE_SQLITE_VEC=${useSqliteVec ? 1 : 0}"
abiFilters (*reactNativeArchitectures())
}
}
Expand Down
2 changes: 1 addition & 1 deletion android/cpp-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct OPSQLiteBridge : jni::JavaClass<OPSQLiteBridge> {
std::string dbPathStr = dbPath->toStdString();

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

static void clearStateNativeJsi(jni::alias_ref<jni::JObject> thiz) {
Expand Down
Binary file not shown.
Binary file not shown.
Binary file added android/src/main/jniLibs/x86/libsqlite_vec.so
Binary file not shown.
Binary file added android/src/main/jniLibs/x86_64/libsqlite_vec.so
Binary file not shown.
6 changes: 4 additions & 2 deletions cpp/DBHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,19 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
std::shared_ptr<ThreadPool> thread_pool,
std::string &db_name, std::string &path,
std::string &crsqlite_path,
std::string &sqlite_vec_path,
std::string &encryption_key)
: base_path(base_path), jsCallInvoker(jsCallInvoker),
thread_pool(thread_pool), db_name(db_name), rt(rt) {

#ifdef OP_SQLITE_USE_SQLCIPHER
BridgeResult result =
opsqlite_open(db_name, path, crsqlite_path, encryption_key);
opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path, encryption_key);
#elif OP_SQLITE_USE_LIBSQL
BridgeResult result = opsqlite_libsql_open(db_name, path, crsqlite_path);
#else
BridgeResult result = opsqlite_open(db_name, path, crsqlite_path);
BridgeResult result =
opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path);
#endif

if (result.type == SQLiteError) {
Expand Down
2 changes: 1 addition & 1 deletion cpp/DBHostObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class JSI_EXPORT DBHostObject : public jsi::HostObject {
std::shared_ptr<react::CallInvoker> js_call_invoker,
std::shared_ptr<ThreadPool> thread_pool, std::string &db_name,
std::string &path, std::string &crsqlite_path,
std::string &encryption_key);
std::string &sqlite_vec_path, std::string &encryption_key);

#ifdef OP_SQLITE_USE_LIBSQL
// Constructor for remoteOpen, purely for remote databases
Expand Down
11 changes: 7 additions & 4 deletions cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace jsi = facebook::jsi;

std::string _base_path;
std::string _crsqlite_path;
std::string _sqlite_vec_path;
std::shared_ptr<react::CallInvoker> _invoker;
std::shared_ptr<ThreadPool> thread_pool = std::make_shared<ThreadPool>();

Expand All @@ -43,10 +44,12 @@ void clearState() {
}

void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
const char *base_path, const char *crsqlite_path) {
const char *base_path, const char *crsqlite_path,
const char *sqlite_vec_path) {
invalidated = false;
_base_path = std::string(base_path);
_crsqlite_path = std::string(crsqlite_path);
_sqlite_vec_path = std::string(sqlite_vec_path);
_invoker = invoker;

auto open = HOSTFN("open", 1) {
Expand Down Expand Up @@ -82,9 +85,9 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
}
}

std::shared_ptr<DBHostObject> db =
std::make_shared<DBHostObject>(rt, path, invoker, thread_pool, name,
path, _crsqlite_path, encryptionKey);
std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
rt, path, invoker, thread_pool, name, path, _crsqlite_path,
_sqlite_vec_path, encryptionKey);
return jsi::Object::createFromHostObject(rt, db);
});

Expand Down
3 changes: 2 additions & 1 deletion cpp/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace jsi = facebook::jsi;
namespace react = facebook::react;

void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
const char *base_path, const char *crsqlite_path);
const char *base_path, const char *crsqlite_path,
const char *sqlite_vec_path);
void clearState();

} // namespace opsqlite
29 changes: 23 additions & 6 deletions cpp/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ 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 &crsqlite_path,
std::string const &sqlite_vec_path,
std::string const &encryptionKey) {
#else
BridgeResult opsqlite_open(std::string const &dbName,
std::string const &last_path,
std::string const &crsqlitePath) {
std::string const &crsqlite_path,
std::string const &sqlite_vec_path) {
#endif
std::string dbPath = opsqlite_get_db_path(dbName, last_path);

Expand All @@ -78,13 +80,15 @@ BridgeResult opsqlite_open(std::string const &dbName,
nullptr, nullptr);
#endif

#ifdef OP_SQLITE_USE_CRSQLITE
sqlite3_enable_load_extension(db, 1);

char *errMsg;
const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";

sqlite3_enable_load_extension(db, 1);
#ifdef OP_SQLITE_USE_CRSQLITE
const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";

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

if (errMsg != nullptr) {
return {.type = SQLiteError, .message = errMsg};
Expand All @@ -93,6 +97,19 @@ BridgeResult opsqlite_open(std::string const &dbName,
}
#endif

#ifdef OP_SQLITE_USE_SQLITE_VEC
const char *vec_entry_point = "sqlite3_vec_init";

sqlite3_load_extension(db, sqlite_vec_path.c_str(), vec_entry_point, &errMsg);

if (errMsg != nullptr) {
return {.type = SQLiteError, .message = errMsg};
} else {
LOGI("Loaded sqlite-vec successfully");
}

#endif

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

Expand Down
6 changes: 4 additions & 2 deletions cpp/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ 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 &crsqlite_path,
std::string const &sqlite_vec_path,
std::string const &encryptionKey);
#else
BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
std::string const &crsqlitePath);
std::string const &crsqlite_path,
std::string const &sqlite_vec_path);
#endif

BridgeResult opsqlite_close(std::string const &dbName);
Expand Down
6 changes: 1 addition & 5 deletions example/ios/OPSQLiteExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@
19F6CBCC0A4E27FBF8BF4A61 /* libPods-OPSQLiteExample-OPSQLiteExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OPSQLiteExample-OPSQLiteExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B4392A12AC88292D35C810B /* Pods-OPSQLiteExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OPSQLiteExample.debug.xcconfig"; path = "Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample.debug.xcconfig"; sourceTree = "<group>"; };
5709B34CF0A7D63546082F79 /* Pods-OPSQLiteExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OPSQLiteExample.release.xcconfig"; path = "Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample.release.xcconfig"; sourceTree = "<group>"; };
5B7EB9410499542E8C5724F5 /* Pods-OPSQLiteExample-OPSQLiteExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OPSQLiteExample-OPSQLiteExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-OPSQLiteExample-OPSQLiteExampleTests/Pods-OPSQLiteExample-OPSQLiteExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
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>"; };
9218E48CFB1F478CAC374D68 /* sample2.sqlite */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = sample2.sqlite; path = ../assets/sqlite/sample2.sqlite; sourceTree = "<group>"; };
9218E48CFB1F478CAC374D68 /* sample2.sqlite */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = sample2.sqlite; path = ../assets/sqlite/sample2.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 @@ -114,8 +112,6 @@
children = (
3B4392A12AC88292D35C810B /* Pods-OPSQLiteExample.debug.xcconfig */,
5709B34CF0A7D63546082F79 /* Pods-OPSQLiteExample.release.xcconfig */,
5B7EB9410499542E8C5724F5 /* Pods-OPSQLiteExample-OPSQLiteExampleTests.debug.xcconfig */,
89C6BE57DB24E9ADA2F236DE /* Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PODS:
- hermes-engine (0.74.0):
- hermes-engine/Pre-built (= 0.74.0)
- hermes-engine/Pre-built (0.74.0)
- op-sqlite (7.0.0):
- op-sqlite (7.3.0):
- React
- React-callinvoker
- React-Core
Expand Down Expand Up @@ -1358,7 +1358,7 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
hermes-engine: 6eae7edb2f563ee41d7c1f91f4f2e57c26d8a5c3
op-sqlite: a8bc5990d5d1774aafbbad7da708da10e03343e3
op-sqlite: 19633619a7badbed615a7276762510ba20a2ae71
RCT-Folly: 045d6ecaa59d826c5736dfba0b2f4083ff8d79df
RCTDeprecation: 3ca8b6c36bfb302e1895b72cfe7db0de0c92cd47
RCTRequired: 9fc183af555fd0c89a366c34c1ae70b7e03b1dc5
Expand Down
3 changes: 2 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"performanceMode": "2",
"iosSqlite": false,
"fts5": true,
"libsql": false
"libsql": false,
"sqliteVec": false
}
}
17 changes: 17 additions & 0 deletions example/src/tests/dbsetup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,24 @@ const expectedVersion = isLibsql()
? '3.44.2'
: '3.45.1';

// const expectedSqliteVecVersion = 'v0.1.2-alpha.7';

export function dbSetupTests() {
describe('DB setup tests', () => {
// it('Should match the sqlite_vec version', async () => {
// let db = open({
// name: 'versionTest.sqlite',
// });

// const res = db.execute('select vec_version();');

// expect(res.rows?._array[0]['vec_version()']).to.equal(
// expectedSqliteVecVersion,
// );

// db.close();
// });

it(`Should match the sqlite expected version ${expectedVersion}`, async () => {
let db = open({
name: 'versionTest.sqlite',
Expand Down Expand Up @@ -55,6 +71,7 @@ export function dbSetupTests() {
location: ANDROID_EXTERNAL_FILES_PATH,
encryptionKey: 'test',
});

androidDb.execute('DROP TABLE IF EXISTS User;');
androidDb.execute(
'CREATE TABLE User ( id INT PRIMARY KEY, name TEXT NOT NULL, age INT, networth REAL) STRICT;',
Expand Down
20 changes: 15 additions & 5 deletions ios/OPSQLite.mm
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,25 @@ - (NSDictionary *)getConstants {
documentPath = [paths objectAtIndex:0];
}

NSBundle *bundle = [NSBundle bundleWithIdentifier:@"io.vlcn.crsqlite"];
NSString *crsqlitePath = [bundle pathForResource:@"crsqlite" ofType:@""];
NSBundle *crsqlite_bundle =
[NSBundle bundleWithIdentifier:@"io.vlcn.crsqlite"];
NSString *crsqlite_path = [crsqlite_bundle pathForResource:@"crsqlite"
ofType:@""];
NSBundle *libsqlitevec_bundle =
[NSBundle bundleWithIdentifier:@"com.ospfranco.sqlitevec"];
NSString *sqlite_vec_path = [libsqlitevec_bundle pathForResource:@"sqlitevec"
ofType:@""];

if (crsqlite_path == nil) {
crsqlite_path = @"";
}

if (crsqlitePath == nil) {
crsqlitePath = @"";
if (sqlite_vec_path == nil) {
sqlite_vec_path = @"";
}

opsqlite::install(runtime, callInvoker, [documentPath UTF8String],
[crsqlitePath UTF8String]);
[crsqlite_path UTF8String], [sqlite_vec_path UTF8String]);
return @true;
}

Expand Down
46 changes: 46 additions & 0 deletions ios/sqlitevec.xcframework/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>sqlitevec.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>sqlitevec.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>
Loading

0 comments on commit b7ff385

Please sign in to comment.