Skip to content

Commit

Permalink
Log corruption error information
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny-signal committed Oct 21, 2021
1 parent 2fa02d2 commit 32828e0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const util = require('./util');
const {
Database: CPPDatabase,
setErrorConstructor,
setCorruptionLogger,
} = require('bindings')('better_sqlite3.node');

function Database(filenameGiven, options) {
Expand Down Expand Up @@ -61,6 +62,7 @@ Database.prototype.close = wrappers.close;
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
Database.prototype.unsafeMode = wrappers.unsafeMode;
Database.prototype[util.inspect] = require('./methods/inspect');
Database.setCorruptionLogger = setCorruptionLogger;

module.exports = Database;
setErrorConstructor(require('./sqlite-error'));
43 changes: 43 additions & 0 deletions src/better_sqlite3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ NODE_MODULE_INIT(/* exports, context */) {
exports->Set(context, InternalizedFromLatin1(isolate, "StatementIterator"), StatementIterator::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "Backup"), Backup::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "setErrorConstructor"), v8::FunctionTemplate::New(isolate, Addon::JS_setErrorConstructor, data)->GetFunction(context).ToLocalChecked()).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "setCorruptionLogger"), v8::FunctionTemplate::New(isolate, Addon::JS_setCorruptionLogger, data)->GetFunction(context).ToLocalChecked()).FromJust();

// Store addon instance data.
addon->Statement.Reset(isolate, v8::Local<v8::Function>::Cast(exports->Get(context, InternalizedFromLatin1(isolate, "Statement")).ToLocalChecked()));
Expand Down Expand Up @@ -1669,6 +1670,48 @@ void Addon::JS_setErrorConstructor (v8::FunctionCallbackInfo <v8 :: Value> const
if ( info . Length ( ) <= ( 0 ) || ! info [ 0 ] -> IsFunction ( ) ) return ThrowTypeError ( "Expected " "first" " argument to be " "a function" ) ; v8 :: Local < v8 :: Function > SqliteError = v8 :: Local < v8 :: Function > :: Cast ( info [ 0 ] ) ;
static_cast < Addon * > ( v8 :: Local < v8 :: External > :: Cast ( info . Data ( ) ) -> Value ( ) ) ->SqliteError.Reset( info . GetIsolate ( ) , SqliteError);
}

class LogWrapper {
public:
LogWrapper(
v8::Isolate* isolate,
v8::Local<v8::Function> fn
): isolate_(isolate) {
fn_.Reset(isolate, fn);
}

void Call(const char* msg) {
v8::HandleScope scope(isolate_);
v8::Local<v8::Function> fn =
v8::Local<v8::Function>::New(isolate_, fn_);
v8::Local<v8::Value> arg = StringFromUtf8(isolate_, msg, -1);
fn->Call(isolate_->GetCurrentContext(), v8::Undefined(isolate_), 1, &arg);
}

static void Fn(void *pArg, int iErrCode, const char *zMsg) {
LogWrapper* wrapper = reinterpret_cast<LogWrapper*>(pArg);
if (iErrCode == SQLITE_CORRUPT || iErrCode == SQLITE_NOTADB) {
wrapper->Call(zMsg);
}
}

private:
v8::Isolate* isolate_;
v8::Persistent<v8::Function> fn_;
};

void Addon::JS_setCorruptionLogger (v8::FunctionCallbackInfo <v8 :: Value> const & info) {
if (info.Length() <= 0)
return ThrowTypeError("Expected one argument");

v8::Local<v8::Function> fn = v8::Local<v8::Function>::Cast(info[0]);
int status = sqlite3_config(
SQLITE_CONFIG_LOG,
LogWrapper::Fn,
new LogWrapper(v8::Isolate::GetCurrent(), fn));
assert(status == SQLITE_OK);
}

#line 48 "./src/better_sqlite3.lzz"
void Addon::Cleanup (void * ptr)
#line 48 "./src/better_sqlite3.lzz"
Expand Down
1 change: 1 addition & 0 deletions src/better_sqlite3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ struct Addon
std::set <Database*, Database::CompareDatabase> dbs;
#line 43 "./src/better_sqlite3.lzz"
static void JS_setErrorConstructor (v8::FunctionCallbackInfo <v8 :: Value> const & info);
static void JS_setCorruptionLogger (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 48 "./src/better_sqlite3.lzz"
static void Cleanup (void * ptr);
#line 55 "./src/better_sqlite3.lzz"
Expand Down

0 comments on commit 32828e0

Please sign in to comment.