pg 1.1.3 → 1.5.4
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/.appveyor.yml +42 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +117 -0
- data/.github/workflows/source-gem.yml +141 -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/Gemfile +14 -0
- data/History.md +884 -0
- data/Manifest.txt +3 -3
- data/README-Windows.rdoc +4 -4
- data/README.ja.md +300 -0
- data/README.md +286 -0
- data/Rakefile +37 -137
- data/Rakefile.cross +62 -62
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/ext/errorcodes.def +80 -0
- data/ext/errorcodes.rb +0 -0
- data/ext/errorcodes.txt +22 -2
- data/ext/extconf.rb +105 -26
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +204 -152
- data/ext/pg.h +52 -21
- data/ext/pg_binary_decoder.c +100 -17
- data/ext/pg_binary_encoder.c +238 -13
- data/ext/pg_coder.c +109 -34
- data/ext/pg_connection.c +1383 -983
- data/ext/pg_copy_coder.c +356 -35
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +522 -0
- data/ext/pg_result.c +439 -172
- data/ext/pg_text_decoder.c +42 -18
- data/ext/pg_text_encoder.c +201 -56
- data/ext/pg_tuple.c +97 -66
- data/ext/pg_type_map.c +45 -11
- 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 +80 -37
- 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} +7 -7
- 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 +35 -12
- data/lib/pg/connection.rb +744 -84
- data/lib/pg/exceptions.rb +15 -1
- data/lib/pg/result.rb +13 -1
- 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/type_map_by_column.rb +2 -1
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +94 -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/pg.gemspec +34 -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/translation/.po4a-version +7 -0
- data/translation/po/all.pot +936 -0
- data/translation/po/ja.po +1036 -0
- data/translation/po4a.cfg +12 -0
- data.tar.gz.sig +0 -0
- metadata +144 -222
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +0 -485
- data/README.ja.rdoc +0 -14
- data/README.rdoc +0 -178
- data/lib/pg/basic_type_mapping.rb +0 -459
- data/lib/pg/binary_decoder.rb +0 -22
- data/lib/pg/constants.rb +0 -11
- data/lib/pg/text_decoder.rb +0 -47
- data/lib/pg/text_encoder.rb +0 -69
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -381
- data/spec/pg/basic_type_mapping_spec.rb +0 -508
- data/spec/pg/connection_spec.rb +0 -1849
- data/spec/pg/connection_sync_spec.rb +0 -41
- data/spec/pg/result_spec.rb +0 -491
- data/spec/pg/tuple_spec.rb +0 -280
- 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 -949
- data/spec/pg_spec.rb +0 -50
- /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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
84
|
+
rb_gc_mark_movable( this->values[i] );
|
|
77
85
|
}
|
|
78
|
-
|
|
86
|
+
rb_gc_mark_movable( pg_tuple_get_field_names(this) );
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
static void
|
|
82
|
-
|
|
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(
|
|
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
|
-
"
|
|
123
|
+
"PG::Tuple",
|
|
97
124
|
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
|
138
|
-
this->typemap
|
|
139
|
-
this->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
|
-
|
|
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(
|
|
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 =
|
|
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]
|
|
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(
|
|
214
|
+
pg_tuple_detach(VALUE self)
|
|
186
215
|
{
|
|
187
|
-
this
|
|
188
|
-
this->
|
|
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(
|
|
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(
|
|
228
|
+
pg_tuple_materialize_field(self, field_num);
|
|
198
229
|
}
|
|
199
230
|
|
|
200
|
-
pg_tuple_detach(
|
|
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
|
-
*
|
|
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(
|
|
293
|
+
return pg_tuple_materialize_field(self, field_num);
|
|
263
294
|
}
|
|
264
295
|
|
|
265
296
|
/*
|
|
266
297
|
* call-seq:
|
|
267
|
-
*
|
|
298
|
+
* tup[ key ] -> value
|
|
268
299
|
*
|
|
269
|
-
* Returns field
|
|
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(
|
|
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
|
|
342
|
+
pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE self)
|
|
305
343
|
{
|
|
306
|
-
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
394
|
+
VALUE value = pg_tuple_materialize_field(self, field_num);
|
|
358
395
|
rb_yield(value);
|
|
359
396
|
}
|
|
360
397
|
|
|
361
|
-
pg_tuple_detach(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
508
|
+
num_fields = RARRAY_LENINT(values);
|
|
476
509
|
|
|
477
|
-
if (
|
|
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
|
|
495
|
-
this->typemap
|
|
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
|
|
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]
|
|
536
|
+
RB_OBJ_WRITE(self, &this->values[i], v);
|
|
505
537
|
}
|
|
506
538
|
|
|
507
539
|
if( dup_names ){
|
|
508
|
-
this->values[num_fields]
|
|
540
|
+
RB_OBJ_WRITE(self, &this->values[num_fields], field_names);
|
|
509
541
|
}
|
|
510
542
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
131
|
+
t_typemap *this = RTYPEDDATA_DATA( self );
|
|
132
|
+
t_typemap *tm;
|
|
133
|
+
UNUSED(tm);
|
|
98
134
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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 =
|
|
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
|
|
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,
|
|
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,
|
|
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 =
|
|
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
|
|
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
|
}
|