@@ -25,6 +25,7 @@ void Database::Init(Handle<Object> target) {
2525 NODE_SET_PROTOTYPE_METHOD (constructor_template, " exec" , Exec);
2626 NODE_SET_PROTOTYPE_METHOD (constructor_template, " serialize" , Serialize);
2727 NODE_SET_PROTOTYPE_METHOD (constructor_template, " parallelize" , Parallelize);
28+ NODE_SET_PROTOTYPE_METHOD (constructor_template, " configure" , Configure);
2829
2930 target->Set (String::NewSymbol (" Database" ),
3031 constructor_template->GetFunction ());
@@ -301,6 +302,69 @@ Handle<Value> Database::Parallelize(const Arguments& args) {
301302 return args.This ();
302303}
303304
305+ Handle<Value> Database::Configure (const Arguments& args) {
306+ HandleScope scope;
307+ Database* db = ObjectWrap::Unwrap<Database>(args.This ());
308+
309+ REQUIRE_ARGUMENTS (2 );
310+
311+ if (args[0 ]->Equals (String::NewSymbol (" trace" ))) {
312+ Local<Function> handle;
313+ Baton* baton = new Baton (db, handle);
314+ db->Schedule (RegisterTraceCallback, baton);
315+ }
316+ else {
317+ ThrowException (Exception::Error (String::Concat (
318+ args[0 ]->ToString (),
319+ String::NewSymbol (" is not a valid configuration option" )
320+ )));
321+ }
322+
323+ return args.This ();
324+ }
325+
326+ void Database::RegisterTraceCallback (Baton* baton) {
327+ assert (baton->db ->open );
328+ assert (baton->db ->handle );
329+ Database* db = baton->db ;
330+
331+ if (db->debug_trace == NULL ) {
332+ // Add it.
333+ db->debug_trace = new AsyncTrace (db, TraceCallback);
334+ sqlite3_trace (db->handle , TraceCallback, db);
335+ }
336+ else {
337+ // Remove it.
338+ sqlite3_trace (db->handle , NULL , NULL );
339+ delete db->debug_trace ;
340+ db->debug_trace = NULL ;
341+ }
342+
343+ delete baton;
344+ }
345+
346+ void Database::TraceCallback (void * db, const char * sql) {
347+ // Note: This function is called in the thread pool.
348+ // Note: Some queries, such as "EXPLAIN" queries, are not sent through this.
349+ static_cast <Database*>(db)->debug_trace ->send (std::string (sql));
350+ }
351+
352+ void Database::TraceCallback (EV_P_ ev_async *w, int revents) {
353+ // Note: This function is called in the main V8 thread.
354+ HandleScope scope;
355+ AsyncTrace* async = static_cast <AsyncTrace*>(w->data );
356+
357+ std::vector<std::string> queries = async->get ();
358+ for (int i = 0 ; i < queries.size (); i++) {
359+ Local<Value> argv[] = {
360+ String::NewSymbol (" trace" ),
361+ String::New (queries[i].c_str ())
362+ };
363+ EMIT_EVENT (async->parent ->handle_ , 2 , argv);
364+ }
365+ queries.clear ();
366+ }
367+
304368Handle<Value> Database::Exec (const Arguments& args) {
305369 HandleScope scope;
306370 Database* db = ObjectWrap::Unwrap<Database>(args.This ());
0 commit comments