Skip to content

Commit 8de04df

Browse files
committed
feat: add null support in JS and update types
1 parent 9be1a8e commit 8de04df

File tree

8 files changed

+77
-35
lines changed

8 files changed

+77
-35
lines changed

package/src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import { HybridNitroSQLite } from './nitro'
33
import { open } from './operations/session'
44
import NitroSQLiteOnLoad from './specs/NativeNitroSQLiteOnLoad'
55
import { execute, executeAsync } from './operations/execute'
6-
7-
export * from './types'
6+
import { NativeSqliteNullValue } from './types'
7+
export type * from './types'
88
export { typeORMDriver } from './typeORM'
99

10+
export const NITRO_SQLITE_NULL: NativeSqliteNullValue = { isNull: true }
11+
1012
export const onInitialized = new Promise<void>((resolve) => {
1113
NitroSQLiteOnLoad.onReactApplicationContextReady(resolve)
1214
})

package/src/operations/execute.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,67 @@
1+
import { NITRO_SQLITE_NULL } from '..'
12
import { HybridNitroSQLite } from '../nitro'
23
import type { NativeQueryResult } from '../specs/NativeQueryResult.nitro'
3-
import type { QueryResult, SQLiteItem, SQLiteQueryParams } from '../types'
4+
import type {
5+
QueryResult,
6+
NativeSQLiteQueryParams,
7+
SQLiteQueryParams,
8+
QueryResultRow,
9+
} from '../types'
410

5-
export function execute<Data extends SQLiteItem = never>(
11+
export function execute<Data extends QueryResultRow = never>(
612
dbName: string,
713
query: string,
814
params?: SQLiteQueryParams
915
): QueryResult<Data> {
10-
const nativeResult = HybridNitroSQLite.execute(dbName, query, params)
16+
const nativeResult = HybridNitroSQLite.execute(
17+
dbName,
18+
query,
19+
toNativeQueryParams(params)
20+
)
1121
const result = buildJsQueryResult<Data>(nativeResult)
1222
return result
1323
}
1424

15-
export async function executeAsync<Data extends SQLiteItem = never>(
25+
export async function executeAsync<Data extends QueryResultRow = never>(
1626
dbName: string,
1727
query: string,
1828
params?: SQLiteQueryParams
1929
): Promise<QueryResult<Data>> {
2030
const nativeResult = await HybridNitroSQLite.executeAsync(
2131
dbName,
2232
query,
23-
params
33+
toNativeQueryParams(params)
2434
)
2535
const result = buildJsQueryResult<Data>(nativeResult)
2636
return result
2737
}
2838

29-
function buildJsQueryResult<Data extends SQLiteItem = never>({
39+
function toNativeQueryParams(
40+
params: SQLiteQueryParams | undefined
41+
): NativeSQLiteQueryParams | undefined {
42+
return params?.map((param) => {
43+
if (param === undefined || param === null) {
44+
return NITRO_SQLITE_NULL
45+
}
46+
return param
47+
})
48+
}
49+
50+
function buildJsQueryResult<Data extends QueryResultRow = never>({
3051
insertId,
3152
rowsAffected,
3253
results,
3354
}: NativeQueryResult): QueryResult<Data> {
34-
const data = results as Data[]
55+
const data = results.map((row) =>
56+
Object.fromEntries(
57+
Object.entries(row).map(([key, value]) => {
58+
if (value === NITRO_SQLITE_NULL) {
59+
return [key, undefined]
60+
}
61+
return [key, value]
62+
})
63+
)
64+
) as Data[]
3565

3666
return {
3767
insertId,

package/src/operations/session.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import type {
55
NitroSQLiteConnection,
66
NitroSQLiteConnectionOptions,
77
QueryResult,
8-
SQLiteItem,
9-
SQLiteQueryParams,
108
Transaction,
9+
SQLiteQueryParams,
10+
QueryResultRow,
1111
} from '../types'
1212
import { execute, executeAsync } from './execute'
1313

@@ -24,11 +24,11 @@ export function open(
2424
detach: (alias: string) => HybridNitroSQLite.detach(options.name, alias),
2525
transaction: (fn: (tx: Transaction) => Promise<void> | void) =>
2626
transaction(options.name, fn),
27-
execute: <Data extends SQLiteItem = never>(
27+
execute: <Data extends QueryResultRow = never>(
2828
query: string,
2929
params?: SQLiteQueryParams
3030
): QueryResult<Data> => execute(options.name, query, params),
31-
executeAsync: <Data extends SQLiteItem = never>(
31+
executeAsync: <Data extends QueryResultRow = never>(
3232
query: string,
3333
params?: SQLiteQueryParams
3434
): Promise<QueryResult<Data>> => executeAsync(options.name, query, params),

package/src/operations/transaction.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { locks, HybridNitroSQLite } from '../nitro'
22
import type {
33
QueryResult,
4-
SQLiteItem,
5-
SQLiteQueryParams,
64
Transaction,
5+
SQLiteQueryParams,
6+
QueryResultRow,
77
} from '../types'
88
import { execute, executeAsync } from './execute'
99

@@ -30,7 +30,7 @@ export const transaction = (
3030
let isFinalized = false
3131

3232
// Local transaction context object implementation
33-
const executeOnTransaction = <Data extends SQLiteItem = never>(
33+
const executeOnTransaction = <Data extends QueryResultRow = never>(
3434
query: string,
3535
params?: SQLiteQueryParams
3636
): QueryResult<Data> => {
@@ -42,7 +42,7 @@ export const transaction = (
4242
return execute(dbName, query, params)
4343
}
4444

45-
const executeAsyncOnTransaction = <Data extends SQLiteItem = never>(
45+
const executeAsyncOnTransaction = <Data extends QueryResultRow = never>(
4646
query: string,
4747
params?: SQLiteQueryParams
4848
): Promise<QueryResult<Data>> => {

package/src/specs/NativeQueryResult.nitro.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { HybridObject } from 'react-native-nitro-modules'
2-
import type { ColumnType, SQLiteValue } from '../types'
2+
import type { ColumnType, NativeSQLiteValue } from '../types'
33

44
/**
55
* Object returned by SQL Query executions {
@@ -17,7 +17,7 @@ export interface NativeQueryResult
1717
readonly insertId?: number
1818

1919
/** Query results */
20-
readonly results: SQLiteQueryResults
20+
readonly results: NativeSQLiteQueryResults
2121
/** Table metadata */
2222
readonly metadata?: Record<string, SQLiteQueryColumnMetadata>
2323
}
@@ -30,7 +30,7 @@ export interface NativeQueryResult
3030
// TODO: Investigate why this doesn't work with nitrogen
3131
// export type SQLiteQueryResultRow = Record<string, SQLiteValue>
3232
// export type SQLiteQueryResults = SQLiteQueryResultRow[]
33-
export type SQLiteQueryResults = Record<string, SQLiteValue>[]
33+
export type NativeSQLiteQueryResults = Record<string, NativeSQLiteValue>[]
3434

3535
// TODO: Investigate why this doesn't work with nitrogen
3636
// export type SQLiteQueryTableMetadata = Record<string, SQLiteQueryColumnMetadata>

package/src/specs/NitroSQLite.nitro.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
BatchQueryResult,
44
FileLoadResult,
55
BatchQueryCommand,
6-
SQLiteQueryParams,
6+
NativeSQLiteQueryParams,
77
} from '../types'
88
import type { NativeQueryResult } from './NativeQueryResult.nitro'
99

@@ -22,12 +22,12 @@ export interface NitroSQLite
2222
execute(
2323
dbName: string,
2424
query: string,
25-
params?: SQLiteQueryParams
25+
params?: NativeSQLiteQueryParams
2626
): NativeQueryResult
2727
executeAsync(
2828
dbName: string,
2929
query: string,
30-
params?: SQLiteQueryParams
30+
params?: NativeSQLiteQueryParams
3131
): Promise<NativeQueryResult>
3232
executeBatch(dbName: string, commands: BatchQueryCommand[]): BatchQueryResult
3333
executeBatchAsync(

package/src/typeORM.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
import type {
99
QueryResult,
10-
SQLiteItem,
11-
SQLiteQueryParams,
1210
Transaction,
11+
SQLiteQueryParams,
12+
QueryResultRow,
1313
} from './types'
1414
import * as Operations from './operations/session'
1515

1616
interface TypeOrmNitroSQLiteConnection {
17-
executeSql: <RowData extends SQLiteItem = never>(
17+
executeSql: <RowData extends QueryResultRow = never>(
1818
sql: string,
1919
params: SQLiteQueryParams | undefined,
2020
okExecute: (res: QueryResult<RowData>) => void,
@@ -48,7 +48,7 @@ export const typeORMDriver = {
4848
const db = Operations.open(options)
4949

5050
const connection: TypeOrmNitroSQLiteConnection = {
51-
executeSql: async <RowData extends SQLiteItem = never>(
51+
executeSql: async <RowData extends QueryResultRow = never>(
5252
sql: string,
5353
params: SQLiteQueryParams | undefined,
5454
okExecute: (res: QueryResult<RowData>) => void,

package/src/types.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,24 @@ export enum ColumnType {
2626
NULL_VALUE,
2727
}
2828

29+
export type BaseSQLiteValue = boolean | number | string | ArrayBuffer
30+
31+
// Passing null/undefined in array types is not possible, so we us a special struct as a workaround.
32+
export type NativeSqliteNullValue = {
33+
isNull: true
34+
}
35+
export type NativeSQLiteValue = BaseSQLiteValue | NativeSqliteNullValue
36+
export type NativeSQLiteQueryParams = NativeSQLiteValue[]
37+
2938
/**
3039
* Represents a value that can be stored in a SQLite database
3140
*/
32-
export type SQLiteValue = boolean | number | string | ArrayBuffer | undefined
33-
34-
export type SQLiteItem = Record<string, SQLiteValue>
41+
export type SQLiteValue = BaseSQLiteValue | null | undefined
42+
export type SQLiteQueryParams = SQLiteValue[]
3543

36-
export interface QueryResult<RowData extends SQLiteItem = SQLiteItem> {
44+
export type QueryResultItem = BaseSQLiteValue | undefined
45+
export type QueryResultRow = Record<string, QueryResultItem>
46+
export interface QueryResult<RowData extends QueryResultRow = QueryResultRow> {
3747
readonly insertId?: number
3848
readonly rowsAffected: number
3949

@@ -50,14 +60,14 @@ export interface QueryResult<RowData extends SQLiteItem = SQLiteItem> {
5060
}
5161
}
5262

53-
export type SQLiteQueryParams = SQLiteValue[]
54-
55-
export type ExecuteQuery = <RowData extends SQLiteItem = SQLiteItem>(
63+
export type ExecuteQuery = <RowData extends QueryResultRow = QueryResultRow>(
5664
query: string,
5765
params?: SQLiteQueryParams
5866
) => QueryResult<RowData>
5967

60-
export type ExecuteAsyncQuery = <RowData extends SQLiteItem = SQLiteItem>(
68+
export type ExecuteAsyncQuery = <
69+
RowData extends QueryResultRow = QueryResultRow,
70+
>(
6171
query: string,
6272
params?: SQLiteQueryParams
6373
) => Promise<QueryResult<RowData>>

0 commit comments

Comments
 (0)