Skip to content

Commit ebf0608

Browse files
committed
refactor: implement sqlite3_stmt raii
1 parent b3c4d4b commit ebf0608

2 files changed

Lines changed: 64 additions & 57 deletions

File tree

src/node_sqlite.cc

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,12 +1573,12 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
15731573
Utf8Value sql(env->isolate(), args[0].As<String>());
15741574
sqlite3_stmt* s = nullptr;
15751575
int r = sqlite3_prepare_v2(db->connection_, *sql, -1, &s, nullptr);
1576+
StatementPtr stmt_ptr(s);
15761577

15771578
CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void());
1578-
BaseObjectPtr<StatementSync> stmt =
1579-
StatementSync::Create(env, BaseObjectPtr<DatabaseSync>(db), s);
1579+
BaseObjectPtr<StatementSync> stmt = StatementSync::Create(
1580+
env, BaseObjectPtr<DatabaseSync>(db), std::move(stmt_ptr));
15801581
if (!stmt) {
1581-
sqlite3_finalize(s);
15821582
return;
15831583
}
15841584
db->statements_.insert(stmt.get());
@@ -2632,10 +2632,9 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
26322632
StatementSync::StatementSync(Environment* env,
26332633
Local<Object> object,
26342634
BaseObjectPtr<DatabaseSync> db,
2635-
sqlite3_stmt* stmt)
2636-
: BaseObject(env, object), db_(std::move(db)) {
2635+
StatementPtr stmt)
2636+
: BaseObject(env, object), db_(std::move(db)), statement_(std::move(stmt)) {
26372637
MakeWeak();
2638-
statement_ = stmt;
26392638
use_big_ints_ = db_->use_big_ints();
26402639
return_arrays_ = db_->return_arrays();
26412640
allow_bare_named_params_ = db_->allow_bare_named_params();
@@ -2656,8 +2655,7 @@ void StatementSync::Close() {
26562655
}
26572656

26582657
void StatementSync::Finalize() {
2659-
sqlite3_finalize(statement_);
2660-
statement_ = nullptr;
2658+
statement_.reset();
26612659
InvalidateColumnNameCache();
26622660
}
26632661

@@ -2686,11 +2684,11 @@ void StatementSync::Dispose(const FunctionCallbackInfo<Value>& args) {
26862684

26872685
inline int StatementSync::ResetStatement() {
26882686
reset_generation_++;
2689-
return sqlite3_reset(statement_);
2687+
return sqlite3_reset(statement_.get());
26902688
}
26912689

26922690
bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
2693-
int r = sqlite3_clear_bindings(statement_);
2691+
int r = sqlite3_clear_bindings(statement_.get());
26942692
CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false);
26952693

26962694
int anon_idx = 1;
@@ -2707,10 +2705,10 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
27072705

27082706
if (allow_bare_named_params_ && !bare_named_params_.has_value()) {
27092707
bare_named_params_.emplace();
2710-
int param_count = sqlite3_bind_parameter_count(statement_);
2708+
int param_count = sqlite3_bind_parameter_count(statement_.get());
27112709
// Parameter indexing starts at one.
27122710
for (int i = 1; i <= param_count; ++i) {
2713-
const char* name = sqlite3_bind_parameter_name(statement_, i);
2711+
const char* name = sqlite3_bind_parameter_name(statement_.get(), i);
27142712
if (name == nullptr) {
27152713
continue;
27162714
}
@@ -2742,12 +2740,12 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
27422740
}
27432741

27442742
Utf8Value utf8_key(env()->isolate(), key);
2745-
int r = sqlite3_bind_parameter_index(statement_, *utf8_key);
2743+
int r = sqlite3_bind_parameter_index(statement_.get(), *utf8_key);
27462744
if (r == 0) {
27472745
if (allow_bare_named_params_) {
27482746
auto lookup = bare_named_params_->find(std::string(*utf8_key));
27492747
if (lookup != bare_named_params_->end()) {
2750-
r = sqlite3_bind_parameter_index(statement_,
2748+
r = sqlite3_bind_parameter_index(statement_.get(),
27512749
lookup->second.c_str());
27522750
}
27532751
}
@@ -2777,7 +2775,8 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
27772775

27782776
for (int i = anon_start; i < args.Length(); ++i) {
27792777
while (1) {
2780-
const char* param = sqlite3_bind_parameter_name(statement_, anon_idx);
2778+
const char* param =
2779+
sqlite3_bind_parameter_name(statement_.get(), anon_idx);
27812780
if (param == nullptr || param[0] == '?') break;
27822781
anon_idx++;
27832782
}
@@ -2803,7 +2802,7 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
28032802
int r;
28042803
if (value->IsNumber()) {
28052804
const double val = value.As<Number>()->Value();
2806-
r = sqlite3_bind_double(statement_, index, val);
2805+
r = sqlite3_bind_double(statement_.get(), index, val);
28072806
} else if (value->IsString()) {
28082807
Utf8Value val(isolate, value.As<String>());
28092808
if (val.IsAllocated()) {
@@ -2813,35 +2812,35 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
28132812
const sqlite3_uint64 length = static_cast<sqlite3_uint64>(val.length());
28142813
val.Release();
28152814
r = sqlite3_bind_text64(
2816-
statement_, index, data, length, std::free, SQLITE_UTF8);
2815+
statement_.get(), index, data, length, std::free, SQLITE_UTF8);
28172816
} else {
2818-
r = sqlite3_bind_text64(statement_,
2817+
r = sqlite3_bind_text64(statement_.get(),
28192818
index,
28202819
*val,
28212820
static_cast<sqlite3_uint64>(val.length()),
28222821
SQLITE_TRANSIENT,
28232822
SQLITE_UTF8);
28242823
}
28252824
} else if (value->IsNull()) {
2826-
r = sqlite3_bind_null(statement_, index);
2825+
r = sqlite3_bind_null(statement_.get(), index);
28272826
} else if (value->IsArrayBufferView() || value->IsArrayBuffer() ||
28282827
value->IsSharedArrayBuffer()) {
28292828
ArrayBufferViewContents<uint8_t> buf(value);
2830-
r = sqlite3_bind_blob64(statement_,
2829+
r = sqlite3_bind_blob64(statement_.get(),
28312830
index,
28322831
buf.data(),
28332832
static_cast<sqlite3_uint64>(buf.length()),
28342833
SQLITE_TRANSIENT);
28352834
} else if (value->IsBoolean()) {
2836-
r = sqlite3_bind_int(statement_, index, value->IsTrue() ? 1 : 0);
2835+
r = sqlite3_bind_int(statement_.get(), index, value->IsTrue() ? 1 : 0);
28372836
} else if (value->IsBigInt()) {
28382837
bool lossless;
28392838
int64_t as_int = value.As<BigInt>()->Int64Value(&lossless);
28402839
if (!lossless) {
28412840
THROW_ERR_INVALID_ARG_VALUE(env(), "BigInt value is too large to bind.");
28422841
return false;
28432842
}
2844-
r = sqlite3_bind_int64(statement_, index, as_int);
2843+
r = sqlite3_bind_int64(statement_.get(), index, as_int);
28452844
} else {
28462845
THROW_ERR_INVALID_ARG_TYPE(
28472846
isolate,
@@ -2856,11 +2855,11 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
28562855

28572856
MaybeLocal<Value> StatementSync::ColumnToValue(const int column) {
28582857
return StatementExecutionHelper::ColumnToValue(
2859-
env(), statement_, column, use_big_ints_);
2858+
env(), statement_.get(), column, use_big_ints_);
28602859
}
28612860

28622861
MaybeLocal<Name> StatementSync::ColumnNameToName(const int column) {
2863-
const char* col_name = sqlite3_column_name(statement_, column);
2862+
const char* col_name = sqlite3_column_name(statement_.get(), column);
28642863
if (col_name == nullptr) {
28652864
THROW_ERR_INVALID_STATE(env(), "Cannot get name of column %d", column);
28662865
return MaybeLocal<Name>();
@@ -2877,10 +2876,10 @@ bool StatementSync::GetCachedColumnNames(LocalVector<Name>* keys) {
28772876
Isolate* isolate = env()->isolate();
28782877

28792878
const int reprepare_count =
2880-
sqlite3_stmt_status(statement_, SQLITE_STMTSTATUS_REPREPARE, false);
2879+
sqlite3_stmt_status(statement_.get(), SQLITE_STMTSTATUS_REPREPARE, false);
28812880
if (reprepare_count != cached_column_names_reprepare_count_) {
28822881
cached_column_names_.clear();
2883-
const int num_cols = sqlite3_column_count(statement_);
2882+
const int num_cols = sqlite3_column_count(statement_.get());
28842883
if (num_cols == 0) {
28852884
cached_column_names_reprepare_count_ = reprepare_count;
28862885
return true;
@@ -3133,12 +3132,12 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
31333132
return;
31343133
}
31353134

3136-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3135+
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_.get()); });
31373136

31383137
Local<Value> result;
31393138
if (StatementExecutionHelper::All(env,
31403139
stmt->db_.get(),
3141-
stmt->statement_,
3140+
stmt->statement_.get(),
31423141
stmt->return_arrays_,
31433142
stmt->use_big_ints_)
31443143
.ToLocal(&result)) {
@@ -3185,7 +3184,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
31853184
Local<Value> result;
31863185
if (StatementExecutionHelper::Get(env,
31873186
stmt->db_.get(),
3188-
stmt->statement_,
3187+
stmt->statement_.get(),
31893188
stmt->return_arrays_,
31903189
stmt->use_big_ints_)
31913190
.ToLocal(&result)) {
@@ -3208,7 +3207,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
32083207

32093208
Local<Object> result;
32103209
if (StatementExecutionHelper::Run(
3211-
env, stmt->db_.get(), stmt->statement_, stmt->use_big_ints_)
3210+
env, stmt->db_.get(), stmt->statement_.get(), stmt->use_big_ints_)
32123211
.ToLocal(&result)) {
32133212
args.GetReturnValue().Set(result);
32143213
}
@@ -3220,7 +3219,7 @@ void StatementSync::Columns(const FunctionCallbackInfo<Value>& args) {
32203219
Environment* env = Environment::GetCurrent(args);
32213220
THROW_AND_RETURN_ON_BAD_STATE(
32223221
env, stmt->IsFinalized(), "statement has been finalized");
3223-
int num_cols = sqlite3_column_count(stmt->statement_);
3222+
int num_cols = sqlite3_column_count(stmt->statement_.get());
32243223
Isolate* isolate = env->isolate();
32253224
LocalVector<Value> cols(isolate);
32263225
auto sqlite_column_template = env->sqlite_column_template();
@@ -3235,14 +3234,14 @@ void StatementSync::Columns(const FunctionCallbackInfo<Value>& args) {
32353234
for (int i = 0; i < num_cols; ++i) {
32363235
MaybeLocal<Value> values[] = {
32373236
NullableSQLiteStringToValue(
3238-
isolate, sqlite3_column_origin_name(stmt->statement_, i)),
3237+
isolate, sqlite3_column_origin_name(stmt->statement_.get(), i)),
32393238
NullableSQLiteStringToValue(
3240-
isolate, sqlite3_column_database_name(stmt->statement_, i)),
3239+
isolate, sqlite3_column_database_name(stmt->statement_.get(), i)),
32413240
stmt->ColumnNameToName(i),
32423241
NullableSQLiteStringToValue(
3243-
isolate, sqlite3_column_table_name(stmt->statement_, i)),
3242+
isolate, sqlite3_column_table_name(stmt->statement_.get(), i)),
32443243
NullableSQLiteStringToValue(
3245-
isolate, sqlite3_column_decltype(stmt->statement_, i)),
3244+
isolate, sqlite3_column_decltype(stmt->statement_.get(), i)),
32463245
};
32473246

32483247
Local<Object> col;
@@ -3264,7 +3263,7 @@ void StatementSync::SourceSQLGetter(const FunctionCallbackInfo<Value>& args) {
32643263
THROW_AND_RETURN_ON_BAD_STATE(
32653264
env, stmt->IsFinalized(), "statement has been finalized");
32663265
Local<String> sql;
3267-
if (!String::NewFromUtf8(env->isolate(), sqlite3_sql(stmt->statement_))
3266+
if (!String::NewFromUtf8(env->isolate(), sqlite3_sql(stmt->statement_.get()))
32683267
.ToLocal(&sql)) {
32693268
return;
32703269
}
@@ -3279,7 +3278,7 @@ void StatementSync::ExpandedSQLGetter(const FunctionCallbackInfo<Value>& args) {
32793278
env, stmt->IsFinalized(), "statement has been finalized");
32803279

32813280
// sqlite3_expanded_sql may return nullptr without producing an error code.
3282-
char* expanded = sqlite3_expanded_sql(stmt->statement_);
3281+
char* expanded = sqlite3_expanded_sql(stmt->statement_.get());
32833282
if (expanded == nullptr) {
32843283
return THROW_ERR_SQLITE_ERROR(
32853284
env->isolate(), "Expanded SQL text would exceed configured limits");
@@ -3453,11 +3452,11 @@ bool SQLTagStore::ResetAndBindStatement(
34533452
int r = stmt->ResetStatement();
34543453
CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, false);
34553454

3456-
r = sqlite3_clear_bindings(stmt->statement_);
3455+
r = sqlite3_clear_bindings(stmt->statement_.get());
34573456
CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, false);
34583457

34593458
uint32_t n_params = args.Length() - 1;
3460-
int param_count = sqlite3_bind_parameter_count(stmt->statement_);
3459+
int param_count = sqlite3_bind_parameter_count(stmt->statement_.get());
34613460
if (param_count != static_cast<int>(n_params)) {
34623461
THROW_ERR_INVALID_ARG_VALUE(
34633462
env,
@@ -3494,7 +3493,7 @@ void SQLTagStore::Run(const FunctionCallbackInfo<Value>& args) {
34943493

34953494
Local<Object> result;
34963495
if (StatementExecutionHelper::Run(
3497-
env, stmt->db_.get(), stmt->statement_, stmt->use_big_ints_)
3496+
env, stmt->db_.get(), stmt->statement_.get(), stmt->use_big_ints_)
34983497
.ToLocal(&result)) {
34993498
args.GetReturnValue().Set(result);
35003499
}
@@ -3549,7 +3548,7 @@ void SQLTagStore::Get(const FunctionCallbackInfo<Value>& args) {
35493548
Local<Value> result;
35503549
if (StatementExecutionHelper::Get(env,
35513550
stmt->db_.get(),
3552-
stmt->statement_,
3551+
stmt->statement_.get(),
35533552
stmt->return_arrays_,
35543553
stmt->use_big_ints_)
35553554
.ToLocal(&result)) {
@@ -3575,11 +3574,11 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
35753574
return;
35763575
}
35773576

3578-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3577+
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_.get()); });
35793578
Local<Value> result;
35803579
if (StatementExecutionHelper::All(env,
35813580
stmt->db_.get(),
3582-
stmt->statement_,
3581+
stmt->statement_.get(),
35833582
stmt->return_arrays_,
35843583
stmt->use_big_ints_)
35853584
.ToLocal(&result)) {
@@ -3645,19 +3644,20 @@ BaseObjectPtr<StatementSync> SQLTagStore::PrepareStatement(
36453644
sqlite3_stmt* s = nullptr;
36463645
int r = sqlite3_prepare_v2(
36473646
session->database_->connection_, sql.data(), sql.size(), &s, nullptr);
3647+
StatementPtr stmt_ptr(s);
36483648

36493649
if (r != SQLITE_OK) {
36503650
THROW_ERR_SQLITE_ERROR(isolate, session->database_.get());
3651-
sqlite3_finalize(s);
36523651
return BaseObjectPtr<StatementSync>();
36533652
}
36543653

3655-
BaseObjectPtr<StatementSync> stmt_obj = StatementSync::Create(
3656-
env, BaseObjectPtr<DatabaseSync>(session->database_), s);
3654+
BaseObjectPtr<StatementSync> stmt_obj =
3655+
StatementSync::Create(env,
3656+
BaseObjectPtr<DatabaseSync>(session->database_),
3657+
std::move(stmt_ptr));
36573658

36583659
if (!stmt_obj) {
36593660
THROW_ERR_SQLITE_ERROR(isolate, "Failed to create StatementSync");
3660-
sqlite3_finalize(s);
36613661
return BaseObjectPtr<StatementSync>();
36623662
}
36633663

@@ -3723,7 +3723,7 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
37233723
}
37243724

37253725
BaseObjectPtr<StatementSync> StatementSync::Create(
3726-
Environment* env, BaseObjectPtr<DatabaseSync> db, sqlite3_stmt* stmt) {
3726+
Environment* env, BaseObjectPtr<DatabaseSync> db, StatementPtr stmt) {
37273727
Local<Object> obj;
37283728
if (!GetConstructorTemplate(env)
37293729
->InstanceTemplate()
@@ -3732,7 +3732,8 @@ BaseObjectPtr<StatementSync> StatementSync::Create(
37323732
return nullptr;
37333733
}
37343734

3735-
return MakeBaseObject<StatementSync>(env, obj, std::move(db), stmt);
3735+
return MakeBaseObject<StatementSync>(
3736+
env, obj, std::move(db), std::move(stmt));
37363737
}
37373738

37383739
StatementSyncIterator::StatementSyncIterator(Environment* env,
@@ -3805,11 +3806,11 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
38053806
iter->statement_reset_generation_ != iter->stmt_->reset_generation_,
38063807
"iterator was invalidated");
38073808

3808-
int r = sqlite3_step(iter->stmt_->statement_);
3809+
int r = sqlite3_step(iter->stmt_->statement_.get());
38093810
if (r != SQLITE_ROW) {
38103811
CHECK_ERROR_OR_THROW(
38113812
env->isolate(), iter->stmt_->db_.get(), r, SQLITE_DONE, void());
3812-
sqlite3_reset(iter->stmt_->statement_);
3813+
sqlite3_reset(iter->stmt_->statement_.get());
38133814
iter->done_ = true;
38143815
MaybeLocal<Value> values[] = {Boolean::New(isolate, true), Null(isolate)};
38153816
Local<Object> result;
@@ -3820,13 +3821,13 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
38203821
return;
38213822
}
38223823

3823-
int num_cols = sqlite3_column_count(iter->stmt_->statement_);
3824+
int num_cols = sqlite3_column_count(iter->stmt_->statement_.get());
38243825
Local<Value> row_value;
38253826
LocalVector<Name> row_keys(isolate);
38263827
LocalVector<Value> row_values(isolate);
38273828

38283829
if (ExtractRowValues(env,
3829-
iter->stmt_->statement_,
3830+
iter->stmt_->statement_.get(),
38303831
num_cols,
38313832
iter->stmt_->use_big_ints_,
38323833
&row_values)
@@ -3862,7 +3863,7 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
38623863
env, iter->stmt_->IsFinalized(), "statement has been finalized");
38633864
Isolate* isolate = env->isolate();
38643865

3865-
sqlite3_reset(iter->stmt_->statement_);
3866+
sqlite3_reset(iter->stmt_->statement_.get());
38663867
iter->done_ = true;
38673868

38683869
auto iter_template = getLazyIterTemplate(env);

0 commit comments

Comments
 (0)