pg 1.6.1 → 1.6.3
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/CHANGELOG.md +26 -0
- data/Gemfile +4 -4
- data/README.md +11 -9
- data/Rakefile +6 -20
- data/ext/errorcodes.def +9 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +8 -1
- data/ext/extconf.rb +39 -9
- data/ext/pg.h +6 -4
- data/ext/pg_binary_decoder.c +1 -1
- data/ext/pg_binary_encoder.c +2 -2
- data/ext/pg_connection.c +22 -2
- data/ext/pg_result.c +96 -42
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +2 -2
- data/ext/pg_tuple.c +6 -6
- data/ext/pg_type_map.c +3 -1
- data/ext/pg_util.c +2 -2
- data/ext/pg_util.h +2 -2
- data/lib/pg/version.rb +2 -1
- data/lib/pg.rb +156 -135
- data/misc/glibc/Dockerfile +20 -0
- data/misc/glibc/docker-compose.yml +9 -0
- data/misc/glibc/glibc_spec.rb +5 -0
- data/ports/patches/krb5/1.22.1/0002-unknown-command-line-option-on-clang.patch +12 -0
- data.tar.gz.sig +0 -0
- metadata +22 -18
- metadata.gz.sig +0 -0
- /data/ports/patches/krb5/{1.21.3 → 1.22.1}/0001-Allow-static-linking-krb5-library.patch +0 -0
- /data/ports/patches/openssl/{3.5.1 → 3.5.2}/0001-aarch64-mingw.patch +0 -0
- /data/ports/patches/postgresql/{17.5 → 18.1}/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +0 -0
- /data/ports/patches/postgresql/{17.5 → 18.1}/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +0 -0
data/ext/pg_result.c
CHANGED
|
@@ -12,6 +12,7 @@ static VALUE sym_symbol, sym_string, sym_static_symbol;
|
|
|
12
12
|
static VALUE pgresult_type_map_set( VALUE, VALUE );
|
|
13
13
|
static t_pg_result *pgresult_get_this( VALUE );
|
|
14
14
|
static t_pg_result *pgresult_get_this_safe( VALUE );
|
|
15
|
+
static void ensure_init_for_tuple(VALUE self);
|
|
15
16
|
|
|
16
17
|
#if defined(HAVE_PQRESULTMEMORYSIZE)
|
|
17
18
|
|
|
@@ -114,7 +115,6 @@ pgresult_gc_mark( void *_this )
|
|
|
114
115
|
|
|
115
116
|
rb_gc_mark_movable( this->connection );
|
|
116
117
|
rb_gc_mark_movable( this->typemap );
|
|
117
|
-
rb_gc_mark_movable( this->tuple_hash );
|
|
118
118
|
rb_gc_mark_movable( this->field_map );
|
|
119
119
|
|
|
120
120
|
for( i=0; i < this->nfields; i++ ){
|
|
@@ -130,7 +130,6 @@ pgresult_gc_compact( void *_this )
|
|
|
130
130
|
|
|
131
131
|
pg_gc_location( this->connection );
|
|
132
132
|
pg_gc_location( this->typemap );
|
|
133
|
-
pg_gc_location( this->tuple_hash );
|
|
134
133
|
pg_gc_location( this->field_map );
|
|
135
134
|
|
|
136
135
|
for( i=0; i < this->nfields; i++ ){
|
|
@@ -212,7 +211,6 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
|
|
|
212
211
|
this->typemap = pg_typemap_all_strings;
|
|
213
212
|
this->p_typemap = RTYPEDDATA_DATA( this->typemap );
|
|
214
213
|
this->nfields = -1;
|
|
215
|
-
this->tuple_hash = Qnil;
|
|
216
214
|
this->field_map = Qnil;
|
|
217
215
|
this->flags = 0;
|
|
218
216
|
self = TypedData_Wrap_Struct(rb_cPGresult, &pgresult_type, this);
|
|
@@ -396,6 +394,7 @@ pg_result_freeze(VALUE self)
|
|
|
396
394
|
{
|
|
397
395
|
t_pg_result *this = pgresult_get_this(self);
|
|
398
396
|
|
|
397
|
+
ensure_init_for_tuple(self);
|
|
399
398
|
RB_OBJ_WRITE(self, &this->connection, Qnil);
|
|
400
399
|
return rb_call_super(0, NULL);
|
|
401
400
|
}
|
|
@@ -513,20 +512,46 @@ static void pgresult_init_fnames(VALUE self)
|
|
|
513
512
|
*
|
|
514
513
|
* The class to represent the query result tuples (rows).
|
|
515
514
|
* An instance of this class is created as the result of every query.
|
|
516
|
-
* All result rows and columns are stored in
|
|
517
|
-
* Whenever a value is accessed it is casted to a Ruby object by the assigned #type_map .
|
|
515
|
+
* All result rows and columns are stored in an immutable memory block attached to the PG::Result object unless streaming is used.
|
|
518
516
|
*
|
|
519
|
-
*
|
|
520
|
-
* You can invoke the #clear method to force deallocation of memory of the instance when finished with the result for better memory performance.
|
|
521
|
-
*
|
|
522
|
-
* Example:
|
|
517
|
+
* A PG::Result has various ways to retrieve the result data:
|
|
523
518
|
* require 'pg'
|
|
524
|
-
* conn = PG.connect(:
|
|
525
|
-
* res
|
|
526
|
-
* res.
|
|
527
|
-
* res
|
|
528
|
-
* res
|
|
519
|
+
* conn = PG.connect(dbname: 'test')
|
|
520
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
521
|
+
* res.num_fields # 3
|
|
522
|
+
* res.num_tuples # 1
|
|
523
|
+
* res.fname(2) # "c"
|
|
524
|
+
* res.fields # ["a", "b", "c"]
|
|
525
|
+
* res.getvalue(0,0) # '1'
|
|
526
|
+
* res[0] # {"a" => "1", "b" => "2", "c" => "3"}
|
|
527
|
+
* res.tuple_values(0) # ["1", "2", nil]
|
|
528
|
+
* res.tuple(0) # #<PG::Tuple a: "1", b: "2", c: nil>
|
|
529
|
+
* res.values # [["1", "2", nil]]
|
|
530
|
+
* res.field_values(:a) # ["1"]
|
|
531
|
+
* res.column_values(1) # ["2"]
|
|
532
|
+
* res.each.first # {"a" => "1", "b" => "2", "c" => nil}
|
|
533
|
+
* res.each_row.first # ["1", "2", nil]
|
|
534
|
+
*
|
|
535
|
+
* Whenever a value is accessed it is casted to a Ruby object by the assigned #type_map which is PG::TypeMapAllStrings by default.
|
|
536
|
+
* Similarly field names can be retrieved either as strings (default) or as symbols which can be switched per #field_name_type= .
|
|
537
|
+
*
|
|
538
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
539
|
+
* res.type_map = PG::TypeMapByColumn.new([PG::TextDecoder::Integer.new]*3)
|
|
540
|
+
* res.field_name_type = :symbol
|
|
541
|
+
* res.fname(2) # :c
|
|
542
|
+
* res.fields # [:a, :b, :c]
|
|
543
|
+
* res.getvalue(0,0) # 1
|
|
544
|
+
* res[0] # {a: 1, b: 2, c: nil}
|
|
545
|
+
* res.tuple_values(0) # [1, 2, nil]
|
|
546
|
+
* res.tuple(0) # #<PG::Tuple a: 1, b: 2, c: nil>
|
|
547
|
+
* res.values # [[1, 2, nil]]
|
|
548
|
+
* res.field_values(:a) # [1]
|
|
549
|
+
* res.column_values(1) # [2]
|
|
550
|
+
* res.each.first # {a: 1, b: 2, c: nil}
|
|
551
|
+
* res.each_row.first # [1, 2, nil]
|
|
529
552
|
*
|
|
553
|
+
* Since pg-1.1 the amount of memory in use by a PG::Result object is estimated and passed to ruby's garbage collector.
|
|
554
|
+
* You can invoke the #clear method to force deallocation of memory of the instance when finished with the result for better memory performance.
|
|
530
555
|
*/
|
|
531
556
|
|
|
532
557
|
/**************************************************************************
|
|
@@ -617,7 +642,7 @@ pgresult_error_message(VALUE self)
|
|
|
617
642
|
* call-seq:
|
|
618
643
|
* res.verbose_error_message( verbosity, show_context ) -> String
|
|
619
644
|
*
|
|
620
|
-
* Returns a reformatted version of the error message associated with
|
|
645
|
+
* Returns a reformatted version of the error message associated with the PG::Result object.
|
|
621
646
|
*
|
|
622
647
|
*/
|
|
623
648
|
static VALUE
|
|
@@ -705,6 +730,10 @@ pgresult_error_field(VALUE self, VALUE field)
|
|
|
705
730
|
* res.ntuples() -> Integer
|
|
706
731
|
*
|
|
707
732
|
* Returns the number of tuples in the query result.
|
|
733
|
+
*
|
|
734
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
735
|
+
* res.ntuples # 1
|
|
736
|
+
* res.num_tuples # 1
|
|
708
737
|
*/
|
|
709
738
|
static VALUE
|
|
710
739
|
pgresult_ntuples(VALUE self)
|
|
@@ -723,6 +752,9 @@ pgresult_ntuples_for_enum(VALUE self, VALUE args, VALUE eobj)
|
|
|
723
752
|
* res.nfields() -> Integer
|
|
724
753
|
*
|
|
725
754
|
* Returns the number of columns in the query result.
|
|
755
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
756
|
+
* res.nfields # 3
|
|
757
|
+
* res.num_fields # 3
|
|
726
758
|
*/
|
|
727
759
|
static VALUE
|
|
728
760
|
pgresult_nfields(VALUE self)
|
|
@@ -734,9 +766,9 @@ pgresult_nfields(VALUE self)
|
|
|
734
766
|
* call-seq:
|
|
735
767
|
* res.binary_tuples() -> Integer
|
|
736
768
|
*
|
|
737
|
-
* Returns 1 if the
|
|
769
|
+
* Returns 1 if the PG::Result contains binary data and 0 if it contains text data.
|
|
738
770
|
*
|
|
739
|
-
* This function is deprecated (except for its use in connection with COPY), because it is possible for a single
|
|
771
|
+
* This function is deprecated (except for its use in connection with COPY), because it is possible for a single PG::Result to contain text data in some columns and binary data in others.
|
|
740
772
|
* Result#fformat is preferred. binary_tuples returns 1 only if all columns of the result are binary (format 1).
|
|
741
773
|
*/
|
|
742
774
|
static VALUE
|
|
@@ -752,6 +784,8 @@ pgresult_binary_tuples(VALUE self)
|
|
|
752
784
|
* Returns the name of the column corresponding to _index_.
|
|
753
785
|
* Depending on #field_name_type= it's a String or Symbol.
|
|
754
786
|
*
|
|
787
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
788
|
+
* res.fname(2) # "c"
|
|
755
789
|
*/
|
|
756
790
|
static VALUE
|
|
757
791
|
pgresult_fname(VALUE self, VALUE index)
|
|
@@ -1122,6 +1156,9 @@ pgresult_oid_value(VALUE self)
|
|
|
1122
1156
|
* res[ n ] -> Hash
|
|
1123
1157
|
*
|
|
1124
1158
|
* Returns tuple _n_ as a hash.
|
|
1159
|
+
*
|
|
1160
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1161
|
+
* res[0] # {"a" => "1", "b" => "2", "c" => "3"}
|
|
1125
1162
|
*/
|
|
1126
1163
|
static VALUE
|
|
1127
1164
|
pgresult_aref(VALUE self, VALUE index)
|
|
@@ -1138,16 +1175,11 @@ pgresult_aref(VALUE self, VALUE index)
|
|
|
1138
1175
|
if ( tuple_num < 0 || tuple_num >= num_tuples )
|
|
1139
1176
|
rb_raise( rb_eIndexError, "Index %d is out of range", tuple_num );
|
|
1140
1177
|
|
|
1141
|
-
|
|
1142
|
-
* This is somewhat faster than populating an empty Hash object. */
|
|
1143
|
-
tuple = NIL_P(this->tuple_hash) ? rb_hash_new() : this->tuple_hash;
|
|
1178
|
+
tuple = rb_hash_new_capa(this->nfields);
|
|
1144
1179
|
for ( field_num = 0; field_num < this->nfields; field_num++ ) {
|
|
1145
1180
|
VALUE val = this->p_typemap->funcs.typecast_result_value(this->p_typemap, self, tuple_num, field_num);
|
|
1146
1181
|
rb_hash_aset( tuple, this->fnames[field_num], val );
|
|
1147
1182
|
}
|
|
1148
|
-
/* Store a copy of the filled hash for use at the next row. */
|
|
1149
|
-
if( num_tuples > 10 )
|
|
1150
|
-
RB_OBJ_WRITE(self, &this->tuple_hash, rb_hash_dup(tuple));
|
|
1151
1183
|
|
|
1152
1184
|
return tuple;
|
|
1153
1185
|
}
|
|
@@ -1156,7 +1188,10 @@ pgresult_aref(VALUE self, VALUE index)
|
|
|
1156
1188
|
* call-seq:
|
|
1157
1189
|
* res.each_row { |row| ... }
|
|
1158
1190
|
*
|
|
1159
|
-
* Yields
|
|
1191
|
+
* Yields an Array object for each row in the result.
|
|
1192
|
+
*
|
|
1193
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1194
|
+
* res.each_row.first # ["1", "2", nil]
|
|
1160
1195
|
*/
|
|
1161
1196
|
static VALUE
|
|
1162
1197
|
pgresult_each_row(VALUE self)
|
|
@@ -1191,6 +1226,9 @@ pgresult_each_row(VALUE self)
|
|
|
1191
1226
|
* res.values -> Array
|
|
1192
1227
|
*
|
|
1193
1228
|
* Returns all tuples as an array of arrays.
|
|
1229
|
+
*
|
|
1230
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1231
|
+
* res.values # [["1", "2", nil]]
|
|
1194
1232
|
*/
|
|
1195
1233
|
static VALUE
|
|
1196
1234
|
pgresult_values(VALUE self)
|
|
@@ -1240,12 +1278,13 @@ make_column_result_array( VALUE self, int col )
|
|
|
1240
1278
|
|
|
1241
1279
|
|
|
1242
1280
|
/*
|
|
1243
|
-
*
|
|
1244
|
-
*
|
|
1281
|
+
* call-seq:
|
|
1282
|
+
* res.column_values( n ) -> array
|
|
1245
1283
|
*
|
|
1246
|
-
*
|
|
1247
|
-
* tuple in the result.
|
|
1284
|
+
* Returns an Array of the values from the nth column of each tuple in the result.
|
|
1248
1285
|
*
|
|
1286
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1287
|
+
* res.column_values(1) # ["2"]
|
|
1249
1288
|
*/
|
|
1250
1289
|
static VALUE
|
|
1251
1290
|
pgresult_column_values(VALUE self, VALUE index)
|
|
@@ -1256,11 +1295,13 @@ pgresult_column_values(VALUE self, VALUE index)
|
|
|
1256
1295
|
|
|
1257
1296
|
|
|
1258
1297
|
/*
|
|
1259
|
-
*
|
|
1298
|
+
* call-seq:
|
|
1260
1299
|
* res.field_values( field ) -> array
|
|
1261
1300
|
*
|
|
1262
|
-
*
|
|
1301
|
+
* Returns an Array of the values from the given _field_ of each tuple in the result.
|
|
1263
1302
|
*
|
|
1303
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1304
|
+
* res.field_values(:a) # ["1"]
|
|
1264
1305
|
*/
|
|
1265
1306
|
static VALUE
|
|
1266
1307
|
pgresult_field_values( VALUE self, VALUE field )
|
|
@@ -1281,11 +1322,13 @@ pgresult_field_values( VALUE self, VALUE field )
|
|
|
1281
1322
|
|
|
1282
1323
|
|
|
1283
1324
|
/*
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1325
|
+
* call-seq:
|
|
1326
|
+
* res.tuple_values( n ) -> array
|
|
1286
1327
|
*
|
|
1287
|
-
*
|
|
1328
|
+
* Returns an Array of the field values from the nth row of the result.
|
|
1288
1329
|
*
|
|
1330
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1331
|
+
* res.tuple_values(0) # ["1", "2", nil]
|
|
1289
1332
|
*/
|
|
1290
1333
|
static VALUE
|
|
1291
1334
|
pgresult_tuple_values(VALUE self, VALUE index)
|
|
@@ -1320,11 +1363,12 @@ static void ensure_init_for_tuple(VALUE self)
|
|
|
1320
1363
|
|
|
1321
1364
|
if( this->field_map == Qnil ){
|
|
1322
1365
|
int i;
|
|
1323
|
-
VALUE field_map
|
|
1366
|
+
VALUE field_map;
|
|
1324
1367
|
|
|
1325
1368
|
if( this->nfields == -1 )
|
|
1326
1369
|
pgresult_init_fnames( self );
|
|
1327
1370
|
|
|
1371
|
+
field_map = rb_hash_new_capa(this->nfields);
|
|
1328
1372
|
for( i = 0; i < this->nfields; i++ ){
|
|
1329
1373
|
rb_hash_aset(field_map, this->fnames[i], INT2FIX(i));
|
|
1330
1374
|
}
|
|
@@ -1334,11 +1378,13 @@ static void ensure_init_for_tuple(VALUE self)
|
|
|
1334
1378
|
}
|
|
1335
1379
|
|
|
1336
1380
|
/*
|
|
1337
|
-
*
|
|
1338
|
-
*
|
|
1381
|
+
* call-seq:
|
|
1382
|
+
* res.tuple( n ) -> PG::Tuple
|
|
1339
1383
|
*
|
|
1340
|
-
*
|
|
1384
|
+
* Returns a PG::Tuple from the nth row of the result.
|
|
1341
1385
|
*
|
|
1386
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1387
|
+
* res.tuple(0) # #<PG::Tuple a: "1", b: "2", c: nil>
|
|
1342
1388
|
*/
|
|
1343
1389
|
static VALUE
|
|
1344
1390
|
pgresult_tuple(VALUE self, VALUE index)
|
|
@@ -1363,7 +1409,10 @@ pgresult_tuple(VALUE self, VALUE index)
|
|
|
1363
1409
|
* call-seq:
|
|
1364
1410
|
* res.each{ |tuple| ... }
|
|
1365
1411
|
*
|
|
1366
|
-
*
|
|
1412
|
+
* Yields a Hash object for each row in the result.
|
|
1413
|
+
*
|
|
1414
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1415
|
+
* res.each.first # {"a" => "1", "b" => "2", "c" => nil}
|
|
1367
1416
|
*/
|
|
1368
1417
|
static VALUE
|
|
1369
1418
|
pgresult_each(VALUE self)
|
|
@@ -1386,6 +1435,9 @@ pgresult_each(VALUE self)
|
|
|
1386
1435
|
* res.fields() -> Array
|
|
1387
1436
|
*
|
|
1388
1437
|
* Depending on #field_name_type= returns an array of strings or symbols representing the names of the fields in the result.
|
|
1438
|
+
*
|
|
1439
|
+
* res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
1440
|
+
* res.fields # ["a", "b", "c"]
|
|
1389
1441
|
*/
|
|
1390
1442
|
static VALUE
|
|
1391
1443
|
pgresult_fields(VALUE self)
|
|
@@ -1402,7 +1454,7 @@ pgresult_fields(VALUE self)
|
|
|
1402
1454
|
* call-seq:
|
|
1403
1455
|
* res.type_map = typemap
|
|
1404
1456
|
*
|
|
1405
|
-
* Set the TypeMap that is used for type casts of result values to ruby objects.
|
|
1457
|
+
* Set the PG::TypeMap that is used for type casts of result values to ruby objects.
|
|
1406
1458
|
*
|
|
1407
1459
|
* All value retrieval methods will respect the type map and will do the
|
|
1408
1460
|
* type casts from PostgreSQL's wire format to Ruby objects on the fly,
|
|
@@ -1410,6 +1462,7 @@ pgresult_fields(VALUE self)
|
|
|
1410
1462
|
*
|
|
1411
1463
|
* +typemap+ must be a kind of PG::TypeMap .
|
|
1412
1464
|
*
|
|
1465
|
+
* See also #map_types! and PG::BasicTypeMapForResults
|
|
1413
1466
|
*/
|
|
1414
1467
|
static VALUE
|
|
1415
1468
|
pgresult_type_map_set(VALUE self, VALUE typemap)
|
|
@@ -1432,7 +1485,8 @@ pgresult_type_map_set(VALUE self, VALUE typemap)
|
|
|
1432
1485
|
* call-seq:
|
|
1433
1486
|
* res.type_map -> value
|
|
1434
1487
|
*
|
|
1435
|
-
* Returns the TypeMap that is currently set for type casts of result values to ruby objects.
|
|
1488
|
+
* Returns the PG::TypeMap that is currently set for type casts of result values to ruby objects.
|
|
1489
|
+
* The default is retrieved from PG::Connection#type_map_for_results , which defaults to PG::TypeMapAllStrings .
|
|
1436
1490
|
*
|
|
1437
1491
|
*/
|
|
1438
1492
|
static VALUE
|
|
@@ -1572,8 +1626,8 @@ pgresult_stream_any(VALUE self, int (*yielder)(VALUE, int, int, void*), void* da
|
|
|
1572
1626
|
* wrapping each row into a dedicated result object, it delivers data in nearly
|
|
1573
1627
|
* the same speed as with ordinary results.
|
|
1574
1628
|
*
|
|
1575
|
-
* The base result must be in status PGRES_SINGLE_TUPLE or PGRES_TUPLES_CHUNK
|
|
1576
|
-
* It iterates over all tuples until the status changes to PGRES_TUPLES_OK
|
|
1629
|
+
* The base result must be in status +PGRES_SINGLE_TUPLE+ or +PGRES_TUPLES_CHUNK+.
|
|
1630
|
+
* It iterates over all tuples until the status changes to +PGRES_TUPLES_OK+.
|
|
1577
1631
|
* A PG::Error is raised for any errors from the server.
|
|
1578
1632
|
*
|
|
1579
1633
|
* Row description data does not change while the iteration. All value retrieval
|
data/ext/pg_text_decoder.c
CHANGED
|
@@ -579,7 +579,7 @@ pg_text_dec_from_base64(t_pg_coder *conv, const char *val, int len, int tuple, i
|
|
|
579
579
|
/* create a buffer of the expected decoded length */
|
|
580
580
|
VALUE out_value = rb_str_new(NULL, BASE64_DECODED_SIZE(len));
|
|
581
581
|
|
|
582
|
-
decoded_len =
|
|
582
|
+
decoded_len = rbpg_base64_decode( RSTRING_PTR(out_value), val, len );
|
|
583
583
|
rb_str_set_len(out_value, decoded_len);
|
|
584
584
|
|
|
585
585
|
/* Is it a pure String conversion? Then we can directly send out_value to the user. */
|
data/ext/pg_text_encoder.c
CHANGED
|
@@ -784,7 +784,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
784
784
|
if(out){
|
|
785
785
|
/* Second encoder pass, if required */
|
|
786
786
|
strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
|
|
787
|
-
|
|
787
|
+
rbpg_base64_encode( out, out, strlen );
|
|
788
788
|
|
|
789
789
|
return BASE64_ENCODED_SIZE(strlen);
|
|
790
790
|
} else {
|
|
@@ -799,7 +799,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
799
799
|
out_str = rb_str_new(NULL, BASE64_ENCODED_SIZE(strlen));
|
|
800
800
|
PG_ENCODING_SET_NOCHECK(out_str, enc_idx);
|
|
801
801
|
|
|
802
|
-
|
|
802
|
+
rbpg_base64_encode( RSTRING_PTR(out_str), RSTRING_PTR(subint), strlen);
|
|
803
803
|
*intermediate = out_str;
|
|
804
804
|
|
|
805
805
|
return -1;
|
data/ext/pg_tuple.c
CHANGED
|
@@ -242,10 +242,10 @@ pg_tuple_materialize(VALUE self)
|
|
|
242
242
|
* An integer +key+ is interpreted as column index.
|
|
243
243
|
* Negative values of index count from the end of the array.
|
|
244
244
|
*
|
|
245
|
-
* Depending on Result#field_name_type= a string or symbol +key+ is interpreted as column name.
|
|
245
|
+
* Depending on PG::Result#field_name_type= a string or symbol +key+ is interpreted as column name.
|
|
246
246
|
*
|
|
247
247
|
* If the key can't be found, there are several options:
|
|
248
|
-
* With no other arguments, it will raise a IndexError exception;
|
|
248
|
+
* With no other arguments, it will raise a +IndexError+ exception;
|
|
249
249
|
* if default is given, then that will be returned;
|
|
250
250
|
* if the optional code block is specified, then that will be run and its result returned.
|
|
251
251
|
*/
|
|
@@ -302,7 +302,7 @@ pg_tuple_fetch(int argc, VALUE *argv, VALUE self)
|
|
|
302
302
|
* An integer +key+ is interpreted as column index.
|
|
303
303
|
* Negative values of index count from the end of the array.
|
|
304
304
|
*
|
|
305
|
-
* Depending on Result#field_name_type= a string or symbol +key+ is interpreted as column name.
|
|
305
|
+
* Depending on PG::Result#field_name_type= a string or symbol +key+ is interpreted as column name.
|
|
306
306
|
*
|
|
307
307
|
* If the key can't be found, it returns +nil+ .
|
|
308
308
|
*/
|
|
@@ -405,7 +405,7 @@ pg_tuple_each_value(VALUE self)
|
|
|
405
405
|
* tup.values -> Array
|
|
406
406
|
*
|
|
407
407
|
* Returns the values of this tuple as Array.
|
|
408
|
-
*
|
|
408
|
+
* <tt>res.tuple(i).values</tt> is equal to <tt>res.tuple_values(i)</tt> .
|
|
409
409
|
*/
|
|
410
410
|
static VALUE
|
|
411
411
|
pg_tuple_values(VALUE self)
|
|
@@ -474,7 +474,7 @@ pg_tuple_dump(VALUE self)
|
|
|
474
474
|
values = rb_ary_new4(this->num_fields, &this->values[0]);
|
|
475
475
|
a = rb_ary_new3(2, field_names, values);
|
|
476
476
|
|
|
477
|
-
|
|
477
|
+
rb_copy_generic_ivar(a, self);
|
|
478
478
|
|
|
479
479
|
return a;
|
|
480
480
|
}
|
|
@@ -510,7 +510,7 @@ pg_tuple_load(VALUE self, VALUE a)
|
|
|
510
510
|
if (RARRAY_LENINT(field_names) != num_fields)
|
|
511
511
|
rb_raise(rb_eTypeError, "different number of fields and values");
|
|
512
512
|
|
|
513
|
-
field_map =
|
|
513
|
+
field_map = rb_hash_new_capa(num_fields);
|
|
514
514
|
for( i = 0; i < num_fields; i++ ){
|
|
515
515
|
rb_hash_aset(field_map, RARRAY_AREF(field_names, i), INT2FIX(i));
|
|
516
516
|
}
|
data/ext/pg_type_map.c
CHANGED
|
@@ -187,7 +187,9 @@ init_pg_type_map(void)
|
|
|
187
187
|
*
|
|
188
188
|
* This is the base class for type maps.
|
|
189
189
|
* See derived classes for implementations of different type cast strategies
|
|
190
|
-
* ( PG::TypeMapByColumn, PG::TypeMapByOid ).
|
|
190
|
+
* ( PG::TypeMapByColumn, PG::TypeMapByOid, etc.).
|
|
191
|
+
*
|
|
192
|
+
* Find more type maps in the {README}[rdoc-ref:README.md@Type+Casts].
|
|
191
193
|
*
|
|
192
194
|
*/
|
|
193
195
|
rb_cTypeMap = rb_define_class_under( rb_mPG, "TypeMap", rb_cObject );
|
data/ext/pg_util.c
CHANGED
|
@@ -15,7 +15,7 @@ static const char base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijk
|
|
|
15
15
|
* in-place (with _out_ == _in_).
|
|
16
16
|
*/
|
|
17
17
|
void
|
|
18
|
-
|
|
18
|
+
rbpg_base64_encode( char *out, const char *in, int len)
|
|
19
19
|
{
|
|
20
20
|
const unsigned char *in_ptr = (const unsigned char *)in + len;
|
|
21
21
|
char *out_ptr = out + BASE64_ENCODED_SIZE(len);
|
|
@@ -72,7 +72,7 @@ static const unsigned char base64_decode_table[] =
|
|
|
72
72
|
* It is possible to decode a string in-place (with _out_ == _in_).
|
|
73
73
|
*/
|
|
74
74
|
int
|
|
75
|
-
|
|
75
|
+
rbpg_base64_decode( char *out, const char *in, unsigned int len)
|
|
76
76
|
{
|
|
77
77
|
unsigned char a, b, c, d;
|
|
78
78
|
const unsigned char *in_ptr = (const unsigned char *)in;
|
data/ext/pg_util.h
CHANGED
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
#define BASE64_ENCODED_SIZE(strlen) (((strlen) + 2) / 3 * 4)
|
|
58
58
|
#define BASE64_DECODED_SIZE(base64len) (((base64len) + 3) / 4 * 3)
|
|
59
59
|
|
|
60
|
-
void
|
|
61
|
-
int
|
|
60
|
+
void rbpg_base64_encode( char *out, const char *in, int len);
|
|
61
|
+
int rbpg_base64_decode( char *out, const char *in, unsigned int len);
|
|
62
62
|
|
|
63
63
|
int rbpg_strncasecmp(const char *s1, const char *s2, size_t n);
|
|
64
64
|
|
data/lib/pg/version.rb
CHANGED