Skip to content

Commit b8f718c

Browse files
committed
implement insert/update/delete hook
1 parent 7fa4634 commit b8f718c

5 files changed

Lines changed: 62 additions & 5 deletions

File tree

lib/sqlite3.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,25 +122,27 @@ Statement.prototype.map = function() {
122122

123123
var isVerbose = false;
124124

125+
var supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];
126+
125127
Database.prototype.addListener = Database.prototype.on = function(type) {
126128
var val = EventEmitter.prototype.addListener.apply(this, arguments);
127-
if (type === 'trace' || type === 'profile') {
129+
if (supportedEvents.indexOf(type) >= 0) {
128130
this.configure(type, true);
129131
}
130132
return val;
131133
};
132134

133135
Database.prototype.removeListener = function(type) {
134136
var val = EventEmitter.prototype.removeListener.apply(this, arguments);
135-
if ((type === 'trace' || type === 'profile') && !this._events[type]) {
137+
if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
136138
this.configure(type, false);
137139
}
138140
return val;
139141
};
140142

141143
Database.prototype.removeAllListeners = function(type) {
142144
var val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
143-
if (type === 'trace' || type === 'profile') {
145+
if (supportedEvents.indexOf(type) >= 0) {
144146
this.configure(type, false);
145147
}
146148
return val;

src/database.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,51 @@ void Database::ProfileCallback(Database *db, ProfileInfo* info) {
413413
delete info;
414414
}
415415

416+
void Database::RegisterUpdateCallback(Baton* baton) {
417+
assert(baton->db->open);
418+
assert(baton->db->handle);
419+
Database* db = baton->db;
420+
421+
if (db->update_event == NULL) {
422+
// Add it.
423+
db->update_event = new AsyncUpdate(db, UpdateCallback);
424+
sqlite3_update_hook(db->handle, UpdateCallback, db);
425+
}
426+
else {
427+
// Remove it.
428+
sqlite3_update_hook(db->handle, NULL, NULL);
429+
delete db->update_event;
430+
db->update_event = NULL;
431+
}
432+
433+
delete baton;
434+
}
435+
436+
void Database::UpdateCallback(void* db, int type, const char* database,
437+
const char* table, sqlite3_int64 rowid) {
438+
// Note: This function is called in the thread pool.
439+
// Note: Some queries, such as "EXPLAIN" queries, are not sent through this.
440+
UpdateInfo* info = new UpdateInfo();
441+
info->type = type;
442+
info->database = std::string(database);
443+
info->table = std::string(table);
444+
info->rowid = rowid;
445+
static_cast<Database*>(db)->update_event->send(info);
446+
}
447+
448+
void Database::UpdateCallback(Database *db, UpdateInfo* info) {
449+
HandleScope scope;
450+
451+
Local<Value> argv[] = {
452+
String::NewSymbol(sqlite_authorizer_string(info->type)),
453+
String::New(info->database.c_str()),
454+
String::New(info->table.c_str()),
455+
Integer::New(info->rowid),
456+
};
457+
EMIT_EVENT(db->handle_, 4, argv);
458+
delete info;
459+
}
460+
416461
Handle<Value> Database::Exec(const Arguments& args) {
417462
HandleScope scope;
418463
Database* db = ObjectWrap::Unwrap<Database>(args.This());

src/database.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class Database : public EventEmitter {
8686
struct UpdateInfo {
8787
int type;
8888
std::string database;
89-
std::string tablename;
89+
std::string table;
9090
sqlite3_int64 rowid;
9191
};
9292

@@ -155,7 +155,7 @@ class Database : public EventEmitter {
155155
static void ProfileCallback(Database* db, ProfileInfo* info);
156156

157157
static void RegisterUpdateCallback(Baton* baton);
158-
static void UpdateCallback(void* db, int type, const char* database, const char* table, sqlite3_uint64 rowid);
158+
static void UpdateCallback(void* db, int type, const char* database, const char* table, sqlite3_int64 rowid);
159159
static void UpdateCallback(Database* db, UpdateInfo* info);
160160

161161
void RemoveCallbacks();

src/macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define NODE_SQLITE3_SRC_MACROS_H
33

44
const char* sqlite_code_string(int code);
5+
const char* sqlite_authorizer_string(int type);
56

67

78
#define REQUIRE_ARGUMENTS(n) \

src/sqlite3.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,12 @@ const char* sqlite_code_string(int code) {
8686
default: return "UNKNOWN";
8787
}
8888
}
89+
90+
const char* sqlite_authorizer_string(int type) {
91+
switch (type) {
92+
case SQLITE_INSERT: return "insert";
93+
case SQLITE_UPDATE: return "update";
94+
case SQLITE_DELETE: return "delete";
95+
default: return "";
96+
}
97+
}

0 commit comments

Comments
 (0)