pg 0.18.2 → 1.5.3
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 +42 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +117 -0
- data/.github/workflows/source-gem.yml +137 -0
- data/.gitignore +22 -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.md +876 -0
- data/Manifest.txt +8 -21
- data/README-Windows.rdoc +17 -28
- data/README.ja.md +276 -0
- data/README.md +286 -0
- data/Rakefile +40 -131
- data/Rakefile.cross +88 -70
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -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 +226 -200
- data/ext/pg.h +99 -99
- data/ext/pg_binary_decoder.c +164 -16
- data/ext/pg_binary_encoder.c +249 -22
- data/ext/pg_coder.c +189 -44
- data/ext/pg_connection.c +1866 -1173
- data/ext/pg_copy_coder.c +398 -42
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +522 -0
- data/ext/pg_result.c +727 -232
- data/ext/pg_text_decoder.c +629 -43
- data/ext/pg_text_encoder.c +269 -102
- data/ext/pg_tuple.c +572 -0
- data/ext/pg_type_map.c +64 -23
- data/ext/pg_type_map_all_strings.c +21 -7
- data/ext/pg_type_map_by_class.c +59 -27
- data/ext/pg_type_map_by_column.c +86 -43
- data/ext/pg_type_map_by_mri_type.c +49 -20
- data/ext/pg_type_map_by_oid.c +62 -29
- data/ext/pg_type_map_in_ruby.c +56 -22
- 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 +67 -0
- data/lib/pg/basic_type_map_for_queries.rb +198 -0
- data/lib/pg/basic_type_map_for_results.rb +104 -0
- data/lib/pg/basic_type_registry.rb +299 -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/coder.rb +36 -13
- data/lib/pg/connection.rb +797 -77
- data/lib/pg/exceptions.rb +16 -2
- data/lib/pg/result.rb +24 -7
- data/lib/pg/text_decoder/date.rb +18 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +14 -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 +12 -0
- data/lib/pg/text_encoder/inet.rb +28 -0
- data/lib/pg/text_encoder/json.rb +14 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- 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 +106 -41
- 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 +34 -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/translation/.po4a-version +7 -0
- data/translation/po/all.pot +910 -0
- data/translation/po/ja.po +1047 -0
- data/translation/po4a.cfg +12 -0
- data.tar.gz.sig +0 -0
- metadata +137 -204
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -5545
- data/History.rdoc +0 -313
- data/README.ja.rdoc +0 -14
- data/README.rdoc +0 -161
- data/lib/pg/basic_type_mapping.rb +0 -399
- data/lib/pg/constants.rb +0 -11
- data/lib/pg/text_decoder.rb +0 -42
- data/lib/pg/text_encoder.rb +0 -27
- 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,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 =
|
|
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
|
+
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
|
-
this->coder_obj
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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;
|
|
@@ -105,7 +163,7 @@ pg_composite_decoder_allocate( VALUE klass )
|
|
|
105
163
|
|
|
106
164
|
/*
|
|
107
165
|
* call-seq:
|
|
108
|
-
* coder.encode( value )
|
|
166
|
+
* coder.encode( value [, encoding] )
|
|
109
167
|
*
|
|
110
168
|
* Encodes the given Ruby object into string representation, without
|
|
111
169
|
* sending data to/from the database server.
|
|
@@ -114,12 +172,23 @@ pg_composite_decoder_allocate( VALUE klass )
|
|
|
114
172
|
*
|
|
115
173
|
*/
|
|
116
174
|
static VALUE
|
|
117
|
-
pg_coder_encode(VALUE
|
|
175
|
+
pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
|
118
176
|
{
|
|
119
177
|
VALUE res;
|
|
120
178
|
VALUE intermediate;
|
|
179
|
+
VALUE value;
|
|
121
180
|
int len, len2;
|
|
122
|
-
|
|
181
|
+
int enc_idx;
|
|
182
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
183
|
+
|
|
184
|
+
if(argc < 1 || argc > 2){
|
|
185
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
|
|
186
|
+
}else if(argc == 1){
|
|
187
|
+
enc_idx = rb_ascii8bit_encindex();
|
|
188
|
+
}else{
|
|
189
|
+
enc_idx = rb_to_encoding_index(argv[1]);
|
|
190
|
+
}
|
|
191
|
+
value = argv[0];
|
|
123
192
|
|
|
124
193
|
if( NIL_P(value) )
|
|
125
194
|
return Qnil;
|
|
@@ -128,22 +197,21 @@ pg_coder_encode(VALUE self, VALUE value)
|
|
|
128
197
|
rb_raise(rb_eRuntimeError, "no encoder function defined");
|
|
129
198
|
}
|
|
130
199
|
|
|
131
|
-
len = this->enc_func( this, value, NULL, &intermediate );
|
|
200
|
+
len = this->enc_func( this, value, NULL, &intermediate, enc_idx );
|
|
132
201
|
|
|
133
202
|
if( len == -1 ){
|
|
134
203
|
/* The intermediate value is a String that can be used directly. */
|
|
135
|
-
OBJ_INFECT(intermediate, value);
|
|
136
204
|
return intermediate;
|
|
137
205
|
}
|
|
138
206
|
|
|
139
207
|
res = rb_str_new(NULL, len);
|
|
140
|
-
|
|
208
|
+
PG_ENCODING_SET_NOCHECK(res, enc_idx);
|
|
209
|
+
len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
|
|
141
210
|
if( len < len2 ){
|
|
142
211
|
rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
|
|
143
212
|
rb_obj_classname( self ), len, len2 );
|
|
144
213
|
}
|
|
145
214
|
rb_str_set_len( res, len2 );
|
|
146
|
-
OBJ_INFECT(res, value);
|
|
147
215
|
|
|
148
216
|
RB_GC_GUARD(intermediate);
|
|
149
217
|
|
|
@@ -165,10 +233,10 @@ static VALUE
|
|
|
165
233
|
pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
166
234
|
{
|
|
167
235
|
char *val;
|
|
168
|
-
|
|
169
|
-
|
|
236
|
+
int tuple = -1;
|
|
237
|
+
int field = -1;
|
|
170
238
|
VALUE res;
|
|
171
|
-
t_pg_coder *this =
|
|
239
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
172
240
|
|
|
173
241
|
if(argc < 1 || argc > 3){
|
|
174
242
|
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
|
|
@@ -180,13 +248,16 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
|
180
248
|
if( NIL_P(argv[0]) )
|
|
181
249
|
return Qnil;
|
|
182
250
|
|
|
183
|
-
|
|
251
|
+
if( this->format == 0 ){
|
|
252
|
+
val = StringValueCStr(argv[0]);
|
|
253
|
+
}else{
|
|
254
|
+
val = StringValuePtr(argv[0]);
|
|
255
|
+
}
|
|
184
256
|
if( !this->dec_func ){
|
|
185
257
|
rb_raise(rb_eRuntimeError, "no decoder function defined");
|
|
186
258
|
}
|
|
187
259
|
|
|
188
|
-
res = this->dec_func(this, val,
|
|
189
|
-
OBJ_INFECT(res, argv[0]);
|
|
260
|
+
res = this->dec_func(this, val, RSTRING_LENINT(argv[0]), tuple, field, ENCODING_GET(argv[0]));
|
|
190
261
|
|
|
191
262
|
return res;
|
|
192
263
|
}
|
|
@@ -203,7 +274,8 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
|
203
274
|
static VALUE
|
|
204
275
|
pg_coder_oid_set(VALUE self, VALUE oid)
|
|
205
276
|
{
|
|
206
|
-
t_pg_coder *this =
|
|
277
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
278
|
+
rb_check_frozen(self);
|
|
207
279
|
this->oid = NUM2UINT(oid);
|
|
208
280
|
return oid;
|
|
209
281
|
}
|
|
@@ -218,7 +290,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
|
|
|
218
290
|
static VALUE
|
|
219
291
|
pg_coder_oid_get(VALUE self)
|
|
220
292
|
{
|
|
221
|
-
t_pg_coder *this =
|
|
293
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
222
294
|
return UINT2NUM(this->oid);
|
|
223
295
|
}
|
|
224
296
|
|
|
@@ -234,7 +306,8 @@ pg_coder_oid_get(VALUE self)
|
|
|
234
306
|
static VALUE
|
|
235
307
|
pg_coder_format_set(VALUE self, VALUE format)
|
|
236
308
|
{
|
|
237
|
-
t_pg_coder *this =
|
|
309
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
310
|
+
rb_check_frozen(self);
|
|
238
311
|
this->format = NUM2INT(format);
|
|
239
312
|
return format;
|
|
240
313
|
}
|
|
@@ -249,10 +322,41 @@ pg_coder_format_set(VALUE self, VALUE format)
|
|
|
249
322
|
static VALUE
|
|
250
323
|
pg_coder_format_get(VALUE self)
|
|
251
324
|
{
|
|
252
|
-
t_pg_coder *this =
|
|
325
|
+
t_pg_coder *this = RTYPEDDATA_DATA(self);
|
|
253
326
|
return INT2NUM(this->format);
|
|
254
327
|
}
|
|
255
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
|
+
|
|
256
360
|
/*
|
|
257
361
|
* call-seq:
|
|
258
362
|
* coder.needs_quotation = Boolean
|
|
@@ -266,7 +370,8 @@ pg_coder_format_get(VALUE self)
|
|
|
266
370
|
static VALUE
|
|
267
371
|
pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
|
268
372
|
{
|
|
269
|
-
t_pg_composite_coder *this =
|
|
373
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
374
|
+
rb_check_frozen(self);
|
|
270
375
|
this->needs_quotation = RTEST(needs_quotation);
|
|
271
376
|
return needs_quotation;
|
|
272
377
|
}
|
|
@@ -281,7 +386,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
|
|
|
281
386
|
static VALUE
|
|
282
387
|
pg_coder_needs_quotation_get(VALUE self)
|
|
283
388
|
{
|
|
284
|
-
t_pg_composite_coder *this =
|
|
389
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
285
390
|
return this->needs_quotation ? Qtrue : Qfalse;
|
|
286
391
|
}
|
|
287
392
|
|
|
@@ -296,7 +401,8 @@ pg_coder_needs_quotation_get(VALUE self)
|
|
|
296
401
|
static VALUE
|
|
297
402
|
pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
|
298
403
|
{
|
|
299
|
-
t_pg_composite_coder *this =
|
|
404
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
405
|
+
rb_check_frozen(self);
|
|
300
406
|
StringValue(delimiter);
|
|
301
407
|
if(RSTRING_LEN(delimiter) != 1)
|
|
302
408
|
rb_raise( rb_eArgError, "delimiter size must be one byte");
|
|
@@ -313,7 +419,7 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
|
|
|
313
419
|
static VALUE
|
|
314
420
|
pg_coder_delimiter_get(VALUE self)
|
|
315
421
|
{
|
|
316
|
-
t_pg_composite_coder *this =
|
|
422
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
|
|
317
423
|
return rb_str_new(&this->delimiter, 1);
|
|
318
424
|
}
|
|
319
425
|
|
|
@@ -329,12 +435,13 @@ pg_coder_delimiter_get(VALUE self)
|
|
|
329
435
|
static VALUE
|
|
330
436
|
pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
|
331
437
|
{
|
|
332
|
-
t_pg_composite_coder *this =
|
|
438
|
+
t_pg_composite_coder *this = RTYPEDDATA_DATA( self );
|
|
333
439
|
|
|
440
|
+
rb_check_frozen(self);
|
|
334
441
|
if ( NIL_P(elem_type) ){
|
|
335
442
|
this->elem = NULL;
|
|
336
443
|
} else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
|
|
337
|
-
this->elem =
|
|
444
|
+
this->elem = RTYPEDDATA_DATA( elem_type );
|
|
338
445
|
} else {
|
|
339
446
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
|
|
340
447
|
rb_obj_classname( elem_type ) );
|
|
@@ -344,25 +451,52 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
|
|
|
344
451
|
return elem_type;
|
|
345
452
|
}
|
|
346
453
|
|
|
347
|
-
|
|
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
|
|
348
467
|
pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
349
468
|
{
|
|
350
|
-
VALUE cfunc_obj =
|
|
469
|
+
VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
|
|
351
470
|
VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
|
|
352
471
|
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
|
|
353
472
|
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
|
|
354
473
|
|
|
355
|
-
|
|
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) );
|
|
356
480
|
|
|
357
481
|
RB_GC_GUARD(cfunc_obj);
|
|
482
|
+
return coder_klass;
|
|
358
483
|
}
|
|
359
484
|
|
|
360
485
|
|
|
361
486
|
static int
|
|
362
|
-
pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
487
|
+
pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
363
488
|
{
|
|
364
|
-
|
|
365
|
-
|
|
489
|
+
int arity = rb_obj_method_arity(conv->coder_obj, s_id_encode);
|
|
490
|
+
if( arity == 1 ){
|
|
491
|
+
VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
|
|
492
|
+
StringValue( out_str );
|
|
493
|
+
*intermediate = rb_str_export_to_enc(out_str, rb_enc_from_index(enc_idx));
|
|
494
|
+
}else{
|
|
495
|
+
VALUE enc = rb_enc_from_encoding(rb_enc_from_index(enc_idx));
|
|
496
|
+
VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 2, value, enc );
|
|
497
|
+
StringValue( out_str );
|
|
498
|
+
*intermediate = out_str;
|
|
499
|
+
}
|
|
366
500
|
return -1;
|
|
367
501
|
}
|
|
368
502
|
|
|
@@ -382,14 +516,14 @@ pg_coder_enc_func(t_pg_coder *this)
|
|
|
382
516
|
}
|
|
383
517
|
|
|
384
518
|
static VALUE
|
|
385
|
-
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)
|
|
386
520
|
{
|
|
387
521
|
VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
|
|
388
522
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
|
389
523
|
}
|
|
390
524
|
|
|
391
525
|
static VALUE
|
|
392
|
-
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)
|
|
393
527
|
{
|
|
394
528
|
VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
|
|
395
529
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
|
@@ -412,7 +546,7 @@ pg_coder_dec_func(t_pg_coder *this, int binary)
|
|
|
412
546
|
|
|
413
547
|
|
|
414
548
|
void
|
|
415
|
-
init_pg_coder()
|
|
549
|
+
init_pg_coder(void)
|
|
416
550
|
{
|
|
417
551
|
s_id_encode = rb_intern("encode");
|
|
418
552
|
s_id_decode = rb_intern("decode");
|
|
@@ -436,14 +570,25 @@ init_pg_coder()
|
|
|
436
570
|
rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
|
|
437
571
|
rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
|
|
438
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
|
+
|
|
439
586
|
/*
|
|
440
587
|
* Name of the coder or the corresponding data type.
|
|
441
588
|
*
|
|
442
589
|
* This accessor is only used in PG::Coder#inspect .
|
|
443
590
|
*/
|
|
444
591
|
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
592
|
|
|
448
593
|
/* Document-class: PG::SimpleCoder < PG::Coder */
|
|
449
594
|
rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );
|