pg 1.5.9 → 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/{History.md → CHANGELOG.md} +80 -0
- data/Gemfile +10 -7
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +4 -4
- data/README.md +66 -23
- data/Rakefile +78 -14
- data/ext/errorcodes.def +9 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +8 -1
- data/ext/extconf.rb +189 -15
- data/ext/gvl_wrappers.c +13 -2
- data/ext/gvl_wrappers.h +33 -0
- data/ext/pg.c +16 -5
- data/ext/pg.h +15 -13
- data/ext/pg_binary_decoder.c +151 -1
- data/ext/pg_binary_encoder.c +212 -9
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +54 -5
- data/ext/pg_connection.c +390 -160
- data/ext/pg_copy_coder.c +2 -2
- data/ext/pg_record_coder.c +1 -1
- data/ext/pg_result.c +104 -52
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +22 -9
- data/ext/pg_tuple.c +8 -8
- data/ext/pg_type_map.c +4 -2
- data/ext/pg_type_map_all_strings.c +1 -1
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +2 -1
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +3 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/pg_util.c +2 -2
- data/ext/pg_util.h +2 -2
- data/lib/pg/basic_type_map_for_queries.rb +7 -3
- data/lib/pg/basic_type_registry.rb +2 -2
- data/lib/pg/cancel_connection.rb +53 -0
- data/lib/pg/coder.rb +4 -2
- data/lib/pg/connection.rb +254 -131
- data/lib/pg/version.rb +2 -1
- data/lib/pg.rb +156 -130
- data/misc/glibc/Dockerfile +20 -0
- data/misc/glibc/docker-compose.yml +9 -0
- data/misc/glibc/glibc_spec.rb +5 -0
- data/misc/yugabyte/Dockerfile +9 -0
- data/misc/yugabyte/docker-compose.yml +28 -0
- data/misc/yugabyte/pg-test.rb +45 -0
- data/pg.gemspec +5 -3
- data/ports/patches/krb5/1.22.1/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/krb5/1.22.1/0002-unknown-command-line-option-on-clang.patch +12 -0
- data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +21 -0
- data/ports/patches/postgresql/18.1/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data.tar.gz.sig +0 -0
- metadata +37 -22
- metadata.gz.sig +0 -0
- data/Manifest.txt +0 -72
- data/Rakefile.cross +0 -303
data/ext/pg_connection.c
CHANGED
|
@@ -30,11 +30,8 @@ static VALUE pgconn_async_flush(VALUE self);
|
|
|
30
30
|
/*
|
|
31
31
|
* Convenience function to raise connection errors
|
|
32
32
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
#endif
|
|
36
|
-
NORETURN( static void
|
|
37
|
-
pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...))
|
|
33
|
+
void
|
|
34
|
+
pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...)
|
|
38
35
|
{
|
|
39
36
|
VALUE msg, error;
|
|
40
37
|
va_list ap;
|
|
@@ -69,6 +66,7 @@ pg_get_connection_safe( VALUE self )
|
|
|
69
66
|
t_pg_connection *this;
|
|
70
67
|
TypedData_Get_Struct( self, t_pg_connection, &pg_connection_type, this);
|
|
71
68
|
|
|
69
|
+
rb_check_frozen(self);
|
|
72
70
|
if ( !this->pgconn )
|
|
73
71
|
pg_raise_conn_error( rb_eConnectionBad, self, "connection is closed");
|
|
74
72
|
|
|
@@ -96,6 +94,20 @@ pg_get_pgconn( VALUE self )
|
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
|
|
97
|
+
void
|
|
98
|
+
pg_unwrap_socket_io( VALUE self, VALUE *p_socket_io, int ruby_sd )
|
|
99
|
+
{
|
|
100
|
+
if ( RTEST(*p_socket_io) ) {
|
|
101
|
+
#if defined(_WIN32)
|
|
102
|
+
if( rb_w32_unwrap_io_handle(ruby_sd) )
|
|
103
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
|
|
104
|
+
#endif
|
|
105
|
+
rb_funcall( *p_socket_io, rb_intern("close"), 0 );
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
RB_OBJ_WRITE(self, p_socket_io, Qnil);
|
|
109
|
+
}
|
|
110
|
+
|
|
99
111
|
|
|
100
112
|
/*
|
|
101
113
|
* Close the associated socket IO object if there is one.
|
|
@@ -104,17 +116,7 @@ static void
|
|
|
104
116
|
pgconn_close_socket_io( VALUE self )
|
|
105
117
|
{
|
|
106
118
|
t_pg_connection *this = pg_get_connection( self );
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if ( RTEST(socket_io) ) {
|
|
110
|
-
#if defined(_WIN32)
|
|
111
|
-
if( rb_w32_unwrap_io_handle(this->ruby_sd) )
|
|
112
|
-
pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
|
|
113
|
-
#endif
|
|
114
|
-
rb_funcall( socket_io, rb_intern("close"), 0 );
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
RB_OBJ_WRITE(self, &this->socket_io, Qnil);
|
|
119
|
+
pg_unwrap_socket_io( self, &this->socket_io, this->ruby_sd);
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
|
|
@@ -230,7 +232,7 @@ static const rb_data_type_t pg_connection_type = {
|
|
|
230
232
|
pgconn_gc_mark,
|
|
231
233
|
pgconn_gc_free,
|
|
232
234
|
pgconn_memsize,
|
|
233
|
-
|
|
235
|
+
pgconn_gc_compact,
|
|
234
236
|
},
|
|
235
237
|
0,
|
|
236
238
|
0,
|
|
@@ -419,7 +421,6 @@ pgconn_s_conninfo_parse(VALUE self, VALUE conninfo)
|
|
|
419
421
|
}
|
|
420
422
|
|
|
421
423
|
|
|
422
|
-
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
|
423
424
|
static VALUE
|
|
424
425
|
pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
425
426
|
{
|
|
@@ -443,7 +444,6 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
|
443
444
|
|
|
444
445
|
return rval;
|
|
445
446
|
}
|
|
446
|
-
#endif
|
|
447
447
|
|
|
448
448
|
|
|
449
449
|
/*
|
|
@@ -609,7 +609,7 @@ pgconn_reset_start(VALUE self)
|
|
|
609
609
|
* conn.reset_poll -> Integer
|
|
610
610
|
*
|
|
611
611
|
* Checks the status of a connection reset operation.
|
|
612
|
-
* See
|
|
612
|
+
* See Connection.connect_start and #connect_poll for
|
|
613
613
|
* usage information and return values.
|
|
614
614
|
*/
|
|
615
615
|
static VALUE
|
|
@@ -760,7 +760,6 @@ pgconn_options(VALUE self)
|
|
|
760
760
|
*
|
|
761
761
|
* Returns the connection options used by a live connection.
|
|
762
762
|
*
|
|
763
|
-
* Available since PostgreSQL-9.3
|
|
764
763
|
*/
|
|
765
764
|
static VALUE
|
|
766
765
|
pgconn_conninfo( VALUE self )
|
|
@@ -847,31 +846,52 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
|
|
|
847
846
|
* call-seq:
|
|
848
847
|
* conn.protocol_version -> Integer
|
|
849
848
|
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
852
|
-
*
|
|
849
|
+
* Interrogates the frontend/backend protocol being used.
|
|
850
|
+
*
|
|
851
|
+
* Applications might wish to use this function to determine whether certain features are supported.
|
|
852
|
+
* Currently, the only value is 3 (3.0 protocol).
|
|
853
|
+
* The protocol version will not change after connection startup is complete, but it could theoretically change during a connection reset.
|
|
854
|
+
* The 3.0 protocol is supported by PostgreSQL server versions 7.4 and above.
|
|
855
|
+
*
|
|
856
|
+
* PG::ConnectionBad is raised if the connection is bad.
|
|
853
857
|
*/
|
|
854
858
|
static VALUE
|
|
855
859
|
pgconn_protocol_version(VALUE self)
|
|
856
860
|
{
|
|
857
|
-
|
|
861
|
+
int protocol_version = PQprotocolVersion(pg_get_pgconn(self));
|
|
862
|
+
if (protocol_version == 0) {
|
|
863
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "PQprotocolVersion() can't get protocol version");
|
|
864
|
+
}
|
|
865
|
+
return INT2NUM(protocol_version);
|
|
858
866
|
}
|
|
859
867
|
|
|
860
868
|
/*
|
|
861
869
|
* call-seq:
|
|
862
870
|
* conn.server_version -> Integer
|
|
863
871
|
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
*
|
|
872
|
+
* Returns an integer representing the server version.
|
|
873
|
+
*
|
|
874
|
+
* Applications might use this function to determine the version of the database server they are connected to.
|
|
875
|
+
* The result is formed by multiplying the server's major version number by 10000 and adding the minor version number.
|
|
876
|
+
* For example, version 10.1 will be returned as 100001, and version 11.0 will be returned as 110000.
|
|
877
|
+
*
|
|
878
|
+
* PG::ConnectionBad is raised if the connection is bad.
|
|
879
|
+
*
|
|
880
|
+
* Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version.
|
|
881
|
+
* For those versions, PQserverVersion uses two digits for each part; for example version 9.1.5 will be returned as 90105, and version 9.2.0 will be returned as 90200.
|
|
882
|
+
*
|
|
883
|
+
* Therefore, for purposes of determining feature compatibility, applications should divide the result of PQserverVersion by 100 not 10000 to determine a logical major version number.
|
|
884
|
+
* In all release series, only the last two digits differ between minor releases (bug-fix releases).
|
|
869
885
|
*
|
|
870
886
|
*/
|
|
871
887
|
static VALUE
|
|
872
888
|
pgconn_server_version(VALUE self)
|
|
873
889
|
{
|
|
874
|
-
|
|
890
|
+
int server_version = PQserverVersion(pg_get_pgconn(self));
|
|
891
|
+
if (server_version == 0) {
|
|
892
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "PQserverVersion() can't get server version");
|
|
893
|
+
}
|
|
894
|
+
return INT2NUM(server_version);
|
|
875
895
|
}
|
|
876
896
|
|
|
877
897
|
/*
|
|
@@ -920,13 +940,42 @@ pgconn_socket(VALUE self)
|
|
|
920
940
|
return INT2NUM(sd);
|
|
921
941
|
}
|
|
922
942
|
|
|
943
|
+
|
|
944
|
+
VALUE
|
|
945
|
+
pg_wrap_socket_io(int sd, VALUE self, VALUE *p_socket_io, int *p_ruby_sd)
|
|
946
|
+
{
|
|
947
|
+
int ruby_sd;
|
|
948
|
+
VALUE cSocket;
|
|
949
|
+
VALUE socket_io = *p_socket_io;
|
|
950
|
+
|
|
951
|
+
#ifdef _WIN32
|
|
952
|
+
ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
|
|
953
|
+
if( ruby_sd == -1 )
|
|
954
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
|
|
955
|
+
|
|
956
|
+
*p_ruby_sd = ruby_sd;
|
|
957
|
+
#else
|
|
958
|
+
*p_ruby_sd = ruby_sd = sd;
|
|
959
|
+
#endif
|
|
960
|
+
|
|
961
|
+
cSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
|
|
962
|
+
socket_io = rb_funcall( cSocket, rb_intern("for_fd"), 1, INT2NUM(ruby_sd));
|
|
963
|
+
|
|
964
|
+
/* Disable autoclose feature */
|
|
965
|
+
rb_funcall( socket_io, s_id_autoclose_set, 1, Qfalse );
|
|
966
|
+
|
|
967
|
+
RB_OBJ_WRITE(self, p_socket_io, socket_io);
|
|
968
|
+
|
|
969
|
+
return socket_io;
|
|
970
|
+
}
|
|
971
|
+
|
|
923
972
|
/*
|
|
924
973
|
* call-seq:
|
|
925
974
|
* conn.socket_io() -> IO
|
|
926
975
|
*
|
|
927
976
|
* Fetch an IO object created from the Connection's underlying socket.
|
|
928
977
|
* This object can be used per <tt>socket_io.wait_readable</tt>, <tt>socket_io.wait_writable</tt> or for <tt>IO.select</tt> to wait for events while running asynchronous API calls.
|
|
929
|
-
* <tt>IO#wait_*able</tt> is
|
|
978
|
+
* <tt>IO#wait_*able</tt> is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
|
|
930
979
|
*
|
|
931
980
|
* The IO object can change while the connection is established, but is memorized afterwards.
|
|
932
981
|
* So be sure not to cache the IO object, but repeat calling <tt>conn.socket_io</tt> instead.
|
|
@@ -937,37 +986,17 @@ pgconn_socket(VALUE self)
|
|
|
937
986
|
static VALUE
|
|
938
987
|
pgconn_socket_io(VALUE self)
|
|
939
988
|
{
|
|
940
|
-
int sd;
|
|
941
|
-
int ruby_sd;
|
|
942
989
|
t_pg_connection *this = pg_get_connection_safe( self );
|
|
943
|
-
VALUE cSocket;
|
|
944
|
-
VALUE socket_io = this->socket_io;
|
|
945
990
|
|
|
946
|
-
if ( !RTEST(socket_io) ) {
|
|
991
|
+
if ( !RTEST(this->socket_io) ) {
|
|
992
|
+
int sd;
|
|
947
993
|
if( (sd = PQsocket(this->pgconn)) < 0){
|
|
948
994
|
pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
|
|
949
995
|
}
|
|
950
|
-
|
|
951
|
-
#ifdef _WIN32
|
|
952
|
-
ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
|
|
953
|
-
if( ruby_sd == -1 )
|
|
954
|
-
pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
|
|
955
|
-
|
|
956
|
-
this->ruby_sd = ruby_sd;
|
|
957
|
-
#else
|
|
958
|
-
ruby_sd = sd;
|
|
959
|
-
#endif
|
|
960
|
-
|
|
961
|
-
cSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
|
|
962
|
-
socket_io = rb_funcall( cSocket, rb_intern("for_fd"), 1, INT2NUM(ruby_sd));
|
|
963
|
-
|
|
964
|
-
/* Disable autoclose feature */
|
|
965
|
-
rb_funcall( socket_io, s_id_autoclose_set, 1, Qfalse );
|
|
966
|
-
|
|
967
|
-
RB_OBJ_WRITE(self, &this->socket_io, socket_io);
|
|
996
|
+
return pg_wrap_socket_io( sd, self, &this->socket_io, &this->ruby_sd);
|
|
968
997
|
}
|
|
969
998
|
|
|
970
|
-
return socket_io;
|
|
999
|
+
return this->socket_io;
|
|
971
1000
|
}
|
|
972
1001
|
|
|
973
1002
|
/*
|
|
@@ -984,6 +1013,7 @@ pgconn_backend_pid(VALUE self)
|
|
|
984
1013
|
return INT2NUM(PQbackendPID(pg_get_pgconn(self)));
|
|
985
1014
|
}
|
|
986
1015
|
|
|
1016
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
|
987
1017
|
typedef struct
|
|
988
1018
|
{
|
|
989
1019
|
struct sockaddr_storage addr;
|
|
@@ -1028,6 +1058,7 @@ pgconn_backend_key(VALUE self)
|
|
|
1028
1058
|
|
|
1029
1059
|
return INT2NUM(be_key);
|
|
1030
1060
|
}
|
|
1061
|
+
#endif
|
|
1031
1062
|
|
|
1032
1063
|
/*
|
|
1033
1064
|
* call-seq:
|
|
@@ -1300,7 +1331,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
|
1300
1331
|
paramsData->lengths[i] = 0;
|
|
1301
1332
|
} else {
|
|
1302
1333
|
t_pg_coder_enc_func enc_func = pg_coder_enc_func( conv );
|
|
1303
|
-
VALUE intermediate;
|
|
1334
|
+
VALUE intermediate = Qnil;
|
|
1304
1335
|
|
|
1305
1336
|
/* 1st pass for retiving the required memory space */
|
|
1306
1337
|
int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
|
|
@@ -1340,8 +1371,6 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
|
1340
1371
|
required_pool_size += len;
|
|
1341
1372
|
}
|
|
1342
1373
|
}
|
|
1343
|
-
|
|
1344
|
-
RB_GC_GUARD(intermediate);
|
|
1345
1374
|
}
|
|
1346
1375
|
}
|
|
1347
1376
|
}
|
|
@@ -1516,6 +1545,19 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
1516
1545
|
return rb_pgresult;
|
|
1517
1546
|
}
|
|
1518
1547
|
|
|
1548
|
+
static VALUE
|
|
1549
|
+
pgconn_sync_describe_close_prepared_portal(VALUE self, VALUE name, PGresult *(*func)(PGconn *, const char *))
|
|
1550
|
+
{
|
|
1551
|
+
PGresult *result;
|
|
1552
|
+
VALUE rb_pgresult;
|
|
1553
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
|
1554
|
+
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
|
|
1555
|
+
result = func(this->pgconn, stmt);
|
|
1556
|
+
rb_pgresult = pg_new_result(result, self);
|
|
1557
|
+
pg_result_check(rb_pgresult);
|
|
1558
|
+
return rb_pgresult;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1519
1561
|
/*
|
|
1520
1562
|
* call-seq:
|
|
1521
1563
|
* conn.sync_describe_prepared( statement_name ) -> PG::Result
|
|
@@ -1527,20 +1569,7 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
1527
1569
|
static VALUE
|
|
1528
1570
|
pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1529
1571
|
{
|
|
1530
|
-
|
|
1531
|
-
VALUE rb_pgresult;
|
|
1532
|
-
t_pg_connection *this = pg_get_connection_safe( self );
|
|
1533
|
-
const char *stmt;
|
|
1534
|
-
if(NIL_P(stmt_name)) {
|
|
1535
|
-
stmt = NULL;
|
|
1536
|
-
}
|
|
1537
|
-
else {
|
|
1538
|
-
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
|
1539
|
-
}
|
|
1540
|
-
result = gvl_PQdescribePrepared(this->pgconn, stmt);
|
|
1541
|
-
rb_pgresult = pg_new_result(result, self);
|
|
1542
|
-
pg_result_check(rb_pgresult);
|
|
1543
|
-
return rb_pgresult;
|
|
1572
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePrepared);
|
|
1544
1573
|
}
|
|
1545
1574
|
|
|
1546
1575
|
|
|
@@ -1555,23 +1584,44 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
|
|
|
1555
1584
|
static VALUE
|
|
1556
1585
|
pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
|
|
1557
1586
|
{
|
|
1558
|
-
|
|
1559
|
-
VALUE rb_pgresult;
|
|
1560
|
-
t_pg_connection *this = pg_get_connection_safe( self );
|
|
1561
|
-
const char *stmt;
|
|
1562
|
-
if(NIL_P(stmt_name)) {
|
|
1563
|
-
stmt = NULL;
|
|
1564
|
-
}
|
|
1565
|
-
else {
|
|
1566
|
-
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
|
1567
|
-
}
|
|
1568
|
-
result = gvl_PQdescribePortal(this->pgconn, stmt);
|
|
1569
|
-
rb_pgresult = pg_new_result(result, self);
|
|
1570
|
-
pg_result_check(rb_pgresult);
|
|
1571
|
-
return rb_pgresult;
|
|
1587
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePortal);
|
|
1572
1588
|
}
|
|
1573
1589
|
|
|
1574
1590
|
|
|
1591
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
1592
|
+
/*
|
|
1593
|
+
* call-seq:
|
|
1594
|
+
* conn.sync_close_prepared( stmt_name ) -> PG::Result
|
|
1595
|
+
*
|
|
1596
|
+
* This function has the same behavior as #async_close_prepared, but is implemented using the synchronous command processing API of libpq.
|
|
1597
|
+
* See #async_exec for the differences between the two API variants.
|
|
1598
|
+
* It's not recommended to use explicit sync or async variants but #close_prepared instead, unless you have a good reason to do so.
|
|
1599
|
+
*
|
|
1600
|
+
* Available since PostgreSQL-17.
|
|
1601
|
+
*/
|
|
1602
|
+
static VALUE
|
|
1603
|
+
pgconn_sync_close_prepared(VALUE self, VALUE stmt_name)
|
|
1604
|
+
{
|
|
1605
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePrepared);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
/*
|
|
1609
|
+
* call-seq:
|
|
1610
|
+
* conn.sync_close_portal( portal_name ) -> PG::Result
|
|
1611
|
+
*
|
|
1612
|
+
* This function has the same behavior as #async_close_portal, but is implemented using the synchronous command processing API of libpq.
|
|
1613
|
+
* See #async_exec for the differences between the two API variants.
|
|
1614
|
+
* It's not recommended to use explicit sync or async variants but #close_portal instead, unless you have a good reason to do so.
|
|
1615
|
+
*
|
|
1616
|
+
* Available since PostgreSQL-17.
|
|
1617
|
+
*/
|
|
1618
|
+
static VALUE
|
|
1619
|
+
pgconn_sync_close_portal(VALUE self, VALUE stmt_name)
|
|
1620
|
+
{
|
|
1621
|
+
return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePortal);
|
|
1622
|
+
}
|
|
1623
|
+
#endif
|
|
1624
|
+
|
|
1575
1625
|
/*
|
|
1576
1626
|
* call-seq:
|
|
1577
1627
|
* conn.make_empty_pgresult( status ) -> PG::Result
|
|
@@ -1588,6 +1638,7 @@ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
|
|
|
1588
1638
|
* * +PGRES_FATAL_ERROR+
|
|
1589
1639
|
* * +PGRES_COPY_BOTH+
|
|
1590
1640
|
* * +PGRES_SINGLE_TUPLE+
|
|
1641
|
+
* * +PGRES_TUPLES_CHUNK+
|
|
1591
1642
|
* * +PGRES_PIPELINE_SYNC+
|
|
1592
1643
|
* * +PGRES_PIPELINE_ABORTED+
|
|
1593
1644
|
*/
|
|
@@ -1812,14 +1863,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
|
1812
1863
|
* (column names, types, etc) that an ordinary Result object for the query
|
|
1813
1864
|
* would have.
|
|
1814
1865
|
*
|
|
1815
|
-
* *Caution:* While processing a query, the server may return some rows and
|
|
1816
|
-
*
|
|
1817
|
-
*
|
|
1818
|
-
*
|
|
1819
|
-
* application
|
|
1820
|
-
* For proper transactional behavior, the application must be designed to discard
|
|
1821
|
-
* or undo whatever has been done with the previously-processed rows, if the query
|
|
1822
|
-
* ultimately fails.
|
|
1866
|
+
* *Caution:* While processing a query, the server may return some rows and then encounter an error, causing the query to be aborted.
|
|
1867
|
+
* Ordinarily, pg discards any such rows and reports only the error.
|
|
1868
|
+
* But in single-row or chunked mode, some rows may have already been returned to the application.
|
|
1869
|
+
* Hence, the application will see some PGRES_SINGLE_TUPLE or PGRES_TUPLES_CHUNK PG::Result objects followed by a PG::Error raised in get_result.
|
|
1870
|
+
* For proper transactional behavior, the application must be designed to discard or undo whatever has been done with the previously-processed rows, if the query ultimately fails.
|
|
1823
1871
|
*
|
|
1824
1872
|
* Example:
|
|
1825
1873
|
* conn.send_query( "your SQL command" )
|
|
@@ -1839,10 +1887,49 @@ pgconn_set_single_row_mode(VALUE self)
|
|
|
1839
1887
|
|
|
1840
1888
|
rb_check_frozen(self);
|
|
1841
1889
|
if( PQsetSingleRowMode(conn) == 0 )
|
|
1842
|
-
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
1890
|
+
pg_raise_conn_error( rb_ePGerror, self, "PQsetSingleRowMode %s", PQerrorMessage(conn));
|
|
1891
|
+
|
|
1892
|
+
return self;
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
1896
|
+
/*
|
|
1897
|
+
* call-seq:
|
|
1898
|
+
* conn.set_chunked_rows_mode -> self
|
|
1899
|
+
*
|
|
1900
|
+
* Select chunked mode for the currently-executing query.
|
|
1901
|
+
*
|
|
1902
|
+
* This function is similar to set_single_row_mode, except that it specifies retrieval of up to +chunk_size+ rows per PGresult, not necessarily just one row.
|
|
1903
|
+
* This function can only be called immediately after send_query or one of its sibling functions, before any other operation on the connection such as consume_input or get_result.
|
|
1904
|
+
* If called at the correct time, the function activates chunked mode for the current query.
|
|
1905
|
+
* Otherwise the mode stays unchanged and the function raises an error.
|
|
1906
|
+
* In any case, the mode reverts to normal after completion of the current query.
|
|
1907
|
+
*
|
|
1908
|
+
* Example:
|
|
1909
|
+
* conn.send_query( "your SQL command" )
|
|
1910
|
+
* conn.set_chunked_rows_mode(10)
|
|
1911
|
+
* loop do
|
|
1912
|
+
* res = conn.get_result or break
|
|
1913
|
+
* res.check
|
|
1914
|
+
* res.each do |row|
|
|
1915
|
+
* # do something with the received max. 10 rows
|
|
1916
|
+
* end
|
|
1917
|
+
* end
|
|
1918
|
+
*
|
|
1919
|
+
* Available since PostgreSQL-17
|
|
1920
|
+
*/
|
|
1921
|
+
static VALUE
|
|
1922
|
+
pgconn_set_chunked_rows_mode(VALUE self, VALUE chunk_size)
|
|
1923
|
+
{
|
|
1924
|
+
PGconn *conn = pg_get_pgconn(self);
|
|
1925
|
+
|
|
1926
|
+
rb_check_frozen(self);
|
|
1927
|
+
if( PQsetChunkedRowsMode(conn, NUM2INT(chunk_size)) == 0 )
|
|
1928
|
+
pg_raise_conn_error( rb_ePGerror, self, "PQsetChunkedRowsMode %s", PQerrorMessage(conn));
|
|
1843
1929
|
|
|
1844
1930
|
return self;
|
|
1845
1931
|
}
|
|
1932
|
+
#endif
|
|
1846
1933
|
|
|
1847
1934
|
static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
|
1848
1935
|
|
|
@@ -1867,7 +1954,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
|
1867
1954
|
/* If called with no or nil parameters, use PQexec for compatibility */
|
|
1868
1955
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
|
1869
1956
|
if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0)
|
|
1870
|
-
pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
|
|
1957
|
+
pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQuery %s", PQerrorMessage(this->pgconn));
|
|
1871
1958
|
|
|
1872
1959
|
pgconn_wait_for_flush( self );
|
|
1873
1960
|
return Qnil;
|
|
@@ -1942,7 +2029,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
|
1942
2029
|
free_query_params( ¶msData );
|
|
1943
2030
|
|
|
1944
2031
|
if(result == 0)
|
|
1945
|
-
pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
|
|
2032
|
+
pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryParams %s", PQerrorMessage(this->pgconn));
|
|
1946
2033
|
|
|
1947
2034
|
pgconn_wait_for_flush( self );
|
|
1948
2035
|
return Qnil;
|
|
@@ -2003,7 +2090,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
|
2003
2090
|
xfree(paramTypes);
|
|
2004
2091
|
|
|
2005
2092
|
if(result == 0) {
|
|
2006
|
-
pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
|
|
2093
|
+
pg_raise_conn_error( rb_eUnableToSend, self, "PQsendPrepare %s", PQerrorMessage(this->pgconn));
|
|
2007
2094
|
}
|
|
2008
2095
|
pgconn_wait_for_flush( self );
|
|
2009
2096
|
return Qnil;
|
|
@@ -2069,7 +2156,21 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
2069
2156
|
free_query_params( ¶msData );
|
|
2070
2157
|
|
|
2071
2158
|
if(result == 0)
|
|
2072
|
-
pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
|
|
2159
|
+
pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryPrepared %s", PQerrorMessage(this->pgconn));
|
|
2160
|
+
|
|
2161
|
+
pgconn_wait_for_flush( self );
|
|
2162
|
+
return Qnil;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
|
|
2166
|
+
static VALUE
|
|
2167
|
+
pgconn_send_describe_close_prepared_portal(VALUE self, VALUE name, int (*func)(PGconn *, const char *), const char *funame)
|
|
2168
|
+
{
|
|
2169
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
|
2170
|
+
const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
|
|
2171
|
+
/* returns 0 on failure */
|
|
2172
|
+
if(func(this->pgconn, stmt) == 0)
|
|
2173
|
+
pg_raise_conn_error( rb_eUnableToSend, self, "%s %s", funame, PQerrorMessage(this->pgconn));
|
|
2073
2174
|
|
|
2074
2175
|
pgconn_wait_for_flush( self );
|
|
2075
2176
|
return Qnil;
|
|
@@ -2085,13 +2186,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
2085
2186
|
static VALUE
|
|
2086
2187
|
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
2087
2188
|
{
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
|
|
2092
|
-
|
|
2093
|
-
pgconn_wait_for_flush( self );
|
|
2094
|
-
return Qnil;
|
|
2189
|
+
return pgconn_send_describe_close_prepared_portal(
|
|
2190
|
+
self, stmt_name, gvl_PQsendDescribePrepared,
|
|
2191
|
+
"PQsendDescribePrepared");
|
|
2095
2192
|
}
|
|
2096
2193
|
|
|
2097
2194
|
|
|
@@ -2105,16 +2202,48 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
|
2105
2202
|
static VALUE
|
|
2106
2203
|
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
2107
2204
|
{
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2205
|
+
return pgconn_send_describe_close_prepared_portal(
|
|
2206
|
+
self, portal, gvl_PQsendDescribePortal,
|
|
2207
|
+
"PQsendDescribePortal");
|
|
2208
|
+
}
|
|
2112
2209
|
|
|
2113
|
-
|
|
2114
|
-
|
|
2210
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
2211
|
+
/*
|
|
2212
|
+
* call-seq:
|
|
2213
|
+
* conn.send_close_prepared( statement_name ) -> nil
|
|
2214
|
+
*
|
|
2215
|
+
* Asynchronously send _command_ to the server. Does not block.
|
|
2216
|
+
* Use in combination with +conn.get_result+.
|
|
2217
|
+
*
|
|
2218
|
+
* Available since PostgreSQL-17.
|
|
2219
|
+
*/
|
|
2220
|
+
static VALUE
|
|
2221
|
+
pgconn_send_close_prepared(VALUE self, VALUE stmt_name)
|
|
2222
|
+
{
|
|
2223
|
+
return pgconn_send_describe_close_prepared_portal(
|
|
2224
|
+
self, stmt_name, gvl_PQsendClosePrepared,
|
|
2225
|
+
"PQsendClosePrepared");
|
|
2115
2226
|
}
|
|
2116
2227
|
|
|
2117
2228
|
|
|
2229
|
+
/*
|
|
2230
|
+
* call-seq:
|
|
2231
|
+
* conn.send_close_portal( portal_name ) -> nil
|
|
2232
|
+
*
|
|
2233
|
+
* Asynchronously send _command_ to the server. Does not block.
|
|
2234
|
+
* Use in combination with +conn.get_result+.
|
|
2235
|
+
*
|
|
2236
|
+
* Available since PostgreSQL-17.
|
|
2237
|
+
*/
|
|
2238
|
+
static VALUE
|
|
2239
|
+
pgconn_send_close_portal(VALUE self, VALUE portal)
|
|
2240
|
+
{
|
|
2241
|
+
return pgconn_send_describe_close_prepared_portal(
|
|
2242
|
+
self, portal, gvl_PQsendClosePortal,
|
|
2243
|
+
"PQsendClosePortal");
|
|
2244
|
+
}
|
|
2245
|
+
#endif
|
|
2246
|
+
|
|
2118
2247
|
static VALUE
|
|
2119
2248
|
pgconn_sync_get_result(VALUE self)
|
|
2120
2249
|
{
|
|
@@ -2204,6 +2333,7 @@ pgconn_sync_flush(VALUE self)
|
|
|
2204
2333
|
return (ret) ? Qfalse : Qtrue;
|
|
2205
2334
|
}
|
|
2206
2335
|
|
|
2336
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
|
2207
2337
|
static VALUE
|
|
2208
2338
|
pgconn_sync_cancel(VALUE self)
|
|
2209
2339
|
{
|
|
@@ -2225,6 +2355,7 @@ pgconn_sync_cancel(VALUE self)
|
|
|
2225
2355
|
PQfreeCancel(cancel);
|
|
2226
2356
|
return retval;
|
|
2227
2357
|
}
|
|
2358
|
+
#endif
|
|
2228
2359
|
|
|
2229
2360
|
|
|
2230
2361
|
/*
|
|
@@ -2252,7 +2383,7 @@ pgconn_notifies(VALUE self)
|
|
|
2252
2383
|
return Qnil;
|
|
2253
2384
|
}
|
|
2254
2385
|
|
|
2255
|
-
hash =
|
|
2386
|
+
hash = rb_hash_new_capa(3);
|
|
2256
2387
|
relname = rb_str_new2(notification->relname);
|
|
2257
2388
|
be_pid = INT2NUM(notification->be_pid);
|
|
2258
2389
|
extra = rb_str_new2(notification->extra);
|
|
@@ -2271,8 +2402,9 @@ pgconn_notifies(VALUE self)
|
|
|
2271
2402
|
static int
|
|
2272
2403
|
rb_io_descriptor(VALUE io)
|
|
2273
2404
|
{
|
|
2405
|
+
rb_io_t *fptr;
|
|
2274
2406
|
Check_Type(io, T_FILE);
|
|
2275
|
-
|
|
2407
|
+
fptr = RFILE(io)->fptr;
|
|
2276
2408
|
rb_io_check_closed(fptr);
|
|
2277
2409
|
return fptr->fd;
|
|
2278
2410
|
}
|
|
@@ -2568,7 +2700,7 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
|
2568
2700
|
VALUE value;
|
|
2569
2701
|
VALUE buffer = Qnil;
|
|
2570
2702
|
VALUE encoder;
|
|
2571
|
-
VALUE intermediate;
|
|
2703
|
+
VALUE intermediate = Qnil;
|
|
2572
2704
|
t_pg_coder *p_coder = NULL;
|
|
2573
2705
|
|
|
2574
2706
|
rb_scan_args( argc, argv, "11", &value, &encoder );
|
|
@@ -2607,7 +2739,6 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
|
2607
2739
|
if(ret == -1)
|
|
2608
2740
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
|
|
2609
2741
|
|
|
2610
|
-
RB_GC_GUARD(intermediate);
|
|
2611
2742
|
RB_GC_GUARD(buffer);
|
|
2612
2743
|
|
|
2613
2744
|
return (ret) ? Qtrue : Qfalse;
|
|
@@ -2702,7 +2833,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
|
|
2702
2833
|
return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
|
|
2703
2834
|
}
|
|
2704
2835
|
|
|
2705
|
-
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
|
2706
2836
|
/*
|
|
2707
2837
|
* call-seq:
|
|
2708
2838
|
* conn.set_error_context_visibility( context_visibility ) -> Integer
|
|
@@ -2722,7 +2852,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
|
|
2722
2852
|
*
|
|
2723
2853
|
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY].
|
|
2724
2854
|
*
|
|
2725
|
-
* Available since PostgreSQL-9.6
|
|
2726
2855
|
*/
|
|
2727
2856
|
static VALUE
|
|
2728
2857
|
pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
|
|
@@ -2731,7 +2860,6 @@ pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
|
|
|
2731
2860
|
PGContextVisibility context_visibility = NUM2INT(in_context_visibility);
|
|
2732
2861
|
return INT2FIX(PQsetErrorContextVisibility(conn, context_visibility));
|
|
2733
2862
|
}
|
|
2734
|
-
#endif
|
|
2735
2863
|
|
|
2736
2864
|
/*
|
|
2737
2865
|
* call-seq:
|
|
@@ -3459,6 +3587,21 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
3459
3587
|
return rb_pgresult;
|
|
3460
3588
|
}
|
|
3461
3589
|
|
|
3590
|
+
static VALUE
|
|
3591
|
+
pgconn_async_describe_close_prepared_potral(VALUE self, VALUE name, VALUE
|
|
3592
|
+
(*func)(VALUE, VALUE))
|
|
3593
|
+
{
|
|
3594
|
+
VALUE rb_pgresult = Qnil;
|
|
3595
|
+
|
|
3596
|
+
pgconn_discard_results( self );
|
|
3597
|
+
func( self, name );
|
|
3598
|
+
rb_pgresult = pgconn_async_get_last_result( self );
|
|
3599
|
+
|
|
3600
|
+
if ( rb_block_given_p() ) {
|
|
3601
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
|
3602
|
+
}
|
|
3603
|
+
return rb_pgresult;
|
|
3604
|
+
}
|
|
3462
3605
|
|
|
3463
3606
|
/*
|
|
3464
3607
|
* call-seq:
|
|
@@ -3471,16 +3614,7 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
|
3471
3614
|
static VALUE
|
|
3472
3615
|
pgconn_async_describe_portal(VALUE self, VALUE portal)
|
|
3473
3616
|
{
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
pgconn_discard_results( self );
|
|
3477
|
-
pgconn_send_describe_portal( self, portal );
|
|
3478
|
-
rb_pgresult = pgconn_async_get_last_result( self );
|
|
3479
|
-
|
|
3480
|
-
if ( rb_block_given_p() ) {
|
|
3481
|
-
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
|
3482
|
-
}
|
|
3483
|
-
return rb_pgresult;
|
|
3617
|
+
return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_describe_portal);
|
|
3484
3618
|
}
|
|
3485
3619
|
|
|
3486
3620
|
|
|
@@ -3495,27 +3629,64 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
|
|
|
3495
3629
|
static VALUE
|
|
3496
3630
|
pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
|
3497
3631
|
{
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
pgconn_discard_results( self );
|
|
3501
|
-
pgconn_send_describe_prepared( self, stmt_name );
|
|
3502
|
-
rb_pgresult = pgconn_async_get_last_result( self );
|
|
3632
|
+
return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_describe_prepared);
|
|
3633
|
+
}
|
|
3503
3634
|
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3635
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
3636
|
+
/*
|
|
3637
|
+
* call-seq:
|
|
3638
|
+
* conn.close_prepared( statement_name ) -> PG::Result
|
|
3639
|
+
*
|
|
3640
|
+
* Submits a request to close the specified prepared statement, and waits for completion.
|
|
3641
|
+
* close_prepared allows an application to close a previously prepared statement.
|
|
3642
|
+
* Closing a statement releases all of its associated resources on the server and allows its name to be reused.
|
|
3643
|
+
* It's the same as using the +DEALLOCATE+ SQL statement, but on a lower protocol level.
|
|
3644
|
+
*
|
|
3645
|
+
* +statement_name+ can be "" or +nil+ to reference the unnamed statement.
|
|
3646
|
+
* It is fine if no statement exists with this name, in that case the operation is a no-op.
|
|
3647
|
+
* On success, a PG::Result with status PGRES_COMMAND_OK is returned.
|
|
3648
|
+
*
|
|
3649
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPREPARED].
|
|
3650
|
+
*
|
|
3651
|
+
* Available since PostgreSQL-17.
|
|
3652
|
+
*/
|
|
3653
|
+
static VALUE
|
|
3654
|
+
pgconn_async_close_prepared(VALUE self, VALUE stmt_name)
|
|
3655
|
+
{
|
|
3656
|
+
return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_close_prepared);
|
|
3508
3657
|
}
|
|
3509
3658
|
|
|
3659
|
+
/*
|
|
3660
|
+
* call-seq:
|
|
3661
|
+
* conn.close_portal( portal_name ) -> PG::Result
|
|
3662
|
+
*
|
|
3663
|
+
* Submits a request to close the specified portal, and waits for completion.
|
|
3664
|
+
*
|
|
3665
|
+
* close_portal allows an application to trigger a close of a previously created portal.
|
|
3666
|
+
* Closing a portal releases all of its associated resources on the server and allows its name to be reused.
|
|
3667
|
+
* (pg does not provide any direct access to portals, but you can use this function to close a cursor created with a DECLARE CURSOR SQL command.)
|
|
3668
|
+
*
|
|
3669
|
+
* +portal_name+ can be "" or +nil+ to reference the unnamed portal.
|
|
3670
|
+
* It is fine if no portal exists with this name, in that case the operation is a no-op.
|
|
3671
|
+
* On success, a PG::Result with status PGRES_COMMAND_OK is returned.
|
|
3672
|
+
*
|
|
3673
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPORTAL].
|
|
3674
|
+
*
|
|
3675
|
+
* Available since PostgreSQL-17.
|
|
3676
|
+
*/
|
|
3677
|
+
static VALUE
|
|
3678
|
+
pgconn_async_close_portal(VALUE self, VALUE portal)
|
|
3679
|
+
{
|
|
3680
|
+
return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_close_portal);
|
|
3681
|
+
}
|
|
3682
|
+
#endif
|
|
3510
3683
|
|
|
3511
|
-
#ifdef HAVE_PQSSLATTRIBUTE
|
|
3512
3684
|
/*
|
|
3513
3685
|
* call-seq:
|
|
3514
3686
|
* conn.ssl_in_use? -> Boolean
|
|
3515
3687
|
*
|
|
3516
3688
|
* Returns +true+ if the connection uses SSL/TLS, +false+ if not.
|
|
3517
3689
|
*
|
|
3518
|
-
* Available since PostgreSQL-9.5
|
|
3519
3690
|
*/
|
|
3520
3691
|
static VALUE
|
|
3521
3692
|
pgconn_ssl_in_use(VALUE self)
|
|
@@ -3549,7 +3720,6 @@ pgconn_ssl_in_use(VALUE self)
|
|
|
3549
3720
|
*
|
|
3550
3721
|
* See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
|
|
3551
3722
|
*
|
|
3552
|
-
* Available since PostgreSQL-9.5
|
|
3553
3723
|
*/
|
|
3554
3724
|
static VALUE
|
|
3555
3725
|
pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
|
@@ -3568,7 +3738,6 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
|
|
3568
3738
|
*
|
|
3569
3739
|
* See also #ssl_attribute
|
|
3570
3740
|
*
|
|
3571
|
-
* Available since PostgreSQL-9.5
|
|
3572
3741
|
*/
|
|
3573
3742
|
static VALUE
|
|
3574
3743
|
pgconn_ssl_attribute_names(VALUE self)
|
|
@@ -3584,8 +3753,6 @@ pgconn_ssl_attribute_names(VALUE self)
|
|
|
3584
3753
|
}
|
|
3585
3754
|
|
|
3586
3755
|
|
|
3587
|
-
#endif
|
|
3588
|
-
|
|
3589
3756
|
|
|
3590
3757
|
#ifdef HAVE_PQENTERPIPELINEMODE
|
|
3591
3758
|
/*
|
|
@@ -3620,6 +3787,8 @@ pgconn_pipeline_status(VALUE self)
|
|
|
3620
3787
|
* Raises PG::Error and has no effect if the connection is not currently idle, i.e., it has a result ready, or it is waiting for more input from the server, etc.
|
|
3621
3788
|
* This function does not actually send anything to the server, it just changes the libpq connection state.
|
|
3622
3789
|
*
|
|
3790
|
+
* See the {PostgreSQL documentation}[https://www.postgresql.org/docs/17/libpq-pipeline-mode.html#LIBPQ-PIPELINE-MODE].
|
|
3791
|
+
*
|
|
3623
3792
|
* Available since PostgreSQL-14
|
|
3624
3793
|
*/
|
|
3625
3794
|
static VALUE
|
|
@@ -3658,29 +3827,55 @@ pgconn_exit_pipeline_mode(VALUE self)
|
|
|
3658
3827
|
|
|
3659
3828
|
/*
|
|
3660
3829
|
* call-seq:
|
|
3661
|
-
* conn.
|
|
3830
|
+
* conn.sync_pipeline_sync -> nil
|
|
3831
|
+
*
|
|
3832
|
+
* This function has the same behavior as #async_pipeline_sync, but is implemented using the synchronous command processing API of libpq.
|
|
3833
|
+
* See #async_exec for the differences between the two API variants.
|
|
3834
|
+
* It's not recommended to use explicit sync or async variants but #pipeline_sync instead, unless you have a good reason to do so.
|
|
3835
|
+
*
|
|
3836
|
+
* Available since PostgreSQL-14
|
|
3837
|
+
*/
|
|
3838
|
+
static VALUE
|
|
3839
|
+
pgconn_sync_pipeline_sync(VALUE self)
|
|
3840
|
+
{
|
|
3841
|
+
PGconn *conn = pg_get_pgconn(self);
|
|
3842
|
+
int res = gvl_PQpipelineSync(conn);
|
|
3843
|
+
if( res != 1 )
|
|
3844
|
+
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
3845
|
+
|
|
3846
|
+
return Qnil;
|
|
3847
|
+
}
|
|
3848
|
+
|
|
3849
|
+
|
|
3850
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
3851
|
+
/*
|
|
3852
|
+
* call-seq:
|
|
3853
|
+
* conn.send_pipeline_sync -> nil
|
|
3662
3854
|
*
|
|
3663
|
-
* Marks a synchronization point in a pipeline by sending a sync message
|
|
3664
|
-
* This serves as the delimiter of an implicit transaction and an error recovery point; see Section 34.5.1.3 of the PostgreSQL documentation.
|
|
3855
|
+
* Marks a synchronization point in a pipeline by sending a sync message without flushing the send buffer.
|
|
3665
3856
|
*
|
|
3857
|
+
* This serves as the delimiter of an implicit transaction and an error recovery point.
|
|
3666
3858
|
* Raises PG::Error if the connection is not in pipeline mode or sending a sync message failed.
|
|
3859
|
+
* Note that the message is not itself flushed to the server automatically; use flush if necessary.
|
|
3667
3860
|
*
|
|
3668
|
-
* Available since PostgreSQL-
|
|
3861
|
+
* Available since PostgreSQL-17
|
|
3669
3862
|
*/
|
|
3670
3863
|
static VALUE
|
|
3671
|
-
|
|
3864
|
+
pgconn_send_pipeline_sync(VALUE self)
|
|
3672
3865
|
{
|
|
3673
3866
|
PGconn *conn = pg_get_pgconn(self);
|
|
3674
|
-
int res =
|
|
3867
|
+
int res = gvl_PQsendPipelineSync(conn);
|
|
3675
3868
|
if( res != 1 )
|
|
3676
3869
|
pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
|
|
3677
3870
|
|
|
3678
3871
|
return Qnil;
|
|
3679
3872
|
}
|
|
3873
|
+
#endif
|
|
3874
|
+
|
|
3680
3875
|
|
|
3681
3876
|
/*
|
|
3682
3877
|
* call-seq:
|
|
3683
|
-
* conn.
|
|
3878
|
+
* conn.send_flush_request -> nil
|
|
3684
3879
|
*
|
|
3685
3880
|
* Sends a request for the server to flush its output buffer.
|
|
3686
3881
|
*
|
|
@@ -4231,9 +4426,11 @@ pgconn_set_default_encoding( VALUE self )
|
|
|
4231
4426
|
* res.type_map_for_queries = typemap
|
|
4232
4427
|
*
|
|
4233
4428
|
* Set the default TypeMap that is used for type casts of query bind parameters.
|
|
4429
|
+
* It can be overwritten per +type_map+ parameter of #exec_params and siblings.
|
|
4234
4430
|
*
|
|
4235
4431
|
* +typemap+ must be a kind of PG::TypeMap .
|
|
4236
4432
|
*
|
|
4433
|
+
* See also #type_map_for_queries
|
|
4237
4434
|
*/
|
|
4238
4435
|
static VALUE
|
|
4239
4436
|
pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
|
|
@@ -4258,6 +4455,9 @@ pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
|
|
|
4258
4455
|
* Returns the default TypeMap that is currently set for type casts of query
|
|
4259
4456
|
* bind parameters.
|
|
4260
4457
|
*
|
|
4458
|
+
* Default is PG::TypeMapAllStrings .
|
|
4459
|
+
*
|
|
4460
|
+
* See also #type_map_for_queries=
|
|
4261
4461
|
*/
|
|
4262
4462
|
static VALUE
|
|
4263
4463
|
pgconn_type_map_for_queries_get(VALUE self)
|
|
@@ -4272,9 +4472,11 @@ pgconn_type_map_for_queries_get(VALUE self)
|
|
|
4272
4472
|
* res.type_map_for_results = typemap
|
|
4273
4473
|
*
|
|
4274
4474
|
* Set the default TypeMap that is used for type casts of result values.
|
|
4475
|
+
* It can be overwritten per PG::Result#type_map= .
|
|
4275
4476
|
*
|
|
4276
4477
|
* +typemap+ must be a kind of PG::TypeMap .
|
|
4277
4478
|
*
|
|
4479
|
+
* See also #type_map_for_results
|
|
4278
4480
|
*/
|
|
4279
4481
|
static VALUE
|
|
4280
4482
|
pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
|
|
@@ -4296,6 +4498,9 @@ pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
|
|
|
4296
4498
|
*
|
|
4297
4499
|
* Returns the default TypeMap that is currently set for type casts of result values.
|
|
4298
4500
|
*
|
|
4501
|
+
* Default is PG::TypeMapAllStrings .
|
|
4502
|
+
*
|
|
4503
|
+
* See also #type_map_for_results=
|
|
4299
4504
|
*/
|
|
4300
4505
|
static VALUE
|
|
4301
4506
|
pgconn_type_map_for_results_get(VALUE self)
|
|
@@ -4312,11 +4517,13 @@ pgconn_type_map_for_results_get(VALUE self)
|
|
|
4312
4517
|
*
|
|
4313
4518
|
* Set the default coder that is used for type casting of parameters
|
|
4314
4519
|
* to #put_copy_data .
|
|
4520
|
+
* It can be overwritten per +encoder+ parameter of #put_copy_data and +coder+ parameter of #copy_data.
|
|
4315
4521
|
*
|
|
4316
4522
|
* +encoder+ can be:
|
|
4317
4523
|
* * a kind of PG::Coder
|
|
4318
4524
|
* * +nil+ - disable type encoding, data must be a String.
|
|
4319
4525
|
*
|
|
4526
|
+
* See also #encoder_for_put_copy_data
|
|
4320
4527
|
*/
|
|
4321
4528
|
static VALUE
|
|
4322
4529
|
pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
|
|
@@ -4346,6 +4553,8 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
|
|
|
4346
4553
|
* * a kind of PG::Coder
|
|
4347
4554
|
* * +nil+ - type encoding is disabled, data must be a String.
|
|
4348
4555
|
*
|
|
4556
|
+
* Default is +nil+ .
|
|
4557
|
+
* See also #encoder_for_put_copy_data=
|
|
4349
4558
|
*/
|
|
4350
4559
|
static VALUE
|
|
4351
4560
|
pgconn_encoder_for_put_copy_data_get(VALUE self)
|
|
@@ -4361,11 +4570,13 @@ pgconn_encoder_for_put_copy_data_get(VALUE self)
|
|
|
4361
4570
|
*
|
|
4362
4571
|
* Set the default coder that is used for type casting of received data
|
|
4363
4572
|
* by #get_copy_data .
|
|
4573
|
+
* It can be overwritten per +decoder+ parameter of #get_copy_data and +coder+ parameter of #copy_data.
|
|
4364
4574
|
*
|
|
4365
4575
|
* +decoder+ can be:
|
|
4366
4576
|
* * a kind of PG::Coder
|
|
4367
4577
|
* * +nil+ - disable type decoding, returned data will be a String.
|
|
4368
4578
|
*
|
|
4579
|
+
* See also #decoder_for_get_copy_data
|
|
4369
4580
|
*/
|
|
4370
4581
|
static VALUE
|
|
4371
4582
|
pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
|
|
@@ -4395,6 +4606,9 @@ pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
|
|
|
4395
4606
|
* * a kind of PG::Coder
|
|
4396
4607
|
* * +nil+ - type encoding is disabled, returned data will be a String.
|
|
4397
4608
|
*
|
|
4609
|
+
* Default is +nil+ .
|
|
4610
|
+
*
|
|
4611
|
+
* See also #decoder_for_get_copy_data=
|
|
4398
4612
|
*/
|
|
4399
4613
|
static VALUE
|
|
4400
4614
|
pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
@@ -4417,7 +4631,7 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
|
4417
4631
|
*
|
|
4418
4632
|
* Settings the type of field names affects only future results.
|
|
4419
4633
|
*
|
|
4420
|
-
* See further description at PG::Result#field_name_type=
|
|
4634
|
+
* See further description at PG::Result#field_name_type= and #field_name_type .
|
|
4421
4635
|
*
|
|
4422
4636
|
*/
|
|
4423
4637
|
static VALUE
|
|
@@ -4524,7 +4738,9 @@ init_pg_connection(void)
|
|
|
4524
4738
|
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
|
|
4525
4739
|
rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
|
|
4526
4740
|
rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
|
|
4741
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
|
4527
4742
|
rb_define_method(rb_cPGconn, "backend_key", pgconn_backend_key, 0);
|
|
4743
|
+
#endif
|
|
4528
4744
|
rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
|
|
4529
4745
|
rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
|
|
4530
4746
|
/* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
|
|
@@ -4536,6 +4752,10 @@ init_pg_connection(void)
|
|
|
4536
4752
|
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_sync_exec_prepared, -1);
|
|
4537
4753
|
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_sync_describe_prepared, 1);
|
|
4538
4754
|
rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_sync_describe_portal, 1);
|
|
4755
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
4756
|
+
rb_define_method(rb_cPGconn, "sync_close_prepared", pgconn_sync_close_prepared, 1);
|
|
4757
|
+
rb_define_method(rb_cPGconn, "sync_close_portal", pgconn_sync_close_portal, 1);
|
|
4758
|
+
#endif
|
|
4539
4759
|
|
|
4540
4760
|
rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
|
|
4541
4761
|
rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
|
|
@@ -4543,6 +4763,10 @@ init_pg_connection(void)
|
|
|
4543
4763
|
rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
|
|
4544
4764
|
rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
|
|
4545
4765
|
rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
|
|
4766
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
4767
|
+
rb_define_method(rb_cPGconn, "close_prepared", pgconn_async_close_prepared, 1);
|
|
4768
|
+
rb_define_method(rb_cPGconn, "close_portal", pgconn_async_close_portal, 1);
|
|
4769
|
+
#endif
|
|
4546
4770
|
|
|
4547
4771
|
rb_define_alias(rb_cPGconn, "async_exec", "exec");
|
|
4548
4772
|
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
|
@@ -4551,6 +4775,10 @@ init_pg_connection(void)
|
|
|
4551
4775
|
rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
|
|
4552
4776
|
rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
|
|
4553
4777
|
rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
|
|
4778
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
4779
|
+
rb_define_alias(rb_cPGconn, "async_close_prepared", "close_prepared");
|
|
4780
|
+
rb_define_alias(rb_cPGconn, "async_close_portal", "close_portal");
|
|
4781
|
+
#endif
|
|
4554
4782
|
|
|
4555
4783
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
|
4556
4784
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
|
@@ -4560,6 +4788,9 @@ init_pg_connection(void)
|
|
|
4560
4788
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
|
4561
4789
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
|
4562
4790
|
rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
|
|
4791
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
4792
|
+
rb_define_method(rb_cPGconn, "set_chunked_rows_mode", pgconn_set_chunked_rows_mode, 1);
|
|
4793
|
+
#endif
|
|
4563
4794
|
|
|
4564
4795
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
|
4565
4796
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
|
@@ -4579,7 +4810,9 @@ init_pg_connection(void)
|
|
|
4579
4810
|
rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
|
|
4580
4811
|
|
|
4581
4812
|
/****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
|
|
4813
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
|
4582
4814
|
rb_define_method(rb_cPGconn, "sync_cancel", pgconn_sync_cancel, 0);
|
|
4815
|
+
#endif
|
|
4583
4816
|
|
|
4584
4817
|
/****** PG::Connection INSTANCE METHODS: NOTIFY ******/
|
|
4585
4818
|
rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
|
|
@@ -4591,9 +4824,7 @@ init_pg_connection(void)
|
|
|
4591
4824
|
|
|
4592
4825
|
/****** PG::Connection INSTANCE METHODS: Control Functions ******/
|
|
4593
4826
|
rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
|
|
4594
|
-
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
|
4595
4827
|
rb_define_method(rb_cPGconn, "set_error_context_visibility", pgconn_set_error_context_visibility, 1 );
|
|
4596
|
-
#endif
|
|
4597
4828
|
rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
|
|
4598
4829
|
rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
|
|
4599
4830
|
|
|
@@ -4615,22 +4846,21 @@ init_pg_connection(void)
|
|
|
4615
4846
|
rb_define_method(rb_cPGconn, "sync_get_last_result", pgconn_sync_get_last_result, 0);
|
|
4616
4847
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_async_get_last_result, 0);
|
|
4617
4848
|
rb_define_alias(rb_cPGconn, "async_get_last_result", "get_last_result");
|
|
4618
|
-
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
|
4619
4849
|
rb_define_method(rb_cPGconn, "sync_encrypt_password", pgconn_sync_encrypt_password, -1);
|
|
4620
|
-
#endif
|
|
4621
4850
|
|
|
4622
|
-
#ifdef HAVE_PQSSLATTRIBUTE
|
|
4623
4851
|
rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
|
|
4624
4852
|
rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
|
|
4625
4853
|
rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
|
|
4626
|
-
#endif
|
|
4627
4854
|
|
|
4628
4855
|
#ifdef HAVE_PQENTERPIPELINEMODE
|
|
4629
4856
|
rb_define_method(rb_cPGconn, "pipeline_status", pgconn_pipeline_status, 0);
|
|
4630
4857
|
rb_define_method(rb_cPGconn, "enter_pipeline_mode", pgconn_enter_pipeline_mode, 0);
|
|
4631
4858
|
rb_define_method(rb_cPGconn, "exit_pipeline_mode", pgconn_exit_pipeline_mode, 0);
|
|
4632
|
-
rb_define_method(rb_cPGconn, "
|
|
4859
|
+
rb_define_method(rb_cPGconn, "sync_pipeline_sync", pgconn_sync_pipeline_sync, 0);
|
|
4633
4860
|
rb_define_method(rb_cPGconn, "send_flush_request", pgconn_send_flush_request, 0);
|
|
4861
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
|
4862
|
+
rb_define_method(rb_cPGconn, "send_pipeline_sync", pgconn_send_pipeline_sync, 0);
|
|
4863
|
+
#endif
|
|
4634
4864
|
#endif
|
|
4635
4865
|
|
|
4636
4866
|
/****** PG::Connection INSTANCE METHODS: Large Object Support ******/
|