Skip to content

Commit

Permalink
added ability to receive updates from sqlite3_update_hook
Browse files Browse the repository at this point in the history
  • Loading branch information
soukand committed Dec 25, 2019
1 parent 1afb915 commit 175f73b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 2 deletions.
7 changes: 7 additions & 0 deletions examples/simple-chaining.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ var db;
function createDb() {
console.log("createDb chain");
db = new sqlite3.Database('chain.sqlite3', createTable);

listenDatabaseUpdates();
}

function listenDatabaseUpdates() {
db.addListener('change', function(eventType, database, table, rowId) {
console.log("database was changed", eventType, database, table, rowId);
});
}

function createTable() {
console.log("createTable lorem");
Expand Down
2 changes: 1 addition & 1 deletion lib/sqlite3.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Statement.prototype.map = function() {

var isVerbose = false;

var supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];
var supportedEvents = [ 'trace', 'profile', 'change' ];

Database.prototype.addListener = Database.prototype.on = function(type) {
var val = EventEmitter.prototype.addListener.apply(this, arguments);
Expand Down
8 changes: 7 additions & 1 deletion src/database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ NAN_METHOD(Database::Configure) {
baton->status = Nan::To<int>(info[1]).FromJust();
db->Schedule(SetBusyTimeout, baton);
}
else if (Nan::Equals(info[0], Nan::New("change").ToLocalChecked()).FromJust()) {
Local<Function> handle;
Baton* baton = new Baton(db, handle);
db->Schedule(RegisterUpdateCallback, baton);
}
else {
return Nan::ThrowError(Exception::Error(String::Concat(
#if V8_MAJOR_VERSION > 6
Expand Down Expand Up @@ -499,12 +504,13 @@ void Database::UpdateCallback(Database *db, UpdateInfo* info) {
Nan::HandleScope scope;

Local<Value> argv[] = {
Nan::New("change").ToLocalChecked(),
Nan::New(sqlite_authorizer_string(info->type)).ToLocalChecked(),
Nan::New(info->database.c_str()).ToLocalChecked(),
Nan::New(info->table.c_str()).ToLocalChecked(),
Nan::New<Number>(info->rowid),
};
EMIT_EVENT(db->handle(), 4, argv);
EMIT_EVENT(db->handle(), 5, argv);
delete info;
}

Expand Down
76 changes: 76 additions & 0 deletions test/update_hook.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var sqlite3 = require('..');
var assert = require('assert');

describe('update_hook', function() {
var db;

beforeEach(function(done) {
db = new sqlite3.Database(':memory:', function(err) {
if (err) return done(err);

db.run("CREATE TABLE update_hooks_test (id int PRIMARY KEY, value text)", done);
});
});

it('emits insert event on inserting data to table', function(done) {
db.addListener('change', function(eventType, database, table, rowId) {
assert.equal(eventType, 'insert');
assert.equal(database, 'main');
assert.equal(table, 'update_hooks_test');
assert.equal(rowId, 1);

return done();
});

db.run("INSERT INTO update_hooks_test VALUES (1, 'value')", function(err) {
if (err) return done(err);

});
});

it('emits update event on row modification in table', function(done) {
db.run("INSERT INTO update_hooks_test VALUES (2, 'value'), (3, 'value4')", function(err) {
if (err) return done(err);

db.addListener('change', function(eventType, database, table, rowId) {
assert.equal(eventType, 'update');
assert.equal(database, 'main');
assert.equal(table, 'update_hooks_test');
assert.equal(rowId, 1);

db.all("SELECT * FROM update_hooks_test WHERE rowid = ?", rowId, function(err, rows) {
assert.deepEqual(rows, [{ id: 2, value: 'new_val' }]);

return done(err);
});
});

db.run("UPDATE update_hooks_test SET value = 'new_val' WHERE id = 2", function(err) {
if (err) return done(err);
});
});
});

it('emits delete event on row was deleted from table', function(done) {
db.run("INSERT INTO update_hooks_test VALUES (2, 'value')", function(err) {
if (err) return done(err);

db.addListener('change', function(eventType, database, table, rowId) {
assert.equal(eventType, 'delete');
assert.equal(database, 'main');
assert.equal(table, 'update_hooks_test');
assert.equal(rowId, 1);

return done();
});

db.run("DELETE FROM update_hooks_test WHERE id = 2", function(err) {
if (err) return done(err);
});
});
});

afterEach(function(done) {
db.close(done);
});
});

0 comments on commit 175f73b

Please sign in to comment.