@@ -446,7 +446,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
446
446
mysql2_result_wrapper * wrapper ;
447
447
unsigned long i ;
448
448
const char * errstr ;
449
- int symbolizeKeys = 0 , asArray = 0 , castBool = 0 , cacheRows = 1 , cast = 1 , streaming = 0 ;
449
+ int symbolizeKeys , asArray , castBool , cacheRows , cast ;
450
450
MYSQL_FIELD * fields = NULL ;
451
451
452
452
GetMysql2Result (self , wrapper );
@@ -459,31 +459,13 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
459
459
opts = defaults ;
460
460
}
461
461
462
- if (rb_hash_aref (opts , sym_symbolize_keys ) == Qtrue ) {
463
- symbolizeKeys = 1 ;
464
- }
465
-
466
- if (rb_hash_aref (opts , sym_as ) == sym_array ) {
467
- asArray = 1 ;
468
- }
469
-
470
- if (rb_hash_aref (opts , sym_cast_booleans ) == Qtrue ) {
471
- castBool = 1 ;
472
- }
473
-
474
- if (rb_hash_aref (opts , sym_cache_rows ) == Qfalse ) {
475
- cacheRows = 0 ;
476
- }
477
-
478
- if (rb_hash_aref (opts , sym_cast ) == Qfalse ) {
479
- cast = 0 ;
480
- }
462
+ symbolizeKeys = RTEST (rb_hash_aref (opts , sym_symbolize_keys ));
463
+ asArray = rb_hash_aref (opts , sym_as ) == sym_array ;
464
+ castBool = RTEST (rb_hash_aref (opts , sym_cast_booleans ));
465
+ cacheRows = RTEST (rb_hash_aref (opts , sym_cache_rows ));
466
+ cast = RTEST (rb_hash_aref (opts , sym_cast ));
481
467
482
- if (rb_hash_aref (opts , sym_stream ) == Qtrue ) {
483
- streaming = 1 ;
484
- }
485
-
486
- if (streaming && cacheRows ) {
468
+ if (wrapper -> is_streaming && cacheRows ) {
487
469
rb_warn ("cacheRows is ignored if streaming is true" );
488
470
}
489
471
@@ -508,40 +490,28 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
508
490
app_timezone = Qnil ;
509
491
}
510
492
511
- if (wrapper -> lastRowProcessed == 0 ) {
512
- if (streaming ) {
513
- /* We can't get number of rows if we're streaming, */
514
- /* until we've finished fetching all rows */
515
- wrapper -> numberOfRows = 0 ;
493
+ if (wrapper -> is_streaming ) {
494
+ /* When streaming, we will only yield rows, not return them. */
495
+ if (wrapper -> rows == Qnil ) {
516
496
wrapper -> rows = rb_ary_new ();
517
- } else {
518
- wrapper -> numberOfRows = mysql_num_rows (wrapper -> result );
519
- if (wrapper -> numberOfRows == 0 ) {
520
- wrapper -> rows = rb_ary_new ();
521
- return wrapper -> rows ;
522
- }
523
- wrapper -> rows = rb_ary_new2 (wrapper -> numberOfRows );
524
497
}
525
- }
526
498
527
- if (streaming ) {
528
499
if (!wrapper -> streamingComplete ) {
529
500
VALUE row ;
530
501
531
502
fields = mysql_fetch_fields (wrapper -> result );
532
503
533
504
do {
534
505
row = rb_mysql_result_fetch_row (self , db_timezone , app_timezone , symbolizeKeys , asArray , castBool , cast , fields );
535
-
536
- if (block != Qnil && row != Qnil ) {
537
- rb_yield (row );
538
- wrapper -> lastRowProcessed ++ ;
506
+ if (row != Qnil ) {
507
+ wrapper -> numberOfRows ++ ;
508
+ if (block != Qnil ) {
509
+ rb_yield (row );
510
+ }
539
511
}
540
512
} while (row != Qnil );
541
513
542
514
rb_mysql_result_free_result (wrapper );
543
-
544
- wrapper -> numberOfRows = wrapper -> lastRowProcessed ;
545
515
wrapper -> streamingComplete = 1 ;
546
516
547
517
// Check for errors, the connection might have gone out from under us
@@ -554,6 +524,15 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
554
524
rb_raise (cMysql2Error , "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery)." );
555
525
}
556
526
} else {
527
+ if (wrapper -> lastRowProcessed == 0 ) {
528
+ wrapper -> numberOfRows = mysql_num_rows (wrapper -> result );
529
+ if (wrapper -> numberOfRows == 0 ) {
530
+ wrapper -> rows = rb_ary_new ();
531
+ return wrapper -> rows ;
532
+ }
533
+ wrapper -> rows = rb_ary_new2 (wrapper -> numberOfRows );
534
+ }
535
+
557
536
if (cacheRows && wrapper -> lastRowProcessed == wrapper -> numberOfRows ) {
558
537
/* we've already read the entire dataset from the C result into our */
559
538
/* internal array. Lets hand that over to the user since it's ready to go */
@@ -601,14 +580,17 @@ static VALUE rb_mysql_result_count(VALUE self) {
601
580
mysql2_result_wrapper * wrapper ;
602
581
603
582
GetMysql2Result (self , wrapper );
583
+ if (wrapper -> is_streaming ) {
584
+ /* This is an unsigned long per result.h */
585
+ return ULONG2NUM (wrapper -> numberOfRows );
586
+ }
587
+
604
588
if (wrapper -> resultFreed ) {
605
- if (wrapper -> streamingComplete ){
606
- return LONG2NUM (wrapper -> numberOfRows );
607
- } else {
608
- return LONG2NUM (RARRAY_LEN (wrapper -> rows ));
609
- }
589
+ /* Ruby arrays have platform signed long length */
590
+ return LONG2NUM (RARRAY_LEN (wrapper -> rows ));
610
591
} else {
611
- return INT2FIX (mysql_num_rows (wrapper -> result ));
592
+ /* MySQL returns an unsigned 64-bit long here */
593
+ return ULL2NUM (mysql_num_rows (wrapper -> result ));
612
594
}
613
595
}
614
596
@@ -634,6 +616,10 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
634
616
635
617
rb_iv_set (obj , "@query_options" , options );
636
618
619
+ /* Options that cannot be changed in results.each(...) { |row| }
620
+ * should be processed here. */
621
+ wrapper -> is_streaming = (rb_hash_aref (options , sym_stream ) == Qtrue ? 1 : 0 );
622
+
637
623
return obj ;
638
624
}
639
625
0 commit comments