DEV Community

Takuya Matsuyama
Takuya Matsuyama

Posted on

How to specify pre-processor flags to the JSI-based React Native libraries

Hi, it's Takuya.
I'm building a note-taking app called Inkdrop for mobile using React Native.

The app uses react-native-quick-sqlite, a fast wrapper of SQLite:

GitHub logo ospfranco / react-native-quick-sqlite

Fast SQLite for react-native.

screenshot

    yarn add react-native-quick-sqlite
    npx pod-install


Quick SQLite embeds the latest version of SQLite and provides a low-level JSI-backed API to execute SQL queries. By using an embedded SQLite you get access the latest security patches and latest features.

Performance metrics are intentionally not posted, anecdotic testimonies suggest anywhere between 2x and 5x speed improvement.

Gotchas

  • Javascript cannot represent integers larger than 53 bits, be careful when loading data if it came from other systems. Read more.
  • It's not possible to use a browser to debug a JSI app, use Flipper (for android Flipper also has SQLite Database explorer).

API

/**
 * All SQLite command results will have at least this status definition:
 * Specific statements or actions can bring more data, relative to its context
 * status: 0 or undefined for correct execution, 1 for error
 *  message: if status === 1, here you will find error
Enter fullscreen mode Exit fullscreen mode

It embeds the latest version of SQLite in C/C++.
That means that you build SQLite from source in your RN project on Xcode and Android Studio (CMake).

It doesn't enable any compile-time options by default, and I needed to enable FTS5 for full-text search in my app.
It can be enabled by specifying a SQLITE_ENABLE_FTS5 pre-processor flag when compiling.

I've managed to enable FTS5 and I'd like to share how to do that in your project.
For Android, the library needs to make some changes. So, it'd be helpful for library maintainers who would support accepting custom build flags.

iOS

Fortunately, CocoaPods allows you to customize the pods project settings via Podfile:

Add a post_install block to your <PROJECT_ROOT>/ios/Podfile like so:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "react-native-quick-sqlite" then
      target.build_configurations.each do |config|
        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '<SQLITE_FLAGS>']
      end
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Replace the <SQLITE_FLAGS> part with flags you want to add.
For example, you could add SQLITE_ENABLE_FTS5=1 to GCC_PREPROCESSOR_DEFINITIONS to enable FTS5 in the iOS project.

Android

The native modules are compiled with CMake that reads CMakeLists.txt.

CMake supports adding flags with add_definitions command.

Add the following lines in the library's CMakeLists.txt:

add_definitions(
  ${SQLITE_FLAGS}
)
Enter fullscreen mode Exit fullscreen mode

It specifies flags via the variable SQLITE_FLAGS, which needs to be specified in react-native-quick-sqlite/android/build.gradle like so:

def SQLITE_FLAGS = rootProject.properties['quickSqliteFlags']

android {
  defaultConfig {
    externalNativeBuild {
        cmake {
            arguments '-DANDROID_STL=c++_shared',
              "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
              "-DNODE_MODULES_DIR=${nodeModules}",
              "-DSQLITE_FLAGS='${SQLITE_FLAGS ? SQLITE_FLAGS : ''}'"
        }
    }
Enter fullscreen mode Exit fullscreen mode

Now, you can define the flags in your <PROJECT_ROOT>/android/gradle.properties like so:

quickSqliteFlags="<SQLITE_FLAGS>"
Enter fullscreen mode Exit fullscreen mode

That's it!
I've sent a pull request to the quick sqlite repository:

feat(ios&android): Support specifying pre-processor flags to sqlite #86

I've managed to enable FTS5 on both iOS and Android by specifying pre-processor flags.

On Android, we need to accept a setting from the parent project. This PR makes it possible to specify SQLite flags via android/gradle.properties.

Also, I've added instructions on how to do that for iOS and Android. Maybe the grammar could be improved tho.

fix #37

Hope that helps.


Follow me online

Top comments (1)

Collapse
 
kulsudo profile image
Kul

I do not understand the following thing: why would I use something apart from the regular SQL?