pg 1.1.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +42 -0
  4. data/.gems +6 -0
  5. data/.github/workflows/binary-gems.yml +117 -0
  6. data/.github/workflows/source-gem.yml +141 -0
  7. data/.gitignore +22 -0
  8. data/.hgsigs +34 -0
  9. data/.hgtags +41 -0
  10. data/.irbrc +23 -0
  11. data/.pryrc +23 -0
  12. data/.tm_properties +21 -0
  13. data/.travis.yml +49 -0
  14. data/Gemfile +14 -0
  15. data/History.md +884 -0
  16. data/Manifest.txt +3 -3
  17. data/README-Windows.rdoc +4 -4
  18. data/README.ja.md +300 -0
  19. data/README.md +286 -0
  20. data/Rakefile +37 -137
  21. data/Rakefile.cross +62 -62
  22. data/certs/ged.pem +24 -0
  23. data/certs/larskanis-2022.pem +26 -0
  24. data/certs/larskanis-2023.pem +24 -0
  25. data/ext/errorcodes.def +80 -0
  26. data/ext/errorcodes.rb +0 -0
  27. data/ext/errorcodes.txt +22 -2
  28. data/ext/extconf.rb +105 -26
  29. data/ext/gvl_wrappers.c +4 -0
  30. data/ext/gvl_wrappers.h +23 -0
  31. data/ext/pg.c +204 -152
  32. data/ext/pg.h +52 -21
  33. data/ext/pg_binary_decoder.c +100 -17
  34. data/ext/pg_binary_encoder.c +238 -13
  35. data/ext/pg_coder.c +109 -34
  36. data/ext/pg_connection.c +1383 -983
  37. data/ext/pg_copy_coder.c +356 -35
  38. data/ext/pg_errors.c +1 -1
  39. data/ext/pg_record_coder.c +522 -0
  40. data/ext/pg_result.c +439 -172
  41. data/ext/pg_text_decoder.c +42 -18
  42. data/ext/pg_text_encoder.c +201 -56
  43. data/ext/pg_tuple.c +97 -66
  44. data/ext/pg_type_map.c +45 -11
  45. data/ext/pg_type_map_all_strings.c +21 -7
  46. data/ext/pg_type_map_by_class.c +59 -27
  47. data/ext/pg_type_map_by_column.c +80 -37
  48. data/ext/pg_type_map_by_mri_type.c +49 -20
  49. data/ext/pg_type_map_by_oid.c +62 -29
  50. data/ext/pg_type_map_in_ruby.c +56 -22
  51. data/ext/{util.c → pg_util.c} +7 -7
  52. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  53. data/lib/pg/basic_type_map_for_queries.rb +198 -0
  54. data/lib/pg/basic_type_map_for_results.rb +104 -0
  55. data/lib/pg/basic_type_registry.rb +299 -0
  56. data/lib/pg/binary_decoder/date.rb +9 -0
  57. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  58. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  59. data/lib/pg/coder.rb +35 -12
  60. data/lib/pg/connection.rb +744 -84
  61. data/lib/pg/exceptions.rb +15 -1
  62. data/lib/pg/result.rb +13 -1
  63. data/lib/pg/text_decoder/date.rb +18 -0
  64. data/lib/pg/text_decoder/inet.rb +9 -0
  65. data/lib/pg/text_decoder/json.rb +14 -0
  66. data/lib/pg/text_decoder/numeric.rb +9 -0
  67. data/lib/pg/text_decoder/timestamp.rb +30 -0
  68. data/lib/pg/text_encoder/date.rb +12 -0
  69. data/lib/pg/text_encoder/inet.rb +28 -0
  70. data/lib/pg/text_encoder/json.rb +14 -0
  71. data/lib/pg/text_encoder/numeric.rb +9 -0
  72. data/lib/pg/text_encoder/timestamp.rb +24 -0
  73. data/lib/pg/type_map_by_column.rb +2 -1
  74. data/lib/pg/version.rb +4 -0
  75. data/lib/pg.rb +94 -39
  76. data/misc/openssl-pg-segfault.rb +31 -0
  77. data/misc/postgres/History.txt +9 -0
  78. data/misc/postgres/Manifest.txt +5 -0
  79. data/misc/postgres/README.txt +21 -0
  80. data/misc/postgres/Rakefile +21 -0
  81. data/misc/postgres/lib/postgres.rb +16 -0
  82. data/misc/ruby-pg/History.txt +9 -0
  83. data/misc/ruby-pg/Manifest.txt +5 -0
  84. data/misc/ruby-pg/README.txt +21 -0
  85. data/misc/ruby-pg/Rakefile +21 -0
  86. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  87. data/pg.gemspec +34 -0
  88. data/rakelib/task_extension.rb +46 -0
  89. data/sample/array_insert.rb +20 -0
  90. data/sample/async_api.rb +102 -0
  91. data/sample/async_copyto.rb +39 -0
  92. data/sample/async_mixed.rb +56 -0
  93. data/sample/check_conn.rb +21 -0
  94. data/sample/copydata.rb +71 -0
  95. data/sample/copyfrom.rb +81 -0
  96. data/sample/copyto.rb +19 -0
  97. data/sample/cursor.rb +21 -0
  98. data/sample/disk_usage_report.rb +177 -0
  99. data/sample/issue-119.rb +94 -0
  100. data/sample/losample.rb +69 -0
  101. data/sample/minimal-testcase.rb +17 -0
  102. data/sample/notify_wait.rb +72 -0
  103. data/sample/pg_statistics.rb +285 -0
  104. data/sample/replication_monitor.rb +222 -0
  105. data/sample/test_binary_values.rb +33 -0
  106. data/sample/wal_shipper.rb +434 -0
  107. data/sample/warehouse_partitions.rb +311 -0
  108. data/translation/.po4a-version +7 -0
  109. data/translation/po/all.pot +936 -0
  110. data/translation/po/ja.po +1036 -0
  111. data/translation/po4a.cfg +12 -0
  112. data.tar.gz.sig +0 -0
  113. metadata +144 -222
  114. metadata.gz.sig +0 -0
  115. data/ChangeLog +0 -6595
  116. data/History.rdoc +0 -485
  117. data/README.ja.rdoc +0 -14
  118. data/README.rdoc +0 -178
  119. data/lib/pg/basic_type_mapping.rb +0 -459
  120. data/lib/pg/binary_decoder.rb +0 -22
  121. data/lib/pg/constants.rb +0 -11
  122. data/lib/pg/text_decoder.rb +0 -47
  123. data/lib/pg/text_encoder.rb +0 -69
  124. data/spec/data/expected_trace.out +0 -26
  125. data/spec/data/random_binary_data +0 -0
  126. data/spec/helpers.rb +0 -381
  127. data/spec/pg/basic_type_mapping_spec.rb +0 -508
  128. data/spec/pg/connection_spec.rb +0 -1849
  129. data/spec/pg/connection_sync_spec.rb +0 -41
  130. data/spec/pg/result_spec.rb +0 -491
  131. data/spec/pg/tuple_spec.rb +0 -280
  132. data/spec/pg/type_map_by_class_spec.rb +0 -138
  133. data/spec/pg/type_map_by_column_spec.rb +0 -222
  134. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  135. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  136. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  137. data/spec/pg/type_map_spec.rb +0 -22
  138. data/spec/pg/type_spec.rb +0 -949
  139. data/spec/pg_spec.rb +0 -50
  140. /data/ext/{util.h → pg_util.h} +0 -0
data/ext/pg_tuple.c CHANGED
@@ -52,57 +52,83 @@ typedef struct {
52
52
  VALUE values[0];
53
53
  } t_pg_tuple;
54
54
 
55
- static inline VALUE
56
- pg_tuple_get_field_names( t_pg_tuple *this )
55
+ static inline VALUE *
56
+ pg_tuple_get_field_names_ptr( t_pg_tuple *this )
57
57
  {
58
58
  if( this->num_fields != (int)RHASH_SIZE(this->field_map) ){
59
- return this->values[this->num_fields];
59
+ return &this->values[this->num_fields];
60
60
  } else {
61
- return Qfalse;
61
+ static VALUE f = Qfalse;
62
+ return &f;
62
63
  }
63
64
  }
64
65
 
66
+ static inline VALUE
67
+ pg_tuple_get_field_names( t_pg_tuple *this )
68
+ {
69
+ return *pg_tuple_get_field_names_ptr(this);
70
+ }
71
+
65
72
  static void
66
- pg_tuple_gc_mark( t_pg_tuple *this )
73
+ pg_tuple_gc_mark( void *_this )
67
74
  {
75
+ t_pg_tuple *this = (t_pg_tuple *)_this;
68
76
  int i;
69
77
 
70
78
  if( !this ) return;
71
- rb_gc_mark( this->result );
72
- rb_gc_mark( this->typemap );
73
- rb_gc_mark( this->field_map );
79
+ rb_gc_mark_movable( this->result );
80
+ rb_gc_mark_movable( this->typemap );
81
+ rb_gc_mark_movable( this->field_map );
74
82
 
75
83
  for( i = 0; i < this->num_fields; i++ ){
76
- rb_gc_mark( this->values[i] );
84
+ rb_gc_mark_movable( this->values[i] );
77
85
  }
78
- rb_gc_mark( pg_tuple_get_field_names(this) );
86
+ rb_gc_mark_movable( pg_tuple_get_field_names(this) );
79
87
  }
80
88
 
81
89
  static void
82
- pg_tuple_gc_free( t_pg_tuple *this )
90
+ pg_tuple_gc_compact( void *_this )
83
91
  {
92
+ t_pg_tuple *this = (t_pg_tuple *)_this;
93
+ int i;
94
+
95
+ if( !this ) return;
96
+ pg_gc_location( this->result );
97
+ pg_gc_location( this->typemap );
98
+ pg_gc_location( this->field_map );
99
+
100
+ for( i = 0; i < this->num_fields; i++ ){
101
+ pg_gc_location( this->values[i] );
102
+ }
103
+ pg_gc_location( *pg_tuple_get_field_names_ptr(this) );
104
+ }
105
+
106
+ static void
107
+ pg_tuple_gc_free( void *_this )
108
+ {
109
+ t_pg_tuple *this = (t_pg_tuple *)_this;
84
110
  if( !this ) return;
85
111
  xfree(this);
86
112
  }
87
113
 
88
114
  static size_t
89
- pg_tuple_memsize( t_pg_tuple *this )
115
+ pg_tuple_memsize( const void *_this )
90
116
  {
117
+ const t_pg_tuple *this = (const t_pg_tuple *)_this;
91
118
  if( this==NULL ) return 0;
92
119
  return sizeof(*this) + sizeof(*this->values) * this->num_fields;
93
120
  }
94
121
 
95
122
  static const rb_data_type_t pg_tuple_type = {
96
- "pg",
123
+ "PG::Tuple",
97
124
  {
98
- (void (*)(void*))pg_tuple_gc_mark,
99
- (void (*)(void*))pg_tuple_gc_free,
100
- (size_t (*)(const void *))pg_tuple_memsize,
125
+ pg_tuple_gc_mark,
126
+ pg_tuple_gc_free,
127
+ pg_tuple_memsize,
128
+ pg_compact_callback(pg_tuple_gc_compact),
101
129
  },
102
130
  0, 0,
103
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
104
- RUBY_TYPED_FREE_IMMEDIATELY,
105
- #endif
131
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
106
132
  };
107
133
 
108
134
  /*
@@ -132,11 +158,10 @@ pg_tuple_new(VALUE result, int row_num)
132
158
  sizeof(*this) +
133
159
  sizeof(*this->values) * num_fields +
134
160
  sizeof(*this->values) * (dup_names ? 1 : 0));
135
- RTYPEDDATA_DATA(self) = this;
136
161
 
137
- this->result = result;
138
- this->typemap = p_result->typemap;
139
- 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);
140
165
  this->row_num = row_num;
141
166
  this->num_fields = num_fields;
142
167
 
@@ -148,9 +173,12 @@ pg_tuple_new(VALUE result, int row_num)
148
173
  /* Some of the column names are duplicated -> we need the keys as Array in addition.
149
174
  * Store it behind the values to save the space in the common case of no dups.
150
175
  */
151
- 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);
152
178
  }
153
179
 
180
+ RTYPEDDATA_DATA(self) = this;
181
+
154
182
  return self;
155
183
  }
156
184
 
@@ -166,38 +194,41 @@ pg_tuple_get_this( VALUE self )
166
194
  }
167
195
 
168
196
  static VALUE
169
- pg_tuple_materialize_field(t_pg_tuple *this, int col)
197
+ pg_tuple_materialize_field(VALUE self, int col)
170
198
  {
199
+ t_pg_tuple *this = RTYPEDDATA_DATA( self );
171
200
  VALUE value = this->values[col];
172
201
 
173
202
  if( value == Qundef ){
174
- t_typemap *p_typemap = DATA_PTR( this->typemap );
203
+ t_typemap *p_typemap = RTYPEDDATA_DATA( this->typemap );
175
204
 
176
205
  pgresult_get(this->result); /* make sure we have a valid PGresult object */
177
206
  value = p_typemap->funcs.typecast_result_value(p_typemap, this->result, this->row_num, col);
178
- this->values[col] = value;
207
+ RB_OBJ_WRITE(self, &this->values[col], value);
179
208
  }
180
209
 
181
210
  return value;
182
211
  }
183
212
 
184
213
  static void
185
- pg_tuple_detach(t_pg_tuple *this)
214
+ pg_tuple_detach(VALUE self)
186
215
  {
187
- this->result = Qnil;
188
- 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);
189
219
  this->row_num = -1;
190
220
  }
191
221
 
192
222
  static void
193
- pg_tuple_materialize(t_pg_tuple *this)
223
+ pg_tuple_materialize(VALUE self)
194
224
  {
225
+ t_pg_tuple *this = RTYPEDDATA_DATA( self );
195
226
  int field_num;
196
227
  for(field_num = 0; field_num < this->num_fields; field_num++) {
197
- pg_tuple_materialize_field(this, field_num);
228
+ pg_tuple_materialize_field(self, field_num);
198
229
  }
199
230
 
200
- pg_tuple_detach(this);
231
+ pg_tuple_detach(self);
201
232
  }
202
233
 
203
234
  /*
@@ -211,7 +242,7 @@ pg_tuple_materialize(t_pg_tuple *this)
211
242
  * An integer +key+ is interpreted as column index.
212
243
  * Negative values of index count from the end of the array.
213
244
  *
214
- * A string +key+ is interpreted as column name.
245
+ * Depending on Result#field_name_type= a string or symbol +key+ is interpreted as column name.
215
246
  *
216
247
  * If the key can't be found, there are several options:
217
248
  * With no other arguments, it will raise a IndexError exception;
@@ -259,14 +290,21 @@ pg_tuple_fetch(int argc, VALUE *argv, VALUE self)
259
290
  field_num = NUM2INT(index);
260
291
  }
261
292
 
262
- return pg_tuple_materialize_field(this, field_num);
293
+ return pg_tuple_materialize_field(self, field_num);
263
294
  }
264
295
 
265
296
  /*
266
297
  * call-seq:
267
- * res[ name ] -> value
298
+ * tup[ key ] -> value
268
299
  *
269
- * Returns field _name_.
300
+ * Returns a field value by either column index or column name.
301
+ *
302
+ * An integer +key+ is interpreted as column index.
303
+ * Negative values of index count from the end of the array.
304
+ *
305
+ * Depending on Result#field_name_type= a string or symbol +key+ is interpreted as column name.
306
+ *
307
+ * If the key can't be found, it returns +nil+ .
270
308
  */
271
309
  static VALUE
272
310
  pg_tuple_aref(VALUE self, VALUE key)
@@ -290,7 +328,7 @@ pg_tuple_aref(VALUE self, VALUE key)
290
328
  field_num = NUM2INT(index);
291
329
  }
292
330
 
293
- return pg_tuple_materialize_field(this, field_num);
331
+ return pg_tuple_materialize_field(self, field_num);
294
332
  }
295
333
 
296
334
  static VALUE
@@ -301,10 +339,9 @@ pg_tuple_num_fields_for_enum(VALUE self, VALUE args, VALUE eobj)
301
339
  }
302
340
 
303
341
  static int
304
- pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE _this)
342
+ pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE self)
305
343
  {
306
- t_pg_tuple *this = (t_pg_tuple *)_this;
307
- VALUE value = pg_tuple_materialize_field(this, NUM2INT(index));
344
+ VALUE value = pg_tuple_materialize_field(self, NUM2INT(index));
308
345
  rb_yield_values(2, key, value);
309
346
  return ST_CONTINUE;
310
347
  }
@@ -326,16 +363,16 @@ pg_tuple_each(VALUE self)
326
363
  field_names = pg_tuple_get_field_names(this);
327
364
 
328
365
  if( field_names == Qfalse ){
329
- 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);
330
367
  } else {
331
368
  int i;
332
369
  for( i = 0; i < this->num_fields; i++ ){
333
- VALUE value = pg_tuple_materialize_field(this, i);
370
+ VALUE value = pg_tuple_materialize_field(self, i);
334
371
  rb_yield_values(2, RARRAY_AREF(field_names, i), value);
335
372
  }
336
373
  }
337
374
 
338
- pg_tuple_detach(this);
375
+ pg_tuple_detach(self);
339
376
  return self;
340
377
  }
341
378
 
@@ -354,11 +391,11 @@ pg_tuple_each_value(VALUE self)
354
391
  RETURN_SIZED_ENUMERATOR(self, 0, NULL, pg_tuple_num_fields_for_enum);
355
392
 
356
393
  for(field_num = 0; field_num < this->num_fields; field_num++) {
357
- VALUE value = pg_tuple_materialize_field(this, field_num);
394
+ VALUE value = pg_tuple_materialize_field(self, field_num);
358
395
  rb_yield(value);
359
396
  }
360
397
 
361
- pg_tuple_detach(this);
398
+ pg_tuple_detach(self);
362
399
  return self;
363
400
  }
364
401
 
@@ -375,7 +412,7 @@ pg_tuple_values(VALUE self)
375
412
  {
376
413
  t_pg_tuple *this = pg_tuple_get_this(self);
377
414
 
378
- pg_tuple_materialize(this);
415
+ pg_tuple_materialize(self);
379
416
  return rb_ary_new4(this->num_fields, &this->values[0]);
380
417
  }
381
418
 
@@ -428,7 +465,7 @@ pg_tuple_dump(VALUE self)
428
465
  VALUE a;
429
466
  t_pg_tuple *this = pg_tuple_get_this(self);
430
467
 
431
- pg_tuple_materialize(this);
468
+ pg_tuple_materialize(self);
432
469
 
433
470
  field_names = pg_tuple_get_field_names(this);
434
471
  if( field_names == Qfalse )
@@ -437,10 +474,7 @@ pg_tuple_dump(VALUE self)
437
474
  values = rb_ary_new4(this->num_fields, &this->values[0]);
438
475
  a = rb_ary_new3(2, field_names, values);
439
476
 
440
- if (FL_TEST(self, FL_EXIVAR)) {
441
- rb_copy_generic_ivar(a, self);
442
- FL_SET(a, FL_EXIVAR);
443
- }
477
+ rb_copy_generic_ivar(a, self);
444
478
 
445
479
  return a;
446
480
  }
@@ -457,7 +491,6 @@ pg_tuple_load(VALUE self, VALUE a)
457
491
  int dup_names;
458
492
 
459
493
  rb_check_frozen(self);
460
- rb_check_trusted(self);
461
494
 
462
495
  TypedData_Get_Struct(self, t_pg_tuple, &pg_tuple_type, this);
463
496
  if (this)
@@ -472,9 +505,9 @@ pg_tuple_load(VALUE self, VALUE a)
472
505
  rb_obj_freeze(field_names);
473
506
  values = RARRAY_AREF(a, 1);
474
507
  Check_Type(values, T_ARRAY);
475
- num_fields = RARRAY_LEN(values);
508
+ num_fields = RARRAY_LENINT(values);
476
509
 
477
- if (RARRAY_LEN(field_names) != num_fields)
510
+ if (RARRAY_LENINT(field_names) != num_fields)
478
511
  rb_raise(rb_eTypeError, "different number of fields and values");
479
512
 
480
513
  field_map = rb_hash_new();
@@ -489,35 +522,33 @@ pg_tuple_load(VALUE self, VALUE a)
489
522
  sizeof(*this) +
490
523
  sizeof(*this->values) * num_fields +
491
524
  sizeof(*this->values) * (dup_names ? 1 : 0));
492
- RTYPEDDATA_DATA(self) = this;
493
525
 
494
- this->result = Qnil;
495
- this->typemap = Qnil;
526
+ RB_OBJ_WRITE(self, &this->result, Qnil);
527
+ RB_OBJ_WRITE(self, &this->typemap, Qnil);
496
528
  this->row_num = -1;
497
529
  this->num_fields = num_fields;
498
- this->field_map = field_map;
530
+ RB_OBJ_WRITE(self, &this->field_map, field_map);
499
531
 
500
532
  for( i = 0; i < num_fields; i++ ){
501
533
  VALUE v = RARRAY_AREF(values, i);
502
534
  if( v == Qundef )
503
535
  rb_raise(rb_eTypeError, "field %d is not materialized", i);
504
- this->values[i] = v;
536
+ RB_OBJ_WRITE(self, &this->values[i], v);
505
537
  }
506
538
 
507
539
  if( dup_names ){
508
- this->values[num_fields] = field_names;
540
+ RB_OBJ_WRITE(self, &this->values[num_fields], field_names);
509
541
  }
510
542
 
511
- if (FL_TEST(a, FL_EXIVAR)) {
512
- rb_copy_generic_ivar(self, a);
513
- FL_SET(self, FL_EXIVAR);
514
- }
543
+ RTYPEDDATA_DATA(self) = this;
544
+
545
+ rb_copy_generic_ivar(self, a);
515
546
 
516
547
  return self;
517
548
  }
518
549
 
519
550
  void
520
- init_pg_tuple()
551
+ init_pg_tuple(void)
521
552
  {
522
553
  rb_cPG_Tuple = rb_define_class_under( rb_mPG, "Tuple", rb_cObject );
523
554
  rb_define_alloc_func( rb_cPG_Tuple, pg_tuple_s_allocate );
data/ext/pg_type_map.c CHANGED
@@ -1,11 +1,45 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_type_map.c,v 2af122820861 2017/01/14 19:56:36 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
8
 
9
+ void
10
+ pg_typemap_mark( void *_this )
11
+ {
12
+ t_typemap *this = (t_typemap *)_this;
13
+ rb_gc_mark_movable(this->default_typemap);
14
+ }
15
+
16
+ size_t
17
+ pg_typemap_memsize( const void *_this )
18
+ {
19
+ t_typemap *this = (t_typemap *)_this;
20
+ return sizeof(*this);
21
+ }
22
+
23
+ void
24
+ pg_typemap_compact( void *_this )
25
+ {
26
+ t_typemap *this = (t_typemap *)_this;
27
+ pg_gc_location(this->default_typemap);
28
+ }
29
+
30
+ const rb_data_type_t pg_typemap_type = {
31
+ "PG::TypeMap",
32
+ {
33
+ pg_typemap_mark,
34
+ RUBY_TYPED_DEFAULT_FREE,
35
+ pg_typemap_memsize,
36
+ pg_compact_callback(pg_typemap_compact),
37
+ },
38
+ 0,
39
+ 0,
40
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
41
+ };
42
+
9
43
  VALUE rb_cTypeMap;
10
44
  VALUE rb_mDefaultTypeMappable;
11
45
  static ID s_id_fit_to_query;
@@ -75,7 +109,7 @@ pg_typemap_s_allocate( VALUE klass )
75
109
  VALUE self;
76
110
  t_typemap *this;
77
111
 
78
- self = Data_Make_Struct( klass, t_typemap, NULL, -1, this );
112
+ self = TypedData_Make_Struct( klass, t_typemap, &pg_typemap_type, this );
79
113
  this->funcs = pg_typemap_funcs;
80
114
 
81
115
  return self;
@@ -94,14 +128,14 @@ pg_typemap_s_allocate( VALUE klass )
94
128
  static VALUE
95
129
  pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
96
130
  {
97
- t_typemap *this = DATA_PTR( self );
131
+ t_typemap *this = RTYPEDDATA_DATA( self );
132
+ t_typemap *tm;
133
+ UNUSED(tm);
98
134
 
99
- if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
100
- rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
101
- rb_obj_classname( typemap ) );
102
- }
103
- Check_Type(typemap, T_DATA);
104
- this->default_typemap = typemap;
135
+ rb_check_frozen(self);
136
+ /* Check type of method param */
137
+ TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, tm);
138
+ RB_OBJ_WRITE(self, &this->default_typemap, typemap);
105
139
 
106
140
  return typemap;
107
141
  }
@@ -119,7 +153,7 @@ pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
119
153
  static VALUE
120
154
  pg_typemap_default_type_map_get(VALUE self)
121
155
  {
122
- t_typemap *this = DATA_PTR( self );
156
+ t_typemap *this = RTYPEDDATA_DATA( self );
123
157
 
124
158
  return this->default_typemap;
125
159
  }
@@ -143,7 +177,7 @@ pg_typemap_with_default_type_map(VALUE self, VALUE typemap)
143
177
  }
144
178
 
145
179
  void
146
- init_pg_type_map()
180
+ init_pg_type_map(void)
147
181
  {
148
182
  s_id_fit_to_query = rb_intern("fit_to_query");
149
183
  s_id_fit_to_result = rb_intern("fit_to_result");
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
3
- * $Id: pg_type_map_all_strings.c,v c53f993a4254 2014/12/12 21:57:29 lars $
3
+ * $Id$
4
4
  *
5
5
  * This is the default typemap.
6
6
  *
@@ -8,6 +8,19 @@
8
8
 
9
9
  #include "pg.h"
10
10
 
11
+ static const rb_data_type_t pg_tmas_type = {
12
+ "PG::TypeMapAllStrings",
13
+ {
14
+ pg_typemap_mark,
15
+ RUBY_TYPED_DEFAULT_FREE,
16
+ pg_typemap_memsize,
17
+ pg_compact_callback(pg_typemap_compact),
18
+ },
19
+ &pg_typemap_type,
20
+ 0,
21
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
22
+ };
23
+
11
24
  VALUE rb_cTypeMapAllStrings;
12
25
  VALUE pg_typemap_all_strings;
13
26
 
@@ -33,9 +46,9 @@ pg_tmas_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
33
46
  len = PQgetlength( p_result->pgresult, tuple, field );
34
47
 
35
48
  if ( 0 == PQfformat(p_result->pgresult, field) ) {
36
- ret = pg_text_dec_string(NULL, val, len, tuple, field, ENCODING_GET(result));
49
+ ret = pg_text_dec_string(NULL, val, len, tuple, field, p_result->enc_idx);
37
50
  } else {
38
- ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, ENCODING_GET(result));
51
+ ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, p_result->enc_idx);
39
52
  }
40
53
 
41
54
  return ret;
@@ -63,6 +76,7 @@ pg_tmas_fit_to_copy_get( VALUE self )
63
76
  static VALUE
64
77
  pg_tmas_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
65
78
  {
79
+ rb_str_modify(field_str);
66
80
  if( format == 0 ){
67
81
  PG_ENCODING_SET_NOCHECK( field_str, enc_idx );
68
82
  } else {
@@ -77,7 +91,7 @@ pg_tmas_s_allocate( VALUE klass )
77
91
  t_typemap *this;
78
92
  VALUE self;
79
93
 
80
- self = Data_Make_Struct( klass, t_typemap, NULL, -1, this );
94
+ self = TypedData_Make_Struct( klass, t_typemap, &pg_tmas_type, this );
81
95
 
82
96
  this->funcs.fit_to_result = pg_tmas_fit_to_result;
83
97
  this->funcs.fit_to_query = pg_tmas_fit_to_query;
@@ -91,7 +105,7 @@ pg_tmas_s_allocate( VALUE klass )
91
105
 
92
106
 
93
107
  void
94
- init_pg_type_map_all_strings()
108
+ init_pg_type_map_all_strings(void)
95
109
  {
96
110
  /*
97
111
  * Document-class: PG::TypeMapAllStrings < PG::TypeMap
@@ -99,7 +113,7 @@ init_pg_type_map_all_strings()
99
113
  * This type map casts all values received from the database server to Strings
100
114
  * and sends all values to the server after conversion to String by +#to_s+ .
101
115
  * That means, it is hard coded to PG::TextEncoder::String for value encoding
102
- * and to PG::TextDecoder::String for text format respectivly PG::BinaryDecoder::Bytea
116
+ * and to PG::TextDecoder::String for text format respectively PG::BinaryDecoder::Bytea
103
117
  * for binary format received from the server.
104
118
  *
105
119
  * It is suitable for type casting query bind parameters, result values and
@@ -111,6 +125,6 @@ init_pg_type_map_all_strings()
111
125
  rb_cTypeMapAllStrings = rb_define_class_under( rb_mPG, "TypeMapAllStrings", rb_cTypeMap );
112
126
  rb_define_alloc_func( rb_cTypeMapAllStrings, pg_tmas_s_allocate );
113
127
 
114
- pg_typemap_all_strings = rb_funcall( rb_cTypeMapAllStrings, rb_intern("new"), 0 );
128
+ pg_typemap_all_strings = rb_obj_freeze( rb_funcall( rb_cTypeMapAllStrings, rb_intern("new"), 0 ));
115
129
  rb_gc_register_address( &pg_typemap_all_strings );
116
130
  }