|
| 1 | +# React Native op-sqlite usage |
| 2 | + |
| 3 | +This note shows how to load `simple` as a SQLite runtime extension in a React |
| 4 | +Native app using [`@op-engineering/op-sqlite`](https://github.com/OP-Engineering/op-sqlite). |
| 5 | + |
| 6 | +`simple` is an FTS5 tokenizer extension, so op-sqlite must be built with FTS5 |
| 7 | +enabled and with runtime extension loading available. |
| 8 | + |
| 9 | +## Build the extension |
| 10 | + |
| 11 | +Build an iOS xcframework: |
| 12 | + |
| 13 | +```sh |
| 14 | +./build-ios-dynamic.sh |
| 15 | +``` |
| 16 | + |
| 17 | +The output is: |
| 18 | + |
| 19 | +```text |
| 20 | +output/libsimple-dynamic.xcframework |
| 21 | +``` |
| 22 | + |
| 23 | +For Android, use the shared library from the normal Android build/release |
| 24 | +artifact and package it as `libsimple.so` for each target ABI. |
| 25 | + |
| 26 | +## iOS |
| 27 | + |
| 28 | +Add the xcframework to your app, for example: |
| 29 | + |
| 30 | +```text |
| 31 | +ios/Frameworks/simple.xcframework |
| 32 | +``` |
| 33 | + |
| 34 | +If you use CocoaPods, create a small local podspec: |
| 35 | + |
| 36 | +```ruby |
| 37 | +Pod::Spec.new do |s| |
| 38 | + s.name = 'SimpleSQLiteExtension' |
| 39 | + s.version = '0.1.0' |
| 40 | + s.summary = 'SQLite simple tokenizer extension' |
| 41 | + s.homepage = 'https://github.com/wangfenjin/simple' |
| 42 | + s.license = { :type => 'MIT' } |
| 43 | + s.author = { 'simple contributors' => 'https://github.com/wangfenjin/simple' } |
| 44 | + s.source = { :git => 'https://github.com/wangfenjin/simple.git', :tag => s.version.to_s } |
| 45 | + s.platform = :ios, '12.0' |
| 46 | + s.vendored_frameworks = 'Frameworks/simple.xcframework' |
| 47 | +end |
| 48 | +``` |
| 49 | + |
| 50 | +Then reference it from `ios/Podfile`: |
| 51 | + |
| 52 | +```ruby |
| 53 | +target 'YourApp' do |
| 54 | + pod 'SimpleSQLiteExtension', :path => '.' |
| 55 | +end |
| 56 | +``` |
| 57 | + |
| 58 | +Run: |
| 59 | + |
| 60 | +```sh |
| 61 | +cd ios |
| 62 | +pod install |
| 63 | +``` |
| 64 | + |
| 65 | +## Android |
| 66 | + |
| 67 | +Package `libsimple.so` in your React Native project, for example: |
| 68 | + |
| 69 | +```text |
| 70 | +android/app/src/main/jniLibs/arm64-v8a/libsimple.so |
| 71 | +android/app/src/main/jniLibs/armeabi-v7a/libsimple.so |
| 72 | +android/app/src/main/jniLibs/x86/libsimple.so |
| 73 | +android/app/src/main/jniLibs/x86_64/libsimple.so |
| 74 | +``` |
| 75 | + |
| 76 | +## Load the extension |
| 77 | + |
| 78 | +Load the extension before creating FTS5 tables that use the `simple` tokenizer. |
| 79 | + |
| 80 | +```ts |
| 81 | +import { Platform } from 'react-native'; |
| 82 | +import { getDylibPath, open } from '@op-engineering/op-sqlite'; |
| 83 | + |
| 84 | +const db = open({ name: 'search.db' }); |
| 85 | + |
| 86 | +if (Platform.OS === 'android') { |
| 87 | + db.loadExtension('libsimple', 'sqlite3_simple_init'); |
| 88 | +} else if (Platform.OS === 'ios') { |
| 89 | + const path = getDylibPath('com.wangfenjin.simple', 'simple'); |
| 90 | + db.loadExtension(path, 'sqlite3_simple_init'); |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +After loading succeeds, `simple` can be used like any other FTS5 tokenizer: |
| 95 | + |
| 96 | +```ts |
| 97 | +db.execute(` |
| 98 | + CREATE VIRTUAL TABLE IF NOT EXISTS docs |
| 99 | + USING fts5(title, body, tokenize = 'simple'); |
| 100 | +`); |
| 101 | + |
| 102 | +db.execute('INSERT INTO docs(title, body) VALUES (?, ?)', [ |
| 103 | + '中华人民共和国国歌', |
| 104 | + '支持中文和拼音搜索', |
| 105 | +]); |
| 106 | + |
| 107 | +const result = db.execute( |
| 108 | + 'SELECT rowid, title FROM docs WHERE docs MATCH simple_query(?)', |
| 109 | + ['中华国歌'], |
| 110 | +); |
| 111 | +``` |
| 112 | + |
| 113 | +To disable pinyin tokens, use the tokenizer option supported by `simple`: |
| 114 | + |
| 115 | +```ts |
| 116 | +db.execute(` |
| 117 | + CREATE VIRTUAL TABLE IF NOT EXISTS docs_no_pinyin |
| 118 | + USING fts5(title, body, tokenize = 'simple 0'); |
| 119 | +`); |
| 120 | +``` |
| 121 | + |
| 122 | +## Troubleshooting |
| 123 | + |
| 124 | +- `no such tokenizer: simple` usually means the extension was not loaded before |
| 125 | + the FTS5 table was created. |
| 126 | +- `not authorized` or `load extension` errors usually mean runtime extension |
| 127 | + loading is disabled in the SQLite build used by your app. |
| 128 | +- iOS apps should load the framework from the app bundle. With op-sqlite, use |
| 129 | + `getDylibPath('com.wangfenjin.simple', 'simple')` for the framework named |
| 130 | + `simple.framework`. |
| 131 | +- Android should load the library name without the `.so` suffix: |
| 132 | + `db.loadExtension('libsimple', 'sqlite3_simple_init')`. |
0 commit comments