Skip to content

Commit eb5e9f7

Browse files
authored
Merge pull request #212 from duckdb/jray/prepare-destroy-sync
add destroySync to DuckDBPreparedStatement
2 parents d5893b7 + 957fb37 commit eb5e9f7

File tree

5 files changed

+43
-12
lines changed

5 files changed

+43
-12
lines changed

api/src/DuckDBPreparedStatement.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ export class DuckDBPreparedStatement {
4747
constructor(prepared_statement: duckdb.PreparedStatement) {
4848
this.prepared_statement = prepared_statement;
4949
}
50+
public destroySync() {
51+
return duckdb.destroy_prepare_sync(this.prepared_statement);
52+
}
5053
public get statementType(): StatementType {
5154
return duckdb.prepared_statement_type(this.prepared_statement);
5255
}

api/test/api.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ describe('api', () => {
398398
const connection = await instance.connect();
399399
const prepared1 = await connection.prepare('select 1');
400400
assert.isDefined(prepared1);
401+
prepared1.destroySync();
401402
connection.disconnectSync();
402403
try {
403404
await connection.prepare('select 2');

bindings/pkgs/@duckdb/node-bindings/duckdb.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ export function decimal_to_double(decimal: Decimal): number;
455455
export function prepare(connection: Connection, query: string): Promise<PreparedStatement>;
456456

457457
// DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement);
458-
// not exposed: destroyed in finalizer
458+
export function destroy_prepare_sync(prepared_statement: PreparedStatement): void;
459459

460460
// DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement);
461461
// not exposed: prepare rejects promise with error

bindings/src/duckdb_node_bindings.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,32 @@ static const napi_type_tag PreparedStatementTypeTag = {
544544
0xA8B03DAD16D34416, 0x9735A7E1F2A1240C
545545
};
546546

547-
void FinalizePreparedStatement(Napi::BasicEnv, duckdb_prepared_statement prepared_statement) {
548-
if (prepared_statement) {
549-
duckdb_destroy_prepare(&prepared_statement);
550-
prepared_statement = nullptr;
551-
}
547+
typedef struct {
548+
duckdb_prepared_statement prepared;
549+
} duckdb_prepared_statement_holder;
550+
551+
duckdb_prepared_statement_holder *CreatePreparedStatementHolder(duckdb_prepared_statement prepared) {
552+
auto prepared_statement_holder_ptr = reinterpret_cast<duckdb_prepared_statement_holder*>(duckdb_malloc(sizeof(duckdb_prepared_statement_holder)));
553+
prepared_statement_holder_ptr->prepared = prepared;
554+
return prepared_statement_holder_ptr;
552555
}
553556

554-
Napi::External<_duckdb_prepared_statement> CreateExternalForPreparedStatement(Napi::Env env, duckdb_prepared_statement prepared_statement) {
555-
return CreateExternal<_duckdb_prepared_statement>(env, PreparedStatementTypeTag, prepared_statement, FinalizePreparedStatement);
557+
void FinalizePreparedStatementHolder(Napi::BasicEnv, duckdb_prepared_statement_holder *prepared_statement_holder_ptr) {
558+
// duckdb_destroy_prepare is a no-op if already destroyed
559+
duckdb_destroy_prepare(&prepared_statement_holder_ptr->prepared);
560+
duckdb_free(prepared_statement_holder_ptr);
561+
}
562+
563+
Napi::External<duckdb_prepared_statement_holder> CreateExternalForPreparedStatement(Napi::Env env, duckdb_prepared_statement prepared_statement) {
564+
return CreateExternal<duckdb_prepared_statement_holder>(env, PreparedStatementTypeTag, CreatePreparedStatementHolder(prepared_statement), FinalizePreparedStatementHolder);
565+
}
566+
567+
duckdb_prepared_statement_holder *GetPreparedStatementHolderFromExternal(Napi::Env env, Napi::Value value) {
568+
return GetDataFromExternal<duckdb_prepared_statement_holder>(env, PreparedStatementTypeTag, value, "Invalid prepared statement argument");
556569
}
557570

558571
duckdb_prepared_statement GetPreparedStatementFromExternal(Napi::Env env, Napi::Value value) {
559-
return GetDataFromExternal<_duckdb_prepared_statement>(env, PreparedStatementTypeTag, value, "Invalid prepared statement argument");
572+
return GetPreparedStatementHolderFromExternal(env, value)->prepared;
560573
}
561574

562575
static const napi_type_tag ResultTypeTag = {
@@ -1232,6 +1245,7 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
12321245
InstanceMethod("decimal_to_double", &DuckDBNodeAddon::decimal_to_double),
12331246

12341247
InstanceMethod("prepare", &DuckDBNodeAddon::prepare),
1248+
InstanceMethod("destroy_prepare_sync", &DuckDBNodeAddon::destroy_prepare_sync),
12351249
InstanceMethod("nparams", &DuckDBNodeAddon::nparams),
12361250
InstanceMethod("parameter_name", &DuckDBNodeAddon::parameter_name),
12371251
InstanceMethod("param_type", &DuckDBNodeAddon::param_type),
@@ -1996,7 +2010,14 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
19962010
}
19972011

19982012
// DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement);
1999-
// not exposed: destroyed in finalizer
2013+
// function destroy_prepare_sync(prepared_statement: PreparedStatement): void
2014+
Napi::Value destroy_prepare_sync(const Napi::CallbackInfo& info) {
2015+
auto env = info.Env();
2016+
auto prepared_statement_holder_ptr = GetPreparedStatementHolderFromExternal(env, info[0]);
2017+
// duckdb_destroy_prepare is a no-op if already destroyed
2018+
duckdb_destroy_prepare(&prepared_statement_holder_ptr->prepared);
2019+
return env.Undefined();
2020+
}
20002021

20012022
// DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement);
20022023
// not exposed: prepare rejects promise with error
@@ -4391,7 +4412,7 @@ NODE_API_ADDON(DuckDBNodeAddon)
43914412
---
43924413
411 total functions
43934414
4394-
242 instance methods
4415+
243 instance methods
43954416
1 unimplemented logical type function
43964417
13 unimplemented scalar function functions
43974418
4 unimplemented scalar function set functions
@@ -4407,7 +4428,7 @@ NODE_API_ADDON(DuckDBNodeAddon)
44074428
6 unimplemented table description functions
44084429
8 unimplemented tasks functions
44094430
12 unimplemented cast function functions
4410-
24 functions not exposed
4431+
23 functions not exposed
44114432
+ 41 unimplemented deprecated functions (of 47)
44124433
---
44134434
411 functions accounted for

bindings/test/prepared_statements.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,4 +448,10 @@ suite('prepared statements', () => {
448448
}
449449
});
450450
});
451+
test('destroy_prepare_sync', async () => {
452+
await withConnection(async (connection) => {
453+
const prepared = await duckdb.prepare(connection, 'select 1');
454+
duckdb.destroy_prepare_sync(prepared);
455+
});
456+
});
451457
});

0 commit comments

Comments
 (0)