react-native-nitro-sqlite 8.2.1-nitro.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNNitroSQLite.podspec +59 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/CMakeLists.txt +38 -0
- package/android/build.gradle +119 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/cpp/cpp-adapter.cpp +21 -0
- package/android/src/main/java/com/margelo/rnnitrosqlite/RNNitroSQLiteOnLoadModule.java +57 -0
- package/android/src/main/java/com/margelo/rnnitrosqlite/RNNitroSQLitePackage.java +48 -0
- package/cpp/NitroSQLiteException.hpp +63 -0
- package/cpp/ThreadPool.cpp +91 -0
- package/cpp/ThreadPool.hpp +50 -0
- package/cpp/importSqlFile.cpp +48 -0
- package/cpp/importSqlFile.hpp +15 -0
- package/cpp/logs.hpp +38 -0
- package/cpp/macros.hpp +13 -0
- package/cpp/operations.cpp +296 -0
- package/cpp/operations.hpp +24 -0
- package/cpp/specs/HybridNativeQueryResult.cpp +20 -0
- package/cpp/specs/HybridNativeQueryResult.hpp +35 -0
- package/cpp/specs/HybridNitroSQLite.cpp +132 -0
- package/cpp/specs/HybridNitroSQLite.hpp +36 -0
- package/cpp/sqlite/sqlite3.c +237594 -0
- package/cpp/sqlite/sqlite3.h +12556 -0
- package/cpp/sqliteExecuteBatch.cpp +70 -0
- package/cpp/sqliteExecuteBatch.hpp +30 -0
- package/cpp/types.hpp +53 -0
- package/cpp/utils.hpp +61 -0
- package/ios/NitroSQLite.xcodeproj/project.pbxproj +447 -0
- package/ios/OnLoad.mm +41 -0
- package/ios/RNNitroSQLite-Swift.h +1 -0
- package/lib/commonjs/index.js +58 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/nitro.js +10 -0
- package/lib/commonjs/nitro.js.map +1 -0
- package/lib/commonjs/operations/execute.js +35 -0
- package/lib/commonjs/operations/execute.js.map +1 -0
- package/lib/commonjs/operations/session.js +39 -0
- package/lib/commonjs/operations/session.js.map +1 -0
- package/lib/commonjs/operations/transaction.js +95 -0
- package/lib/commonjs/operations/transaction.js.map +1 -0
- package/lib/commonjs/specs/NativeNitroSQLiteOnLoad.ios.js +11 -0
- package/lib/commonjs/specs/NativeNitroSQLiteOnLoad.ios.js.map +1 -0
- package/lib/commonjs/specs/NativeNitroSQLiteOnLoad.js +9 -0
- package/lib/commonjs/specs/NativeNitroSQLiteOnLoad.js.map +1 -0
- package/lib/commonjs/specs/NativeQueryResult.nitro.js +6 -0
- package/lib/commonjs/specs/NativeQueryResult.nitro.js.map +1 -0
- package/lib/commonjs/specs/NitroSQLite.nitro.js +6 -0
- package/lib/commonjs/specs/NitroSQLite.nitro.js.map +1 -0
- package/lib/commonjs/typeORM.js +62 -0
- package/lib/commonjs/typeORM.js.map +1 -0
- package/lib/commonjs/types.js +35 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/index.js +23 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/nitro.js +4 -0
- package/lib/module/nitro.js.map +1 -0
- package/lib/module/operations/execute.js +28 -0
- package/lib/module/operations/execute.js.map +1 -0
- package/lib/module/operations/session.js +31 -0
- package/lib/module/operations/session.js.map +1 -0
- package/lib/module/operations/transaction.js +88 -0
- package/lib/module/operations/transaction.js.map +1 -0
- package/lib/module/specs/NativeNitroSQLiteOnLoad.ios.js +5 -0
- package/lib/module/specs/NativeNitroSQLiteOnLoad.ios.js.map +1 -0
- package/lib/module/specs/NativeNitroSQLiteOnLoad.js +3 -0
- package/lib/module/specs/NativeNitroSQLiteOnLoad.js.map +1 -0
- package/lib/module/specs/NativeQueryResult.nitro.js +2 -0
- package/lib/module/specs/NativeQueryResult.nitro.js.map +1 -0
- package/lib/module/specs/NitroSQLite.nitro.js +2 -0
- package/lib/module/specs/NitroSQLite.nitro.js.map +1 -0
- package/lib/module/typeORM.js +54 -0
- package/lib/module/typeORM.js.map +1 -0
- package/lib/module/types.js +33 -0
- package/lib/module/types.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/typescript/index.d.ts +30 -0
- package/lib/typescript/nitro.d.ts +7 -0
- package/lib/typescript/operations/execute.d.ts +3 -0
- package/lib/typescript/operations/session.d.ts +4 -0
- package/lib/typescript/operations/transaction.d.ts +5 -0
- package/lib/typescript/specs/NativeNitroSQLiteOnLoad.d.ts +6 -0
- package/lib/typescript/specs/NativeNitroSQLiteOnLoad.ios.d.ts +3 -0
- package/lib/typescript/specs/NativeQueryResult.nitro.d.ts +37 -0
- package/lib/typescript/specs/NitroSQLite.nitro.d.ts +19 -0
- package/lib/typescript/typeORM.d.ts +19 -0
- package/lib/typescript/types.d.ts +79 -0
- package/nitrogen/generated/android/RNNitroSQLite+autolinking.cmake +48 -0
- package/nitrogen/generated/android/RNNitroSQLite+autolinking.gradle +25 -0
- package/nitrogen/generated/android/RNNitroSQLiteOnLoad.cpp +40 -0
- package/nitrogen/generated/android/RNNitroSQLiteOnLoad.hpp +25 -0
- package/nitrogen/generated/android/RNNitroSQLiteOnLoad.kt +1 -0
- package/nitrogen/generated/ios/RNNitroSQLite+autolinking.rb +56 -0
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.cpp +8 -0
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.hpp +303 -0
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Umbrella.hpp +67 -0
- package/nitrogen/generated/ios/RNNitroSQLiteAutolinking.mm +35 -0
- package/nitrogen/generated/ios/RNNitroSQLiteAutolinking.swift +10 -0
- package/nitrogen/generated/shared/c++/BatchQueryCommand.hpp +77 -0
- package/nitrogen/generated/shared/c++/BatchQueryResult.hpp +68 -0
- package/nitrogen/generated/shared/c++/ColumnType.hpp +68 -0
- package/nitrogen/generated/shared/c++/FileLoadResult.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridNativeQueryResultSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridNativeQueryResultSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.hpp +91 -0
- package/nitrogen/generated/shared/c++/SQLiteQueryColumnMetadata.hpp +78 -0
- package/package.json +98 -0
- package/src/index.ts +26 -0
- package/src/nitro.ts +11 -0
- package/src/operations/execute.ts +45 -0
- package/src/operations/session.ts +58 -0
- package/src/operations/transaction.ts +137 -0
- package/src/specs/NativeNitroSQLiteOnLoad.ios.ts +7 -0
- package/src/specs/NativeNitroSQLiteOnLoad.ts +7 -0
- package/src/specs/NativeQueryResult.nitro.ts +44 -0
- package/src/specs/NitroSQLite.nitro.ts +39 -0
- package/src/typeORM.ts +101 -0
- package/src/types.ts +105 -0
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-nitro-sqlite",
|
|
3
|
+
"version": "8.2.1-nitro.1",
|
|
4
|
+
"description": "Fast SQLite for react-native",
|
|
5
|
+
"main": "lib/commonjs/index",
|
|
6
|
+
"module": "lib/module/index",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index",
|
|
9
|
+
"source": "src/index",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"react-native",
|
|
12
|
+
"ios",
|
|
13
|
+
"android"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/margelo/react-native-nitro-sqlite.git"
|
|
18
|
+
},
|
|
19
|
+
"author": "Margelo <hello@margelo.com> (https://github.com/margelo)",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/margelo/react-native-nitro-sqlite/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/margelo/react-native-nitro-sqlite#readme",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"registry": "https://registry.npmjs.org/"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"src",
|
|
30
|
+
"lib",
|
|
31
|
+
"nitrogen",
|
|
32
|
+
"android",
|
|
33
|
+
"ios",
|
|
34
|
+
"cpp",
|
|
35
|
+
"nitrogen",
|
|
36
|
+
"RNNitroSQLite.podspec",
|
|
37
|
+
"!lib/typescript/example",
|
|
38
|
+
"!android/build",
|
|
39
|
+
"!android/.cxx",
|
|
40
|
+
"!ios/build",
|
|
41
|
+
"!**/__tests__",
|
|
42
|
+
"!**/__fixtures__",
|
|
43
|
+
"!**/__mocks__"
|
|
44
|
+
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"typescript": "tsc --noEmit",
|
|
47
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
|
48
|
+
"prepare": "rm -rf lib && bun typescript && bob build",
|
|
49
|
+
"bootstrap": "bun --filter=\"**\" install && bun tsc && bun --filter=\"example\" pods",
|
|
50
|
+
"specs": "bun typescript && bun nitro-codegen --logLevel=\"debug\"",
|
|
51
|
+
"release": "bun prepare && release-it"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"typeorm": "^0.3.20"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@react-native/typescript-config": "0.75.2",
|
|
58
|
+
"babel-plugin-transform-typescript-metadata": "^0.3.2",
|
|
59
|
+
"nitro-codegen": "^0.11.0",
|
|
60
|
+
"react": "18.3.1",
|
|
61
|
+
"react-native": "0.75.2",
|
|
62
|
+
"react-native-builder-bob": "^0.18.2"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"react": "*",
|
|
66
|
+
"react-native": ">=0.74.0",
|
|
67
|
+
"react-native-nitro-modules": "*"
|
|
68
|
+
},
|
|
69
|
+
"codegenConfig": {
|
|
70
|
+
"name": "RNNitroSQLite",
|
|
71
|
+
"type": "modules",
|
|
72
|
+
"jsSrcsDir": "src",
|
|
73
|
+
"android": {
|
|
74
|
+
"javaPackageName": "com.margelo.rnnitrosqlite"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"react-native-builder-bob": {
|
|
78
|
+
"source": "src",
|
|
79
|
+
"output": "lib",
|
|
80
|
+
"targets": [
|
|
81
|
+
"commonjs",
|
|
82
|
+
"module",
|
|
83
|
+
[
|
|
84
|
+
"typescript",
|
|
85
|
+
{
|
|
86
|
+
"tsc": "../node_modules/.bin/tsc"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"release-it": {
|
|
92
|
+
"npm": {
|
|
93
|
+
"publish": true,
|
|
94
|
+
"publishPackageManager": "bun"
|
|
95
|
+
},
|
|
96
|
+
"git": false
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { transaction } from './operations/transaction'
|
|
2
|
+
import { HybridNitroSQLite } from './nitro'
|
|
3
|
+
import { open } from './operations/session'
|
|
4
|
+
import NitroSQLiteOnLoad from './specs/NativeNitroSQLiteOnLoad'
|
|
5
|
+
import { execute, executeAsync } from './operations/execute'
|
|
6
|
+
|
|
7
|
+
export * from './types'
|
|
8
|
+
export { typeORMDriver } from './typeORM'
|
|
9
|
+
|
|
10
|
+
export const onInitialized = new Promise<void>((resolve) => {
|
|
11
|
+
NitroSQLiteOnLoad.onReactApplicationContextReady(resolve)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const NitroSQLite = {
|
|
15
|
+
...HybridNitroSQLite,
|
|
16
|
+
native: HybridNitroSQLite,
|
|
17
|
+
onInitialized,
|
|
18
|
+
// Overwrite native functions with session-based JS implementations,
|
|
19
|
+
// where the database name can be ommited once opened
|
|
20
|
+
open,
|
|
21
|
+
transaction,
|
|
22
|
+
execute,
|
|
23
|
+
executeAsync,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { open } from './operations/session'
|
package/src/nitro.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules'
|
|
2
|
+
import type { NitroSQLite as NitroSQLiteSpec } from './specs/NitroSQLite.nitro'
|
|
3
|
+
import type { PendingTransaction } from './operations/transaction'
|
|
4
|
+
|
|
5
|
+
export const HybridNitroSQLite =
|
|
6
|
+
NitroModules.createHybridObject<NitroSQLiteSpec>('NitroSQLite')
|
|
7
|
+
|
|
8
|
+
export const locks: Record<
|
|
9
|
+
string,
|
|
10
|
+
{ queue: PendingTransaction[]; inProgress: boolean }
|
|
11
|
+
> = {}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { HybridNitroSQLite } from '../nitro'
|
|
2
|
+
import type { NativeQueryResult } from '../specs/NativeQueryResult.nitro'
|
|
3
|
+
import type { QueryResult, SQLiteItem, SQLiteQueryParams } from '../types'
|
|
4
|
+
|
|
5
|
+
export function execute<Data extends SQLiteItem = never>(
|
|
6
|
+
dbName: string,
|
|
7
|
+
query: string,
|
|
8
|
+
params?: SQLiteQueryParams
|
|
9
|
+
): QueryResult<Data> {
|
|
10
|
+
const nativeResult = HybridNitroSQLite.execute(dbName, query, params)
|
|
11
|
+
const result = buildJsQueryResult<Data>(nativeResult)
|
|
12
|
+
return result
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function executeAsync<Data extends SQLiteItem = never>(
|
|
16
|
+
dbName: string,
|
|
17
|
+
query: string,
|
|
18
|
+
params?: SQLiteQueryParams
|
|
19
|
+
): Promise<QueryResult<Data>> {
|
|
20
|
+
const nativeResult = await HybridNitroSQLite.executeAsync(
|
|
21
|
+
dbName,
|
|
22
|
+
query,
|
|
23
|
+
params
|
|
24
|
+
)
|
|
25
|
+
const result = buildJsQueryResult<Data>(nativeResult)
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function buildJsQueryResult<Data extends SQLiteItem = never>({
|
|
30
|
+
insertId,
|
|
31
|
+
rowsAffected,
|
|
32
|
+
results,
|
|
33
|
+
}: NativeQueryResult): QueryResult<Data> {
|
|
34
|
+
const data = results as Data[]
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
insertId,
|
|
38
|
+
rowsAffected,
|
|
39
|
+
rows: {
|
|
40
|
+
_array: data,
|
|
41
|
+
length: data.length,
|
|
42
|
+
item: (idx: number) => data[idx],
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { locks, HybridNitroSQLite } from '../nitro'
|
|
2
|
+
import { transaction } from './transaction'
|
|
3
|
+
import type {
|
|
4
|
+
BatchQueryCommand,
|
|
5
|
+
NitroSQLiteConnection,
|
|
6
|
+
NitroSQLiteConnectionOptions,
|
|
7
|
+
QueryResult,
|
|
8
|
+
SQLiteItem,
|
|
9
|
+
SQLiteQueryParams,
|
|
10
|
+
Transaction,
|
|
11
|
+
} from '../types'
|
|
12
|
+
import { execute, executeAsync } from './execute'
|
|
13
|
+
|
|
14
|
+
export function open(
|
|
15
|
+
options: NitroSQLiteConnectionOptions
|
|
16
|
+
): NitroSQLiteConnection {
|
|
17
|
+
openDb(options.name, options.location)
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
close: () => close(options.name),
|
|
21
|
+
delete: () => HybridNitroSQLite.drop(options.name, options.location),
|
|
22
|
+
attach: (dbNameToAttach: string, alias: string, location?: string) =>
|
|
23
|
+
HybridNitroSQLite.attach(options.name, dbNameToAttach, alias, location),
|
|
24
|
+
detach: (alias: string) => HybridNitroSQLite.detach(options.name, alias),
|
|
25
|
+
transaction: (fn: (tx: Transaction) => Promise<void> | void) =>
|
|
26
|
+
transaction(options.name, fn),
|
|
27
|
+
execute: <Data extends SQLiteItem = never>(
|
|
28
|
+
query: string,
|
|
29
|
+
params?: SQLiteQueryParams
|
|
30
|
+
): QueryResult<Data> => execute(options.name, query, params),
|
|
31
|
+
executeAsync: <Data extends SQLiteItem = never>(
|
|
32
|
+
query: string,
|
|
33
|
+
params?: SQLiteQueryParams
|
|
34
|
+
): Promise<QueryResult<Data>> => executeAsync(options.name, query, params),
|
|
35
|
+
executeBatch: (commands: BatchQueryCommand[]) =>
|
|
36
|
+
HybridNitroSQLite.executeBatch(options.name, commands),
|
|
37
|
+
executeBatchAsync: (commands: BatchQueryCommand[]) =>
|
|
38
|
+
HybridNitroSQLite.executeBatchAsync(options.name, commands),
|
|
39
|
+
loadFile: (location: string) =>
|
|
40
|
+
HybridNitroSQLite.loadFile(options.name, location),
|
|
41
|
+
loadFileAsync: (location: string) =>
|
|
42
|
+
HybridNitroSQLite.loadFileAsync(options.name, location),
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function openDb(dbName: string, location?: string) {
|
|
47
|
+
HybridNitroSQLite.open(dbName, location)
|
|
48
|
+
|
|
49
|
+
locks[dbName] = {
|
|
50
|
+
queue: [],
|
|
51
|
+
inProgress: false,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function close(dbName: string) {
|
|
56
|
+
HybridNitroSQLite.close(dbName)
|
|
57
|
+
delete locks[dbName]
|
|
58
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { locks, HybridNitroSQLite } from '../nitro'
|
|
2
|
+
import type {
|
|
3
|
+
QueryResult,
|
|
4
|
+
SQLiteItem,
|
|
5
|
+
SQLiteQueryParams,
|
|
6
|
+
Transaction,
|
|
7
|
+
} from '../types'
|
|
8
|
+
import { execute, executeAsync } from './execute'
|
|
9
|
+
|
|
10
|
+
export interface PendingTransaction {
|
|
11
|
+
/*
|
|
12
|
+
* The start function should not throw or return a promise because the
|
|
13
|
+
* queue just calls it and does not monitor for failures or completions.
|
|
14
|
+
*
|
|
15
|
+
* It should catch any errors and call the resolve or reject of the wrapping
|
|
16
|
+
* promise when complete.
|
|
17
|
+
*
|
|
18
|
+
* It should also automatically commit or rollback the transaction if needed
|
|
19
|
+
*/
|
|
20
|
+
start: () => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const transaction = async (
|
|
24
|
+
dbName: string,
|
|
25
|
+
fn: (tx: Transaction) => Promise<void> | void
|
|
26
|
+
): Promise<void> => {
|
|
27
|
+
if (locks[dbName] == null)
|
|
28
|
+
throw Error(`Nitro SQLite Error: No lock found on db: ${dbName}`)
|
|
29
|
+
|
|
30
|
+
let isFinalized = false
|
|
31
|
+
|
|
32
|
+
// Local transaction context object implementation
|
|
33
|
+
const executeOnTransaction = <Data extends SQLiteItem = never>(
|
|
34
|
+
query: string,
|
|
35
|
+
params?: SQLiteQueryParams
|
|
36
|
+
): QueryResult<Data> => {
|
|
37
|
+
if (isFinalized) {
|
|
38
|
+
throw Error(
|
|
39
|
+
`Nitro SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
return execute(dbName, query, params)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const executeAsyncOnTransaction = <Data extends SQLiteItem = never>(
|
|
46
|
+
query: string,
|
|
47
|
+
params?: SQLiteQueryParams
|
|
48
|
+
): Promise<QueryResult<Data>> => {
|
|
49
|
+
if (isFinalized) {
|
|
50
|
+
throw Error(
|
|
51
|
+
`Nitro SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
return executeAsync(dbName, query, params)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const commit = () => {
|
|
58
|
+
if (isFinalized) {
|
|
59
|
+
throw Error(
|
|
60
|
+
`Nitro SQLite Error: Cannot execute commit on finalized transaction: ${dbName}`
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
const result = HybridNitroSQLite.execute(dbName, 'COMMIT')
|
|
64
|
+
isFinalized = true
|
|
65
|
+
return result
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const rollback = () => {
|
|
69
|
+
if (isFinalized) {
|
|
70
|
+
throw Error(
|
|
71
|
+
`Nitro SQLite Error: Cannot execute rollback on finalized transaction: ${dbName}`
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
const result = HybridNitroSQLite.execute(dbName, 'ROLLBACK')
|
|
75
|
+
isFinalized = true
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function run() {
|
|
80
|
+
try {
|
|
81
|
+
await HybridNitroSQLite.executeAsync(dbName, 'BEGIN TRANSACTION')
|
|
82
|
+
|
|
83
|
+
await fn({
|
|
84
|
+
commit,
|
|
85
|
+
execute: executeOnTransaction,
|
|
86
|
+
executeAsync: executeAsyncOnTransaction,
|
|
87
|
+
rollback,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
if (!isFinalized) commit()
|
|
91
|
+
} catch (executionError) {
|
|
92
|
+
if (!isFinalized) {
|
|
93
|
+
try {
|
|
94
|
+
rollback()
|
|
95
|
+
} catch (rollbackError) {
|
|
96
|
+
throw rollbackError
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
throw executionError
|
|
101
|
+
} finally {
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
103
|
+
locks[dbName]!.inProgress = false
|
|
104
|
+
isFinalized = false
|
|
105
|
+
startNextTransaction(dbName)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const tx: PendingTransaction = {
|
|
111
|
+
start: () => {
|
|
112
|
+
run().then(resolve).catch(reject)
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
locks[dbName]?.queue.push(tx)
|
|
117
|
+
startNextTransaction(dbName)
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function startNextTransaction(dbName: string) {
|
|
122
|
+
if (locks[dbName] == null) throw Error(`Lock not found for db: ${dbName}`)
|
|
123
|
+
|
|
124
|
+
if (locks[dbName].inProgress) {
|
|
125
|
+
// Transaction is already in process bail out
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (locks[dbName].queue.length > 0) {
|
|
130
|
+
locks[dbName].inProgress = true
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
132
|
+
const tx = locks[dbName].queue.shift()!
|
|
133
|
+
setImmediate(() => {
|
|
134
|
+
tx.start()
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
import type { ColumnType, SQLiteValue } from '../types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Object returned by SQL Query executions {
|
|
6
|
+
* insertId: Represent the auto-generated row id if applicable
|
|
7
|
+
* rowsAffected: Number of affected rows if result of a update query
|
|
8
|
+
* message: if status === 1, here you will find error description
|
|
9
|
+
* rows: if status is undefined or 0 this object will contain the query results
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* @interface NativeQueryResult
|
|
13
|
+
*/
|
|
14
|
+
export interface NativeQueryResult
|
|
15
|
+
extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
16
|
+
readonly rowsAffected: number
|
|
17
|
+
readonly insertId?: number
|
|
18
|
+
|
|
19
|
+
/** Query results */
|
|
20
|
+
readonly results: SQLiteQueryResults
|
|
21
|
+
/** Table metadata */
|
|
22
|
+
readonly metadata?: Record<string, SQLiteQueryColumnMetadata>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Table metadata
|
|
27
|
+
* Describes some information about the table and it's columns fetched by the query
|
|
28
|
+
* The index is the name of the column
|
|
29
|
+
*/
|
|
30
|
+
// TODO: Investigate why this doesn't work with nitrogen
|
|
31
|
+
// export type SQLiteQueryResultRow = Record<string, SQLiteValue>
|
|
32
|
+
// export type SQLiteQueryResults = SQLiteQueryResultRow[]
|
|
33
|
+
export type SQLiteQueryResults = Record<string, SQLiteValue>[]
|
|
34
|
+
|
|
35
|
+
// TODO: Investigate why this doesn't work with nitrogen
|
|
36
|
+
// export type SQLiteQueryTableMetadata = Record<string, SQLiteQueryColumnMetadata>
|
|
37
|
+
export interface SQLiteQueryColumnMetadata {
|
|
38
|
+
/** The name used for this column for this result set */
|
|
39
|
+
name: string
|
|
40
|
+
/** The declared column type for this column, when fetched directly from a table or a View resulting from a table column. "UNKNOWN" for dynamic values, like function returned ones. */
|
|
41
|
+
type: ColumnType
|
|
42
|
+
/** The index for this column for this result set */
|
|
43
|
+
index: number
|
|
44
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
import type {
|
|
3
|
+
BatchQueryResult,
|
|
4
|
+
FileLoadResult,
|
|
5
|
+
BatchQueryCommand,
|
|
6
|
+
SQLiteQueryParams,
|
|
7
|
+
} from '../types'
|
|
8
|
+
import type { NativeQueryResult } from './NativeQueryResult.nitro'
|
|
9
|
+
|
|
10
|
+
export interface NitroSQLite
|
|
11
|
+
extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
12
|
+
open(dbName: string, location?: string): void
|
|
13
|
+
close(dbName: string): void
|
|
14
|
+
drop(dbName: string, location?: string): void
|
|
15
|
+
attach(
|
|
16
|
+
mainDbName: string,
|
|
17
|
+
dbNameToAttach: string,
|
|
18
|
+
alias: string,
|
|
19
|
+
location?: string
|
|
20
|
+
): void
|
|
21
|
+
detach(mainDbName: string, alias: string): void
|
|
22
|
+
execute(
|
|
23
|
+
dbName: string,
|
|
24
|
+
query: string,
|
|
25
|
+
params?: SQLiteQueryParams
|
|
26
|
+
): NativeQueryResult
|
|
27
|
+
executeAsync(
|
|
28
|
+
dbName: string,
|
|
29
|
+
query: string,
|
|
30
|
+
params?: SQLiteQueryParams
|
|
31
|
+
): Promise<NativeQueryResult>
|
|
32
|
+
executeBatch(dbName: string, commands: BatchQueryCommand[]): BatchQueryResult
|
|
33
|
+
executeBatchAsync(
|
|
34
|
+
dbName: string,
|
|
35
|
+
commands: BatchQueryCommand[]
|
|
36
|
+
): Promise<BatchQueryResult>
|
|
37
|
+
loadFile(dbName: string, location: string): FileLoadResult
|
|
38
|
+
loadFileAsync(dbName: string, location: string): Promise<FileLoadResult>
|
|
39
|
+
}
|
package/src/typeORM.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// _________ _______ ______ ____ _____ __ __ _____ _____
|
|
2
|
+
// |__ __\ \ / / __ \| ____/ __ \| __ \| \/ | /\ | __ \_ _|
|
|
3
|
+
// | | \ \_/ /| |__) | |__ | | | | |__) | \ / | / \ | |__) || |
|
|
4
|
+
// | | \ / | ___/| __|| | | | _ /| |\/| | / /\ \ | ___/ | |
|
|
5
|
+
// | | | | | | | |___| |__| | | \ \| | | | / ____ \| | _| |_
|
|
6
|
+
// |_| |_| |_| |______\____/|_| \_\_| |_| /_/ \_\_| |_____|
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
QueryResult,
|
|
10
|
+
SQLiteItem,
|
|
11
|
+
SQLiteQueryParams,
|
|
12
|
+
Transaction,
|
|
13
|
+
} from './types'
|
|
14
|
+
import * as Operations from './operations/session'
|
|
15
|
+
|
|
16
|
+
interface TypeOrmNitroSQLiteConnection {
|
|
17
|
+
executeSql: <RowData extends SQLiteItem = never>(
|
|
18
|
+
sql: string,
|
|
19
|
+
params: SQLiteQueryParams | undefined,
|
|
20
|
+
okExecute: (res: QueryResult<RowData>) => void,
|
|
21
|
+
failExecute: (msg: string) => void
|
|
22
|
+
) => Promise<void>
|
|
23
|
+
transaction: (fn: (tx: Transaction) => Promise<void>) => Promise<void>
|
|
24
|
+
close: (okClose: () => void, failClose: (e: unknown) => void) => void
|
|
25
|
+
attach: (
|
|
26
|
+
dbNameToAttach: string,
|
|
27
|
+
alias: string,
|
|
28
|
+
location: string | undefined,
|
|
29
|
+
callback: () => void
|
|
30
|
+
) => void
|
|
31
|
+
detach: (alias: string, callback: () => void) => void
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* DO NOT USE THIS! THIS IS MEANT FOR TYPEORM
|
|
36
|
+
* If you are looking for a convenience wrapper use `connect`
|
|
37
|
+
*/
|
|
38
|
+
export const typeORMDriver = {
|
|
39
|
+
openDatabase: (
|
|
40
|
+
options: {
|
|
41
|
+
name: string
|
|
42
|
+
location?: string
|
|
43
|
+
},
|
|
44
|
+
ok: (db: TypeOrmNitroSQLiteConnection) => void,
|
|
45
|
+
fail: (msg: string) => void
|
|
46
|
+
): TypeOrmNitroSQLiteConnection | null => {
|
|
47
|
+
try {
|
|
48
|
+
const db = Operations.open(options)
|
|
49
|
+
|
|
50
|
+
const connection: TypeOrmNitroSQLiteConnection = {
|
|
51
|
+
executeSql: async <RowData extends SQLiteItem = never>(
|
|
52
|
+
sql: string,
|
|
53
|
+
params: SQLiteQueryParams | undefined,
|
|
54
|
+
okExecute: (res: QueryResult<RowData>) => void,
|
|
55
|
+
failExecute: (msg: string) => void
|
|
56
|
+
) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await db.executeAsync<RowData>(sql, params)
|
|
59
|
+
okExecute(result)
|
|
60
|
+
} catch (e: unknown) {
|
|
61
|
+
failExecute(e as string)
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
transaction: (
|
|
65
|
+
fn: (tx: Transaction) => Promise<void>
|
|
66
|
+
): Promise<void> => {
|
|
67
|
+
return db.transaction(fn)
|
|
68
|
+
},
|
|
69
|
+
close: (okClose: () => void, failClose: (e: unknown) => void) => {
|
|
70
|
+
try {
|
|
71
|
+
db.close()
|
|
72
|
+
okClose()
|
|
73
|
+
} catch (e) {
|
|
74
|
+
failClose(e)
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
attach: (
|
|
78
|
+
dbNameToAttach: string,
|
|
79
|
+
alias: string,
|
|
80
|
+
location: string | undefined,
|
|
81
|
+
callback: () => void
|
|
82
|
+
) => {
|
|
83
|
+
db.attach(dbNameToAttach, alias, location)
|
|
84
|
+
callback()
|
|
85
|
+
},
|
|
86
|
+
detach: (alias: string, callback: () => void) => {
|
|
87
|
+
db.detach(alias)
|
|
88
|
+
callback()
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
ok(connection)
|
|
93
|
+
|
|
94
|
+
return connection
|
|
95
|
+
} catch (e: unknown) {
|
|
96
|
+
fail(e as string)
|
|
97
|
+
|
|
98
|
+
return null
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export interface NitroSQLiteConnectionOptions {
|
|
2
|
+
name: string
|
|
3
|
+
location?: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface NitroSQLiteConnection {
|
|
7
|
+
close(): void
|
|
8
|
+
delete(): void
|
|
9
|
+
attach(dbNameToAttach: string, alias: string, location?: string): void
|
|
10
|
+
detach(alias: string): void
|
|
11
|
+
transaction(fn: (tx: Transaction) => Promise<void> | void): Promise<void>
|
|
12
|
+
execute: ExecuteQuery
|
|
13
|
+
executeAsync: ExecuteAsyncQuery
|
|
14
|
+
executeBatch(commands: BatchQueryCommand[]): BatchQueryResult
|
|
15
|
+
executeBatchAsync(commands: BatchQueryCommand[]): Promise<BatchQueryResult>
|
|
16
|
+
loadFile(location: string): FileLoadResult
|
|
17
|
+
loadFileAsync(location: string): Promise<FileLoadResult>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
21
|
+
export enum ColumnType {
|
|
22
|
+
BOOLEAN,
|
|
23
|
+
NUMBER,
|
|
24
|
+
INT64,
|
|
25
|
+
TEXT,
|
|
26
|
+
ARRAY_BUFFER,
|
|
27
|
+
NULL_VALUE,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Represents a value that can be stored in a SQLite database
|
|
32
|
+
*/
|
|
33
|
+
export type SQLiteValue =
|
|
34
|
+
| boolean
|
|
35
|
+
| number
|
|
36
|
+
| bigint
|
|
37
|
+
| string
|
|
38
|
+
| ArrayBuffer
|
|
39
|
+
| undefined
|
|
40
|
+
|
|
41
|
+
export type SQLiteItem = Record<string, SQLiteValue>
|
|
42
|
+
|
|
43
|
+
export interface QueryResult<RowData extends SQLiteItem = SQLiteItem> {
|
|
44
|
+
readonly insertId?: number
|
|
45
|
+
readonly rowsAffected: number
|
|
46
|
+
|
|
47
|
+
readonly rows?: {
|
|
48
|
+
/** Raw array with all dataset */
|
|
49
|
+
_array: RowData[]
|
|
50
|
+
/** The lengh of the dataset */
|
|
51
|
+
length: number
|
|
52
|
+
/** A convenience function to acess the index based the row object
|
|
53
|
+
* @param idx the row index
|
|
54
|
+
* @returns the row structure identified by column names
|
|
55
|
+
*/
|
|
56
|
+
item: (idx: number) => RowData | undefined
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type SQLiteQueryParams = SQLiteValue[]
|
|
61
|
+
|
|
62
|
+
export type ExecuteQuery = <RowData extends SQLiteItem = SQLiteItem>(
|
|
63
|
+
query: string,
|
|
64
|
+
params?: SQLiteQueryParams
|
|
65
|
+
) => QueryResult<RowData>
|
|
66
|
+
|
|
67
|
+
export type ExecuteAsyncQuery = <RowData extends SQLiteItem = SQLiteItem>(
|
|
68
|
+
query: string,
|
|
69
|
+
params?: SQLiteQueryParams
|
|
70
|
+
) => Promise<QueryResult<RowData>>
|
|
71
|
+
|
|
72
|
+
export interface Transaction {
|
|
73
|
+
commit(): QueryResult
|
|
74
|
+
rollback(): QueryResult
|
|
75
|
+
execute: ExecuteQuery
|
|
76
|
+
executeAsync: ExecuteAsyncQuery
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Allows the execution of bulk of sql commands
|
|
81
|
+
* inside a transaction
|
|
82
|
+
* If a single query must be executed many times with different arguments, its preferred
|
|
83
|
+
* to declare it a single time, and use an array of array parameters.
|
|
84
|
+
*/
|
|
85
|
+
export interface BatchQueryCommand {
|
|
86
|
+
query: string
|
|
87
|
+
params?: SQLiteQueryParams | SQLiteQueryParams[]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* status: 0 or undefined for correct execution, 1 for error
|
|
92
|
+
* message: if status === 1, here you will find error description
|
|
93
|
+
* rowsAffected: Number of affected rows if status == 0
|
|
94
|
+
*/
|
|
95
|
+
export interface BatchQueryResult {
|
|
96
|
+
rowsAffected?: number
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Result of loading a file and executing every line as a SQL command
|
|
101
|
+
* Similar to BatchQueryResult
|
|
102
|
+
*/
|
|
103
|
+
export interface FileLoadResult extends BatchQueryResult {
|
|
104
|
+
commands?: number
|
|
105
|
+
}
|