Skip to content

Commit

Permalink
Merge pull request #35 from ospfranco/async-callback-threads
Browse files Browse the repository at this point in the history
  • Loading branch information
Oscar Franco committed Mar 17, 2022
2 parents a8430bc + 6ad4158 commit 127b0de
Show file tree
Hide file tree
Showing 52 changed files with 7,279 additions and 3,572 deletions.
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
6 changes: 5 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 All @@ -59,3 +60,6 @@ android/.cxx

# generated by bob
lib/
# Gradle
android/gradle/
android/gradle*
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'
60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<h1 align="center">React Native Quick SQLite</h1>

<h3 align="center">Fast SQLite for react-native.</h3>
<h3 align="center">Fast SQLite for React-Native.</h3>

![Frame 2](https://user-images.githubusercontent.com/1634213/127499575-aed1d0e2-8a93-42ab-917e-badaab8916f6.png)
![screenshot](https://raw.githubusercontent.com/ospfranco/react-native-quick-sqlite/main/header.png)

<div align="center">
<pre align="center">
Expand All @@ -21,7 +21,7 @@
</div>
<br />

This library uses [JSI](https://formidable.com/blog/2019/jsi-jsc-part-2) to directly call C++ code from JS. It provides a low-level API to execute SQL queries, therefore I recommend you use it with TypeORM.
This library provides a low-level API to execute SQL queries, fast bindings via [JSI](https://formidable.com/blog/2019/jsi-jsc-part-2).

Inspired/compatible with [react-native-sqlite-storage](https://github.com/andpor/react-native-sqlite-storage) and [react-native-sqlite2](https://github.com/craftzdog/react-native-sqlite-2).

Expand All @@ -30,21 +30,9 @@ Inspired/compatible with [react-native-sqlite-storage](https://github.com/andpor
- **Javascript cannot represent intergers larger than 53 bits**, be careful when loading data if it came from other systems. [Read more](https://github.com/ospfranco/react-native-quick-sqlite/issues/16#issuecomment-1018412991).
- **It's not possible to use a browser to debug a JSI app**, use [Flipper](https://github.com/facebook/flipper) (for android Flipper also has SQLite Database explorer).
- Your app will now include C++, you will need to install the NDK on your machine for android.
- 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.

## API

It is also possible to directly execute SQL against the db:

```typescript
interface QueryResult {
status: 0 | 1; // 0 for correct execution
Expand All @@ -60,23 +48,41 @@ interface BatchQueryResult {
}

interface ISQLite {
open: (dbName: string, location?: string) => any;
close: (dbName: string) => any;
open: (dbName: string, location?: string) => { status: 0 | 1 };
close: (dbName: string) => { status: 0 | 1 };
executeSql: (
dbName: string,
query: string,
params: any[] | undefined
) => QueryResult;
asyncExecuteSql: (
dbName: string,
query: string,
params: any[] | undefined,
cb: (res: QueryResult) => void
) => void;
executeSqlBatch: (
dbName: string,
commands: SQLBatchParams[]
) => BatchQueryResult;
asyncExecuteSqlBatch: (
dbName: string,
commands: SQLBatchParams[],
cb: (res: BatchQueryResult) => void
) => void;
loadSqlFile: (dbName: string, location: string) => FileLoadResult;
asyncLoadSqlFile: (
dbName: string,
location: string,
cb: (res: FileLoadResult) => void
) => void;
}
```

In your code
# Usage

```typescript
// Import as early as possible, auto-installs bindings
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,9 +134,25 @@ if (!result.status) {
}
```

Async versions are also available if you have too much SQL to execute

```ts
sqlite.asyncExecuteSql('myDatabase', 'SELECT * FROM "User";', [], (result) => {
if (result.status === 0) {
console.log('users', result.rows);
}
});
```

## 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 example patch via patch-package.

## 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)!
If you want to learn how to make your own JSI module buy my [JSI/C++ Cheatsheet](http://ospfranco.gumroad.com/l/jsi_guide), I'm also available for [freelance work](mailto:ospfranco@protonmail.com?subject=Freelance)!

## License

Expand Down
142 changes: 107 additions & 35 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,49 +1,121 @@
cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.9.0)

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
# )
set (CMAKE_CXX_STANDARD 14)
#set (CMAKE_CXX_FLAGS "-DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_HAVE_MEMRCHR=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DON_ANDROID -DONANDROID -DFOR_HERMES=${FOR_HERMES}")

set (PACKAGE_NAME "react-native-quick-sqlite")
set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
set (RN_SO_DIR ${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/first-party/react/jni)

if(${REACT_NATIVE_VERSION} LESS 66)
set (
INCLUDE_JSI_CPP
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
)
set (
INCLUDE_JSIDYNAMIC_CPP
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp"
)
endif()

file (GLOB LIBFBJNI_INCLUDE_DIR "${BUILD_DIR}/fbjni-*-headers.jar/")

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"
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
"${NODE_MODULES_DIR}/react-native/ReactCommon"
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
"${NODE_MODULES_DIR}/hermes-engine/android/include/"
${INCLUDE_JSI_CPP} # only on older RN versions
${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions
)

add_library(sequel
add_library(
${PACKAGE_NAME}
SHARED
../../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/sqliteBridge.cpp
../cpp/sqliteBridge.h
../cpp/installer.cpp
../cpp/installer.h
../cpp/sqlite3.h
../cpp/sqlite3.c
../cpp/JSIHelper.h
../cpp/JSIHelper.cpp
../cpp/ThreadPool.h
../cpp/ThreadPool.cpp
../cpp/sqlfileloader.h
../cpp/sqlfileloader.cpp
../cpp/sqlbatchexecutor.h
../cpp/sqlbatchexecutor.cpp
cpp-adapter.cpp
)

# find fbjni package
file (GLOB LIBFBJNI_INCLUDE_DIR "${BUILD_DIR}/fbjni-*-headers.jar/")

target_link_libraries(sequel android log)
target_include_directories(
${PACKAGE_NAME}
PRIVATE
# --- fbjni ---
"${LIBFBJNI_INCLUDE_DIR}"
# --- React Native ---
"${NODE_MODULES_DIR}/react-native/React"
"${NODE_MODULES_DIR}/react-native/React/Base"
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni"
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
"${NODE_MODULES_DIR}/react-native/ReactCommon"
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
"${NODE_MODULES_DIR}/hermes-engine/android/include/"
${INCLUDE_JSI_CPP} # only on older RN versions
${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions
)

file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}")

find_library(
FBJNI_LIB
fbjni
PATHS ${LIBRN_DIR}
NO_CMAKE_FIND_ROOT_PATH
)

find_library(
REACT_NATIVE_JNI_LIB
reactnativejni
PATHS ${LIBRN_DIR}
NO_CMAKE_FIND_ROOT_PATH
)
if(${REACT_NATIVE_VERSION} LESS 66)
# JSI lib didn't exist on RN 0.65 and before. Simply omit it.
set (JSI_LIB "")
else()
# RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually.
find_library(
JSI_LIB
jsi
PATHS ${LIBRN_DIR}
NO_CMAKE_FIND_ROOT_PATH
)
endif()

find_library(
LOG_LIB
log
)

# target_link_libraries(sequel fbjni::fbjni android log)
target_link_libraries(
${PACKAGE_NAME}
${LOG_LIB}
${JSI_LIB}
${REACT_NATIVE_JNI_LIB}
${FBJNI_LIB}
android
)
Loading

0 comments on commit 127b0de

Please sign in to comment.