Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	.yarn/install-state.gz
#	.yarnrc.yml
#	cpp/bindings.cpp
#	cpp/bridge.cpp
#	cpp/bridge.h
#	example/ios/Podfile.lock
#	example/package.json
#	example/src/Database.ts
#	example/tsconfig.json
#	example/yarn.lock
#	op-sqlcipher.podspec
#	package.json
#	yarn.lock
  • Loading branch information
ospfranco committed Jan 2, 2024
2 parents b6f69f9 + 4ba6811 commit ac1723f
Show file tree
Hide file tree
Showing 25 changed files with 12,325 additions and 254 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ sqlcipher

# Yarn
.yarn/*
example/.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
Expand Down
Binary file modified .yarn/install-state.gz
Binary file not shown.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Created by [@ospfranco](https://twitter.com/ospfranco). **Please consider Sponso

## Benchmarks

You can find the [benchmarking code in the example app](https://github.com/OP-Engineering/op-sqlite/blob/main/example/src/Database.ts#L44). You should expect anywhere between a 5x to an 8x improvement over non-JSI packages, and now a 5x to 8x improvement over quick-sqlite and expo-sqlite. Loading a 300k record database (in milliseconds).
You can find the [benchmarking code in the example app](https://github.com/OP-Engineering/op-sqlite/blob/main/example/src/Database.ts#L44). This is run using the `OP_SQLITE_PERF` flag which in turns disables some old and unused features of sqlite to squeeze the last drop of performance.

![benchmark](benchmark.png)

Expand Down Expand Up @@ -127,7 +127,7 @@ const largeDb = open({
});
```

# Speed
# Performance

op-sqlite is already the fastest solution it can be, but it doesn't mean you cannot tweak SQLite to be faster (at the cost of some disadvantages). One possible tweak is turning on [Memory Mapping](https://www.sqlite.org/mmap.html). It allows to read/write to/from the disk without going through the kernel. However, if your queries throw an error your application might crash.

Expand All @@ -152,6 +152,14 @@ If you use [prepared statements](#prepared-statements) plus memory mapping and s

![mmkv comparison](mmkv.png)

# Perf flag

You can turn on the performance flag to tweak all possible performance enhancing compilation flags, this greatly affects performance of sqlite itself

```
OP_SQLITE_PERF=1 npx pod-install
```

# SQLite Gotchas

## Strictness
Expand Down
Binary file modified benchmark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions cpp/DumbHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,35 @@ jsi::Value DumbHostObject::get(jsi::Runtime &rt,
}
}

for (auto pairField : ownValues) {
if (name == pairField.first) {
return toJSI(rt, pairField.second);
}
}

return {};
}

void DumbHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name,
const jsi::Value &value) {
auto key = name.utf8(rt);
auto fields = metadata.get();
for (int i = 0; i < fields->size(); i++) {
auto fieldName = std::get<std::string>(fields->at(i).fields[0].second);
if (fieldName == key) {
values[i] = toVariant(rt, value);
return;
}
}

for (auto pairField : ownValues) {
if (key == pairField.first) {
pairField.second = toVariant(rt, value);
return;
}
}

ownValues.push_back(std::make_pair(key, toVariant(rt, value)));
}

} // namespace opsqlite
5 changes: 5 additions & 0 deletions cpp/DumbHostObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ class JSI_EXPORT DumbHostObject : public jsi::HostObject {

jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);

void set(jsi::Runtime &rt, const jsi::PropNameID &name,
const jsi::Value &value);

std::vector<JSVariant> values;

std::shared_ptr<std::vector<SmartHostObject>> metadata;

std::vector<std::pair<std::string, JSVariant>> ownValues;
};

} // namespace opsqlite
Expand Down
43 changes: 20 additions & 23 deletions cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ bool invalidated = false;
void clearState() {
invalidated = true;
// Will terminate all operations and database connections
sqliteCloseAll();
sqlite_close_all();
// We then join all the threads before the context gets invalidated
pool.restartPool();

updateHooks.clear();
commitHooks.clear();
rollbackHooks.clear();
Expand Down Expand Up @@ -88,7 +87,7 @@ void install(jsi::Runtime &rt,

encryptionKey = args[2].asString(rt).utf8(rt);

BridgeResult result = sqliteOpenDb(dbName, path, encryptionKey);
BridgeResult result = sqlite_open(dbName, path, encryptionKey);

if (result.type == SQLiteError) {
throw std::runtime_error(result.message);
Expand Down Expand Up @@ -122,7 +121,7 @@ void install(jsi::Runtime &rt,
std::string databaseToAttach = args[1].asString(rt).utf8(rt);
std::string alias = args[2].asString(rt).utf8(rt);
BridgeResult result =
sqliteAttachDb(dbName, tempDocPath, databaseToAttach, alias);
sqlite_attach(dbName, tempDocPath, databaseToAttach, alias);

if (result.type == SQLiteError) {
throw std::runtime_error(result.message);
Expand All @@ -144,7 +143,7 @@ void install(jsi::Runtime &rt,

std::string dbName = args[0].asString(rt).utf8(rt);
std::string alias = args[1].asString(rt).utf8(rt);
BridgeResult result = sqliteDetachDb(dbName, alias);
BridgeResult result = sqlite_detach(dbName, alias);

if (result.type == SQLiteError) {
throw jsi::JSError(rt, result.message.c_str());
Expand All @@ -165,7 +164,7 @@ void install(jsi::Runtime &rt,

std::string dbName = args[0].asString(rt).utf8(rt);

BridgeResult result = sqliteCloseDb(dbName);
BridgeResult result = sqlite_close(dbName);

if (result.type == SQLiteError) {
throw jsi::JSError(rt, result.message.c_str());
Expand Down Expand Up @@ -197,7 +196,7 @@ void install(jsi::Runtime &rt,
tempDocPath = tempDocPath + "/" + args[1].asString(rt).utf8(rt);
}

BridgeResult result = sqliteRemoveDb(dbName, tempDocPath);
BridgeResult result = sqlite_remove(dbName, tempDocPath);

if (result.type == SQLiteError) {
throw std::runtime_error(result.message);
Expand All @@ -220,7 +219,7 @@ void install(jsi::Runtime &rt,
std::shared_ptr<std::vector<SmartHostObject>> metadata =
std::make_shared<std::vector<SmartHostObject>>();

auto status = sqliteExecute(dbName, query, &params, &results, metadata);
auto status = sqlite_execute(dbName, query, &params, &results, metadata);

if (status.type == SQLiteError) {
throw std::runtime_error(status.message);
Expand Down Expand Up @@ -256,7 +255,7 @@ void install(jsi::Runtime &rt,
std::make_shared<std::vector<SmartHostObject>>();

auto status =
sqliteExecute(dbName, query, &params, &results, metadata);
sqlite_execute(dbName, query, &params, &results, metadata);

if (invalidated) {
return;
Expand Down Expand Up @@ -430,17 +429,16 @@ void install(jsi::Runtime &rt,

auto updateHook = HOSTFN("updateHook", 2) {
if (sizeof(args) < 2) {
throw std::runtime_error(
"[op-sqlite][loadFileAsync] Incorrect parameters: "
"dbName and callback needed");
throw std::runtime_error("[op-sqlite][updateHook] Incorrect parameters: "
"dbName and callback needed");
return {};
}

auto dbName = args[0].asString(rt).utf8(rt);
auto callback = std::make_shared<jsi::Value>(rt, args[1]);

if (callback->isUndefined() || callback->isNull()) {
unregisterUpdateHook(dbName);
sqlite_deregister_update_hook(dbName);
return {};
}

Expand All @@ -457,7 +455,7 @@ void install(jsi::Runtime &rt,
if (operation != "DELETE") {
std::string query = "SELECT * FROM " + tableName +
" where rowid = " + std::to_string(rowId) + ";";
sqliteExecute(dbName, query, &params, &results, metadata);
sqlite_execute(dbName, query, &params, &results, metadata);
}

invoker->invokeAsync(
Expand All @@ -482,23 +480,22 @@ void install(jsi::Runtime &rt,
});
};

registerUpdateHook(dbName, std::move(hook));
sqlite_register_update_hook(dbName, std::move(hook));

return {};
});

auto commitHook = HOSTFN("commitHook", 2) {
if (sizeof(args) < 2) {
throw std::runtime_error(
"[op-sqlite][loadFileAsync] Incorrect parameters: "
"dbName and callback needed");
throw std::runtime_error("[op-sqlite][commitHook] Incorrect parameters: "
"dbName and callback needed");
return {};
}

auto dbName = args[0].asString(rt).utf8(rt);
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
if (callback->isUndefined() || callback->isNull()) {
unregisterCommitHook(dbName);
sqlite_deregister_commit_hook(dbName);
return {};
}
commitHooks[dbName] = callback;
Expand All @@ -508,15 +505,15 @@ void install(jsi::Runtime &rt,
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
};

registerCommitHook(dbName, std::move(hook));
sqlite_register_commit_hook(dbName, std::move(hook));

return {};
});

auto rollbackHook = HOSTFN("rollbackHook", 2) {
if (sizeof(args) < 2) {
throw std::runtime_error(
"[op-sqlite][loadFileAsync] Incorrect parameters: "
"[op-sqlite][rollbackHook] Incorrect parameters: "
"dbName and callback needed");
return {};
}
Expand All @@ -525,7 +522,7 @@ void install(jsi::Runtime &rt,
auto callback = std::make_shared<jsi::Value>(rt, args[1]);

if (callback->isUndefined() || callback->isNull()) {
unregisterRollbackHook(dbName);
sqlite_deregister_rollback_hook(dbName);
return {};
}
rollbackHooks[dbName] = callback;
Expand All @@ -535,7 +532,7 @@ void install(jsi::Runtime &rt,
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
};

registerRollbackHook(dbName, std::move(hook));
sqlite_register_rollback_hook(dbName, std::move(hook));
return {};
});

Expand Down
Loading

0 comments on commit ac1723f

Please sign in to comment.