pg 0.18.1 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.appveyor.yml +42 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +117 -0
- data/.github/workflows/source-gem.yml +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/BSDL +2 -2
- data/Gemfile +17 -0
- data/History.md +901 -0
- data/Manifest.txt +8 -21
- data/README-Windows.rdoc +17 -28
- data/README.ja.md +300 -0
- data/README.md +286 -0
- data/Rakefile +43 -131
- data/Rakefile.cross +89 -70
- 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 +113 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +36 -2
- data/ext/extconf.rb +128 -55
- data/ext/gvl_wrappers.c +8 -0
- data/ext/gvl_wrappers.h +44 -33
- data/ext/pg.c +228 -202
- data/ext/pg.h +108 -99
- data/ext/pg_binary_decoder.c +164 -16
- data/ext/pg_binary_encoder.c +249 -22
- data/ext/pg_coder.c +189 -44
- data/ext/pg_connection.c +1889 -1195
- data/ext/pg_copy_coder.c +398 -42
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +522 -0
- data/ext/pg_result.c +729 -234
- data/ext/pg_text_decoder.c +635 -52
- data/ext/pg_text_encoder.c +294 -130
- data/ext/pg_tuple.c +572 -0
- data/ext/pg_type_map.c +64 -23
- data/ext/pg_type_map_all_strings.c +21 -7
- data/ext/pg_type_map_by_class.c +59 -27
- data/ext/pg_type_map_by_column.c +86 -43
- data/ext/pg_type_map_by_mri_type.c +50 -21
- data/ext/pg_type_map_by_oid.c +62 -29
- data/ext/pg_type_map_in_ruby.c +59 -28
- data/ext/{util.c → pg_util.c} +13 -13
- data/ext/{util.h → pg_util.h} +3 -3
- 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 +303 -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 +813 -74
- data/lib/pg/exceptions.rb +16 -2
- data/lib/pg/result.rb +24 -7
- data/lib/pg/text_decoder/date.rb +18 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +14 -0
- data/lib/pg/text_decoder/numeric.rb +9 -0
- data/lib/pg/text_decoder/timestamp.rb +30 -0
- data/lib/pg/text_encoder/date.rb +12 -0
- data/lib/pg/text_encoder/inet.rb +28 -0
- data/lib/pg/text_encoder/json.rb +14 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +3 -2
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +106 -41
- data/misc/openssl-pg-segfault.rb +31 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +21 -0
- data/misc/postgres/lib/postgres.rb +16 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +21 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
- data/pg.gemspec +34 -0
- data/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +1 -1
- data/sample/async_api.rb +4 -8
- data/sample/async_copyto.rb +1 -1
- data/sample/async_mixed.rb +1 -1
- data/sample/check_conn.rb +1 -1
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +1 -1
- data/sample/copyto.rb +1 -1
- data/sample/cursor.rb +1 -1
- data/sample/disk_usage_report.rb +6 -15
- data/sample/issue-119.rb +2 -2
- data/sample/losample.rb +1 -1
- data/sample/minimal-testcase.rb +2 -2
- data/sample/notify_wait.rb +1 -1
- data/sample/pg_statistics.rb +6 -15
- data/sample/replication_monitor.rb +9 -18
- data/sample/test_binary_values.rb +1 -1
- data/sample/wal_shipper.rb +2 -2
- data/sample/warehouse_partitions.rb +8 -17
- data.tar.gz.sig +0 -0
- metadata +135 -207
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -5378
- data/History.rdoc +0 -297
- data/README.ja.rdoc +0 -14
- data/README.rdoc +0 -161
- data/lib/pg/basic_type_mapping.rb +0 -399
- data/lib/pg/constants.rb +0 -11
- data/lib/pg/text_decoder.rb +0 -42
- data/lib/pg/text_encoder.rb +0 -27
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -355
- data/spec/pg/basic_type_mapping_spec.rb +0 -251
- data/spec/pg/connection_spec.rb +0 -1459
- data/spec/pg/result_spec.rb +0 -449
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -222
- data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
- data/spec/pg/type_map_by_oid_spec.rb +0 -149
- data/spec/pg/type_map_in_ruby_spec.rb +0 -164
- data/spec/pg/type_map_spec.rb +0 -22
- data/spec/pg/type_spec.rb +0 -665
- data/spec/pg_spec.rb +0 -50
data/ext/pg_text_encoder.c
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* pg_text_encoder.c - PG::TextEncoder module
|
|
3
|
-
* $Id
|
|
3
|
+
* $Id$
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* intermediate - Pointer to a VALUE that might be set by the encoding function to some
|
|
29
29
|
* value in the first call that can be retrieved later in the second call.
|
|
30
30
|
* This VALUE is not yet initialized by the caller.
|
|
31
|
+
* enc_idx - Index of the output Encoding that strings should be converted to.
|
|
31
32
|
*
|
|
32
33
|
* Returns:
|
|
33
34
|
* >= 0 - If out==NULL the encoder function must return the expected output buffer size.
|
|
@@ -40,15 +41,20 @@
|
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
#include "pg.h"
|
|
43
|
-
#include "
|
|
44
|
+
#include "pg_util.h"
|
|
45
|
+
#ifdef HAVE_INTTYPES_H
|
|
44
46
|
#include <inttypes.h>
|
|
47
|
+
#endif
|
|
45
48
|
#include <math.h>
|
|
46
49
|
|
|
47
50
|
VALUE rb_mPG_TextEncoder;
|
|
48
51
|
static ID s_id_encode;
|
|
49
52
|
static ID s_id_to_i;
|
|
53
|
+
static ID s_id_to_s;
|
|
54
|
+
static ID s_cBigDecimal;
|
|
55
|
+
static VALUE s_str_F;
|
|
50
56
|
|
|
51
|
-
static int pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate);
|
|
57
|
+
static int pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx);
|
|
52
58
|
|
|
53
59
|
VALUE
|
|
54
60
|
pg_obj_to_i( VALUE value )
|
|
@@ -74,7 +80,7 @@ pg_obj_to_i( VALUE value )
|
|
|
74
80
|
*
|
|
75
81
|
*/
|
|
76
82
|
static int
|
|
77
|
-
pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
|
83
|
+
pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
78
84
|
{
|
|
79
85
|
switch( TYPE(value) ){
|
|
80
86
|
case T_FALSE:
|
|
@@ -92,10 +98,10 @@ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
92
98
|
if(out) *out = '1';
|
|
93
99
|
return 1;
|
|
94
100
|
} else {
|
|
95
|
-
return pg_text_enc_integer(this, value, out, intermediate);
|
|
101
|
+
return pg_text_enc_integer(this, value, out, intermediate, enc_idx);
|
|
96
102
|
}
|
|
97
103
|
default:
|
|
98
|
-
return pg_coder_enc_to_s(this, value, out, intermediate);
|
|
104
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
|
99
105
|
}
|
|
100
106
|
/* never reached */
|
|
101
107
|
return 0;
|
|
@@ -111,45 +117,71 @@ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
111
117
|
*
|
|
112
118
|
*/
|
|
113
119
|
int
|
|
114
|
-
pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
|
120
|
+
pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
115
121
|
{
|
|
116
|
-
|
|
122
|
+
VALUE str = rb_obj_as_string(value);
|
|
123
|
+
if( ENCODING_GET(str) == enc_idx ){
|
|
124
|
+
*intermediate = str;
|
|
125
|
+
}else{
|
|
126
|
+
*intermediate = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
|
|
127
|
+
}
|
|
117
128
|
return -1;
|
|
118
129
|
}
|
|
119
130
|
|
|
131
|
+
static int
|
|
132
|
+
count_leading_zero_bits(unsigned long long x)
|
|
133
|
+
{
|
|
134
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
135
|
+
return __builtin_clzll(x);
|
|
136
|
+
#elif defined(_MSC_VER)
|
|
137
|
+
DWORD r = 0;
|
|
138
|
+
_BitScanForward64(&r, x);
|
|
139
|
+
return (int)r;
|
|
140
|
+
#else
|
|
141
|
+
unsigned int a;
|
|
142
|
+
for(a=0; a < sizeof(unsigned long long) * 8; a++){
|
|
143
|
+
if( x & (1 << (sizeof(unsigned long long) * 8 - 1))) return a;
|
|
144
|
+
x <<= 1;
|
|
145
|
+
}
|
|
146
|
+
return a;
|
|
147
|
+
#endif
|
|
148
|
+
}
|
|
120
149
|
|
|
121
150
|
/*
|
|
122
151
|
* Document-class: PG::TextEncoder::Integer < PG::SimpleEncoder
|
|
123
152
|
*
|
|
124
|
-
* This is the encoder class for the PostgreSQL
|
|
153
|
+
* This is the encoder class for the PostgreSQL integer types.
|
|
125
154
|
*
|
|
126
155
|
* Non-Integer values are expected to have method +to_i+ defined.
|
|
127
156
|
*
|
|
128
157
|
*/
|
|
129
158
|
static int
|
|
130
|
-
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
|
159
|
+
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
131
160
|
{
|
|
132
161
|
if(out){
|
|
133
162
|
if(TYPE(*intermediate) == T_STRING){
|
|
134
|
-
return pg_coder_enc_to_s(this, value, out, intermediate);
|
|
163
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
|
135
164
|
}else{
|
|
136
165
|
char *start = out;
|
|
137
166
|
int len;
|
|
138
167
|
int neg = 0;
|
|
139
|
-
long long
|
|
168
|
+
long long sll = NUM2LL(*intermediate);
|
|
169
|
+
unsigned long long ll;
|
|
140
170
|
|
|
141
|
-
if (
|
|
142
|
-
/*
|
|
143
|
-
* as a positive integer,
|
|
171
|
+
if (sll < 0) {
|
|
172
|
+
/* Avoid problems with the most negative integer not being representable
|
|
173
|
+
* as a positive integer, by using unsigned long long for encoding.
|
|
144
174
|
*/
|
|
145
|
-
ll = -
|
|
175
|
+
ll = -sll;
|
|
146
176
|
neg = 1;
|
|
177
|
+
} else {
|
|
178
|
+
ll = sll;
|
|
147
179
|
}
|
|
148
180
|
|
|
149
181
|
/* Compute the result string backwards. */
|
|
150
182
|
do {
|
|
151
|
-
long long remainder;
|
|
152
|
-
long long oldval = ll;
|
|
183
|
+
unsigned long long remainder;
|
|
184
|
+
unsigned long long oldval = ll;
|
|
153
185
|
|
|
154
186
|
ll /= 10;
|
|
155
187
|
remainder = oldval - ll * 10;
|
|
@@ -159,7 +191,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
159
191
|
if (neg)
|
|
160
192
|
*out++ = '-';
|
|
161
193
|
|
|
162
|
-
len = out - start;
|
|
194
|
+
len = (int)(out - start);
|
|
163
195
|
|
|
164
196
|
/* Reverse string. */
|
|
165
197
|
out--;
|
|
@@ -176,45 +208,17 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
176
208
|
}else{
|
|
177
209
|
*intermediate = pg_obj_to_i(value);
|
|
178
210
|
if(TYPE(*intermediate) == T_FIXNUM){
|
|
179
|
-
int len;
|
|
180
211
|
long long sll = NUM2LL(*intermediate);
|
|
181
|
-
long long ll = sll < 0 ? -sll : sll;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if( ll < 100 ){
|
|
185
|
-
len = ll < 10 ? 1 : 2;
|
|
186
|
-
}else{
|
|
187
|
-
len = ll < 1000 ? 3 : 4;
|
|
188
|
-
}
|
|
189
|
-
}else{
|
|
190
|
-
if( ll < 1000000 ){
|
|
191
|
-
len = ll < 100000 ? 5 : 6;
|
|
192
|
-
}else{
|
|
193
|
-
len = ll < 10000000 ? 7 : 8;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}else{
|
|
197
|
-
if( ll < 1000000000000LL ){
|
|
198
|
-
if( ll < 10000000000LL ){
|
|
199
|
-
len = ll < 1000000000LL ? 9 : 10;
|
|
200
|
-
}else{
|
|
201
|
-
len = ll < 100000000000LL ? 11 : 12;
|
|
202
|
-
}
|
|
203
|
-
}else{
|
|
204
|
-
if( ll < 100000000000000LL ){
|
|
205
|
-
len = ll < 10000000000000LL ? 13 : 14;
|
|
206
|
-
}else{
|
|
207
|
-
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return sll < 0 ? len+1 : len;
|
|
212
|
+
unsigned long long ll = sll < 0 ? -sll : sll;
|
|
213
|
+
int len = (sizeof(unsigned long long) * 8 - count_leading_zero_bits(ll)) / 3;
|
|
214
|
+
return sll < 0 ? len+2 : len+1;
|
|
212
215
|
}else{
|
|
213
|
-
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate);
|
|
216
|
+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
|
|
214
217
|
}
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
220
|
|
|
221
|
+
#define MAX_DOUBLE_DIGITS 16
|
|
218
222
|
|
|
219
223
|
/*
|
|
220
224
|
* Document-class: PG::TextEncoder::Float < PG::SimpleEncoder
|
|
@@ -223,10 +227,16 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
223
227
|
*
|
|
224
228
|
*/
|
|
225
229
|
static int
|
|
226
|
-
pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
230
|
+
pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
227
231
|
{
|
|
228
232
|
if(out){
|
|
229
233
|
double dvalue = NUM2DBL(value);
|
|
234
|
+
int len = 0;
|
|
235
|
+
int neg = 0;
|
|
236
|
+
int exp2i, exp10i, i;
|
|
237
|
+
unsigned long long ll, remainder, oldval;
|
|
238
|
+
VALUE intermediate;
|
|
239
|
+
|
|
230
240
|
/* Cast to the same strings as value.to_s . */
|
|
231
241
|
if( isinf(dvalue) ){
|
|
232
242
|
if( dvalue < 0 ){
|
|
@@ -240,12 +250,143 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
|
240
250
|
memcpy( out, "NaN", 3);
|
|
241
251
|
return 3;
|
|
242
252
|
}
|
|
243
|
-
|
|
253
|
+
|
|
254
|
+
/*
|
|
255
|
+
* The following computation is roughly a conversion kind of
|
|
256
|
+
* sprintf( out, "%.16E", dvalue);
|
|
257
|
+
*/
|
|
258
|
+
|
|
259
|
+
/* write the algebraic sign */
|
|
260
|
+
if( dvalue < 0 ) {
|
|
261
|
+
dvalue = -dvalue;
|
|
262
|
+
*out++ = '-';
|
|
263
|
+
neg++;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* retrieve the power of 2 exponent */
|
|
267
|
+
frexp(dvalue, &exp2i);
|
|
268
|
+
/* compute the power of 10 exponent */
|
|
269
|
+
exp10i = (int)floor(exp2i * 0.30102999566398114); /* Math.log(2)/Math.log(10) */
|
|
270
|
+
/* move the decimal point, so that we get an integer of MAX_DOUBLE_DIGITS decimal digits */
|
|
271
|
+
ll = (unsigned long long)(dvalue * pow(10, MAX_DOUBLE_DIGITS - 1 - exp10i) + 0.5);
|
|
272
|
+
|
|
273
|
+
/* avoid leading zeros due to inaccuracy of deriving exp10i from exp2i */
|
|
274
|
+
/* otherwise we would print "09.0" instead of "9.0" */
|
|
275
|
+
if( ll < 1000000000000000 ){ /* pow(10, MAX_DOUBLE_DIGITS-1) */
|
|
276
|
+
exp10i--;
|
|
277
|
+
ll *= 10;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if( exp10i <= -5 || exp10i >= 15 ) {
|
|
281
|
+
/* Write the float in exponent format (1.23e45) */
|
|
282
|
+
|
|
283
|
+
/* write fraction digits from right to left */
|
|
284
|
+
for( i = MAX_DOUBLE_DIGITS; i > 1; i--){
|
|
285
|
+
oldval = ll;
|
|
286
|
+
ll /= 10;
|
|
287
|
+
remainder = oldval - ll * 10;
|
|
288
|
+
/* omit trailing zeros */
|
|
289
|
+
if(remainder != 0 || len ) {
|
|
290
|
+
out[i] = '0' + remainder;
|
|
291
|
+
len++;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* write decimal point */
|
|
296
|
+
if( len ){
|
|
297
|
+
out[1] = '.';
|
|
298
|
+
len++;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* write remaining single digit left to the decimal point */
|
|
302
|
+
oldval = ll;
|
|
303
|
+
ll /= 10;
|
|
304
|
+
remainder = oldval - ll * 10;
|
|
305
|
+
out[0] = '0' + remainder;
|
|
306
|
+
len++;
|
|
307
|
+
|
|
308
|
+
/* write exponent */
|
|
309
|
+
out[len++] = 'e';
|
|
310
|
+
intermediate = INT2NUM(exp10i);
|
|
311
|
+
|
|
312
|
+
return neg + len + pg_text_enc_integer(conv, Qnil, out + len, &intermediate, enc_idx);
|
|
313
|
+
} else {
|
|
314
|
+
/* write the float in non exponent format (0.001234 or 123450.0) */
|
|
315
|
+
|
|
316
|
+
/* write digits from right to left */
|
|
317
|
+
int lz = exp10i < 0 ? 0 : exp10i;
|
|
318
|
+
for( i = MAX_DOUBLE_DIGITS - (exp10i < 0 ? exp10i : 0); i >= 0; i-- ){
|
|
319
|
+
oldval = ll;
|
|
320
|
+
ll /= 10;
|
|
321
|
+
remainder = oldval - ll * 10;
|
|
322
|
+
/* write decimal point */
|
|
323
|
+
if( i - 1 == lz ){
|
|
324
|
+
out[i--] = '.';
|
|
325
|
+
len++;
|
|
326
|
+
}
|
|
327
|
+
/* if possible then omit trailing zeros */
|
|
328
|
+
if(remainder != 0 || len || i - 2 == lz) {
|
|
329
|
+
out[i] = '0' + remainder;
|
|
330
|
+
len++;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return neg + len;
|
|
334
|
+
}
|
|
244
335
|
}else{
|
|
245
|
-
return
|
|
336
|
+
return 1 /*sign*/ + MAX_DOUBLE_DIGITS + 1 /*dot*/ + 1 /*e*/ + 1 /*exp sign*/ + 3 /*exp digits*/;
|
|
246
337
|
}
|
|
247
338
|
}
|
|
248
339
|
|
|
340
|
+
|
|
341
|
+
/*
|
|
342
|
+
* Document-class: PG::TextEncoder::Numeric < PG::SimpleEncoder
|
|
343
|
+
*
|
|
344
|
+
* This is the encoder class for the PostgreSQL numeric types.
|
|
345
|
+
*
|
|
346
|
+
* It converts Integer, Float and BigDecimal objects.
|
|
347
|
+
* All other objects are expected to respond to +to_s+.
|
|
348
|
+
*/
|
|
349
|
+
static int
|
|
350
|
+
pg_text_enc_numeric(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
351
|
+
{
|
|
352
|
+
switch(TYPE(value)){
|
|
353
|
+
case T_FIXNUM:
|
|
354
|
+
case T_BIGNUM:
|
|
355
|
+
return pg_text_enc_integer(this, value, out, intermediate, enc_idx);
|
|
356
|
+
case T_FLOAT:
|
|
357
|
+
return pg_text_enc_float(this, value, out, intermediate, enc_idx);
|
|
358
|
+
default:
|
|
359
|
+
if(out){ /* second pass */
|
|
360
|
+
rb_bug("unexpected value type: %d", TYPE(value));
|
|
361
|
+
} else { /* first pass */
|
|
362
|
+
if( rb_obj_is_kind_of(value, s_cBigDecimal) ){
|
|
363
|
+
/* value.to_s('F') */
|
|
364
|
+
*intermediate = rb_funcall(value, s_id_to_s, 1, s_str_F);
|
|
365
|
+
return -1; /* no second pass */
|
|
366
|
+
} else {
|
|
367
|
+
return pg_coder_enc_to_s(this, value, NULL, intermediate, enc_idx);
|
|
368
|
+
/* no second pass */
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
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
|
+
|
|
389
|
+
|
|
249
390
|
static const char hextab[] = {
|
|
250
391
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
|
251
392
|
};
|
|
@@ -253,17 +394,20 @@ static const char hextab[] = {
|
|
|
253
394
|
/*
|
|
254
395
|
* Document-class: PG::TextEncoder::Bytea < PG::SimpleEncoder
|
|
255
396
|
*
|
|
256
|
-
* This is an encoder class for the PostgreSQL bytea type
|
|
257
|
-
* or newer.
|
|
397
|
+
* This is an encoder class for the PostgreSQL +bytea+ type.
|
|
258
398
|
*
|
|
259
399
|
* The binary String is converted to hexadecimal representation for transmission
|
|
260
400
|
* in text format. For query bind parameters it is recommended to use
|
|
261
|
-
* PG::BinaryEncoder::Bytea
|
|
262
|
-
* 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.
|
|
263
407
|
*
|
|
264
408
|
*/
|
|
265
409
|
static int
|
|
266
|
-
pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
410
|
+
pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
267
411
|
{
|
|
268
412
|
if(out){
|
|
269
413
|
size_t strlen = RSTRING_LEN(*intermediate);
|
|
@@ -278,11 +422,11 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
|
278
422
|
*optr++ = hextab[c >> 4];
|
|
279
423
|
*optr++ = hextab[c & 0xf];
|
|
280
424
|
}
|
|
281
|
-
return optr - out;
|
|
425
|
+
return (int)(optr - out);
|
|
282
426
|
}else{
|
|
283
427
|
*intermediate = rb_obj_as_string(value);
|
|
284
428
|
/* The output starts with "\x" and each character is converted to hex. */
|
|
285
|
-
return 2 +
|
|
429
|
+
return 2 + RSTRING_LENINT(*intermediate) * 2;
|
|
286
430
|
}
|
|
287
431
|
}
|
|
288
432
|
|
|
@@ -299,7 +443,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
|
299
443
|
/* count data plus backslashes; detect chars needing quotes */
|
|
300
444
|
if (strlen == 0)
|
|
301
445
|
needquote = 1; /* force quotes for empty string */
|
|
302
|
-
else if (strlen == 4 &&
|
|
446
|
+
else if (strlen == 4 && rbpg_strncasecmp(p_in, "NULL", strlen) == 0)
|
|
303
447
|
needquote = 1; /* force quotes for literal NULL */
|
|
304
448
|
else
|
|
305
449
|
needquote = 0;
|
|
@@ -342,13 +486,13 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
|
342
486
|
}
|
|
343
487
|
|
|
344
488
|
static char *
|
|
345
|
-
quote_string(t_pg_coder *this, VALUE value, VALUE string, char *current_out, int with_quote, t_quote_func quote_buffer, void *func_data)
|
|
489
|
+
quote_string(t_pg_coder *this, VALUE value, VALUE string, char *current_out, int with_quote, t_quote_func quote_buffer, void *func_data, int enc_idx)
|
|
346
490
|
{
|
|
347
491
|
int strlen;
|
|
348
492
|
VALUE subint;
|
|
349
493
|
t_pg_coder_enc_func enc_func = pg_coder_enc_func(this);
|
|
350
494
|
|
|
351
|
-
strlen = enc_func(this, value, NULL, &subint);
|
|
495
|
+
strlen = enc_func(this, value, NULL, &subint, enc_idx);
|
|
352
496
|
|
|
353
497
|
if( strlen == -1 ){
|
|
354
498
|
/* we can directly use String value in subint */
|
|
@@ -374,20 +518,20 @@ quote_string(t_pg_coder *this, VALUE value, VALUE string, char *current_out, int
|
|
|
374
518
|
current_out = pg_rb_str_ensure_capa( string, 2 * strlen + 2, current_out, NULL );
|
|
375
519
|
|
|
376
520
|
/* Place the unescaped string at current output position. */
|
|
377
|
-
strlen = enc_func(this, value, current_out, &subint);
|
|
521
|
+
strlen = enc_func(this, value, current_out, &subint, enc_idx);
|
|
378
522
|
|
|
379
523
|
current_out += quote_buffer( func_data, current_out, strlen, current_out );
|
|
380
524
|
}else{
|
|
381
525
|
/* size of the unquoted string */
|
|
382
526
|
current_out = pg_rb_str_ensure_capa( string, strlen, current_out, NULL );
|
|
383
|
-
current_out += enc_func(this, value, current_out, &subint);
|
|
527
|
+
current_out += enc_func(this, value, current_out, &subint, enc_idx);
|
|
384
528
|
}
|
|
385
529
|
}
|
|
386
530
|
return current_out;
|
|
387
531
|
}
|
|
388
532
|
|
|
389
533
|
static char *
|
|
390
|
-
write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE string, int quote)
|
|
534
|
+
write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE string, int quote, int enc_idx)
|
|
391
535
|
{
|
|
392
536
|
int i;
|
|
393
537
|
|
|
@@ -405,7 +549,7 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
|
405
549
|
|
|
406
550
|
switch(TYPE(entry)){
|
|
407
551
|
case T_ARRAY:
|
|
408
|
-
current_out = write_array(this, entry, current_out, string, quote);
|
|
552
|
+
current_out = write_array(this, entry, current_out, string, quote, enc_idx);
|
|
409
553
|
break;
|
|
410
554
|
case T_NIL:
|
|
411
555
|
current_out = pg_rb_str_ensure_capa( string, 4, current_out, NULL );
|
|
@@ -415,7 +559,7 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
|
415
559
|
*current_out++ = 'L';
|
|
416
560
|
break;
|
|
417
561
|
default:
|
|
418
|
-
current_out = quote_string( this->elem, entry, string, current_out, quote, quote_array_buffer, this );
|
|
562
|
+
current_out = quote_string( this->elem, entry, string, current_out, quote, quote_array_buffer, this, enc_idx );
|
|
419
563
|
}
|
|
420
564
|
}
|
|
421
565
|
current_out = pg_rb_str_ensure_capa( string, 1, current_out, NULL );
|
|
@@ -437,60 +581,56 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
|
437
581
|
*
|
|
438
582
|
*/
|
|
439
583
|
static int
|
|
440
|
-
pg_text_enc_array(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
584
|
+
pg_text_enc_array(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
441
585
|
{
|
|
442
586
|
char *end_ptr;
|
|
443
587
|
t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
|
|
444
588
|
|
|
445
589
|
if( TYPE(value) == T_ARRAY){
|
|
446
|
-
|
|
590
|
+
VALUE out_str = rb_str_new(NULL, 0);
|
|
591
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
|
447
592
|
|
|
448
|
-
end_ptr = write_array(this, value, RSTRING_PTR(
|
|
593
|
+
end_ptr = write_array(this, value, RSTRING_PTR(out_str), out_str, this->needs_quotation, enc_idx);
|
|
449
594
|
|
|
450
|
-
rb_str_set_len(
|
|
595
|
+
rb_str_set_len( out_str, end_ptr - RSTRING_PTR(out_str) );
|
|
596
|
+
*intermediate = out_str;
|
|
451
597
|
|
|
452
598
|
return -1;
|
|
453
599
|
} else {
|
|
454
|
-
return pg_coder_enc_to_s( conv, value, out, intermediate );
|
|
600
|
+
return pg_coder_enc_to_s( conv, value, out, intermediate, enc_idx );
|
|
455
601
|
}
|
|
456
602
|
}
|
|
457
603
|
|
|
458
|
-
static
|
|
459
|
-
|
|
460
|
-
char *
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
604
|
+
static char *
|
|
605
|
+
quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
|
606
|
+
char *p_in = RSTRING_PTR(value);
|
|
607
|
+
size_t strlen = RSTRING_LEN(value);
|
|
608
|
+
char *p_inend = p_in + strlen;
|
|
609
|
+
char *end_capa = current_out;
|
|
610
|
+
|
|
611
|
+
PG_RB_STR_ENSURE_CAPA( out_string, strlen + 2, current_out, end_capa );
|
|
612
|
+
*current_out++ = '"';
|
|
613
|
+
for(; p_in != p_inend; p_in++) {
|
|
614
|
+
char c = *p_in;
|
|
615
|
+
if (c == '"'){
|
|
616
|
+
PG_RB_STR_ENSURE_CAPA( out_string, p_inend - p_in + 2, current_out, end_capa );
|
|
617
|
+
*current_out++ = '"';
|
|
618
|
+
} else if (c == 0){
|
|
619
|
+
rb_raise(rb_eArgError, "string contains null byte");
|
|
468
620
|
}
|
|
621
|
+
*current_out++ = c;
|
|
469
622
|
}
|
|
623
|
+
PG_RB_STR_ENSURE_CAPA( out_string, 1, current_out, end_capa );
|
|
624
|
+
*current_out++ = '"';
|
|
470
625
|
|
|
471
|
-
|
|
472
|
-
ptr2 = p_out + strlen + backslashs + 2;
|
|
473
|
-
/* Write end quote */
|
|
474
|
-
*--ptr2 = '"';
|
|
475
|
-
|
|
476
|
-
/* Then store the escaped string on the final position, walking
|
|
477
|
-
* right to left, until all backslashs are placed. */
|
|
478
|
-
while( ptr1 != p_in ) {
|
|
479
|
-
*--ptr2 = *--ptr1;
|
|
480
|
-
if(*ptr2 == '"'){
|
|
481
|
-
*--ptr2 = '"';
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
/* Write start quote */
|
|
485
|
-
*p_out = '"';
|
|
486
|
-
return strlen + backslashs + 2;
|
|
626
|
+
return current_out;
|
|
487
627
|
}
|
|
488
628
|
|
|
489
629
|
static char *
|
|
490
|
-
pg_text_enc_array_identifier(
|
|
630
|
+
pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
|
|
491
631
|
{
|
|
492
|
-
|
|
493
|
-
|
|
632
|
+
long i;
|
|
633
|
+
long nr_elems;
|
|
494
634
|
|
|
495
635
|
Check_Type(value, T_ARRAY);
|
|
496
636
|
nr_elems = RARRAY_LEN(value);
|
|
@@ -498,7 +638,11 @@ pg_text_enc_array_identifier(t_pg_composite_coder *this, VALUE value, VALUE stri
|
|
|
498
638
|
for( i=0; i<nr_elems; i++){
|
|
499
639
|
VALUE entry = rb_ary_entry(value, i);
|
|
500
640
|
|
|
501
|
-
|
|
641
|
+
StringValue(entry);
|
|
642
|
+
if( ENCODING_GET(entry) != enc_idx ){
|
|
643
|
+
entry = rb_str_export_to_enc(entry, rb_enc_from_index(enc_idx));
|
|
644
|
+
}
|
|
645
|
+
out = quote_identifier(entry, string, out);
|
|
502
646
|
if( i < nr_elems-1 ){
|
|
503
647
|
out = pg_rb_str_ensure_capa( string, 1, out, NULL );
|
|
504
648
|
*out++ = '.';
|
|
@@ -508,29 +652,38 @@ pg_text_enc_array_identifier(t_pg_composite_coder *this, VALUE value, VALUE stri
|
|
|
508
652
|
}
|
|
509
653
|
|
|
510
654
|
/*
|
|
511
|
-
* Document-class: PG::TextEncoder::Identifier < PG::
|
|
655
|
+
* Document-class: PG::TextEncoder::Identifier < PG::SimpleEncoder
|
|
512
656
|
*
|
|
513
657
|
* This is the encoder class for PostgreSQL identifiers.
|
|
514
658
|
*
|
|
515
|
-
* An Array value can be used for "schema.table.column"
|
|
659
|
+
* An Array value can be used for identifiers of the kind "schema.table.column".
|
|
660
|
+
* This ensures that each element is properly quoted:
|
|
516
661
|
* PG::TextEncoder::Identifier.new.encode(['schema', 'table', 'column'])
|
|
517
|
-
* => "schema"."table"."column"
|
|
662
|
+
* => '"schema"."table"."column"'
|
|
518
663
|
*
|
|
664
|
+
* This encoder can also be used per PG::Connection#quote_ident .
|
|
519
665
|
*/
|
|
520
|
-
|
|
521
|
-
pg_text_enc_identifier(t_pg_coder *
|
|
666
|
+
int
|
|
667
|
+
pg_text_enc_identifier(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
522
668
|
{
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
*intermediate = rb_str_new(NULL, 0);
|
|
526
|
-
out = RSTRING_PTR(*intermediate);
|
|
527
|
-
|
|
669
|
+
VALUE out_str;
|
|
670
|
+
UNUSED( this );
|
|
528
671
|
if( TYPE(value) == T_ARRAY){
|
|
529
|
-
|
|
672
|
+
out_str = rb_str_new(NULL, 0);
|
|
673
|
+
out = RSTRING_PTR(out_str);
|
|
674
|
+
out = pg_text_enc_array_identifier(value, out_str, out, enc_idx);
|
|
530
675
|
} else {
|
|
531
|
-
|
|
676
|
+
StringValue(value);
|
|
677
|
+
if( ENCODING_GET(value) != enc_idx ){
|
|
678
|
+
value = rb_str_export_to_enc(value, rb_enc_from_index(enc_idx));
|
|
679
|
+
}
|
|
680
|
+
out_str = rb_str_new(NULL, RSTRING_LEN(value) + 2);
|
|
681
|
+
out = RSTRING_PTR(out_str);
|
|
682
|
+
out = quote_identifier(value, out_str, out);
|
|
532
683
|
}
|
|
533
|
-
rb_str_set_len(
|
|
684
|
+
rb_str_set_len( out_str, out - RSTRING_PTR(out_str) );
|
|
685
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
|
686
|
+
*intermediate = out_str;
|
|
534
687
|
return -1;
|
|
535
688
|
}
|
|
536
689
|
|
|
@@ -572,18 +725,26 @@ quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
|
572
725
|
*
|
|
573
726
|
* This is the encoder class for PostgreSQL literals.
|
|
574
727
|
*
|
|
575
|
-
* A literal is quoted and escaped by the
|
|
728
|
+
* A literal is quoted and escaped by the <tt>'</tt> character, so that it can be inserted into SQL queries.
|
|
729
|
+
* It works equal to PG::Connection#escape_literal, but integrates into the type cast system of ruby-pg.
|
|
730
|
+
*
|
|
731
|
+
* Both expressions have the same result:
|
|
732
|
+
* conn.escape_literal(PG::TextEncoder::Array.new.encode(["v1","v2"])) # => "'{v1,v2}'"
|
|
733
|
+
* PG::TextEncoder::QuotedLiteral.new(elements_type: PG::TextEncoder::Array.new).encode(["v1","v2"]) # => "'{v1,v2}'"
|
|
734
|
+
* While escape_literal requires a intermediate ruby string allocation, QuotedLiteral encodes the values directly to the result string.
|
|
576
735
|
*
|
|
577
736
|
*/
|
|
578
737
|
static int
|
|
579
|
-
pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
738
|
+
pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
580
739
|
{
|
|
581
740
|
t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
|
|
741
|
+
VALUE out_str = rb_str_new(NULL, 0);
|
|
742
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
|
582
743
|
|
|
583
|
-
|
|
584
|
-
out =
|
|
585
|
-
|
|
586
|
-
|
|
744
|
+
out = RSTRING_PTR(out_str);
|
|
745
|
+
out = quote_string(this->elem, value, out_str, out, this->needs_quotation, quote_literal_buffer, this, enc_idx);
|
|
746
|
+
rb_str_set_len( out_str, out - RSTRING_PTR(out_str) );
|
|
747
|
+
*intermediate = out_str;
|
|
587
748
|
return -1;
|
|
588
749
|
}
|
|
589
750
|
|
|
@@ -594,7 +755,7 @@ pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *inte
|
|
|
594
755
|
*
|
|
595
756
|
*/
|
|
596
757
|
static int
|
|
597
|
-
pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
|
758
|
+
pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
|
598
759
|
{
|
|
599
760
|
int strlen;
|
|
600
761
|
VALUE subint;
|
|
@@ -603,13 +764,13 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
603
764
|
|
|
604
765
|
if(out){
|
|
605
766
|
/* Second encoder pass, if required */
|
|
606
|
-
strlen = enc_func(this->elem, value, out, intermediate);
|
|
767
|
+
strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
|
|
607
768
|
base64_encode( out, out, strlen );
|
|
608
769
|
|
|
609
770
|
return BASE64_ENCODED_SIZE(strlen);
|
|
610
771
|
} else {
|
|
611
772
|
/* First encoder pass */
|
|
612
|
-
strlen = enc_func(this->elem, value, NULL, &subint);
|
|
773
|
+
strlen = enc_func(this->elem, value, NULL, &subint, enc_idx);
|
|
613
774
|
|
|
614
775
|
if( strlen == -1 ){
|
|
615
776
|
/* Encoded string is returned in subint */
|
|
@@ -617,6 +778,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
617
778
|
|
|
618
779
|
strlen = RSTRING_LENINT(subint);
|
|
619
780
|
out_str = rb_str_new(NULL, BASE64_ENCODED_SIZE(strlen));
|
|
781
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
|
620
782
|
|
|
621
783
|
base64_encode( RSTRING_PTR(out_str), RSTRING_PTR(subint), strlen);
|
|
622
784
|
*intermediate = out_str;
|
|
@@ -632,13 +794,15 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
632
794
|
|
|
633
795
|
|
|
634
796
|
void
|
|
635
|
-
init_pg_text_encoder()
|
|
797
|
+
init_pg_text_encoder(void)
|
|
636
798
|
{
|
|
637
799
|
s_id_encode = rb_intern("encode");
|
|
638
800
|
s_id_to_i = rb_intern("to_i");
|
|
801
|
+
s_id_to_s = rb_intern("to_s");
|
|
639
802
|
|
|
640
803
|
/* This module encapsulates all encoder classes with text output format */
|
|
641
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);
|
|
642
806
|
|
|
643
807
|
/* Make RDoc aware of the encoder classes... */
|
|
644
808
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Boolean", rb_cPG_SimpleEncoder ); */
|
|
@@ -651,11 +815,11 @@ init_pg_text_encoder()
|
|
|
651
815
|
pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
652
816
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
|
|
653
817
|
pg_define_coder( "Bytea", pg_text_enc_bytea, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
818
|
+
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Identifier", rb_cPG_SimpleEncoder ); */
|
|
819
|
+
pg_define_coder( "Identifier", pg_text_enc_identifier, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
|
654
820
|
|
|
655
821
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Array", rb_cPG_CompositeEncoder ); */
|
|
656
822
|
pg_define_coder( "Array", pg_text_enc_array, rb_cPG_CompositeEncoder, rb_mPG_TextEncoder );
|
|
657
|
-
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Identifier", rb_cPG_CompositeEncoder ); */
|
|
658
|
-
pg_define_coder( "Identifier", pg_text_enc_identifier, rb_cPG_CompositeEncoder, rb_mPG_TextEncoder );
|
|
659
823
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "QuotedLiteral", rb_cPG_CompositeEncoder ); */
|
|
660
824
|
pg_define_coder( "QuotedLiteral", pg_text_enc_quoted_literal, rb_cPG_CompositeEncoder, rb_mPG_TextEncoder );
|
|
661
825
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "ToBase64", rb_cPG_CompositeEncoder ); */
|