pg 1.0.0 → 1.5.9
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/Gemfile +20 -0
- data/History.md +932 -0
- data/Manifest.txt +8 -3
- data/README-Windows.rdoc +4 -4
- data/README.ja.md +300 -0
- data/README.md +286 -0
- data/Rakefile +41 -138
- data/Rakefile.cross +71 -66
- data/certs/ged.pem +24 -0
- data/certs/kanis@comcard.de.pem +20 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/certs/larskanis-2024.pem +24 -0
- data/ext/errorcodes.def +84 -5
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +23 -6
- data/ext/extconf.rb +109 -25
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +213 -155
- data/ext/pg.h +89 -23
- data/ext/pg_binary_decoder.c +164 -16
- data/ext/pg_binary_encoder.c +238 -13
- data/ext/pg_coder.c +159 -35
- data/ext/pg_connection.c +1584 -967
- data/ext/pg_copy_coder.c +373 -43
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +522 -0
- data/ext/pg_result.c +710 -217
- data/ext/pg_text_decoder.c +630 -43
- data/ext/pg_text_encoder.c +222 -72
- data/ext/pg_tuple.c +572 -0
- 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} +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 +202 -0
- data/lib/pg/basic_type_map_for_results.rb +104 -0
- data/lib/pg/basic_type_registry.rb +311 -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 +769 -70
- data/lib/pg/exceptions.rb +22 -2
- data/lib/pg/result.rb +14 -2
- data/lib/pg/text_decoder/date.rb +21 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +17 -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 +13 -0
- data/lib/pg/text_encoder/inet.rb +31 -0
- data/lib/pg/text_encoder/json.rb +17 -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 -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 +36 -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.tar.gz.sig +0 -0
- metadata +138 -223
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +0 -422
- data/README.ja.rdoc +0 -14
- data/README.rdoc +0 -167
- data/lib/pg/basic_type_mapping.rb +0 -426
- data/lib/pg/constants.rb +0 -11
- data/lib/pg/text_decoder.rb +0 -51
- data/lib/pg/text_encoder.rb +0 -35
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -348
- data/spec/pg/basic_type_mapping_spec.rb +0 -305
- data/spec/pg/connection_spec.rb +0 -1719
- data/spec/pg/result_spec.rb +0 -456
- 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 -777
- data/spec/pg_spec.rb +0 -50
data/ext/pg_binary_encoder.c
CHANGED
@@ -1,16 +1,19 @@
|
|
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
|
-
#include "
|
8
|
+
#include "pg_util.h"
|
9
9
|
#ifdef HAVE_INTTYPES_H
|
10
10
|
#include <inttypes.h>
|
11
11
|
#endif
|
12
12
|
|
13
13
|
VALUE rb_mPG_BinaryEncoder;
|
14
|
+
static ID s_id_year;
|
15
|
+
static ID s_id_month;
|
16
|
+
static ID s_id_day;
|
14
17
|
|
15
18
|
|
16
19
|
/*
|
@@ -25,11 +28,12 @@ static int
|
|
25
28
|
pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
26
29
|
{
|
27
30
|
char mybool;
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
if (value == Qtrue) {
|
32
|
+
mybool = 1;
|
33
|
+
} else if (value == Qfalse) {
|
34
|
+
mybool = 0;
|
35
|
+
} else {
|
36
|
+
rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
|
33
37
|
}
|
34
38
|
if(out) *out = mybool;
|
35
39
|
return 1;
|
@@ -38,7 +42,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
|
|
38
42
|
/*
|
39
43
|
* Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
|
40
44
|
*
|
41
|
-
* This is the encoder class for the PostgreSQL int2 type.
|
45
|
+
* This is the encoder class for the PostgreSQL +int2+ (alias +smallint+) type.
|
42
46
|
*
|
43
47
|
* Non-Number values are expected to have method +to_i+ defined.
|
44
48
|
*
|
@@ -55,9 +59,9 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
|
|
55
59
|
}
|
56
60
|
|
57
61
|
/*
|
58
|
-
* Document-class: PG::BinaryEncoder::
|
62
|
+
* Document-class: PG::BinaryEncoder::Int4 < PG::SimpleEncoder
|
59
63
|
*
|
60
|
-
* This is the encoder class for the PostgreSQL int4 type.
|
64
|
+
* This is the encoder class for the PostgreSQL +int4+ (alias +integer+) type.
|
61
65
|
*
|
62
66
|
* Non-Number values are expected to have method +to_i+ defined.
|
63
67
|
*
|
@@ -74,9 +78,9 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
|
|
74
78
|
}
|
75
79
|
|
76
80
|
/*
|
77
|
-
* Document-class: PG::BinaryEncoder::
|
81
|
+
* Document-class: PG::BinaryEncoder::Int8 < PG::SimpleEncoder
|
78
82
|
*
|
79
|
-
* This is the encoder class for the PostgreSQL int8 type.
|
83
|
+
* This is the encoder class for the PostgreSQL +int8+ (alias +bigint+) type.
|
80
84
|
*
|
81
85
|
* Non-Number values are expected to have method +to_i+ defined.
|
82
86
|
*
|
@@ -92,6 +96,215 @@ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
|
|
92
96
|
return 8;
|
93
97
|
}
|
94
98
|
|
99
|
+
/*
|
100
|
+
* Document-class: PG::BinaryEncoder::Float4 < PG::SimpleEncoder
|
101
|
+
*
|
102
|
+
* This is the binary encoder class for the PostgreSQL +float4+ type.
|
103
|
+
*
|
104
|
+
*/
|
105
|
+
static int
|
106
|
+
pg_bin_enc_float4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
107
|
+
{
|
108
|
+
union {
|
109
|
+
float f;
|
110
|
+
int32_t i;
|
111
|
+
} swap4;
|
112
|
+
|
113
|
+
if(out){
|
114
|
+
swap4.f = NUM2DBL(*intermediate);
|
115
|
+
write_nbo32(swap4.i, out);
|
116
|
+
}else{
|
117
|
+
*intermediate = value;
|
118
|
+
}
|
119
|
+
return 4;
|
120
|
+
}
|
121
|
+
|
122
|
+
/*
|
123
|
+
* Document-class: PG::BinaryEncoder::Float8 < PG::SimpleEncoder
|
124
|
+
*
|
125
|
+
* This is the binary encoder class for the PostgreSQL +float8+ type.
|
126
|
+
*
|
127
|
+
*/
|
128
|
+
static int
|
129
|
+
pg_bin_enc_float8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
130
|
+
{
|
131
|
+
union {
|
132
|
+
double f;
|
133
|
+
int64_t i;
|
134
|
+
} swap8;
|
135
|
+
|
136
|
+
if(out){
|
137
|
+
swap8.f = NUM2DBL(*intermediate);
|
138
|
+
write_nbo64(swap8.i, out);
|
139
|
+
}else{
|
140
|
+
*intermediate = value;
|
141
|
+
}
|
142
|
+
return 8;
|
143
|
+
}
|
144
|
+
|
145
|
+
#define PG_INT32_MIN (-0x7FFFFFFF-1)
|
146
|
+
#define PG_INT32_MAX (0x7FFFFFFF)
|
147
|
+
#define PG_INT64_MIN (-0x7FFFFFFFFFFFFFFFL - 1)
|
148
|
+
#define PG_INT64_MAX 0x7FFFFFFFFFFFFFFFL
|
149
|
+
|
150
|
+
/*
|
151
|
+
* Document-class: PG::BinaryEncoder::Timestamp < PG::SimpleEncoder
|
152
|
+
*
|
153
|
+
* This is a encoder class for conversion of Ruby Time objects to PostgreSQL binary timestamps.
|
154
|
+
*
|
155
|
+
* The following flags can be used to specify timezone interpretation:
|
156
|
+
* * +PG::Coder::TIMESTAMP_DB_UTC+ : Send timestamp as UTC time (default)
|
157
|
+
* * +PG::Coder::TIMESTAMP_DB_LOCAL+ : Send timestamp as local time (slower)
|
158
|
+
*
|
159
|
+
* Example:
|
160
|
+
* enco = PG::BinaryEncoder::Timestamp.new(flags: PG::Coder::TIMESTAMP_DB_UTC)
|
161
|
+
* enco.encode(Time.utc(2000, 1, 1)) # => "\x00\x00\x00\x00\x00\x00\x00\x00"
|
162
|
+
*
|
163
|
+
* String values are expected to contain a binary data with a length of 8 byte.
|
164
|
+
*
|
165
|
+
*/
|
166
|
+
static int
|
167
|
+
pg_bin_enc_timestamp(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
168
|
+
{
|
169
|
+
if(out){
|
170
|
+
int64_t timestamp;
|
171
|
+
struct timespec ts;
|
172
|
+
|
173
|
+
/* second call -> write data to *out */
|
174
|
+
switch(TYPE(*intermediate)){
|
175
|
+
case T_STRING:
|
176
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
177
|
+
case T_TRUE:
|
178
|
+
write_nbo64(PG_INT64_MAX, out);
|
179
|
+
return 8;
|
180
|
+
case T_FALSE:
|
181
|
+
write_nbo64(PG_INT64_MIN, out);
|
182
|
+
return 8;
|
183
|
+
}
|
184
|
+
|
185
|
+
ts = rb_time_timespec(*intermediate);
|
186
|
+
/* PostgreSQL's timestamp is based on year 2000 and Ruby's time is based on 1970.
|
187
|
+
* Adjust the 30 years difference. */
|
188
|
+
timestamp = ((int64_t)ts.tv_sec - 10957L * 24L * 3600L) * 1000000 + ((int64_t)ts.tv_nsec / 1000);
|
189
|
+
|
190
|
+
if( this->flags & PG_CODER_TIMESTAMP_DB_LOCAL ) {
|
191
|
+
/* send as local time */
|
192
|
+
timestamp += NUM2LL(rb_funcall(*intermediate, rb_intern("utc_offset"), 0)) * 1000000;
|
193
|
+
}
|
194
|
+
|
195
|
+
write_nbo64(timestamp, out);
|
196
|
+
}else{
|
197
|
+
/* first call -> determine the required length */
|
198
|
+
if(TYPE(value) == T_STRING){
|
199
|
+
char *pstr = RSTRING_PTR(value);
|
200
|
+
if(RSTRING_LEN(value) >= 1){
|
201
|
+
switch(pstr[0]) {
|
202
|
+
case 'I':
|
203
|
+
case 'i':
|
204
|
+
*intermediate = Qtrue;
|
205
|
+
return 8;
|
206
|
+
case '-':
|
207
|
+
if (RSTRING_LEN(value) >= 2 && (pstr[1] == 'I' || pstr[1] == 'i')) {
|
208
|
+
*intermediate = Qfalse;
|
209
|
+
return 8;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
215
|
+
}
|
216
|
+
|
217
|
+
if( this->flags & PG_CODER_TIMESTAMP_DB_LOCAL ) {
|
218
|
+
/* make a local time, so that utc_offset is set */
|
219
|
+
value = rb_funcall(value, rb_intern("getlocal"), 0);
|
220
|
+
}
|
221
|
+
*intermediate = value;
|
222
|
+
}
|
223
|
+
return 8;
|
224
|
+
}
|
225
|
+
|
226
|
+
#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
|
227
|
+
int
|
228
|
+
date2j(int year, int month, int day)
|
229
|
+
{
|
230
|
+
int julian;
|
231
|
+
int century;
|
232
|
+
|
233
|
+
if (month > 2)
|
234
|
+
{
|
235
|
+
month += 1;
|
236
|
+
year += 4800;
|
237
|
+
}
|
238
|
+
else
|
239
|
+
{
|
240
|
+
month += 13;
|
241
|
+
year += 4799;
|
242
|
+
}
|
243
|
+
|
244
|
+
century = year / 100;
|
245
|
+
julian = year * 365 - 32167;
|
246
|
+
julian += year / 4 - century + century / 4;
|
247
|
+
julian += 7834 * month / 256 + day;
|
248
|
+
|
249
|
+
return julian;
|
250
|
+
} /* date2j() */
|
251
|
+
|
252
|
+
/*
|
253
|
+
* Document-class: PG::BinaryEncoder::Date < PG::SimpleEncoder
|
254
|
+
*
|
255
|
+
* This is a encoder class for conversion of Ruby Date objects to PostgreSQL binary date.
|
256
|
+
*
|
257
|
+
* String values are expected to contain a binary data with a length of 4 byte.
|
258
|
+
*
|
259
|
+
*/
|
260
|
+
static int
|
261
|
+
pg_bin_enc_date(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
262
|
+
{
|
263
|
+
if(out){
|
264
|
+
/* second call -> write data to *out */
|
265
|
+
switch(TYPE(*intermediate)){
|
266
|
+
case T_STRING:
|
267
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
268
|
+
case T_TRUE:
|
269
|
+
write_nbo32(PG_INT32_MAX, out);
|
270
|
+
return 4;
|
271
|
+
case T_FALSE:
|
272
|
+
write_nbo32(PG_INT32_MIN, out);
|
273
|
+
return 4;
|
274
|
+
}
|
275
|
+
|
276
|
+
VALUE year = rb_funcall(value, s_id_year, 0);
|
277
|
+
VALUE month = rb_funcall(value, s_id_month, 0);
|
278
|
+
VALUE day = rb_funcall(value, s_id_day, 0);
|
279
|
+
int jday = date2j(NUM2INT(year), NUM2INT(month), NUM2INT(day)) - POSTGRES_EPOCH_JDATE;
|
280
|
+
write_nbo32(jday, out);
|
281
|
+
|
282
|
+
}else{
|
283
|
+
/* first call -> determine the required length */
|
284
|
+
if(TYPE(value) == T_STRING){
|
285
|
+
char *pstr = RSTRING_PTR(value);
|
286
|
+
if(RSTRING_LEN(value) >= 1){
|
287
|
+
switch(pstr[0]) {
|
288
|
+
case 'I':
|
289
|
+
case 'i':
|
290
|
+
*intermediate = Qtrue;
|
291
|
+
return 4;
|
292
|
+
case '-':
|
293
|
+
if (RSTRING_LEN(value) >= 2 && (pstr[1] == 'I' || pstr[1] == 'i')) {
|
294
|
+
*intermediate = Qfalse;
|
295
|
+
return 4;
|
296
|
+
}
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
301
|
+
}
|
302
|
+
|
303
|
+
*intermediate = value;
|
304
|
+
}
|
305
|
+
return 4;
|
306
|
+
}
|
307
|
+
|
95
308
|
/*
|
96
309
|
* Document-class: PG::BinaryEncoder::FromBase64 < PG::CompositeEncoder
|
97
310
|
*
|
@@ -138,8 +351,12 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
|
|
138
351
|
}
|
139
352
|
|
140
353
|
void
|
141
|
-
init_pg_binary_encoder()
|
354
|
+
init_pg_binary_encoder(void)
|
142
355
|
{
|
356
|
+
s_id_year = rb_intern("year");
|
357
|
+
s_id_month = rb_intern("month");
|
358
|
+
s_id_day = rb_intern("day");
|
359
|
+
|
143
360
|
/* This module encapsulates all encoder classes with binary output format */
|
144
361
|
rb_mPG_BinaryEncoder = rb_define_module_under( rb_mPG, "BinaryEncoder" );
|
145
362
|
|
@@ -152,10 +369,18 @@ init_pg_binary_encoder()
|
|
152
369
|
pg_define_coder( "Int4", pg_bin_enc_int4, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
153
370
|
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Int8", rb_cPG_SimpleEncoder ); */
|
154
371
|
pg_define_coder( "Int8", pg_bin_enc_int8, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
372
|
+
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Float4", rb_cPG_SimpleEncoder ); */
|
373
|
+
pg_define_coder( "Float4", pg_bin_enc_float4, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
374
|
+
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Float8", rb_cPG_SimpleEncoder ); */
|
375
|
+
pg_define_coder( "Float8", pg_bin_enc_float8, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
155
376
|
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "String", rb_cPG_SimpleEncoder ); */
|
156
377
|
pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
157
378
|
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
|
158
379
|
pg_define_coder( "Bytea", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
380
|
+
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Timestamp", rb_cPG_SimpleEncoder ); */
|
381
|
+
pg_define_coder( "Timestamp", pg_bin_enc_timestamp, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
382
|
+
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Date", rb_cPG_SimpleEncoder ); */
|
383
|
+
pg_define_coder( "Date", pg_bin_enc_date, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
|
159
384
|
|
160
385
|
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "FromBase64", rb_cPG_CompositeEncoder ); */
|
161
386
|
pg_define_coder( "FromBase64", pg_bin_enc_from_base64, rb_cPG_CompositeEncoder, rb_mPG_BinaryEncoder );
|