react-native-nitro-sqlite 9.8.1 → 10.0.0

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.
Files changed (145) hide show
  1. package/RNNitroSQLite.podspec +7 -3
  2. package/android/CMakeLists.txt +3 -2
  3. package/android/build.gradle +2 -0
  4. package/android/sqlite-flags.gradle +47 -0
  5. package/cpp/NitroSQLiteDatabaseConnections.cpp +306 -0
  6. package/cpp/NitroSQLiteDatabaseConnections.hpp +86 -0
  7. package/cpp/{databaseMigration.cpp → NitroSQLiteDatabaseMigration.cpp} +2 -2
  8. package/cpp/{sqliteExecuteBatch.cpp → NitroSQLiteExecuteBatch.cpp} +4 -4
  9. package/cpp/{sqliteExecuteBatch.hpp → NitroSQLiteExecuteBatch.hpp} +3 -6
  10. package/cpp/{importSqlFile.cpp → NitroSQLiteImportSqlFile.cpp} +4 -4
  11. package/cpp/{importSqlFile.hpp → NitroSQLiteImportSqlFile.hpp} +3 -3
  12. package/cpp/{macros.hpp → NitroSQLiteMacros.hpp} +3 -3
  13. package/cpp/NitroSQLiteOperations.cpp +396 -0
  14. package/cpp/NitroSQLiteOperations.hpp +72 -0
  15. package/cpp/{types.hpp → NitroSQLiteTypes.hpp} +3 -6
  16. package/cpp/{utils.hpp → NitroSQLiteUtils.hpp} +2 -2
  17. package/cpp/hybridObjects/HybridNitroSQLite.cpp +108 -22
  18. package/cpp/hybridObjects/HybridNitroSQLite.hpp +49 -5
  19. package/cpp/hybridObjects/HybridNitroSQLitePreparedStatement.cpp +59 -0
  20. package/cpp/hybridObjects/HybridNitroSQLitePreparedStatement.hpp +33 -0
  21. package/cpp/hybridObjects/HybridNitroSQLiteQueryResult.hpp +6 -4
  22. package/ios/OnLoad.mm +38 -2
  23. package/lib/commonjs/DatabaseQueue.js +52 -16
  24. package/lib/commonjs/DatabaseQueue.js.map +1 -1
  25. package/lib/commonjs/NitroSQLiteError.js +6 -7
  26. package/lib/commonjs/NitroSQLiteError.js.map +1 -1
  27. package/lib/commonjs/OnLoad.js +1 -1
  28. package/lib/commonjs/index.js +8 -3
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/commonjs/operations/execute.js +19 -4
  31. package/lib/commonjs/operations/execute.js.map +1 -1
  32. package/lib/commonjs/operations/executeBatch.js +19 -6
  33. package/lib/commonjs/operations/executeBatch.js.map +1 -1
  34. package/lib/commonjs/operations/prepare.js +54 -0
  35. package/lib/commonjs/operations/prepare.js.map +1 -0
  36. package/lib/commonjs/operations/session.js +106 -30
  37. package/lib/commonjs/operations/session.js.map +1 -1
  38. package/lib/commonjs/operations/transaction.js +30 -5
  39. package/lib/commonjs/operations/transaction.js.map +1 -1
  40. package/lib/commonjs/specs/NitroSQLitePreparedStatement.nitro.js +6 -0
  41. package/lib/commonjs/specs/NitroSQLitePreparedStatement.nitro.js.map +1 -0
  42. package/lib/commonjs/typeORM.js +10 -3
  43. package/lib/commonjs/typeORM.js.map +1 -1
  44. package/lib/commonjs/types.js +35 -9
  45. package/lib/commonjs/types.js.map +1 -1
  46. package/lib/module/DatabaseQueue.js +52 -16
  47. package/lib/module/DatabaseQueue.js.map +1 -1
  48. package/lib/module/NitroSQLiteError.js +6 -7
  49. package/lib/module/NitroSQLiteError.js.map +1 -1
  50. package/lib/module/OnLoad.js +1 -1
  51. package/lib/module/index.js +8 -3
  52. package/lib/module/index.js.map +1 -1
  53. package/lib/module/operations/execute.js +20 -5
  54. package/lib/module/operations/execute.js.map +1 -1
  55. package/lib/module/operations/executeBatch.js +20 -7
  56. package/lib/module/operations/executeBatch.js.map +1 -1
  57. package/lib/module/operations/prepare.js +49 -0
  58. package/lib/module/operations/prepare.js.map +1 -0
  59. package/lib/module/operations/session.js +107 -31
  60. package/lib/module/operations/session.js.map +1 -1
  61. package/lib/module/operations/transaction.js +30 -5
  62. package/lib/module/operations/transaction.js.map +1 -1
  63. package/lib/module/specs/NitroSQLitePreparedStatement.nitro.js +4 -0
  64. package/lib/module/specs/NitroSQLitePreparedStatement.nitro.js.map +1 -0
  65. package/lib/module/typeORM.js +11 -3
  66. package/lib/module/typeORM.js.map +1 -1
  67. package/lib/module/types.js +48 -9
  68. package/lib/module/types.js.map +1 -1
  69. package/lib/typescript/commonjs/DatabaseQueue.d.ts +15 -7
  70. package/lib/typescript/commonjs/DatabaseQueue.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/NitroSQLiteError.d.ts +6 -7
  72. package/lib/typescript/commonjs/NitroSQLiteError.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/index.d.ts +9 -2
  74. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/operations/execute.d.ts +17 -2
  76. package/lib/typescript/commonjs/operations/execute.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/operations/executeBatch.d.ts +15 -2
  78. package/lib/typescript/commonjs/operations/executeBatch.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/operations/prepare.d.ts +13 -0
  80. package/lib/typescript/commonjs/operations/prepare.d.ts.map +1 -0
  81. package/lib/typescript/commonjs/operations/session.d.ts +8 -0
  82. package/lib/typescript/commonjs/operations/session.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/operations/transaction.d.ts +11 -1
  84. package/lib/typescript/commonjs/operations/transaction.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/specs/NitroSQLite.nitro.d.ts +83 -2
  86. package/lib/typescript/commonjs/specs/NitroSQLite.nitro.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/specs/NitroSQLitePreparedStatement.nitro.d.ts +26 -0
  88. package/lib/typescript/commonjs/specs/NitroSQLitePreparedStatement.nitro.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/specs/NitroSQLiteQueryResult.nitro.d.ts +9 -15
  90. package/lib/typescript/commonjs/specs/NitroSQLiteQueryResult.nitro.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/typeORM.d.ts +14 -3
  92. package/lib/typescript/commonjs/typeORM.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/types.d.ts +124 -21
  94. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  95. package/lib/typescript/module/DatabaseQueue.d.ts +15 -7
  96. package/lib/typescript/module/DatabaseQueue.d.ts.map +1 -1
  97. package/lib/typescript/module/NitroSQLiteError.d.ts +6 -7
  98. package/lib/typescript/module/NitroSQLiteError.d.ts.map +1 -1
  99. package/lib/typescript/module/index.d.ts +9 -2
  100. package/lib/typescript/module/index.d.ts.map +1 -1
  101. package/lib/typescript/module/operations/execute.d.ts +17 -2
  102. package/lib/typescript/module/operations/execute.d.ts.map +1 -1
  103. package/lib/typescript/module/operations/executeBatch.d.ts +15 -2
  104. package/lib/typescript/module/operations/executeBatch.d.ts.map +1 -1
  105. package/lib/typescript/module/operations/prepare.d.ts +13 -0
  106. package/lib/typescript/module/operations/prepare.d.ts.map +1 -0
  107. package/lib/typescript/module/operations/session.d.ts +8 -0
  108. package/lib/typescript/module/operations/session.d.ts.map +1 -1
  109. package/lib/typescript/module/operations/transaction.d.ts +11 -1
  110. package/lib/typescript/module/operations/transaction.d.ts.map +1 -1
  111. package/lib/typescript/module/specs/NitroSQLite.nitro.d.ts +83 -2
  112. package/lib/typescript/module/specs/NitroSQLite.nitro.d.ts.map +1 -1
  113. package/lib/typescript/module/specs/NitroSQLitePreparedStatement.nitro.d.ts +26 -0
  114. package/lib/typescript/module/specs/NitroSQLitePreparedStatement.nitro.d.ts.map +1 -0
  115. package/lib/typescript/module/specs/NitroSQLiteQueryResult.nitro.d.ts +9 -15
  116. package/lib/typescript/module/specs/NitroSQLiteQueryResult.nitro.d.ts.map +1 -1
  117. package/lib/typescript/module/typeORM.d.ts +14 -3
  118. package/lib/typescript/module/typeORM.d.ts.map +1 -1
  119. package/lib/typescript/module/types.d.ts +124 -21
  120. package/lib/typescript/module/types.d.ts.map +1 -1
  121. package/nitrogen/generated/android/RNNitroSQLite+autolinking.cmake +1 -0
  122. package/nitrogen/generated/shared/c++/HybridNitroSQLitePreparedStatementSpec.cpp +24 -0
  123. package/nitrogen/generated/shared/c++/HybridNitroSQLitePreparedStatementSpec.hpp +73 -0
  124. package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.cpp +3 -0
  125. package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.hpp +8 -2
  126. package/package.json +4 -2
  127. package/src/DatabaseQueue.ts +81 -25
  128. package/src/NitroSQLiteError.ts +6 -7
  129. package/src/OnLoad.ts +1 -1
  130. package/src/index.ts +7 -3
  131. package/src/operations/execute.ts +22 -3
  132. package/src/operations/executeBatch.ts +20 -5
  133. package/src/operations/prepare.ts +69 -0
  134. package/src/operations/session.ts +136 -45
  135. package/src/operations/transaction.ts +37 -4
  136. package/src/specs/NitroSQLite.nitro.ts +84 -2
  137. package/src/specs/NitroSQLitePreparedStatement.nitro.ts +28 -0
  138. package/src/specs/NitroSQLiteQueryResult.nitro.ts +9 -15
  139. package/src/typeORM.ts +14 -3
  140. package/src/types.ts +135 -21
  141. package/cpp/operations.cpp +0 -358
  142. package/cpp/operations.hpp +0 -56
  143. /package/android/{cpp-adapter.cpp → RNNitroSQLiteAdapter.cpp} +0 -0
  144. /package/cpp/{databaseMigration.hpp → NitroSQLiteDatabaseMigration.hpp} +0 -0
  145. /package/cpp/{logs.hpp → NitroSQLiteLogs.hpp} +0 -0
@@ -11,95 +11,186 @@ import type {
11
11
  } from '../types'
12
12
  import { executeAsyncManaged, executeManaged } from './execute'
13
13
  import { executeBatch, executeBatchAsync } from './executeBatch'
14
+ import { prepare } from './prepare'
14
15
  import NitroSQLiteError from '../NitroSQLiteError'
15
16
  import {
16
17
  closeDatabaseQueue,
18
+ getDatabaseQueue,
17
19
  isDatabaseOpen,
18
20
  openDatabaseQueue,
19
- queueOperationAsync,
21
+ queueStatementAsync,
20
22
  startOperationSync,
21
23
  } from '../DatabaseQueue'
24
+ import type { DatabaseQueueKey } from '../DatabaseQueue'
22
25
 
26
+ /**
27
+ * Open a database and return a managed connection. The default connection is
28
+ * addressed by its name, and opening it twice throws. Set `connection` to
29
+ * `'independent'` to open another native handle to the same file. Async calls
30
+ * on each connection run in call order.
31
+ * @param options Database name, optional directory, connection mode, and read-only setting.
32
+ * @returns A connection bound to the opened native handle.
33
+ */
23
34
  export function open(
24
35
  options: NitroSQLiteConnectionOptions,
25
36
  ): NitroSQLiteConnection {
26
- openDatabaseQueue(options.name)
37
+ const { name, location: databaseLocation, connection, readOnly } = options
38
+ const { connectionId, queueKey } = openNativeConnection(options)
39
+ const connectionQueue = getDatabaseQueue(queueKey)
27
40
 
28
- try {
29
- HybridNitroSQLite.open(options.name, options.location)
30
- } catch (error) {
31
- closeDatabaseQueue(options.name)
32
- throw NitroSQLiteError.fromError(error)
41
+ const assertCurrentConnection = () => {
42
+ if (
43
+ !isDatabaseOpen(queueKey) ||
44
+ getDatabaseQueue(queueKey) !== connectionQueue
45
+ ) {
46
+ throw new NitroSQLiteError(
47
+ `Database ${name} is not open. There is no connection to the database.`,
48
+ )
49
+ }
50
+ }
51
+
52
+ const assertNoReplacement = () => {
53
+ if (
54
+ isDatabaseOpen(queueKey) &&
55
+ getDatabaseQueue(queueKey) !== connectionQueue
56
+ ) {
57
+ throw new NitroSQLiteError(
58
+ `Database ${name} has been reopened with another connection.`,
59
+ )
60
+ }
61
+ }
62
+
63
+ const runSyncOperation = <Result>(callback: () => Result): Result => {
64
+ try {
65
+ assertCurrentConnection()
66
+ return startOperationSync(queueKey, callback)
67
+ } catch (error) {
68
+ throw NitroSQLiteError.fromError(error)
69
+ }
70
+ }
71
+
72
+ const runOperation = <Result>(callback: () => Result): Result => {
73
+ assertCurrentConnection()
74
+ return callback()
33
75
  }
34
76
 
35
77
  return {
36
78
  close: () => {
37
- try {
38
- startOperationSync(options.name, () =>
39
- HybridNitroSQLite.close(options.name),
40
- )
41
- closeDatabaseQueue(options.name)
42
- } catch (error) {
43
- throw NitroSQLiteError.fromError(error)
44
- }
79
+ runSyncOperation(() => HybridNitroSQLite.close(connectionId))
80
+ closeDatabaseQueue(queueKey)
45
81
  },
46
82
  delete: () => {
83
+ if (readOnly) {
84
+ throw new NitroSQLiteError(`Cannot delete read-only database ${name}.`)
85
+ }
86
+
87
+ let dropFailed = false
47
88
  try {
48
- if (!isDatabaseOpen(options.name)) {
49
- HybridNitroSQLite.drop(options.name, options.location)
89
+ assertNoReplacement()
90
+ const drop = () => {
91
+ try {
92
+ if (connection === 'independent') {
93
+ HybridNitroSQLite.drop(name, databaseLocation, connectionId)
94
+ } else {
95
+ HybridNitroSQLite.drop(name, databaseLocation)
96
+ }
97
+ } catch (error) {
98
+ dropFailed = true
99
+ throw error
100
+ }
101
+ }
102
+
103
+ if (!isDatabaseOpen(queueKey)) {
104
+ drop()
50
105
  return
51
106
  }
52
107
 
53
- startOperationSync(options.name, () =>
54
- HybridNitroSQLite.drop(options.name, options.location),
55
- )
56
- closeDatabaseQueue(options.name)
108
+ startOperationSync(queueKey, drop)
109
+ closeDatabaseQueue(queueKey)
57
110
  } catch (error) {
111
+ if (
112
+ dropFailed &&
113
+ isDatabaseOpen(queueKey) &&
114
+ getDatabaseQueue(queueKey) === connectionQueue &&
115
+ !HybridNitroSQLite.isConnectionOpen(connectionId)
116
+ ) {
117
+ closeDatabaseQueue(queueKey)
118
+ }
58
119
  throw NitroSQLiteError.fromError(error)
59
120
  }
60
121
  },
61
122
  attach: (dbNameToAttach: string, alias: string, location?: string) =>
62
- runSyncOperation(options.name, () =>
63
- HybridNitroSQLite.attach(options.name, dbNameToAttach, alias, location),
123
+ runSyncOperation(() =>
124
+ HybridNitroSQLite.attach(connectionId, dbNameToAttach, alias, location),
64
125
  ),
65
126
  detach: (alias: string) =>
66
- runSyncOperation(options.name, () =>
67
- HybridNitroSQLite.detach(options.name, alias),
68
- ),
69
- transaction: <Result = void>(fn: (tx: Transaction) => Promise<Result>) =>
70
- transaction(options.name, fn),
127
+ runSyncOperation(() => HybridNitroSQLite.detach(connectionId, alias)),
128
+ transaction: async <Result = void>(
129
+ fn: (tx: Transaction) => Promise<Result>,
130
+ ) => runOperation(() => transaction(connectionId, fn, false, queueKey)),
71
131
  execute: <Row extends QueryResultRow = never>(
72
132
  query: string,
73
133
  params?: SQLiteQueryParams,
74
- ): QueryResult<Row> => executeManaged(options.name, query, params),
75
- executeAsync: <Row extends QueryResultRow = never>(
134
+ ): QueryResult<Row> =>
135
+ runOperation(() => executeManaged(connectionId, query, params, queueKey)),
136
+ executeAsync: async <Row extends QueryResultRow = never>(
76
137
  query: string,
77
138
  params?: SQLiteQueryParams,
78
139
  ): Promise<QueryResult<Row>> =>
79
- executeAsyncManaged(options.name, query, params),
140
+ runOperation(() =>
141
+ executeAsyncManaged(connectionId, query, params, queueKey),
142
+ ),
143
+ prepare: (query: string) =>
144
+ runOperation(() => prepare(connectionId, query, queueKey)),
80
145
  executeBatch: (commands: BatchQueryCommand[]) =>
81
- executeBatch(options.name, commands),
82
- executeBatchAsync: (commands: BatchQueryCommand[]) =>
83
- executeBatchAsync(options.name, commands),
146
+ runOperation(() => executeBatch(connectionId, commands, queueKey)),
147
+ executeBatchAsync: async (commands: BatchQueryCommand[]) =>
148
+ runOperation(() => executeBatchAsync(connectionId, commands, queueKey)),
84
149
  loadFile: (location: string) =>
85
- runSyncOperation(options.name, () =>
86
- HybridNitroSQLite.loadFile(options.name, location),
150
+ runSyncOperation(() =>
151
+ HybridNitroSQLite.loadFile(connectionId, location),
87
152
  ),
88
153
  loadFileAsync: (location: string) =>
89
- queueOperationAsync(options.name, async () => {
90
- try {
91
- return await HybridNitroSQLite.loadFileAsync(options.name, location)
92
- } catch (error) {
93
- throw NitroSQLiteError.fromError(error)
94
- }
95
- }),
154
+ runOperation(() =>
155
+ queueStatementAsync(queueKey, async () => {
156
+ try {
157
+ return await HybridNitroSQLite.loadFileAsync(connectionId, location)
158
+ } catch (error) {
159
+ throw NitroSQLiteError.fromError(error)
160
+ }
161
+ }),
162
+ ),
96
163
  }
97
164
  }
98
165
 
99
- function runSyncOperation<Result>(dbName: string, callback: () => Result) {
166
+ function openNativeConnection(options: NitroSQLiteConnectionOptions): {
167
+ connectionId: string
168
+ queueKey: DatabaseQueueKey
169
+ } {
170
+ if (options.connection === 'independent') {
171
+ let connectionId: string
172
+ try {
173
+ connectionId = options.readOnly
174
+ ? HybridNitroSQLite.openConnection(options.name, options.location, true)
175
+ : HybridNitroSQLite.openConnection(options.name, options.location)
176
+ const queueKey = Symbol(options.name)
177
+ openDatabaseQueue(queueKey)
178
+ return { connectionId, queueKey }
179
+ } catch (error) {
180
+ throw NitroSQLiteError.fromError(error)
181
+ }
182
+ }
183
+
184
+ openDatabaseQueue(options.name)
100
185
  try {
101
- return startOperationSync(dbName, callback)
186
+ if (options.readOnly) {
187
+ HybridNitroSQLite.open(options.name, options.location, true)
188
+ } else {
189
+ HybridNitroSQLite.open(options.name, options.location)
190
+ }
102
191
  } catch (error) {
192
+ closeDatabaseQueue(options.name)
103
193
  throw NitroSQLiteError.fromError(error)
104
194
  }
195
+ return { connectionId: options.name, queueKey: options.name }
105
196
  }
@@ -7,15 +7,35 @@ import type {
7
7
  } from '../types'
8
8
  import { executeAsyncNative, executeNative } from './execute'
9
9
  import NitroSQLiteError from '../NitroSQLiteError'
10
+ import type { DatabaseQueueKey } from '../DatabaseQueue'
10
11
 
12
+ /** Queue a transaction for an open managed connection.
13
+ * Use only the supplied `tx` for work on this database inside the callback.
14
+ * A successful callback commits unless it explicitly committed or rolled back;
15
+ * a thrown error rolls back unless the transaction was already finalized.
16
+ * @param dbName Name of the open database.
17
+ * @param transactionCallback Async callback receiving the transaction handle.
18
+ * @param isExclusive Begin an exclusive transaction when true.
19
+ * @returns The callback's result after the transaction finishes.
20
+ */
11
21
  export const transaction = async <Result = void>(
12
22
  dbName: string,
13
23
  transactionCallback: (tx: Transaction) => Promise<Result>,
14
24
  isExclusive = false,
25
+ queueKey: DatabaseQueueKey = dbName,
15
26
  ) => {
16
- throwIfDatabaseIsNotOpen(dbName)
27
+ throwIfDatabaseIsNotOpen(queueKey)
17
28
 
18
29
  let isFinished = false
30
+ const pendingAsyncStatements = new Set<Promise<unknown>>()
31
+
32
+ const throwIfAsyncPending = () => {
33
+ if (pendingAsyncStatements.size > 0) {
34
+ throw new NitroSQLiteError(
35
+ `Cannot run synchronous operation on transaction ${dbName} while async queries are pending. Await all tx.executeAsync calls first.`,
36
+ )
37
+ }
38
+ }
19
39
 
20
40
  const executeOnTransaction = <Row extends QueryResultRow = never>(
21
41
  query: string,
@@ -26,6 +46,7 @@ export const transaction = async <Result = void>(
26
46
  `Cannot execute query on finalized transaction: ${dbName}`,
27
47
  )
28
48
  }
49
+ throwIfAsyncPending()
29
50
  return executeNative(dbName, query, params)
30
51
  }
31
52
 
@@ -38,7 +59,13 @@ export const transaction = async <Result = void>(
38
59
  `Cannot execute query on finalized transaction: ${dbName}`,
39
60
  )
40
61
  }
41
- return executeAsyncNative(dbName, query, params)
62
+ const pending = executeAsyncNative<Row>(dbName, query, params)
63
+ pendingAsyncStatements.add(pending)
64
+ pending.then(
65
+ () => pendingAsyncStatements.delete(pending),
66
+ () => pendingAsyncStatements.delete(pending),
67
+ )
68
+ return pending
42
69
  }
43
70
 
44
71
  const commit = () => {
@@ -47,6 +74,7 @@ export const transaction = async <Result = void>(
47
74
  `Cannot execute commit on finalized transaction: ${dbName}`,
48
75
  )
49
76
  }
77
+ throwIfAsyncPending()
50
78
  isFinished = true
51
79
  return executeNative(dbName, 'COMMIT')
52
80
  }
@@ -57,11 +85,12 @@ export const transaction = async <Result = void>(
57
85
  `Cannot execute rollback on finalized transaction: ${dbName}`,
58
86
  )
59
87
  }
88
+ throwIfAsyncPending()
60
89
  isFinished = true
61
90
  return executeNative(dbName, 'ROLLBACK')
62
91
  }
63
92
 
64
- return await queueOperationAsync(dbName, async () => {
93
+ return await queueOperationAsync(queueKey, async () => {
65
94
  try {
66
95
  await executeAsyncNative(
67
96
  dbName,
@@ -80,8 +109,12 @@ export const transaction = async <Result = void>(
80
109
  return result
81
110
  } catch (executionError) {
82
111
  if (!isFinished) {
112
+ isFinished = true
113
+ // All queued native calls must finish before ROLLBACK can run
114
+ // synchronously on this connection.
115
+ await Promise.allSettled(pendingAsyncStatements)
83
116
  try {
84
- rollback()
117
+ executeNative(dbName, 'ROLLBACK')
85
118
  } catch (rollbackError) {
86
119
  throw NitroSQLiteError.fromError(rollbackError)
87
120
  }
@@ -6,37 +6,119 @@ import type {
6
6
  SQLiteQueryParams,
7
7
  } from '../types'
8
8
  import type { NitroSQLiteQueryResult } from './NitroSQLiteQueryResult.nitro'
9
+ import type { NitroSQLitePreparedStatement } from './NitroSQLitePreparedStatement.nitro'
9
10
 
11
+ /** Native database operations exposed through `NitroSQLite.native`.
12
+ * These calls bypass the managed connection queue. Coordinate them with any
13
+ * transaction or pending operation on the same database yourself.
14
+ */
10
15
  export interface NitroSQLite
11
16
  extends HybridObject<{
12
17
  ios: 'c++'
13
18
  android: 'c++'
14
19
  }> {
15
- open(dbName: string, location?: string): void
20
+ /** Open a name-based default connection, creating the database unless `readOnly` is true.
21
+ * @param dbName Database file name and default connection key.
22
+ * @param location Directory relative to the platform database directory.
23
+ * @param readOnly Open an existing database without write access.
24
+ */
25
+ open(dbName: string, location?: string, readOnly?: boolean): void
26
+ /** Open a separate native handle, even when the database file is already open.
27
+ * Independent connections require a thread-safe SQLite build.
28
+ * @param dbName Database file name.
29
+ * @param location Directory relative to the platform database directory.
30
+ * @param readOnly Open an existing database without write access.
31
+ * @returns An opaque ID to pass to native connection operations.
32
+ */
33
+ openConnection(dbName: string, location?: string, readOnly?: boolean): string
34
+ /** Check whether a native connection ID is still open.
35
+ * @param connectionId ID returned by `openConnection`.
36
+ */
37
+ isConnectionOpen(connectionId: string): boolean
38
+ /** Close a default connection by name or an independent connection by ID. */
16
39
  close(dbName: string): void
17
- drop(dbName: string, location?: string): void
40
+ /** Delete a database and close the indicated connection if open.
41
+ * Deletion fails while another connection or attachment uses the database file.
42
+ * @param dbName Database file name.
43
+ * @param location Directory relative to the platform database directory.
44
+ * @param connectionId Optional ID of the independent connection to close.
45
+ */
46
+ drop(dbName: string, location?: string, connectionId?: string): void
47
+ /** Attach a database file to an open main database under an SQL schema alias.
48
+ * @param mainDbName Name of the open main database.
49
+ * @param dbNameToAttach File name of the database to attach.
50
+ * @param alias SQL schema name for the attached database.
51
+ * @param location Directory relative to the platform database directory.
52
+ */
53
+
18
54
  attach(
19
55
  mainDbName: string,
20
56
  dbNameToAttach: string,
21
57
  alias: string,
22
58
  location?: string,
23
59
  ): void
60
+ /** Detach an attached database by its alias.
61
+ * @param mainDbName Name of the open main database.
62
+ * @param alias SQL schema name used when attaching.
63
+ */
24
64
  detach(mainDbName: string, alias: string): void
65
+ /** Execute one SQL statement synchronously on the calling thread.
66
+ * @param dbName Name of an open database.
67
+ * @param query SQL statement with optional positional placeholders.
68
+ * @param params Positional values bound to SQL placeholders.
69
+ * @returns Native query rows, affected row count, insert ID, and metadata.
70
+ */
25
71
  execute(
26
72
  dbName: string,
27
73
  query: string,
28
74
  params?: SQLiteQueryParams,
29
75
  ): NitroSQLiteQueryResult
76
+ /** Execute one SQL statement on a background thread.
77
+ * @param dbName Name of an open database.
78
+ * @param query SQL statement with optional positional placeholders.
79
+ * @param params Positional values bound to SQL placeholders.
80
+ * @returns A promise of the native query result.
81
+ */
30
82
  executeAsync(
31
83
  dbName: string,
32
84
  query: string,
33
85
  params?: SQLiteQueryParams,
34
86
  ): Promise<NitroSQLiteQueryResult>
87
+ /** Prepare one SQL statement on an open native connection for repeated execution.
88
+ * Finalize the returned statement before closing its connection.
89
+ * @param dbName Name or ID of an open database connection.
90
+ * @param query SQL statement with optional positional placeholders.
91
+ * @returns A native statement with synchronous and asynchronous execution methods.
92
+ */
93
+ prepare(dbName: string, query: string): NitroSQLitePreparedStatement
94
+ /** Execute commands in one exclusive transaction on the calling thread.
95
+ * An empty batch throws; a failed command rolls back the batch.
96
+ * @param dbName Name of an open database.
97
+ * @param commands SQL commands and optional parameter sets.
98
+ * @returns Total affected row count.
99
+ */
35
100
  executeBatch(dbName: string, commands: BatchQueryCommand[]): BatchQueryResult
101
+ /** Execute commands in one exclusive transaction on a background thread.
102
+ * An empty batch rejects; a failed command rolls back the batch.
103
+ * @param dbName Name of an open database.
104
+ * @param commands SQL commands and optional parameter sets.
105
+ * @returns A promise of the total affected row count.
106
+ */
36
107
  executeBatchAsync(
37
108
  dbName: string,
38
109
  commands: BatchQueryCommand[],
39
110
  ): Promise<BatchQueryResult>
111
+ /** Import a SQL file in one exclusive transaction on the calling thread.
112
+ * Each non-empty line is treated as one statement.
113
+ * @param dbName Name of an open database.
114
+ * @param location Path to the SQL file.
115
+ * @returns Number of executed commands and affected rows.
116
+ */
40
117
  loadFile(dbName: string, location: string): FileLoadResult
118
+ /** Import a SQL file on a background thread.
119
+ * @param dbName Name of an open database.
120
+ * @param location Path to the SQL file.
121
+ * @returns A promise of the command and affected row counts.
122
+ */
41
123
  loadFileAsync(dbName: string, location: string): Promise<FileLoadResult>
42
124
  }
@@ -0,0 +1,28 @@
1
+ import type { HybridObject } from 'react-native-nitro-modules'
2
+ import type { SQLiteQueryParams } from '../types'
3
+ import type { NitroSQLiteQueryResult } from './NitroSQLiteQueryResult.nitro'
4
+
5
+ /** Native prepared statement returned by `NitroSQLite.native.prepare()`. */
6
+ export interface NitroSQLitePreparedStatement
7
+ extends HybridObject<{
8
+ ios: 'c++'
9
+ android: 'c++'
10
+ }> {
11
+ /** Whether the native statement has been finalized. */
12
+ readonly isFinalized: boolean
13
+
14
+ /** Execute on the calling thread, replacing the previous parameter bindings.
15
+ * Throws after finalization or connection closure.
16
+ * @param params Values bound to positional placeholders.
17
+ * @returns Native query rows, affected row count, insert ID, and metadata.
18
+ */
19
+ execute(params?: SQLiteQueryParams): NitroSQLiteQueryResult
20
+ /** Execute on a background thread, replacing the previous parameter bindings.
21
+ * Rejects after finalization or connection closure.
22
+ * @param params Values bound to positional placeholders.
23
+ * @returns A promise of the native query result.
24
+ */
25
+ executeAsync(params?: SQLiteQueryParams): Promise<NitroSQLiteQueryResult>
26
+ /** Release the native statement. Repeated calls are safe. */
27
+ finalize(): void
28
+ }
@@ -1,28 +1,21 @@
1
1
  import type { HybridObject } from 'react-native-nitro-modules'
2
2
  import type { ColumnType, SQLiteValue } from '../types'
3
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 QueryResult
13
- */
4
+ /** Native result of one SQL statement. The managed API also adds a `rows` adapter. */
14
5
  export interface NitroSQLiteQueryResult
15
6
  extends HybridObject<{
16
7
  ios: 'c++'
17
8
  android: 'c++'
18
9
  }> {
10
+ /** SQLite's latest row change count. For a read-only query it may reflect an earlier write. */
19
11
  readonly rowsAffected: number
12
+ /** Last insert row ID for this connection. It may refer to an earlier statement. */
20
13
  readonly insertId?: number
21
14
 
22
- /** Query results */
15
+ /** Rows keyed by result column names. */
23
16
  readonly results: Record<string, SQLiteValue>[]
24
17
 
25
- /** Table metadata */
18
+ /** Column metadata keyed by result column name, when available. */
26
19
  readonly metadata?: Record<string, NitroSQLiteQueryColumnMetadata>
27
20
  }
28
21
 
@@ -33,13 +26,14 @@ export interface NitroSQLiteQueryResult
33
26
 
34
27
  // type NitroQueryResultRow = Record<string, SQLiteValue>
35
28
 
29
+ /** Name, declared type, and position of a result column. */
36
30
  export type NitroSQLiteQueryColumnMetadata = {
37
- /** The name used for this column for this result set */
31
+ /** Name used for this column in the result set. */
38
32
  name: string
39
33
 
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. */
34
+ /** Native type category derived from the column declaration. */
41
35
  type: ColumnType
42
36
 
43
- /** The index for this column for this result set */
37
+ /** Zero-based position in the result set. */
44
38
  index: number
45
39
  }
package/src/typeORM.ts CHANGED
@@ -13,29 +13,40 @@ import type {
13
13
  } from './types'
14
14
  import * as Operations from './operations/session'
15
15
 
16
+ /** Callback-oriented connection returned to TypeORM. */
16
17
  interface TypeOrmNitroSQLiteConnection {
18
+ /** Execute SQL asynchronously and report the result through a callback. */
17
19
  executeSql: <RowData extends QueryResultRow = never>(
18
20
  sql: string,
19
21
  params: SQLiteQueryParams | undefined,
20
22
  okExecute: (res: QueryResult<RowData>) => void,
21
23
  failExecute: (msg: string) => void,
22
24
  ) => Promise<void>
25
+ /** Run TypeORM work in a managed transaction. */
23
26
  transaction: (fn: (tx: Transaction) => Promise<void>) => Promise<void>
27
+ /** Close the connection and report completion through callbacks. */
24
28
  close: (okClose: () => void, failClose: (e: unknown) => void) => void
29
+ /** Attach another database and invoke `callback` after it succeeds. */
25
30
  attach: (
26
31
  dbNameToAttach: string,
27
32
  alias: string,
28
33
  location: string | undefined,
29
34
  callback: () => void,
30
35
  ) => void
36
+ /** Detach an attached database and invoke `callback` after it succeeds. */
31
37
  detach: (alias: string, callback: () => void) => void
32
38
  }
33
39
 
34
- /**
35
- * DO NOT USE THIS! THIS IS MEANT FOR TYPEORM
36
- * If you are looking for a convenience wrapper use `connect`
40
+ /** Adapter for TypeORM's React Native driver. Application code should use `open()`.
41
+ * `openDatabase` reports success or failure through callbacks and returns the
42
+ * connection on success, or `null` when opening fails.
37
43
  */
38
44
  export const typeORMDriver = {
45
+ /** Open a database for TypeORM.
46
+ * @param options Database name and optional relative directory.
47
+ * @param ok Receives the adapter connection on success.
48
+ * @param fail Receives the opening error on failure.
49
+ */
39
50
  openDatabase: (
40
51
  options: {
41
52
  name: string