pg 0.18.0 → 1.0.0
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/BSDL +2 -2
- data/ChangeLog +1221 -4
- data/History.rdoc +130 -0
- data/Manifest.txt +0 -18
- data/README-Windows.rdoc +15 -26
- data/README.rdoc +16 -10
- data/Rakefile +32 -23
- data/Rakefile.cross +56 -38
- data/ext/errorcodes.def +33 -0
- data/ext/errorcodes.txt +15 -1
- data/ext/extconf.rb +27 -35
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +27 -39
- data/ext/pg.c +19 -51
- data/ext/pg.h +22 -79
- data/ext/pg_binary_decoder.c +3 -1
- data/ext/pg_binary_encoder.c +14 -12
- data/ext/pg_coder.c +31 -10
- data/ext/pg_connection.c +350 -263
- data/ext/pg_copy_coder.c +34 -4
- data/ext/pg_result.c +27 -25
- data/ext/pg_text_decoder.c +9 -10
- data/ext/pg_text_encoder.c +93 -73
- data/ext/pg_type_map.c +20 -13
- data/ext/pg_type_map_by_column.c +7 -7
- data/ext/pg_type_map_by_mri_type.c +2 -2
- data/ext/pg_type_map_in_ruby.c +4 -7
- data/ext/util.c +3 -3
- data/ext/util.h +1 -1
- data/lib/pg/basic_type_mapping.rb +69 -42
- data/lib/pg/connection.rb +89 -38
- data/lib/pg/result.rb +10 -5
- data/lib/pg/text_decoder.rb +12 -3
- data/lib/pg/text_encoder.rb +8 -0
- data/lib/pg.rb +18 -10
- data/spec/helpers.rb +9 -16
- data/spec/pg/basic_type_mapping_spec.rb +58 -4
- data/spec/pg/connection_spec.rb +477 -217
- data/spec/pg/result_spec.rb +14 -7
- data/spec/pg/type_map_by_class_spec.rb +2 -2
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_spec.rb +145 -33
- data/spec/pg_spec.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +67 -66
- metadata.gz.sig +0 -0
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -186
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -294
- data/sample/replication_monitor.rb +0 -231
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -320
data/ext/pg_text_encoder.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_text_encoder.c - PG::TextEncoder module
|
3
|
-
* $Id: pg_text_encoder.c,v
|
3
|
+
* $Id: pg_text_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
|
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.
|
@@ -41,14 +42,16 @@
|
|
41
42
|
|
42
43
|
#include "pg.h"
|
43
44
|
#include "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;
|
50
53
|
|
51
|
-
static int pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate);
|
54
|
+
static int pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx);
|
52
55
|
|
53
56
|
VALUE
|
54
57
|
pg_obj_to_i( VALUE value )
|
@@ -74,7 +77,7 @@ pg_obj_to_i( VALUE value )
|
|
74
77
|
*
|
75
78
|
*/
|
76
79
|
static int
|
77
|
-
pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
80
|
+
pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
78
81
|
{
|
79
82
|
switch( TYPE(value) ){
|
80
83
|
case T_FALSE:
|
@@ -92,10 +95,10 @@ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
92
95
|
if(out) *out = '1';
|
93
96
|
return 1;
|
94
97
|
} else {
|
95
|
-
return pg_text_enc_integer(this, value, out, intermediate);
|
98
|
+
return pg_text_enc_integer(this, value, out, intermediate, enc_idx);
|
96
99
|
}
|
97
100
|
default:
|
98
|
-
return pg_coder_enc_to_s(this, value, out, intermediate);
|
101
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
99
102
|
}
|
100
103
|
/* never reached */
|
101
104
|
return 0;
|
@@ -111,9 +114,14 @@ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
111
114
|
*
|
112
115
|
*/
|
113
116
|
int
|
114
|
-
pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
117
|
+
pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
115
118
|
{
|
116
|
-
|
119
|
+
VALUE str = rb_obj_as_string(value);
|
120
|
+
if( ENCODING_GET(str) == enc_idx ){
|
121
|
+
*intermediate = str;
|
122
|
+
}else{
|
123
|
+
*intermediate = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
|
124
|
+
}
|
117
125
|
return -1;
|
118
126
|
}
|
119
127
|
|
@@ -127,11 +135,11 @@ pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
|
127
135
|
*
|
128
136
|
*/
|
129
137
|
static int
|
130
|
-
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
|
138
|
+
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
131
139
|
{
|
132
140
|
if(out){
|
133
141
|
if(TYPE(*intermediate) == T_STRING){
|
134
|
-
return pg_coder_enc_to_s(this, value, out, intermediate);
|
142
|
+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
|
135
143
|
}else{
|
136
144
|
char *start = out;
|
137
145
|
int len;
|
@@ -204,13 +212,13 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
204
212
|
if( ll < 100000000000000LL ){
|
205
213
|
len = ll < 10000000000000LL ? 13 : 14;
|
206
214
|
}else{
|
207
|
-
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate);
|
215
|
+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
|
208
216
|
}
|
209
217
|
}
|
210
218
|
}
|
211
219
|
return sll < 0 ? len+1 : len;
|
212
220
|
}else{
|
213
|
-
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate);
|
221
|
+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
|
214
222
|
}
|
215
223
|
}
|
216
224
|
}
|
@@ -223,7 +231,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
223
231
|
*
|
224
232
|
*/
|
225
233
|
static int
|
226
|
-
pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
234
|
+
pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
227
235
|
{
|
228
236
|
if(out){
|
229
237
|
double dvalue = NUM2DBL(value);
|
@@ -263,7 +271,7 @@ static const char hextab[] = {
|
|
263
271
|
*
|
264
272
|
*/
|
265
273
|
static int
|
266
|
-
pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
274
|
+
pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
267
275
|
{
|
268
276
|
if(out){
|
269
277
|
size_t strlen = RSTRING_LEN(*intermediate);
|
@@ -299,7 +307,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
299
307
|
/* count data plus backslashes; detect chars needing quotes */
|
300
308
|
if (strlen == 0)
|
301
309
|
needquote = 1; /* force quotes for empty string */
|
302
|
-
else if (strlen == 4 &&
|
310
|
+
else if (strlen == 4 && rbpg_strncasecmp(p_in, "NULL", strlen) == 0)
|
303
311
|
needquote = 1; /* force quotes for literal NULL */
|
304
312
|
else
|
305
313
|
needquote = 0;
|
@@ -342,13 +350,13 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
342
350
|
}
|
343
351
|
|
344
352
|
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)
|
353
|
+
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
354
|
{
|
347
355
|
int strlen;
|
348
356
|
VALUE subint;
|
349
357
|
t_pg_coder_enc_func enc_func = pg_coder_enc_func(this);
|
350
358
|
|
351
|
-
strlen = enc_func(this, value, NULL, &subint);
|
359
|
+
strlen = enc_func(this, value, NULL, &subint, enc_idx);
|
352
360
|
|
353
361
|
if( strlen == -1 ){
|
354
362
|
/* we can directly use String value in subint */
|
@@ -374,20 +382,20 @@ quote_string(t_pg_coder *this, VALUE value, VALUE string, char *current_out, int
|
|
374
382
|
current_out = pg_rb_str_ensure_capa( string, 2 * strlen + 2, current_out, NULL );
|
375
383
|
|
376
384
|
/* Place the unescaped string at current output position. */
|
377
|
-
strlen = enc_func(this, value, current_out, &subint);
|
385
|
+
strlen = enc_func(this, value, current_out, &subint, enc_idx);
|
378
386
|
|
379
387
|
current_out += quote_buffer( func_data, current_out, strlen, current_out );
|
380
388
|
}else{
|
381
389
|
/* size of the unquoted string */
|
382
390
|
current_out = pg_rb_str_ensure_capa( string, strlen, current_out, NULL );
|
383
|
-
current_out += enc_func(this, value, current_out, &subint);
|
391
|
+
current_out += enc_func(this, value, current_out, &subint, enc_idx);
|
384
392
|
}
|
385
393
|
}
|
386
394
|
return current_out;
|
387
395
|
}
|
388
396
|
|
389
397
|
static char *
|
390
|
-
write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE string, int quote)
|
398
|
+
write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE string, int quote, int enc_idx)
|
391
399
|
{
|
392
400
|
int i;
|
393
401
|
|
@@ -405,7 +413,7 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
405
413
|
|
406
414
|
switch(TYPE(entry)){
|
407
415
|
case T_ARRAY:
|
408
|
-
current_out = write_array(this, entry, current_out, string, quote);
|
416
|
+
current_out = write_array(this, entry, current_out, string, quote, enc_idx);
|
409
417
|
break;
|
410
418
|
case T_NIL:
|
411
419
|
current_out = pg_rb_str_ensure_capa( string, 4, current_out, NULL );
|
@@ -415,7 +423,7 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
415
423
|
*current_out++ = 'L';
|
416
424
|
break;
|
417
425
|
default:
|
418
|
-
current_out = quote_string( this->elem, entry, string, current_out, quote, quote_array_buffer, this );
|
426
|
+
current_out = quote_string( this->elem, entry, string, current_out, quote, quote_array_buffer, this, enc_idx );
|
419
427
|
}
|
420
428
|
}
|
421
429
|
current_out = pg_rb_str_ensure_capa( string, 1, current_out, NULL );
|
@@ -437,57 +445,54 @@ write_array(t_pg_composite_coder *this, VALUE value, char *current_out, VALUE st
|
|
437
445
|
*
|
438
446
|
*/
|
439
447
|
static int
|
440
|
-
pg_text_enc_array(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
448
|
+
pg_text_enc_array(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
441
449
|
{
|
442
450
|
char *end_ptr;
|
443
451
|
t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
|
444
452
|
|
445
453
|
if( TYPE(value) == T_ARRAY){
|
446
|
-
|
454
|
+
VALUE out_str = rb_str_new(NULL, 0);
|
455
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
447
456
|
|
448
|
-
end_ptr = write_array(this, value, RSTRING_PTR(
|
457
|
+
end_ptr = write_array(this, value, RSTRING_PTR(out_str), out_str, this->needs_quotation, enc_idx);
|
449
458
|
|
450
|
-
rb_str_set_len(
|
459
|
+
rb_str_set_len( out_str, end_ptr - RSTRING_PTR(out_str) );
|
460
|
+
*intermediate = out_str;
|
451
461
|
|
452
462
|
return -1;
|
453
463
|
} else {
|
454
|
-
return pg_coder_enc_to_s( conv, value, out, intermediate );
|
464
|
+
return pg_coder_enc_to_s( conv, value, out, intermediate, enc_idx );
|
455
465
|
}
|
456
466
|
}
|
457
467
|
|
458
|
-
static
|
459
|
-
|
468
|
+
static char *
|
469
|
+
quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
470
|
+
char *p_in = RSTRING_PTR(value);
|
460
471
|
char *ptr1;
|
461
|
-
|
462
|
-
|
472
|
+
size_t strlen = RSTRING_LEN(value);
|
473
|
+
char *end_capa = current_out;
|
463
474
|
|
464
|
-
|
475
|
+
PG_RB_STR_ENSURE_CAPA( out_string, strlen + 2, current_out, end_capa );
|
476
|
+
*current_out++ = '"';
|
465
477
|
for(ptr1 = p_in; ptr1 != p_in + strlen; ptr1++) {
|
466
|
-
|
467
|
-
|
478
|
+
char c = *ptr1;
|
479
|
+
if (c == '"'){
|
480
|
+
strlen++;
|
481
|
+
PG_RB_STR_ENSURE_CAPA( out_string, p_in - ptr1 + strlen + 1, current_out, end_capa );
|
482
|
+
*current_out++ = '"';
|
483
|
+
} else if (c == 0){
|
484
|
+
break;
|
468
485
|
}
|
486
|
+
*current_out++ = c;
|
469
487
|
}
|
488
|
+
PG_RB_STR_ENSURE_CAPA( out_string, 1, current_out, end_capa );
|
489
|
+
*current_out++ = '"';
|
470
490
|
|
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;
|
491
|
+
return current_out;
|
487
492
|
}
|
488
493
|
|
489
494
|
static char *
|
490
|
-
pg_text_enc_array_identifier(
|
495
|
+
pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
|
491
496
|
{
|
492
497
|
int i;
|
493
498
|
int nr_elems;
|
@@ -498,7 +503,11 @@ pg_text_enc_array_identifier(t_pg_composite_coder *this, VALUE value, VALUE stri
|
|
498
503
|
for( i=0; i<nr_elems; i++){
|
499
504
|
VALUE entry = rb_ary_entry(value, i);
|
500
505
|
|
501
|
-
|
506
|
+
StringValue(entry);
|
507
|
+
if( ENCODING_GET(entry) != enc_idx ){
|
508
|
+
entry = rb_str_export_to_enc(entry, rb_enc_from_index(enc_idx));
|
509
|
+
}
|
510
|
+
out = quote_identifier(entry, string, out);
|
502
511
|
if( i < nr_elems-1 ){
|
503
512
|
out = pg_rb_str_ensure_capa( string, 1, out, NULL );
|
504
513
|
*out++ = '.';
|
@@ -508,29 +517,37 @@ pg_text_enc_array_identifier(t_pg_composite_coder *this, VALUE value, VALUE stri
|
|
508
517
|
}
|
509
518
|
|
510
519
|
/*
|
511
|
-
* Document-class: PG::TextEncoder::Identifier < PG::
|
520
|
+
* Document-class: PG::TextEncoder::Identifier < PG::SimpleEncoder
|
512
521
|
*
|
513
522
|
* This is the encoder class for PostgreSQL identifiers.
|
514
523
|
*
|
515
524
|
* An Array value can be used for "schema.table.column" type identifiers:
|
516
525
|
* PG::TextEncoder::Identifier.new.encode(['schema', 'table', 'column'])
|
517
|
-
* => "schema"."table"."column"
|
526
|
+
* => '"schema"."table"."column"'
|
518
527
|
*
|
528
|
+
* This encoder can also be used per PG::Connection#quote_ident .
|
519
529
|
*/
|
520
|
-
|
521
|
-
pg_text_enc_identifier(t_pg_coder *
|
530
|
+
int
|
531
|
+
pg_text_enc_identifier(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
522
532
|
{
|
523
|
-
|
524
|
-
|
525
|
-
*intermediate = rb_str_new(NULL, 0);
|
526
|
-
out = RSTRING_PTR(*intermediate);
|
527
|
-
|
533
|
+
VALUE out_str;
|
534
|
+
UNUSED( this );
|
528
535
|
if( TYPE(value) == T_ARRAY){
|
529
|
-
|
536
|
+
out_str = rb_str_new(NULL, 0);
|
537
|
+
out = RSTRING_PTR(out_str);
|
538
|
+
out = pg_text_enc_array_identifier(value, out_str, out, enc_idx);
|
530
539
|
} else {
|
531
|
-
|
540
|
+
StringValue(value);
|
541
|
+
if( ENCODING_GET(value) != enc_idx ){
|
542
|
+
value = rb_str_export_to_enc(value, rb_enc_from_index(enc_idx));
|
543
|
+
}
|
544
|
+
out_str = rb_str_new(NULL, RSTRING_LEN(value) + 2);
|
545
|
+
out = RSTRING_PTR(out_str);
|
546
|
+
out = quote_identifier(value, out_str, out);
|
532
547
|
}
|
533
|
-
rb_str_set_len(
|
548
|
+
rb_str_set_len( out_str, out - RSTRING_PTR(out_str) );
|
549
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
550
|
+
*intermediate = out_str;
|
534
551
|
return -1;
|
535
552
|
}
|
536
553
|
|
@@ -576,14 +593,16 @@ quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
576
593
|
*
|
577
594
|
*/
|
578
595
|
static int
|
579
|
-
pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
596
|
+
pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
580
597
|
{
|
581
598
|
t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
|
599
|
+
VALUE out_str = rb_str_new(NULL, 0);
|
600
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
582
601
|
|
583
|
-
|
584
|
-
out =
|
585
|
-
|
586
|
-
|
602
|
+
out = RSTRING_PTR(out_str);
|
603
|
+
out = quote_string(this->elem, value, out_str, out, this->needs_quotation, quote_literal_buffer, this, enc_idx);
|
604
|
+
rb_str_set_len( out_str, out - RSTRING_PTR(out_str) );
|
605
|
+
*intermediate = out_str;
|
587
606
|
return -1;
|
588
607
|
}
|
589
608
|
|
@@ -594,7 +613,7 @@ pg_text_enc_quoted_literal(t_pg_coder *conv, VALUE value, char *out, VALUE *inte
|
|
594
613
|
*
|
595
614
|
*/
|
596
615
|
static int
|
597
|
-
pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
|
616
|
+
pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
|
598
617
|
{
|
599
618
|
int strlen;
|
600
619
|
VALUE subint;
|
@@ -603,13 +622,13 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
603
622
|
|
604
623
|
if(out){
|
605
624
|
/* Second encoder pass, if required */
|
606
|
-
strlen = enc_func(this->elem, value, out, intermediate);
|
625
|
+
strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
|
607
626
|
base64_encode( out, out, strlen );
|
608
627
|
|
609
628
|
return BASE64_ENCODED_SIZE(strlen);
|
610
629
|
} else {
|
611
630
|
/* First encoder pass */
|
612
|
-
strlen = enc_func(this->elem, value, NULL, &subint);
|
631
|
+
strlen = enc_func(this->elem, value, NULL, &subint, enc_idx);
|
613
632
|
|
614
633
|
if( strlen == -1 ){
|
615
634
|
/* Encoded string is returned in subint */
|
@@ -617,6 +636,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
617
636
|
|
618
637
|
strlen = RSTRING_LENINT(subint);
|
619
638
|
out_str = rb_str_new(NULL, BASE64_ENCODED_SIZE(strlen));
|
639
|
+
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
620
640
|
|
621
641
|
base64_encode( RSTRING_PTR(out_str), RSTRING_PTR(subint), strlen);
|
622
642
|
*intermediate = out_str;
|
@@ -651,11 +671,11 @@ init_pg_text_encoder()
|
|
651
671
|
pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
652
672
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
|
653
673
|
pg_define_coder( "Bytea", pg_text_enc_bytea, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
674
|
+
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Identifier", rb_cPG_SimpleEncoder ); */
|
675
|
+
pg_define_coder( "Identifier", pg_text_enc_identifier, rb_cPG_SimpleEncoder, rb_mPG_TextEncoder );
|
654
676
|
|
655
677
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Array", rb_cPG_CompositeEncoder ); */
|
656
678
|
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
679
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "QuotedLiteral", rb_cPG_CompositeEncoder ); */
|
660
680
|
pg_define_coder( "QuotedLiteral", pg_text_enc_quoted_literal, rb_cPG_CompositeEncoder, rb_mPG_TextEncoder );
|
661
681
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "ToBase64", rb_cPG_CompositeEncoder ); */
|
data/ext/pg_type_map.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id: pg_type_map.c,v
|
3
|
+
* $Id: pg_type_map.c,v 2af122820861 2017/01/14 19:56:36 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -11,55 +11,62 @@ VALUE rb_mDefaultTypeMappable;
|
|
11
11
|
static ID s_id_fit_to_query;
|
12
12
|
static ID s_id_fit_to_result;
|
13
13
|
|
14
|
+
NORETURN( VALUE
|
15
|
+
pg_typemap_fit_to_result( VALUE self, VALUE result ));
|
16
|
+
NORETURN( VALUE
|
17
|
+
pg_typemap_fit_to_query( VALUE self, VALUE params ));
|
18
|
+
NORETURN( int
|
19
|
+
pg_typemap_fit_to_copy_get( VALUE self ));
|
20
|
+
NORETURN( VALUE
|
21
|
+
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field ));
|
22
|
+
NORETURN( t_pg_coder *
|
23
|
+
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field ));
|
24
|
+
NORETURN( VALUE
|
25
|
+
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx ));
|
26
|
+
|
14
27
|
VALUE
|
15
28
|
pg_typemap_fit_to_result( VALUE self, VALUE result )
|
16
29
|
{
|
17
30
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map result values", rb_obj_classname(self) );
|
18
|
-
return Qnil;
|
19
31
|
}
|
20
32
|
|
21
33
|
VALUE
|
22
34
|
pg_typemap_fit_to_query( VALUE self, VALUE params )
|
23
35
|
{
|
24
36
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map query params", rb_obj_classname(self) );
|
25
|
-
return Qnil;
|
26
37
|
}
|
27
38
|
|
28
39
|
int
|
29
40
|
pg_typemap_fit_to_copy_get( VALUE self )
|
30
41
|
{
|
31
42
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map get_copy_data results", rb_obj_classname(self) );
|
32
|
-
return Qnil;
|
33
43
|
}
|
34
44
|
|
35
45
|
VALUE
|
36
46
|
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
|
37
47
|
{
|
38
48
|
rb_raise( rb_eNotImpError, "type map is not suitable to map result values" );
|
39
|
-
return Qnil;
|
40
49
|
}
|
41
50
|
|
42
51
|
t_pg_coder *
|
43
52
|
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field )
|
44
53
|
{
|
45
54
|
rb_raise( rb_eNotImpError, "type map is not suitable to map query params" );
|
46
|
-
return NULL;
|
47
55
|
}
|
48
56
|
|
49
57
|
VALUE
|
50
58
|
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
|
51
59
|
{
|
52
60
|
rb_raise( rb_eNotImpError, "type map is not suitable to map get_copy_data results" );
|
53
|
-
return Qnil;
|
54
61
|
}
|
55
62
|
|
56
63
|
const struct pg_typemap_funcs pg_typemap_funcs = {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
64
|
+
pg_typemap_fit_to_result,
|
65
|
+
pg_typemap_fit_to_query,
|
66
|
+
pg_typemap_fit_to_copy_get,
|
67
|
+
pg_typemap_result_value,
|
68
|
+
pg_typemap_typecast_query_param,
|
69
|
+
pg_typemap_typecast_copy_get
|
63
70
|
};
|
64
71
|
|
65
72
|
static VALUE
|
data/ext/pg_type_map_by_column.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id: pg_type_map_by_column.c,v
|
3
|
+
* $Id: pg_type_map_by_column.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -162,12 +162,12 @@ pg_tmbc_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, i
|
|
162
162
|
}
|
163
163
|
|
164
164
|
const struct pg_typemap_funcs pg_tmbc_funcs = {
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
165
|
+
pg_tmbc_fit_to_result,
|
166
|
+
pg_tmbc_fit_to_query,
|
167
|
+
pg_tmbc_fit_to_copy_get,
|
168
|
+
pg_tmbc_result_value,
|
169
|
+
pg_tmbc_typecast_query_param,
|
170
|
+
pg_tmbc_typecast_copy_get
|
171
171
|
};
|
172
172
|
|
173
173
|
static void
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_type_map_by_mri_type.c - PG::TypeMapByMriType class extension
|
3
|
-
* $Id: pg_type_map_by_mri_type.c,v
|
3
|
+
* $Id: pg_type_map_by_mri_type.c,v 1269b8ad77b8 2015/02/06 16:38:23 lars $
|
4
4
|
*
|
5
5
|
* This type map can be used to select value encoders based on the MRI-internal
|
6
6
|
* value type code.
|
@@ -39,7 +39,7 @@ static VALUE rb_cTypeMapByMriType;
|
|
39
39
|
typedef struct {
|
40
40
|
t_typemap typemap;
|
41
41
|
struct pg_tmbmt_converter {
|
42
|
-
FOR_EACH_MRI_TYPE( DECLARE_CODER )
|
42
|
+
FOR_EACH_MRI_TYPE( DECLARE_CODER )
|
43
43
|
} coders;
|
44
44
|
} t_tmbmt;
|
45
45
|
|
data/ext/pg_type_map_in_ruby.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_type_map_in_ruby.c - PG::TypeMapInRuby class extension
|
3
|
-
* $Id: pg_type_map_in_ruby.c,v
|
3
|
+
* $Id: pg_type_map_in_ruby.c,v 3d89d3aae4fd 2015/01/05 16:19:41 kanis $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -212,12 +212,9 @@ pg_tmir_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format
|
|
212
212
|
rb_encoding *p_encoding = rb_enc_from_index(enc_idx);
|
213
213
|
VALUE enc = rb_enc_from_encoding(p_encoding);
|
214
214
|
/* field_str is reused in-place by pg_text_dec_copy_row(), so we need to make
|
215
|
-
* a copy of the string buffer
|
216
|
-
|
217
|
-
|
218
|
-
VALUE field_str_copy = rb_str_new(RSTRING_PTR(field_str), RSTRING_LEN(field_str));
|
219
|
-
PG_ENCODING_SET_NOCHECK(field_str_copy, ENCODING_GET(field_str));
|
220
|
-
OBJ_INFECT(field_str_copy, field_str);
|
215
|
+
* a copy of the string buffer for use in ruby space. */
|
216
|
+
VALUE field_str_copy = rb_str_dup(field_str);
|
217
|
+
rb_str_modify(field_str_copy);
|
221
218
|
|
222
219
|
return rb_funcall( this->self, s_id_typecast_copy_get, 4, field_str_copy, INT2NUM(fieldno), INT2NUM(format), enc );
|
223
220
|
}
|
data/ext/util.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* util.c - Utils for ruby-pg
|
3
|
-
* $Id: util.c,v
|
3
|
+
* $Id: util.c,v 5fb9170f6a7d 2015/06/29 11:15:12 kanis $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -17,7 +17,7 @@ static const char base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijk
|
|
17
17
|
void
|
18
18
|
base64_encode( char *out, char *in, int len)
|
19
19
|
{
|
20
|
-
char *in_ptr = in + len;
|
20
|
+
unsigned char *in_ptr = (unsigned char *)in + len;
|
21
21
|
char *out_ptr = out + BASE64_ENCODED_SIZE(len);
|
22
22
|
int part_len = len % 3;
|
23
23
|
|
@@ -124,7 +124,7 @@ base64_decode( char *out, char *in, unsigned int len)
|
|
124
124
|
* At most n bytes will be examined from each string.
|
125
125
|
*/
|
126
126
|
int
|
127
|
-
|
127
|
+
rbpg_strncasecmp(const char *s1, const char *s2, size_t n)
|
128
128
|
{
|
129
129
|
while (n-- > 0)
|
130
130
|
{
|
data/ext/util.h
CHANGED
@@ -60,6 +60,6 @@
|
|
60
60
|
void base64_encode( char *out, char *in, int len);
|
61
61
|
int base64_decode( char *out, char *in, unsigned int len);
|
62
62
|
|
63
|
-
int
|
63
|
+
int rbpg_strncasecmp(const char *s1, const char *s2, size_t n);
|
64
64
|
|
65
65
|
#endif /* end __utils_h */
|