Skip to content

Commit ae7ac42

Browse files
authored
feat: Add null/undefined support (#109)
* feat: add null support in JS and update types * chore: update nitrogen specs * fix: rename null type * fix: missing nitrogen file * feat: add null support in cpp code * feat: add ENABLE_SIMPLE_NULL_HANDLING flag * chore: update nitro specs * fix: rename types * refactor: rename simple null handling functions * fix: check for null struct in buildQueryResult * test: add unit tests for passing and receiving null values * feat: improve NITRO_SQLITE_NULL handling
1 parent 9be1a8e commit ae7ac42

31 files changed

+291
-87
lines changed

example/src/tests/unitTests.spec.ts

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import Chance from 'chance'
2-
import type {
3-
NitroSQLiteConnection,
4-
BatchQueryCommand,
2+
import {
3+
type NitroSQLiteConnection,
4+
type BatchQueryCommand,
5+
NITRO_SQLITE_NULL,
6+
enableSimpleNullHandling,
57
} from 'react-native-nitro-sqlite'
68
import { beforeEach, describe, it } from './MochaRNAdapter'
79
import chai from 'chai'
@@ -19,6 +21,8 @@ export function registerUnitTests() {
1921
let testDb: NitroSQLiteConnection
2022

2123
beforeEach(() => {
24+
enableSimpleNullHandling(false)
25+
2226
try {
2327
resetTestDb()
2428

@@ -54,6 +58,62 @@ export function registerUnitTests() {
5458
expect(res.rows?.item).to.be.a('function')
5559
})
5660

61+
it('Insert with null', () => {
62+
const id = chance.integer()
63+
const name = chance.name()
64+
const age = NITRO_SQLITE_NULL
65+
const networth = NITRO_SQLITE_NULL
66+
const res = testDb.execute(
67+
'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
68+
[id, name, age, networth]
69+
)
70+
71+
expect(res.rowsAffected).to.equal(1)
72+
expect(res.insertId).to.equal(1)
73+
expect(res.rows?._array).to.eql([])
74+
expect(res.rows?.length).to.equal(0)
75+
expect(res.rows?.item).to.be.a('function')
76+
77+
const selectRes = testDb.execute('SELECT * FROM User')
78+
expect(selectRes.rows?._array).to.eql([
79+
{
80+
id,
81+
name,
82+
age,
83+
networth,
84+
},
85+
])
86+
})
87+
88+
it('Insert with null (simple null handling)', () => {
89+
enableSimpleNullHandling(true)
90+
91+
const id = chance.integer()
92+
const name = chance.name()
93+
const age = undefined
94+
const networth = null
95+
const res = testDb.execute(
96+
'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
97+
[id, name, age, networth]
98+
)
99+
100+
expect(res.rowsAffected).to.equal(1)
101+
expect(res.insertId).to.equal(1)
102+
expect(res.rows?._array).to.eql([])
103+
expect(res.rows?.length).to.equal(0)
104+
expect(res.rows?.item).to.be.a('function')
105+
106+
const selectRes = testDb.execute('SELECT * FROM User')
107+
expect(selectRes.rows?._array).to.eql([
108+
{
109+
id,
110+
name,
111+
age: null,
112+
networth: null,
113+
},
114+
])
115+
})
116+
57117
it('Query without params', () => {
58118
const id = chance.integer()
59119
const name = chance.name()

package/cpp/operations.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,12 @@ void bindStatement(sqlite3_stmt* statement, const SQLiteQueryParams& values) {
102102
for (int valueIndex = 0; valueIndex < values.size(); valueIndex++) {
103103
int sqliteIndex = valueIndex+1;
104104
SQLiteValue value = values.at(valueIndex);
105-
// if (std::holds_alternative<std::monostate>(value))
106-
// {
107-
// sqlite3_bind_null(statement, sqliteIndex);
108-
// }
109-
if (std::holds_alternative<bool>(value)) {
105+
if (std::holds_alternative<SQLiteNullValue>(value)) {
106+
sqlite3_bind_null(statement, sqliteIndex);
107+
} else if (std::holds_alternative<bool>(value)) {
110108
sqlite3_bind_int(statement, sqliteIndex, std::get<bool>(value));
111109
} else if (std::holds_alternative<double>(value)) {
112110
sqlite3_bind_double(statement, sqliteIndex, std::get<double>(value));
113-
} else if (std::holds_alternative<int64_t>(value)) {
114-
sqlite3_bind_int64(statement, sqliteIndex, std::get<int64_t>(value));
115111
} else if (std::holds_alternative<std::string>(value)) {
116112
const auto stringValue = std::get<std::string>(value);
117113
sqlite3_bind_text(statement, sqliteIndex, stringValue.c_str(), stringValue.length(), SQLITE_TRANSIENT);
@@ -191,7 +187,7 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str
191187
case SQLITE_NULL:
192188
// Intentionally left blank to switch to default case
193189
default:
194-
// row[column_name] = std::monostate();
190+
row[column_name] = SQLiteNullValue(true);
195191
break;
196192
}
197193
i++;

package/cpp/types.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#pragma once
22

3+
#include <string>
4+
#include <NitroModules/ArrayBuffer.hpp>
35
#include "SQLiteQueryColumnMetadata.hpp"
46
#include "ColumnType.hpp"
5-
#include <NitroModules/ArrayBuffer.hpp>
6-
#include <string>
7+
#include "SQLiteNullValue.hpp"
78

89
using namespace margelo::nitro;
910
using namespace margelo::nitro::rnnitrosqlite;
1011

1112
namespace margelo::rnnitrosqlite {
1213

13-
// using SQLiteValue = std::variant<std::string, double, int64_t, bool, std::shared_ptr<ArrayBuffer>, std::monostate>;
14-
using SQLiteValue = std::variant<std::string, double, int64_t, bool, std::shared_ptr<ArrayBuffer>>;
14+
using SQLiteValue = std::variant<std::string, double, bool, std::shared_ptr<ArrayBuffer>, SQLiteNullValue>;
1515
using SQLiteQueryParams = std::vector<SQLiteValue>;
1616
using SQLiteQueryResultRow = std::unordered_map<std::string, SQLiteValue>;
1717
using SQLiteQueryResults = std::vector<SQLiteQueryResultRow>;

package/nitrogen/generated/android/RNNitroSQLite+autolinking.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RNNitroSQLite+autolinking.cmake
33
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
# https://github.com/mrousavy/nitro
5-
# Copyright © 2024 Marc Rousavy @ Margelo
5+
# Copyright © 2025 Marc Rousavy @ Margelo
66
#
77

88
# This is a CMake file that adds all files generated by Nitrogen

package/nitrogen/generated/android/RNNitroSQLite+autolinking.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// RNNitroSQLite+autolinking.gradle
33
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
/// https://github.com/mrousavy/nitro
5-
/// Copyright © 2024 Marc Rousavy @ Margelo
5+
/// Copyright © 2025 Marc Rousavy @ Margelo
66
///
77

88
/// This is a Gradle file that adds all files generated by Nitrogen

package/nitrogen/generated/android/RNNitroSQLiteOnLoad.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// RNNitroSQLiteOnLoad.cpp
33
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
/// https://github.com/mrousavy/nitro
5-
/// Copyright © 2024 Marc Rousavy @ Margelo
5+
/// Copyright © 2025 Marc Rousavy @ Margelo
66
///
77

88
#include "RNNitroSQLiteOnLoad.hpp"

package/nitrogen/generated/android/RNNitroSQLiteOnLoad.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// RNNitroSQLiteOnLoad.hpp
33
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
/// https://github.com/mrousavy/nitro
5-
/// Copyright © 2024 Marc Rousavy @ Margelo
5+
/// Copyright © 2025 Marc Rousavy @ Margelo
66
///
77

88
#include <jni.h>

package/nitrogen/generated/ios/RNNitroSQLite+autolinking.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RNNitroSQLite+autolinking.rb
33
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
# https://github.com/mrousavy/nitro
5-
# Copyright © 2024 Marc Rousavy @ Margelo
5+
# Copyright © 2025 Marc Rousavy @ Margelo
66
#
77

88
# This is a Ruby script that adds all files generated by Nitrogen

package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// RNNitroSQLite-Swift-Cxx-Bridge.cpp
33
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
/// https://github.com/mrousavy/nitro
5-
/// Copyright © 2024 Marc Rousavy @ Margelo
5+
/// Copyright © 2025 Marc Rousavy @ Margelo
66
///
77

88
#include "RNNitroSQLite-Swift-Cxx-Bridge.hpp"

package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// RNNitroSQLite-Swift-Cxx-Bridge.hpp
33
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
44
/// https://github.com/mrousavy/nitro
5-
/// Copyright © 2024 Marc Rousavy @ Margelo
5+
/// Copyright © 2025 Marc Rousavy @ Margelo
66
///
77

88
#pragma once

0 commit comments

Comments
 (0)