pg 1.0.0 → 1.5.9

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 (126) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Gemfile +20 -0
  4. data/History.md +932 -0
  5. data/Manifest.txt +8 -3
  6. data/README-Windows.rdoc +4 -4
  7. data/README.ja.md +300 -0
  8. data/README.md +286 -0
  9. data/Rakefile +41 -138
  10. data/Rakefile.cross +71 -66
  11. data/certs/ged.pem +24 -0
  12. data/certs/kanis@comcard.de.pem +20 -0
  13. data/certs/larskanis-2022.pem +26 -0
  14. data/certs/larskanis-2023.pem +24 -0
  15. data/certs/larskanis-2024.pem +24 -0
  16. data/ext/errorcodes.def +84 -5
  17. data/ext/errorcodes.rb +1 -1
  18. data/ext/errorcodes.txt +23 -6
  19. data/ext/extconf.rb +109 -25
  20. data/ext/gvl_wrappers.c +4 -0
  21. data/ext/gvl_wrappers.h +23 -0
  22. data/ext/pg.c +213 -155
  23. data/ext/pg.h +89 -23
  24. data/ext/pg_binary_decoder.c +164 -16
  25. data/ext/pg_binary_encoder.c +238 -13
  26. data/ext/pg_coder.c +159 -35
  27. data/ext/pg_connection.c +1584 -967
  28. data/ext/pg_copy_coder.c +373 -43
  29. data/ext/pg_errors.c +1 -1
  30. data/ext/pg_record_coder.c +522 -0
  31. data/ext/pg_result.c +710 -217
  32. data/ext/pg_text_decoder.c +630 -43
  33. data/ext/pg_text_encoder.c +222 -72
  34. data/ext/pg_tuple.c +572 -0
  35. data/ext/pg_type_map.c +45 -11
  36. data/ext/pg_type_map_all_strings.c +21 -7
  37. data/ext/pg_type_map_by_class.c +59 -27
  38. data/ext/pg_type_map_by_column.c +80 -37
  39. data/ext/pg_type_map_by_mri_type.c +49 -20
  40. data/ext/pg_type_map_by_oid.c +62 -29
  41. data/ext/pg_type_map_in_ruby.c +56 -22
  42. data/ext/{util.c → pg_util.c} +12 -12
  43. data/ext/{util.h → pg_util.h} +2 -2
  44. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  45. data/lib/pg/basic_type_map_for_queries.rb +202 -0
  46. data/lib/pg/basic_type_map_for_results.rb +104 -0
  47. data/lib/pg/basic_type_registry.rb +311 -0
  48. data/lib/pg/binary_decoder/date.rb +9 -0
  49. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  50. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  51. data/lib/pg/coder.rb +36 -13
  52. data/lib/pg/connection.rb +769 -70
  53. data/lib/pg/exceptions.rb +22 -2
  54. data/lib/pg/result.rb +14 -2
  55. data/lib/pg/text_decoder/date.rb +21 -0
  56. data/lib/pg/text_decoder/inet.rb +9 -0
  57. data/lib/pg/text_decoder/json.rb +17 -0
  58. data/lib/pg/text_decoder/numeric.rb +9 -0
  59. data/lib/pg/text_decoder/timestamp.rb +30 -0
  60. data/lib/pg/text_encoder/date.rb +13 -0
  61. data/lib/pg/text_encoder/inet.rb +31 -0
  62. data/lib/pg/text_encoder/json.rb +17 -0
  63. data/lib/pg/text_encoder/numeric.rb +9 -0
  64. data/lib/pg/text_encoder/timestamp.rb +24 -0
  65. data/lib/pg/tuple.rb +30 -0
  66. data/lib/pg/type_map_by_column.rb +3 -2
  67. data/lib/pg/version.rb +4 -0
  68. data/lib/pg.rb +106 -39
  69. data/misc/openssl-pg-segfault.rb +31 -0
  70. data/misc/postgres/History.txt +9 -0
  71. data/misc/postgres/Manifest.txt +5 -0
  72. data/misc/postgres/README.txt +21 -0
  73. data/misc/postgres/Rakefile +21 -0
  74. data/misc/postgres/lib/postgres.rb +16 -0
  75. data/misc/ruby-pg/History.txt +9 -0
  76. data/misc/ruby-pg/Manifest.txt +5 -0
  77. data/misc/ruby-pg/README.txt +21 -0
  78. data/misc/ruby-pg/Rakefile +21 -0
  79. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  80. data/pg.gemspec +36 -0
  81. data/rakelib/task_extension.rb +46 -0
  82. data/sample/array_insert.rb +20 -0
  83. data/sample/async_api.rb +102 -0
  84. data/sample/async_copyto.rb +39 -0
  85. data/sample/async_mixed.rb +56 -0
  86. data/sample/check_conn.rb +21 -0
  87. data/sample/copydata.rb +71 -0
  88. data/sample/copyfrom.rb +81 -0
  89. data/sample/copyto.rb +19 -0
  90. data/sample/cursor.rb +21 -0
  91. data/sample/disk_usage_report.rb +177 -0
  92. data/sample/issue-119.rb +94 -0
  93. data/sample/losample.rb +69 -0
  94. data/sample/minimal-testcase.rb +17 -0
  95. data/sample/notify_wait.rb +72 -0
  96. data/sample/pg_statistics.rb +285 -0
  97. data/sample/replication_monitor.rb +222 -0
  98. data/sample/test_binary_values.rb +33 -0
  99. data/sample/wal_shipper.rb +434 -0
  100. data/sample/warehouse_partitions.rb +311 -0
  101. data.tar.gz.sig +0 -0
  102. metadata +138 -223
  103. metadata.gz.sig +0 -0
  104. data/.gemtest +0 -0
  105. data/ChangeLog +0 -6595
  106. data/History.rdoc +0 -422
  107. data/README.ja.rdoc +0 -14
  108. data/README.rdoc +0 -167
  109. data/lib/pg/basic_type_mapping.rb +0 -426
  110. data/lib/pg/constants.rb +0 -11
  111. data/lib/pg/text_decoder.rb +0 -51
  112. data/lib/pg/text_encoder.rb +0 -35
  113. data/spec/data/expected_trace.out +0 -26
  114. data/spec/data/random_binary_data +0 -0
  115. data/spec/helpers.rb +0 -348
  116. data/spec/pg/basic_type_mapping_spec.rb +0 -305
  117. data/spec/pg/connection_spec.rb +0 -1719
  118. data/spec/pg/result_spec.rb +0 -456
  119. data/spec/pg/type_map_by_class_spec.rb +0 -138
  120. data/spec/pg/type_map_by_column_spec.rb +0 -222
  121. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  122. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  123. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  124. data/spec/pg/type_map_spec.rb +0 -22
  125. data/spec/pg/type_spec.rb +0 -777
  126. data/spec/pg_spec.rb +0 -50
data/ext/pg_coder.c CHANGED
@@ -26,53 +26,111 @@ pg_coder_allocate( VALUE klass )
26
26
  void
27
27
  pg_coder_init_encoder( VALUE self )
28
28
  {
29
- t_pg_coder *this = DATA_PTR( self );
29
+ t_pg_coder *this = RTYPEDDATA_DATA( self );
30
30
  VALUE klass = rb_class_of(self);
31
31
  if( rb_const_defined( klass, s_id_CFUNC ) ){
32
32
  VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
33
- this->enc_func = DATA_PTR(cfunc);
33
+ this->enc_func = RTYPEDDATA_DATA(cfunc);
34
34
  } else {
35
35
  this->enc_func = NULL;
36
36
  }
37
37
  this->dec_func = NULL;
38
- this->coder_obj = self;
38
+ RB_OBJ_WRITE(self, &this->coder_obj, self);
39
39
  this->oid = 0;
40
40
  this->format = 0;
41
+ this->flags = 0;
41
42
  rb_iv_set( self, "@name", Qnil );
42
43
  }
43
44
 
44
45
  void
45
46
  pg_coder_init_decoder( VALUE self )
46
47
  {
47
- t_pg_coder *this = DATA_PTR( self );
48
+ t_pg_coder *this = RTYPEDDATA_DATA( self );
48
49
  VALUE klass = rb_class_of(self);
49
50
  this->enc_func = NULL;
50
51
  if( rb_const_defined( klass, s_id_CFUNC ) ){
51
52
  VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
52
- this->dec_func = DATA_PTR(cfunc);
53
+ this->dec_func = RTYPEDDATA_DATA(cfunc);
53
54
  } else {
54
55
  this->dec_func = NULL;
55
56
  }
56
- this->coder_obj = self;
57
+ RB_OBJ_WRITE(self, &this->coder_obj, self);
57
58
  this->oid = 0;
58
59
  this->format = 0;
60
+ this->flags = 0;
59
61
  rb_iv_set( self, "@name", Qnil );
60
62
  }
61
63
 
64
+ static size_t
65
+ pg_coder_memsize(const void *_this)
66
+ {
67
+ const t_pg_coder *this = (const t_pg_coder *)_this;
68
+ return sizeof(*this);
69
+ }
70
+
71
+ static size_t
72
+ pg_composite_coder_memsize(const void *_this)
73
+ {
74
+ const t_pg_composite_coder *this = (const t_pg_composite_coder *)_this;
75
+ return sizeof(*this);
76
+ }
77
+
78
+ void
79
+ pg_coder_compact(void *_this)
80
+ {
81
+ t_pg_coder *this = (t_pg_coder *)_this;
82
+ pg_gc_location(this->coder_obj);
83
+ }
84
+
85
+ static void
86
+ pg_composite_coder_compact(void *_this)
87
+ {
88
+ t_pg_composite_coder *this = (t_pg_composite_coder *)_this;
89
+ pg_coder_compact(&this->comp);
90
+ }
91
+
92
+ const rb_data_type_t pg_coder_type = {
93
+ "PG::Coder",
94
+ {
95
+ (RUBY_DATA_FUNC) NULL,
96
+ RUBY_TYPED_DEFAULT_FREE,
97
+ pg_coder_memsize,
98
+ pg_compact_callback(pg_coder_compact),
99
+ },
100
+ 0,
101
+ 0,
102
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
103
+ // macro to update VALUE references, as to trigger write barriers.
104
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
105
+ };
106
+
62
107
  static VALUE
63
108
  pg_simple_encoder_allocate( VALUE klass )
64
109
  {
65
110
  t_pg_coder *this;
66
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
111
+ VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
67
112
  pg_coder_init_encoder( self );
68
113
  return self;
69
114
  }
70
115
 
116
+ static const rb_data_type_t pg_composite_coder_type = {
117
+ "PG::CompositeCoder",
118
+ {
119
+ (RUBY_DATA_FUNC) NULL,
120
+ RUBY_TYPED_DEFAULT_FREE,
121
+ pg_composite_coder_memsize,
122
+ pg_compact_callback(pg_composite_coder_compact),
123
+ },
124
+ &pg_coder_type,
125
+ 0,
126
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
127
+ };
128
+
71
129
  static VALUE
72
130
  pg_composite_encoder_allocate( VALUE klass )
73
131
  {
74
132
  t_pg_composite_coder *this;
75
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
133
+ VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
76
134
  pg_coder_init_encoder( self );
77
135
  this->elem = NULL;
78
136
  this->needs_quotation = 1;
@@ -85,7 +143,7 @@ static VALUE
85
143
  pg_simple_decoder_allocate( VALUE klass )
86
144
  {
87
145
  t_pg_coder *this;
88
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
146
+ VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
89
147
  pg_coder_init_decoder( self );
90
148
  return self;
91
149
  }
@@ -94,7 +152,7 @@ static VALUE
94
152
  pg_composite_decoder_allocate( VALUE klass )
95
153
  {
96
154
  t_pg_composite_coder *this;
97
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
155
+ VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
98
156
  pg_coder_init_decoder( self );
99
157
  this->elem = NULL;
100
158
  this->needs_quotation = 1;
@@ -121,7 +179,7 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
121
179
  VALUE value;
122
180
  int len, len2;
123
181
  int enc_idx;
124
- t_pg_coder *this = DATA_PTR(self);
182
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
125
183
 
126
184
  if(argc < 1 || argc > 2){
127
185
  rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
@@ -143,7 +201,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
143
201
 
144
202
  if( len == -1 ){
145
203
  /* The intermediate value is a String that can be used directly. */
146
- OBJ_INFECT(intermediate, value);
147
204
  return intermediate;
148
205
  }
149
206
 
@@ -155,7 +212,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
155
212
  rb_obj_classname( self ), len, len2 );
156
213
  }
157
214
  rb_str_set_len( res, len2 );
158
- OBJ_INFECT(res, value);
159
215
 
160
216
  RB_GC_GUARD(intermediate);
161
217
 
@@ -180,7 +236,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
180
236
  int tuple = -1;
181
237
  int field = -1;
182
238
  VALUE res;
183
- t_pg_coder *this = DATA_PTR(self);
239
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
184
240
 
185
241
  if(argc < 1 || argc > 3){
186
242
  rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
@@ -192,13 +248,16 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
192
248
  if( NIL_P(argv[0]) )
193
249
  return Qnil;
194
250
 
195
- val = StringValuePtr(argv[0]);
251
+ if( this->format == 0 ){
252
+ val = StringValueCStr(argv[0]);
253
+ }else{
254
+ val = StringValuePtr(argv[0]);
255
+ }
196
256
  if( !this->dec_func ){
197
257
  rb_raise(rb_eRuntimeError, "no decoder function defined");
198
258
  }
199
259
 
200
- res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
201
- OBJ_INFECT(res, argv[0]);
260
+ res = this->dec_func(this, val, RSTRING_LENINT(argv[0]), tuple, field, ENCODING_GET(argv[0]));
202
261
 
203
262
  return res;
204
263
  }
@@ -215,7 +274,8 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
215
274
  static VALUE
216
275
  pg_coder_oid_set(VALUE self, VALUE oid)
217
276
  {
218
- t_pg_coder *this = DATA_PTR(self);
277
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
278
+ rb_check_frozen(self);
219
279
  this->oid = NUM2UINT(oid);
220
280
  return oid;
221
281
  }
@@ -230,7 +290,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
230
290
  static VALUE
231
291
  pg_coder_oid_get(VALUE self)
232
292
  {
233
- t_pg_coder *this = DATA_PTR(self);
293
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
234
294
  return UINT2NUM(this->oid);
235
295
  }
236
296
 
@@ -246,7 +306,8 @@ pg_coder_oid_get(VALUE self)
246
306
  static VALUE
247
307
  pg_coder_format_set(VALUE self, VALUE format)
248
308
  {
249
- t_pg_coder *this = DATA_PTR(self);
309
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
310
+ rb_check_frozen(self);
250
311
  this->format = NUM2INT(format);
251
312
  return format;
252
313
  }
@@ -261,10 +322,41 @@ pg_coder_format_set(VALUE self, VALUE format)
261
322
  static VALUE
262
323
  pg_coder_format_get(VALUE self)
263
324
  {
264
- t_pg_coder *this = DATA_PTR(self);
325
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
265
326
  return INT2NUM(this->format);
266
327
  }
267
328
 
329
+ /*
330
+ * call-seq:
331
+ * coder.flags = Integer
332
+ *
333
+ * Set coder specific bitwise OR-ed flags.
334
+ * See the particular en- or decoder description for available flags.
335
+ *
336
+ * The default is +0+.
337
+ */
338
+ static VALUE
339
+ pg_coder_flags_set(VALUE self, VALUE flags)
340
+ {
341
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
342
+ rb_check_frozen(self);
343
+ this->flags = NUM2INT(flags);
344
+ return flags;
345
+ }
346
+
347
+ /*
348
+ * call-seq:
349
+ * coder.flags -> Integer
350
+ *
351
+ * Get current bitwise OR-ed coder flags.
352
+ */
353
+ static VALUE
354
+ pg_coder_flags_get(VALUE self)
355
+ {
356
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
357
+ return INT2NUM(this->flags);
358
+ }
359
+
268
360
  /*
269
361
  * call-seq:
270
362
  * coder.needs_quotation = Boolean
@@ -278,7 +370,8 @@ pg_coder_format_get(VALUE self)
278
370
  static VALUE
279
371
  pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
280
372
  {
281
- t_pg_composite_coder *this = DATA_PTR(self);
373
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
374
+ rb_check_frozen(self);
282
375
  this->needs_quotation = RTEST(needs_quotation);
283
376
  return needs_quotation;
284
377
  }
@@ -293,7 +386,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
293
386
  static VALUE
294
387
  pg_coder_needs_quotation_get(VALUE self)
295
388
  {
296
- t_pg_composite_coder *this = DATA_PTR(self);
389
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
297
390
  return this->needs_quotation ? Qtrue : Qfalse;
298
391
  }
299
392
 
@@ -308,7 +401,8 @@ pg_coder_needs_quotation_get(VALUE self)
308
401
  static VALUE
309
402
  pg_coder_delimiter_set(VALUE self, VALUE delimiter)
310
403
  {
311
- t_pg_composite_coder *this = DATA_PTR(self);
404
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
405
+ rb_check_frozen(self);
312
406
  StringValue(delimiter);
313
407
  if(RSTRING_LEN(delimiter) != 1)
314
408
  rb_raise( rb_eArgError, "delimiter size must be one byte");
@@ -325,7 +419,7 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
325
419
  static VALUE
326
420
  pg_coder_delimiter_get(VALUE self)
327
421
  {
328
- t_pg_composite_coder *this = DATA_PTR(self);
422
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
329
423
  return rb_str_new(&this->delimiter, 1);
330
424
  }
331
425
 
@@ -341,12 +435,13 @@ pg_coder_delimiter_get(VALUE self)
341
435
  static VALUE
342
436
  pg_coder_elements_type_set(VALUE self, VALUE elem_type)
343
437
  {
344
- t_pg_composite_coder *this = DATA_PTR( self );
438
+ t_pg_composite_coder *this = RTYPEDDATA_DATA( self );
345
439
 
440
+ rb_check_frozen(self);
346
441
  if ( NIL_P(elem_type) ){
347
442
  this->elem = NULL;
348
443
  } else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
349
- this->elem = DATA_PTR( elem_type );
444
+ this->elem = RTYPEDDATA_DATA( elem_type );
350
445
  } else {
351
446
  rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
352
447
  rb_obj_classname( elem_type ) );
@@ -356,17 +451,35 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
356
451
  return elem_type;
357
452
  }
358
453
 
359
- void
454
+ static const rb_data_type_t pg_coder_cfunc_type = {
455
+ "PG::Coder::CFUNC",
456
+ {
457
+ (RUBY_DATA_FUNC)NULL,
458
+ (RUBY_DATA_FUNC)NULL,
459
+ (size_t (*)(const void *))NULL,
460
+ },
461
+ 0,
462
+ 0,
463
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
464
+ };
465
+
466
+ VALUE
360
467
  pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
361
468
  {
362
- VALUE cfunc_obj = Data_Wrap_Struct( rb_cObject, NULL, NULL, func );
469
+ VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
363
470
  VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
364
471
  if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
365
472
  rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
366
473
 
367
- rb_define_const( coder_klass, "CFUNC", cfunc_obj );
474
+ if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
475
+ rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
476
+ if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
477
+ rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
478
+
479
+ rb_define_const( coder_klass, "CFUNC", rb_obj_freeze(cfunc_obj) );
368
480
 
369
481
  RB_GC_GUARD(cfunc_obj);
482
+ return coder_klass;
370
483
  }
371
484
 
372
485
 
@@ -403,14 +516,14 @@ pg_coder_enc_func(t_pg_coder *this)
403
516
  }
404
517
 
405
518
  static VALUE
406
- pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
519
+ pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
407
520
  {
408
521
  VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
409
522
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
410
523
  }
411
524
 
412
525
  static VALUE
413
- pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
526
+ pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
414
527
  {
415
528
  VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
416
529
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
@@ -433,7 +546,7 @@ pg_coder_dec_func(t_pg_coder *this, int binary)
433
546
 
434
547
 
435
548
  void
436
- init_pg_coder()
549
+ init_pg_coder(void)
437
550
  {
438
551
  s_id_encode = rb_intern("encode");
439
552
  s_id_decode = rb_intern("decode");
@@ -457,14 +570,25 @@ init_pg_coder()
457
570
  rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
458
571
  rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
459
572
  rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
573
+ rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
574
+ rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
575
+
576
+ /* define flags to be used with PG::Coder#flags= */
577
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
578
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
579
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
580
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
581
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
582
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
583
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
584
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
585
+
460
586
  /*
461
587
  * Name of the coder or the corresponding data type.
462
588
  *
463
589
  * This accessor is only used in PG::Coder#inspect .
464
590
  */
465
591
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
466
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
467
- rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
468
592
 
469
593
  /* Document-class: PG::SimpleCoder < PG::Coder */
470
594
  rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );