pg 1.2.3 → 1.6.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +986 -0
- data/Gemfile +23 -0
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +300 -0
- data/README.md +327 -0
- data/Rakefile +123 -144
- data/certs/ged.pem +24 -0
- data/certs/kanis@comcard.de.pem +20 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/certs/larskanis-2024.pem +24 -0
- data/ext/errorcodes.def +16 -5
- data/ext/errorcodes.rb +0 -0
- data/ext/errorcodes.txt +5 -5
- data/ext/extconf.rb +259 -33
- data/ext/gvl_wrappers.c +17 -2
- data/ext/gvl_wrappers.h +56 -0
- data/ext/pg.c +89 -63
- data/ext/pg.h +31 -8
- data/ext/pg_binary_decoder.c +232 -1
- data/ext/pg_binary_encoder.c +428 -1
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +148 -36
- data/ext/pg_connection.c +1365 -817
- data/ext/pg_copy_coder.c +360 -38
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +56 -25
- data/ext/pg_result.c +187 -76
- data/ext/pg_text_decoder.c +32 -11
- data/ext/pg_text_encoder.c +65 -33
- data/ext/pg_tuple.c +84 -61
- data/ext/pg_type_map.c +44 -10
- data/ext/pg_type_map_all_strings.c +17 -3
- data/ext/pg_type_map_by_class.c +54 -27
- data/ext/pg_type_map_by_column.c +74 -31
- data/ext/pg_type_map_by_mri_type.c +48 -19
- data/ext/pg_type_map_by_oid.c +61 -27
- data/ext/pg_type_map_in_ruby.c +55 -21
- data/ext/pg_util.c +2 -2
- data/lib/pg/basic_type_map_based_on_result.rb +67 -0
- data/lib/pg/basic_type_map_for_queries.rb +206 -0
- data/lib/pg/basic_type_map_for_results.rb +104 -0
- data/lib/pg/basic_type_registry.rb +311 -0
- data/lib/pg/binary_decoder/date.rb +9 -0
- data/lib/pg/binary_decoder/timestamp.rb +26 -0
- data/lib/pg/binary_encoder/timestamp.rb +20 -0
- data/lib/pg/cancel_connection.rb +53 -0
- data/lib/pg/coder.rb +18 -14
- data/lib/pg/connection.rb +894 -91
- data/lib/pg/exceptions.rb +20 -1
- data/lib/pg/text_decoder/date.rb +21 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +17 -0
- data/lib/pg/text_decoder/numeric.rb +9 -0
- data/lib/pg/text_decoder/timestamp.rb +30 -0
- data/lib/pg/text_encoder/date.rb +13 -0
- data/lib/pg/text_encoder/inet.rb +31 -0
- data/lib/pg/text_encoder/json.rb +17 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +109 -39
- data/misc/openssl-pg-segfault.rb +31 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +21 -0
- data/misc/postgres/lib/postgres.rb +16 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +21 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
- data/misc/yugabyte/Dockerfile +9 -0
- data/misc/yugabyte/docker-compose.yml +28 -0
- data/misc/yugabyte/pg-test.rb +45 -0
- data/pg.gemspec +38 -0
- data/ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch +21 -0
- data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +102 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/async_mixed.rb +56 -0
- data/sample/check_conn.rb +21 -0
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/disk_usage_report.rb +177 -0
- data/sample/issue-119.rb +94 -0
- data/sample/losample.rb +69 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/notify_wait.rb +72 -0
- data/sample/pg_statistics.rb +285 -0
- data/sample/replication_monitor.rb +222 -0
- data/sample/test_binary_values.rb +33 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +311 -0
- data.tar.gz.sig +0 -0
- metadata +139 -213
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/ChangeLog +0 -0
- data/History.rdoc +0 -578
- data/Manifest.txt +0 -73
- data/README.ja.rdoc +0 -13
- data/README.rdoc +0 -213
- data/Rakefile.cross +0 -299
- data/lib/pg/basic_type_mapping.rb +0 -522
- data/lib/pg/binary_decoder.rb +0 -23
- data/lib/pg/constants.rb +0 -12
- data/lib/pg/text_decoder.rb +0 -46
- data/lib/pg/text_encoder.rb +0 -59
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -380
- data/spec/pg/basic_type_mapping_spec.rb +0 -630
- data/spec/pg/connection_spec.rb +0 -1949
- data/spec/pg/connection_sync_spec.rb +0 -41
- data/spec/pg/result_spec.rb +0 -681
- data/spec/pg/tuple_spec.rb +0 -333
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -226
- data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
- data/spec/pg/type_map_by_oid_spec.rb +0 -149
- data/spec/pg/type_map_in_ruby_spec.rb +0 -164
- data/spec/pg/type_map_spec.rb +0 -22
- data/spec/pg/type_spec.rb +0 -1123
- data/spec/pg_spec.rb +0 -50
data/ext/pg_coder.c
CHANGED
@@ -26,16 +26,16 @@ pg_coder_allocate( VALUE klass )
|
|
26
26
|
void
|
27
27
|
pg_coder_init_encoder( VALUE self )
|
28
28
|
{
|
29
|
-
t_pg_coder *this =
|
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 =
|
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
|
38
|
+
RB_OBJ_WRITE(self, &this->coder_obj, self);
|
39
39
|
this->oid = 0;
|
40
40
|
this->format = 0;
|
41
41
|
this->flags = 0;
|
@@ -45,52 +45,97 @@ pg_coder_init_encoder( VALUE self )
|
|
45
45
|
void
|
46
46
|
pg_coder_init_decoder( VALUE self )
|
47
47
|
{
|
48
|
-
t_pg_coder *this =
|
48
|
+
t_pg_coder *this = RTYPEDDATA_DATA( self );
|
49
49
|
VALUE klass = rb_class_of(self);
|
50
50
|
this->enc_func = NULL;
|
51
51
|
if( rb_const_defined( klass, s_id_CFUNC ) ){
|
52
52
|
VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
|
53
|
-
this->dec_func =
|
53
|
+
this->dec_func = RTYPEDDATA_DATA(cfunc);
|
54
54
|
} else {
|
55
55
|
this->dec_func = NULL;
|
56
56
|
}
|
57
|
-
this->coder_obj
|
57
|
+
RB_OBJ_WRITE(self, &this->coder_obj, self);
|
58
58
|
this->oid = 0;
|
59
59
|
this->format = 0;
|
60
60
|
this->flags = 0;
|
61
61
|
rb_iv_set( self, "@name", Qnil );
|
62
62
|
}
|
63
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
|
+
|
64
78
|
void
|
65
|
-
|
79
|
+
pg_coder_compact(void *_this)
|
66
80
|
{
|
67
|
-
|
81
|
+
t_pg_coder *this = (t_pg_coder *)_this;
|
82
|
+
pg_gc_location(this->coder_obj);
|
68
83
|
}
|
69
84
|
|
70
85
|
static void
|
71
|
-
|
86
|
+
pg_composite_coder_compact(void *_this)
|
72
87
|
{
|
73
|
-
|
88
|
+
t_pg_composite_coder *this = (t_pg_composite_coder *)_this;
|
89
|
+
pg_coder_compact(&this->comp);
|
74
90
|
}
|
75
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_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
|
+
|
76
107
|
static VALUE
|
77
108
|
pg_simple_encoder_allocate( VALUE klass )
|
78
109
|
{
|
79
110
|
t_pg_coder *this;
|
80
|
-
VALUE self =
|
111
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
|
81
112
|
pg_coder_init_encoder( self );
|
82
113
|
return self;
|
83
114
|
}
|
84
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_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
|
+
|
85
129
|
static VALUE
|
86
130
|
pg_composite_encoder_allocate( VALUE klass )
|
87
131
|
{
|
88
132
|
t_pg_composite_coder *this;
|
89
|
-
VALUE self =
|
133
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
|
90
134
|
pg_coder_init_encoder( self );
|
91
135
|
this->elem = NULL;
|
92
136
|
this->needs_quotation = 1;
|
93
137
|
this->delimiter = ',';
|
138
|
+
this->dimensions = -1;
|
94
139
|
rb_iv_set( self, "@elements_type", Qnil );
|
95
140
|
return self;
|
96
141
|
}
|
@@ -99,7 +144,7 @@ static VALUE
|
|
99
144
|
pg_simple_decoder_allocate( VALUE klass )
|
100
145
|
{
|
101
146
|
t_pg_coder *this;
|
102
|
-
VALUE self =
|
147
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
|
103
148
|
pg_coder_init_decoder( self );
|
104
149
|
return self;
|
105
150
|
}
|
@@ -108,11 +153,12 @@ static VALUE
|
|
108
153
|
pg_composite_decoder_allocate( VALUE klass )
|
109
154
|
{
|
110
155
|
t_pg_composite_coder *this;
|
111
|
-
VALUE self =
|
156
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
|
112
157
|
pg_coder_init_decoder( self );
|
113
158
|
this->elem = NULL;
|
114
159
|
this->needs_quotation = 1;
|
115
160
|
this->delimiter = ',';
|
161
|
+
this->dimensions = -1;
|
116
162
|
rb_iv_set( self, "@elements_type", Qnil );
|
117
163
|
return self;
|
118
164
|
}
|
@@ -131,11 +177,11 @@ static VALUE
|
|
131
177
|
pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
132
178
|
{
|
133
179
|
VALUE res;
|
134
|
-
VALUE intermediate;
|
180
|
+
VALUE intermediate = Qnil;
|
135
181
|
VALUE value;
|
136
182
|
int len, len2;
|
137
183
|
int enc_idx;
|
138
|
-
t_pg_coder *this =
|
184
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
139
185
|
|
140
186
|
if(argc < 1 || argc > 2){
|
141
187
|
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
|
@@ -169,8 +215,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
|
169
215
|
}
|
170
216
|
rb_str_set_len( res, len2 );
|
171
217
|
|
172
|
-
RB_GC_GUARD(intermediate);
|
173
|
-
|
174
218
|
return res;
|
175
219
|
}
|
176
220
|
|
@@ -192,7 +236,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
192
236
|
int tuple = -1;
|
193
237
|
int field = -1;
|
194
238
|
VALUE res;
|
195
|
-
t_pg_coder *this =
|
239
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
196
240
|
|
197
241
|
if(argc < 1 || argc > 3){
|
198
242
|
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
|
@@ -213,7 +257,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
213
257
|
rb_raise(rb_eRuntimeError, "no decoder function defined");
|
214
258
|
}
|
215
259
|
|
216
|
-
res = this->dec_func(this, val,
|
260
|
+
res = this->dec_func(this, val, RSTRING_LENINT(argv[0]), tuple, field, ENCODING_GET(argv[0]));
|
217
261
|
|
218
262
|
return res;
|
219
263
|
}
|
@@ -230,7 +274,8 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
230
274
|
static VALUE
|
231
275
|
pg_coder_oid_set(VALUE self, VALUE oid)
|
232
276
|
{
|
233
|
-
t_pg_coder *this =
|
277
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
278
|
+
rb_check_frozen(self);
|
234
279
|
this->oid = NUM2UINT(oid);
|
235
280
|
return oid;
|
236
281
|
}
|
@@ -245,7 +290,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
|
|
245
290
|
static VALUE
|
246
291
|
pg_coder_oid_get(VALUE self)
|
247
292
|
{
|
248
|
-
t_pg_coder *this =
|
293
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
249
294
|
return UINT2NUM(this->oid);
|
250
295
|
}
|
251
296
|
|
@@ -261,7 +306,8 @@ pg_coder_oid_get(VALUE self)
|
|
261
306
|
static VALUE
|
262
307
|
pg_coder_format_set(VALUE self, VALUE format)
|
263
308
|
{
|
264
|
-
t_pg_coder *this =
|
309
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
310
|
+
rb_check_frozen(self);
|
265
311
|
this->format = NUM2INT(format);
|
266
312
|
return format;
|
267
313
|
}
|
@@ -276,7 +322,7 @@ pg_coder_format_set(VALUE self, VALUE format)
|
|
276
322
|
static VALUE
|
277
323
|
pg_coder_format_get(VALUE self)
|
278
324
|
{
|
279
|
-
t_pg_coder *this =
|
325
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
280
326
|
return INT2NUM(this->format);
|
281
327
|
}
|
282
328
|
|
@@ -292,7 +338,8 @@ pg_coder_format_get(VALUE self)
|
|
292
338
|
static VALUE
|
293
339
|
pg_coder_flags_set(VALUE self, VALUE flags)
|
294
340
|
{
|
295
|
-
t_pg_coder *this =
|
341
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
342
|
+
rb_check_frozen(self);
|
296
343
|
this->flags = NUM2INT(flags);
|
297
344
|
return flags;
|
298
345
|
}
|
@@ -306,7 +353,7 @@ pg_coder_flags_set(VALUE self, VALUE flags)
|
|
306
353
|
static VALUE
|
307
354
|
pg_coder_flags_get(VALUE self)
|
308
355
|
{
|
309
|
-
t_pg_coder *this =
|
356
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
310
357
|
return INT2NUM(this->flags);
|
311
358
|
}
|
312
359
|
|
@@ -317,13 +364,15 @@ pg_coder_flags_get(VALUE self)
|
|
317
364
|
* Specifies whether the assigned #elements_type requires quotation marks to
|
318
365
|
* be transferred safely. Encoding with #needs_quotation=false is somewhat
|
319
366
|
* faster.
|
367
|
+
* It is only used by text coders and ignored by binary coders.
|
320
368
|
*
|
321
369
|
* The default is +true+. This option is ignored for decoding of values.
|
322
370
|
*/
|
323
371
|
static VALUE
|
324
372
|
pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
325
373
|
{
|
326
|
-
t_pg_composite_coder *this =
|
374
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
375
|
+
rb_check_frozen(self);
|
327
376
|
this->needs_quotation = RTEST(needs_quotation);
|
328
377
|
return needs_quotation;
|
329
378
|
}
|
@@ -338,7 +387,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
|
338
387
|
static VALUE
|
339
388
|
pg_coder_needs_quotation_get(VALUE self)
|
340
389
|
{
|
341
|
-
t_pg_composite_coder *this =
|
390
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
342
391
|
return this->needs_quotation ? Qtrue : Qfalse;
|
343
392
|
}
|
344
393
|
|
@@ -349,11 +398,13 @@ pg_coder_needs_quotation_get(VALUE self)
|
|
349
398
|
* Specifies the character that separates values within the composite type.
|
350
399
|
* The default is a comma.
|
351
400
|
* This must be a single one-byte character.
|
401
|
+
* It is only used by text coders and ignored by binary coders.
|
352
402
|
*/
|
353
403
|
static VALUE
|
354
404
|
pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
355
405
|
{
|
356
|
-
t_pg_composite_coder *this =
|
406
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
407
|
+
rb_check_frozen(self);
|
357
408
|
StringValue(delimiter);
|
358
409
|
if(RSTRING_LEN(delimiter) != 1)
|
359
410
|
rb_raise( rb_eArgError, "delimiter size must be one byte");
|
@@ -370,10 +421,53 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
|
370
421
|
static VALUE
|
371
422
|
pg_coder_delimiter_get(VALUE self)
|
372
423
|
{
|
373
|
-
t_pg_composite_coder *this =
|
424
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
374
425
|
return rb_str_new(&this->delimiter, 1);
|
375
426
|
}
|
376
427
|
|
428
|
+
/*
|
429
|
+
* call-seq:
|
430
|
+
* coder.dimensions = Integer
|
431
|
+
* coder.dimensions = nil
|
432
|
+
*
|
433
|
+
* Set number of array dimensions to be encoded.
|
434
|
+
*
|
435
|
+
* This property ensures, that this number of dimensions is always encoded.
|
436
|
+
* If less dimensions than this number are in the given value, an ArgumentError is raised.
|
437
|
+
* If more dimensions than this number are in the value, the Array value is passed to the next encoder.
|
438
|
+
*
|
439
|
+
* Setting dimensions is especially useful, when a Record shall be encoded into an Array, since the Array encoder can not distinguish if the array shall be encoded as a higher dimension or as a record otherwise.
|
440
|
+
*
|
441
|
+
* The default is +nil+.
|
442
|
+
*
|
443
|
+
* See #dimensions
|
444
|
+
*/
|
445
|
+
static VALUE
|
446
|
+
pg_coder_dimensions_set(VALUE self, VALUE dimensions)
|
447
|
+
{
|
448
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
449
|
+
rb_check_frozen(self);
|
450
|
+
if(!NIL_P(dimensions) && NUM2INT(dimensions) < 0)
|
451
|
+
rb_raise( rb_eArgError, "dimensions must be nil or >= 0");
|
452
|
+
this->dimensions = NIL_P(dimensions) ? -1 : NUM2INT(dimensions);
|
453
|
+
return dimensions;
|
454
|
+
}
|
455
|
+
|
456
|
+
/*
|
457
|
+
* call-seq:
|
458
|
+
* coder.dimensions -> Integer | nil
|
459
|
+
*
|
460
|
+
* Get number of enforced array dimensions or +nil+ if not set.
|
461
|
+
*
|
462
|
+
* See #dimensions=
|
463
|
+
*/
|
464
|
+
static VALUE
|
465
|
+
pg_coder_dimensions_get(VALUE self)
|
466
|
+
{
|
467
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
468
|
+
return this->dimensions < 0 ? Qnil : INT2NUM(this->dimensions);
|
469
|
+
}
|
470
|
+
|
377
471
|
/*
|
378
472
|
* call-seq:
|
379
473
|
* coder.elements_type = coder
|
@@ -386,12 +480,13 @@ pg_coder_delimiter_get(VALUE self)
|
|
386
480
|
static VALUE
|
387
481
|
pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
388
482
|
{
|
389
|
-
t_pg_composite_coder *this =
|
483
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA( self );
|
390
484
|
|
485
|
+
rb_check_frozen(self);
|
391
486
|
if ( NIL_P(elem_type) ){
|
392
487
|
this->elem = NULL;
|
393
488
|
} else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
|
394
|
-
this->elem =
|
489
|
+
this->elem = RTYPEDDATA_DATA( elem_type );
|
395
490
|
} else {
|
396
491
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
|
397
492
|
rb_obj_classname( elem_type ) );
|
@@ -401,10 +496,22 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
|
401
496
|
return elem_type;
|
402
497
|
}
|
403
498
|
|
404
|
-
|
499
|
+
static const rb_data_type_t pg_coder_cfunc_type = {
|
500
|
+
"PG::Coder::CFUNC",
|
501
|
+
{
|
502
|
+
(RUBY_DATA_FUNC)NULL,
|
503
|
+
(RUBY_DATA_FUNC)NULL,
|
504
|
+
(size_t (*)(const void *))NULL,
|
505
|
+
},
|
506
|
+
0,
|
507
|
+
0,
|
508
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
|
509
|
+
};
|
510
|
+
|
511
|
+
VALUE
|
405
512
|
pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
406
513
|
{
|
407
|
-
VALUE cfunc_obj =
|
514
|
+
VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
|
408
515
|
VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
|
409
516
|
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
|
410
517
|
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
|
@@ -414,9 +521,10 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
414
521
|
if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
|
415
522
|
rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
|
416
523
|
|
417
|
-
rb_define_const( coder_klass, "CFUNC", cfunc_obj );
|
524
|
+
rb_define_const( coder_klass, "CFUNC", rb_obj_freeze(cfunc_obj) );
|
418
525
|
|
419
526
|
RB_GC_GUARD(cfunc_obj);
|
527
|
+
return coder_klass;
|
420
528
|
}
|
421
529
|
|
422
530
|
|
@@ -483,7 +591,7 @@ pg_coder_dec_func(t_pg_coder *this, int binary)
|
|
483
591
|
|
484
592
|
|
485
593
|
void
|
486
|
-
init_pg_coder()
|
594
|
+
init_pg_coder(void)
|
487
595
|
{
|
488
596
|
s_id_encode = rb_intern("encode");
|
489
597
|
s_id_decode = rb_intern("decode");
|
@@ -541,6 +649,8 @@ init_pg_coder()
|
|
541
649
|
*
|
542
650
|
* This is the base class for all type cast classes of PostgreSQL types,
|
543
651
|
* that are made up of some sub type.
|
652
|
+
*
|
653
|
+
* See PG::TextEncoder::Array, PG::TextDecoder::Array, PG::BinaryEncoder::Array, PG::BinaryDecoder::Array, etc.
|
544
654
|
*/
|
545
655
|
rb_cPG_CompositeCoder = rb_define_class_under( rb_mPG, "CompositeCoder", rb_cPG_Coder );
|
546
656
|
rb_define_method( rb_cPG_CompositeCoder, "elements_type=", pg_coder_elements_type_set, 1 );
|
@@ -549,6 +659,8 @@ init_pg_coder()
|
|
549
659
|
rb_define_method( rb_cPG_CompositeCoder, "needs_quotation?", pg_coder_needs_quotation_get, 0 );
|
550
660
|
rb_define_method( rb_cPG_CompositeCoder, "delimiter=", pg_coder_delimiter_set, 1 );
|
551
661
|
rb_define_method( rb_cPG_CompositeCoder, "delimiter", pg_coder_delimiter_get, 0 );
|
662
|
+
rb_define_method( rb_cPG_CompositeCoder, "dimensions=", pg_coder_dimensions_set, 1 );
|
663
|
+
rb_define_method( rb_cPG_CompositeCoder, "dimensions", pg_coder_dimensions_get, 0 );
|
552
664
|
|
553
665
|
/* Document-class: PG::CompositeEncoder < PG::CompositeCoder */
|
554
666
|
rb_cPG_CompositeEncoder = rb_define_class_under( rb_mPG, "CompositeEncoder", rb_cPG_CompositeCoder );
|