@@ -39,6 +39,7 @@ void Statement::Init(v8::Handle<Object> target) {
3939 NODE_SET_PROTOTYPE_METHOD (constructor_template, " bind" , Bind);
4040 NODE_SET_PROTOTYPE_METHOD (constructor_template, " get" , Get);
4141 NODE_SET_PROTOTYPE_METHOD (constructor_template, " run" , Run);
42+ NODE_SET_PROTOTYPE_METHOD (constructor_template, " all" , All);
4243 NODE_SET_PROTOTYPE_METHOD (constructor_template, " reset" , Reset);
4344 NODE_SET_PROTOTYPE_METHOD (constructor_template, " finalize" , Finalize);
4445
@@ -446,6 +447,89 @@ int Statement::EIO_AfterRun(eio_req *req) {
446447 return 0 ;
447448}
448449
450+ Handle<Value> Statement::All (const Arguments& args) {
451+ HandleScope scope;
452+ Statement* stmt = ObjectWrap::Unwrap<Statement>(args.This ());
453+
454+ Baton* baton = stmt->Bind <RowsBaton>(args);
455+ stmt->Schedule (EIO_BeginAll, baton);
456+
457+ return args.This ();
458+ }
459+
460+ void Statement::EIO_BeginAll (Baton* baton) {
461+ assert (!baton->stmt ->locked );
462+ assert (!baton->stmt ->finalized );
463+ assert (baton->stmt ->prepared );
464+ baton->stmt ->locked = true ;
465+ eio_custom (EIO_All, EIO_PRI_DEFAULT , EIO_AfterAll, baton);
466+ }
467+
468+ int Statement::EIO_All (eio_req *req) {
469+ STATEMENT_INIT (RowsBaton);
470+
471+ sqlite3_mutex* mtx = sqlite3_db_mutex (stmt->db ->handle );
472+ sqlite3_mutex_enter (mtx);
473+
474+ // Make sure that we also reset when there are no parameters.
475+ if (!baton->parameters .size ()) {
476+ sqlite3_reset (stmt->handle );
477+ }
478+
479+ if (stmt->Bind (baton->parameters )) {
480+ while ((stmt->status = sqlite3_step (stmt->handle )) == SQLITE_ROW ) {
481+ Data::Row* row = new Data::Row ();
482+ GetRow (row, stmt->handle );
483+ baton->rows .push_back (row);
484+ }
485+
486+ if (stmt->status != SQLITE_DONE ) {
487+ stmt->message = std::string (sqlite3_errmsg (stmt->db ->handle ));
488+ }
489+ }
490+
491+ sqlite3_mutex_leave (mtx);
492+
493+ return 0 ;
494+ }
495+
496+ int Statement::EIO_AfterAll (eio_req *req) {
497+ HandleScope scope;
498+ STATEMENT_INIT (RowsBaton);
499+
500+ if (stmt->status != SQLITE_DONE ) {
501+ Error (baton);
502+ }
503+ else {
504+ // Fire callbacks.
505+ if (!baton->callback .IsEmpty () && baton->callback ->IsFunction ()) {
506+ if (baton->rows .size ()) {
507+ // Create the result array from the data we acquired.
508+ Local<Array> result (Array::New (baton->rows .size ()));
509+ Data::Rows::const_iterator it = baton->rows .begin ();
510+ Data::Rows::const_iterator end = baton->rows .end ();
511+ for (int i = 0 ; it < end; it++, i++) {
512+ result->Set (i, RowToJS (*it));
513+ }
514+
515+ Local<Value> argv[] = { Local<Value>::New (Null ()), result };
516+ TRY_CATCH_CALL (stmt->handle_ , baton->callback , 2 , argv);
517+ }
518+ else {
519+ // There were no result rows.
520+ Local<Value> argv[] = {
521+ Local<Value>::New (Null ()),
522+ Local<Value>::New (Array::New (0 ))
523+ };
524+ TRY_CATCH_CALL (stmt->handle_ , baton->callback , 2 , argv);
525+ }
526+ }
527+ }
528+
529+ STATEMENT_END ();
530+ return 0 ;
531+ }
532+
449533Handle<Value> Statement::Reset (const Arguments& args) {
450534 HandleScope scope;
451535 Statement* stmt = ObjectWrap::Unwrap<Statement>(args.This ());
@@ -492,8 +576,9 @@ int Statement::EIO_AfterReset(eio_req *req) {
492576Local<Array> Statement::RowToJS (Data::Row* row) {
493577 Local<Array> result (Array::New (row->size ()));
494578
495- Data::Row::iterator it = row->begin ();
496- for (int i = 0 ; it < row->end (); it++, i++) {
579+ Data::Row::const_iterator it = row->begin ();
580+ Data::Row::const_iterator end = row->end ();
581+ for (int i = 0 ; it < end; it++, i++) {
497582 Data::Field* field = *it;
498583 switch (field->type ) {
499584 case SQLITE_INTEGER : {
0 commit comments