Skip to content

Commit 9bca95a

Browse files
committed
sqlite: add sqlite prepare options args
1 parent 842448b commit 9bca95a

File tree

4 files changed

+171
-167
lines changed

4 files changed

+171
-167
lines changed

src/node_sqlite.cc

Lines changed: 83 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,89 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
11551155
BaseObjectPtr<StatementSync> stmt =
11561156
StatementSync::Create(env, BaseObjectPtr<DatabaseSync>(db), s);
11571157
db->statements_.insert(stmt.get());
1158+
1159+
if (args.Length() > 1 && !args[1]->IsUndefined()) {
1160+
if (!args[1]->IsObject()) {
1161+
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
1162+
"The \"options\" argument must be an object.");
1163+
return;
1164+
}
1165+
Local<Object> options = args[1].As<Object>();
1166+
1167+
Local<Value> return_arrays_v;
1168+
if (!options
1169+
->Get(env->context(),
1170+
FIXED_ONE_BYTE_STRING(env->isolate(), "returnArrays"))
1171+
.ToLocal(&return_arrays_v)) {
1172+
return;
1173+
}
1174+
if (!return_arrays_v->IsUndefined()) {
1175+
if (!return_arrays_v->IsBoolean()) {
1176+
THROW_ERR_INVALID_ARG_TYPE(
1177+
env->isolate(),
1178+
"The \"options.returnArrays\" argument must be a boolean.");
1179+
return;
1180+
}
1181+
stmt->return_arrays_ = return_arrays_v->IsTrue();
1182+
}
1183+
1184+
Local<Value> read_big_ints_v;
1185+
if (!options
1186+
->Get(env->context(),
1187+
FIXED_ONE_BYTE_STRING(env->isolate(), "readBigInts"))
1188+
.ToLocal(&read_big_ints_v)) {
1189+
return;
1190+
}
1191+
if (!read_big_ints_v->IsUndefined()) {
1192+
if (!read_big_ints_v->IsBoolean()) {
1193+
THROW_ERR_INVALID_ARG_TYPE(
1194+
env->isolate(),
1195+
"The \"options.readBigInts\" argument must be a boolean.");
1196+
return;
1197+
}
1198+
stmt->use_big_ints_ = read_big_ints_v->IsTrue();
1199+
}
1200+
1201+
Local<Value> allow_bare_named_params_v;
1202+
if (!options
1203+
->Get(env->context(),
1204+
FIXED_ONE_BYTE_STRING(env->isolate(),
1205+
"allowBareNamedParameters"))
1206+
.ToLocal(&allow_bare_named_params_v)) {
1207+
return;
1208+
}
1209+
if (!allow_bare_named_params_v->IsUndefined()) {
1210+
if (!allow_bare_named_params_v->IsBoolean()) {
1211+
THROW_ERR_INVALID_ARG_TYPE(
1212+
env->isolate(),
1213+
"The \"options.allowBareNamedParameters\" argument must be a "
1214+
"boolean.");
1215+
return;
1216+
}
1217+
stmt->allow_bare_named_params_ = allow_bare_named_params_v->IsTrue();
1218+
}
1219+
1220+
Local<Value> allow_unknown_named_params_v;
1221+
if (!options
1222+
->Get(env->context(),
1223+
FIXED_ONE_BYTE_STRING(env->isolate(),
1224+
"allowUnknownNamedParameters"))
1225+
.ToLocal(&allow_unknown_named_params_v)) {
1226+
return;
1227+
}
1228+
if (!allow_unknown_named_params_v->IsUndefined()) {
1229+
if (!allow_unknown_named_params_v->IsBoolean()) {
1230+
THROW_ERR_INVALID_ARG_TYPE(
1231+
env->isolate(),
1232+
"The \"options.allowUnknownNamedParameters\" argument must be a "
1233+
"boolean.");
1234+
return;
1235+
}
1236+
stmt->allow_unknown_named_params_ =
1237+
allow_unknown_named_params_v->IsTrue();
1238+
}
1239+
}
1240+
11581241
args.GetReturnValue().Set(stmt->object());
11591242
}
11601243

@@ -2587,73 +2670,6 @@ void StatementSync::ExpandedSQLGetter(const FunctionCallbackInfo<Value>& args) {
25872670
args.GetReturnValue().Set(result);
25882671
}
25892672

2590-
void StatementSync::SetAllowBareNamedParameters(
2591-
const FunctionCallbackInfo<Value>& args) {
2592-
StatementSync* stmt;
2593-
ASSIGN_OR_RETURN_UNWRAP(&stmt, args.This());
2594-
Environment* env = Environment::GetCurrent(args);
2595-
THROW_AND_RETURN_ON_BAD_STATE(
2596-
env, stmt->IsFinalized(), "statement has been finalized");
2597-
2598-
if (!args[0]->IsBoolean()) {
2599-
THROW_ERR_INVALID_ARG_TYPE(
2600-
env->isolate(),
2601-
"The \"allowBareNamedParameters\" argument must be a boolean.");
2602-
return;
2603-
}
2604-
2605-
stmt->allow_bare_named_params_ = args[0]->IsTrue();
2606-
}
2607-
2608-
void StatementSync::SetAllowUnknownNamedParameters(
2609-
const FunctionCallbackInfo<Value>& args) {
2610-
StatementSync* stmt;
2611-
ASSIGN_OR_RETURN_UNWRAP(&stmt, args.This());
2612-
Environment* env = Environment::GetCurrent(args);
2613-
THROW_AND_RETURN_ON_BAD_STATE(
2614-
env, stmt->IsFinalized(), "statement has been finalized");
2615-
2616-
if (!args[0]->IsBoolean()) {
2617-
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
2618-
"The \"enabled\" argument must be a boolean.");
2619-
return;
2620-
}
2621-
2622-
stmt->allow_unknown_named_params_ = args[0]->IsTrue();
2623-
}
2624-
2625-
void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
2626-
StatementSync* stmt;
2627-
ASSIGN_OR_RETURN_UNWRAP(&stmt, args.This());
2628-
Environment* env = Environment::GetCurrent(args);
2629-
THROW_AND_RETURN_ON_BAD_STATE(
2630-
env, stmt->IsFinalized(), "statement has been finalized");
2631-
2632-
if (!args[0]->IsBoolean()) {
2633-
THROW_ERR_INVALID_ARG_TYPE(
2634-
env->isolate(), "The \"readBigInts\" argument must be a boolean.");
2635-
return;
2636-
}
2637-
2638-
stmt->use_big_ints_ = args[0]->IsTrue();
2639-
}
2640-
2641-
void StatementSync::SetReturnArrays(const FunctionCallbackInfo<Value>& args) {
2642-
StatementSync* stmt;
2643-
ASSIGN_OR_RETURN_UNWRAP(&stmt, args.This());
2644-
Environment* env = Environment::GetCurrent(args);
2645-
THROW_AND_RETURN_ON_BAD_STATE(
2646-
env, stmt->IsFinalized(), "statement has been finalized");
2647-
2648-
if (!args[0]->IsBoolean()) {
2649-
THROW_ERR_INVALID_ARG_TYPE(
2650-
env->isolate(), "The \"returnArrays\" argument must be a boolean.");
2651-
return;
2652-
}
2653-
2654-
stmt->return_arrays_ = args[0]->IsTrue();
2655-
}
2656-
26572673
void IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
26582674
THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
26592675
}
@@ -3002,18 +3018,6 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
30023018
tmpl,
30033019
FIXED_ONE_BYTE_STRING(isolate, "expandedSQL"),
30043020
StatementSync::ExpandedSQLGetter);
3005-
SetProtoMethod(isolate,
3006-
tmpl,
3007-
"setAllowBareNamedParameters",
3008-
StatementSync::SetAllowBareNamedParameters);
3009-
SetProtoMethod(isolate,
3010-
tmpl,
3011-
"setAllowUnknownNamedParameters",
3012-
StatementSync::SetAllowUnknownNamedParameters);
3013-
SetProtoMethod(
3014-
isolate, tmpl, "setReadBigInts", StatementSync::SetReadBigInts);
3015-
SetProtoMethod(
3016-
isolate, tmpl, "setReturnArrays", StatementSync::SetReturnArrays);
30173021
env->set_sqlite_statement_sync_constructor_template(tmpl);
30183022
}
30193023
return tmpl;

src/node_sqlite.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,6 @@ class StatementSync : public BaseObject {
220220
static void SourceSQLGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
221221
static void ExpandedSQLGetter(
222222
const v8::FunctionCallbackInfo<v8::Value>& args);
223-
static void SetAllowBareNamedParameters(
224-
const v8::FunctionCallbackInfo<v8::Value>& args);
225-
static void SetAllowUnknownNamedParameters(
226-
const v8::FunctionCallbackInfo<v8::Value>& args);
227-
static void SetReadBigInts(const v8::FunctionCallbackInfo<v8::Value>& args);
228-
static void SetReturnArrays(const v8::FunctionCallbackInfo<v8::Value>& args);
229223
v8::MaybeLocal<v8::Value> ColumnToValue(const int column);
230224
v8::MaybeLocal<v8::Name> ColumnNameToName(const int column);
231225
void Finalize();
@@ -246,6 +240,7 @@ class StatementSync : public BaseObject {
246240
bool BindParams(const v8::FunctionCallbackInfo<v8::Value>& args);
247241
bool BindValue(const v8::Local<v8::Value>& value, const int index);
248242

243+
friend class DatabaseSync;
249244
friend class StatementSyncIterator;
250245
friend class SQLTagStore;
251246
friend class StatementExecutionHelper;

test/parallel/test-sqlite-named-parameters.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,33 @@ suite('named parameters', () => {
7979
});
8080
});
8181

82-
suite('StatementSync.prototype.setAllowUnknownNamedParameters()', () => {
83-
test('unknown named parameter support can be toggled', (t) => {
82+
suite('allowUnknownNamedParameters', () => {
83+
test('unknown named parameters can be allowed', (t) => {
8484
const db = new DatabaseSync(':memory:');
8585
t.after(() => { db.close(); });
8686
const setup = db.exec(
8787
'CREATE TABLE data(key INTEGER, val INTEGER) STRICT;'
8888
);
8989
t.assert.strictEqual(setup, undefined);
90-
const stmt = db.prepare('INSERT INTO data (key, val) VALUES ($k, $v)');
91-
t.assert.strictEqual(stmt.setAllowUnknownNamedParameters(true), undefined);
90+
const stmt = db.prepare('INSERT INTO data (key, val) VALUES ($k, $v)', {
91+
allowUnknownNamedParameters: true,
92+
});
9293
const params = { $a: 1, $b: 2, $k: 42, $y: 25, $v: 84, $z: 99 };
9394
t.assert.deepStrictEqual(
9495
stmt.run(params),
9596
{ changes: 1, lastInsertRowid: 1 },
9697
);
97-
t.assert.strictEqual(stmt.setAllowUnknownNamedParameters(false), undefined);
98+
});
99+
100+
test('unknown named parameters are rejected by default', (t) => {
101+
const db = new DatabaseSync(':memory:');
102+
t.after(() => { db.close(); });
103+
const setup = db.exec(
104+
'CREATE TABLE data(key INTEGER, val INTEGER) STRICT;'
105+
);
106+
t.assert.strictEqual(setup, undefined);
107+
const stmt = db.prepare('INSERT INTO data (key, val) VALUES ($k, $v)');
108+
const params = { $a: 1, $b: 2, $k: 42, $y: 25, $v: 84, $z: 99 };
98109
t.assert.throws(() => {
99110
stmt.run(params);
100111
}, {
@@ -110,12 +121,13 @@ suite('StatementSync.prototype.setAllowUnknownNamedParameters()', () => {
110121
'CREATE TABLE data(key INTEGER PRIMARY KEY, val INTEGER) STRICT;'
111122
);
112123
t.assert.strictEqual(setup, undefined);
113-
const stmt = db.prepare('INSERT INTO data (key, val) VALUES ($k, $v)');
114124
t.assert.throws(() => {
115-
stmt.setAllowUnknownNamedParameters();
125+
db.prepare('INSERT INTO data (key, val) VALUES ($k, $v)', {
126+
allowUnknownNamedParameters: 'true',
127+
});
116128
}, {
117129
code: 'ERR_INVALID_ARG_TYPE',
118-
message: /The "enabled" argument must be a boolean/,
130+
message: /The "options\.allowUnknownNamedParameters" argument must be a boolean/,
119131
});
120132
});
121133
});

0 commit comments

Comments
 (0)