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

Add async exec call #28

Closed
wants to merge 8 commits into from
Closed
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
2 changes: 2 additions & 0 deletions .bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ project.xcworkspace
.idea
.gradle
local.properties
android.iml
*.iml
*.hprof

# Cocoapods
#
Expand Down
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby '2.7.4'
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ Inspired/compatible with [react-native-sqlite-storage](https://github.com/andpor
- This library supports SQLite BLOBs which are mapped to JS ArrayBuffers, check out the sample project on how to use it
- From version 2.0.0 onwards errors are no longer thrown on invalid SQL statements. The response contains a `status` number, `0` signals correct execution, `1` signals an error.
- From version 3.0.0 onwards no JS errors are thown, every operation returns an object with a `status` field.
- If you want to run the example project on android, you will have to change the paths on the android/CMakeLists.txt file, they are already there, just uncomment them.

## Use TypeORM

This package offers a low-level API to raw execute SQL queries. I strongly recommend to use [TypeORM](https://github.com/typeorm/typeorm) (with [patch-package](https://github.com/ds300/patch-package)). TypeORM already has a sqlite-storage driver. In the `example` project on the `patch` folder you can a find a [patch for TypeORM](https://github.com/ospfranco/react-native-quick-sqlite/blob/main/example/patches/typeorm%2B0.2.31.patch).

Follow the instructions to make TypeORM work with React Native (enable decorators, configure babel, etc), then apply the patch via patch-package and you should be good to go.
- On older react-native versions you might face weird NDK/SDK/Cmake errors, the latest version is tested against RN 0.67.3

## API

Expand All @@ -61,22 +55,32 @@ interface BatchQueryResult {

interface ISQLite {
open: (dbName: string, location?: string) => any;

close: (dbName: string) => any;

executeSql: (
dbName: string,
query: string,
params: any[] | undefined
) => QueryResult;

asyncExecuteSql: (
dbName: string,
query: string,
params: any[] | undefined
) => Promise<QueryResult>;

executeSqlBatch: (
dbName: string,
commands: SQLBatchParams[]
) => BatchQueryResult;
}
```

In your code
# Usage

```typescript
// You need to import this once in your app, it installs the binding on android
import 'react-native-quick-sqlite';

// `sqlite` is a globally registered object, so you can directly call it from anywhere in your javascript
Expand Down Expand Up @@ -128,6 +132,12 @@ if (!result.status) {
}
```

## Use TypeORM

This package offers a low-level API to raw execute SQL queries. I strongly recommend to use [TypeORM](https://github.com/typeorm/typeorm) (with [patch-package](https://github.com/ds300/patch-package)). TypeORM already has a sqlite-storage driver. In the `example` project on the `patch` folder you can a find a [patch for TypeORM](https://github.com/ospfranco/react-native-quick-sqlite/blob/main/example/patches/typeorm%2B0.2.31.patch).

Follow the instructions to make TypeORM work with React Native (enable decorators, configure babel, etc), then apply the patch via patch-package and you should be good to go.

## Learn React Native JSI

If you want to learn how to make your own JSI module buy my [JSI/C++ Cheatsheet](http://ospfranco.gumroad.com/l/IeeIvl), I'm also available for [freelance work](mailto:ospfranco@protonmail.com?subject=Freelance)!
Expand Down
34 changes: 6 additions & 28 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,40 +1,19 @@
cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.9.0)

set (PACKAGE_NAME "react-native-quick-sqlite")
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 11)

# Uncomment the following lines to compile the example project
# include_directories(
# ../cpp
# ../node_modules/react-native/React
# ../node_modules/react-native/React/Base
# ../node_modules/react-native/ReactCommon/jsi
# )

# add_library(sequel
# SHARED

# ../node_modules/react-native/ReactCommon/jsi/jsi/jsi.cpp
# ../cpp/sequel.cpp
# ../cpp/sequel.h
# ../cpp/SequelResult.h
# ../cpp/react-native-quick-sqlite.cpp
# ../cpp/react-native-quick-sqlite.h
# ../cpp/sqlite3.h
# ../cpp/sqlite3.c
# cpp-adapter.cpp
# )

include_directories(
../cpp
../../react-native/React
../../react-native/React/Base
../../react-native/ReactCommon/jsi
"${NODE_MODULES_DIR}/react-native/React"
"${NODE_MODULES_DIR}/react-native/React/Base"
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
)

add_library(sequel
SHARED
../../react-native/ReactCommon/jsi/jsi/jsi.cpp
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
../cpp/sequel.cpp
../cpp/sequel.h
../cpp/SequelResult.h
Expand All @@ -45,5 +24,4 @@ add_library(sequel
cpp-adapter.cpp
)


target_link_libraries(sequel android log)
43 changes: 27 additions & 16 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
buildscript {
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['Sequel_kotlinVersion']

import java.nio.file.Paths

buildscript {
repositories {
google()
jcenter()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:4.2.2'
}
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

def getExtOrDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['Sequel_' + name]
Expand All @@ -25,20 +23,39 @@ def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Sequel_' + name]).toInteger()
}

static def findNodeModules(baseDir) {
def basePath = baseDir.toPath().normalize()
// Node's module resolution algorithm searches up to the root directory,
// after which the base path will be null
while (basePath) {
def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
return nodeModulesPath.toString()
}
basePath = basePath.getParent()
}
throw new GradleException("react-native-quick-base64: Failed to find node_modules/ path!")
}

def nodeModules = findNodeModules(projectDir);
logger.warn("react-native-quick-sqlite: node_modules/ found at: ${nodeModules}");

android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
buildToolsVersion getExtOrDefault('buildToolsVersion')

defaultConfig {
minSdkVersion 16
minSdkVersion 21
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
versionCode 1
versionName "1.0"

externalNativeBuild {
cmake {
cppFlags "-O2 -frtti -fexceptions -Wall -Wno-unused-variable -fstack-protector-all"
arguments "-DDEV_CMAKE=true"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DNODE_MODULES_DIR=${nodeModules}"
}
}

Expand Down Expand Up @@ -66,7 +83,6 @@ android {

repositories {
mavenCentral()
jcenter()
google()

def found = false
Expand All @@ -76,10 +92,7 @@ repositories {
if (rootProject.ext.has('reactNativeAndroidRoot')) {
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
} else {
defaultDir = new File(
projectDir,
'/../../../node_modules/react-native/android'
)
defaultDir = file("$nodeModules/react-native/android")
}

if (defaultDir.exists()) {
Expand Down Expand Up @@ -135,10 +148,8 @@ repositories {
}
}

def kotlin_version = getExtOrDefault('kotlinVersion')

dependencies {
// noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
8 changes: 4 additions & 4 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Sequel_kotlinVersion=1.3.50
Sequel_compileSdkVersion=29
Sequel_buildToolsVersion=29.0.2
Sequel_targetSdkVersion=29
Sequel_kotlinVersion=1.6.0
Sequel_compileSdkVersion=30
Sequel_buildToolsVersion=30
Sequel_targetSdkVersion=30
46 changes: 20 additions & 26 deletions android/src/main/java/com/reactnativesequel/SequelModule.java
Original file line number Diff line number Diff line change
@@ -1,45 +1,39 @@
package com.reactnativequicksqlite;

import androidx.annotation.NonNull;
import android.util.Log;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

class SequelModule extends ReactContextBaseJavaModule {
static {
System.loadLibrary("sequel");
}

public static final String NAME = "QuickSQLite";
private static native void initialize(long jsiPtr, String docDir);
private static native void destruct();

public SequelModule(ReactApplicationContext reactContext) {
super(reactContext);
public SequelModule(ReactApplicationContext context) {
super(context);
}

@NonNull
@Override
public String getName() {
return "Sequel";
return NAME;
}


@NonNull
@Override
public void initialize() {
super.initialize();

// LEFT HERE:
// Convert the second arg into a std::string in the cpp-adapter file
// https://stackoverflow.com/questions/41820039/jstringjni-to-stdstringc-with-utf8-characters
SequelModule.initialize(
this.getReactApplicationContext().getJavaScriptContextHolder().get(),
this.getReactApplicationContext().getFilesDir().getAbsolutePath()
);
}

@Override
public void onCatalystInstanceDestroy() {
SequelModule.destruct();
@ReactMethod(isBlockingSynchronousMethod = true)
public boolean install() {
try {
System.loadLibrary("sequel");

ReactApplicationContext context = getReactApplicationContext();
initialize(
context.getJavaScriptContextHolder().get(),
context.getFilesDir().getAbsolutePath()
);
return true;
} catch (Exception exception) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class SequelPackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new SequelModule(reactContext));
return Collections.singletonList(new SequelModule(reactContext));
}

@NonNull
Expand Down
Loading