pg 1.0.0 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +156 -0
- data/Manifest.txt +8 -2
- data/README-Windows.rdoc +4 -4
- data/README.ja.rdoc +1 -2
- data/README.rdoc +55 -9
- data/Rakefile +9 -7
- data/Rakefile.cross +58 -57
- data/ext/errorcodes.def +68 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +19 -2
- data/ext/extconf.rb +7 -5
- data/ext/pg.c +141 -98
- data/ext/pg.h +64 -21
- data/ext/pg_binary_decoder.c +82 -15
- data/ext/pg_binary_encoder.c +13 -12
- data/ext/pg_coder.c +73 -12
- data/ext/pg_connection.c +625 -346
- data/ext/pg_copy_coder.c +16 -8
- data/ext/pg_record_coder.c +491 -0
- data/ext/pg_result.c +571 -191
- data/ext/pg_text_decoder.c +606 -40
- data/ext/pg_text_encoder.c +185 -54
- data/ext/pg_tuple.c +549 -0
- data/ext/pg_type_map.c +1 -1
- data/ext/pg_type_map_all_strings.c +4 -4
- data/ext/pg_type_map_by_class.c +9 -4
- data/ext/pg_type_map_by_column.c +7 -6
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +3 -2
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/{util.c → pg_util.c} +10 -10
- data/ext/{util.h → pg_util.h} +2 -2
- data/lib/pg.rb +8 -6
- data/lib/pg/basic_type_mapping.rb +121 -25
- data/lib/pg/binary_decoder.rb +23 -0
- data/lib/pg/coder.rb +23 -2
- data/lib/pg/connection.rb +22 -3
- data/lib/pg/constants.rb +2 -1
- data/lib/pg/exceptions.rb +2 -1
- data/lib/pg/result.rb +14 -2
- data/lib/pg/text_decoder.rb +21 -26
- data/lib/pg/text_encoder.rb +32 -8
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +3 -2
- data/spec/helpers.rb +52 -20
- data/spec/pg/basic_type_mapping_spec.rb +362 -37
- data/spec/pg/connection_spec.rb +376 -146
- data/spec/pg/connection_sync_spec.rb +41 -0
- data/spec/pg/result_spec.rb +240 -15
- data/spec/pg/tuple_spec.rb +333 -0
- data/spec/pg/type_map_by_class_spec.rb +2 -2
- data/spec/pg/type_map_by_column_spec.rb +6 -2
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_map_by_oid_spec.rb +3 -3
- data/spec/pg/type_map_in_ruby_spec.rb +1 -1
- data/spec/pg/type_map_spec.rb +1 -1
- data/spec/pg/type_spec.rb +363 -17
- data/spec/pg_spec.rb +1 -1
- metadata +47 -47
- metadata.gz.sig +0 -0
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -13,13 +13,14 @@
|
|
13
13
|
VALUE rb_cPGconn;
|
14
14
|
static ID s_id_encode;
|
15
15
|
static VALUE sym_type, sym_format, sym_value;
|
16
|
+
static VALUE sym_symbol, sym_string, sym_static_symbol;
|
16
17
|
|
17
18
|
static PQnoticeReceiver default_notice_receiver = NULL;
|
18
19
|
static PQnoticeProcessor default_notice_processor = NULL;
|
19
20
|
|
20
21
|
static VALUE pgconn_finish( VALUE );
|
21
22
|
static VALUE pgconn_set_default_encoding( VALUE self );
|
22
|
-
void pgconn_set_internal_encoding_index( VALUE );
|
23
|
+
static void pgconn_set_internal_encoding_index( VALUE );
|
23
24
|
|
24
25
|
/*
|
25
26
|
* Global functions
|
@@ -85,8 +86,7 @@ pgconn_close_socket_io( VALUE self )
|
|
85
86
|
|
86
87
|
if ( RTEST(socket_io) ) {
|
87
88
|
#if defined(_WIN32)
|
88
|
-
|
89
|
-
if( rb_w32_unwrap_io_handle(ruby_sd) ){
|
89
|
+
if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
|
90
90
|
rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
|
91
91
|
}
|
92
92
|
#endif
|
@@ -153,7 +153,6 @@ pgconn_gc_mark( t_pg_connection *this )
|
|
153
153
|
rb_gc_mark( this->type_map_for_queries );
|
154
154
|
rb_gc_mark( this->type_map_for_results );
|
155
155
|
rb_gc_mark( this->trace_stream );
|
156
|
-
rb_gc_mark( this->external_encoding );
|
157
156
|
rb_gc_mark( this->encoder_for_put_copy_data );
|
158
157
|
rb_gc_mark( this->decoder_for_get_copy_data );
|
159
158
|
}
|
@@ -165,6 +164,10 @@ pgconn_gc_mark( t_pg_connection *this )
|
|
165
164
|
static void
|
166
165
|
pgconn_gc_free( t_pg_connection *this )
|
167
166
|
{
|
167
|
+
#if defined(_WIN32)
|
168
|
+
if ( RTEST(this->socket_io) )
|
169
|
+
rb_w32_unwrap_io_handle( this->ruby_sd );
|
170
|
+
#endif
|
168
171
|
if (this->pgconn != NULL)
|
169
172
|
PQfinish( this->pgconn );
|
170
173
|
|
@@ -197,7 +200,6 @@ pgconn_s_allocate( VALUE klass )
|
|
197
200
|
this->encoder_for_put_copy_data = Qnil;
|
198
201
|
this->decoder_for_get_copy_data = Qnil;
|
199
202
|
this->trace_stream = Qnil;
|
200
|
-
this->external_encoding = Qnil;
|
201
203
|
|
202
204
|
return self;
|
203
205
|
}
|
@@ -214,32 +216,27 @@ pgconn_s_allocate( VALUE klass )
|
|
214
216
|
*
|
215
217
|
* Create a connection to the specified server.
|
216
218
|
*
|
219
|
+
* +connection_hash+ must be a ruby Hash with connection parameters.
|
220
|
+
* See the {list of valid parameters}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS] in the PostgreSQL documentation.
|
221
|
+
*
|
222
|
+
* There are two accepted formats for +connection_string+: plain <code>keyword = value</code> strings and URIs.
|
223
|
+
* See the documentation of {connection strings}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING].
|
224
|
+
*
|
225
|
+
* The positional parameter form has the same functionality except that the missing parameters will always take on default values. The parameters are:
|
217
226
|
* [+host+]
|
218
227
|
* server hostname
|
219
|
-
* [+hostaddr+]
|
220
|
-
* server address (avoids hostname lookup, overrides +host+)
|
221
228
|
* [+port+]
|
222
229
|
* server port number
|
230
|
+
* [+options+]
|
231
|
+
* backend options
|
232
|
+
* [+tty+]
|
233
|
+
* (ignored in newer versions of PostgreSQL)
|
223
234
|
* [+dbname+]
|
224
235
|
* connecting database name
|
225
236
|
* [+user+]
|
226
237
|
* login user name
|
227
238
|
* [+password+]
|
228
239
|
* login password
|
229
|
-
* [+connect_timeout+]
|
230
|
-
* maximum time to wait for connection to succeed
|
231
|
-
* [+options+]
|
232
|
-
* backend options
|
233
|
-
* [+tty+]
|
234
|
-
* (ignored in newer versions of PostgreSQL)
|
235
|
-
* [+sslmode+]
|
236
|
-
* (disable|allow|prefer|require)
|
237
|
-
* [+krbsrvname+]
|
238
|
-
* kerberos service name
|
239
|
-
* [+gsslib+]
|
240
|
-
* GSS library to use for GSSAPI authentication
|
241
|
-
* [+service+]
|
242
|
-
* service name to use for additional parameters
|
243
240
|
*
|
244
241
|
* Examples:
|
245
242
|
*
|
@@ -255,7 +252,7 @@ pgconn_s_allocate( VALUE klass )
|
|
255
252
|
* # As an Array
|
256
253
|
* PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
|
257
254
|
*
|
258
|
-
* If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the
|
255
|
+
* If the Ruby default internal encoding is set (i.e., <code>Encoding.default_internal != nil</code>), the
|
259
256
|
* connection will have its +client_encoding+ set accordingly.
|
260
257
|
*
|
261
258
|
* Raises a PG::Error if the connection fails.
|
@@ -294,14 +291,16 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
294
291
|
* PG::Connection.connect_start(connection_string) -> conn
|
295
292
|
* PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn
|
296
293
|
*
|
297
|
-
* This is an asynchronous version of PG::Connection.
|
294
|
+
* This is an asynchronous version of PG::Connection.new.
|
298
295
|
*
|
299
296
|
* Use #connect_poll to poll the status of the connection.
|
300
297
|
*
|
301
298
|
* NOTE: this does *not* set the connection's +client_encoding+ for you if
|
302
|
-
* Encoding.default_internal is set. To set it after the connection is established,
|
299
|
+
* +Encoding.default_internal+ is set. To set it after the connection is established,
|
303
300
|
* call #internal_encoding=. You can also set it automatically by setting
|
304
|
-
* ENV['PGCLIENTENCODING']
|
301
|
+
* <code>ENV['PGCLIENTENCODING']</code>, or include the 'options' connection parameter.
|
302
|
+
*
|
303
|
+
* See also the 'sample' directory of this gem and the corresponding {libpq functions}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS].
|
305
304
|
*
|
306
305
|
*/
|
307
306
|
static VALUE
|
@@ -344,6 +343,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
344
343
|
*
|
345
344
|
* Check server status.
|
346
345
|
*
|
346
|
+
* See PG::Connection.new for a description of the parameters.
|
347
|
+
*
|
347
348
|
* Returns one of:
|
348
349
|
* [+PQPING_OK+]
|
349
350
|
* server is accepting connections
|
@@ -353,8 +354,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
353
354
|
* could not establish connection
|
354
355
|
* [+PQPING_NO_ATTEMPT+]
|
355
356
|
* connection not attempted (bad params)
|
356
|
-
*
|
357
|
-
* Available since PostgreSQL-9.1
|
358
357
|
*/
|
359
358
|
static VALUE
|
360
359
|
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
@@ -425,7 +424,8 @@ pgconn_s_conndefaults(VALUE self)
|
|
425
424
|
* Return value is the encrypted password.
|
426
425
|
* The caller can assume the string doesn't contain any special characters that would require escaping.
|
427
426
|
*
|
428
|
-
* Available since PostgreSQL-10
|
427
|
+
* Available since PostgreSQL-10.
|
428
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
|
429
429
|
*/
|
430
430
|
static VALUE
|
431
431
|
pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
@@ -444,10 +444,6 @@ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
444
444
|
if ( encrypted ) {
|
445
445
|
rval = rb_str_new2( encrypted );
|
446
446
|
PQfreemem( encrypted );
|
447
|
-
|
448
|
-
OBJ_INFECT( rval, password );
|
449
|
-
OBJ_INFECT( rval, username );
|
450
|
-
OBJ_INFECT( rval, algorithm );
|
451
447
|
} else {
|
452
448
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
453
449
|
}
|
@@ -480,9 +476,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
480
476
|
rval = rb_str_new2( encrypted );
|
481
477
|
PQfreemem( encrypted );
|
482
478
|
|
483
|
-
OBJ_INFECT( rval, password );
|
484
|
-
OBJ_INFECT( rval, username );
|
485
|
-
|
486
479
|
return rval;
|
487
480
|
}
|
488
481
|
|
@@ -628,7 +621,7 @@ pgconn_db(VALUE self)
|
|
628
621
|
{
|
629
622
|
char *db = PQdb(pg_get_pgconn(self));
|
630
623
|
if (!db) return Qnil;
|
631
|
-
return
|
624
|
+
return rb_str_new2(db);
|
632
625
|
}
|
633
626
|
|
634
627
|
/*
|
@@ -642,7 +635,7 @@ pgconn_user(VALUE self)
|
|
642
635
|
{
|
643
636
|
char *user = PQuser(pg_get_pgconn(self));
|
644
637
|
if (!user) return Qnil;
|
645
|
-
return
|
638
|
+
return rb_str_new2(user);
|
646
639
|
}
|
647
640
|
|
648
641
|
/*
|
@@ -656,7 +649,7 @@ pgconn_pass(VALUE self)
|
|
656
649
|
{
|
657
650
|
char *user = PQpass(pg_get_pgconn(self));
|
658
651
|
if (!user) return Qnil;
|
659
|
-
return
|
652
|
+
return rb_str_new2(user);
|
660
653
|
}
|
661
654
|
|
662
655
|
/*
|
@@ -670,7 +663,7 @@ pgconn_host(VALUE self)
|
|
670
663
|
{
|
671
664
|
char *host = PQhost(pg_get_pgconn(self));
|
672
665
|
if (!host) return Qnil;
|
673
|
-
return
|
666
|
+
return rb_str_new2(host);
|
674
667
|
}
|
675
668
|
|
676
669
|
/*
|
@@ -697,7 +690,7 @@ pgconn_tty(VALUE self)
|
|
697
690
|
{
|
698
691
|
char *tty = PQtty(pg_get_pgconn(self));
|
699
692
|
if (!tty) return Qnil;
|
700
|
-
return
|
693
|
+
return rb_str_new2(tty);
|
701
694
|
}
|
702
695
|
|
703
696
|
/*
|
@@ -711,7 +704,7 @@ pgconn_options(VALUE self)
|
|
711
704
|
{
|
712
705
|
char *options = PQoptions(pg_get_pgconn(self));
|
713
706
|
if (!options) return Qnil;
|
714
|
-
return
|
707
|
+
return rb_str_new2(options);
|
715
708
|
}
|
716
709
|
|
717
710
|
|
@@ -792,7 +785,7 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
|
|
792
785
|
if(ret == NULL)
|
793
786
|
return Qnil;
|
794
787
|
else
|
795
|
-
return
|
788
|
+
return rb_str_new2(ret);
|
796
789
|
}
|
797
790
|
|
798
791
|
/*
|
@@ -837,7 +830,7 @@ pgconn_error_message(VALUE self)
|
|
837
830
|
{
|
838
831
|
char *error = PQerrorMessage(pg_get_pgconn(self));
|
839
832
|
if (!error) return Qnil;
|
840
|
-
return
|
833
|
+
return rb_str_new2(error);
|
841
834
|
}
|
842
835
|
|
843
836
|
/*
|
@@ -861,6 +854,8 @@ static VALUE
|
|
861
854
|
pgconn_socket(VALUE self)
|
862
855
|
{
|
863
856
|
int sd;
|
857
|
+
pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
|
858
|
+
|
864
859
|
if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
|
865
860
|
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
866
861
|
return INT2NUM(sd);
|
@@ -893,16 +888,15 @@ pgconn_socket_io(VALUE self)
|
|
893
888
|
|
894
889
|
#ifdef _WIN32
|
895
890
|
ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
|
891
|
+
this->ruby_sd = ruby_sd;
|
896
892
|
#else
|
897
893
|
ruby_sd = sd;
|
898
894
|
#endif
|
899
895
|
|
900
896
|
socket_io = rb_funcall( rb_cIO, rb_intern("for_fd"), 1, INT2NUM(ruby_sd) );
|
901
897
|
|
902
|
-
/* Disable autoclose feature
|
903
|
-
|
904
|
-
rb_funcall( socket_io, id_autoclose, 1, Qfalse );
|
905
|
-
}
|
898
|
+
/* Disable autoclose feature */
|
899
|
+
rb_funcall( socket_io, id_autoclose, 1, Qfalse );
|
906
900
|
|
907
901
|
this->socket_io = socket_io;
|
908
902
|
}
|
@@ -958,40 +952,31 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
|
|
958
952
|
|
959
953
|
/*
|
960
954
|
* call-seq:
|
961
|
-
* conn.
|
962
|
-
* conn.
|
955
|
+
* conn.sync_exec(sql) -> PG::Result
|
956
|
+
* conn.sync_exec(sql) {|pg_result| block }
|
963
957
|
*
|
964
|
-
*
|
965
|
-
*
|
966
|
-
* On failure, it raises a PG::Error.
|
958
|
+
* This function has the same behavior as #async_exec, but is implemented using the synchronous command processing API of libpq.
|
959
|
+
* It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
|
967
960
|
*
|
968
|
-
*
|
969
|
-
*
|
970
|
-
* argument placeholders are used.
|
971
|
-
*
|
972
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
973
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
974
|
-
* In this instance, <code>conn.exec</code> returns the value of the block.
|
961
|
+
* Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
|
962
|
+
* However #async_exec has two advantages:
|
975
963
|
*
|
976
|
-
* #
|
977
|
-
*
|
978
|
-
*
|
979
|
-
* the query is finished. This is most notably visible by a delayed reaction to Control+C.
|
980
|
-
* Both methods ensure that other threads can process while waiting for the server to
|
981
|
-
* complete the request.
|
964
|
+
* 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
|
965
|
+
* 2. Ruby VM gets notified about IO blocked operations.
|
966
|
+
* It can therefore schedule things like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
|
982
967
|
*/
|
983
968
|
static VALUE
|
984
969
|
pgconn_exec(int argc, VALUE *argv, VALUE self)
|
985
970
|
{
|
986
|
-
|
971
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
987
972
|
PGresult *result = NULL;
|
988
973
|
VALUE rb_pgresult;
|
989
974
|
|
990
|
-
/* If called with no parameters, use PQexec */
|
991
|
-
if ( argc == 1 ) {
|
975
|
+
/* If called with no or nil parameters, use PQexec for compatibility */
|
976
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
992
977
|
VALUE query_str = argv[0];
|
993
978
|
|
994
|
-
result = gvl_PQexec(
|
979
|
+
result = gvl_PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx));
|
995
980
|
rb_pgresult = pg_new_result(result, self);
|
996
981
|
pg_result_check(rb_pgresult);
|
997
982
|
if (rb_block_given_p()) {
|
@@ -999,11 +984,10 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
999
984
|
}
|
1000
985
|
return rb_pgresult;
|
1001
986
|
}
|
987
|
+
pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
|
1002
988
|
|
1003
989
|
/* Otherwise, just call #exec_params instead for backward-compatibility */
|
1004
|
-
|
1005
|
-
return pgconn_exec_params( argc, argv, self );
|
1006
|
-
}
|
990
|
+
return pgconn_exec_params( argc, argv, self );
|
1007
991
|
|
1008
992
|
}
|
1009
993
|
|
@@ -1254,66 +1238,34 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1254
1238
|
|
1255
1239
|
/*
|
1256
1240
|
* call-seq:
|
1257
|
-
* conn.
|
1258
|
-
* conn.
|
1259
|
-
*
|
1260
|
-
* Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
|
1261
|
-
* for parameters.
|
1241
|
+
* conn.sync_exec_params(sql, params[, result_format[, type_map]] ) -> PG::Result
|
1242
|
+
* conn.sync_exec_params(sql, params[, result_format[, type_map]] ) {|pg_result| block }
|
1262
1243
|
*
|
1263
|
-
*
|
1264
|
-
*
|
1265
|
-
*
|
1266
|
-
* Each element of the +params+ array may be either:
|
1267
|
-
* a hash of the form:
|
1268
|
-
* {:value => String (value of bind parameter)
|
1269
|
-
* :type => Integer (oid of type of bind parameter)
|
1270
|
-
* :format => Integer (0 for text, 1 for binary)
|
1271
|
-
* }
|
1272
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1273
|
-
* { :value => <string value>, :type => 0, :format => 0 }
|
1274
|
-
*
|
1275
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1276
|
-
* inside the SQL query. The 0th element of the +params+ array is bound
|
1277
|
-
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
1278
|
-
*
|
1279
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1280
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1281
|
-
* explicit casts in the query to ensure that the right type is used.
|
1282
|
-
*
|
1283
|
-
* For example: "SELECT $1::int"
|
1284
|
-
*
|
1285
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1286
|
-
* for binary.
|
1287
|
-
*
|
1288
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1289
|
-
* This will type cast the params from various Ruby types before transmission
|
1290
|
-
* based on the encoders defined by the type map. When a type encoder is used
|
1291
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1292
|
-
* instead out of the hash form described above.
|
1293
|
-
*
|
1294
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1295
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1296
|
-
* In this instance, <code>conn.exec</code> returns the value of the block.
|
1244
|
+
* This function has the same behavior as #async_exec_params, but is implemented using the synchronous command processing API of libpq.
|
1245
|
+
* See #async_exec for the differences between the two API variants.
|
1246
|
+
* It's not recommended to use explicit sync or async variants but #exec_params instead, unless you have a good reason to do so.
|
1297
1247
|
*/
|
1298
1248
|
static VALUE
|
1299
1249
|
pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
1300
1250
|
{
|
1301
|
-
|
1251
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1302
1252
|
PGresult *result = NULL;
|
1303
1253
|
VALUE rb_pgresult;
|
1304
1254
|
VALUE command, in_res_fmt;
|
1305
1255
|
int nParams;
|
1306
1256
|
int resultFormat;
|
1307
|
-
struct query_params_data paramsData = {
|
1257
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1308
1258
|
|
1259
|
+
/* For compatibility we accept 1 to 4 parameters */
|
1309
1260
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1310
1261
|
paramsData.with_types = 1;
|
1311
1262
|
|
1312
1263
|
/*
|
1313
|
-
*
|
1314
|
-
*
|
1264
|
+
* For backward compatibility no or +nil+ for the second parameter
|
1265
|
+
* is passed to #exec
|
1315
1266
|
*/
|
1316
1267
|
if ( NIL_P(paramsData.params) ) {
|
1268
|
+
pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
|
1317
1269
|
return pgconn_exec( 1, argv, self );
|
1318
1270
|
}
|
1319
1271
|
pgconn_query_assign_typemap( self, ¶msData );
|
@@ -1321,7 +1273,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1321
1273
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1322
1274
|
nParams = alloc_query_params( ¶msData );
|
1323
1275
|
|
1324
|
-
result = gvl_PQexecParams(
|
1276
|
+
result = gvl_PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1325
1277
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1326
1278
|
|
1327
1279
|
free_query_params( ¶msData );
|
@@ -1338,28 +1290,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1338
1290
|
|
1339
1291
|
/*
|
1340
1292
|
* call-seq:
|
1341
|
-
* conn.
|
1293
|
+
* conn.sync_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
1342
1294
|
*
|
1343
|
-
*
|
1344
|
-
*
|
1345
|
-
*
|
1346
|
-
*
|
1347
|
-
* +param_types+ is an optional parameter to specify the Oids of the
|
1348
|
-
* types of the parameters.
|
1349
|
-
*
|
1350
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1351
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1352
|
-
* explicit casts in the query to ensure that the right type is used.
|
1353
|
-
*
|
1354
|
-
* For example: "SELECT $1::int"
|
1355
|
-
*
|
1356
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1357
|
-
* inside the SQL query.
|
1295
|
+
* This function has the same behavior as #async_prepare, but is implemented using the synchronous command processing API of libpq.
|
1296
|
+
* See #async_exec for the differences between the two API variants.
|
1297
|
+
* It's not recommended to use explicit sync or async variants but #prepare instead, unless you have a good reason to do so.
|
1358
1298
|
*/
|
1359
1299
|
static VALUE
|
1360
1300
|
pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
1361
1301
|
{
|
1362
|
-
|
1302
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1363
1303
|
PGresult *result = NULL;
|
1364
1304
|
VALUE rb_pgresult;
|
1365
1305
|
VALUE name, command, in_paramtypes;
|
@@ -1369,7 +1309,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1369
1309
|
Oid *paramTypes = NULL;
|
1370
1310
|
const char *name_cstr;
|
1371
1311
|
const char *command_cstr;
|
1372
|
-
int enc_idx =
|
1312
|
+
int enc_idx = this->enc_idx;
|
1373
1313
|
|
1374
1314
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1375
1315
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1387,7 +1327,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1387
1327
|
paramTypes[i] = NUM2UINT(param);
|
1388
1328
|
}
|
1389
1329
|
}
|
1390
|
-
result = gvl_PQprepare(
|
1330
|
+
result = gvl_PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1391
1331
|
|
1392
1332
|
xfree(paramTypes);
|
1393
1333
|
|
@@ -1398,49 +1338,23 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1398
1338
|
|
1399
1339
|
/*
|
1400
1340
|
* call-seq:
|
1401
|
-
* conn.
|
1402
|
-
* conn.
|
1403
|
-
*
|
1404
|
-
* Execute prepared named statement specified by _statement_name_.
|
1405
|
-
* Returns a PG::Result instance on success.
|
1406
|
-
* On failure, it raises a PG::Error.
|
1407
|
-
*
|
1408
|
-
* +params+ is an array of the optional bind parameters for the
|
1409
|
-
* SQL query. Each element of the +params+ array may be either:
|
1410
|
-
* a hash of the form:
|
1411
|
-
* {:value => String (value of bind parameter)
|
1412
|
-
* :format => Integer (0 for text, 1 for binary)
|
1413
|
-
* }
|
1414
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1415
|
-
* { :value => <string value>, :format => 0 }
|
1416
|
-
*
|
1417
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1418
|
-
* inside the SQL query. The 0th element of the +params+ array is bound
|
1419
|
-
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
1420
|
-
*
|
1421
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1422
|
-
* for binary.
|
1341
|
+
* conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
|
1342
|
+
* conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
|
1423
1343
|
*
|
1424
|
-
*
|
1425
|
-
*
|
1426
|
-
*
|
1427
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1428
|
-
* instead out of the hash form described above.
|
1429
|
-
*
|
1430
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1431
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1432
|
-
* In this instance, <code>conn.exec_prepared</code> returns the value of the block.
|
1344
|
+
* This function has the same behavior as #async_exec_prepared, but is implemented using the synchronous command processing API of libpq.
|
1345
|
+
* See #async_exec for the differences between the two API variants.
|
1346
|
+
* It's not recommended to use explicit sync or async variants but #exec_prepared instead, unless you have a good reason to do so.
|
1433
1347
|
*/
|
1434
1348
|
static VALUE
|
1435
1349
|
pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
1436
1350
|
{
|
1437
|
-
|
1351
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1438
1352
|
PGresult *result = NULL;
|
1439
1353
|
VALUE rb_pgresult;
|
1440
1354
|
VALUE name, in_res_fmt;
|
1441
1355
|
int nParams;
|
1442
1356
|
int resultFormat;
|
1443
|
-
struct query_params_data paramsData = {
|
1357
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1444
1358
|
|
1445
1359
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1446
1360
|
paramsData.with_types = 0;
|
@@ -1453,7 +1367,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1453
1367
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1454
1368
|
nParams = alloc_query_params( ¶msData );
|
1455
1369
|
|
1456
|
-
result = gvl_PQexecPrepared(
|
1370
|
+
result = gvl_PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1457
1371
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1458
1372
|
resultFormat);
|
1459
1373
|
|
@@ -1470,25 +1384,26 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1470
1384
|
|
1471
1385
|
/*
|
1472
1386
|
* call-seq:
|
1473
|
-
* conn.
|
1387
|
+
* conn.sync_describe_prepared( statement_name ) -> PG::Result
|
1474
1388
|
*
|
1475
|
-
*
|
1476
|
-
*
|
1389
|
+
* This function has the same behavior as #async_describe_prepared, but is implemented using the synchronous command processing API of libpq.
|
1390
|
+
* See #async_exec for the differences between the two API variants.
|
1391
|
+
* It's not recommended to use explicit sync or async variants but #describe_prepared instead, unless you have a good reason to do so.
|
1477
1392
|
*/
|
1478
1393
|
static VALUE
|
1479
1394
|
pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
1480
1395
|
{
|
1481
1396
|
PGresult *result;
|
1482
1397
|
VALUE rb_pgresult;
|
1483
|
-
|
1398
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1484
1399
|
const char *stmt;
|
1485
1400
|
if(NIL_P(stmt_name)) {
|
1486
1401
|
stmt = NULL;
|
1487
1402
|
}
|
1488
1403
|
else {
|
1489
|
-
stmt = pg_cstr_enc(stmt_name,
|
1404
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1490
1405
|
}
|
1491
|
-
result = gvl_PQdescribePrepared(
|
1406
|
+
result = gvl_PQdescribePrepared(this->pgconn, stmt);
|
1492
1407
|
rb_pgresult = pg_new_result(result, self);
|
1493
1408
|
pg_result_check(rb_pgresult);
|
1494
1409
|
return rb_pgresult;
|
@@ -1497,9 +1412,11 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1497
1412
|
|
1498
1413
|
/*
|
1499
1414
|
* call-seq:
|
1500
|
-
* conn.
|
1415
|
+
* conn.sync_describe_portal( portal_name ) -> PG::Result
|
1501
1416
|
*
|
1502
|
-
*
|
1417
|
+
* This function has the same behavior as #async_describe_portal, but is implemented using the synchronous command processing API of libpq.
|
1418
|
+
* See #async_exec for the differences between the two API variants.
|
1419
|
+
* It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
|
1503
1420
|
*/
|
1504
1421
|
static VALUE
|
1505
1422
|
pgconn_describe_portal(self, stmt_name)
|
@@ -1507,15 +1424,15 @@ pgconn_describe_portal(self, stmt_name)
|
|
1507
1424
|
{
|
1508
1425
|
PGresult *result;
|
1509
1426
|
VALUE rb_pgresult;
|
1510
|
-
|
1427
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1511
1428
|
const char *stmt;
|
1512
1429
|
if(NIL_P(stmt_name)) {
|
1513
1430
|
stmt = NULL;
|
1514
1431
|
}
|
1515
1432
|
else {
|
1516
|
-
stmt = pg_cstr_enc(stmt_name,
|
1433
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1517
1434
|
}
|
1518
|
-
result = gvl_PQdescribePortal(
|
1435
|
+
result = gvl_PQdescribePortal(this->pgconn, stmt);
|
1519
1436
|
rb_pgresult = pg_new_result(result, self);
|
1520
1437
|
pg_result_check(rb_pgresult);
|
1521
1438
|
return rb_pgresult;
|
@@ -1562,13 +1479,15 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1562
1479
|
* Consider using exec_params, which avoids the need for passing values
|
1563
1480
|
* inside of SQL commands.
|
1564
1481
|
*
|
1565
|
-
*
|
1482
|
+
* Character encoding of escaped string will be equal to client encoding of connection.
|
1566
1483
|
*
|
1567
1484
|
* NOTE: This class version of this method can only be used safely in client
|
1568
1485
|
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1569
1486
|
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1570
1487
|
* results if used in programs that use multiple database connections; use the
|
1571
1488
|
* same method on the connection object in such cases.
|
1489
|
+
*
|
1490
|
+
* See also convenience functions #escape_literal and #escape_identifier which also add proper quotes around the string.
|
1572
1491
|
*/
|
1573
1492
|
static VALUE
|
1574
1493
|
pgconn_s_escape(VALUE self, VALUE string)
|
@@ -1579,8 +1498,8 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1579
1498
|
int enc_idx;
|
1580
1499
|
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1581
1500
|
|
1582
|
-
|
1583
|
-
enc_idx =
|
1501
|
+
StringValueCStr(string);
|
1502
|
+
enc_idx = singleton ? ENCODING_GET(string) : pg_get_connection(self)->enc_idx;
|
1584
1503
|
if( ENCODING_GET(string) != enc_idx ){
|
1585
1504
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1586
1505
|
}
|
@@ -1597,7 +1516,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1597
1516
|
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1598
1517
|
}
|
1599
1518
|
rb_str_set_len(result, size);
|
1600
|
-
OBJ_INFECT(result, string);
|
1601
1519
|
|
1602
1520
|
return result;
|
1603
1521
|
}
|
@@ -1643,7 +1561,6 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
|
|
1643
1561
|
}
|
1644
1562
|
|
1645
1563
|
ret = rb_str_new((char*)to, to_len - 1);
|
1646
|
-
OBJ_INFECT(ret, str);
|
1647
1564
|
PQfreemem(to);
|
1648
1565
|
return ret;
|
1649
1566
|
}
|
@@ -1673,7 +1590,6 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1673
1590
|
to = PQunescapeBytea(from, &to_len);
|
1674
1591
|
|
1675
1592
|
ret = rb_str_new((char*)to, to_len);
|
1676
|
-
OBJ_INFECT(ret, str);
|
1677
1593
|
PQfreemem(to);
|
1678
1594
|
return ret;
|
1679
1595
|
}
|
@@ -1684,33 +1600,32 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1684
1600
|
*
|
1685
1601
|
* Escape an arbitrary String +str+ as a literal.
|
1686
1602
|
*
|
1687
|
-
*
|
1603
|
+
* See also PG::TextEncoder::QuotedLiteral for a type cast integrated version of this function.
|
1688
1604
|
*/
|
1689
1605
|
static VALUE
|
1690
1606
|
pgconn_escape_literal(VALUE self, VALUE string)
|
1691
1607
|
{
|
1692
|
-
|
1608
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1693
1609
|
char *escaped = NULL;
|
1694
1610
|
VALUE error;
|
1695
1611
|
VALUE result = Qnil;
|
1696
|
-
int enc_idx =
|
1612
|
+
int enc_idx = this->enc_idx;
|
1697
1613
|
|
1698
|
-
|
1614
|
+
StringValueCStr(string);
|
1699
1615
|
if( ENCODING_GET(string) != enc_idx ){
|
1700
1616
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1701
1617
|
}
|
1702
1618
|
|
1703
|
-
escaped = PQescapeLiteral(
|
1619
|
+
escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1704
1620
|
if (escaped == NULL)
|
1705
1621
|
{
|
1706
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1622
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1707
1623
|
rb_iv_set(error, "@connection", self);
|
1708
1624
|
rb_exc_raise(error);
|
1709
1625
|
return Qnil;
|
1710
1626
|
}
|
1711
1627
|
result = rb_str_new2(escaped);
|
1712
1628
|
PQfreemem(escaped);
|
1713
|
-
OBJ_INFECT(result, string);
|
1714
1629
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1715
1630
|
|
1716
1631
|
return result;
|
@@ -1725,34 +1640,31 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1725
1640
|
* This method does the same as #quote_ident with a String argument,
|
1726
1641
|
* but it doesn't support an Array argument and it makes use of libpq
|
1727
1642
|
* to process the string.
|
1728
|
-
*
|
1729
|
-
* Available since PostgreSQL-9.0
|
1730
1643
|
*/
|
1731
1644
|
static VALUE
|
1732
1645
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
1733
1646
|
{
|
1734
|
-
|
1647
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1735
1648
|
char *escaped = NULL;
|
1736
1649
|
VALUE error;
|
1737
1650
|
VALUE result = Qnil;
|
1738
|
-
int enc_idx =
|
1651
|
+
int enc_idx = this->enc_idx;
|
1739
1652
|
|
1740
|
-
|
1653
|
+
StringValueCStr(string);
|
1741
1654
|
if( ENCODING_GET(string) != enc_idx ){
|
1742
1655
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1743
1656
|
}
|
1744
1657
|
|
1745
|
-
escaped = PQescapeIdentifier(
|
1658
|
+
escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1746
1659
|
if (escaped == NULL)
|
1747
1660
|
{
|
1748
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1661
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1749
1662
|
rb_iv_set(error, "@connection", self);
|
1750
1663
|
rb_exc_raise(error);
|
1751
1664
|
return Qnil;
|
1752
1665
|
}
|
1753
1666
|
result = rb_str_new2(escaped);
|
1754
1667
|
PQfreemem(escaped);
|
1755
|
-
OBJ_INFECT(result, string);
|
1756
1668
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1757
1669
|
|
1758
1670
|
return result;
|
@@ -1793,8 +1705,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1793
1705
|
* # do something with the received row
|
1794
1706
|
* end
|
1795
1707
|
* end
|
1796
|
-
*
|
1797
|
-
* Available since PostgreSQL-9.2
|
1798
1708
|
*/
|
1799
1709
|
static VALUE
|
1800
1710
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1812,15 +1722,54 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1812
1722
|
return self;
|
1813
1723
|
}
|
1814
1724
|
|
1725
|
+
static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
1726
|
+
|
1815
1727
|
/*
|
1816
1728
|
* call-seq:
|
1817
|
-
* conn.send_query(sql
|
1729
|
+
* conn.send_query(sql) -> nil
|
1818
1730
|
*
|
1819
1731
|
* Sends SQL query request specified by _sql_ to PostgreSQL for
|
1820
1732
|
* asynchronous processing, and immediately returns.
|
1821
1733
|
* On failure, it raises a PG::Error.
|
1822
1734
|
*
|
1823
|
-
*
|
1735
|
+
* For backward compatibility, if you pass more than one parameter to this method,
|
1736
|
+
* it will call #send_query_params for you. New code should explicitly use #send_query_params if
|
1737
|
+
* argument placeholders are used.
|
1738
|
+
*
|
1739
|
+
*/
|
1740
|
+
static VALUE
|
1741
|
+
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
1742
|
+
{
|
1743
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1744
|
+
VALUE error;
|
1745
|
+
|
1746
|
+
/* If called with no or nil parameters, use PQexec for compatibility */
|
1747
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
1748
|
+
if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0) {
|
1749
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1750
|
+
rb_iv_set(error, "@connection", self);
|
1751
|
+
rb_exc_raise(error);
|
1752
|
+
}
|
1753
|
+
return Qnil;
|
1754
|
+
}
|
1755
|
+
|
1756
|
+
pg_deprecated(2, ("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
|
1757
|
+
|
1758
|
+
/* If called with parameters, and optionally result_format,
|
1759
|
+
* use PQsendQueryParams
|
1760
|
+
*/
|
1761
|
+
return pgconn_send_query_params( argc, argv, self);
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
/*
|
1765
|
+
* call-seq:
|
1766
|
+
* conn.send_query_params(sql, params [, result_format [, type_map ]] ) -> nil
|
1767
|
+
*
|
1768
|
+
* Sends SQL query request specified by _sql_ to PostgreSQL for
|
1769
|
+
* asynchronous processing, and immediately returns.
|
1770
|
+
* On failure, it raises a PG::Error.
|
1771
|
+
*
|
1772
|
+
* +params+ is an array of the bind parameters for the SQL query.
|
1824
1773
|
* Each element of the +params+ array may be either:
|
1825
1774
|
* a hash of the form:
|
1826
1775
|
* {:value => String (value of bind parameter)
|
@@ -1843,7 +1792,7 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1843
1792
|
* The optional +result_format+ should be 0 for text results, 1
|
1844
1793
|
* for binary.
|
1845
1794
|
*
|
1846
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1795
|
+
* +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1847
1796
|
* This will type cast the params from various Ruby types before transmission
|
1848
1797
|
* based on the encoders defined by the type map. When a type encoder is used
|
1849
1798
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -1851,44 +1800,30 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1851
1800
|
*
|
1852
1801
|
*/
|
1853
1802
|
static VALUE
|
1854
|
-
|
1803
|
+
pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
1855
1804
|
{
|
1856
|
-
|
1805
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1857
1806
|
int result;
|
1858
1807
|
VALUE command, in_res_fmt;
|
1859
1808
|
VALUE error;
|
1860
1809
|
int nParams;
|
1861
1810
|
int resultFormat;
|
1862
|
-
struct query_params_data paramsData = {
|
1811
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1863
1812
|
|
1864
|
-
rb_scan_args(argc, argv, "
|
1813
|
+
rb_scan_args(argc, argv, "22", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1865
1814
|
paramsData.with_types = 1;
|
1866
1815
|
|
1867
|
-
/* If called with no parameters, use PQsendQuery */
|
1868
|
-
if(NIL_P(paramsData.params)) {
|
1869
|
-
if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
|
1870
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1871
|
-
rb_iv_set(error, "@connection", self);
|
1872
|
-
rb_exc_raise(error);
|
1873
|
-
}
|
1874
|
-
return Qnil;
|
1875
|
-
}
|
1876
|
-
|
1877
|
-
/* If called with parameters, and optionally result_format,
|
1878
|
-
* use PQsendQueryParams
|
1879
|
-
*/
|
1880
|
-
|
1881
1816
|
pgconn_query_assign_typemap( self, ¶msData );
|
1882
1817
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1883
1818
|
nParams = alloc_query_params( ¶msData );
|
1884
1819
|
|
1885
|
-
result = gvl_PQsendQueryParams(
|
1820
|
+
result = gvl_PQsendQueryParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1886
1821
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1887
1822
|
|
1888
1823
|
free_query_params( ¶msData );
|
1889
1824
|
|
1890
1825
|
if(result == 0) {
|
1891
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1826
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1892
1827
|
rb_iv_set(error, "@connection", self);
|
1893
1828
|
rb_exc_raise(error);
|
1894
1829
|
}
|
@@ -1918,7 +1853,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1918
1853
|
static VALUE
|
1919
1854
|
pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
1920
1855
|
{
|
1921
|
-
|
1856
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1922
1857
|
int result;
|
1923
1858
|
VALUE name, command, in_paramtypes;
|
1924
1859
|
VALUE param;
|
@@ -1928,7 +1863,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1928
1863
|
Oid *paramTypes = NULL;
|
1929
1864
|
const char *name_cstr;
|
1930
1865
|
const char *command_cstr;
|
1931
|
-
int enc_idx =
|
1866
|
+
int enc_idx = this->enc_idx;
|
1932
1867
|
|
1933
1868
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1934
1869
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1946,12 +1881,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1946
1881
|
paramTypes[i] = NUM2UINT(param);
|
1947
1882
|
}
|
1948
1883
|
}
|
1949
|
-
result = gvl_PQsendPrepare(
|
1884
|
+
result = gvl_PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1950
1885
|
|
1951
1886
|
xfree(paramTypes);
|
1952
1887
|
|
1953
1888
|
if(result == 0) {
|
1954
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1889
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1955
1890
|
rb_iv_set(error, "@connection", self);
|
1956
1891
|
rb_exc_raise(error);
|
1957
1892
|
}
|
@@ -1983,7 +1918,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1983
1918
|
* The optional +result_format+ should be 0 for text results, 1
|
1984
1919
|
* for binary.
|
1985
1920
|
*
|
1986
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1921
|
+
* +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1987
1922
|
* This will type cast the params from various Ruby types before transmission
|
1988
1923
|
* based on the encoders defined by the type map. When a type encoder is used
|
1989
1924
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -1993,13 +1928,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1993
1928
|
static VALUE
|
1994
1929
|
pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
1995
1930
|
{
|
1996
|
-
|
1931
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1997
1932
|
int result;
|
1998
1933
|
VALUE name, in_res_fmt;
|
1999
1934
|
VALUE error;
|
2000
1935
|
int nParams;
|
2001
1936
|
int resultFormat;
|
2002
|
-
struct query_params_data paramsData = {
|
1937
|
+
struct query_params_data paramsData = { this->enc_idx };
|
2003
1938
|
|
2004
1939
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
2005
1940
|
paramsData.with_types = 0;
|
@@ -2013,14 +1948,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
2013
1948
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
2014
1949
|
nParams = alloc_query_params( ¶msData );
|
2015
1950
|
|
2016
|
-
result = gvl_PQsendQueryPrepared(
|
1951
|
+
result = gvl_PQsendQueryPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
2017
1952
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
2018
1953
|
resultFormat);
|
2019
1954
|
|
2020
1955
|
free_query_params( ¶msData );
|
2021
1956
|
|
2022
1957
|
if(result == 0) {
|
2023
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1958
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2024
1959
|
rb_iv_set(error, "@connection", self);
|
2025
1960
|
rb_exc_raise(error);
|
2026
1961
|
}
|
@@ -2038,10 +1973,10 @@ static VALUE
|
|
2038
1973
|
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
2039
1974
|
{
|
2040
1975
|
VALUE error;
|
2041
|
-
|
1976
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2042
1977
|
/* returns 0 on failure */
|
2043
|
-
if(gvl_PQsendDescribePrepared(
|
2044
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1978
|
+
if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0) {
|
1979
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2045
1980
|
rb_iv_set(error, "@connection", self);
|
2046
1981
|
rb_exc_raise(error);
|
2047
1982
|
}
|
@@ -2060,10 +1995,10 @@ static VALUE
|
|
2060
1995
|
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
2061
1996
|
{
|
2062
1997
|
VALUE error;
|
2063
|
-
|
1998
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2064
1999
|
/* returns 0 on failure */
|
2065
|
-
if(gvl_PQsendDescribePortal(
|
2066
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
2000
|
+
if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
|
2001
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2067
2002
|
rb_iv_set(error, "@connection", self);
|
2068
2003
|
rb_exc_raise(error);
|
2069
2004
|
}
|
@@ -2264,7 +2199,7 @@ pgconn_cancel(VALUE self)
|
|
2264
2199
|
static VALUE
|
2265
2200
|
pgconn_notifies(VALUE self)
|
2266
2201
|
{
|
2267
|
-
|
2202
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2268
2203
|
PGnotify *notification;
|
2269
2204
|
VALUE hash;
|
2270
2205
|
VALUE sym_relname, sym_be_pid, sym_extra;
|
@@ -2274,17 +2209,17 @@ pgconn_notifies(VALUE self)
|
|
2274
2209
|
sym_be_pid = ID2SYM(rb_intern("be_pid"));
|
2275
2210
|
sym_extra = ID2SYM(rb_intern("extra"));
|
2276
2211
|
|
2277
|
-
notification = gvl_PQnotifies(
|
2212
|
+
notification = gvl_PQnotifies(this->pgconn);
|
2278
2213
|
if (notification == NULL) {
|
2279
2214
|
return Qnil;
|
2280
2215
|
}
|
2281
2216
|
|
2282
2217
|
hash = rb_hash_new();
|
2283
|
-
relname =
|
2218
|
+
relname = rb_str_new2(notification->relname);
|
2284
2219
|
be_pid = INT2NUM(notification->be_pid);
|
2285
|
-
extra =
|
2286
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2287
|
-
PG_ENCODING_SET_NOCHECK( extra,
|
2220
|
+
extra = rb_str_new2(notification->extra);
|
2221
|
+
PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
|
2222
|
+
PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
|
2288
2223
|
|
2289
2224
|
rb_hash_aset(hash, sym_relname, relname);
|
2290
2225
|
rb_hash_aset(hash, sym_be_pid, be_pid);
|
@@ -2298,15 +2233,11 @@ pgconn_notifies(VALUE self)
|
|
2298
2233
|
#if defined( _WIN32 )
|
2299
2234
|
/*
|
2300
2235
|
* On Windows, use platform-specific strategies to wait for the socket
|
2301
|
-
* instead of
|
2236
|
+
* instead of rb_wait_for_single_fd().
|
2302
2237
|
*/
|
2303
2238
|
|
2304
2239
|
int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
2305
2240
|
|
2306
|
-
/* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
|
2307
|
-
* and does not wait (nor sleep) any time even if timeout is given.
|
2308
|
-
* Instead use the Winsock events and rb_w32_wait_events(). */
|
2309
|
-
|
2310
2241
|
static void *
|
2311
2242
|
wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
|
2312
2243
|
{
|
@@ -2391,7 +2322,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2391
2322
|
int sd = PQsocket( conn );
|
2392
2323
|
int ret;
|
2393
2324
|
void *retval;
|
2394
|
-
rb_fdset_t sd_rset;
|
2395
2325
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2396
2326
|
|
2397
2327
|
if ( sd < 0 )
|
@@ -2401,17 +2331,12 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2401
2331
|
if ( PQconsumeInput(conn) == 0 )
|
2402
2332
|
rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
|
2403
2333
|
|
2404
|
-
rb_fd_init( &sd_rset );
|
2405
|
-
|
2406
2334
|
if ( ptimeout ) {
|
2407
2335
|
gettimeofday(&currtime, NULL);
|
2408
2336
|
timeradd(&currtime, ptimeout, &aborttime);
|
2409
2337
|
}
|
2410
2338
|
|
2411
2339
|
while ( !(retval=is_readable(conn)) ) {
|
2412
|
-
rb_fd_zero( &sd_rset );
|
2413
|
-
rb_fd_set( sd, &sd_rset );
|
2414
|
-
|
2415
2340
|
if ( ptimeout ) {
|
2416
2341
|
gettimeofday(&currtime, NULL);
|
2417
2342
|
timersub(&aborttime, &currtime, &waittime);
|
@@ -2420,30 +2345,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2420
2345
|
/* Is the given timeout valid? */
|
2421
2346
|
if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
|
2422
2347
|
/* Wait for the socket to become readable before checking again */
|
2423
|
-
ret =
|
2348
|
+
ret = rb_wait_for_single_fd( sd, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
|
2424
2349
|
} else {
|
2425
2350
|
ret = 0;
|
2426
2351
|
}
|
2427
2352
|
|
2428
2353
|
if ( ret < 0 ){
|
2429
|
-
|
2430
|
-
rb_sys_fail( "rb_thread_select()" );
|
2354
|
+
rb_sys_fail( "rb_wait_for_single_fd()" );
|
2431
2355
|
}
|
2432
2356
|
|
2433
2357
|
/* Return false if the select() timed out */
|
2434
2358
|
if ( ret == 0 ){
|
2435
|
-
rb_fd_term( &sd_rset );
|
2436
2359
|
return NULL;
|
2437
2360
|
}
|
2438
2361
|
|
2439
2362
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
2440
2363
|
if ( PQconsumeInput(conn) == 0 ){
|
2441
|
-
rb_fd_term( &sd_rset );
|
2442
2364
|
rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
|
2443
2365
|
}
|
2444
2366
|
}
|
2445
2367
|
|
2446
|
-
rb_fd_term( &sd_rset );
|
2447
2368
|
return retval;
|
2448
2369
|
}
|
2449
2370
|
|
@@ -2458,27 +2379,20 @@ notify_readable(PGconn *conn)
|
|
2458
2379
|
|
2459
2380
|
/*
|
2460
2381
|
* call-seq:
|
2461
|
-
* conn.wait_for_notify( [ timeout ] ) -> String
|
2462
|
-
* conn.wait_for_notify( [ timeout ] ) { |event, pid| block }
|
2463
|
-
* conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } # PostgreSQL 9.0
|
2382
|
+
* conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } -> String
|
2464
2383
|
*
|
2465
2384
|
* Blocks while waiting for notification(s), or until the optional
|
2466
2385
|
* _timeout_ is reached, whichever comes first. _timeout_ is
|
2467
2386
|
* measured in seconds and can be fractional.
|
2468
2387
|
*
|
2469
|
-
* Returns +nil+ if _timeout_ is reached, the name of the NOTIFY
|
2470
|
-
*
|
2471
|
-
*
|
2472
|
-
*
|
2473
|
-
* Under PostgreSQL 9.0 and later, if the notification is sent with
|
2474
|
-
* the optional +payload+ string, it will be given to the block as the
|
2475
|
-
* third argument.
|
2476
|
-
*
|
2388
|
+
* Returns +nil+ if _timeout_ is reached, the name of the NOTIFY event otherwise.
|
2389
|
+
* If used in block form, passes the name of the NOTIFY +event+, the generating
|
2390
|
+
* +pid+ and the optional +payload+ string into the block.
|
2477
2391
|
*/
|
2478
2392
|
static VALUE
|
2479
2393
|
pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
2480
2394
|
{
|
2481
|
-
|
2395
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2482
2396
|
PGnotify *pnotification;
|
2483
2397
|
struct timeval timeout;
|
2484
2398
|
struct timeval *ptimeout = NULL;
|
@@ -2494,17 +2408,17 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2494
2408
|
ptimeout = &timeout;
|
2495
2409
|
}
|
2496
2410
|
|
2497
|
-
pnotification = (PGnotify*) wait_socket_readable(
|
2411
|
+
pnotification = (PGnotify*) wait_socket_readable( this->pgconn, ptimeout, notify_readable);
|
2498
2412
|
|
2499
2413
|
/* Return nil if the select timed out */
|
2500
2414
|
if ( !pnotification ) return Qnil;
|
2501
2415
|
|
2502
|
-
relname =
|
2503
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2416
|
+
relname = rb_str_new2( pnotification->relname );
|
2417
|
+
PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
|
2504
2418
|
be_pid = INT2NUM( pnotification->be_pid );
|
2505
2419
|
if ( *pnotification->extra ) {
|
2506
|
-
extra =
|
2507
|
-
PG_ENCODING_SET_NOCHECK( extra,
|
2420
|
+
extra = rb_str_new2( pnotification->extra );
|
2421
|
+
PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
|
2508
2422
|
}
|
2509
2423
|
PQfreemem( pnotification );
|
2510
2424
|
|
@@ -2564,7 +2478,7 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2564
2478
|
|
2565
2479
|
if( p_coder ){
|
2566
2480
|
t_pg_coder_enc_func enc_func;
|
2567
|
-
int enc_idx =
|
2481
|
+
int enc_idx = this->enc_idx;
|
2568
2482
|
|
2569
2483
|
enc_func = pg_coder_enc_func( p_coder );
|
2570
2484
|
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
@@ -2614,16 +2528,16 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2614
2528
|
VALUE error;
|
2615
2529
|
int ret;
|
2616
2530
|
const char *error_message = NULL;
|
2617
|
-
|
2531
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2618
2532
|
|
2619
2533
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2620
2534
|
error_message = NULL;
|
2621
2535
|
else
|
2622
|
-
error_message = pg_cstr_enc(str,
|
2536
|
+
error_message = pg_cstr_enc(str, this->enc_idx);
|
2623
2537
|
|
2624
|
-
ret = gvl_PQputCopyEnd(
|
2538
|
+
ret = gvl_PQputCopyEnd(this->pgconn, error_message);
|
2625
2539
|
if(ret == -1) {
|
2626
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
2540
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
2627
2541
|
rb_iv_set(error, "@connection", self);
|
2628
2542
|
rb_exc_raise(error);
|
2629
2543
|
}
|
@@ -2632,16 +2546,18 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2632
2546
|
|
2633
2547
|
/*
|
2634
2548
|
* call-seq:
|
2635
|
-
* conn.get_copy_data( [ async = false [, decoder = nil ]] ) ->
|
2549
|
+
* conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
|
2636
2550
|
*
|
2637
|
-
* Return
|
2551
|
+
* Return one row of data, +nil+
|
2638
2552
|
* if the copy is done, or +false+ if the call would
|
2639
2553
|
* block (only possible if _async_ is true).
|
2640
2554
|
*
|
2641
|
-
* _decoder_
|
2642
|
-
*
|
2643
|
-
*
|
2644
|
-
*
|
2555
|
+
* If _decoder_ is not set or +nil+, data is returned as binary string.
|
2556
|
+
*
|
2557
|
+
* If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
|
2558
|
+
* PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
|
2559
|
+
* COPY text format to an Array of Strings.
|
2560
|
+
* Optionally the decoder can type cast the single fields to various Ruby types in one step,
|
2645
2561
|
* if PG::TextDecoder::CopyRow#type_map is set accordingly.
|
2646
2562
|
*
|
2647
2563
|
* See also #copy_data.
|
@@ -2687,9 +2603,9 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2687
2603
|
|
2688
2604
|
if( p_coder ){
|
2689
2605
|
t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, p_coder->format );
|
2690
|
-
result = dec_func( p_coder, buffer, ret, 0, 0,
|
2606
|
+
result = dec_func( p_coder, buffer, ret, 0, 0, this->enc_idx );
|
2691
2607
|
} else {
|
2692
|
-
result =
|
2608
|
+
result = rb_str_new(buffer, ret);
|
2693
2609
|
}
|
2694
2610
|
|
2695
2611
|
PQfreemem(buffer);
|
@@ -2702,9 +2618,16 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2702
2618
|
*
|
2703
2619
|
* Sets connection's verbosity to _verbosity_ and returns
|
2704
2620
|
* the previous setting. Available settings are:
|
2621
|
+
*
|
2705
2622
|
* * PQERRORS_TERSE
|
2706
2623
|
* * PQERRORS_DEFAULT
|
2707
2624
|
* * PQERRORS_VERBOSE
|
2625
|
+
* * PQERRORS_SQLSTATE
|
2626
|
+
*
|
2627
|
+
* Changing the verbosity does not affect the messages available from already-existing PG::Result objects, only subsequently-created ones.
|
2628
|
+
* (But see PG::Result#verbose_error_message if you want to print a previous error with a different verbosity.)
|
2629
|
+
*
|
2630
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORVERBOSITY].
|
2708
2631
|
*/
|
2709
2632
|
static VALUE
|
2710
2633
|
pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
@@ -2714,6 +2637,37 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
|
2714
2637
|
return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
|
2715
2638
|
}
|
2716
2639
|
|
2640
|
+
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
2641
|
+
/*
|
2642
|
+
* call-seq:
|
2643
|
+
* conn.set_error_context_visibility( context_visibility ) -> Integer
|
2644
|
+
*
|
2645
|
+
* Sets connection's context display mode to _context_visibility_ and returns
|
2646
|
+
* the previous setting. Available settings are:
|
2647
|
+
* * PQSHOW_CONTEXT_NEVER
|
2648
|
+
* * PQSHOW_CONTEXT_ERRORS
|
2649
|
+
* * PQSHOW_CONTEXT_ALWAYS
|
2650
|
+
*
|
2651
|
+
* This mode controls whether the CONTEXT field is included in messages (unless the verbosity setting is TERSE, in which case CONTEXT is never shown).
|
2652
|
+
* The NEVER mode never includes CONTEXT, while ALWAYS always includes it if available.
|
2653
|
+
* In ERRORS mode (the default), CONTEXT fields are included only for error messages, not for notices and warnings.
|
2654
|
+
*
|
2655
|
+
* Changing this mode does not affect the messages available from already-existing PG::Result objects, only subsequently-created ones.
|
2656
|
+
* (But see PG::Result#verbose_error_message if you want to print a previous error with a different display mode.)
|
2657
|
+
*
|
2658
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY].
|
2659
|
+
*
|
2660
|
+
* Available since PostgreSQL-9.6
|
2661
|
+
*/
|
2662
|
+
static VALUE
|
2663
|
+
pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
|
2664
|
+
{
|
2665
|
+
PGconn *conn = pg_get_pgconn(self);
|
2666
|
+
PGContextVisibility context_visibility = NUM2INT(in_context_visibility);
|
2667
|
+
return INT2FIX(PQsetErrorContextVisibility(conn, context_visibility));
|
2668
|
+
}
|
2669
|
+
#endif
|
2670
|
+
|
2717
2671
|
/*
|
2718
2672
|
* call-seq:
|
2719
2673
|
* conn.trace( stream ) -> nil
|
@@ -2732,7 +2686,7 @@ pgconn_trace(VALUE self, VALUE stream)
|
|
2732
2686
|
VALUE new_file;
|
2733
2687
|
t_pg_connection *this = pg_get_connection_safe( self );
|
2734
2688
|
|
2735
|
-
if(rb_respond_to(stream,rb_intern("fileno"))
|
2689
|
+
if(!rb_respond_to(stream,rb_intern("fileno")))
|
2736
2690
|
rb_raise(rb_eArgError, "stream does not respond to method: fileno");
|
2737
2691
|
|
2738
2692
|
fileno = rb_funcall(stream, rb_intern("fileno"), 0);
|
@@ -2865,8 +2819,8 @@ notice_processor_proxy(void *arg, const char *message)
|
|
2865
2819
|
t_pg_connection *this = pg_get_connection( self );
|
2866
2820
|
|
2867
2821
|
if (this->notice_receiver != Qnil) {
|
2868
|
-
VALUE message_str =
|
2869
|
-
PG_ENCODING_SET_NOCHECK( message_str,
|
2822
|
+
VALUE message_str = rb_str_new2(message);
|
2823
|
+
PG_ENCODING_SET_NOCHECK( message_str, this->enc_idx );
|
2870
2824
|
rb_funcall(this->notice_receiver, rb_intern("call"), 1, message_str);
|
2871
2825
|
}
|
2872
2826
|
return;
|
@@ -2924,7 +2878,7 @@ static VALUE
|
|
2924
2878
|
pgconn_get_client_encoding(VALUE self)
|
2925
2879
|
{
|
2926
2880
|
char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self)));
|
2927
|
-
return
|
2881
|
+
return rb_str_new2(encoding);
|
2928
2882
|
}
|
2929
2883
|
|
2930
2884
|
|
@@ -3036,14 +2990,12 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
|
3036
2990
|
int enc_idx;
|
3037
2991
|
|
3038
2992
|
if( rb_obj_is_kind_of(self, rb_cPGconn) ){
|
3039
|
-
enc_idx =
|
2993
|
+
enc_idx = pg_get_connection(self)->enc_idx;
|
3040
2994
|
}else{
|
3041
2995
|
enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
|
3042
2996
|
}
|
3043
2997
|
pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
|
3044
2998
|
|
3045
|
-
OBJ_INFECT(ret, str_or_array);
|
3046
|
-
|
3047
2999
|
return ret;
|
3048
3000
|
}
|
3049
3001
|
|
@@ -3072,10 +3024,6 @@ static VALUE
|
|
3072
3024
|
pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
3073
3025
|
PGconn *conn = pg_get_pgconn( self );
|
3074
3026
|
|
3075
|
-
/* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
|
3076
|
-
* and does not wait (nor sleep) any time even if timeout is given.
|
3077
|
-
* Instead use the Winsock events and rb_w32_wait_events(). */
|
3078
|
-
|
3079
3027
|
struct timeval timeout;
|
3080
3028
|
struct timeval *ptimeout = NULL;
|
3081
3029
|
VALUE timeout_in;
|
@@ -3142,24 +3090,285 @@ pgconn_get_last_result(VALUE self)
|
|
3142
3090
|
|
3143
3091
|
/*
|
3144
3092
|
* call-seq:
|
3145
|
-
* conn.
|
3146
|
-
* conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
|
3093
|
+
* conn.discard_results()
|
3147
3094
|
*
|
3148
|
-
*
|
3149
|
-
*
|
3150
|
-
*
|
3095
|
+
* Silently discard any prior query result that application didn't eat.
|
3096
|
+
* This is done prior of Connection#exec and sibling methods and can
|
3097
|
+
* be called explicitly when using the async API.
|
3098
|
+
*/
|
3099
|
+
static VALUE
|
3100
|
+
pgconn_discard_results(VALUE self)
|
3101
|
+
{
|
3102
|
+
PGconn *conn = pg_get_pgconn(self);
|
3103
|
+
|
3104
|
+
PGresult *cur;
|
3105
|
+
while ((cur = gvl_PQgetResult(conn)) != NULL) {
|
3106
|
+
int status = PQresultStatus(cur);
|
3107
|
+
PQclear(cur);
|
3108
|
+
if (status == PGRES_COPY_IN){
|
3109
|
+
gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
|
3110
|
+
}
|
3111
|
+
if (status == PGRES_COPY_OUT){
|
3112
|
+
char *buffer = NULL;
|
3113
|
+
while( gvl_PQgetCopyData(conn, &buffer, 0) > 0)
|
3114
|
+
PQfreemem(buffer);
|
3115
|
+
}
|
3116
|
+
}
|
3117
|
+
|
3118
|
+
return Qnil;
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
/*
|
3122
|
+
* call-seq:
|
3123
|
+
* conn.exec(sql) -> PG::Result
|
3124
|
+
* conn.exec(sql) {|pg_result| block }
|
3125
|
+
*
|
3126
|
+
* Sends SQL query request specified by _sql_ to PostgreSQL.
|
3127
|
+
* On success, it returns a PG::Result instance with all result rows and columns.
|
3128
|
+
* On failure, it raises a PG::Error.
|
3129
|
+
*
|
3130
|
+
* For backward compatibility, if you pass more than one parameter to this method,
|
3131
|
+
* it will call #exec_params for you. New code should explicitly use #exec_params if
|
3132
|
+
* argument placeholders are used.
|
3133
|
+
*
|
3134
|
+
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
3135
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
3136
|
+
* In this instance, <code>conn.exec</code> returns the value of the block.
|
3137
|
+
*
|
3138
|
+
* #exec is an alias for #async_exec which is almost identical to #sync_exec .
|
3139
|
+
* #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
|
3140
|
+
* #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
|
3141
|
+
* Both methods ensure that other threads can process while waiting for the server to
|
3142
|
+
* complete the request, but #sync_exec blocks all signals to be processed until the query is finished.
|
3143
|
+
* This is most notably visible by a delayed reaction to Control+C.
|
3144
|
+
* It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
|
3145
|
+
*
|
3146
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXEC].
|
3151
3147
|
*/
|
3152
3148
|
static VALUE
|
3153
3149
|
pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
3154
3150
|
{
|
3155
3151
|
VALUE rb_pgresult = Qnil;
|
3156
3152
|
|
3157
|
-
|
3153
|
+
pgconn_discard_results( self );
|
3154
|
+
pgconn_send_query( argc, argv, self );
|
3158
3155
|
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3159
|
-
pgconn_get_last_result( self );
|
3156
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3160
3157
|
|
3161
|
-
|
3162
|
-
|
3158
|
+
if ( rb_block_given_p() ) {
|
3159
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3160
|
+
}
|
3161
|
+
return rb_pgresult;
|
3162
|
+
}
|
3163
|
+
|
3164
|
+
|
3165
|
+
/*
|
3166
|
+
* call-seq:
|
3167
|
+
* conn.exec_params(sql, params [, result_format [, type_map ]] ) -> nil
|
3168
|
+
* conn.exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
|
3169
|
+
*
|
3170
|
+
* Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
|
3171
|
+
* for parameters.
|
3172
|
+
*
|
3173
|
+
* Returns a PG::Result instance on success. On failure, it raises a PG::Error.
|
3174
|
+
*
|
3175
|
+
* +params+ is an array of the bind parameters for the SQL query.
|
3176
|
+
* Each element of the +params+ array may be either:
|
3177
|
+
* a hash of the form:
|
3178
|
+
* {:value => String (value of bind parameter)
|
3179
|
+
* :type => Integer (oid of type of bind parameter)
|
3180
|
+
* :format => Integer (0 for text, 1 for binary)
|
3181
|
+
* }
|
3182
|
+
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
3183
|
+
* { :value => <string value>, :type => 0, :format => 0 }
|
3184
|
+
*
|
3185
|
+
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
3186
|
+
* inside the SQL query. The 0th element of the +params+ array is bound
|
3187
|
+
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
3188
|
+
*
|
3189
|
+
* If the types are not specified, they will be inferred by PostgreSQL.
|
3190
|
+
* Instead of specifying type oids, it's recommended to simply add
|
3191
|
+
* explicit casts in the query to ensure that the right type is used.
|
3192
|
+
*
|
3193
|
+
* For example: "SELECT $1::int"
|
3194
|
+
*
|
3195
|
+
* The optional +result_format+ should be 0 for text results, 1
|
3196
|
+
* for binary.
|
3197
|
+
*
|
3198
|
+
* +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
3199
|
+
* This will type cast the params from various Ruby types before transmission
|
3200
|
+
* based on the encoders defined by the type map. When a type encoder is used
|
3201
|
+
* the format and oid of a given bind parameter are retrieved from the encoder
|
3202
|
+
* instead out of the hash form described above.
|
3203
|
+
*
|
3204
|
+
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
3205
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
3206
|
+
* In this instance, <code>conn.exec</code> returns the value of the block.
|
3207
|
+
*
|
3208
|
+
* The primary advantage of #exec_params over #exec is that parameter values can be separated from the command string, thus avoiding the need for tedious and error-prone quoting and escaping.
|
3209
|
+
* Unlike #exec, #exec_params allows at most one SQL command in the given string.
|
3210
|
+
* (There can be semicolons in it, but not more than one nonempty command.)
|
3211
|
+
* This is a limitation of the underlying protocol, but has some usefulness as an extra defense against SQL-injection attacks.
|
3212
|
+
*
|
3213
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXECPARAMS].
|
3214
|
+
*/
|
3215
|
+
static VALUE
|
3216
|
+
pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
3217
|
+
{
|
3218
|
+
VALUE rb_pgresult = Qnil;
|
3219
|
+
|
3220
|
+
pgconn_discard_results( self );
|
3221
|
+
/* If called with no or nil parameters, use PQsendQuery for compatibility */
|
3222
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
3223
|
+
pg_deprecated(3, ("forwarding async_exec_params to async_exec is deprecated"));
|
3224
|
+
pgconn_send_query( argc, argv, self );
|
3225
|
+
} else {
|
3226
|
+
pgconn_send_query_params( argc, argv, self );
|
3227
|
+
}
|
3228
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3229
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3230
|
+
|
3231
|
+
if ( rb_block_given_p() ) {
|
3232
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3233
|
+
}
|
3234
|
+
return rb_pgresult;
|
3235
|
+
}
|
3236
|
+
|
3237
|
+
|
3238
|
+
/*
|
3239
|
+
* call-seq:
|
3240
|
+
* conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
3241
|
+
*
|
3242
|
+
* Prepares statement _sql_ with name _name_ to be executed later.
|
3243
|
+
* Returns a PG::Result instance on success.
|
3244
|
+
* On failure, it raises a PG::Error.
|
3245
|
+
*
|
3246
|
+
* +param_types+ is an optional parameter to specify the Oids of the
|
3247
|
+
* types of the parameters.
|
3248
|
+
*
|
3249
|
+
* If the types are not specified, they will be inferred by PostgreSQL.
|
3250
|
+
* Instead of specifying type oids, it's recommended to simply add
|
3251
|
+
* explicit casts in the query to ensure that the right type is used.
|
3252
|
+
*
|
3253
|
+
* For example: "SELECT $1::int"
|
3254
|
+
*
|
3255
|
+
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
3256
|
+
* inside the SQL query.
|
3257
|
+
*
|
3258
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQPREPARE].
|
3259
|
+
*/
|
3260
|
+
static VALUE
|
3261
|
+
pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
3262
|
+
{
|
3263
|
+
VALUE rb_pgresult = Qnil;
|
3264
|
+
|
3265
|
+
pgconn_discard_results( self );
|
3266
|
+
pgconn_send_prepare( argc, argv, self );
|
3267
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3268
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3269
|
+
|
3270
|
+
if ( rb_block_given_p() ) {
|
3271
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3272
|
+
}
|
3273
|
+
return rb_pgresult;
|
3274
|
+
}
|
3275
|
+
|
3276
|
+
|
3277
|
+
/*
|
3278
|
+
* call-seq:
|
3279
|
+
* conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
|
3280
|
+
* conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
|
3281
|
+
*
|
3282
|
+
* Execute prepared named statement specified by _statement_name_.
|
3283
|
+
* Returns a PG::Result instance on success.
|
3284
|
+
* On failure, it raises a PG::Error.
|
3285
|
+
*
|
3286
|
+
* +params+ is an array of the optional bind parameters for the
|
3287
|
+
* SQL query. Each element of the +params+ array may be either:
|
3288
|
+
* a hash of the form:
|
3289
|
+
* {:value => String (value of bind parameter)
|
3290
|
+
* :format => Integer (0 for text, 1 for binary)
|
3291
|
+
* }
|
3292
|
+
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
3293
|
+
* { :value => <string value>, :format => 0 }
|
3294
|
+
*
|
3295
|
+
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
3296
|
+
* inside the SQL query. The 0th element of the +params+ array is bound
|
3297
|
+
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
3298
|
+
*
|
3299
|
+
* The optional +result_format+ should be 0 for text results, 1
|
3300
|
+
* for binary.
|
3301
|
+
*
|
3302
|
+
* +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
3303
|
+
* This will type cast the params from various Ruby types before transmission
|
3304
|
+
* based on the encoders defined by the type map. When a type encoder is used
|
3305
|
+
* the format and oid of a given bind parameter are retrieved from the encoder
|
3306
|
+
* instead out of the hash form described above.
|
3307
|
+
*
|
3308
|
+
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
3309
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
3310
|
+
* In this instance, <code>conn.exec_prepared</code> returns the value of the block.
|
3311
|
+
*
|
3312
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXECPREPARED].
|
3313
|
+
*/
|
3314
|
+
static VALUE
|
3315
|
+
pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
3316
|
+
{
|
3317
|
+
VALUE rb_pgresult = Qnil;
|
3318
|
+
|
3319
|
+
pgconn_discard_results( self );
|
3320
|
+
pgconn_send_query_prepared( argc, argv, self );
|
3321
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3322
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3323
|
+
|
3324
|
+
if ( rb_block_given_p() ) {
|
3325
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3326
|
+
}
|
3327
|
+
return rb_pgresult;
|
3328
|
+
}
|
3329
|
+
|
3330
|
+
|
3331
|
+
/*
|
3332
|
+
* call-seq:
|
3333
|
+
* conn.describe_portal( portal_name ) -> PG::Result
|
3334
|
+
*
|
3335
|
+
* Retrieve information about the portal _portal_name_.
|
3336
|
+
*
|
3337
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL].
|
3338
|
+
*/
|
3339
|
+
static VALUE
|
3340
|
+
pgconn_async_describe_portal(VALUE self, VALUE portal)
|
3341
|
+
{
|
3342
|
+
VALUE rb_pgresult = Qnil;
|
3343
|
+
|
3344
|
+
pgconn_discard_results( self );
|
3345
|
+
pgconn_send_describe_portal( self, portal );
|
3346
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3347
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3348
|
+
|
3349
|
+
if ( rb_block_given_p() ) {
|
3350
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3351
|
+
}
|
3352
|
+
return rb_pgresult;
|
3353
|
+
}
|
3354
|
+
|
3355
|
+
|
3356
|
+
/*
|
3357
|
+
* call-seq:
|
3358
|
+
* conn.describe_prepared( statement_name ) -> PG::Result
|
3359
|
+
*
|
3360
|
+
* Retrieve information about the prepared statement _statement_name_.
|
3361
|
+
*
|
3362
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED].
|
3363
|
+
*/
|
3364
|
+
static VALUE
|
3365
|
+
pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
3366
|
+
{
|
3367
|
+
VALUE rb_pgresult = Qnil;
|
3368
|
+
|
3369
|
+
pgconn_discard_results( self );
|
3370
|
+
pgconn_send_describe_prepared( self, stmt_name );
|
3371
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3163
3372
|
rb_pgresult = pgconn_get_last_result( self );
|
3164
3373
|
|
3165
3374
|
if ( rb_block_given_p() ) {
|
@@ -3174,7 +3383,7 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3174
3383
|
* call-seq:
|
3175
3384
|
* conn.ssl_in_use? -> Boolean
|
3176
3385
|
*
|
3177
|
-
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3386
|
+
* Returns +true+ if the connection uses SSL/TLS, +false+ if not.
|
3178
3387
|
*
|
3179
3388
|
* Available since PostgreSQL-9.5
|
3180
3389
|
*/
|
@@ -3208,7 +3417,7 @@ pgconn_ssl_in_use(VALUE self)
|
|
3208
3417
|
* If SSL compression is in use, returns the name of the compression algorithm, or "on" if compression is used but the algorithm is not known. If compression is not in use, returns "off".
|
3209
3418
|
*
|
3210
3419
|
*
|
3211
|
-
* See also #ssl_attribute_names and
|
3420
|
+
* See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
|
3212
3421
|
*
|
3213
3422
|
* Available since PostgreSQL-9.5
|
3214
3423
|
*/
|
@@ -3436,7 +3645,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3436
3645
|
return Qnil;
|
3437
3646
|
}
|
3438
3647
|
|
3439
|
-
str =
|
3648
|
+
str = rb_str_new(buffer, ret);
|
3440
3649
|
xfree(buffer);
|
3441
3650
|
|
3442
3651
|
return str;
|
@@ -3540,12 +3749,15 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3540
3749
|
}
|
3541
3750
|
|
3542
3751
|
|
3543
|
-
void
|
3752
|
+
static void
|
3544
3753
|
pgconn_set_internal_encoding_index( VALUE self )
|
3545
3754
|
{
|
3546
|
-
|
3547
|
-
|
3548
|
-
|
3755
|
+
int enc_idx;
|
3756
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
3757
|
+
rb_encoding *enc = pg_conn_enc_get( this->pgconn );
|
3758
|
+
enc_idx = rb_enc_to_index(enc);
|
3759
|
+
if( enc_idx >= (1<<(PG_ENC_IDX_BITS-1)) ) rb_raise(rb_eArgError, "unsupported encoding index %d", enc_idx);
|
3760
|
+
this->enc_idx = enc_idx;
|
3549
3761
|
}
|
3550
3762
|
|
3551
3763
|
/*
|
@@ -3588,7 +3800,6 @@ static VALUE pgconn_external_encoding(VALUE self);
|
|
3588
3800
|
static VALUE
|
3589
3801
|
pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
3590
3802
|
{
|
3591
|
-
VALUE enc_inspect;
|
3592
3803
|
if (NIL_P(enc)) {
|
3593
3804
|
pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
|
3594
3805
|
return enc;
|
@@ -3609,11 +3820,6 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3609
3820
|
pgconn_set_internal_encoding_index( self );
|
3610
3821
|
return enc;
|
3611
3822
|
}
|
3612
|
-
|
3613
|
-
enc_inspect = rb_inspect(enc);
|
3614
|
-
rb_raise( rb_ePGerror, "unknown encoding: %s", StringValueCStr(enc_inspect) );
|
3615
|
-
|
3616
|
-
return Qnil;
|
3617
3823
|
}
|
3618
3824
|
|
3619
3825
|
|
@@ -3632,14 +3838,9 @@ pgconn_external_encoding(VALUE self)
|
|
3632
3838
|
rb_encoding *enc = NULL;
|
3633
3839
|
const char *pg_encname = NULL;
|
3634
3840
|
|
3635
|
-
/* Use cached value if found */
|
3636
|
-
if ( RTEST(this->external_encoding) ) return this->external_encoding;
|
3637
|
-
|
3638
3841
|
pg_encname = PQparameterStatus( this->pgconn, "server_encoding" );
|
3639
3842
|
enc = pg_get_pg_encname_as_rb_encoding( pg_encname );
|
3640
|
-
|
3641
|
-
|
3642
|
-
return this->external_encoding;
|
3843
|
+
return rb_enc_from_encoding( enc );
|
3643
3844
|
}
|
3644
3845
|
|
3645
3846
|
|
@@ -3657,9 +3858,10 @@ pgconn_set_client_encoding_async1( VALUE args )
|
|
3657
3858
|
|
3658
3859
|
|
3659
3860
|
static VALUE
|
3660
|
-
pgconn_set_client_encoding_async2( VALUE arg )
|
3861
|
+
pgconn_set_client_encoding_async2( VALUE arg, VALUE ex )
|
3661
3862
|
{
|
3662
3863
|
UNUSED(arg);
|
3864
|
+
UNUSED(ex);
|
3663
3865
|
return 1;
|
3664
3866
|
}
|
3665
3867
|
|
@@ -3690,7 +3892,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3690
3892
|
if (( enc = rb_default_internal_encoding() )) {
|
3691
3893
|
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3692
3894
|
if ( pgconn_set_client_encoding_async(self, encname) != 0 )
|
3693
|
-
|
3895
|
+
rb_warning( "Failed to set the default_internal encoding to %s: '%s'",
|
3694
3896
|
encname, PQerrorMessage(conn) );
|
3695
3897
|
pgconn_set_internal_encoding_index( self );
|
3696
3898
|
return rb_enc_from_encoding( enc );
|
@@ -3879,6 +4081,58 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
3879
4081
|
return this->decoder_for_get_copy_data;
|
3880
4082
|
}
|
3881
4083
|
|
4084
|
+
/*
|
4085
|
+
* call-seq:
|
4086
|
+
* conn.field_name_type = Symbol
|
4087
|
+
*
|
4088
|
+
* Set default type of field names of results retrieved by this connection.
|
4089
|
+
* It can be set to one of:
|
4090
|
+
* * +:string+ to use String based field names
|
4091
|
+
* * +:symbol+ to use Symbol based field names
|
4092
|
+
*
|
4093
|
+
* The default is +:string+ .
|
4094
|
+
*
|
4095
|
+
* Settings the type of field names affects only future results.
|
4096
|
+
*
|
4097
|
+
* See further description at PG::Result#field_name_type=
|
4098
|
+
*
|
4099
|
+
*/
|
4100
|
+
static VALUE
|
4101
|
+
pgconn_field_name_type_set(VALUE self, VALUE sym)
|
4102
|
+
{
|
4103
|
+
t_pg_connection *this = pg_get_connection( self );
|
4104
|
+
|
4105
|
+
this->flags &= ~PG_RESULT_FIELD_NAMES_MASK;
|
4106
|
+
if( sym == sym_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_SYMBOL;
|
4107
|
+
else if ( sym == sym_static_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_STATIC_SYMBOL;
|
4108
|
+
else if ( sym == sym_string );
|
4109
|
+
else rb_raise(rb_eArgError, "invalid argument %+"PRIsVALUE, sym);
|
4110
|
+
|
4111
|
+
return sym;
|
4112
|
+
}
|
4113
|
+
|
4114
|
+
/*
|
4115
|
+
* call-seq:
|
4116
|
+
* conn.field_name_type -> Symbol
|
4117
|
+
*
|
4118
|
+
* Get type of field names.
|
4119
|
+
*
|
4120
|
+
* See description at #field_name_type=
|
4121
|
+
*/
|
4122
|
+
static VALUE
|
4123
|
+
pgconn_field_name_type_get(VALUE self)
|
4124
|
+
{
|
4125
|
+
t_pg_connection *this = pg_get_connection( self );
|
4126
|
+
|
4127
|
+
if( this->flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
|
4128
|
+
return sym_symbol;
|
4129
|
+
} else if( this->flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
|
4130
|
+
return sym_static_symbol;
|
4131
|
+
} else {
|
4132
|
+
return sym_string;
|
4133
|
+
}
|
4134
|
+
}
|
4135
|
+
|
3882
4136
|
|
3883
4137
|
/*
|
3884
4138
|
* Document-class: PG::Connection
|
@@ -3890,8 +4144,13 @@ init_pg_connection()
|
|
3890
4144
|
sym_type = ID2SYM(rb_intern("type"));
|
3891
4145
|
sym_format = ID2SYM(rb_intern("format"));
|
3892
4146
|
sym_value = ID2SYM(rb_intern("value"));
|
4147
|
+
sym_string = ID2SYM(rb_intern("string"));
|
4148
|
+
sym_symbol = ID2SYM(rb_intern("symbol"));
|
4149
|
+
sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
|
3893
4150
|
|
3894
4151
|
rb_cPGconn = rb_define_class_under( rb_mPG, "Connection", rb_cObject );
|
4152
|
+
/* Help rdoc to known the Constants module */
|
4153
|
+
/* rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" ); */
|
3895
4154
|
rb_include_module(rb_cPGconn, rb_mPGconstants);
|
3896
4155
|
|
3897
4156
|
/****** PG::Connection CLASS METHODS ******/
|
@@ -3946,13 +4205,28 @@ init_pg_connection()
|
|
3946
4205
|
/* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
|
3947
4206
|
|
3948
4207
|
/****** PG::Connection INSTANCE METHODS: Command Execution ******/
|
3949
|
-
rb_define_method(rb_cPGconn, "
|
3950
|
-
|
3951
|
-
rb_define_method(rb_cPGconn, "
|
3952
|
-
rb_define_method(rb_cPGconn, "
|
3953
|
-
rb_define_method(rb_cPGconn, "
|
3954
|
-
rb_define_method(rb_cPGconn, "
|
3955
|
-
|
4208
|
+
rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
|
4209
|
+
rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
|
4210
|
+
rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
|
4211
|
+
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
|
4212
|
+
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
|
4213
|
+
rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
|
4214
|
+
|
4215
|
+
rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
|
4216
|
+
rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
|
4217
|
+
rb_define_method(rb_cPGconn, "prepare", pgconn_async_prepare, -1);
|
4218
|
+
rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
|
4219
|
+
rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
|
4220
|
+
rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
|
4221
|
+
|
4222
|
+
rb_define_alias(rb_cPGconn, "async_exec", "exec");
|
4223
|
+
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4224
|
+
rb_define_alias(rb_cPGconn, "async_exec_params", "exec_params");
|
4225
|
+
rb_define_alias(rb_cPGconn, "async_prepare", "prepare");
|
4226
|
+
rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
|
4227
|
+
rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
|
4228
|
+
rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
|
4229
|
+
|
3956
4230
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
3957
4231
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
3958
4232
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
@@ -3964,6 +4238,7 @@ init_pg_connection()
|
|
3964
4238
|
|
3965
4239
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
3966
4240
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
4241
|
+
rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
|
3967
4242
|
rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
|
3968
4243
|
rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
|
3969
4244
|
rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
|
@@ -3975,6 +4250,7 @@ init_pg_connection()
|
|
3975
4250
|
rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
|
3976
4251
|
rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
|
3977
4252
|
rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
|
4253
|
+
rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
|
3978
4254
|
|
3979
4255
|
/****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
|
3980
4256
|
rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
|
@@ -3989,6 +4265,9 @@ init_pg_connection()
|
|
3989
4265
|
|
3990
4266
|
/****** PG::Connection INSTANCE METHODS: Control Functions ******/
|
3991
4267
|
rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
|
4268
|
+
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
4269
|
+
rb_define_method(rb_cPGconn, "set_error_context_visibility", pgconn_set_error_context_visibility, 1 );
|
4270
|
+
#endif
|
3992
4271
|
rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
|
3993
4272
|
rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
|
3994
4273
|
|
@@ -4005,8 +4284,6 @@ init_pg_connection()
|
|
4005
4284
|
rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
|
4006
4285
|
rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
|
4007
4286
|
rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
4008
|
-
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
4009
|
-
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4010
4287
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
|
4011
4288
|
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
4012
4289
|
rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
|
@@ -4059,5 +4336,7 @@ init_pg_connection()
|
|
4059
4336
|
rb_define_method(rb_cPGconn, "encoder_for_put_copy_data", pgconn_encoder_for_put_copy_data_get, 0);
|
4060
4337
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data=", pgconn_decoder_for_get_copy_data_set, 1);
|
4061
4338
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data", pgconn_decoder_for_get_copy_data_get, 0);
|
4062
|
-
}
|
4063
4339
|
|
4340
|
+
rb_define_method(rb_cPGconn, "field_name_type=", pgconn_field_name_type_set, 1 );
|
4341
|
+
rb_define_method(rb_cPGconn, "field_name_type", pgconn_field_name_type_get, 0 );
|
4342
|
+
}
|