pg 1.1.4 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
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 +137 -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 +876 -0
  16. data/Manifest.txt +3 -3
  17. data/README-Windows.rdoc +4 -4
  18. data/README.ja.md +276 -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 +76 -0
  26. data/ext/errorcodes.rb +0 -0
  27. data/ext/errorcodes.txt +21 -2
  28. data/ext/extconf.rb +101 -26
  29. data/ext/gvl_wrappers.c +4 -0
  30. data/ext/gvl_wrappers.h +23 -0
  31. data/ext/pg.c +203 -151
  32. data/ext/pg.h +48 -21
  33. data/ext/pg_binary_decoder.c +89 -10
  34. data/ext/pg_binary_encoder.c +238 -13
  35. data/ext/pg_coder.c +109 -34
  36. data/ext/pg_connection.c +1365 -976
  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 +436 -171
  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 +910 -0
  110. data/translation/po/ja.po +1047 -0
  111. data/translation/po4a.cfg +12 -0
  112. data.tar.gz.sig +0 -0
  113. metadata +151 -218
  114. metadata.gz.sig +0 -0
  115. data/ChangeLog +0 -6595
  116. data/History.rdoc +0 -492
  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 -380
  127. data/spec/pg/basic_type_mapping_spec.rb +0 -508
  128. data/spec/pg/connection_spec.rb +0 -1872
  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
  }