@@ -789,6 +789,66 @@ static void rb_mysql_row_query_options(VALUE opts, ID *db_timezone, ID *app_time
789
789
}
790
790
}
791
791
792
+ static VALUE rb_mysql_result_element (VALUE self , VALUE seek ) {
793
+ result_each_args args ;
794
+ MYSQL_FIELD * fields = NULL ;
795
+ long offset ;
796
+ ID db_timezone , app_timezone ;
797
+ int symbolizeKeys , asArray , castBool , cacheRows , cast ;
798
+ VALUE opts , (* fetch_row_func )(VALUE , MYSQL_FIELD * fields , const result_each_args * args );
799
+
800
+ GET_RESULT (self );
801
+
802
+ offset = NUM2LONG (seek );
803
+
804
+ if (!wrapper -> numberOfRows ) {
805
+ wrapper -> numberOfRows = mysql_num_rows (wrapper -> result );
806
+ }
807
+
808
+ opts = rb_iv_get (self , "@query_options" );
809
+ rb_mysql_row_query_options (opts , & db_timezone , & app_timezone , & symbolizeKeys , & asArray , & castBool , & cast , & cacheRows );
810
+
811
+ if (wrapper -> is_streaming ) {
812
+ rb_raise (cMysql2Error , "Element reference operator #[] cannot be used in streaming mode." );
813
+ }
814
+
815
+ /* count back from the end if passed a negative number */
816
+ if (offset < 0 ) {
817
+ offset = wrapper -> numberOfRows + offset ;
818
+ }
819
+
820
+ /* negative offset was too big */
821
+ if (offset < 0 ) {
822
+ return Qnil ;
823
+ /* rb_raise(cMysql2Error, "Out of range: offset %ld is beyond %lu rows (offset begins at 0).", offset, wrapper->numberOfRows); */
824
+ }
825
+
826
+ if (wrapper -> numberOfRows <= (unsigned long )offset ) {
827
+ return Qnil ;
828
+ /* rb_raise(cMysql2Error, "Out of range: offset %ld is beyond %lu rows (offset begins at 0).", offset, wrapper->numberOfRows); */
829
+ }
830
+
831
+ mysql_data_seek (wrapper -> result , offset );
832
+
833
+ // Backward compat
834
+ args .symbolizeKeys = symbolizeKeys ;
835
+ args .asArray = asArray ;
836
+ args .castBool = castBool ;
837
+ args .cacheRows = cacheRows ;
838
+ args .cast = cast ;
839
+ args .db_timezone = db_timezone ;
840
+ args .app_timezone = app_timezone ;
841
+ args .block_given = Qnil ;
842
+
843
+ if (wrapper -> stmt ) {
844
+ fetch_row_func = rb_mysql_result_fetch_row_stmt ;
845
+ } else {
846
+ fetch_row_func = rb_mysql_result_fetch_row ;
847
+ }
848
+
849
+ return fetch_row_func (self , fields , & args );
850
+ }
851
+
792
852
static VALUE rb_mysql_result_each_ (VALUE self ,
793
853
VALUE (* fetch_row_func )(VALUE , MYSQL_FIELD * fields , const result_each_args * args ),
794
854
const result_each_args * args )
@@ -878,7 +938,7 @@ static VALUE rb_mysql_result_each_(VALUE self,
878
938
static VALUE rb_mysql_result_each (int argc , VALUE * argv , VALUE self ) {
879
939
result_each_args args ;
880
940
VALUE defaults , opts , block , (* fetch_row_func )(VALUE , MYSQL_FIELD * fields , const result_each_args * args );
881
- ID db_timezone , app_timezone , dbTz , appTz ;
941
+ ID db_timezone , app_timezone ;
882
942
int symbolizeKeys , asArray , castBool , cacheRows , cast ;
883
943
884
944
GET_RESULT (self );
@@ -891,44 +951,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
891
951
opts = defaults ;
892
952
}
893
953
894
- symbolizeKeys = RTEST (rb_hash_aref (opts , sym_symbolize_keys ));
895
- asArray = rb_hash_aref (opts , sym_as ) == sym_array ;
896
- castBool = RTEST (rb_hash_aref (opts , sym_cast_booleans ));
897
- cacheRows = RTEST (rb_hash_aref (opts , sym_cache_rows ));
898
- cast = RTEST (rb_hash_aref (opts , sym_cast ));
899
-
900
- if (wrapper -> is_streaming && cacheRows ) {
901
- rb_warn (":cache_rows is ignored if :stream is true" );
902
- }
903
-
904
- if (wrapper -> stmt && !cacheRows && !wrapper -> is_streaming ) {
905
- rb_warn (":cache_rows is forced for prepared statements (if not streaming)" );
906
- }
907
-
908
- if (wrapper -> stmt && !cast ) {
909
- rb_warn (":cast is forced for prepared statements" );
910
- }
911
-
912
- dbTz = rb_hash_aref (opts , sym_database_timezone );
913
- if (dbTz == sym_local ) {
914
- db_timezone = intern_local ;
915
- } else if (dbTz == sym_utc ) {
916
- db_timezone = intern_utc ;
917
- } else {
918
- if (!NIL_P (dbTz )) {
919
- rb_warn (":database_timezone option must be :utc or :local - defaulting to :local" );
920
- }
921
- db_timezone = intern_local ;
922
- }
923
-
924
- appTz = rb_hash_aref (opts , sym_application_timezone );
925
- if (appTz == sym_local ) {
926
- app_timezone = intern_local ;
927
- } else if (appTz == sym_utc ) {
928
- app_timezone = intern_utc ;
929
- } else {
930
- app_timezone = Qnil ;
931
- }
954
+ rb_mysql_row_query_options (opts , & db_timezone , & app_timezone , & symbolizeKeys , & asArray , & castBool , & cast , & cacheRows );
932
955
933
956
if (wrapper -> lastRowProcessed == 0 && !wrapper -> is_streaming ) {
934
957
wrapper -> numberOfRows = wrapper -> stmt ? mysql_stmt_num_rows (wrapper -> stmt ) : mysql_num_rows (wrapper -> result );
@@ -1019,6 +1042,7 @@ void init_mysql2_result() {
1019
1042
cDateTime = rb_const_get (rb_cObject , rb_intern ("DateTime" ));
1020
1043
1021
1044
cMysql2Result = rb_define_class_under (mMysql2 , "Result" , rb_cObject );
1045
+ rb_define_method (cMysql2Result , "[]" , rb_mysql_result_element , 1 );
1022
1046
rb_define_method (cMysql2Result , "each" , rb_mysql_result_each , -1 );
1023
1047
rb_define_method (cMysql2Result , "fields" , rb_mysql_result_fetch_fields , 0 );
1024
1048
rb_define_method (cMysql2Result , "count" , rb_mysql_result_count , 0 );
0 commit comments