@@ -52,6 +52,7 @@ void MysqlStatement::Init(Handle<Object> target) {
52
52
NODE_SET_PROTOTYPE_METHOD (constructor_template, " errnoSync" , MysqlStatement::ErrnoSync);
53
53
NODE_SET_PROTOTYPE_METHOD (constructor_template, " errorSync" , MysqlStatement::ErrorSync);
54
54
NODE_SET_PROTOTYPE_METHOD (constructor_template, " executeSync" , MysqlStatement::ExecuteSync);
55
+ NODE_SET_PROTOTYPE_METHOD (constructor_template, " fetchAllSync" , MysqlStatement::FetchAllSync);
55
56
NODE_SET_PROTOTYPE_METHOD (constructor_template, " fieldCountSync" , MysqlStatement::FieldCountSync);
56
57
NODE_SET_PROTOTYPE_METHOD (constructor_template, " freeResultSync" , MysqlStatement::FreeResultSync);
57
58
NODE_SET_PROTOTYPE_METHOD (constructor_template, " lastInsertIdSync" , MysqlStatement::LastInsertIdSync);
@@ -457,6 +458,164 @@ Handle<Value> MysqlStatement::ExecuteSync(const Arguments& args) {
457
458
return scope.Close (True ());
458
459
}
459
460
461
+ /* *
462
+ * Returns row data from statement result
463
+ *
464
+ * @return {Object}
465
+ */
466
+ Handle<Value> MysqlStatement::FetchAllSync (const Arguments& args) {
467
+ HandleScope scope;
468
+
469
+ MysqlStatement *stmt = OBJUNWRAP<MysqlStatement>(args.This ());
470
+
471
+ MYSQLSTMT_MUSTBE_INITIALIZED;
472
+ MYSQLSTMT_MUSTBE_PREPARED;
473
+
474
+ /* Get meta data for binding buffers */
475
+ unsigned int field_count = mysql_stmt_field_count (stmt->_stmt );
476
+ uint32_t i = 0 , j = 0 ;
477
+ unsigned long length[field_count];
478
+ int row_count = 0 ;
479
+ my_bool is_null[field_count];
480
+ MYSQL_BIND bind[field_count];
481
+ MYSQL_RES *meta;
482
+ MYSQL_FIELD *fields;
483
+
484
+ /* Buffers */
485
+ int int_data[field_count];
486
+ double double_data[field_count];
487
+ char str_data[field_count][64 ];
488
+ MYSQL_TIME date_data[field_count];
489
+ memset (date_data, 0 , sizeof (date_data));
490
+
491
+ memset (bind, 0 , sizeof (bind));
492
+ meta = mysql_stmt_result_metadata (stmt->_stmt );
493
+ fields = meta->fields ;
494
+ while (i < field_count) {
495
+ bind[i].buffer_type = fields[i].type ;
496
+
497
+ switch (fields[i].type ) {
498
+ case MYSQL_TYPE_NULL:
499
+ case MYSQL_TYPE_TINY:
500
+ case MYSQL_TYPE_SHORT:
501
+ case MYSQL_TYPE_LONG:
502
+ case MYSQL_TYPE_LONGLONG:
503
+ case MYSQL_TYPE_INT24:
504
+ bind[i].buffer = &int_data[i];
505
+ break ;
506
+ case MYSQL_TYPE_FLOAT:
507
+ case MYSQL_TYPE_DOUBLE:
508
+ case MYSQL_TYPE_DECIMAL:
509
+ case MYSQL_TYPE_NEWDECIMAL:
510
+ bind[i].buffer = &double_data[i];
511
+ break ;
512
+ case MYSQL_TYPE_STRING:
513
+ case MYSQL_TYPE_VAR_STRING:
514
+ case MYSQL_TYPE_VARCHAR:
515
+ bind[i].buffer = (char *) str_data[i];
516
+ bind[i].buffer_length = fields[i].length ;
517
+ break ;
518
+ case MYSQL_TYPE_YEAR:
519
+ case MYSQL_TYPE_DATE:
520
+ case MYSQL_TYPE_NEWDATE:
521
+ case MYSQL_TYPE_TIME:
522
+ case MYSQL_TYPE_DATETIME:
523
+ case MYSQL_TYPE_TIMESTAMP:
524
+ bind[i].buffer = (char *) &date_data[i];
525
+ }
526
+
527
+ bind[i].is_null = &is_null[i];
528
+ bind[i].length = &length[i];
529
+ i++;
530
+ }
531
+
532
+ /* If error on binding return null */
533
+ if (mysql_stmt_bind_result (stmt->_stmt , bind)) {
534
+ return scope.Close (Null ());
535
+ }
536
+
537
+ /* If error on buffering results return null */
538
+ if (mysql_stmt_store_result (stmt->_stmt )) {
539
+ return scope.Close (Null ());
540
+ }
541
+
542
+ Local<Array> js_result_rows = Array::New ();
543
+ Local<Object> js_result_row;
544
+ Local<Value> js_result;
545
+
546
+ row_count = mysql_stmt_num_rows (stmt->_stmt );
547
+
548
+ /* If no rows, return empty array */
549
+ if (!row_count) {
550
+ return scope.Close (js_result_rows);
551
+ }
552
+
553
+ i = 0 ;
554
+ while (mysql_stmt_fetch (stmt->_stmt ) != MYSQL_NO_DATA) {
555
+ js_result_row = Object::New ();
556
+
557
+ j = 0 ;
558
+ while (j < field_count) {
559
+ // fprintf(stdout, "Value: %s", buffers[j]);
560
+ switch (fields[j].type ) {
561
+ case MYSQL_TYPE_NULL:
562
+ case MYSQL_TYPE_TINY:
563
+ case MYSQL_TYPE_SHORT:
564
+ case MYSQL_TYPE_LONG:
565
+ case MYSQL_TYPE_LONGLONG:
566
+ case MYSQL_TYPE_INT24:
567
+ // fprintf(stdout, "Value: %d (%ld)\n", int_data[j], length[j]);
568
+ js_result = Integer::New (int_data[j]);
569
+ break ;
570
+ case MYSQL_TYPE_FLOAT:
571
+ case MYSQL_TYPE_DOUBLE:
572
+ // js_result = Number::New(double_data[j]);
573
+ break ;
574
+ case MYSQL_TYPE_DECIMAL:
575
+ case MYSQL_TYPE_NEWDECIMAL:
576
+ // fprintf(stdout, "Value: %f (%ld)\n", double_data[j], length[j]);
577
+ js_result = Number::New (double_data[j])->ToString ();
578
+ break ;
579
+ case MYSQL_TYPE_STRING:
580
+ case MYSQL_TYPE_VAR_STRING:
581
+ case MYSQL_TYPE_VARCHAR:
582
+ // fprintf(stdout, "Value: %s (%ld)\n", str_data[j], length[j]);
583
+ js_result = V8STR2 (str_data[j], length[j]);
584
+ break ;
585
+ case MYSQL_TYPE_YEAR:
586
+ case MYSQL_TYPE_DATE:
587
+ case MYSQL_TYPE_NEWDATE:
588
+ case MYSQL_TYPE_TIME:
589
+ case MYSQL_TYPE_DATETIME:
590
+ case MYSQL_TYPE_TIMESTAMP:
591
+ MYSQL_TIME ts = date_data[j];
592
+ time_t rawtime;
593
+ struct tm * datetime;
594
+ time (&rawtime);
595
+ datetime = localtime (&rawtime);
596
+ datetime->tm_year = ts.year - 1900 ;
597
+ datetime->tm_mon = ts.month - 1 ;
598
+ datetime->tm_mday = ts.day ;
599
+ datetime->tm_hour = ts.hour ;
600
+ datetime->tm_min = ts.minute ;
601
+ datetime->tm_sec = ts.second ;
602
+ time_t timestamp = mktime (datetime);
603
+
604
+ js_result = Date::New (1000 * (double ) timestamp);
605
+ break ;
606
+ }
607
+
608
+ js_result_row->Set (V8STR (fields[j].name ), js_result);
609
+ j++;
610
+ }
611
+
612
+ js_result_rows->Set (Integer::NewFromUnsigned (i), js_result_row);
613
+ i++;
614
+ }
615
+
616
+ return scope.Close (js_result_rows);
617
+ }
618
+
460
619
/* *
461
620
* Returns the number of field in the given statement
462
621
*
0 commit comments