Skip to content
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
40 changes: 24 additions & 16 deletions cpp/DBHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,18 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
auto obj_params = args[0].asObject(rt);

std::string secondary_db_name =
obj_params.getProperty(rt, "secondaryDbFileName").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
obj_params.getProperty(rt, "secondaryDbFileName")
.asString(rt));
std::string alias =
obj_params.getProperty(rt, "alias").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
obj_params.getProperty(rt, "alias").asString(rt));

if (obj_params.hasProperty(rt, "location")) {
std::string location =
obj_params.getProperty(rt, "location").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
obj_params.getProperty(rt, "location")
.asString(rt));
secondary_db_path = secondary_db_path + location;
}

Expand Down Expand Up @@ -278,7 +283,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
throw std::runtime_error("[op-sqlite] alias must be a strings");
}

std::string alias = args[0].asString(rt).utf8(rt);
std::string alias = jsi_string_to_utf8(rt, args[0].asString(rt));
if (alias.find('\0') != std::string::npos) {
throw std::runtime_error(
"[op-sqlite] detach alias must not contain a zero byte");
Expand Down Expand Up @@ -367,7 +372,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["executeRaw"] = HFN(this) {
const std::string query = args[0].asString(rt).utf8(rt);
const std::string query = jsi_string_to_utf8(rt, args[0].asString(rt));
const std::vector<JSVariant> params = count == 2 && args[1].isObject()
? to_variant_vec(rt, args[1])
: std::vector<JSVariant>();
Expand All @@ -394,7 +399,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["executeSync"] = HFN(this) {
std::string query = args[0].asString(rt).utf8(rt);
std::string query = jsi_string_to_utf8(rt, args[0].asString(rt));
std::vector<JSVariant> params;

if (count == 2) {
Expand All @@ -410,7 +415,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["executeRawSync"] = HFN(this) {
const std::string query = args[0].asString(rt).utf8(rt);
const std::string query = jsi_string_to_utf8(rt, args[0].asString(rt));
std::vector<JSVariant> params = count == 2 && args[1].isObject()
? to_variant_vec(rt, args[1])
: std::vector<JSVariant>();
Expand All @@ -427,7 +432,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["execute"] = HFN(this) {
const std::string query = args[0].asString(rt).utf8(rt);
const std::string query = jsi_string_to_utf8(rt, args[0].asString(rt));
std::vector<JSVariant> params = count == 2 && args[1].isObject()
? to_variant_vec(rt, args[1])
: std::vector<JSVariant>();
Expand All @@ -449,7 +454,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["executeWithHostObjects"] = HFN(this) {
const std::string query = args[0].asString(rt).utf8(rt);
const std::string query = jsi_string_to_utf8(rt, args[0].asString(rt));
std::vector<JSVariant> params = count == 2 && args[1].isObject()
? to_variant_vec(rt, args[1])
: std::vector<JSVariant>();
Expand Down Expand Up @@ -550,7 +555,8 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
"[op-sqlite][loadFile] Incorrect parameter count");
}

const std::string sqlFileName = args[0].asString(rt).utf8(rt);
const std::string sqlFileName =
jsi_string_to_utf8(rt, args[0].asString(rt));

return promisify(
rt, thread_pool,
Expand Down Expand Up @@ -611,10 +617,10 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
});

function_map["loadExtension"] = HFN(this) {
auto path = args[0].asString(rt).utf8(rt);
auto path = jsi_string_to_utf8(rt, args[0].asString(rt));
std::string entry_point;
if (count > 1 && args[1].isString()) {
entry_point = args[1].asString(rt).utf8(rt);
entry_point = jsi_string_to_utf8(rt, args[1].asString(rt));
}

opsqlite_load_extension(db, path, entry_point);
Expand All @@ -625,7 +631,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
auto query = args[0].asObject(rt);

const std::string query_str =
query.getProperty(rt, "query").asString(rt).utf8(rt);
jsi_string_to_utf8(rt, query.getProperty(rt, "query").asString(rt));
auto js_args = query.getProperty(rt, "arguments");
auto js_discriminators =
query.getProperty(rt, "fireOn").asObject(rt).asArray(rt);
Expand All @@ -643,7 +649,9 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
auto js_discriminator =
js_discriminators.getValueAtIndex(rt, i).asObject(rt);
std::string table =
js_discriminator.getProperty(rt, "table").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
js_discriminator.getProperty(rt, "table")
.asString(rt));
std::vector<int> ids;
if (js_discriminator.hasProperty(rt, "ids")) {
auto js_ids =
Expand Down Expand Up @@ -679,7 +687,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
#endif

function_map["prepareStatement"] = HFN(this) {
auto query = args[0].asString(rt).utf8(rt);
auto query = jsi_string_to_utf8(rt, args[0].asString(rt));
#ifdef OP_SQLITE_USE_LIBSQL
libsql_stmt_t statement = opsqlite_libsql_prepare_statement(db, query);
#else
Expand All @@ -701,7 +709,7 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {
"[op-sqlite][open] database location must be a string");
}

std::string last_path = args[0].asString(rt).utf8(rt);
std::string last_path = jsi_string_to_utf8(rt, args[0].asString(rt));

if (last_path == ":memory:") {
path = ":memory:";
Expand Down
36 changes: 25 additions & 11 deletions cpp/OPSqlite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,22 @@ void install(jsi::Runtime &rt,

auto open = HFN0 {
jsi::Object options = args[0].asObject(rt);
std::string name = options.getProperty(rt, "name").asString(rt).utf8(rt);
std::string name =
jsi_string_to_utf8(rt, options.getProperty(rt, "name").asString(rt));
std::string path = std::string(_base_path);
std::string location;
std::string encryption_key;

if (options.hasProperty(rt, "location")) {
location = options.getProperty(rt, "location").asString(rt).utf8(rt);
location = jsi_string_to_utf8(
rt, options.getProperty(rt, "location").asString(rt));
}

if (options.hasProperty(rt, "encryptionKey")) {
encryption_key =
options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
options.getProperty(rt, "encryptionKey")
.asString(rt));
}

if (!location.empty()) {
Expand Down Expand Up @@ -122,10 +126,12 @@ void install(jsi::Runtime &rt,
auto open_remote = HFN(=) {
jsi::Object options = args[0].asObject(rt);

std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
std::string url =
jsi_string_to_utf8(rt, options.getProperty(rt, "url").asString(rt));

std::string auth_token =
options.getProperty(rt, "authToken").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
options.getProperty(rt, "authToken").asString(rt));

#ifdef OP_SQLITE_USE_LIBSQL
std::shared_ptr<DBHostObject> db =
Expand All @@ -143,11 +149,14 @@ void install(jsi::Runtime &rt,

auto open_sync = HFN(=) {
jsi::Object options = args[0].asObject(rt);
std::string name = options.getProperty(rt, "name").asString(rt).utf8(rt);
std::string name =
jsi_string_to_utf8(rt, options.getProperty(rt, "name").asString(rt));
std::string path = std::string(_base_path);
std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
std::string url =
jsi_string_to_utf8(rt, options.getProperty(rt, "url").asString(rt));
std::string auth_token =
options.getProperty(rt, "authToken").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
options.getProperty(rt, "authToken").asString(rt));

int sync_interval = 0;
if (options.hasProperty(rt, "libsqlSyncInterval")) {
Expand All @@ -163,18 +172,23 @@ void install(jsi::Runtime &rt,
std::string encryption_key;
if (options.hasProperty(rt, "encryptionKey")) {
encryption_key =
options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
options.getProperty(rt, "encryptionKey")
.asString(rt));
}

std::string remote_encryption_key;
if (options.hasProperty(rt, "remoteEncryptionKey")) {
remote_encryption_key =
options.getProperty(rt, "remoteEncryptionKey").asString(rt).utf8(rt);
jsi_string_to_utf8(rt,
options.getProperty(rt, "remoteEncryptionKey")
.asString(rt));
}

std::string location;
if (options.hasProperty(rt, "location")) {
location = options.getProperty(rt, "location").asString(rt).utf8(rt);
location = jsi_string_to_utf8(
rt, options.getProperty(rt, "location").asString(rt));
}
if (!location.empty()) {
if (location == ":memory:") {
Expand Down
7 changes: 4 additions & 3 deletions cpp/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ inline JSVariant to_variant(jsi::Runtime &rt, const jsi::Value &value) {
return JSVariant(doubleVal);
}
} else if (value.isString()) {
std::string strVal = value.asString(rt).utf8(rt);
std::string strVal = jsi_string_to_utf8(rt, value.asString(rt));
return JSVariant(strVal);
} else if (value.isObject()) {
auto obj = value.asObject(rt);
Expand Down Expand Up @@ -145,7 +145,8 @@ std::vector<std::string> to_string_vec(jsi::Runtime &rt, jsi::Value const &xs) {
jsi::Array values = xs.asObject(rt).asArray(rt);
std::vector<std::string> res;
for (int ii = 0; ii < values.length(rt); ii++) {
std::string value = values.getValueAtIndex(rt, ii).asString(rt).utf8(rt);
std::string value =
jsi_string_to_utf8(rt, values.getValueAtIndex(rt, ii).asString(rt));
res.emplace_back(value);
}
return res;
Expand Down Expand Up @@ -267,7 +268,7 @@ void to_batch_arguments(jsi::Runtime &rt, jsi::Array const &tuples,
}

const std::string query =
tuple.getValueAtIndex(rt, 0).asString(rt).utf8(rt);
jsi_string_to_utf8(rt, tuple.getValueAtIndex(rt, 0).asString(rt));
if (length == 1) {
commands->push_back({query});
continue;
Expand Down
25 changes: 25 additions & 0 deletions cpp/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ namespace opsqlite {
namespace jsi = facebook::jsi;
namespace react = facebook::react;

struct JSIStringDataAppender {
std::string *out;

void operator()(bool ascii, const void *data, size_t num) const {
if (ascii) {
out->append(static_cast<const char *>(data), num);
return;
}

const auto *u16 = static_cast<const char16_t *>(data);
out->reserve(out->size() + num);
for (size_t i = 0; i < num; i++) {
out->push_back(static_cast<char>(u16[i]));
}
}
};

inline std::string jsi_string_to_utf8(jsi::Runtime &rt,
const jsi::String &value) {
std::string result;
JSIStringDataAppender cb{&result};
value.getStringData(rt, cb);
return result;
}
Comment on lines +22 to +45

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As intended, JS effectively uses utf-8 but the retarded decision at the beginning of the universe was to use utf-16


jsi::Value to_jsi(jsi::Runtime &rt, const JSVariant &value);

JSVariant to_variant(jsi::Runtime &rt, jsi::Value const &value);
Expand Down
3 changes: 2 additions & 1 deletion example/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ gem 'concurrent-ruby', '< 1.3.4'
gem 'bigdecimal'
gem 'logger'
gem 'benchmark'
gem 'mutex_m'
gem 'mutex_m'
gem 'nkf'
7 changes: 5 additions & 2 deletions example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ GEM
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
nkf (0.2.0)
prism (1.6.0)
public_suffix (4.0.7)
rexml (3.4.4)
Expand All @@ -118,7 +119,6 @@ PLATFORMS
arm-linux-gnu
arm-linux-musl
arm64-darwin
ruby
x86-linux-gnu
x86-linux-musl
x86_64-darwin
Expand All @@ -133,6 +133,7 @@ DEPENDENCIES
concurrent-ruby (< 1.3.4)
logger
mutex_m
nkf
xcodeproj (< 1.26.0)

CHECKSUMS
Expand All @@ -144,6 +145,7 @@ CHECKSUMS
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
bundler (4.0.11) sha256=5bcec0fb78302e48d02ee46f10ee6e6942be647ba5b44a6d1ddfda9a240ce785
claide (1.1.0) sha256=6d3c5c089dde904d96aa30e73306d0d4bd444b1accb9b3125ce14a3c0183f82e
cocoapods (1.15.2) sha256=f0f5153de8d028d133b96f423e04f37fb97a1da0d11dda581a9f46c0cba4090a
cocoapods-core (1.15.2) sha256=322650d97fe1ad4c0831a09669764b888bd91c6d79d0f6bb07281a17667a2136
Expand Down Expand Up @@ -183,6 +185,7 @@ CHECKSUMS
nanaimo (0.3.0) sha256=aaaedc60497070b864a7e220f7c4b4cad3a0daddda2c30055ba8dae306342376
nap (1.1.0) sha256=949691660f9d041d75be611bb2a8d2fd559c467537deac241f4097d9b5eea576
netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f
nkf (0.2.0)
prism (1.6.0) sha256=bfc0281a81718c4872346bc858dc84abd3a60cae78336c65ad35c8fbff641c6b
public_suffix (4.0.7) sha256=8be161e2421f8d45b0098c042c06486789731ea93dc3a896d30554ee38b573b8
rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
Expand All @@ -196,4 +199,4 @@ RUBY VERSION
ruby 3.3.0

BUNDLED WITH
4.0.1
4.0.11
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader

class MainApplication : Application(), ReactApplication {
override val reactHost: ReactHost by lazy {
Expand All @@ -21,9 +19,6 @@ class MainApplication : Application(), ReactApplication {

override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
load()
}
loadReactNative(this)
}
}
8 changes: 4 additions & 4 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
buildscript {
ext {
buildToolsVersion = "35.0.0"
buildToolsVersion = "36.0.0"
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 35
compileSdkVersion = 36
targetSdkVersion = 36
ndkVersion = "27.1.12297006"
kotlinVersion = "2.0.21"
kotlinVersion = "2.1.20"
}
repositories {
google()
Expand Down
4 changes: 2 additions & 2 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
android.useAndroidX=true
android.enableJetifier=true
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
newArchEnabled=true
hermesEnabled=true
hermesEnabled=true
edgeToEdgeEnabled=false
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Loading
Loading