Skip to content

Commit 305e2af

Browse files
committed
wip: this compiles using maybelocal
1 parent d3535a9 commit 305e2af

File tree

3 files changed

+63
-12
lines changed

3 files changed

+63
-12
lines changed

src/node_sqlite.cc

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ class SQLiteAsyncWork : public ThreadPoolWork {
429429
explicit SQLiteAsyncWork(Environment* env,
430430
DatabaseSync* db,
431431
Local<Promise::Resolver> resolver,
432-
std::function<int()> work,
432+
std::function<MaybeLocal<Value>()> work,
433433
std::function<void()> after)
434434
: ThreadPoolWork(env, "node_sqlite_async"),
435435
env_(env),
@@ -441,17 +441,18 @@ class SQLiteAsyncWork : public ThreadPoolWork {
441441

442442
void DoThreadPoolWork() override {
443443
if (work_) {
444-
work_status_ = work_();
444+
result_ = work_();
445445
}
446446
}
447447

448448
void AfterThreadPoolWork(int status) override {
449449
Isolate* isolate = env_->isolate();
450450
HandleScope handle_scope(isolate);
451+
Local<Value> result;
451452
Local<Promise::Resolver> resolver =
452453
Local<Promise::Resolver>::New(isolate, resolver_);
453454

454-
if (work_status_ != 0) {
455+
if (!result_.ToLocal(&result)) {
455456
// create sqlite error and put in the rejection
456457
resolver->Reject(env_->context(), Null(isolate)).ToChecked();
457458
return;
@@ -464,9 +465,9 @@ class SQLiteAsyncWork : public ThreadPoolWork {
464465
Environment* env_;
465466
DatabaseSync* db_;
466467
Global<Promise::Resolver> resolver_;
467-
std::function<int()> work_ = nullptr;
468+
std::function<MaybeLocal<Value>()> work_ = nullptr;
468469
std::function<void()> after_ = nullptr;
469-
int work_status_ = 0;
470+
MaybeLocal<Value> result_;
470471
};
471472

472473
class BackupJob : public ThreadPoolWork {
@@ -2186,7 +2187,7 @@ Statement::Statement(Environment* env,
21862187
BaseObjectPtr<DatabaseSync> db,
21872188
sqlite3_stmt* stmt,
21882189
bool async)
2189-
: BaseObject(env, object), db_(std::move(db)) {
2190+
: BaseObject(env, object), db_(std::move(db)), async_(async) {
21902191
MakeWeak();
21912192
statement_ = stmt;
21922193
// In the future, some of these options could be set at the database
@@ -2351,24 +2352,26 @@ void Statement::Run(const FunctionCallbackInfo<Value>& args) {
23512352
THROW_AND_RETURN_ON_BAD_STATE(
23522353
env, stmt->IsFinalized(), "statement has been finalized");
23532354

2354-
auto task = [args, stmt, env]() -> Local<Value> {
2355+
auto task = [args, stmt, env]() -> MaybeLocal<Value> {
23552356
int r = sqlite3_reset(stmt->statement_);
23562357
/* CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK,
23572358
* void()); */
23582359
if (r != SQLITE_OK) {
2359-
return Local<Value>();
2360+
THROW_ERR_SQLITE_ERROR(env->isolate(), r);
2361+
return MaybeLocal<Value>();
23602362
}
23612363

23622364
if (!stmt->BindParams(args)) {
2363-
return Local<Value>();
2365+
return MaybeLocal<Value>();
23642366
}
23652367

23662368
sqlite3_step(stmt->statement_);
23672369
r = sqlite3_reset(stmt->statement_);
23682370
/* CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK,
23692371
* void()); */
23702372
if (r != SQLITE_OK) {
2371-
return Local<Value>();
2373+
THROW_ERR_SQLITE_ERROR(env->isolate(), r);
2374+
return MaybeLocal<Value>();
23722375
}
23732376
Local<Object> result = Object::New(env->isolate());
23742377
sqlite3_int64 last_insert_rowid =
@@ -2392,11 +2395,31 @@ void Statement::Run(const FunctionCallbackInfo<Value>& args) {
23922395
.IsNothing() ||
23932396
result->Set(env->context(), env->changes_string(), changes_val)
23942397
.IsNothing()) {
2395-
return Local<Value>();
2398+
return MaybeLocal<Value>();
23962399
}
23972400

2398-
return result;
2401+
return MaybeLocal<Object>(result);
23992402
};
2403+
2404+
if (!stmt->async_) {
2405+
Local<Value> result;
2406+
if (!task().ToLocal(&result)) {
2407+
return;
2408+
}
2409+
2410+
args.GetReturnValue().Set(result);
2411+
return;
2412+
}
2413+
2414+
Local<Promise::Resolver> resolver;
2415+
if (!Promise::Resolver::New(env->context()).ToLocal(&resolver)) {
2416+
return;
2417+
}
2418+
2419+
args.GetReturnValue().Set(resolver->GetPromise());
2420+
// TODO(myself): todo: save work somewhere for cleaning it up
2421+
SQLiteAsyncWork *work = new SQLiteAsyncWork(env, stmt->db_.get(), resolver, task, nullptr);
2422+
work->DoThreadPoolWork();
24002423
}
24012424

24022425
void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
@@ -2641,6 +2664,7 @@ Local<FunctionTemplate> Statement::GetConstructorTemplate(Environment* env) {
26412664
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "Statement"));
26422665
tmpl->InstanceTemplate()->SetInternalFieldCount(
26432666
Statement::kInternalFieldCount);
2667+
SetProtoMethod(isolate, tmpl, "run", Statement::Run);
26442668
env->set_sqlite_statement_constructor_template(tmpl);
26452669
}
26462670
return tmpl;

src/node_sqlite.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class DatabaseOpenConfiguration {
5050
class StatementSync;
5151
class Statement;
5252
class BackupJob;
53+
class SQLiteAsyncWork;
5354

5455
class DatabaseSync : public BaseObject {
5556
public:
@@ -144,6 +145,7 @@ class Statement : public BaseObject {
144145
bool use_big_ints_;
145146
bool allow_bare_named_params_;
146147
bool allow_unknown_named_params_;
148+
std::set<SQLiteAsyncWork*> async_tasks_;
147149
std::optional<std::map<std::string, std::string>> bare_named_params_;
148150
};
149151

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
const { skipIfSQLiteMissing } = require('../common');
3+
skipIfSQLiteMissing();
4+
const tmpdir = require('../common/tmpdir');
5+
const { join } = require('node:path');
6+
const { DatabaseSync, Statement } = require('node:sqlite');
7+
const { suite, test } = require('node:test');
8+
let cnt = 0;
9+
10+
tmpdir.refresh();
11+
12+
function nextDb() {
13+
return join(tmpdir.path, `database-${cnt++}.db`);
14+
}
15+
16+
suite('Statement() constructor', () => {
17+
test('Statement cannot be constructed directly', (t) => {
18+
t.assert.throws(() => {
19+
new StatementSync();
20+
}, {
21+
code: 'ERR_ILLEGAL_CONSTRUCTOR',
22+
message: /Illegal constructor/,
23+
});
24+
});
25+
});

0 commit comments

Comments
 (0)