pg 1.6.3 → 1.7.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +52 -6
- data/Gemfile +1 -0
- data/README.ja.md +81 -30
- data/README.md +14 -7
- data/Rakefile +8 -7
- data/certs/larskanis-2026.pem +24 -0
- data/ext/extconf.rb +18 -28
- data/ext/gvl_wrappers.c +2 -2
- data/ext/gvl_wrappers.h +40 -160
- data/ext/pg.c +8 -12
- data/ext/pg.h +8 -11
- data/ext/pg_binary_decoder.c +6 -2
- data/ext/pg_binary_encoder.c +7 -0
- data/ext/pg_cancel_connection.c +6 -6
- data/ext/pg_coder.c +4 -4
- data/ext/pg_connection.c +196 -159
- data/ext/pg_copy_coder.c +34 -21
- data/ext/pg_record_coder.c +10 -6
- data/ext/pg_result.c +42 -26
- data/ext/pg_text_decoder.c +6 -6
- data/ext/pg_text_encoder.c +7 -2
- data/ext/pg_tuple.c +1 -1
- data/ext/pg_type_map.c +41 -1
- data/ext/pg_type_map_all_strings.c +2 -2
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +2 -2
- data/ext/pg_type_map_by_oid.c +1 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/lib/pg/basic_type_map_based_on_result.rb +5 -0
- data/lib/pg/basic_type_map_for_queries.rb +9 -2
- data/lib/pg/basic_type_map_for_results.rb +5 -0
- data/lib/pg/connection.rb +166 -76
- data/lib/pg/text_decoder/date.rb +1 -1
- data/lib/pg/text_decoder/json.rb +1 -1
- data/lib/pg/text_encoder/date.rb +7 -1
- data/lib/pg/text_encoder/json.rb +1 -1
- data/lib/pg/version.rb +1 -1
- data/misc/yugabyte/docker-compose.yml +1 -1
- data/pg.gemspec +1 -1
- data/sample/async_mixed.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +18 -19
- metadata.gz.sig +0 -0
- data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +0 -21
- data/ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +0 -52
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0001-Allow-static-linking-krb5-library.patch +0 -0
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0002-unknown-command-line-option-on-clang.patch +0 -0
- /data/ports/patches/postgresql/{18.1 → 18.6}/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +0 -0
data/ext/pg_connection.c
CHANGED
|
@@ -14,7 +14,7 @@ VALUE rb_cPGconn;
|
|
|
14
14
|
static ID s_id_encode;
|
|
15
15
|
static ID s_id_autoclose_set;
|
|
16
16
|
static VALUE sym_type, sym_format, sym_value;
|
|
17
|
-
static VALUE sym_symbol, sym_string
|
|
17
|
+
static VALUE sym_symbol, sym_string;
|
|
18
18
|
|
|
19
19
|
static VALUE pgconn_finish( VALUE );
|
|
20
20
|
static VALUE pgconn_set_default_encoding( VALUE self );
|
|
@@ -153,13 +153,13 @@ pgconn_make_conninfo_array( const PQconninfoOption *options )
|
|
|
153
153
|
return ary;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
static const char *pg_cstr_enc(VALUE str, int enc_idx){
|
|
156
|
+
static const char *pg_cstr_enc(VALUE str, int enc_idx, VALUE *transcoded_str){
|
|
157
157
|
const char *ptr = StringValueCStr(str);
|
|
158
158
|
if( ENCODING_GET(str) == enc_idx ){
|
|
159
159
|
return ptr;
|
|
160
160
|
} else {
|
|
161
|
-
|
|
162
|
-
return StringValueCStr(
|
|
161
|
+
*transcoded_str = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
|
|
162
|
+
return StringValueCStr(*transcoded_str);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -188,6 +188,7 @@ pgconn_gc_compact( void *_this )
|
|
|
188
188
|
pg_gc_location( this->socket_io );
|
|
189
189
|
pg_gc_location( this->notice_receiver );
|
|
190
190
|
pg_gc_location( this->notice_processor );
|
|
191
|
+
pg_gc_location( this->self );
|
|
191
192
|
pg_gc_location( this->type_map_for_queries );
|
|
192
193
|
pg_gc_location( this->type_map_for_results );
|
|
193
194
|
pg_gc_location( this->trace_stream );
|
|
@@ -260,6 +261,7 @@ pgconn_s_allocate( VALUE klass )
|
|
|
260
261
|
RB_OBJ_WRITE(self, &this->socket_io, Qnil);
|
|
261
262
|
RB_OBJ_WRITE(self, &this->notice_receiver, Qnil);
|
|
262
263
|
RB_OBJ_WRITE(self, &this->notice_processor, Qnil);
|
|
264
|
+
RB_OBJ_WRITE(self, &this->self, self);
|
|
263
265
|
RB_OBJ_WRITE(self, &this->type_map_for_queries, pg_typemap_all_strings);
|
|
264
266
|
RB_OBJ_WRITE(self, &this->type_map_for_results, pg_typemap_all_strings);
|
|
265
267
|
RB_OBJ_WRITE(self, &this->encoder_for_put_copy_data, Qnil);
|
|
@@ -280,7 +282,8 @@ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
|
|
|
280
282
|
|
|
281
283
|
this = pg_get_connection( self );
|
|
282
284
|
conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
|
|
283
|
-
this->pgconn =
|
|
285
|
+
this->pgconn = PQconnectdb(StringValueCStr(conninfo));
|
|
286
|
+
RB_GC_GUARD(conninfo);
|
|
284
287
|
|
|
285
288
|
if(this->pgconn == NULL)
|
|
286
289
|
rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate PGconn structure");
|
|
@@ -329,6 +332,7 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
|
329
332
|
this = pg_get_connection( rb_conn );
|
|
330
333
|
conninfo = rb_funcall2( klass, rb_intern("parse_connect_args"), argc, argv );
|
|
331
334
|
this->pgconn = gvl_PQconnectStart( StringValueCStr(conninfo) );
|
|
335
|
+
RB_GC_GUARD(conninfo);
|
|
332
336
|
|
|
333
337
|
if( this->pgconn == NULL )
|
|
334
338
|
rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate PGconn structure");
|
|
@@ -350,6 +354,7 @@ pgconn_s_sync_ping( int argc, VALUE *argv, VALUE klass )
|
|
|
350
354
|
|
|
351
355
|
conninfo = rb_funcall2( klass, rb_intern("parse_connect_args"), argc, argv );
|
|
352
356
|
ping = gvl_PQping( StringValueCStr(conninfo) );
|
|
357
|
+
RB_GC_GUARD(conninfo);
|
|
353
358
|
|
|
354
359
|
return INT2FIX((int)ping);
|
|
355
360
|
}
|
|
@@ -434,7 +439,7 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
|
434
439
|
Check_Type(password, T_STRING);
|
|
435
440
|
Check_Type(username, T_STRING);
|
|
436
441
|
|
|
437
|
-
encrypted =
|
|
442
|
+
encrypted = PQencryptPasswordConn(conn, StringValueCStr(password), StringValueCStr(username), RTEST(algorithm) ? StringValueCStr(algorithm) : NULL);
|
|
438
443
|
if ( encrypted ) {
|
|
439
444
|
rval = rb_str_new2( encrypted );
|
|
440
445
|
PQfreemem( encrypted );
|
|
@@ -560,7 +565,7 @@ static VALUE
|
|
|
560
565
|
pgconn_sync_reset( VALUE self )
|
|
561
566
|
{
|
|
562
567
|
pgconn_close_socket_io( self );
|
|
563
|
-
|
|
568
|
+
PQreset( pg_get_pgconn(self) );
|
|
564
569
|
return self;
|
|
565
570
|
}
|
|
566
571
|
|
|
@@ -568,13 +573,17 @@ static VALUE
|
|
|
568
573
|
pgconn_reset_start2( VALUE self, VALUE conninfo )
|
|
569
574
|
{
|
|
570
575
|
t_pg_connection *this = pg_get_connection( self );
|
|
576
|
+
/* Ensure conninfo is a valid C string before closing the connection. */
|
|
577
|
+
char *p_conninfo = StringValueCStr(conninfo);
|
|
571
578
|
|
|
572
579
|
/* Close old connection */
|
|
573
580
|
pgconn_close_socket_io( self );
|
|
574
581
|
PQfinish( this->pgconn );
|
|
582
|
+
this->pgconn = NULL; /* Ensure no double free can happen. */
|
|
575
583
|
|
|
576
584
|
/* Start new connection */
|
|
577
|
-
this->pgconn = gvl_PQconnectStart(
|
|
585
|
+
this->pgconn = gvl_PQconnectStart( p_conninfo );
|
|
586
|
+
RB_GC_GUARD(conninfo);
|
|
578
587
|
|
|
579
588
|
if( this->pgconn == NULL )
|
|
580
589
|
rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate PGconn structure");
|
|
@@ -865,6 +874,33 @@ pgconn_protocol_version(VALUE self)
|
|
|
865
874
|
return INT2NUM(protocol_version);
|
|
866
875
|
}
|
|
867
876
|
|
|
877
|
+
#ifdef LIBPQ_HAS_FULL_PROTOCOL_VERSION
|
|
878
|
+
/*
|
|
879
|
+
* call-seq:
|
|
880
|
+
* conn.full_protocol_version -> Integer
|
|
881
|
+
*
|
|
882
|
+
* Interrogates the frontend/backend protocol being used, including minor version.
|
|
883
|
+
*
|
|
884
|
+
* Applications might wish to use this function to determine whether certain features are supported.
|
|
885
|
+
* The result is the major version multiplied by 10000 added to the minor version, e.g. 30002 for version 3.2.
|
|
886
|
+
* The protocol version will not change after connection startup is complete, but it could theoretically change during a connection reset.
|
|
887
|
+
* The 3.0 protocol is supported by PostgreSQL server versions 7.4 and above.
|
|
888
|
+
*
|
|
889
|
+
* PG::ConnectionBad is raised if the connection is bad.
|
|
890
|
+
*
|
|
891
|
+
* Available since PostgreSQL-18.
|
|
892
|
+
*/
|
|
893
|
+
static VALUE
|
|
894
|
+
pgconn_full_protocol_version(VALUE self)
|
|
895
|
+
{
|
|
896
|
+
int protocol_version = PQfullProtocolVersion(pg_get_pgconn(self));
|
|
897
|
+
if (protocol_version == 0) {
|
|
898
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "PQfullProtocolVersion() can't get protocol version");
|
|
899
|
+
}
|
|
900
|
+
return INT2NUM(protocol_version);
|
|
901
|
+
}
|
|
902
|
+
#endif
|
|
903
|
+
|
|
868
904
|
/*
|
|
869
905
|
* call-seq:
|
|
870
906
|
* conn.server_version -> Integer
|
|
@@ -1013,7 +1049,7 @@ pgconn_backend_pid(VALUE self)
|
|
|
1013
1049
|
return INT2NUM(PQbackendPID(pg_get_pgconn(self)));
|
|
1014
1050
|
}
|
|
1015
1051
|
|
|
1016
|
-
#ifndef
|
|
1052
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
1017
1053
|
typedef struct
|
|
1018
1054
|
{
|
|
1019
1055
|
struct sockaddr_storage addr;
|
|
@@ -1100,11 +1136,11 @@ static VALUE pgconn_sync_exec_params( int, VALUE *, VALUE );
|
|
|
1100
1136
|
* This function has the same behavior as #async_exec, but is implemented using the synchronous command processing API of libpq.
|
|
1101
1137
|
* It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
|
|
1102
1138
|
*
|
|
1103
|
-
*
|
|
1104
|
-
* However #async_exec has two advantages:
|
|
1139
|
+
* However #async_exec has some advantages:
|
|
1105
1140
|
*
|
|
1106
|
-
* 1. #async_exec
|
|
1107
|
-
* 2.
|
|
1141
|
+
* 1. Only #async_exec allows concurrent threads to run, while waiting for a server response.
|
|
1142
|
+
* 2. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
|
|
1143
|
+
* 3. Ruby VM gets notified about IO blocked operations and can pass them through <tt>Fiber.scheduler</tt>.
|
|
1108
1144
|
* So only <tt>async_*</tt> methods are compatible to event based schedulers like the async gem.
|
|
1109
1145
|
*/
|
|
1110
1146
|
static VALUE
|
|
@@ -1117,8 +1153,10 @@ pgconn_sync_exec(int argc, VALUE *argv, VALUE self)
|
|
|
1117
1153
|
/* If called with no or nil parameters, use PQexec for compatibility */
|
|
1118
1154
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
|
1119
1155
|
VALUE query_str = argv[0];
|
|
1156
|
+
VALUE transcoded_str;
|
|
1120
1157
|
|
|
1121
|
-
result =
|
|
1158
|
+
result = PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx, &transcoded_str));
|
|
1159
|
+
RB_GC_GUARD(transcoded_str);
|
|
1122
1160
|
rb_pgresult = pg_new_result(result, self);
|
|
1123
1161
|
pg_result_check(rb_pgresult);
|
|
1124
1162
|
if (rb_block_given_p()) {
|
|
@@ -1256,7 +1294,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
|
1256
1294
|
int nParams;
|
|
1257
1295
|
int i=0;
|
|
1258
1296
|
t_pg_coder *conv;
|
|
1259
|
-
|
|
1297
|
+
size_t required_pool_size;
|
|
1260
1298
|
char *memory_pool;
|
|
1261
1299
|
|
|
1262
1300
|
Check_Type(paramsData->params, T_ARRAY);
|
|
@@ -1268,7 +1306,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
|
1268
1306
|
paramsData->typecast_heap_chain = Qnil;
|
|
1269
1307
|
paramsData->gc_array = Qnil;
|
|
1270
1308
|
|
|
1271
|
-
nParams = (
|
|
1309
|
+
nParams = RARRAY_LENINT(paramsData->params);
|
|
1272
1310
|
|
|
1273
1311
|
required_pool_size = nParams * (
|
|
1274
1312
|
sizeof(char *) +
|
|
@@ -1415,6 +1453,7 @@ pgconn_sync_exec_params( int argc, VALUE *argv, VALUE self )
|
|
|
1415
1453
|
PGresult *result = NULL;
|
|
1416
1454
|
VALUE rb_pgresult;
|
|
1417
1455
|
VALUE command, in_res_fmt;
|
|
1456
|
+
VALUE transcoded_str;
|
|
1418
1457
|
int nParams;
|
|
1419
1458
|
int resultFormat;
|
|
1420
1459
|
struct query_params_data paramsData = { this->enc_idx };
|
|
@@ -1436,9 +1475,10 @@ pgconn_sync_exec_params( int argc, VALUE *argv, VALUE self )
|
|
|
1436
1475
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
|
1437
1476
|
nParams = alloc_query_params( ¶msData );
|
|
1438
1477
|
|
|
1439
|
-
result =
|
|
1478
|
+
result = PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx, &transcoded_str), nParams, paramsData.types,
|
|
1440
1479
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
|
1441
1480
|
|
|
1481
|
+
RB_GC_GUARD(transcoded_str);
|
|
1442
1482
|
free_query_params( ¶msData );
|
|
1443
1483
|
|
|
1444
1484
|
rb_pgresult = pg_new_result(result, self);
|
|
@@ -1467,6 +1507,7 @@ pgconn_sync_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
1467
1507
|
VALUE rb_pgresult;
|
|
1468
1508
|
VALUE name, command, in_paramtypes;
|
|
1469
1509
|
VALUE param;
|
|
1510
|
+
VALUE transcoded_str1, transcoded_str2;
|
|
1470
1511
|
int i = 0;
|
|
1471
1512
|
int nParams = 0;
|
|
1472
1513
|
Oid *paramTypes = NULL;
|
|
@@ -1475,12 +1516,12 @@ pgconn_sync_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
1475
1516
|
int enc_idx = this->enc_idx;
|
|
1476
1517
|
|
|
1477
1518
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
|
1478
|
-
name_cstr = pg_cstr_enc(name, enc_idx);
|
|
1479
|
-
command_cstr = pg_cstr_enc(command, enc_idx);
|
|
1519
|
+
name_cstr = pg_cstr_enc(name, enc_idx, &transcoded_str1);
|
|
1520
|
+
command_cstr = pg_cstr_enc(command, enc_idx, &transcoded_str2);
|
|
1480
1521
|
|
|
1481
1522
|
if(! NIL_P(in_paramtypes)) {
|
|
1482
1523
|
Check_Type(in_paramtypes, T_ARRAY);
|
|
1483
|
-
nParams = (
|
|
1524
|
+
nParams = RARRAY_LENINT(in_paramtypes);
|
|
1484
1525
|
paramTypes = ALLOC_N(Oid, nParams);
|
|
1485
1526
|
for(i = 0; i < nParams; i++) {
|
|
1486
1527
|
param = rb_ary_entry(in_paramtypes, i);
|
|
@@ -1490,8 +1531,10 @@ pgconn_sync_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
1490
1531
|
paramTypes[i] = NUM2UINT(param);
|
|
1491
1532
|
}
|
|
1492
1533
|
}
|
|
1493
|
-
result =
|
|
1534
|
+
result = PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
|
1494
1535
|
|
|
1536
|
+
RB_GC_GUARD(transcoded_str1);
|
|
1537
|
+
RB_GC_GUARD(transcoded_str2);
|
|
1495
1538
|
xfree(paramTypes);
|
|
1496
1539
|
|
|
1497
1540
|
rb_pgresult = pg_new_result(result, self);
|
|
@@ -1515,6 +1558,7 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
1515
1558
|
PGresult *result = NULL;
|
|
1516
1559
|
VALUE rb_pgresult;
|
|
1517
1560
|
VALUE name, in_res_fmt;
|
|
1561
|
+
VALUE transcoded_str;
|
|
1518
1562
|
int nParams;
|
|
1519
1563
|
int resultFormat;
|
|
1520
1564
|
struct query_params_data paramsData = { this->enc_idx };
|
|
@@ -1530,10 +1574,11 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
1530
1574
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
|
1531
1575
|
nParams = alloc_query_params( ¶msData );
|
|
1532
1576
|
|
|
1533
|
-
result =
|
|
1577
|
+
result = PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx, &transcoded_str), nParams,
|
|
1534
1578
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
|
1535
1579
|
resultFormat);
|
|
1536
1580
|
|
|
1581
|
+
RB_GC_GUARD(transcoded_str);
|
|
1537
1582
|
free_query_params( ¶msData );
|
|
1538
1583
|
|
|
1539
1584
|
rb_pgresult = pg_new_result(result, self);
|
|
@@ -1550,9 +1595,13 @@ pgconn_sync_describe_close_prepared_portal(VALUE self, VALUE name, PGresult *(*f
|
|
|
1550
1595
|
{
|
|
1551
1596
|
PGresult *result;
|
|
1552
1597
|
VALUE rb_pgresult;
|
|
1598
|
+
VALUE transcoded_str;
|
|
1553
1599
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
1554
|
-
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
|
|
1600
|
+
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx, &transcoded_str);
|
|
1601
|
+
|
|
1555
1602
|
result = func(this->pgconn, stmt);
|
|
1603
|
+
|
|
1604
|
+
RB_GC_GUARD(transcoded_str);
|
|
1556
1605
|
rb_pgresult = pg_new_result(result, self);
|
|
1557
1606
|
pg_result_check(rb_pgresult);
|
|
1558
1607
|
return rb_pgresult;
|
|
@@ -1569,7 +1618,7 @@ pgconn_sync_describe_close_prepared_portal(VALUE self, VALUE name, PGresult *(*f
|
|
|
1569
1618
|
static VALUE
|
|
1570
1619
|
pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1571
1620
|
{
|
|
1572
|
-
return pgconn_sync_describe_close_prepared_portal(self, stmt_name,
|
|
1621
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, PQdescribePrepared);
|
|
1573
1622
|
}
|
|
1574
1623
|
|
|
1575
1624
|
|
|
@@ -1584,11 +1633,11 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
|
|
|
1584
1633
|
static VALUE
|
|
1585
1634
|
pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
|
|
1586
1635
|
{
|
|
1587
|
-
return pgconn_sync_describe_close_prepared_portal(self, stmt_name,
|
|
1636
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, PQdescribePortal);
|
|
1588
1637
|
}
|
|
1589
1638
|
|
|
1590
1639
|
|
|
1591
|
-
#ifdef
|
|
1640
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
1592
1641
|
/*
|
|
1593
1642
|
* call-seq:
|
|
1594
1643
|
* conn.sync_close_prepared( stmt_name ) -> PG::Result
|
|
@@ -1602,7 +1651,7 @@ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
|
|
|
1602
1651
|
static VALUE
|
|
1603
1652
|
pgconn_sync_close_prepared(VALUE self, VALUE stmt_name)
|
|
1604
1653
|
{
|
|
1605
|
-
return pgconn_sync_describe_close_prepared_portal(self, stmt_name,
|
|
1654
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, PQclosePrepared);
|
|
1606
1655
|
}
|
|
1607
1656
|
|
|
1608
1657
|
/*
|
|
@@ -1618,7 +1667,7 @@ pgconn_sync_close_prepared(VALUE self, VALUE stmt_name)
|
|
|
1618
1667
|
static VALUE
|
|
1619
1668
|
pgconn_sync_close_portal(VALUE self, VALUE stmt_name)
|
|
1620
1669
|
{
|
|
1621
|
-
return pgconn_sync_describe_close_prepared_portal(self, stmt_name,
|
|
1670
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, PQclosePortal);
|
|
1622
1671
|
}
|
|
1623
1672
|
#endif
|
|
1624
1673
|
|
|
@@ -1892,7 +1941,7 @@ pgconn_set_single_row_mode(VALUE self)
|
|
|
1892
1941
|
return self;
|
|
1893
1942
|
}
|
|
1894
1943
|
|
|
1895
|
-
#ifdef
|
|
1944
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
1896
1945
|
/*
|
|
1897
1946
|
* call-seq:
|
|
1898
1947
|
* conn.set_chunked_rows_mode -> self
|
|
@@ -1949,13 +1998,15 @@ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
|
|
1949
1998
|
static VALUE
|
|
1950
1999
|
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1951
2000
|
{
|
|
2001
|
+
VALUE transcoded_str;
|
|
1952
2002
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
1953
2003
|
|
|
1954
2004
|
/* If called with no or nil parameters, use PQexec for compatibility */
|
|
1955
2005
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
|
1956
|
-
if(
|
|
2006
|
+
if(PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx, &transcoded_str)) == 0)
|
|
1957
2007
|
pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQuery %s", PQerrorMessage(this->pgconn));
|
|
1958
2008
|
|
|
2009
|
+
RB_GC_GUARD(transcoded_str);
|
|
1959
2010
|
pgconn_wait_for_flush( self );
|
|
1960
2011
|
return Qnil;
|
|
1961
2012
|
}
|
|
@@ -2012,6 +2063,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
|
2012
2063
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
2013
2064
|
int result;
|
|
2014
2065
|
VALUE command, in_res_fmt;
|
|
2066
|
+
VALUE transcoded_str;
|
|
2015
2067
|
int nParams;
|
|
2016
2068
|
int resultFormat;
|
|
2017
2069
|
struct query_params_data paramsData = { this->enc_idx };
|
|
@@ -2023,9 +2075,10 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
|
2023
2075
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
|
2024
2076
|
nParams = alloc_query_params( ¶msData );
|
|
2025
2077
|
|
|
2026
|
-
result =
|
|
2078
|
+
result = PQsendQueryParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx, &transcoded_str), nParams, paramsData.types,
|
|
2027
2079
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
|
2028
2080
|
|
|
2081
|
+
RB_GC_GUARD(transcoded_str);
|
|
2029
2082
|
free_query_params( ¶msData );
|
|
2030
2083
|
|
|
2031
2084
|
if(result == 0)
|
|
@@ -2062,6 +2115,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
2062
2115
|
int result;
|
|
2063
2116
|
VALUE name, command, in_paramtypes;
|
|
2064
2117
|
VALUE param;
|
|
2118
|
+
VALUE transcoded_str1, transcoded_str2;
|
|
2065
2119
|
int i = 0;
|
|
2066
2120
|
int nParams = 0;
|
|
2067
2121
|
Oid *paramTypes = NULL;
|
|
@@ -2070,12 +2124,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
2070
2124
|
int enc_idx = this->enc_idx;
|
|
2071
2125
|
|
|
2072
2126
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
|
2073
|
-
name_cstr = pg_cstr_enc(name, enc_idx);
|
|
2074
|
-
command_cstr = pg_cstr_enc(command, enc_idx);
|
|
2127
|
+
name_cstr = pg_cstr_enc(name, enc_idx, &transcoded_str1);
|
|
2128
|
+
command_cstr = pg_cstr_enc(command, enc_idx, &transcoded_str2);
|
|
2075
2129
|
|
|
2076
2130
|
if(! NIL_P(in_paramtypes)) {
|
|
2077
2131
|
Check_Type(in_paramtypes, T_ARRAY);
|
|
2078
|
-
nParams = (
|
|
2132
|
+
nParams = RARRAY_LENINT(in_paramtypes);
|
|
2079
2133
|
paramTypes = ALLOC_N(Oid, nParams);
|
|
2080
2134
|
for(i = 0; i < nParams; i++) {
|
|
2081
2135
|
param = rb_ary_entry(in_paramtypes, i);
|
|
@@ -2085,8 +2139,10 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
2085
2139
|
paramTypes[i] = NUM2UINT(param);
|
|
2086
2140
|
}
|
|
2087
2141
|
}
|
|
2088
|
-
result =
|
|
2142
|
+
result = PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
|
2089
2143
|
|
|
2144
|
+
RB_GC_GUARD(transcoded_str1);
|
|
2145
|
+
RB_GC_GUARD(transcoded_str2);
|
|
2090
2146
|
xfree(paramTypes);
|
|
2091
2147
|
|
|
2092
2148
|
if(result == 0) {
|
|
@@ -2134,6 +2190,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
2134
2190
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
2135
2191
|
int result;
|
|
2136
2192
|
VALUE name, in_res_fmt;
|
|
2193
|
+
VALUE transcoded_str;
|
|
2137
2194
|
int nParams;
|
|
2138
2195
|
int resultFormat;
|
|
2139
2196
|
struct query_params_data paramsData = { this->enc_idx };
|
|
@@ -2149,10 +2206,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
2149
2206
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
|
2150
2207
|
nParams = alloc_query_params( ¶msData );
|
|
2151
2208
|
|
|
2152
|
-
result =
|
|
2209
|
+
result = PQsendQueryPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx, &transcoded_str), nParams,
|
|
2153
2210
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
|
2154
2211
|
resultFormat);
|
|
2155
2212
|
|
|
2213
|
+
RB_GC_GUARD(transcoded_str);
|
|
2156
2214
|
free_query_params( ¶msData );
|
|
2157
2215
|
|
|
2158
2216
|
if(result == 0)
|
|
@@ -2166,12 +2224,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
2166
2224
|
static VALUE
|
|
2167
2225
|
pgconn_send_describe_close_prepared_portal(VALUE self, VALUE name, int (*func)(PGconn *, const char *), const char *funame)
|
|
2168
2226
|
{
|
|
2227
|
+
VALUE transcoded_str;
|
|
2169
2228
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
2170
|
-
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
|
|
2229
|
+
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx, &transcoded_str);
|
|
2171
2230
|
/* returns 0 on failure */
|
|
2172
2231
|
if(func(this->pgconn, stmt) == 0)
|
|
2173
2232
|
pg_raise_conn_error( rb_eUnableToSend, self, "%s %s", funame, PQerrorMessage(this->pgconn));
|
|
2174
2233
|
|
|
2234
|
+
RB_GC_GUARD(transcoded_str);
|
|
2175
2235
|
pgconn_wait_for_flush( self );
|
|
2176
2236
|
return Qnil;
|
|
2177
2237
|
}
|
|
@@ -2187,7 +2247,7 @@ static VALUE
|
|
|
2187
2247
|
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
2188
2248
|
{
|
|
2189
2249
|
return pgconn_send_describe_close_prepared_portal(
|
|
2190
|
-
self, stmt_name,
|
|
2250
|
+
self, stmt_name, PQsendDescribePrepared,
|
|
2191
2251
|
"PQsendDescribePrepared");
|
|
2192
2252
|
}
|
|
2193
2253
|
|
|
@@ -2203,11 +2263,11 @@ static VALUE
|
|
|
2203
2263
|
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
2204
2264
|
{
|
|
2205
2265
|
return pgconn_send_describe_close_prepared_portal(
|
|
2206
|
-
self, portal,
|
|
2266
|
+
self, portal, PQsendDescribePortal,
|
|
2207
2267
|
"PQsendDescribePortal");
|
|
2208
2268
|
}
|
|
2209
2269
|
|
|
2210
|
-
#ifdef
|
|
2270
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
2211
2271
|
/*
|
|
2212
2272
|
* call-seq:
|
|
2213
2273
|
* conn.send_close_prepared( statement_name ) -> nil
|
|
@@ -2221,7 +2281,7 @@ static VALUE
|
|
|
2221
2281
|
pgconn_send_close_prepared(VALUE self, VALUE stmt_name)
|
|
2222
2282
|
{
|
|
2223
2283
|
return pgconn_send_describe_close_prepared_portal(
|
|
2224
|
-
self, stmt_name,
|
|
2284
|
+
self, stmt_name, PQsendClosePrepared,
|
|
2225
2285
|
"PQsendClosePrepared");
|
|
2226
2286
|
}
|
|
2227
2287
|
|
|
@@ -2239,7 +2299,7 @@ static VALUE
|
|
|
2239
2299
|
pgconn_send_close_portal(VALUE self, VALUE portal)
|
|
2240
2300
|
{
|
|
2241
2301
|
return pgconn_send_describe_close_prepared_portal(
|
|
2242
|
-
self, portal,
|
|
2302
|
+
self, portal, PQsendClosePortal,
|
|
2243
2303
|
"PQsendClosePortal");
|
|
2244
2304
|
}
|
|
2245
2305
|
#endif
|
|
@@ -2251,7 +2311,7 @@ pgconn_sync_get_result(VALUE self)
|
|
|
2251
2311
|
PGresult *result;
|
|
2252
2312
|
VALUE rb_pgresult;
|
|
2253
2313
|
|
|
2254
|
-
result =
|
|
2314
|
+
result = PQgetResult(conn);
|
|
2255
2315
|
if(result == NULL)
|
|
2256
2316
|
return Qnil;
|
|
2257
2317
|
rb_pgresult = pg_new_result(result, self);
|
|
@@ -2293,7 +2353,7 @@ pgconn_consume_input(VALUE self)
|
|
|
2293
2353
|
static VALUE
|
|
2294
2354
|
pgconn_is_busy(VALUE self)
|
|
2295
2355
|
{
|
|
2296
|
-
return
|
|
2356
|
+
return PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
|
|
2297
2357
|
}
|
|
2298
2358
|
|
|
2299
2359
|
static VALUE
|
|
@@ -2333,7 +2393,7 @@ pgconn_sync_flush(VALUE self)
|
|
|
2333
2393
|
return (ret) ? Qfalse : Qtrue;
|
|
2334
2394
|
}
|
|
2335
2395
|
|
|
2336
|
-
#ifndef
|
|
2396
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
2337
2397
|
static VALUE
|
|
2338
2398
|
pgconn_sync_cancel(VALUE self)
|
|
2339
2399
|
{
|
|
@@ -2346,7 +2406,7 @@ pgconn_sync_cancel(VALUE self)
|
|
|
2346
2406
|
if(cancel == NULL)
|
|
2347
2407
|
pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
|
|
2348
2408
|
|
|
2349
|
-
ret =
|
|
2409
|
+
ret = PQcancel(cancel, errbuf, sizeof(errbuf));
|
|
2350
2410
|
if(ret == 1)
|
|
2351
2411
|
retval = Qnil;
|
|
2352
2412
|
else
|
|
@@ -2378,7 +2438,7 @@ pgconn_notifies(VALUE self)
|
|
|
2378
2438
|
sym_be_pid = ID2SYM(rb_intern("be_pid"));
|
|
2379
2439
|
sym_extra = ID2SYM(rb_intern("extra"));
|
|
2380
2440
|
|
|
2381
|
-
notification =
|
|
2441
|
+
notification = PQnotifies(this->pgconn);
|
|
2382
2442
|
if (notification == NULL) {
|
|
2383
2443
|
return Qnil;
|
|
2384
2444
|
}
|
|
@@ -2398,33 +2458,13 @@ pgconn_notifies(VALUE self)
|
|
|
2398
2458
|
return hash;
|
|
2399
2459
|
}
|
|
2400
2460
|
|
|
2401
|
-
#ifndef HAVE_RB_IO_DESCRIPTOR
|
|
2402
|
-
static int
|
|
2403
|
-
rb_io_descriptor(VALUE io)
|
|
2404
|
-
{
|
|
2405
|
-
rb_io_t *fptr;
|
|
2406
|
-
Check_Type(io, T_FILE);
|
|
2407
|
-
fptr = RFILE(io)->fptr;
|
|
2408
|
-
rb_io_check_closed(fptr);
|
|
2409
|
-
return fptr->fd;
|
|
2410
|
-
}
|
|
2411
|
-
#endif
|
|
2412
|
-
|
|
2413
2461
|
#if defined(_WIN32)
|
|
2414
2462
|
|
|
2415
2463
|
/* We use a specialized implementation of rb_io_wait() on Windows.
|
|
2416
2464
|
* This is because rb_io_wait() and rb_wait_for_single_fd() are very slow on Windows.
|
|
2417
2465
|
*/
|
|
2418
2466
|
|
|
2419
|
-
#if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
|
|
2420
2467
|
#include <ruby/fiber/scheduler.h>
|
|
2421
|
-
#endif
|
|
2422
|
-
|
|
2423
|
-
typedef enum {
|
|
2424
|
-
PG_RUBY_IO_READABLE = RB_WAITFD_IN,
|
|
2425
|
-
PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
|
|
2426
|
-
PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
|
|
2427
|
-
} pg_rb_io_event_t;
|
|
2428
2468
|
|
|
2429
2469
|
int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
|
2430
2470
|
|
|
@@ -2448,9 +2488,9 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
|
2448
2488
|
timeradd(&currtime, &ptimeout, &aborttime);
|
|
2449
2489
|
}
|
|
2450
2490
|
|
|
2451
|
-
if(rb_events &
|
|
2452
|
-
if(rb_events &
|
|
2453
|
-
if(rb_events &
|
|
2491
|
+
if(rb_events & RUBY_IO_READABLE) w32_events |= FD_READ | FD_ACCEPT | FD_CLOSE;
|
|
2492
|
+
if(rb_events & RUBY_IO_WRITABLE) w32_events |= FD_WRITE | FD_CONNECT;
|
|
2493
|
+
if(rb_events & RUBY_IO_PRIORITY) w32_events |= FD_OOB;
|
|
2454
2494
|
|
|
2455
2495
|
for(;;) {
|
|
2456
2496
|
if ( WSAEventSelect(_get_osfhandle(rb_io_descriptor(io)), hEvent, w32_events) == SOCKET_ERROR ) {
|
|
@@ -2494,49 +2534,20 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
|
2494
2534
|
|
|
2495
2535
|
static VALUE
|
|
2496
2536
|
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
2497
|
-
|
|
2498
|
-
/* We don't support Fiber.scheduler on Windows ruby-3.0 because there is no fast way to check whether a scheduler is active.
|
|
2499
|
-
* Fortunately ruby-3.1 offers a C-API for it.
|
|
2500
|
-
*/
|
|
2537
|
+
/* Avoid slow rb_io_wait() on Windows, if no scheduler is active. */
|
|
2501
2538
|
VALUE scheduler = rb_fiber_scheduler_current();
|
|
2502
2539
|
|
|
2503
2540
|
if (!NIL_P(scheduler)) {
|
|
2504
2541
|
return rb_io_wait(io, events, timeout);
|
|
2505
2542
|
}
|
|
2506
|
-
#endif
|
|
2507
2543
|
return pg_rb_thread_io_wait(io, events, timeout);
|
|
2508
2544
|
}
|
|
2509
2545
|
|
|
2510
|
-
#elif defined(HAVE_RB_IO_WAIT)
|
|
2511
|
-
|
|
2512
|
-
/* Use our own function and constants names, to avoid conflicts with truffleruby-head on its road to ruby-3.0 compatibility. */
|
|
2513
|
-
#define pg_rb_io_wait rb_io_wait
|
|
2514
|
-
#define PG_RUBY_IO_READABLE RUBY_IO_READABLE
|
|
2515
|
-
#define PG_RUBY_IO_WRITABLE RUBY_IO_WRITABLE
|
|
2516
|
-
#define PG_RUBY_IO_PRIORITY RUBY_IO_PRIORITY
|
|
2517
|
-
|
|
2518
2546
|
#else
|
|
2519
|
-
/* For compat with ruby < 3.0 */
|
|
2520
|
-
|
|
2521
|
-
typedef enum {
|
|
2522
|
-
PG_RUBY_IO_READABLE = RB_WAITFD_IN,
|
|
2523
|
-
PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
|
|
2524
|
-
PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
|
|
2525
|
-
} pg_rb_io_event_t;
|
|
2526
|
-
|
|
2527
|
-
static VALUE
|
|
2528
|
-
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
2529
|
-
struct timeval waittime;
|
|
2530
|
-
int res;
|
|
2531
2547
|
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
waittime.tv_usec = (time_t)((NUM2DBL(timeout) - (double)waittime.tv_sec) * 1e6);
|
|
2535
|
-
}
|
|
2536
|
-
res = rb_wait_for_single_fd(rb_io_descriptor(io), NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
|
|
2548
|
+
/* Use rb_io_wait on non-Windows systems */
|
|
2549
|
+
#define pg_rb_io_wait rb_io_wait
|
|
2537
2550
|
|
|
2538
|
-
return UINT2NUM(res);
|
|
2539
|
-
}
|
|
2540
2551
|
#endif
|
|
2541
2552
|
|
|
2542
2553
|
static void *
|
|
@@ -2571,7 +2582,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
|
|
|
2571
2582
|
|
|
2572
2583
|
socket_io = pgconn_socket_io(self);
|
|
2573
2584
|
/* Wait for the socket to become readable before checking again */
|
|
2574
|
-
ret = pg_rb_io_wait(socket_io, RB_INT2NUM(
|
|
2585
|
+
ret = pg_rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), wait_timeout);
|
|
2575
2586
|
} else {
|
|
2576
2587
|
ret = Qfalse;
|
|
2577
2588
|
}
|
|
@@ -2608,9 +2619,9 @@ pgconn_async_flush(VALUE self)
|
|
|
2608
2619
|
/* wait for the socket to become read- or write-ready */
|
|
2609
2620
|
int events;
|
|
2610
2621
|
VALUE socket_io = pgconn_socket_io(self);
|
|
2611
|
-
events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(
|
|
2622
|
+
events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE | RUBY_IO_WRITABLE), Qnil));
|
|
2612
2623
|
|
|
2613
|
-
if (events &
|
|
2624
|
+
if (events & RUBY_IO_READABLE){
|
|
2614
2625
|
pgconn_consume_input(self);
|
|
2615
2626
|
}
|
|
2616
2627
|
}
|
|
@@ -2636,7 +2647,7 @@ pgconn_flush_data_set( VALUE self, VALUE enabled ){
|
|
|
2636
2647
|
static void *
|
|
2637
2648
|
notify_readable(PGconn *conn)
|
|
2638
2649
|
{
|
|
2639
|
-
return (void*)
|
|
2650
|
+
return (void*)PQnotifies(conn);
|
|
2640
2651
|
}
|
|
2641
2652
|
|
|
2642
2653
|
/*
|
|
@@ -2735,7 +2746,7 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
|
2735
2746
|
|
|
2736
2747
|
Check_Type(buffer, T_STRING);
|
|
2737
2748
|
|
|
2738
|
-
ret =
|
|
2749
|
+
ret = PQputCopyData(this->pgconn, RSTRING_PTR(buffer), RSTRING_LENINT(buffer));
|
|
2739
2750
|
if(ret == -1)
|
|
2740
2751
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
|
|
2741
2752
|
|
|
@@ -2748,6 +2759,7 @@ static VALUE
|
|
|
2748
2759
|
pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2749
2760
|
{
|
|
2750
2761
|
VALUE str;
|
|
2762
|
+
VALUE transcoded_str;
|
|
2751
2763
|
int ret;
|
|
2752
2764
|
const char *error_message = NULL;
|
|
2753
2765
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
@@ -2755,15 +2767,41 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
|
2755
2767
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
|
2756
2768
|
error_message = NULL;
|
|
2757
2769
|
else
|
|
2758
|
-
error_message = pg_cstr_enc(str, this->enc_idx);
|
|
2770
|
+
error_message = pg_cstr_enc(str, this->enc_idx, &transcoded_str);
|
|
2759
2771
|
|
|
2760
|
-
ret =
|
|
2772
|
+
ret = PQputCopyEnd(this->pgconn, error_message);
|
|
2761
2773
|
if(ret == -1)
|
|
2762
2774
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
|
|
2763
2775
|
|
|
2776
|
+
RB_GC_GUARD(transcoded_str);
|
|
2764
2777
|
return (ret) ? Qtrue : Qfalse;
|
|
2765
2778
|
}
|
|
2766
2779
|
|
|
2780
|
+
struct pgconn_copy_data {
|
|
2781
|
+
t_pg_coder *coder;
|
|
2782
|
+
char *buffer;
|
|
2783
|
+
int length;
|
|
2784
|
+
int enc_idx;
|
|
2785
|
+
};
|
|
2786
|
+
|
|
2787
|
+
static VALUE
|
|
2788
|
+
pgconn_decode_copy_data(VALUE data_ptr)
|
|
2789
|
+
{
|
|
2790
|
+
struct pgconn_copy_data *data = (struct pgconn_copy_data *)data_ptr;
|
|
2791
|
+
t_pg_coder_dec_func dec_func = pg_coder_dec_func(data->coder, data->coder->format);
|
|
2792
|
+
|
|
2793
|
+
return dec_func(data->coder, data->buffer, data->length, 0, 0, data->enc_idx);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
static VALUE
|
|
2797
|
+
pgconn_free_copy_data(VALUE data_ptr)
|
|
2798
|
+
{
|
|
2799
|
+
struct pgconn_copy_data *data = (struct pgconn_copy_data *)data_ptr;
|
|
2800
|
+
|
|
2801
|
+
PQfreemem(data->buffer);
|
|
2802
|
+
return Qnil;
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2767
2805
|
static VALUE
|
|
2768
2806
|
pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2769
2807
|
{
|
|
@@ -2786,7 +2824,7 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
|
2786
2824
|
TypedData_Get_Struct(decoder, t_pg_coder, &pg_coder_type, p_coder);
|
|
2787
2825
|
}
|
|
2788
2826
|
|
|
2789
|
-
ret =
|
|
2827
|
+
ret = PQgetCopyData(this->pgconn, &buffer, RTEST(async_in));
|
|
2790
2828
|
if(ret == -2){ /* error */
|
|
2791
2829
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
|
|
2792
2830
|
}
|
|
@@ -2798,8 +2836,9 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
|
2798
2836
|
}
|
|
2799
2837
|
|
|
2800
2838
|
if( p_coder ){
|
|
2801
|
-
|
|
2802
|
-
|
|
2839
|
+
struct pgconn_copy_data data = { p_coder, buffer, ret, this->enc_idx };
|
|
2840
|
+
|
|
2841
|
+
return rb_ensure(pgconn_decode_copy_data, (VALUE)&data, pgconn_free_copy_data, (VALUE)&data);
|
|
2803
2842
|
} else {
|
|
2804
2843
|
result = rb_str_new(buffer, ret);
|
|
2805
2844
|
}
|
|
@@ -2932,11 +2971,10 @@ pgconn_untrace(VALUE self)
|
|
|
2932
2971
|
void
|
|
2933
2972
|
notice_receiver_proxy(void *arg, const PGresult *pgresult)
|
|
2934
2973
|
{
|
|
2935
|
-
|
|
2936
|
-
t_pg_connection *this = pg_get_connection( self );
|
|
2974
|
+
t_pg_connection *this = (t_pg_connection*)arg;
|
|
2937
2975
|
|
|
2938
2976
|
if (this->notice_receiver != Qnil) {
|
|
2939
|
-
VALUE result = pg_new_result_autoclear( (PGresult *)pgresult, self );
|
|
2977
|
+
VALUE result = pg_new_result_autoclear( (PGresult *)pgresult, this->self );
|
|
2940
2978
|
|
|
2941
2979
|
rb_funcall(this->notice_receiver, rb_intern("call"), 1, result);
|
|
2942
2980
|
pg_result_clear( result );
|
|
@@ -2991,7 +3029,7 @@ pgconn_set_notice_receiver(VALUE self)
|
|
|
2991
3029
|
old_proc = this->notice_receiver;
|
|
2992
3030
|
if( rb_block_given_p() ) {
|
|
2993
3031
|
proc = rb_block_proc();
|
|
2994
|
-
PQsetNoticeReceiver(this->pgconn, gvl_notice_receiver_proxy, (void *)
|
|
3032
|
+
PQsetNoticeReceiver(this->pgconn, gvl_notice_receiver_proxy, (void *)this);
|
|
2995
3033
|
} else {
|
|
2996
3034
|
/* if no block is given, set back to default */
|
|
2997
3035
|
proc = Qnil;
|
|
@@ -3010,8 +3048,7 @@ pgconn_set_notice_receiver(VALUE self)
|
|
|
3010
3048
|
void
|
|
3011
3049
|
notice_processor_proxy(void *arg, const char *message)
|
|
3012
3050
|
{
|
|
3013
|
-
|
|
3014
|
-
t_pg_connection *this = pg_get_connection( self );
|
|
3051
|
+
t_pg_connection *this = (t_pg_connection*)arg;
|
|
3015
3052
|
|
|
3016
3053
|
if (this->notice_processor != Qnil) {
|
|
3017
3054
|
VALUE message_str = rb_str_new2(message);
|
|
@@ -3052,7 +3089,7 @@ pgconn_set_notice_processor(VALUE self)
|
|
|
3052
3089
|
old_proc = this->notice_processor;
|
|
3053
3090
|
if( rb_block_given_p() ) {
|
|
3054
3091
|
proc = rb_block_proc();
|
|
3055
|
-
PQsetNoticeProcessor(this->pgconn, gvl_notice_processor_proxy, (void *)
|
|
3092
|
+
PQsetNoticeProcessor(this->pgconn, gvl_notice_processor_proxy, (void *)this);
|
|
3056
3093
|
} else {
|
|
3057
3094
|
/* if no block is given, set back to default */
|
|
3058
3095
|
proc = Qnil;
|
|
@@ -3094,7 +3131,7 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
|
|
|
3094
3131
|
rb_check_frozen(self);
|
|
3095
3132
|
Check_Type(str, T_STRING);
|
|
3096
3133
|
|
|
3097
|
-
if ( (
|
|
3134
|
+
if ( (PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
|
|
3098
3135
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
3099
3136
|
|
|
3100
3137
|
pgconn_set_internal_encoding_index( self );
|
|
@@ -3159,7 +3196,7 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
|
|
3159
3196
|
static void *
|
|
3160
3197
|
get_result_readable(PGconn *conn)
|
|
3161
3198
|
{
|
|
3162
|
-
return
|
|
3199
|
+
return PQisBusy(conn) ? NULL : (void*)1;
|
|
3163
3200
|
}
|
|
3164
3201
|
|
|
3165
3202
|
|
|
@@ -3217,7 +3254,7 @@ pgconn_sync_get_last_result(VALUE self)
|
|
|
3217
3254
|
|
|
3218
3255
|
|
|
3219
3256
|
cur = prev = NULL;
|
|
3220
|
-
while ((cur =
|
|
3257
|
+
while ((cur = PQgetResult(conn)) != NULL) {
|
|
3221
3258
|
int status;
|
|
3222
3259
|
|
|
3223
3260
|
if (prev) PQclear(prev);
|
|
@@ -3269,7 +3306,7 @@ pgconn_async_get_last_result(VALUE self)
|
|
|
3269
3306
|
*/
|
|
3270
3307
|
wait_socket_readable(self, NULL, get_result_readable);
|
|
3271
3308
|
|
|
3272
|
-
cur =
|
|
3309
|
+
cur = PQgetResult(conn);
|
|
3273
3310
|
if (cur == NULL)
|
|
3274
3311
|
break;
|
|
3275
3312
|
|
|
@@ -3326,18 +3363,18 @@ pgconn_discard_results(VALUE self)
|
|
|
3326
3363
|
/* pgconn_block() raises an exception in case of errors.
|
|
3327
3364
|
* To avoid this call pg_rb_io_wait() and PQconsumeInput() without rb_raise().
|
|
3328
3365
|
*/
|
|
3329
|
-
while(
|
|
3366
|
+
while( PQisBusy(conn) ){
|
|
3330
3367
|
int events;
|
|
3331
3368
|
|
|
3332
3369
|
switch( PQflush(conn) ) {
|
|
3333
3370
|
case 1:
|
|
3334
|
-
events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(
|
|
3335
|
-
if (events &
|
|
3371
|
+
events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE | RUBY_IO_WRITABLE), Qnil));
|
|
3372
|
+
if (events & RUBY_IO_READABLE){
|
|
3336
3373
|
if ( PQconsumeInput(conn) == 0 ) goto error;
|
|
3337
3374
|
}
|
|
3338
3375
|
break;
|
|
3339
3376
|
case 0:
|
|
3340
|
-
pg_rb_io_wait(socket_io, RB_INT2NUM(
|
|
3377
|
+
pg_rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
|
|
3341
3378
|
if ( PQconsumeInput(conn) == 0 ) goto error;
|
|
3342
3379
|
break;
|
|
3343
3380
|
default:
|
|
@@ -3345,23 +3382,23 @@ pgconn_discard_results(VALUE self)
|
|
|
3345
3382
|
}
|
|
3346
3383
|
}
|
|
3347
3384
|
|
|
3348
|
-
cur =
|
|
3385
|
+
cur = PQgetResult(conn);
|
|
3349
3386
|
if( cur == NULL) break;
|
|
3350
3387
|
|
|
3351
3388
|
status = PQresultStatus(cur);
|
|
3352
3389
|
PQclear(cur);
|
|
3353
3390
|
if (status == PGRES_COPY_IN){
|
|
3354
|
-
while(
|
|
3391
|
+
while( PQputCopyEnd(conn, "COPY terminated by new query or discard_results") == 0 ){
|
|
3355
3392
|
pgconn_async_flush(self);
|
|
3356
3393
|
}
|
|
3357
3394
|
}
|
|
3358
3395
|
if (status == PGRES_COPY_OUT){
|
|
3359
3396
|
for(;;) {
|
|
3360
3397
|
char *buffer = NULL;
|
|
3361
|
-
int st =
|
|
3398
|
+
int st = PQgetCopyData(conn, &buffer, 1);
|
|
3362
3399
|
if( st == 0 ) {
|
|
3363
3400
|
/* would block -> wait for readable data */
|
|
3364
|
-
pg_rb_io_wait(socket_io, RB_INT2NUM(
|
|
3401
|
+
pg_rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
|
|
3365
3402
|
if ( PQconsumeInput(conn) == 0 ) goto error;
|
|
3366
3403
|
} else if( st > 0 ) {
|
|
3367
3404
|
/* some data retrieved -> discard it */
|
|
@@ -3398,12 +3435,12 @@ error:
|
|
|
3398
3435
|
* and the PG::Result object will automatically be cleared when the block terminates.
|
|
3399
3436
|
* In this instance, <code>conn.exec</code> returns the value of the block.
|
|
3400
3437
|
*
|
|
3401
|
-
* #exec is an alias for #async_exec which is
|
|
3438
|
+
* #exec is an alias for #async_exec which is functional identical to #sync_exec .
|
|
3402
3439
|
* #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
|
|
3403
3440
|
* #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
|
|
3404
3441
|
* Only #async_exec is compatible to <tt>Fiber.scheduler</tt> based asynchronous IO processing introduced in ruby-3.0.
|
|
3405
|
-
*
|
|
3406
|
-
*
|
|
3442
|
+
* Only #async_exec ensures that other threads can process while waiting for the server to complete the request.
|
|
3443
|
+
* In contrast #sync_exec blocks all threads and signals to be processed until the query is finished.
|
|
3407
3444
|
* This is most notably visible by a delayed reaction to Control+C.
|
|
3408
3445
|
* It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
|
|
3409
3446
|
*
|
|
@@ -3438,12 +3475,13 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
|
3438
3475
|
* +params+ is an array of the bind parameters for the SQL query.
|
|
3439
3476
|
* Each element of the +params+ array may be either:
|
|
3440
3477
|
* a hash of the form:
|
|
3441
|
-
* {:value
|
|
3442
|
-
* :type
|
|
3443
|
-
* :
|
|
3478
|
+
* {:value => String (value of bind parameter)
|
|
3479
|
+
* :type => Integer (oid of type of bind parameter)
|
|
3480
|
+
* :typename => String (name of type of bind parameter, only used for conn.embed_params )
|
|
3481
|
+
* :format => Integer (0 for text, 1 for binary)
|
|
3444
3482
|
* }
|
|
3445
3483
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
|
3446
|
-
* { :value
|
|
3484
|
+
* { :value => <string value>, :type => 0, :format => 0 }
|
|
3447
3485
|
*
|
|
3448
3486
|
* PostgreSQL bind parameters are represented as $1, $2, $3, etc.,
|
|
3449
3487
|
* inside the SQL query. The 0th element of the +params+ array is bound
|
|
@@ -3632,7 +3670,7 @@ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
|
|
3632
3670
|
return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_describe_prepared);
|
|
3633
3671
|
}
|
|
3634
3672
|
|
|
3635
|
-
#ifdef
|
|
3673
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
3636
3674
|
/*
|
|
3637
3675
|
* call-seq:
|
|
3638
3676
|
* conn.close_prepared( statement_name ) -> PG::Result
|
|
@@ -3754,7 +3792,7 @@ pgconn_ssl_attribute_names(VALUE self)
|
|
|
3754
3792
|
|
|
3755
3793
|
|
|
3756
3794
|
|
|
3757
|
-
#ifdef
|
|
3795
|
+
#ifdef LIBPQ_HAS_PIPELINING
|
|
3758
3796
|
/*
|
|
3759
3797
|
* call-seq:
|
|
3760
3798
|
* conn.pipeline_status -> Integer
|
|
@@ -3839,7 +3877,7 @@ static VALUE
|
|
|
3839
3877
|
pgconn_sync_pipeline_sync(VALUE self)
|
|
3840
3878
|
{
|
|
3841
3879
|
PGconn *conn = pg_get_pgconn(self);
|
|
3842
|
-
int res =
|
|
3880
|
+
int res = PQpipelineSync(conn);
|
|
3843
3881
|
if( res != 1 )
|
|
3844
3882
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
3845
3883
|
|
|
@@ -3847,7 +3885,7 @@ pgconn_sync_pipeline_sync(VALUE self)
|
|
|
3847
3885
|
}
|
|
3848
3886
|
|
|
3849
3887
|
|
|
3850
|
-
#ifdef
|
|
3888
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
3851
3889
|
/*
|
|
3852
3890
|
* call-seq:
|
|
3853
3891
|
* conn.send_pipeline_sync -> nil
|
|
@@ -3864,7 +3902,7 @@ static VALUE
|
|
|
3864
3902
|
pgconn_send_pipeline_sync(VALUE self)
|
|
3865
3903
|
{
|
|
3866
3904
|
PGconn *conn = pg_get_pgconn(self);
|
|
3867
|
-
int res =
|
|
3905
|
+
int res = PQsendPipelineSync(conn);
|
|
3868
3906
|
if( res != 1 )
|
|
3869
3907
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
3870
3908
|
|
|
@@ -4305,7 +4343,7 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
|
4305
4343
|
rb_encoding *rbenc = rb_to_encoding( enc );
|
|
4306
4344
|
const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc );
|
|
4307
4345
|
|
|
4308
|
-
if (
|
|
4346
|
+
if ( PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
|
|
4309
4347
|
VALUE server_encoding = pgconn_external_encoding( self );
|
|
4310
4348
|
rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s",
|
|
4311
4349
|
rb_enc_name(rb_to_encoding(server_encoding)), name );
|
|
@@ -4345,12 +4383,12 @@ pgconn_external_encoding(VALUE self)
|
|
|
4345
4383
|
static VALUE
|
|
4346
4384
|
pgconn_async_set_client_encoding(VALUE self, VALUE encname)
|
|
4347
4385
|
{
|
|
4348
|
-
VALUE
|
|
4386
|
+
VALUE query;
|
|
4349
4387
|
|
|
4350
4388
|
rb_check_frozen(self);
|
|
4351
4389
|
Check_Type(encname, T_STRING);
|
|
4352
|
-
|
|
4353
|
-
query
|
|
4390
|
+
query = rb_str_new_cstr("set client_encoding to ");
|
|
4391
|
+
rb_str_concat(query, pgconn_escape_literal(self, encname));
|
|
4354
4392
|
|
|
4355
4393
|
pgconn_async_exec(1, &query, self);
|
|
4356
4394
|
pgconn_set_internal_encoding_index( self );
|
|
@@ -4642,7 +4680,6 @@ pgconn_field_name_type_set(VALUE self, VALUE sym)
|
|
|
4642
4680
|
rb_check_frozen(self);
|
|
4643
4681
|
this->flags &= ~PG_RESULT_FIELD_NAMES_MASK;
|
|
4644
4682
|
if( sym == sym_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_SYMBOL;
|
|
4645
|
-
else if ( sym == sym_static_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_STATIC_SYMBOL;
|
|
4646
4683
|
else if ( sym == sym_string );
|
|
4647
4684
|
else rb_raise(rb_eArgError, "invalid argument %+"PRIsVALUE, sym);
|
|
4648
4685
|
|
|
@@ -4664,8 +4701,6 @@ pgconn_field_name_type_get(VALUE self)
|
|
|
4664
4701
|
|
|
4665
4702
|
if( this->flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
|
|
4666
4703
|
return sym_symbol;
|
|
4667
|
-
} else if( this->flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
|
|
4668
|
-
return sym_static_symbol;
|
|
4669
4704
|
} else {
|
|
4670
4705
|
return sym_string;
|
|
4671
4706
|
}
|
|
@@ -4685,7 +4720,6 @@ init_pg_connection(void)
|
|
|
4685
4720
|
sym_value = ID2SYM(rb_intern("value"));
|
|
4686
4721
|
sym_string = ID2SYM(rb_intern("string"));
|
|
4687
4722
|
sym_symbol = ID2SYM(rb_intern("symbol"));
|
|
4688
|
-
sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
|
|
4689
4723
|
|
|
4690
4724
|
rb_cPGconn = rb_define_class_under( rb_mPG, "Connection", rb_cObject );
|
|
4691
4725
|
/* Help rdoc to known the Constants module */
|
|
@@ -4733,12 +4767,15 @@ init_pg_connection(void)
|
|
|
4733
4767
|
rb_define_method(rb_cPGconn, "transaction_status", pgconn_transaction_status, 0);
|
|
4734
4768
|
rb_define_method(rb_cPGconn, "parameter_status", pgconn_parameter_status, 1);
|
|
4735
4769
|
rb_define_method(rb_cPGconn, "protocol_version", pgconn_protocol_version, 0);
|
|
4770
|
+
#ifdef LIBPQ_HAS_FULL_PROTOCOL_VERSION
|
|
4771
|
+
rb_define_method(rb_cPGconn, "full_protocol_version", pgconn_full_protocol_version, 0);
|
|
4772
|
+
#endif
|
|
4736
4773
|
rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
|
|
4737
4774
|
rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
|
|
4738
4775
|
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
|
|
4739
4776
|
rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
|
|
4740
4777
|
rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
|
|
4741
|
-
#ifndef
|
|
4778
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
4742
4779
|
rb_define_method(rb_cPGconn, "backend_key", pgconn_backend_key, 0);
|
|
4743
4780
|
#endif
|
|
4744
4781
|
rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
|
|
@@ -4752,7 +4789,7 @@ init_pg_connection(void)
|
|
|
4752
4789
|
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_sync_exec_prepared, -1);
|
|
4753
4790
|
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_sync_describe_prepared, 1);
|
|
4754
4791
|
rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_sync_describe_portal, 1);
|
|
4755
|
-
#ifdef
|
|
4792
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
4756
4793
|
rb_define_method(rb_cPGconn, "sync_close_prepared", pgconn_sync_close_prepared, 1);
|
|
4757
4794
|
rb_define_method(rb_cPGconn, "sync_close_portal", pgconn_sync_close_portal, 1);
|
|
4758
4795
|
#endif
|
|
@@ -4763,7 +4800,7 @@ init_pg_connection(void)
|
|
|
4763
4800
|
rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
|
|
4764
4801
|
rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
|
|
4765
4802
|
rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
|
|
4766
|
-
#ifdef
|
|
4803
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
4767
4804
|
rb_define_method(rb_cPGconn, "close_prepared", pgconn_async_close_prepared, 1);
|
|
4768
4805
|
rb_define_method(rb_cPGconn, "close_portal", pgconn_async_close_portal, 1);
|
|
4769
4806
|
#endif
|
|
@@ -4775,7 +4812,7 @@ init_pg_connection(void)
|
|
|
4775
4812
|
rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
|
|
4776
4813
|
rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
|
|
4777
4814
|
rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
|
|
4778
|
-
#ifdef
|
|
4815
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
4779
4816
|
rb_define_alias(rb_cPGconn, "async_close_prepared", "close_prepared");
|
|
4780
4817
|
rb_define_alias(rb_cPGconn, "async_close_portal", "close_portal");
|
|
4781
4818
|
#endif
|
|
@@ -4788,7 +4825,7 @@ init_pg_connection(void)
|
|
|
4788
4825
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
|
4789
4826
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
|
4790
4827
|
rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
|
|
4791
|
-
#ifdef
|
|
4828
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
4792
4829
|
rb_define_method(rb_cPGconn, "set_chunked_rows_mode", pgconn_set_chunked_rows_mode, 1);
|
|
4793
4830
|
#endif
|
|
4794
4831
|
|
|
@@ -4810,7 +4847,7 @@ init_pg_connection(void)
|
|
|
4810
4847
|
rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
|
|
4811
4848
|
|
|
4812
4849
|
/****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
|
|
4813
|
-
#ifndef
|
|
4850
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
4814
4851
|
rb_define_method(rb_cPGconn, "sync_cancel", pgconn_sync_cancel, 0);
|
|
4815
4852
|
#endif
|
|
4816
4853
|
|
|
@@ -4852,13 +4889,13 @@ init_pg_connection(void)
|
|
|
4852
4889
|
rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
|
|
4853
4890
|
rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
|
|
4854
4891
|
|
|
4855
|
-
#ifdef
|
|
4892
|
+
#ifdef LIBPQ_HAS_PIPELINING
|
|
4856
4893
|
rb_define_method(rb_cPGconn, "pipeline_status", pgconn_pipeline_status, 0);
|
|
4857
4894
|
rb_define_method(rb_cPGconn, "enter_pipeline_mode", pgconn_enter_pipeline_mode, 0);
|
|
4858
4895
|
rb_define_method(rb_cPGconn, "exit_pipeline_mode", pgconn_exit_pipeline_mode, 0);
|
|
4859
4896
|
rb_define_method(rb_cPGconn, "sync_pipeline_sync", pgconn_sync_pipeline_sync, 0);
|
|
4860
4897
|
rb_define_method(rb_cPGconn, "send_flush_request", pgconn_send_flush_request, 0);
|
|
4861
|
-
#ifdef
|
|
4898
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
4862
4899
|
rb_define_method(rb_cPGconn, "send_pipeline_sync", pgconn_send_pipeline_sync, 0);
|
|
4863
4900
|
#endif
|
|
4864
4901
|
#endif
|