Skip to content

Commit 946a3f6

Browse files
soukanddaniellockyer
authored andcommitted
Added ability to receive updates from sqlite3_update_hook
closes TryGhost#419 - this adds support for a `change` event which forwards events arising from `sqlite3_update_hook`
1 parent 97cc584 commit 946a3f6

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

lib/sqlite3.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Statement.prototype.map = function() {
146146

147147
let isVerbose = false;
148148

149-
const supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];
149+
const supportedEvents = [ 'trace', 'profile', 'change' ];
150150

151151
Database.prototype.addListener = Database.prototype.on = function(type) {
152152
const val = EventEmitter.prototype.addListener.apply(this, arguments);

src/database.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,11 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
387387
Baton* baton = new LimitBaton(db, handle, id, value);
388388
db->Schedule(SetLimit, baton);
389389
}
390+
else if (info[0].StrictEquals(Napi::String::New(env, "change"))) {
391+
Napi::Function handle;
392+
Baton* baton = new Baton(db, handle);
393+
db->Schedule(RegisterUpdateCallback, baton);
394+
}
390395
else {
391396
Napi::TypeError::New(env, (StringConcat(
392397
#if V8_MAJOR_VERSION > 6
@@ -556,12 +561,13 @@ void Database::UpdateCallback(Database *db, UpdateInfo* i) {
556561
Napi::HandleScope scope(env);
557562

558563
Napi::Value argv[] = {
564+
Napi::String::New(env, "change"),
559565
Napi::String::New(env, sqlite_authorizer_string(info->type)),
560566
Napi::String::New(env, info->database.c_str()),
561567
Napi::String::New(env, info->table.c_str()),
562568
Napi::Number::New(env, info->rowid),
563569
};
564-
EMIT_EVENT(db->Value(), 4, argv);
570+
EMIT_EVENT(db->Value(), 5, argv);
565571
}
566572

567573
Napi::Value Database::Exec(const Napi::CallbackInfo& info) {
@@ -762,4 +768,8 @@ void Database::RemoveCallbacks() {
762768
debug_profile->finish();
763769
debug_profile = NULL;
764770
}
771+
if (update_event) {
772+
update_event->finish();
773+
update_event = NULL;
774+
}
765775
}

test/update_hook.test.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
var sqlite3 = require('..');
2+
var assert = require('assert');
3+
4+
describe('update_hook', function() {
5+
var db;
6+
7+
beforeEach(function(done) {
8+
db = new sqlite3.Database(':memory:', function(err) {
9+
if (err) return done(err);
10+
11+
db.run("CREATE TABLE update_hooks_test (id int PRIMARY KEY, value text)", done);
12+
});
13+
});
14+
15+
it('emits insert event on inserting data to table', function(done) {
16+
db.addListener('change', function(eventType, database, table, rowId) {
17+
assert.equal(eventType, 'insert');
18+
assert.equal(database, 'main');
19+
assert.equal(table, 'update_hooks_test');
20+
assert.equal(rowId, 1);
21+
22+
return done();
23+
});
24+
25+
db.run("INSERT INTO update_hooks_test VALUES (1, 'value')", function(err) {
26+
if (err) return done(err);
27+
});
28+
});
29+
30+
it('emits update event on row modification in table', function(done) {
31+
db.run("INSERT INTO update_hooks_test VALUES (2, 'value'), (3, 'value4')", function(err) {
32+
if (err) return done(err);
33+
34+
db.addListener('change', function(eventType, database, table, rowId) {
35+
assert.equal(eventType, 'update');
36+
assert.equal(database, 'main');
37+
assert.equal(table, 'update_hooks_test');
38+
assert.equal(rowId, 1);
39+
40+
db.all("SELECT * FROM update_hooks_test WHERE rowid = ?", rowId, function(err, rows) {
41+
assert.deepEqual(rows, [{ id: 2, value: 'new_val' }]);
42+
43+
return done(err);
44+
});
45+
});
46+
47+
db.run("UPDATE update_hooks_test SET value = 'new_val' WHERE id = 2", function(err) {
48+
if (err) return done(err);
49+
});
50+
});
51+
});
52+
53+
it('emits delete event on row was deleted from table', function(done) {
54+
db.run("INSERT INTO update_hooks_test VALUES (2, 'value')", function(err) {
55+
if (err) return done(err);
56+
57+
db.addListener('change', function(eventType, database, table, rowId) {
58+
assert.equal(eventType, 'delete');
59+
assert.equal(database, 'main');
60+
assert.equal(table, 'update_hooks_test');
61+
assert.equal(rowId, 1);
62+
63+
return done();
64+
});
65+
66+
db.run("DELETE FROM update_hooks_test WHERE id = 2", function(err) {
67+
if (err) return done(err);
68+
});
69+
});
70+
});
71+
72+
afterEach(function(done) {
73+
db.close(done);
74+
});
75+
});

0 commit comments

Comments
 (0)