@@ -128,7 +128,7 @@ static const rb_data_type_t pg_tuple_type = {
128128 pg_compact_callback (pg_tuple_gc_compact ),
129129 },
130130 0 , 0 ,
131- RUBY_TYPED_FREE_IMMEDIATELY ,
131+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED ,
132132};
133133
134134/*
@@ -159,9 +159,9 @@ pg_tuple_new(VALUE result, int row_num)
159159 sizeof (* this -> values ) * num_fields +
160160 sizeof (* this -> values ) * (dup_names ? 1 : 0 ));
161161
162- this -> result = result ;
163- this -> typemap = p_result -> typemap ;
164- this -> field_map = field_map ;
162+ RB_OBJ_WRITE ( self , & this -> result , result ) ;
163+ RB_OBJ_WRITE ( self , & this -> typemap , p_result -> typemap ) ;
164+ RB_OBJ_WRITE ( self , & this -> field_map , field_map ) ;
165165 this -> row_num = row_num ;
166166 this -> num_fields = num_fields ;
167167
@@ -173,7 +173,8 @@ pg_tuple_new(VALUE result, int row_num)
173173 /* Some of the column names are duplicated -> we need the keys as Array in addition.
174174 * Store it behind the values to save the space in the common case of no dups.
175175 */
176- this -> values [num_fields ] = rb_obj_freeze (rb_ary_new4 (num_fields , p_result -> fnames ));
176+ VALUE keys_array = rb_obj_freeze (rb_ary_new4 (num_fields , p_result -> fnames ));
177+ RB_OBJ_WRITE (self , & this -> values [num_fields ], keys_array );
177178 }
178179
179180 RTYPEDDATA_DATA (self ) = this ;
@@ -193,38 +194,41 @@ pg_tuple_get_this( VALUE self )
193194}
194195
195196static VALUE
196- pg_tuple_materialize_field (t_pg_tuple * this , int col )
197+ pg_tuple_materialize_field (VALUE self , int col )
197198{
199+ t_pg_tuple * this = RTYPEDDATA_DATA ( self );
198200 VALUE value = this -> values [col ];
199201
200202 if ( value == Qundef ){
201203 t_typemap * p_typemap = RTYPEDDATA_DATA ( this -> typemap );
202204
203205 pgresult_get (this -> result ); /* make sure we have a valid PGresult object */
204206 value = p_typemap -> funcs .typecast_result_value (p_typemap , this -> result , this -> row_num , col );
205- this -> values [col ] = value ;
207+ RB_OBJ_WRITE ( self , & this -> values [col ], value ) ;
206208 }
207209
208210 return value ;
209211}
210212
211213static void
212- pg_tuple_detach (t_pg_tuple * this )
214+ pg_tuple_detach (VALUE self )
213215{
214- this -> result = Qnil ;
215- this -> typemap = Qnil ;
216+ t_pg_tuple * this = RTYPEDDATA_DATA ( self );
217+ RB_OBJ_WRITE (self , & this -> result , Qnil );
218+ RB_OBJ_WRITE (self , & this -> typemap , Qnil );
216219 this -> row_num = -1 ;
217220}
218221
219222static void
220- pg_tuple_materialize (t_pg_tuple * this )
223+ pg_tuple_materialize (VALUE self )
221224{
225+ t_pg_tuple * this = RTYPEDDATA_DATA ( self );
222226 int field_num ;
223227 for (field_num = 0 ; field_num < this -> num_fields ; field_num ++ ) {
224- pg_tuple_materialize_field (this , field_num );
228+ pg_tuple_materialize_field (self , field_num );
225229 }
226230
227- pg_tuple_detach (this );
231+ pg_tuple_detach (self );
228232}
229233
230234/*
@@ -286,7 +290,7 @@ pg_tuple_fetch(int argc, VALUE *argv, VALUE self)
286290 field_num = NUM2INT (index );
287291 }
288292
289- return pg_tuple_materialize_field (this , field_num );
293+ return pg_tuple_materialize_field (self , field_num );
290294}
291295
292296/*
@@ -324,7 +328,7 @@ pg_tuple_aref(VALUE self, VALUE key)
324328 field_num = NUM2INT (index );
325329 }
326330
327- return pg_tuple_materialize_field (this , field_num );
331+ return pg_tuple_materialize_field (self , field_num );
328332}
329333
330334static VALUE
@@ -335,10 +339,9 @@ pg_tuple_num_fields_for_enum(VALUE self, VALUE args, VALUE eobj)
335339}
336340
337341static int
338- pg_tuple_yield_key_value (VALUE key , VALUE index , VALUE _this )
342+ pg_tuple_yield_key_value (VALUE key , VALUE index , VALUE self )
339343{
340- t_pg_tuple * this = (t_pg_tuple * )_this ;
341- VALUE value = pg_tuple_materialize_field (this , NUM2INT (index ));
344+ VALUE value = pg_tuple_materialize_field (self , NUM2INT (index ));
342345 rb_yield_values (2 , key , value );
343346 return ST_CONTINUE ;
344347}
@@ -360,16 +363,16 @@ pg_tuple_each(VALUE self)
360363 field_names = pg_tuple_get_field_names (this );
361364
362365 if ( field_names == Qfalse ){
363- rb_hash_foreach (this -> field_map , pg_tuple_yield_key_value , ( VALUE ) this );
366+ rb_hash_foreach (this -> field_map , pg_tuple_yield_key_value , self );
364367 } else {
365368 int i ;
366369 for ( i = 0 ; i < this -> num_fields ; i ++ ){
367- VALUE value = pg_tuple_materialize_field (this , i );
370+ VALUE value = pg_tuple_materialize_field (self , i );
368371 rb_yield_values (2 , RARRAY_AREF (field_names , i ), value );
369372 }
370373 }
371374
372- pg_tuple_detach (this );
375+ pg_tuple_detach (self );
373376 return self ;
374377}
375378
@@ -388,11 +391,11 @@ pg_tuple_each_value(VALUE self)
388391 RETURN_SIZED_ENUMERATOR (self , 0 , NULL , pg_tuple_num_fields_for_enum );
389392
390393 for (field_num = 0 ; field_num < this -> num_fields ; field_num ++ ) {
391- VALUE value = pg_tuple_materialize_field (this , field_num );
394+ VALUE value = pg_tuple_materialize_field (self , field_num );
392395 rb_yield (value );
393396 }
394397
395- pg_tuple_detach (this );
398+ pg_tuple_detach (self );
396399 return self ;
397400}
398401
@@ -409,7 +412,7 @@ pg_tuple_values(VALUE self)
409412{
410413 t_pg_tuple * this = pg_tuple_get_this (self );
411414
412- pg_tuple_materialize (this );
415+ pg_tuple_materialize (self );
413416 return rb_ary_new4 (this -> num_fields , & this -> values [0 ]);
414417}
415418
@@ -462,7 +465,7 @@ pg_tuple_dump(VALUE self)
462465 VALUE a ;
463466 t_pg_tuple * this = pg_tuple_get_this (self );
464467
465- pg_tuple_materialize (this );
468+ pg_tuple_materialize (self );
466469
467470 field_names = pg_tuple_get_field_names (this );
468471 if ( field_names == Qfalse )
@@ -520,26 +523,26 @@ pg_tuple_load(VALUE self, VALUE a)
520523 sizeof (* this -> values ) * num_fields +
521524 sizeof (* this -> values ) * (dup_names ? 1 : 0 ));
522525
523- this -> result = Qnil ;
524- this -> typemap = Qnil ;
526+ RB_OBJ_WRITE ( self , & this -> result , Qnil ) ;
527+ RB_OBJ_WRITE ( self , & this -> typemap , Qnil ) ;
525528 this -> row_num = -1 ;
526529 this -> num_fields = num_fields ;
527- this -> field_map = field_map ;
530+ RB_OBJ_WRITE ( self , & this -> field_map , field_map ) ;
528531
529532 for ( i = 0 ; i < num_fields ; i ++ ){
530533 VALUE v = RARRAY_AREF (values , i );
531534 if ( v == Qundef )
532535 rb_raise (rb_eTypeError , "field %d is not materialized" , i );
533- this -> values [i ] = v ;
536+ RB_OBJ_WRITE ( self , & this -> values [i ], v ) ;
534537 }
535538
536539 if ( dup_names ){
537- this -> values [num_fields ] = field_names ;
540+ RB_OBJ_WRITE ( self , & this -> values [num_fields ], field_names ) ;
538541 }
539542
540543 RTYPEDDATA_DATA (self ) = this ;
541544
542- rb_copy_generic_ivar (self , a );
545+ rb_copy_generic_ivar (self , a );
543546
544547 return self ;
545548}
0 commit comments