pg 1.2.1-x64-mingw32 → 1.3.0.rc2-x64-mingw32
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 +36 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +85 -0
- data/.github/workflows/source-gem.yml +130 -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/Gemfile +14 -0
- data/History.rdoc +93 -7
- data/Manifest.txt +0 -1
- data/README.rdoc +8 -7
- data/Rakefile +31 -140
- data/Rakefile.cross +55 -56
- data/certs/ged.pem +24 -0
- data/ext/errorcodes.def +8 -0
- data/ext/errorcodes.txt +3 -1
- data/ext/extconf.rb +90 -19
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +59 -4
- data/ext/pg.h +18 -0
- data/ext/pg_coder.c +90 -24
- data/ext/pg_connection.c +606 -533
- data/ext/pg_copy_coder.c +45 -15
- data/ext/pg_record_coder.c +38 -9
- data/ext/pg_result.c +61 -31
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +6 -6
- data/ext/pg_tuple.c +47 -21
- data/ext/pg_type_map.c +41 -8
- data/ext/pg_type_map_all_strings.c +14 -1
- data/ext/pg_type_map_by_class.c +50 -21
- data/ext/pg_type_map_by_column.c +64 -28
- data/ext/pg_type_map_by_mri_type.c +47 -18
- data/ext/pg_type_map_by_oid.c +52 -23
- data/ext/pg_type_map_in_ruby.c +50 -19
- data/ext/pg_util.c +2 -2
- data/lib/2.5/pg_ext.so +0 -0
- data/lib/2.6/pg_ext.so +0 -0
- data/lib/2.7/pg_ext.so +0 -0
- data/lib/3.0/pg_ext.so +0 -0
- 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 +296 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +579 -57
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +38 -24
- data/lib/x64-mingw32/libpq.dll +0 -0
- 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/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +106 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/async_mixed.rb +56 -0
- data/sample/check_conn.rb +21 -0
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/disk_usage_report.rb +177 -0
- data/sample/issue-119.rb +94 -0
- data/sample/losample.rb +69 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/notify_wait.rb +72 -0
- data/sample/pg_statistics.rb +285 -0
- data/sample/replication_monitor.rb +222 -0
- data/sample/test_binary_values.rb +33 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +311 -0
- data.tar.gz.sig +0 -0
- metadata +94 -235
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -0
- data/lib/2.2/pg_ext.so +0 -0
- data/lib/2.3/pg_ext.so +0 -0
- data/lib/2.4/pg_ext.so +0 -0
- data/lib/libpq.dll +0 -0
- data/lib/pg/basic_type_mapping.rb +0 -522
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -382
- data/spec/pg/basic_type_mapping_spec.rb +0 -645
- data/spec/pg/connection_spec.rb +0 -1911
- 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_copy_coder.c
CHANGED
@@ -21,17 +21,47 @@ typedef struct {
|
|
21
21
|
|
22
22
|
|
23
23
|
static void
|
24
|
-
pg_copycoder_mark(
|
24
|
+
pg_copycoder_mark( void *_this )
|
25
25
|
{
|
26
|
-
|
27
|
-
|
26
|
+
t_pg_copycoder *this = (t_pg_copycoder *)_this;
|
27
|
+
rb_gc_mark_movable(this->typemap);
|
28
|
+
rb_gc_mark_movable(this->null_string);
|
28
29
|
}
|
29
30
|
|
31
|
+
static size_t
|
32
|
+
pg_copycoder_memsize( const void *_this )
|
33
|
+
{
|
34
|
+
const t_pg_copycoder *this = (const t_pg_copycoder *)_this;
|
35
|
+
return sizeof(*this);
|
36
|
+
}
|
37
|
+
|
38
|
+
static void
|
39
|
+
pg_copycoder_compact( void *_this )
|
40
|
+
{
|
41
|
+
t_pg_copycoder *this = (t_pg_copycoder *)_this;
|
42
|
+
pg_coder_compact(&this->comp);
|
43
|
+
pg_gc_location(this->typemap);
|
44
|
+
pg_gc_location(this->null_string);
|
45
|
+
}
|
46
|
+
|
47
|
+
static const rb_data_type_t pg_copycoder_type = {
|
48
|
+
"PG::CopyCoder",
|
49
|
+
{
|
50
|
+
pg_copycoder_mark,
|
51
|
+
RUBY_TYPED_DEFAULT_FREE,
|
52
|
+
pg_copycoder_memsize,
|
53
|
+
pg_compact_callback(pg_copycoder_compact),
|
54
|
+
},
|
55
|
+
&pg_coder_type,
|
56
|
+
0,
|
57
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
58
|
+
};
|
59
|
+
|
30
60
|
static VALUE
|
31
61
|
pg_copycoder_encoder_allocate( VALUE klass )
|
32
62
|
{
|
33
63
|
t_pg_copycoder *this;
|
34
|
-
VALUE self =
|
64
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
|
35
65
|
pg_coder_init_encoder( self );
|
36
66
|
this->typemap = pg_typemap_all_strings;
|
37
67
|
this->delimiter = '\t';
|
@@ -43,7 +73,7 @@ static VALUE
|
|
43
73
|
pg_copycoder_decoder_allocate( VALUE klass )
|
44
74
|
{
|
45
75
|
t_pg_copycoder *this;
|
46
|
-
VALUE self =
|
76
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
|
47
77
|
pg_coder_init_decoder( self );
|
48
78
|
this->typemap = pg_typemap_all_strings;
|
49
79
|
this->delimiter = '\t';
|
@@ -62,7 +92,7 @@ pg_copycoder_decoder_allocate( VALUE klass )
|
|
62
92
|
static VALUE
|
63
93
|
pg_copycoder_delimiter_set(VALUE self, VALUE delimiter)
|
64
94
|
{
|
65
|
-
t_pg_copycoder *this =
|
95
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA(self);
|
66
96
|
StringValue(delimiter);
|
67
97
|
if(RSTRING_LEN(delimiter) != 1)
|
68
98
|
rb_raise( rb_eArgError, "delimiter size must be one byte");
|
@@ -79,7 +109,7 @@ pg_copycoder_delimiter_set(VALUE self, VALUE delimiter)
|
|
79
109
|
static VALUE
|
80
110
|
pg_copycoder_delimiter_get(VALUE self)
|
81
111
|
{
|
82
|
-
t_pg_copycoder *this =
|
112
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA(self);
|
83
113
|
return rb_str_new(&this->delimiter, 1);
|
84
114
|
}
|
85
115
|
|
@@ -92,7 +122,7 @@ pg_copycoder_delimiter_get(VALUE self)
|
|
92
122
|
static VALUE
|
93
123
|
pg_copycoder_null_string_set(VALUE self, VALUE null_string)
|
94
124
|
{
|
95
|
-
t_pg_copycoder *this =
|
125
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA(self);
|
96
126
|
StringValue(null_string);
|
97
127
|
this->null_string = null_string;
|
98
128
|
return null_string;
|
@@ -104,7 +134,7 @@ pg_copycoder_null_string_set(VALUE self, VALUE null_string)
|
|
104
134
|
static VALUE
|
105
135
|
pg_copycoder_null_string_get(VALUE self)
|
106
136
|
{
|
107
|
-
t_pg_copycoder *this =
|
137
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA(self);
|
108
138
|
return this->null_string;
|
109
139
|
}
|
110
140
|
|
@@ -122,7 +152,7 @@ pg_copycoder_null_string_get(VALUE self)
|
|
122
152
|
static VALUE
|
123
153
|
pg_copycoder_type_map_set(VALUE self, VALUE type_map)
|
124
154
|
{
|
125
|
-
t_pg_copycoder *this =
|
155
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA( self );
|
126
156
|
|
127
157
|
if ( !rb_obj_is_kind_of(type_map, rb_cTypeMap) ){
|
128
158
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
|
@@ -142,7 +172,7 @@ pg_copycoder_type_map_set(VALUE self, VALUE type_map)
|
|
142
172
|
static VALUE
|
143
173
|
pg_copycoder_type_map_get(VALUE self)
|
144
174
|
{
|
145
|
-
t_pg_copycoder *this =
|
175
|
+
t_pg_copycoder *this = RTYPEDDATA_DATA( self );
|
146
176
|
|
147
177
|
return this->typemap;
|
148
178
|
}
|
@@ -187,7 +217,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
187
217
|
char *current_out;
|
188
218
|
char *end_capa_ptr;
|
189
219
|
|
190
|
-
p_typemap =
|
220
|
+
p_typemap = RTYPEDDATA_DATA( this->typemap );
|
191
221
|
p_typemap->funcs.fit_to_query( this->typemap, value );
|
192
222
|
|
193
223
|
/* Allocate a new string with embedded capacity and realloc exponential when needed. */
|
@@ -224,7 +254,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
224
254
|
|
225
255
|
if( strlen == -1 ){
|
226
256
|
/* we can directly use String value in subint */
|
227
|
-
strlen =
|
257
|
+
strlen = RSTRING_LENINT(subint);
|
228
258
|
|
229
259
|
/* size of string assuming the worst case, that every character must be escaped. */
|
230
260
|
PG_RB_STR_ENSURE_CAPA( *intermediate, strlen * 2, current_out, end_capa_ptr );
|
@@ -375,7 +405,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
|
|
375
405
|
char *end_capa_ptr;
|
376
406
|
t_typemap *p_typemap;
|
377
407
|
|
378
|
-
p_typemap =
|
408
|
+
p_typemap = RTYPEDDATA_DATA( this->typemap );
|
379
409
|
expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
|
380
410
|
|
381
411
|
/* The received input string will probably have this->nfields fields. */
|
@@ -396,7 +426,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
|
|
396
426
|
int found_delim = 0;
|
397
427
|
const char *start_ptr;
|
398
428
|
const char *end_ptr;
|
399
|
-
|
429
|
+
long input_len;
|
400
430
|
|
401
431
|
/* Remember start of field on input side */
|
402
432
|
start_ptr = cur_ptr;
|
data/ext/pg_record_coder.c
CHANGED
@@ -16,16 +16,45 @@ typedef struct {
|
|
16
16
|
|
17
17
|
|
18
18
|
static void
|
19
|
-
pg_recordcoder_mark(
|
19
|
+
pg_recordcoder_mark( void *_this )
|
20
20
|
{
|
21
|
-
|
21
|
+
t_pg_recordcoder *this = (t_pg_recordcoder *)_this;
|
22
|
+
rb_gc_mark_movable(this->typemap);
|
22
23
|
}
|
23
24
|
|
25
|
+
static size_t
|
26
|
+
pg_recordcoder_memsize( const void *_this )
|
27
|
+
{
|
28
|
+
const t_pg_recordcoder *this = (const t_pg_recordcoder *)_this;
|
29
|
+
return sizeof(*this);
|
30
|
+
}
|
31
|
+
|
32
|
+
static void
|
33
|
+
pg_recordcoder_compact( void *_this )
|
34
|
+
{
|
35
|
+
t_pg_recordcoder *this = (t_pg_recordcoder *)_this;
|
36
|
+
pg_coder_compact(&this->comp);
|
37
|
+
pg_gc_location(this->typemap);
|
38
|
+
}
|
39
|
+
|
40
|
+
static const rb_data_type_t pg_recordcoder_type = {
|
41
|
+
"PG::RecordCoder",
|
42
|
+
{
|
43
|
+
pg_recordcoder_mark,
|
44
|
+
RUBY_TYPED_DEFAULT_FREE,
|
45
|
+
pg_recordcoder_memsize,
|
46
|
+
pg_compact_callback(pg_recordcoder_compact),
|
47
|
+
},
|
48
|
+
&pg_coder_type,
|
49
|
+
0,
|
50
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
51
|
+
};
|
52
|
+
|
24
53
|
static VALUE
|
25
54
|
pg_recordcoder_encoder_allocate( VALUE klass )
|
26
55
|
{
|
27
56
|
t_pg_recordcoder *this;
|
28
|
-
VALUE self =
|
57
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
|
29
58
|
pg_coder_init_encoder( self );
|
30
59
|
this->typemap = pg_typemap_all_strings;
|
31
60
|
return self;
|
@@ -35,7 +64,7 @@ static VALUE
|
|
35
64
|
pg_recordcoder_decoder_allocate( VALUE klass )
|
36
65
|
{
|
37
66
|
t_pg_recordcoder *this;
|
38
|
-
VALUE self =
|
67
|
+
VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
|
39
68
|
pg_coder_init_decoder( self );
|
40
69
|
this->typemap = pg_typemap_all_strings;
|
41
70
|
return self;
|
@@ -55,7 +84,7 @@ pg_recordcoder_decoder_allocate( VALUE klass )
|
|
55
84
|
static VALUE
|
56
85
|
pg_recordcoder_type_map_set(VALUE self, VALUE type_map)
|
57
86
|
{
|
58
|
-
t_pg_recordcoder *this =
|
87
|
+
t_pg_recordcoder *this = RTYPEDDATA_DATA( self );
|
59
88
|
|
60
89
|
if ( !rb_obj_is_kind_of(type_map, rb_cTypeMap) ){
|
61
90
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
|
@@ -75,7 +104,7 @@ pg_recordcoder_type_map_set(VALUE self, VALUE type_map)
|
|
75
104
|
static VALUE
|
76
105
|
pg_recordcoder_type_map_get(VALUE self)
|
77
106
|
{
|
78
|
-
t_pg_recordcoder *this =
|
107
|
+
t_pg_recordcoder *this = RTYPEDDATA_DATA( self );
|
79
108
|
|
80
109
|
return this->typemap;
|
81
110
|
}
|
@@ -155,7 +184,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
|
|
155
184
|
char *current_out;
|
156
185
|
char *end_capa_ptr;
|
157
186
|
|
158
|
-
p_typemap =
|
187
|
+
p_typemap = RTYPEDDATA_DATA( this->typemap );
|
159
188
|
p_typemap->funcs.fit_to_query( this->typemap, value );
|
160
189
|
|
161
190
|
/* Allocate a new string with embedded capacity and realloc exponential when needed. */
|
@@ -167,7 +196,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
|
|
167
196
|
for( i=0; i<RARRAY_LEN(value); i++){
|
168
197
|
char *ptr1;
|
169
198
|
char *ptr2;
|
170
|
-
|
199
|
+
long strlen;
|
171
200
|
int backslashs;
|
172
201
|
VALUE subint;
|
173
202
|
VALUE entry;
|
@@ -357,7 +386,7 @@ pg_text_dec_record(t_pg_coder *conv, char *input_line, int len, int _tuple, int
|
|
357
386
|
char *end_capa_ptr;
|
358
387
|
t_typemap *p_typemap;
|
359
388
|
|
360
|
-
p_typemap =
|
389
|
+
p_typemap = RTYPEDDATA_DATA( this->typemap );
|
361
390
|
expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
|
362
391
|
|
363
392
|
/* The received input string will probably have this->nfields fields. */
|
data/ext/pg_result.c
CHANGED
@@ -107,17 +107,34 @@ pgresult_approx_size(const PGresult *result)
|
|
107
107
|
* GC Mark function
|
108
108
|
*/
|
109
109
|
static void
|
110
|
-
pgresult_gc_mark(
|
110
|
+
pgresult_gc_mark( void *_this )
|
111
111
|
{
|
112
|
+
t_pg_result *this = (t_pg_result *)_this;
|
112
113
|
int i;
|
113
114
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
rb_gc_mark_movable( this->connection );
|
116
|
+
rb_gc_mark_movable( this->typemap );
|
117
|
+
rb_gc_mark_movable( this->tuple_hash );
|
118
|
+
rb_gc_mark_movable( this->field_map );
|
118
119
|
|
119
120
|
for( i=0; i < this->nfields; i++ ){
|
120
|
-
|
121
|
+
rb_gc_mark_movable( this->fnames[i] );
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
static void
|
126
|
+
pgresult_gc_compact( void *_this )
|
127
|
+
{
|
128
|
+
t_pg_result *this = (t_pg_result *)_this;
|
129
|
+
int i;
|
130
|
+
|
131
|
+
pg_gc_location( this->connection );
|
132
|
+
pg_gc_location( this->typemap );
|
133
|
+
pg_gc_location( this->tuple_hash );
|
134
|
+
pg_gc_location( this->field_map );
|
135
|
+
|
136
|
+
for( i=0; i < this->nfields; i++ ){
|
137
|
+
pg_gc_location( this->fnames[i] );
|
121
138
|
}
|
122
139
|
}
|
123
140
|
|
@@ -125,8 +142,9 @@ pgresult_gc_mark( t_pg_result *this )
|
|
125
142
|
* GC Free function
|
126
143
|
*/
|
127
144
|
static void
|
128
|
-
pgresult_clear(
|
145
|
+
pgresult_clear( void *_this )
|
129
146
|
{
|
147
|
+
t_pg_result *this = (t_pg_result *)_this;
|
130
148
|
if( this->pgresult && !this->autoclear ){
|
131
149
|
PQclear(this->pgresult);
|
132
150
|
#ifdef HAVE_RB_GC_ADJUST_MEMORY_USAGE
|
@@ -139,15 +157,17 @@ pgresult_clear( t_pg_result *this )
|
|
139
157
|
}
|
140
158
|
|
141
159
|
static void
|
142
|
-
pgresult_gc_free(
|
160
|
+
pgresult_gc_free( void *_this )
|
143
161
|
{
|
162
|
+
t_pg_result *this = (t_pg_result *)_this;
|
144
163
|
pgresult_clear( this );
|
145
164
|
xfree(this);
|
146
165
|
}
|
147
166
|
|
148
167
|
static size_t
|
149
|
-
pgresult_memsize(
|
168
|
+
pgresult_memsize( const void *_this )
|
150
169
|
{
|
170
|
+
const t_pg_result *this = (const t_pg_result *)_this;
|
151
171
|
/* Ideally the memory 'this' is pointing to should be taken into account as well.
|
152
172
|
* However we don't want to store two memory sizes in t_pg_result just for reporting by ObjectSpace.memsize_of.
|
153
173
|
*/
|
@@ -155,16 +175,15 @@ pgresult_memsize( t_pg_result *this )
|
|
155
175
|
}
|
156
176
|
|
157
177
|
static const rb_data_type_t pgresult_type = {
|
158
|
-
"
|
178
|
+
"PG::Result",
|
159
179
|
{
|
160
|
-
|
161
|
-
|
162
|
-
|
180
|
+
pgresult_gc_mark,
|
181
|
+
pgresult_gc_free,
|
182
|
+
pgresult_memsize,
|
183
|
+
pg_compact_callback(pgresult_gc_compact),
|
163
184
|
},
|
164
185
|
0, 0,
|
165
|
-
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
166
186
|
RUBY_TYPED_FREE_IMMEDIATELY,
|
167
|
-
#endif
|
168
187
|
};
|
169
188
|
|
170
189
|
/* Needed by sequel_pg gem, do not delete */
|
@@ -191,7 +210,7 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
|
|
191
210
|
this->pgresult = result;
|
192
211
|
this->connection = rb_pgconn;
|
193
212
|
this->typemap = pg_typemap_all_strings;
|
194
|
-
this->p_typemap =
|
213
|
+
this->p_typemap = RTYPEDDATA_DATA( this->typemap );
|
195
214
|
this->nfields = -1;
|
196
215
|
this->tuple_hash = Qnil;
|
197
216
|
this->field_map = Qnil;
|
@@ -202,11 +221,11 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
|
|
202
221
|
t_pg_connection *p_conn = pg_get_connection(rb_pgconn);
|
203
222
|
VALUE typemap = p_conn->type_map_for_results;
|
204
223
|
/* Type check is done when assigned to PG::Connection. */
|
205
|
-
t_typemap *p_typemap =
|
224
|
+
t_typemap *p_typemap = RTYPEDDATA_DATA(typemap);
|
206
225
|
|
207
226
|
this->enc_idx = p_conn->enc_idx;
|
208
227
|
this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
|
209
|
-
this->p_typemap =
|
228
|
+
this->p_typemap = RTYPEDDATA_DATA( this->typemap );
|
210
229
|
this->flags = p_conn->flags;
|
211
230
|
} else {
|
212
231
|
this->enc_idx = rb_locale_encindex();
|
@@ -270,7 +289,11 @@ pg_new_result_autoclear(PGresult *result, VALUE rb_pgconn)
|
|
270
289
|
* call-seq:
|
271
290
|
* res.check -> nil
|
272
291
|
*
|
273
|
-
* Raises appropriate exception if PG::Result is in a bad state
|
292
|
+
* Raises appropriate exception if PG::Result is in a bad state, which is:
|
293
|
+
* * +PGRES_BAD_RESPONSE+
|
294
|
+
* * +PGRES_FATAL_ERROR+
|
295
|
+
* * +PGRES_NONFATAL_ERROR+
|
296
|
+
* * +PGRES_PIPELINE_ABORTED+
|
274
297
|
*/
|
275
298
|
VALUE
|
276
299
|
pg_result_check( VALUE self )
|
@@ -295,10 +318,16 @@ pg_result_check( VALUE self )
|
|
295
318
|
case PGRES_SINGLE_TUPLE:
|
296
319
|
case PGRES_EMPTY_QUERY:
|
297
320
|
case PGRES_COMMAND_OK:
|
321
|
+
#ifdef HAVE_PQENTERPIPELINEMODE
|
322
|
+
case PGRES_PIPELINE_SYNC:
|
323
|
+
#endif
|
298
324
|
return self;
|
299
325
|
case PGRES_BAD_RESPONSE:
|
300
326
|
case PGRES_FATAL_ERROR:
|
301
327
|
case PGRES_NONFATAL_ERROR:
|
328
|
+
#ifdef HAVE_PQENTERPIPELINEMODE
|
329
|
+
case PGRES_PIPELINE_ABORTED:
|
330
|
+
#endif
|
302
331
|
error = rb_str_new2( PQresultErrorMessage(this->pgresult) );
|
303
332
|
break;
|
304
333
|
default:
|
@@ -353,7 +382,7 @@ pg_result_clear(VALUE self)
|
|
353
382
|
* call-seq:
|
354
383
|
* res.cleared? -> boolean
|
355
384
|
*
|
356
|
-
* Returns +true+ if the backend result memory has been
|
385
|
+
* Returns +true+ if the backend result memory has been freed.
|
357
386
|
*/
|
358
387
|
VALUE
|
359
388
|
pgresult_cleared_p( VALUE self )
|
@@ -367,7 +396,7 @@ pgresult_cleared_p( VALUE self )
|
|
367
396
|
* res.autoclear? -> boolean
|
368
397
|
*
|
369
398
|
* Returns +true+ if the underlying C struct will be cleared at the end of a callback.
|
370
|
-
* This applies only to Result objects received by the block to PG::
|
399
|
+
* This applies only to Result objects received by the block to PG::Connection#set_notice_receiver .
|
371
400
|
*
|
372
401
|
* All other Result objects are automatically cleared by the GC when the object is no longer in use or manually by PG::Result#clear .
|
373
402
|
*
|
@@ -495,6 +524,9 @@ static void pgresult_init_fnames(VALUE self)
|
|
495
524
|
* * +PGRES_NONFATAL_ERROR+
|
496
525
|
* * +PGRES_FATAL_ERROR+
|
497
526
|
* * +PGRES_COPY_BOTH+
|
527
|
+
* * +PGRES_SINGLE_TUPLE+
|
528
|
+
* * +PGRES_PIPELINE_SYNC+
|
529
|
+
* * +PGRES_PIPELINE_ABORTED+
|
498
530
|
*/
|
499
531
|
static VALUE
|
500
532
|
pgresult_result_status(VALUE self)
|
@@ -506,7 +538,7 @@ pgresult_result_status(VALUE self)
|
|
506
538
|
* call-seq:
|
507
539
|
* res.res_status( status ) -> String
|
508
540
|
*
|
509
|
-
* Returns the string representation of
|
541
|
+
* Returns the string representation of +status+.
|
510
542
|
*
|
511
543
|
*/
|
512
544
|
static VALUE
|
@@ -1003,7 +1035,7 @@ pgresult_cmd_tuples(VALUE self)
|
|
1003
1035
|
{
|
1004
1036
|
long n;
|
1005
1037
|
n = strtol(PQcmdTuples(pgresult_get(self)),NULL, 10);
|
1006
|
-
return
|
1038
|
+
return LONG2NUM(n);
|
1007
1039
|
}
|
1008
1040
|
|
1009
1041
|
/*
|
@@ -1325,14 +1357,11 @@ pgresult_type_map_set(VALUE self, VALUE typemap)
|
|
1325
1357
|
t_pg_result *this = pgresult_get_this(self);
|
1326
1358
|
t_typemap *p_typemap;
|
1327
1359
|
|
1328
|
-
|
1329
|
-
|
1330
|
-
rb_obj_classname( typemap ) );
|
1331
|
-
}
|
1332
|
-
Data_Get_Struct(typemap, t_typemap, p_typemap);
|
1360
|
+
/* Check type of method param */
|
1361
|
+
TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, p_typemap);
|
1333
1362
|
|
1334
1363
|
this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
|
1335
|
-
this->p_typemap =
|
1364
|
+
this->p_typemap = RTYPEDDATA_DATA( this->typemap );
|
1336
1365
|
|
1337
1366
|
return typemap;
|
1338
1367
|
}
|
@@ -1531,7 +1560,7 @@ pgresult_stream_each_tuple(VALUE self)
|
|
1531
1560
|
* It can be set to one of:
|
1532
1561
|
* * +:string+ to use String based field names
|
1533
1562
|
* * +:symbol+ to use Symbol based field names
|
1534
|
-
* * +:static_symbol+ to use pinned Symbol (can not be garbage collected) - Don't use this, it will probably removed in future.
|
1563
|
+
* * +:static_symbol+ to use pinned Symbol (can not be garbage collected) - Don't use this, it will probably be removed in future.
|
1535
1564
|
*
|
1536
1565
|
* The default is retrieved from PG::Connection#field_name_type , which defaults to +:string+ .
|
1537
1566
|
*
|
@@ -1587,7 +1616,8 @@ init_pg_result()
|
|
1587
1616
|
sym_symbol = ID2SYM(rb_intern("symbol"));
|
1588
1617
|
sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
|
1589
1618
|
|
1590
|
-
rb_cPGresult = rb_define_class_under( rb_mPG, "Result",
|
1619
|
+
rb_cPGresult = rb_define_class_under( rb_mPG, "Result", rb_cObject );
|
1620
|
+
rb_undef_alloc_func(rb_cPGresult);
|
1591
1621
|
rb_include_module(rb_cPGresult, rb_mEnumerable);
|
1592
1622
|
rb_include_module(rb_cPGresult, rb_mPGconstants);
|
1593
1623
|
|
data/ext/pg_text_decoder.c
CHANGED
@@ -854,7 +854,7 @@ pg_text_dec_inet(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
|
|
854
854
|
|
855
855
|
ip_int_native = read_nbo32(dst);
|
856
856
|
|
857
|
-
/* Work around broken IPAddr behavior of
|
857
|
+
/* Work around broken IPAddr behavior of converting portion
|
858
858
|
of address after netmask to 0 */
|
859
859
|
switch (mask) {
|
860
860
|
case 0:
|
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
|
|
@@ -403,11 +403,11 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
403
403
|
*optr++ = hextab[c >> 4];
|
404
404
|
*optr++ = hextab[c & 0xf];
|
405
405
|
}
|
406
|
-
return optr - out;
|
406
|
+
return (int)(optr - out);
|
407
407
|
}else{
|
408
408
|
*intermediate = rb_obj_as_string(value);
|
409
409
|
/* The output starts with "\x" and each character is converted to hex. */
|
410
|
-
return 2 +
|
410
|
+
return 2 + RSTRING_LENINT(*intermediate) * 2;
|
411
411
|
}
|
412
412
|
}
|
413
413
|
|
@@ -610,8 +610,8 @@ quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
|
610
610
|
static char *
|
611
611
|
pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
|
612
612
|
{
|
613
|
-
|
614
|
-
|
613
|
+
long i;
|
614
|
+
long nr_elems;
|
615
615
|
|
616
616
|
Check_Type(value, T_ARRAY);
|
617
617
|
nr_elems = RARRAY_LEN(value);
|
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;
|
63
|
+
}
|
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
|
+
|
72
|
+
static void
|
73
|
+
pg_tuple_gc_mark( void *_this )
|
74
|
+
{
|
75
|
+
t_pg_tuple *this = (t_pg_tuple *)_this;
|
76
|
+
int i;
|
77
|
+
|
78
|
+
if( !this ) return;
|
79
|
+
rb_gc_mark_movable( this->result );
|
80
|
+
rb_gc_mark_movable( this->typemap );
|
81
|
+
rb_gc_mark_movable( this->field_map );
|
82
|
+
|
83
|
+
for( i = 0; i < this->num_fields; i++ ){
|
84
|
+
rb_gc_mark_movable( this->values[i] );
|
62
85
|
}
|
86
|
+
rb_gc_mark_movable( pg_tuple_get_field_names(this) );
|
63
87
|
}
|
64
88
|
|
65
89
|
static void
|
66
|
-
|
90
|
+
pg_tuple_gc_compact( void *_this )
|
67
91
|
{
|
92
|
+
t_pg_tuple *this = (t_pg_tuple *)_this;
|
68
93
|
int i;
|
69
94
|
|
70
95
|
if( !this ) return;
|
71
|
-
|
72
|
-
|
73
|
-
|
96
|
+
pg_gc_location( this->result );
|
97
|
+
pg_gc_location( this->typemap );
|
98
|
+
pg_gc_location( this->field_map );
|
74
99
|
|
75
100
|
for( i = 0; i < this->num_fields; i++ ){
|
76
|
-
|
101
|
+
pg_gc_location( this->values[i] );
|
77
102
|
}
|
78
|
-
|
103
|
+
pg_gc_location( *pg_tuple_get_field_names_ptr(this) );
|
79
104
|
}
|
80
105
|
|
81
106
|
static void
|
82
|
-
pg_tuple_gc_free(
|
107
|
+
pg_tuple_gc_free( void *_this )
|
83
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
|
-
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
104
131
|
RUBY_TYPED_FREE_IMMEDIATELY,
|
105
|
-
#endif
|
106
132
|
};
|
107
133
|
|
108
134
|
/*
|
@@ -172,7 +198,7 @@ pg_tuple_materialize_field(t_pg_tuple *this, int col)
|
|
172
198
|
VALUE value = this->values[col];
|
173
199
|
|
174
200
|
if( value == Qundef ){
|
175
|
-
t_typemap *p_typemap =
|
201
|
+
t_typemap *p_typemap = RTYPEDDATA_DATA( this->typemap );
|
176
202
|
|
177
203
|
pgresult_get(this->result); /* make sure we have a valid PGresult object */
|
178
204
|
value = p_typemap->funcs.typecast_result_value(p_typemap, this->result, this->row_num, col);
|
@@ -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();
|