Skip to content

Commit

Permalink
made logging synchronous
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaWise committed Jan 22, 2019
1 parent 6611477 commit c97fd0f
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 204 deletions.
3 changes: 1 addition & 2 deletions lib/database.js
Expand Up @@ -42,10 +42,9 @@ function Database(filenameGiven, options) {
.replace(/\/\/+/g, '/')
+ '?mode=memory&cache=shared';
}
return new CPPDatabase(filename, filenameGiven, memory || anonymous, readonly, fileMustExist, timeout, verbose ? defer(verbose) : null);
return new CPPDatabase(filename, filenameGiven, memory || anonymous, readonly, fileMustExist, timeout, verbose || null);
}

const defer = fn => arg => process.nextTick(fn, arg);
util.wrap(CPPDatabase, 'pragma', require('./pragma'));
util.wrap(CPPDatabase, 'function', require('./function'));
util.wrap(CPPDatabase, 'aggregate', require('./aggregate'));
Expand Down
178 changes: 90 additions & 88 deletions src/better_sqlite3.cpp

Large diffs are not rendered by default.

132 changes: 66 additions & 66 deletions src/better_sqlite3.hpp
Expand Up @@ -222,9 +222,9 @@ class Database : public node::ObjectWrap
#line 15 "./src/objects/database.lzz"
static void ThrowSqliteError (char const * message, int code);
#line 26 "./src/objects/database.lzz"
void Log (v8::Isolate * isolate, v8::Local <v8::Value> data);
bool Log (v8::Isolate * isolate, v8::Local <v8::Value> data);
#line 33 "./src/objects/database.lzz"
void Log (v8::Isolate * isolate, sqlite3_stmt * handle);
bool Log (v8::Isolate * isolate, sqlite3_stmt * handle);
#line 42 "./src/objects/database.lzz"
void AddStatement (Statement * stmt);
#line 43 "./src/objects/database.lzz"
Expand Down Expand Up @@ -293,59 +293,59 @@ class Database : public node::ObjectWrap
static void JS_prepare (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 182 "./src/objects/database.lzz"
static void JS_exec (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 198 "./src/objects/database.lzz"
static void JS_pragma (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 202 "./src/objects/database.lzz"
static void JS_pragma (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 206 "./src/objects/database.lzz"
static void JS_checkpoint (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 245 "./src/objects/database.lzz"
#line 249 "./src/objects/database.lzz"
static void JS_backup (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 254 "./src/objects/database.lzz"
#line 258 "./src/objects/database.lzz"
static void JS_function (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 276 "./src/objects/database.lzz"
#line 280 "./src/objects/database.lzz"
static void JS_aggregate (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 303 "./src/objects/database.lzz"
#line 307 "./src/objects/database.lzz"
static void JS_loadExtension (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 317 "./src/objects/database.lzz"
#line 321 "./src/objects/database.lzz"
static void JS_close (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 328 "./src/objects/database.lzz"
#line 332 "./src/objects/database.lzz"
static void JS_defaultSafeIntegers (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 335 "./src/objects/database.lzz"
static void JS_open (v8::Local <v8 :: String> _, v8::PropertyCallbackInfo <v8 :: Value> const & info);
#line 339 "./src/objects/database.lzz"
static void JS_open (v8::Local <v8 :: String> _, v8::PropertyCallbackInfo <v8 :: Value> const & info);
#line 343 "./src/objects/database.lzz"
static void JS_inTransaction (v8::Local <v8 :: String> _, v8::PropertyCallbackInfo <v8 :: Value> const & info);
#line 344 "./src/objects/database.lzz"
#line 348 "./src/objects/database.lzz"
void CloseHandles ();
#line 356 "./src/objects/database.lzz"
#line 360 "./src/objects/database.lzz"
static void AtExit (void * _);
#line 361 "./src/objects/database.lzz"
#line 365 "./src/objects/database.lzz"
static std::set <Database*, Database::CompareDatabase> dbs;
#line 362 "./src/objects/database.lzz"
#line 366 "./src/objects/database.lzz"
static v8::Persistent <v8::Function> SqliteError;
#line 363 "./src/objects/database.lzz"
#line 367 "./src/objects/database.lzz"
static int const MAX_BUFFER_SIZE = node::Buffer::kMaxLength > INT_MAX ? INT_MAX : static_cast<int>(node::Buffer::kMaxLength);
#line 364 "./src/objects/database.lzz"
#line 368 "./src/objects/database.lzz"
static int const MAX_STRING_SIZE = v8::String::kMaxLength > INT_MAX ? INT_MAX : static_cast<int>(v8::String::kMaxLength);
#line 366 "./src/objects/database.lzz"
#line 370 "./src/objects/database.lzz"
sqlite3 * const db_handle;
#line 367 "./src/objects/database.lzz"
#line 371 "./src/objects/database.lzz"
bool open;
#line 368 "./src/objects/database.lzz"
#line 372 "./src/objects/database.lzz"
bool busy;
#line 369 "./src/objects/database.lzz"
#line 373 "./src/objects/database.lzz"
bool pragma_mode;
#line 370 "./src/objects/database.lzz"
#line 374 "./src/objects/database.lzz"
bool safe_ints;
#line 371 "./src/objects/database.lzz"
#line 375 "./src/objects/database.lzz"
bool was_js_error;
#line 372 "./src/objects/database.lzz"
#line 376 "./src/objects/database.lzz"
bool const has_logger;
#line 373 "./src/objects/database.lzz"
#line 377 "./src/objects/database.lzz"
unsigned short int iterators;
#line 374 "./src/objects/database.lzz"
#line 378 "./src/objects/database.lzz"
CopyablePersistent <v8::Value> const logger;
#line 375 "./src/objects/database.lzz"
#line 379 "./src/objects/database.lzz"
std::set <Statement*, Database::CompareStatement> stmts;
#line 376 "./src/objects/database.lzz"
#line 380 "./src/objects/database.lzz"
std::set <Backup*, Database::CompareBackup> backups;
};
#line 1 "./src/objects/statement.lzz"
Expand Down Expand Up @@ -389,49 +389,49 @@ class Statement : public node::ObjectWrap
static void JS_new (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 139 "./src/objects/statement.lzz"
static void JS_run (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 159 "./src/objects/statement.lzz"
#line 157 "./src/objects/statement.lzz"
static void JS_get (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 177 "./src/objects/statement.lzz"
#line 172 "./src/objects/statement.lzz"
static void JS_all (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 199 "./src/objects/statement.lzz"
#line 193 "./src/objects/statement.lzz"
static void JS_iterate (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 204 "./src/objects/statement.lzz"
#line 198 "./src/objects/statement.lzz"
static void JS_bind (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 215 "./src/objects/statement.lzz"
#line 209 "./src/objects/statement.lzz"
static void JS_pluck (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 226 "./src/objects/statement.lzz"
#line 220 "./src/objects/statement.lzz"
static void JS_expand (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 237 "./src/objects/statement.lzz"
#line 231 "./src/objects/statement.lzz"
static void JS_raw (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 248 "./src/objects/statement.lzz"
#line 242 "./src/objects/statement.lzz"
static void JS_safeIntegers (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 257 "./src/objects/statement.lzz"
#line 251 "./src/objects/statement.lzz"
static void JS_columns (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 298 "./src/objects/statement.lzz"
#line 292 "./src/objects/statement.lzz"
static v8::Persistent <v8::Function> constructor;
#line 299 "./src/objects/statement.lzz"
#line 293 "./src/objects/statement.lzz"
static sqlite3_uint64 next_id;
#line 300 "./src/objects/statement.lzz"
#line 294 "./src/objects/statement.lzz"
static bool constructing_privileges;
#line 302 "./src/objects/statement.lzz"
#line 296 "./src/objects/statement.lzz"
Database * const db;
#line 303 "./src/objects/statement.lzz"
#line 297 "./src/objects/statement.lzz"
sqlite3_stmt * const handle;
#line 304 "./src/objects/statement.lzz"
#line 298 "./src/objects/statement.lzz"
Extras * const extras;
#line 305 "./src/objects/statement.lzz"
#line 299 "./src/objects/statement.lzz"
bool alive;
#line 306 "./src/objects/statement.lzz"
#line 300 "./src/objects/statement.lzz"
bool locked;
#line 307 "./src/objects/statement.lzz"
#line 301 "./src/objects/statement.lzz"
bool bound;
#line 308 "./src/objects/statement.lzz"
#line 302 "./src/objects/statement.lzz"
bool has_bind_map;
#line 309 "./src/objects/statement.lzz"
#line 303 "./src/objects/statement.lzz"
bool safe_ints;
#line 310 "./src/objects/statement.lzz"
#line 304 "./src/objects/statement.lzz"
char mode;
#line 311 "./src/objects/statement.lzz"
#line 305 "./src/objects/statement.lzz"
bool const returns_data;
};
#line 1 "./src/objects/statement-iterator.lzz"
Expand Down Expand Up @@ -461,35 +461,35 @@ class StatementIterator : public node::ObjectWrap
static void JS_symbolIterator (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 87 "./src/objects/statement-iterator.lzz"
void Next (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 107 "./src/objects/statement-iterator.lzz"
#line 111 "./src/objects/statement-iterator.lzz"
void Return (v8::FunctionCallbackInfo <v8 :: Value> const & info);
#line 112 "./src/objects/statement-iterator.lzz"
#line 116 "./src/objects/statement-iterator.lzz"
void Throw ();
#line 118 "./src/objects/statement-iterator.lzz"
#line 122 "./src/objects/statement-iterator.lzz"
void Cleanup ();
#line 126 "./src/objects/statement-iterator.lzz"
#line 130 "./src/objects/statement-iterator.lzz"
static v8::Local <v8::Object> NewRecord (v8::Isolate * isolate, v8::Local <v8::Context> ctx, v8::Local <v8::Value> value, bool done = false);
#line 133 "./src/objects/statement-iterator.lzz"
static v8::Local <v8::Object> DoneRecord (v8::Isolate * isolate);
#line 137 "./src/objects/statement-iterator.lzz"
static v8::Local <v8::Object> DoneRecord (v8::Isolate * isolate);
#line 141 "./src/objects/statement-iterator.lzz"
static v8::Persistent <v8::Function> constructor;
#line 138 "./src/objects/statement-iterator.lzz"
#line 142 "./src/objects/statement-iterator.lzz"
static v8::FunctionCallbackInfo <v8 :: Value> const * caller_info;
#line 140 "./src/objects/statement-iterator.lzz"
#line 144 "./src/objects/statement-iterator.lzz"
Statement * const stmt;
#line 141 "./src/objects/statement-iterator.lzz"
#line 145 "./src/objects/statement-iterator.lzz"
sqlite3_stmt * const handle;
#line 142 "./src/objects/statement-iterator.lzz"
#line 146 "./src/objects/statement-iterator.lzz"
Database::State * const db_state;
#line 143 "./src/objects/statement-iterator.lzz"
#line 147 "./src/objects/statement-iterator.lzz"
bool const bound;
#line 144 "./src/objects/statement-iterator.lzz"
#line 148 "./src/objects/statement-iterator.lzz"
bool const safe_ints;
#line 145 "./src/objects/statement-iterator.lzz"
#line 149 "./src/objects/statement-iterator.lzz"
char const mode;
#line 146 "./src/objects/statement-iterator.lzz"
#line 150 "./src/objects/statement-iterator.lzz"
bool alive;
#line 147 "./src/objects/statement-iterator.lzz"
#line 151 "./src/objects/statement-iterator.lzz"
bool logged;
};
#line 1 "./src/objects/backup.lzz"
Expand Down
32 changes: 18 additions & 14 deletions src/objects/database.lzz
Expand Up @@ -23,19 +23,19 @@ public:
}

// Allows Statements to log their executed SQL.
void Log(v8::Isolate* isolate, v8::Local<v8::Value> data) {
if (has_logger) {
v8::Local<v8::Function>::Cast(v8::Local<v8::Value>::New(isolate, logger))
->Call(OnlyContext, v8::Undefined(isolate), 1, &data)
.ToLocalChecked();
}
bool Log(v8::Isolate* isolate, v8::Local<v8::Value> data) {
if (!has_logger) return false;
assert(was_js_error == false);
return was_js_error = v8::Local<v8::Function>::Cast(v8::Local<v8::Value>::New(isolate, logger))
->Call(OnlyContext, v8::Undefined(isolate), 1, &data)
.IsEmpty();
}
void Log(v8::Isolate* isolate, sqlite3_stmt* handle) {
if (has_logger) {
char* expanded = sqlite3_expanded_sql(handle);
Log(isolate, StringFromUtf8(isolate, expanded ? expanded : sqlite3_sql(handle), -1));
if (expanded) sqlite3_free(expanded);
}
bool Log(v8::Isolate* isolate, sqlite3_stmt* handle) {
if (!has_logger) return false;
char* expanded = sqlite3_expanded_sql(handle);
bool failed = Log(isolate, StringFromUtf8(isolate, expanded ? expanded : sqlite3_sql(handle), -1));
if (expanded) sqlite3_free(expanded);
return failed;
}

// Allow Statements to manage themselves when created and garbage collected.
Expand Down Expand Up @@ -185,10 +185,14 @@ private:
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
db->busy = true;
UseIsolate;
if (db->Log(isolate, source)) {
db->busy = false;
db->ThrowDatabaseError();
return;
}
v8::String::Utf8Value sql(EXTRACT_STRING(isolate, source));
db->busy = true;
db->Log(isolate, source);
int status = sqlite3_exec(db->db_handle, *sql, NULL, NULL, NULL);
db->busy = false;
if (status == SQLITE_OK) info.GetReturnValue().Set(info.This());
Expand Down
10 changes: 7 additions & 3 deletions src/objects/statement-iterator.lzz
Expand Up @@ -59,9 +59,9 @@ private:
STATEMENT_START_LOGIC(REQUIRE_STATEMENT_RETURNS_DATA, ADDS_ITERATOR);
iter = new StatementIterator(stmt, bound);
}
UseIsolate;
UseIsolateAndContext;
iter->Wrap(info.This());
SetFrozen(isolate, OnlyContext, info.This(), CS::statement, caller_info->This());
SetFrozen(isolate, ctx, info.This(), CS::statement, caller_info->This());

info.GetReturnValue().Set(info.This());
}
Expand Down Expand Up @@ -89,7 +89,11 @@ private:
db_state->busy = true;
if (!logged) {
logged = true;
stmt->db->Log(OnlyIsolate, handle);
if (stmt->db->Log(OnlyIsolate, handle)) {
db_state->busy = false;
Throw();
return;
}
}
int status = sqlite3_step(handle);
db_state->busy = false;
Expand Down
8 changes: 1 addition & 7 deletions src/objects/statement.lzz
Expand Up @@ -138,11 +138,9 @@ private:

NODE_METHOD(JS_run) {
STATEMENT_START(REQUIRE_STATEMENT_DOESNT_RETURN_DATA, DOES_MUTATE);
UseIsolate;
sqlite3* db_handle = db->GetHandle();
int total_changes_before = sqlite3_total_changes(db_handle);

db->Log(isolate, handle);
sqlite3_step(handle);
if (sqlite3_reset(handle) == SQLITE_OK) {
int changes = sqlite3_total_changes(db_handle) == total_changes_before ? 0 : sqlite3_changes(db_handle);
Expand All @@ -158,9 +156,6 @@ private:

NODE_METHOD(JS_get) {
STATEMENT_START(REQUIRE_STATEMENT_RETURNS_DATA, DOES_NOT_MUTATE);
UseIsolate;

db->Log(isolate, handle);
int status = sqlite3_step(handle);
if (status == SQLITE_ROW) {
v8::Local<v8::Value> result = Data::GetRowJS(isolate, OnlyContext, handle, stmt->safe_ints, stmt->mode);
Expand All @@ -176,14 +171,13 @@ private:

NODE_METHOD(JS_all) {
STATEMENT_START(REQUIRE_STATEMENT_RETURNS_DATA, DOES_NOT_MUTATE);
UseIsolateAndContext;
UseContext;
v8::Local<v8::Array> result = v8::Array::New(isolate, 0);
uint32_t row_count = 0;
const bool safe_ints = stmt->safe_ints;
const char mode = stmt->mode;
bool js_error = false;

db->Log(isolate, handle);
while (sqlite3_step(handle) == SQLITE_ROW) {
if (row_count == 0xffffffff) { ThrowRangeError("Array overflow (too many rows returned)"); js_error = true; break; }
result->Set(ctx, row_count++, Data::GetRowJS(isolate, ctx, handle, safe_ints, mode)).FromJust();
Expand Down
9 changes: 8 additions & 1 deletion src/util/query-macros.lzz
Expand Up @@ -30,9 +30,16 @@
return ThrowTypeError("This statement already has bound parameters"); \
} ((void)0)


#define STATEMENT_THROW() db->GetState()->busy = false; STATEMENT_THROW_LOGIC()
#define STATEMENT_RETURN(x) db->GetState()->busy = false; STATEMENT_RETURN_LOGIC(x)
#define STATEMENT_START(x, y) STATEMENT_START_LOGIC(x, y); db->GetState()->busy = true
#define STATEMENT_START(x, y) \
STATEMENT_START_LOGIC(x, y); \
db->GetState()->busy = true; \
UseIsolate; \
if (db->Log(isolate, handle)) { \
STATEMENT_THROW(); \
} ((void)0)


#define DOES_NOT_MUTATE() REQUIRE_STATEMENT_NOT_LOCKED(stmt)
Expand Down

0 comments on commit c97fd0f

Please sign in to comment.