Skip to content

Commit 7c4a3f3

Browse files
committed
finally, the base implementaiton
1 parent 305e2af commit 7c4a3f3

File tree

2 files changed

+60
-78
lines changed

2 files changed

+60
-78
lines changed

src/node_sqlite.cc

Lines changed: 37 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,13 @@ class CustomAggregate {
426426

427427
class SQLiteAsyncWork : public ThreadPoolWork {
428428
public:
429-
explicit SQLiteAsyncWork(Environment* env,
430-
DatabaseSync* db,
431-
Local<Promise::Resolver> resolver,
432-
std::function<MaybeLocal<Value>()> work,
433-
std::function<void()> after)
429+
explicit SQLiteAsyncWork(
430+
Environment* env,
431+
DatabaseSync* db,
432+
Local<Promise::Resolver> resolver,
433+
std::function<int()> work, // the work will always return a status code
434+
// (that is the SQLite thing)
435+
std::function<void(int, Local<Promise::Resolver>)> after)
434436
: ThreadPoolWork(env, "node_sqlite_async"),
435437
env_(env),
436438
db_(db),
@@ -448,26 +450,21 @@ class SQLiteAsyncWork : public ThreadPoolWork {
448450
void AfterThreadPoolWork(int status) override {
449451
Isolate* isolate = env_->isolate();
450452
HandleScope handle_scope(isolate);
451-
Local<Value> result;
452453
Local<Promise::Resolver> resolver =
453454
Local<Promise::Resolver>::New(isolate, resolver_);
454455

455-
if (!result_.ToLocal(&result)) {
456-
// create sqlite error and put in the rejection
457-
resolver->Reject(env_->context(), Null(isolate)).ToChecked();
458-
return;
456+
if (after_) {
457+
after_(result_, resolver);
459458
}
460-
461-
resolver->Resolve(env()->context(), Undefined(isolate)).ToChecked();
462459
}
463460

464461
private:
465462
Environment* env_;
466463
DatabaseSync* db_;
467464
Global<Promise::Resolver> resolver_;
468-
std::function<MaybeLocal<Value>()> work_ = nullptr;
469-
std::function<void()> after_ = nullptr;
470-
MaybeLocal<Value> result_;
465+
std::function<int()> work_ = nullptr;
466+
std::function<void(int, Local<Promise::Resolver>)> after_ = nullptr;
467+
int result_;
471468
};
472469

473470
class BackupJob : public ThreadPoolWork {
@@ -2352,64 +2349,35 @@ void Statement::Run(const FunctionCallbackInfo<Value>& args) {
23522349
THROW_AND_RETURN_ON_BAD_STATE(
23532350
env, stmt->IsFinalized(), "statement has been finalized");
23542351

2355-
auto task = [args, stmt, env]() -> MaybeLocal<Value> {
2356-
int r = sqlite3_reset(stmt->statement_);
2357-
/* CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK,
2358-
* void()); */
2359-
if (r != SQLITE_OK) {
2360-
THROW_ERR_SQLITE_ERROR(env->isolate(), r);
2361-
return MaybeLocal<Value>();
2362-
}
2363-
2364-
if (!stmt->BindParams(args)) {
2365-
return MaybeLocal<Value>();
2366-
}
2367-
2368-
sqlite3_step(stmt->statement_);
2369-
r = sqlite3_reset(stmt->statement_);
2370-
/* CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK,
2371-
* void()); */
2372-
if (r != SQLITE_OK) {
2373-
THROW_ERR_SQLITE_ERROR(env->isolate(), r);
2374-
return MaybeLocal<Value>();
2375-
}
2376-
Local<Object> result = Object::New(env->isolate());
2377-
sqlite3_int64 last_insert_rowid =
2378-
sqlite3_last_insert_rowid(stmt->db_->Connection());
2379-
sqlite3_int64 changes = sqlite3_changes64(stmt->db_->Connection());
2380-
Local<Value> last_insert_rowid_val;
2381-
Local<Value> changes_val;
2382-
2383-
if (stmt->use_big_ints_) {
2384-
last_insert_rowid_val = BigInt::New(env->isolate(), last_insert_rowid);
2385-
changes_val = BigInt::New(env->isolate(), changes);
2386-
} else {
2387-
last_insert_rowid_val = Number::New(env->isolate(), last_insert_rowid);
2388-
changes_val = Number::New(env->isolate(), changes);
2389-
}
2390-
2391-
if (result
2392-
->Set(env->context(),
2393-
env->last_insert_rowid_string(),
2394-
last_insert_rowid_val)
2395-
.IsNothing() ||
2396-
result->Set(env->context(), env->changes_string(), changes_val)
2397-
.IsNothing()) {
2398-
return MaybeLocal<Value>();
2399-
}
2400-
2401-
return MaybeLocal<Object>(result);
2352+
auto task = [args, stmt, env]() -> int {
2353+
return -69;
24022354
};
24032355

24042356
if (!stmt->async_) {
2405-
Local<Value> result;
2406-
if (!task().ToLocal(&result)) {
2357+
int r = task();
2358+
args.GetReturnValue().Set(Integer::New(env->isolate(), r));
2359+
return;
2360+
}
2361+
2362+
auto after = [env](int sqlite_status, Local<Promise::Resolver> resolver) {
2363+
Local<String> message;
2364+
2365+
if (sqlite_status != SQLITE_OK) {
2366+
if (String::NewFromUtf8(env->isolate(), "Something went really wrong")
2367+
.ToLocal(&message)) {
2368+
resolver->Reject(env->context(), message);
2369+
return;
2370+
}
2371+
}
2372+
2373+
if (!String::NewFromUtf8(env->isolate(), "SQLite operation completed")
2374+
.ToLocal(&message)) {
2375+
resolver->Reject(env->context(), Undefined(env->isolate()));
24072376
return;
24082377
}
24092378

2410-
args.GetReturnValue().Set(result);
2411-
return;
2412-
}
2379+
resolver->Resolve(env->context(), message);
2380+
};
24132381

24142382
Local<Promise::Resolver> resolver;
24152383
if (!Promise::Resolver::New(env->context()).ToLocal(&resolver)) {
@@ -2418,8 +2386,8 @@ void Statement::Run(const FunctionCallbackInfo<Value>& args) {
24182386

24192387
args.GetReturnValue().Set(resolver->GetPromise());
24202388
// 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();
2389+
SQLiteAsyncWork *work = new SQLiteAsyncWork(env, stmt->db_.get(), resolver, task, after);
2390+
work->ScheduleWork();
24232391
}
24242392

24252393
void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {

test/parallel/test-sqlite-statement-async.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,27 @@ function nextDb() {
1313
return join(tmpdir.path, `database-${cnt++}.db`);
1414
}
1515

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-
});
16+
const db = new DatabaseSync(':memory:');
17+
db.exec(`CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT);`);
18+
19+
const stmt = db.prepare(`INSERT INTO test (name) VALUES (?);`, true);
20+
21+
const p = stmt.run('Alice');
22+
console.log({stmt, p})
23+
24+
p.then((message) => {
25+
console.log({message})
26+
}).catch((err) => {
27+
console.error('Error running statement:', err);
2528
});
29+
30+
// suite('Statement() constructor', () => {
31+
// test('Statement cannot be constructed directly', (t) => {
32+
// t.assert.throws(() => {
33+
// new StatementSync();
34+
// }, {
35+
// code: 'ERR_ILLEGAL_CONSTRUCTOR',
36+
// message: /Illegal constructor/,
37+
// });
38+
// });
39+
// });

0 commit comments

Comments
 (0)