Skip to content

Commit 27121c0

Browse files
committed
Implement Statement.safeIntegers()
1 parent be3d9f5 commit 27121c0

File tree

5 files changed

+81
-11
lines changed

5 files changed

+81
-11
lines changed

index.js

+9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const {
2121
statementRun,
2222
statementRowsSync,
2323
statementColumns,
24+
statementSafeIntegers,
2425
rowsNext,
2526
} = load(__dirname) || require(`@libsql/experimental-${currentTarget()}`);
2627

@@ -278,6 +279,14 @@ class Statement {
278279
columns() {
279280
return statementColumns.call(this.stmt);
280281
}
282+
283+
/**
284+
* Toggle 64-bit integer support.
285+
*/
286+
safeIntegers(toggle) {
287+
statementSafeIntegers.call(this.stmt, toggle || true);
288+
return this;
289+
}
281290
}
282291

283292
module.exports = Database;

integration-tests/tests/async.test.js

+22
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,28 @@ test.serial("Statement.all() [raw]", async (t) => {
111111
t.deepEqual(await stmt.raw().all(), expected);
112112
});
113113

114+
test.serial("Statement.all() [default safe integers]", async (t) => {
115+
const db = t.context.db;
116+
db.defaultSafeIntegers();
117+
const stmt = await db.prepare("SELECT * FROM users");
118+
const expected = [
119+
[1n, "Alice", "alice@example.org"],
120+
[2n, "Bob", "bob@example.com"],
121+
];
122+
t.deepEqual(await stmt.raw().all(), expected);
123+
});
124+
125+
test.serial("Statement.all() [statement safe integers]", async (t) => {
126+
const db = t.context.db;
127+
const stmt = await db.prepare("SELECT * FROM users");
128+
stmt.safeIntegers();
129+
const expected = [
130+
[1n, "Alice", "alice@example.org"],
131+
[2n, "Bob", "bob@example.com"],
132+
];
133+
t.deepEqual(await stmt.raw().all(), expected);
134+
});
135+
114136
test.serial("Statement.columns()", async (t) => {
115137
const db = t.context.db;
116138

integration-tests/tests/sync.test.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ test.serial("Statement.all() [raw]", async (t) => {
110110
t.deepEqual(stmt.raw().all(), expected);
111111
});
112112

113-
test.serial("Statement.all() [64-bit integers]", async (t) => {
113+
test.serial("Statement.all() [default safe integers]", async (t) => {
114114
const db = t.context.db;
115115
db.defaultSafeIntegers();
116116
const stmt = db.prepare("SELECT * FROM users");
@@ -121,6 +121,17 @@ test.serial("Statement.all() [64-bit integers]", async (t) => {
121121
t.deepEqual(stmt.raw().all(), expected);
122122
});
123123

124+
test.serial("Statement.all() [statement safe integers]", async (t) => {
125+
const db = t.context.db;
126+
const stmt = db.prepare("SELECT * FROM users");
127+
stmt.safeIntegers();
128+
const expected = [
129+
[1n, "Alice", "alice@example.org"],
130+
[2n, "Bob", "bob@example.com"],
131+
];
132+
t.deepEqual(stmt.raw().all(), expected);
133+
});
134+
124135
test.serial("Statement.columns()", async (t) => {
125136
const db = t.context.db;
126137

promise.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ const {
1515
databaseSync,
1616
databaseExecAsync,
1717
databasePrepareAsync,
18+
databaseDefaultSafeIntegers,
1819
statementRaw,
1920
statementGet,
2021
statementRun,
2122
statementRowsAsync,
2223
statementColumns,
24+
statementSafeIntegers,
2325
rowsNext,
2426
} = load(__dirname) || require(`@libsql/experimental-${currentTarget()}`);
2527

@@ -182,8 +184,12 @@ class Database {
182184
databaseClose.call(this.db);
183185
}
184186

185-
defaultSafeIntegers(...args) {
186-
throw new Error("not implemented");
187+
/**
188+
* Toggle 64-bit integer support.
189+
*/
190+
defaultSafeIntegers(toggle) {
191+
databaseDefaultSafeIntegers.call(this.db, toggle || true);
192+
return this;
187193
}
188194

189195
unsafeMode(...args) {
@@ -275,6 +281,15 @@ class Statement {
275281
columns() {
276282
return statementColumns.call(this.stmt);
277283
}
284+
285+
/**
286+
* Toggle 64-bit integer support.
287+
*/
288+
safeIntegers(toggle) {
289+
statementSafeIntegers.call(this.stmt, toggle || true);
290+
return this;
291+
}
292+
278293
}
279294

280295
module.exports = Database;

src/lib.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl Database {
124124
conn: db.conn.clone(),
125125
stmt: Arc::new(stmt),
126126
raw: RefCell::new(false),
127-
safe_ints: *db.default_safe_integers.borrow(),
127+
safe_ints: RefCell::new(*db.default_safe_integers.borrow()),
128128
rt: db.rt.handle().clone(),
129129
};
130130
Ok(cx.boxed(stmt))
@@ -146,7 +146,7 @@ impl Database {
146146
conn: conn.clone(),
147147
stmt: Arc::new(stmt),
148148
raw: RefCell::new(false),
149-
safe_ints,
149+
safe_ints: RefCell::new(safe_ints),
150150
rt: rt,
151151
};
152152
deferred.settle_with(&channel, |mut cx| Ok(cx.boxed(stmt)));
@@ -191,7 +191,7 @@ struct Statement {
191191
conn: Arc<libsql::v2::Connection>,
192192
stmt: Arc<libsql::v2::Statement>,
193193
raw: RefCell<bool>,
194-
safe_ints: bool,
194+
safe_ints: RefCell<bool>,
195195
rt: tokio::runtime::Handle,
196196
}
197197

@@ -259,7 +259,7 @@ impl Statement {
259259
let stmt: Handle<'_, JsBox<Statement>> = cx.this()?;
260260
let params = cx.argument::<JsValue>(0)?;
261261
let params = convert_params(&mut cx, params)?;
262-
262+
let safe_ints = *stmt.safe_ints.borrow();
263263
let fut = stmt.stmt.query(&params);
264264
let result = stmt.rt.block_on(fut);
265265
let mut rows = result.or_else(|err| cx.throw_error(from_libsql_error(err)))?;
@@ -270,11 +270,11 @@ impl Statement {
270270
Some(row) => {
271271
if *stmt.raw.borrow() {
272272
let mut result = cx.empty_array();
273-
convert_row_raw(&mut cx, stmt.safe_ints, &mut result, &rows, &row)?;
273+
convert_row_raw(&mut cx, safe_ints, &mut result, &rows, &row)?;
274274
Ok(result.upcast())
275275
} else {
276276
let mut result = cx.empty_object();
277-
convert_row(&mut cx, stmt.safe_ints, &mut result, &rows, &row)?;
277+
convert_row(&mut cx, safe_ints, &mut result, &rows, &row)?;
278278
Ok(result.upcast())
279279
}
280280
}
@@ -300,7 +300,7 @@ impl Statement {
300300
let rows = Rows {
301301
rows: RefCell::new(rows),
302302
raw: *stmt.raw.borrow(),
303-
safe_ints: stmt.safe_ints,
303+
safe_ints: *stmt.safe_ints.borrow(),
304304
};
305305
Ok(cx.boxed(rows).upcast())
306306
}
@@ -319,7 +319,7 @@ impl Statement {
319319
let channel = cx.channel();
320320
let rt = stmt.rt.clone();
321321
let raw = *stmt.raw.borrow();
322-
let safe_ints = stmt.safe_ints;
322+
let safe_ints = *stmt.safe_ints.borrow();
323323
let stmt = stmt.stmt.clone();
324324
rt.spawn(async move {
325325
let fut = stmt.query(&params);
@@ -364,6 +364,18 @@ impl Statement {
364364
}
365365
Ok(result.upcast())
366366
}
367+
368+
fn js_safe_integers(mut cx: FunctionContext) -> JsResult<JsNull> {
369+
let stmt: Handle<'_, JsBox<Statement>> = cx.this()?;
370+
let toggle = cx.argument::<JsBoolean>(0)?;
371+
let toggle = toggle.value(&mut cx);
372+
stmt.set_safe_integers(toggle);
373+
Ok(cx.null())
374+
}
375+
376+
fn set_safe_integers(&self, toggle: bool) {
377+
self.safe_ints.replace(toggle);
378+
}
367379
}
368380

369381
struct Rows {
@@ -518,6 +530,7 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
518530
cx.export_function("statementRowsSync", Statement::js_rows_sync)?;
519531
cx.export_function("statementRowsAsync", Statement::js_rows_async)?;
520532
cx.export_function("statementColumns", Statement::js_columns)?;
533+
cx.export_function("statementSafeIntegers", Statement::js_safe_integers)?;
521534
cx.export_function("rowsNext", Rows::js_next)?;
522535
Ok(())
523536
}

0 commit comments

Comments
 (0)