pg 1.2.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 +0 -1
- data/README.ja.md +300 -0
- data/README.md +286 -0
- data/Rakefile +33 -135
- data/Rakefile.cross +12 -13
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/ext/errorcodes.def +12 -0
- data/ext/errorcodes.rb +0 -0
- data/ext/errorcodes.txt +4 -1
- data/ext/extconf.rb +104 -25
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +73 -58
- data/ext/pg.h +28 -5
- data/ext/pg_binary_decoder.c +80 -1
- data/ext/pg_binary_encoder.c +225 -1
- data/ext/pg_coder.c +96 -33
- data/ext/pg_connection.c +1010 -704
- data/ext/pg_copy_coder.c +351 -33
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +50 -19
- data/ext/pg_result.c +177 -64
- data/ext/pg_text_decoder.c +29 -11
- data/ext/pg_text_encoder.c +29 -16
- data/ext/pg_tuple.c +83 -60
- 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 +73 -31
- data/ext/pg_type_map_by_mri_type.c +48 -19
- data/ext/pg_type_map_by_oid.c +59 -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 +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 +15 -13
- data/lib/pg/connection.rb +743 -83
- data/lib/pg/exceptions.rb +14 -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/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 +135 -207
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -0
- data/History.rdoc +0 -578
- data/README.ja.rdoc +0 -13
- data/README.rdoc +0 -213
- 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_text_encoder.c
CHANGED
|
@@ -191,7 +191,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
191
191
|
if (neg)
|
|
192
192
|
*out++ = '-';
|
|
193
193
|
|
|
194
|
-
len = out - start;
|
|
194
|
+
len = (int)(out - start);
|
|
195
195
|
|
|
196
196
|
/* Reverse string. */
|
|
197
197
|
out--;
|
|
@@ -252,7 +252,7 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
/*
|
|
255
|
-
* The following
|
|
255
|
+
* The following computation is roughly a conversion kind of
|
|
256
256
|
* sprintf( out, "%.16E", dvalue);
|
|
257
257
|
*/
|
|
258
258
|
|
|
@@ -371,6 +371,21 @@ pg_text_enc_numeric(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
/* called per autoload when TextEncoder::Numeric is used */
|
|
375
|
+
static VALUE
|
|
376
|
+
init_pg_text_encoder_numeric(VALUE rb_mPG_TextDecoder)
|
|
377
|
+
{
|
|
378
|
+
s_str_F = rb_str_freeze(rb_str_new_cstr("F"));
|
|
379
|
+
rb_global_variable(&s_str_F);
|
|
380
|
+
rb_require("bigdecimal");
|
|
381
|
+
s_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
|
382
|
+
|
|
383
|
+
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Numeric", rb_cPG_SimpleEncoder ); */
|
|
384
|
+
pg_define_coder( "Numeric", pg_text_enc_numeric, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
385
|
+
|
|
386
|
+
return Qnil;
|
|
387
|
+
}
|
|
388
|
+
|
|
374
389
|
|
|
375
390
|
static const char hextab[] = {
|
|
376
391
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
|
@@ -383,8 +398,12 @@ static const char hextab[] = {
|
|
|
383
398
|
*
|
|
384
399
|
* The binary String is converted to hexadecimal representation for transmission
|
|
385
400
|
* in text format. For query bind parameters it is recommended to use
|
|
386
|
-
* PG::BinaryEncoder::Bytea
|
|
387
|
-
* CPU usage.
|
|
401
|
+
* PG::BinaryEncoder::Bytea or the hash form <tt>{value: binary_string, format: 1}</tt> instead,
|
|
402
|
+
* in order to decrease network traffic and CPU usage.
|
|
403
|
+
* See PG::Connection#exec_params for using the hash form.
|
|
404
|
+
*
|
|
405
|
+
* This encoder is particular useful when PG::TextEncoder::CopyRow is used with the COPY command.
|
|
406
|
+
* In this case there's no way to change the format of a single column to binary, so that the data have to be converted to bytea hex representation.
|
|
388
407
|
*
|
|
389
408
|
*/
|
|
390
409
|
static int
|
|
@@ -403,11 +422,11 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
|
403
422
|
*optr++ = hextab[c >> 4];
|
|
404
423
|
*optr++ = hextab[c & 0xf];
|
|
405
424
|
}
|
|
406
|
-
return optr - out;
|
|
425
|
+
return (int)(optr - out);
|
|
407
426
|
}else{
|
|
408
427
|
*intermediate = rb_obj_as_string(value);
|
|
409
428
|
/* The output starts with "\x" and each character is converted to hex. */
|
|
410
|
-
return 2 +
|
|
429
|
+
return 2 + RSTRING_LENINT(*intermediate) * 2;
|
|
411
430
|
}
|
|
412
431
|
}
|
|
413
432
|
|
|
@@ -610,8 +629,8 @@ quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
|
|
610
629
|
static char *
|
|
611
630
|
pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
|
|
612
631
|
{
|
|
613
|
-
|
|
614
|
-
|
|
632
|
+
long i;
|
|
633
|
+
long nr_elems;
|
|
615
634
|
|
|
616
635
|
Check_Type(value, T_ARRAY);
|
|
617
636
|
nr_elems = RARRAY_LEN(value);
|
|
@@ -775,19 +794,15 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
775
794
|
|
|
776
795
|
|
|
777
796
|
void
|
|
778
|
-
init_pg_text_encoder()
|
|
797
|
+
init_pg_text_encoder(void)
|
|
779
798
|
{
|
|
780
799
|
s_id_encode = rb_intern("encode");
|
|
781
800
|
s_id_to_i = rb_intern("to_i");
|
|
782
801
|
s_id_to_s = rb_intern("to_s");
|
|
783
|
-
s_str_F = rb_str_freeze(rb_str_new_cstr("F"));
|
|
784
|
-
rb_global_variable(&s_str_F);
|
|
785
|
-
rb_require("bigdecimal");
|
|
786
|
-
s_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
|
787
|
-
|
|
788
802
|
|
|
789
803
|
/* This module encapsulates all encoder classes with text output format */
|
|
790
804
|
rb_mPG_TextEncoder = rb_define_module_under( rb_mPG, "TextEncoder" );
|
|
805
|
+
rb_define_private_method(rb_singleton_class(rb_mPG_TextEncoder), "init_numeric", init_pg_text_encoder_numeric, 0);
|
|
791
806
|
|
|
792
807
|
/* Make RDoc aware of the encoder classes... */
|
|
793
808
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Boolean", rb_cPG_SimpleEncoder ); */
|
|
@@ -796,8 +811,6 @@ init_pg_text_encoder()
|
|
|
796
811
|
pg_define_coder( "Integer", pg_text_enc_integer, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
797
812
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Float", rb_cPG_SimpleEncoder ); */
|
|
798
813
|
pg_define_coder( "Float", pg_text_enc_float, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
799
|
-
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Numeric", rb_cPG_SimpleEncoder ); */
|
|
800
|
-
pg_define_coder( "Numeric", pg_text_enc_numeric, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
801
814
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "String", rb_cPG_SimpleEncoder ); */
|
|
802
815
|
pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
803
816
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
|
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
|
/*
|
|
@@ -133,9 +159,9 @@ pg_tuple_new(VALUE result, int row_num)
|
|
|
133
159
|
sizeof(*this->values) * num_fields +
|
|
134
160
|
sizeof(*this->values) * (dup_names ? 1 : 0));
|
|
135
161
|
|
|
136
|
-
this->result
|
|
137
|
-
this->typemap
|
|
138
|
-
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);
|
|
139
165
|
this->row_num = row_num;
|
|
140
166
|
this->num_fields = num_fields;
|
|
141
167
|
|
|
@@ -147,7 +173,8 @@ pg_tuple_new(VALUE result, int row_num)
|
|
|
147
173
|
/* Some of the column names are duplicated -> we need the keys as Array in addition.
|
|
148
174
|
* Store it behind the values to save the space in the common case of no dups.
|
|
149
175
|
*/
|
|
150
|
-
|
|
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);
|
|
151
178
|
}
|
|
152
179
|
|
|
153
180
|
RTYPEDDATA_DATA(self) = this;
|
|
@@ -167,38 +194,41 @@ pg_tuple_get_this( VALUE self )
|
|
|
167
194
|
}
|
|
168
195
|
|
|
169
196
|
static VALUE
|
|
170
|
-
pg_tuple_materialize_field(
|
|
197
|
+
pg_tuple_materialize_field(VALUE self, int col)
|
|
171
198
|
{
|
|
199
|
+
t_pg_tuple *this = RTYPEDDATA_DATA( self );
|
|
172
200
|
VALUE value = this->values[col];
|
|
173
201
|
|
|
174
202
|
if( value == Qundef ){
|
|
175
|
-
t_typemap *p_typemap =
|
|
203
|
+
t_typemap *p_typemap = RTYPEDDATA_DATA( this->typemap );
|
|
176
204
|
|
|
177
205
|
pgresult_get(this->result); /* make sure we have a valid PGresult object */
|
|
178
206
|
value = p_typemap->funcs.typecast_result_value(p_typemap, this->result, this->row_num, col);
|
|
179
|
-
this->values[col]
|
|
207
|
+
RB_OBJ_WRITE(self, &this->values[col], value);
|
|
180
208
|
}
|
|
181
209
|
|
|
182
210
|
return value;
|
|
183
211
|
}
|
|
184
212
|
|
|
185
213
|
static void
|
|
186
|
-
pg_tuple_detach(
|
|
214
|
+
pg_tuple_detach(VALUE self)
|
|
187
215
|
{
|
|
188
|
-
this
|
|
189
|
-
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);
|
|
190
219
|
this->row_num = -1;
|
|
191
220
|
}
|
|
192
221
|
|
|
193
222
|
static void
|
|
194
|
-
pg_tuple_materialize(
|
|
223
|
+
pg_tuple_materialize(VALUE self)
|
|
195
224
|
{
|
|
225
|
+
t_pg_tuple *this = RTYPEDDATA_DATA( self );
|
|
196
226
|
int field_num;
|
|
197
227
|
for(field_num = 0; field_num < this->num_fields; field_num++) {
|
|
198
|
-
pg_tuple_materialize_field(
|
|
228
|
+
pg_tuple_materialize_field(self, field_num);
|
|
199
229
|
}
|
|
200
230
|
|
|
201
|
-
pg_tuple_detach(
|
|
231
|
+
pg_tuple_detach(self);
|
|
202
232
|
}
|
|
203
233
|
|
|
204
234
|
/*
|
|
@@ -260,7 +290,7 @@ pg_tuple_fetch(int argc, VALUE *argv, VALUE self)
|
|
|
260
290
|
field_num = NUM2INT(index);
|
|
261
291
|
}
|
|
262
292
|
|
|
263
|
-
return pg_tuple_materialize_field(
|
|
293
|
+
return pg_tuple_materialize_field(self, field_num);
|
|
264
294
|
}
|
|
265
295
|
|
|
266
296
|
/*
|
|
@@ -298,7 +328,7 @@ pg_tuple_aref(VALUE self, VALUE key)
|
|
|
298
328
|
field_num = NUM2INT(index);
|
|
299
329
|
}
|
|
300
330
|
|
|
301
|
-
return pg_tuple_materialize_field(
|
|
331
|
+
return pg_tuple_materialize_field(self, field_num);
|
|
302
332
|
}
|
|
303
333
|
|
|
304
334
|
static VALUE
|
|
@@ -309,10 +339,9 @@ pg_tuple_num_fields_for_enum(VALUE self, VALUE args, VALUE eobj)
|
|
|
309
339
|
}
|
|
310
340
|
|
|
311
341
|
static int
|
|
312
|
-
pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE
|
|
342
|
+
pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE self)
|
|
313
343
|
{
|
|
314
|
-
|
|
315
|
-
VALUE value = pg_tuple_materialize_field(this, NUM2INT(index));
|
|
344
|
+
VALUE value = pg_tuple_materialize_field(self, NUM2INT(index));
|
|
316
345
|
rb_yield_values(2, key, value);
|
|
317
346
|
return ST_CONTINUE;
|
|
318
347
|
}
|
|
@@ -334,16 +363,16 @@ pg_tuple_each(VALUE self)
|
|
|
334
363
|
field_names = pg_tuple_get_field_names(this);
|
|
335
364
|
|
|
336
365
|
if( field_names == Qfalse ){
|
|
337
|
-
rb_hash_foreach(this->field_map, pg_tuple_yield_key_value,
|
|
366
|
+
rb_hash_foreach(this->field_map, pg_tuple_yield_key_value, self);
|
|
338
367
|
} else {
|
|
339
368
|
int i;
|
|
340
369
|
for( i = 0; i < this->num_fields; i++ ){
|
|
341
|
-
VALUE value = pg_tuple_materialize_field(
|
|
370
|
+
VALUE value = pg_tuple_materialize_field(self, i);
|
|
342
371
|
rb_yield_values(2, RARRAY_AREF(field_names, i), value);
|
|
343
372
|
}
|
|
344
373
|
}
|
|
345
374
|
|
|
346
|
-
pg_tuple_detach(
|
|
375
|
+
pg_tuple_detach(self);
|
|
347
376
|
return self;
|
|
348
377
|
}
|
|
349
378
|
|
|
@@ -362,11 +391,11 @@ pg_tuple_each_value(VALUE self)
|
|
|
362
391
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, pg_tuple_num_fields_for_enum);
|
|
363
392
|
|
|
364
393
|
for(field_num = 0; field_num < this->num_fields; field_num++) {
|
|
365
|
-
VALUE value = pg_tuple_materialize_field(
|
|
394
|
+
VALUE value = pg_tuple_materialize_field(self, field_num);
|
|
366
395
|
rb_yield(value);
|
|
367
396
|
}
|
|
368
397
|
|
|
369
|
-
pg_tuple_detach(
|
|
398
|
+
pg_tuple_detach(self);
|
|
370
399
|
return self;
|
|
371
400
|
}
|
|
372
401
|
|
|
@@ -383,7 +412,7 @@ pg_tuple_values(VALUE self)
|
|
|
383
412
|
{
|
|
384
413
|
t_pg_tuple *this = pg_tuple_get_this(self);
|
|
385
414
|
|
|
386
|
-
pg_tuple_materialize(
|
|
415
|
+
pg_tuple_materialize(self);
|
|
387
416
|
return rb_ary_new4(this->num_fields, &this->values[0]);
|
|
388
417
|
}
|
|
389
418
|
|
|
@@ -436,7 +465,7 @@ pg_tuple_dump(VALUE self)
|
|
|
436
465
|
VALUE a;
|
|
437
466
|
t_pg_tuple *this = pg_tuple_get_this(self);
|
|
438
467
|
|
|
439
|
-
pg_tuple_materialize(
|
|
468
|
+
pg_tuple_materialize(self);
|
|
440
469
|
|
|
441
470
|
field_names = pg_tuple_get_field_names(this);
|
|
442
471
|
if( field_names == Qfalse )
|
|
@@ -445,10 +474,7 @@ pg_tuple_dump(VALUE self)
|
|
|
445
474
|
values = rb_ary_new4(this->num_fields, &this->values[0]);
|
|
446
475
|
a = rb_ary_new3(2, field_names, values);
|
|
447
476
|
|
|
448
|
-
|
|
449
|
-
rb_copy_generic_ivar(a, self);
|
|
450
|
-
FL_SET(a, FL_EXIVAR);
|
|
451
|
-
}
|
|
477
|
+
rb_copy_generic_ivar(a, self);
|
|
452
478
|
|
|
453
479
|
return a;
|
|
454
480
|
}
|
|
@@ -479,9 +505,9 @@ pg_tuple_load(VALUE self, VALUE a)
|
|
|
479
505
|
rb_obj_freeze(field_names);
|
|
480
506
|
values = RARRAY_AREF(a, 1);
|
|
481
507
|
Check_Type(values, T_ARRAY);
|
|
482
|
-
num_fields =
|
|
508
|
+
num_fields = RARRAY_LENINT(values);
|
|
483
509
|
|
|
484
|
-
if (
|
|
510
|
+
if (RARRAY_LENINT(field_names) != num_fields)
|
|
485
511
|
rb_raise(rb_eTypeError, "different number of fields and values");
|
|
486
512
|
|
|
487
513
|
field_map = rb_hash_new();
|
|
@@ -497,35 +523,32 @@ pg_tuple_load(VALUE self, VALUE a)
|
|
|
497
523
|
sizeof(*this->values) * num_fields +
|
|
498
524
|
sizeof(*this->values) * (dup_names ? 1 : 0));
|
|
499
525
|
|
|
500
|
-
this->result
|
|
501
|
-
this->typemap
|
|
526
|
+
RB_OBJ_WRITE(self, &this->result, Qnil);
|
|
527
|
+
RB_OBJ_WRITE(self, &this->typemap, Qnil);
|
|
502
528
|
this->row_num = -1;
|
|
503
529
|
this->num_fields = num_fields;
|
|
504
|
-
this->field_map
|
|
530
|
+
RB_OBJ_WRITE(self, &this->field_map, field_map);
|
|
505
531
|
|
|
506
532
|
for( i = 0; i < num_fields; i++ ){
|
|
507
533
|
VALUE v = RARRAY_AREF(values, i);
|
|
508
534
|
if( v == Qundef )
|
|
509
535
|
rb_raise(rb_eTypeError, "field %d is not materialized", i);
|
|
510
|
-
this->values[i]
|
|
536
|
+
RB_OBJ_WRITE(self, &this->values[i], v);
|
|
511
537
|
}
|
|
512
538
|
|
|
513
539
|
if( dup_names ){
|
|
514
|
-
this->values[num_fields]
|
|
540
|
+
RB_OBJ_WRITE(self, &this->values[num_fields], field_names);
|
|
515
541
|
}
|
|
516
542
|
|
|
517
543
|
RTYPEDDATA_DATA(self) = this;
|
|
518
544
|
|
|
519
|
-
|
|
520
|
-
rb_copy_generic_ivar(self, a);
|
|
521
|
-
FL_SET(self, FL_EXIVAR);
|
|
522
|
-
}
|
|
545
|
+
rb_copy_generic_ivar(self, a);
|
|
523
546
|
|
|
524
547
|
return self;
|
|
525
548
|
}
|
|
526
549
|
|
|
527
550
|
void
|
|
528
|
-
init_pg_tuple()
|
|
551
|
+
init_pg_tuple(void)
|
|
529
552
|
{
|
|
530
553
|
rb_cPG_Tuple = rb_define_class_under( rb_mPG, "Tuple", rb_cObject );
|
|
531
554
|
rb_define_alloc_func( rb_cPG_Tuple, pg_tuple_s_allocate );
|
data/ext/pg_type_map.c
CHANGED
|
@@ -6,6 +6,40 @@
|
|
|
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");
|
|
@@ -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
|
|
|
@@ -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
|
|
@@ -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
|
}
|