pg 0.18.2 → 1.4.5
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.appveyor.yml +36 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +86 -0
- data/.github/workflows/source-gem.yml +131 -0
- data/.gitignore +13 -0
- data/.hgsigs +34 -0
- data/.hgtags +41 -0
- data/.irbrc +23 -0
- data/.pryrc +23 -0
- data/.tm_properties +21 -0
- data/.travis.yml +49 -0
- data/BSDL +2 -2
- data/Gemfile +14 -0
- data/History.rdoc +480 -4
- data/Manifest.txt +8 -21
- data/README-Windows.rdoc +17 -28
- data/README.ja.rdoc +1 -2
- data/README.rdoc +92 -20
- data/Rakefile +33 -133
- data/Rakefile.cross +89 -67
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/ext/errorcodes.def +113 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +36 -2
- data/ext/extconf.rb +120 -54
- data/ext/gvl_wrappers.c +8 -0
- data/ext/gvl_wrappers.h +44 -33
- data/ext/pg.c +216 -172
- data/ext/pg.h +93 -98
- data/ext/pg_binary_decoder.c +85 -16
- data/ext/pg_binary_encoder.c +25 -22
- data/ext/pg_coder.c +176 -40
- data/ext/pg_connection.c +1735 -1138
- data/ext/pg_copy_coder.c +95 -28
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +521 -0
- data/ext/pg_result.c +642 -221
- data/ext/pg_text_decoder.c +609 -41
- data/ext/pg_text_encoder.c +254 -100
- data/ext/pg_tuple.c +569 -0
- data/ext/pg_type_map.c +62 -22
- data/ext/pg_type_map_all_strings.c +20 -6
- data/ext/pg_type_map_by_class.c +55 -25
- data/ext/pg_type_map_by_column.c +81 -42
- data/ext/pg_type_map_by_mri_type.c +49 -20
- data/ext/pg_type_map_by_oid.c +56 -26
- data/ext/pg_type_map_in_ruby.c +52 -21
- data/ext/{util.c → pg_util.c} +12 -12
- data/ext/{util.h → pg_util.h} +2 -2
- data/lib/pg/basic_type_map_based_on_result.rb +47 -0
- data/lib/pg/basic_type_map_for_queries.rb +193 -0
- data/lib/pg/basic_type_map_for_results.rb +81 -0
- data/lib/pg/basic_type_registry.rb +301 -0
- data/lib/pg/binary_decoder.rb +23 -0
- data/lib/pg/coder.rb +24 -3
- data/lib/pg/connection.rb +711 -64
- data/lib/pg/constants.rb +2 -1
- data/lib/pg/exceptions.rb +9 -2
- data/lib/pg/result.rb +24 -7
- data/lib/pg/text_decoder.rb +27 -23
- data/lib/pg/text_encoder.rb +40 -8
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +3 -2
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +61 -36
- 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/pg.gemspec +32 -0
- data/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +1 -1
- data/sample/async_api.rb +4 -8
- data/sample/async_copyto.rb +1 -1
- data/sample/async_mixed.rb +1 -1
- data/sample/check_conn.rb +1 -1
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +1 -1
- data/sample/copyto.rb +1 -1
- data/sample/cursor.rb +1 -1
- data/sample/disk_usage_report.rb +6 -15
- data/sample/issue-119.rb +2 -2
- data/sample/losample.rb +1 -1
- data/sample/minimal-testcase.rb +2 -2
- data/sample/notify_wait.rb +1 -1
- data/sample/pg_statistics.rb +6 -15
- data/sample/replication_monitor.rb +9 -18
- data/sample/test_binary_values.rb +1 -1
- data/sample/wal_shipper.rb +2 -2
- data/sample/warehouse_partitions.rb +8 -17
- data.tar.gz.sig +0 -0
- metadata +74 -216
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -5545
- data/lib/pg/basic_type_mapping.rb +0 -399
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -355
- data/spec/pg/basic_type_mapping_spec.rb +0 -251
- data/spec/pg/connection_spec.rb +0 -1535
- data/spec/pg/result_spec.rb +0 -449
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -222
- 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 -688
- data/spec/pg_spec.rb +0 -50
data/ext/pg_coder.c
CHANGED
|
@@ -26,11 +26,11 @@ 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
|
}
|
|
@@ -38,41 +38,97 @@ pg_coder_init_encoder( VALUE self )
|
|
|
38
38
|
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 =
|
|
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 =
|
|
53
|
+
this->dec_func = RTYPEDDATA_DATA(cfunc);
|
|
53
54
|
} else {
|
|
54
55
|
this->dec_func = NULL;
|
|
55
56
|
}
|
|
56
57
|
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
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
103
|
+
};
|
|
104
|
+
|
|
62
105
|
static VALUE
|
|
63
106
|
pg_simple_encoder_allocate( VALUE klass )
|
|
64
107
|
{
|
|
65
108
|
t_pg_coder *this;
|
|
66
|
-
VALUE self =
|
|
109
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
|
|
67
110
|
pg_coder_init_encoder( self );
|
|
68
111
|
return self;
|
|
69
112
|
}
|
|
70
113
|
|
|
114
|
+
static const rb_data_type_t pg_composite_coder_type = {
|
|
115
|
+
"PG::CompositeCoder",
|
|
116
|
+
{
|
|
117
|
+
(RUBY_DATA_FUNC) NULL,
|
|
118
|
+
RUBY_TYPED_DEFAULT_FREE,
|
|
119
|
+
pg_composite_coder_memsize,
|
|
120
|
+
pg_compact_callback(pg_composite_coder_compact),
|
|
121
|
+
},
|
|
122
|
+
&pg_coder_type,
|
|
123
|
+
0,
|
|
124
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
125
|
+
};
|
|
126
|
+
|
|
71
127
|
static VALUE
|
|
72
128
|
pg_composite_encoder_allocate( VALUE klass )
|
|
73
129
|
{
|
|
74
130
|
t_pg_composite_coder *this;
|
|
75
|
-
VALUE self =
|
|
131
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
|
|
76
132
|
pg_coder_init_encoder( self );
|
|
77
133
|
this->elem = NULL;
|
|
78
134
|
this->needs_quotation = 1;
|
|
@@ -85,7 +141,7 @@ static VALUE
|
|
|
85
141
|
pg_simple_decoder_allocate( VALUE klass )
|
|
86
142
|
{
|
|
87
143
|
t_pg_coder *this;
|
|
88
|
-
VALUE self =
|
|
144
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
|
|
89
145
|
pg_coder_init_decoder( self );
|
|
90
146
|
return self;
|
|
91
147
|
}
|
|
@@ -94,7 +150,7 @@ static VALUE
|
|
|
94
150
|
pg_composite_decoder_allocate( VALUE klass )
|
|
95
151
|
{
|
|
96
152
|
t_pg_composite_coder *this;
|
|
97
|
-
VALUE self =
|
|
153
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
|
|
98
154
|
pg_coder_init_decoder( self );
|
|
99
155
|
this->elem = NULL;
|
|
100
156
|
this->needs_quotation = 1;
|
|
@@ -105,7 +161,7 @@ pg_composite_decoder_allocate( VALUE klass )
|
|
|
105
161
|
|
|
106
162
|
/*
|
|
107
163
|
* call-seq:
|
|
108
|
-
* coder.encode( value )
|
|
164
|
+
* coder.encode( value [, encoding] )
|
|
109
165
|
*
|
|
110
166
|
* Encodes the given Ruby object into string representation, without
|
|
111
167
|
* sending data to/from the database server.
|
|
@@ -114,12 +170,23 @@ pg_composite_decoder_allocate( VALUE klass )
|
|
|
114
170
|
*
|
|
115
171
|
*/
|
|
116
172
|
static VALUE
|
|
117
|
-
pg_coder_encode(VALUE
|
|
173
|
+
pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
|
118
174
|
{
|
|
119
175
|
VALUE res;
|
|
120
176
|
VALUE intermediate;
|
|
177
|
+
VALUE value;
|
|
121
178
|
int len, len2;
|
|
122
|
-
|
|
179
|
+
int enc_idx;
|
|
180
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
181
|
+
|
|
182
|
+
if(argc < 1 || argc > 2){
|
|
183
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
|
|
184
|
+
}else if(argc == 1){
|
|
185
|
+
enc_idx = rb_ascii8bit_encindex();
|
|
186
|
+
}else{
|
|
187
|
+
enc_idx = rb_to_encoding_index(argv[1]);
|
|
188
|
+
}
|
|
189
|
+
value = argv[0];
|
|
123
190
|
|
|
124
191
|
if( NIL_P(value) )
|
|
125
192
|
return Qnil;
|
|
@@ -128,22 +195,21 @@ pg_coder_encode(VALUE self, VALUE value)
|
|
|
128
195
|
rb_raise(rb_eRuntimeError, "no encoder function defined");
|
|
129
196
|
}
|
|
130
197
|
|
|
131
|
-
len = this->enc_func( this, value, NULL, &intermediate );
|
|
198
|
+
len = this->enc_func( this, value, NULL, &intermediate, enc_idx );
|
|
132
199
|
|
|
133
200
|
if( len == -1 ){
|
|
134
201
|
/* The intermediate value is a String that can be used directly. */
|
|
135
|
-
OBJ_INFECT(intermediate, value);
|
|
136
202
|
return intermediate;
|
|
137
203
|
}
|
|
138
204
|
|
|
139
205
|
res = rb_str_new(NULL, len);
|
|
140
|
-
|
|
206
|
+
PG_ENCODING_SET_NOCHECK(res, enc_idx);
|
|
207
|
+
len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
|
|
141
208
|
if( len < len2 ){
|
|
142
209
|
rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
|
|
143
210
|
rb_obj_classname( self ), len, len2 );
|
|
144
211
|
}
|
|
145
212
|
rb_str_set_len( res, len2 );
|
|
146
|
-
OBJ_INFECT(res, value);
|
|
147
213
|
|
|
148
214
|
RB_GC_GUARD(intermediate);
|
|
149
215
|
|
|
@@ -165,10 +231,10 @@ static VALUE
|
|
|
165
231
|
pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
166
232
|
{
|
|
167
233
|
char *val;
|
|
168
|
-
|
|
169
|
-
|
|
234
|
+
int tuple = -1;
|
|
235
|
+
int field = -1;
|
|
170
236
|
VALUE res;
|
|
171
|
-
t_pg_coder *this =
|
|
237
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
172
238
|
|
|
173
239
|
if(argc < 1 || argc > 3){
|
|
174
240
|
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
|
|
@@ -180,13 +246,16 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
|
180
246
|
if( NIL_P(argv[0]) )
|
|
181
247
|
return Qnil;
|
|
182
248
|
|
|
183
|
-
|
|
249
|
+
if( this->format == 0 ){
|
|
250
|
+
val = StringValueCStr(argv[0]);
|
|
251
|
+
}else{
|
|
252
|
+
val = StringValuePtr(argv[0]);
|
|
253
|
+
}
|
|
184
254
|
if( !this->dec_func ){
|
|
185
255
|
rb_raise(rb_eRuntimeError, "no decoder function defined");
|
|
186
256
|
}
|
|
187
257
|
|
|
188
|
-
res = this->dec_func(this, val,
|
|
189
|
-
OBJ_INFECT(res, argv[0]);
|
|
258
|
+
res = this->dec_func(this, val, RSTRING_LENINT(argv[0]), tuple, field, ENCODING_GET(argv[0]));
|
|
190
259
|
|
|
191
260
|
return res;
|
|
192
261
|
}
|
|
@@ -203,7 +272,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
|
203
272
|
static VALUE
|
|
204
273
|
pg_coder_oid_set(VALUE self, VALUE oid)
|
|
205
274
|
{
|
|
206
|
-
t_pg_coder *this =
|
|
275
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
207
276
|
this->oid = NUM2UINT(oid);
|
|
208
277
|
return oid;
|
|
209
278
|
}
|
|
@@ -218,7 +287,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
|
|
|
218
287
|
static VALUE
|
|
219
288
|
pg_coder_oid_get(VALUE self)
|
|
220
289
|
{
|
|
221
|
-
t_pg_coder *this =
|
|
290
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
222
291
|
return UINT2NUM(this->oid);
|
|
223
292
|
}
|
|
224
293
|
|
|
@@ -234,7 +303,7 @@ pg_coder_oid_get(VALUE self)
|
|
|
234
303
|
static VALUE
|
|
235
304
|
pg_coder_format_set(VALUE self, VALUE format)
|
|
236
305
|
{
|
|
237
|
-
t_pg_coder *this =
|
|
306
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
238
307
|
this->format = NUM2INT(format);
|
|
239
308
|
return format;
|
|
240
309
|
}
|
|
@@ -249,10 +318,40 @@ pg_coder_format_set(VALUE self, VALUE format)
|
|
|
249
318
|
static VALUE
|
|
250
319
|
pg_coder_format_get(VALUE self)
|
|
251
320
|
{
|
|
252
|
-
t_pg_coder *this =
|
|
321
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
253
322
|
return INT2NUM(this->format);
|
|
254
323
|
}
|
|
255
324
|
|
|
325
|
+
/*
|
|
326
|
+
* call-seq:
|
|
327
|
+
* coder.flags = Integer
|
|
328
|
+
*
|
|
329
|
+
* Set coder specific bitwise OR-ed flags.
|
|
330
|
+
* See the particular en- or decoder description for available flags.
|
|
331
|
+
*
|
|
332
|
+
* The default is +0+.
|
|
333
|
+
*/
|
|
334
|
+
static VALUE
|
|
335
|
+
pg_coder_flags_set(VALUE self, VALUE flags)
|
|
336
|
+
{
|
|
337
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
338
|
+
this->flags = NUM2INT(flags);
|
|
339
|
+
return flags;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/*
|
|
343
|
+
* call-seq:
|
|
344
|
+
* coder.flags -> Integer
|
|
345
|
+
*
|
|
346
|
+
* Get current bitwise OR-ed coder flags.
|
|
347
|
+
*/
|
|
348
|
+
static VALUE
|
|
349
|
+
pg_coder_flags_get(VALUE self)
|
|
350
|
+
{
|
|
351
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
352
|
+
return INT2NUM(this->flags);
|
|
353
|
+
}
|
|
354
|
+
|
|
256
355
|
/*
|
|
257
356
|
* call-seq:
|
|
258
357
|
* coder.needs_quotation = Boolean
|
|
@@ -266,7 +365,7 @@ pg_coder_format_get(VALUE self)
|
|
|
266
365
|
static VALUE
|
|
267
366
|
pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
|
268
367
|
{
|
|
269
|
-
t_pg_composite_coder *this =
|
|
368
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
270
369
|
this->needs_quotation = RTEST(needs_quotation);
|
|
271
370
|
return needs_quotation;
|
|
272
371
|
}
|
|
@@ -281,7 +380,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
|
|
281
380
|
static VALUE
|
|
282
381
|
pg_coder_needs_quotation_get(VALUE self)
|
|
283
382
|
{
|
|
284
|
-
t_pg_composite_coder *this =
|
|
383
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
285
384
|
return this->needs_quotation ? Qtrue : Qfalse;
|
|
286
385
|
}
|
|
287
386
|
|
|
@@ -296,7 +395,7 @@ pg_coder_needs_quotation_get(VALUE self)
|
|
|
296
395
|
static VALUE
|
|
297
396
|
pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
|
298
397
|
{
|
|
299
|
-
t_pg_composite_coder *this =
|
|
398
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
300
399
|
StringValue(delimiter);
|
|
301
400
|
if(RSTRING_LEN(delimiter) != 1)
|
|
302
401
|
rb_raise( rb_eArgError, "delimiter size must be one byte");
|
|
@@ -313,7 +412,7 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
|
|
313
412
|
static VALUE
|
|
314
413
|
pg_coder_delimiter_get(VALUE self)
|
|
315
414
|
{
|
|
316
|
-
t_pg_composite_coder *this =
|
|
415
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
317
416
|
return rb_str_new(&this->delimiter, 1);
|
|
318
417
|
}
|
|
319
418
|
|
|
@@ -329,12 +428,12 @@ pg_coder_delimiter_get(VALUE self)
|
|
|
329
428
|
static VALUE
|
|
330
429
|
pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
|
331
430
|
{
|
|
332
|
-
t_pg_composite_coder *this =
|
|
431
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA( self );
|
|
333
432
|
|
|
334
433
|
if ( NIL_P(elem_type) ){
|
|
335
434
|
this->elem = NULL;
|
|
336
435
|
} else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
|
|
337
|
-
this->elem =
|
|
436
|
+
this->elem = RTYPEDDATA_DATA( elem_type );
|
|
338
437
|
} else {
|
|
339
438
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
|
|
340
439
|
rb_obj_classname( elem_type ) );
|
|
@@ -344,14 +443,31 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
|
|
344
443
|
return elem_type;
|
|
345
444
|
}
|
|
346
445
|
|
|
446
|
+
static const rb_data_type_t pg_coder_cfunc_type = {
|
|
447
|
+
"PG::Coder::CFUNC",
|
|
448
|
+
{
|
|
449
|
+
(RUBY_DATA_FUNC)NULL,
|
|
450
|
+
(RUBY_DATA_FUNC)NULL,
|
|
451
|
+
(size_t (*)(const void *))NULL,
|
|
452
|
+
},
|
|
453
|
+
0,
|
|
454
|
+
0,
|
|
455
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
456
|
+
};
|
|
457
|
+
|
|
347
458
|
void
|
|
348
459
|
pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
349
460
|
{
|
|
350
|
-
VALUE cfunc_obj =
|
|
461
|
+
VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
|
|
351
462
|
VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
|
|
352
463
|
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
|
|
353
464
|
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
|
|
354
465
|
|
|
466
|
+
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
|
|
467
|
+
rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
|
|
468
|
+
if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
|
|
469
|
+
rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
|
|
470
|
+
|
|
355
471
|
rb_define_const( coder_klass, "CFUNC", cfunc_obj );
|
|
356
472
|
|
|
357
473
|
RB_GC_GUARD(cfunc_obj);
|
|
@@ -359,10 +475,19 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
|
359
475
|
|
|
360
476
|
|
|
361
477
|
static int
|
|
362
|
-
pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
478
|
+
pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
363
479
|
{
|
|
364
|
-
|
|
365
|
-
|
|
480
|
+
int arity = rb_obj_method_arity(conv->coder_obj, s_id_encode);
|
|
481
|
+
if( arity == 1 ){
|
|
482
|
+
VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
|
|
483
|
+
StringValue( out_str );
|
|
484
|
+
*intermediate = rb_str_export_to_enc(out_str, rb_enc_from_index(enc_idx));
|
|
485
|
+
}else{
|
|
486
|
+
VALUE enc = rb_enc_from_encoding(rb_enc_from_index(enc_idx));
|
|
487
|
+
VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 2, value, enc );
|
|
488
|
+
StringValue( out_str );
|
|
489
|
+
*intermediate = out_str;
|
|
490
|
+
}
|
|
366
491
|
return -1;
|
|
367
492
|
}
|
|
368
493
|
|
|
@@ -382,14 +507,14 @@ pg_coder_enc_func(t_pg_coder *this)
|
|
|
382
507
|
}
|
|
383
508
|
|
|
384
509
|
static VALUE
|
|
385
|
-
pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
|
|
510
|
+
pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
|
|
386
511
|
{
|
|
387
512
|
VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
|
|
388
513
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
|
389
514
|
}
|
|
390
515
|
|
|
391
516
|
static VALUE
|
|
392
|
-
pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
|
|
517
|
+
pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
|
|
393
518
|
{
|
|
394
519
|
VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
|
|
395
520
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
|
@@ -412,7 +537,7 @@ pg_coder_dec_func(t_pg_coder *this, int binary)
|
|
|
412
537
|
|
|
413
538
|
|
|
414
539
|
void
|
|
415
|
-
init_pg_coder()
|
|
540
|
+
init_pg_coder(void)
|
|
416
541
|
{
|
|
417
542
|
s_id_encode = rb_intern("encode");
|
|
418
543
|
s_id_decode = rb_intern("decode");
|
|
@@ -436,14 +561,25 @@ init_pg_coder()
|
|
|
436
561
|
rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
|
|
437
562
|
rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
|
|
438
563
|
rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
|
|
564
|
+
rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
|
|
565
|
+
rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
|
|
566
|
+
|
|
567
|
+
/* define flags to be used with PG::Coder#flags= */
|
|
568
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
|
|
569
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
|
|
570
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
|
|
571
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
|
|
572
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
|
|
573
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
|
|
574
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
|
|
575
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
|
|
576
|
+
|
|
439
577
|
/*
|
|
440
578
|
* Name of the coder or the corresponding data type.
|
|
441
579
|
*
|
|
442
580
|
* This accessor is only used in PG::Coder#inspect .
|
|
443
581
|
*/
|
|
444
582
|
rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
|
|
445
|
-
rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, 1 );
|
|
446
|
-
rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
|
|
447
583
|
|
|
448
584
|
/* Document-class: PG::SimpleCoder < PG::Coder */
|
|
449
585
|
rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );
|