pg 0.19.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/ChangeLog +218 -1
- data/History.rdoc +106 -0
- data/Manifest.txt +5 -18
- data/README.rdoc +15 -5
- data/Rakefile +8 -9
- data/Rakefile.cross +19 -22
- data/ext/errorcodes.def +17 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +11 -1
- data/ext/extconf.rb +14 -32
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -39
- data/ext/pg.c +19 -48
- data/ext/pg.h +46 -81
- data/ext/pg_binary_decoder.c +69 -6
- data/ext/pg_coder.c +53 -4
- data/ext/pg_connection.c +401 -253
- data/ext/pg_copy_coder.c +10 -5
- data/ext/pg_result.c +359 -131
- data/ext/pg_text_decoder.c +597 -37
- data/ext/pg_text_encoder.c +6 -7
- data/ext/pg_tuple.c +541 -0
- data/ext/pg_type_map.c +14 -7
- data/ext/util.c +6 -6
- data/ext/util.h +2 -2
- data/lib/pg/basic_type_mapping.rb +40 -7
- data/lib/pg/binary_decoder.rb +22 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +27 -7
- data/lib/pg/constants.rb +1 -1
- data/lib/pg/exceptions.rb +1 -1
- data/lib/pg/result.rb +6 -5
- data/lib/pg/text_decoder.rb +19 -23
- data/lib/pg/text_encoder.rb +36 -2
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +1 -1
- data/lib/pg.rb +21 -11
- data/spec/helpers.rb +47 -19
- data/spec/pg/basic_type_mapping_spec.rb +230 -27
- data/spec/pg/connection_spec.rb +402 -275
- data/spec/pg/connection_sync_spec.rb +41 -0
- data/spec/pg/result_spec.rb +59 -17
- data/spec/pg/tuple_spec.rb +280 -0
- data/spec/pg/type_map_by_class_spec.rb +2 -2
- data/spec/pg/type_map_by_column_spec.rb +1 -1
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_map_by_oid_spec.rb +1 -1
- 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 +184 -12
- data/spec/pg_spec.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +47 -53
- metadata.gz.sig +0 -0
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -186
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -294
- data/sample/replication_monitor.rb +0 -231
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -320
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id: pg_connection.c,v
|
3
|
+
* $Id: pg_connection.c,v e57f6b452eb3 2018/08/18 10:58:52 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -18,19 +18,8 @@ static PQnoticeReceiver default_notice_receiver = NULL;
|
|
18
18
|
static PQnoticeProcessor default_notice_processor = NULL;
|
19
19
|
|
20
20
|
static VALUE pgconn_finish( VALUE );
|
21
|
-
#ifdef M17N_SUPPORTED
|
22
21
|
static VALUE pgconn_set_default_encoding( VALUE self );
|
23
22
|
void pgconn_set_internal_encoding_index( VALUE );
|
24
|
-
#endif
|
25
|
-
|
26
|
-
#ifndef HAVE_RB_THREAD_FD_SELECT
|
27
|
-
#define rb_fdset_t fd_set
|
28
|
-
#define rb_fd_init(f)
|
29
|
-
#define rb_fd_zero(f) FD_ZERO(f)
|
30
|
-
#define rb_fd_set(n, f) FD_SET(n, f)
|
31
|
-
#define rb_fd_term(f)
|
32
|
-
#define rb_thread_fd_select rb_thread_select
|
33
|
-
#endif
|
34
23
|
|
35
24
|
/*
|
36
25
|
* Global functions
|
@@ -95,7 +84,7 @@ pgconn_close_socket_io( VALUE self )
|
|
95
84
|
VALUE socket_io = this->socket_io;
|
96
85
|
|
97
86
|
if ( RTEST(socket_io) ) {
|
98
|
-
#if defined(_WIN32)
|
87
|
+
#if defined(_WIN32)
|
99
88
|
int ruby_sd = NUM2INT(rb_funcall( socket_io, rb_intern("fileno"), 0 ));
|
100
89
|
if( rb_w32_unwrap_io_handle(ruby_sd) ){
|
101
90
|
rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
|
@@ -209,6 +198,8 @@ pgconn_s_allocate( VALUE klass )
|
|
209
198
|
this->decoder_for_get_copy_data = Qnil;
|
210
199
|
this->trace_stream = Qnil;
|
211
200
|
this->external_encoding = Qnil;
|
201
|
+
this->socket = -1;
|
202
|
+
this->guess_result_memsize = 1;
|
212
203
|
|
213
204
|
return self;
|
214
205
|
}
|
@@ -281,7 +272,6 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
281
272
|
this = pg_get_connection( self );
|
282
273
|
conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
|
283
274
|
this->pgconn = gvl_PQconnectdb(StringValueCStr(conninfo));
|
284
|
-
|
285
275
|
if(this->pgconn == NULL)
|
286
276
|
rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate structure");
|
287
277
|
|
@@ -291,9 +281,11 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
291
281
|
rb_exc_raise(error);
|
292
282
|
}
|
293
283
|
|
294
|
-
|
284
|
+
this->socket = PQsocket( this->pgconn );
|
285
|
+
if ( this->socket < 0 )
|
286
|
+
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
287
|
+
|
295
288
|
pgconn_set_default_encoding( self );
|
296
|
-
#endif
|
297
289
|
|
298
290
|
if (rb_block_given_p()) {
|
299
291
|
return rb_ensure(rb_yield, self, pgconn_finish, self);
|
@@ -343,18 +335,21 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
343
335
|
rb_exc_raise(error);
|
344
336
|
}
|
345
337
|
|
338
|
+
this->socket = PQsocket( this->pgconn );
|
339
|
+
if ( this->socket < 0 )
|
340
|
+
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
341
|
+
|
346
342
|
if ( rb_block_given_p() ) {
|
347
343
|
return rb_ensure( rb_yield, rb_conn, pgconn_finish, rb_conn );
|
348
344
|
}
|
349
345
|
return rb_conn;
|
350
346
|
}
|
351
347
|
|
352
|
-
#ifdef HAVE_PQPING
|
353
348
|
/*
|
354
349
|
* call-seq:
|
355
|
-
* PG::Connection.ping(connection_hash) ->
|
356
|
-
* PG::Connection.ping(connection_string) ->
|
357
|
-
* PG::Connection.ping(host, port, options, tty, dbname, login, password) ->
|
350
|
+
* PG::Connection.ping(connection_hash) -> Integer
|
351
|
+
* PG::Connection.ping(connection_string) -> Integer
|
352
|
+
* PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
|
358
353
|
*
|
359
354
|
* Check server status.
|
360
355
|
*
|
@@ -367,6 +362,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
367
362
|
* could not establish connection
|
368
363
|
* [+PQPING_NO_ATTEMPT+]
|
369
364
|
* connection not attempted (bad params)
|
365
|
+
*
|
366
|
+
* Available since PostgreSQL-9.1
|
370
367
|
*/
|
371
368
|
static VALUE
|
372
369
|
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
@@ -379,7 +376,6 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
|
379
376
|
|
380
377
|
return INT2FIX((int)ping);
|
381
378
|
}
|
382
|
-
#endif
|
383
379
|
|
384
380
|
|
385
381
|
/*
|
@@ -418,16 +414,65 @@ pgconn_s_conndefaults(VALUE self)
|
|
418
414
|
}
|
419
415
|
|
420
416
|
|
417
|
+
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
421
418
|
/*
|
422
419
|
* call-seq:
|
423
|
-
*
|
420
|
+
* conn.encrypt_password( password, username, algorithm=nil ) -> String
|
424
421
|
*
|
425
|
-
* This function is intended to be used by client applications that
|
426
|
-
* send
|
427
|
-
*
|
428
|
-
*
|
422
|
+
* This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
|
423
|
+
* It is good practice not to send the original cleartext password in such a command, because it might be exposed in command logs, activity displays, and so on.
|
424
|
+
* Instead, use this function to convert the password to encrypted form before it is sent.
|
425
|
+
*
|
426
|
+
* The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
|
427
|
+
* +algorithm+ specifies the encryption algorithm to use to encrypt the password.
|
428
|
+
* Currently supported algorithms are +md5+ and +scram-sha-256+ (+on+ and +off+ are also accepted as aliases for +md5+, for compatibility with older server versions).
|
429
|
+
* Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
|
430
|
+
* If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
|
431
|
+
* That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
|
432
|
+
* If you wish to use the default algorithm for the server but want to avoid blocking, query +password_encryption+ yourself before calling #encrypt_password, and pass that value as the algorithm.
|
429
433
|
*
|
430
434
|
* Return value is the encrypted password.
|
435
|
+
* The caller can assume the string doesn't contain any special characters that would require escaping.
|
436
|
+
*
|
437
|
+
* Available since PostgreSQL-10
|
438
|
+
*/
|
439
|
+
static VALUE
|
440
|
+
pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
441
|
+
{
|
442
|
+
char *encrypted = NULL;
|
443
|
+
VALUE rval = Qnil;
|
444
|
+
VALUE password, username, algorithm;
|
445
|
+
PGconn *conn = pg_get_pgconn(self);
|
446
|
+
|
447
|
+
rb_scan_args( argc, argv, "21", &password, &username, &algorithm );
|
448
|
+
|
449
|
+
Check_Type(password, T_STRING);
|
450
|
+
Check_Type(username, T_STRING);
|
451
|
+
|
452
|
+
encrypted = gvl_PQencryptPasswordConn(conn, StringValueCStr(password), StringValueCStr(username), RTEST(algorithm) ? StringValueCStr(algorithm) : NULL);
|
453
|
+
if ( encrypted ) {
|
454
|
+
rval = rb_str_new2( encrypted );
|
455
|
+
PQfreemem( encrypted );
|
456
|
+
|
457
|
+
OBJ_INFECT( rval, password );
|
458
|
+
OBJ_INFECT( rval, username );
|
459
|
+
OBJ_INFECT( rval, algorithm );
|
460
|
+
} else {
|
461
|
+
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
462
|
+
}
|
463
|
+
|
464
|
+
return rval;
|
465
|
+
}
|
466
|
+
#endif
|
467
|
+
|
468
|
+
|
469
|
+
/*
|
470
|
+
* call-seq:
|
471
|
+
* PG::Connection.encrypt_password( password, username ) -> String
|
472
|
+
*
|
473
|
+
* This is an older, deprecated version of #encrypt_password.
|
474
|
+
* The difference is that this function always uses +md5+ as the encryption algorithm.
|
475
|
+
*
|
431
476
|
*/
|
432
477
|
static VALUE
|
433
478
|
pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
@@ -457,7 +502,7 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
457
502
|
|
458
503
|
/*
|
459
504
|
* call-seq:
|
460
|
-
* conn.connect_poll() ->
|
505
|
+
* conn.connect_poll() -> Integer
|
461
506
|
*
|
462
507
|
* Returns one of:
|
463
508
|
* [+PGRES_POLLING_READING+]
|
@@ -566,7 +611,7 @@ pgconn_reset_start(VALUE self)
|
|
566
611
|
|
567
612
|
/*
|
568
613
|
* call-seq:
|
569
|
-
* conn.reset_poll ->
|
614
|
+
* conn.reset_poll -> Integer
|
570
615
|
*
|
571
616
|
* Checks the status of a connection reset operation.
|
572
617
|
* See #connect_start and #connect_poll for
|
@@ -613,7 +658,7 @@ pgconn_user(VALUE self)
|
|
613
658
|
* call-seq:
|
614
659
|
* conn.pass()
|
615
660
|
*
|
616
|
-
* Returns the authenticated
|
661
|
+
* Returns the authenticated password.
|
617
662
|
*/
|
618
663
|
static VALUE
|
619
664
|
pgconn_pass(VALUE self)
|
@@ -686,6 +731,7 @@ pgconn_options(VALUE self)
|
|
686
731
|
*
|
687
732
|
* Returns the connection options used by a live connection.
|
688
733
|
*
|
734
|
+
* Available since PostgreSQL-9.3
|
689
735
|
*/
|
690
736
|
static VALUE
|
691
737
|
pgconn_conninfo( VALUE self )
|
@@ -805,7 +851,9 @@ pgconn_error_message(VALUE self)
|
|
805
851
|
|
806
852
|
/*
|
807
853
|
* call-seq:
|
808
|
-
* conn.socket() ->
|
854
|
+
* conn.socket() -> Integer
|
855
|
+
*
|
856
|
+
* This method is deprecated. Please use the more portable method #socket_io .
|
809
857
|
*
|
810
858
|
* Returns the socket's file descriptor for this connection.
|
811
859
|
* <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
|
@@ -815,7 +863,7 @@ pgconn_error_message(VALUE self)
|
|
815
863
|
* creates an IO that's associated with the connection object itself,
|
816
864
|
* and so won't go out of scope until the connection does.
|
817
865
|
*
|
818
|
-
* *Note:* On Windows the file descriptor is not
|
866
|
+
* *Note:* On Windows the file descriptor is not usable,
|
819
867
|
* since it can not be used to build a Ruby IO object.
|
820
868
|
*/
|
821
869
|
static VALUE
|
@@ -827,22 +875,17 @@ pgconn_socket(VALUE self)
|
|
827
875
|
return INT2NUM(sd);
|
828
876
|
}
|
829
877
|
|
830
|
-
|
831
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
832
|
-
|
833
878
|
/*
|
834
879
|
* call-seq:
|
835
880
|
* conn.socket_io() -> IO
|
836
881
|
*
|
837
|
-
* Fetch a
|
882
|
+
* Fetch a memorized IO object created from the Connection's underlying socket.
|
838
883
|
* This object can be used for IO.select to wait for events while running
|
839
884
|
* asynchronous API calls.
|
840
885
|
*
|
841
886
|
* Using this instead of #socket avoids the problem of the underlying connection
|
842
887
|
* being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt>
|
843
|
-
* goes out of scope.
|
844
|
-
*
|
845
|
-
* This method can also be used on Windows but requires Ruby-2.0+.
|
888
|
+
* goes out of scope. In contrast to #socket, it also works on Windows.
|
846
889
|
*/
|
847
890
|
static VALUE
|
848
891
|
pgconn_socket_io(VALUE self)
|
@@ -865,10 +908,8 @@ pgconn_socket_io(VALUE self)
|
|
865
908
|
|
866
909
|
socket_io = rb_funcall( rb_cIO, rb_intern("for_fd"), 1, INT2NUM(ruby_sd) );
|
867
910
|
|
868
|
-
/* Disable autoclose feature
|
869
|
-
|
870
|
-
rb_funcall( socket_io, id_autoclose, 1, Qfalse );
|
871
|
-
}
|
911
|
+
/* Disable autoclose feature */
|
912
|
+
rb_funcall( socket_io, id_autoclose, 1, Qfalse );
|
872
913
|
|
873
914
|
this->socket_io = socket_io;
|
874
915
|
}
|
@@ -876,11 +917,9 @@ pgconn_socket_io(VALUE self)
|
|
876
917
|
return socket_io;
|
877
918
|
}
|
878
919
|
|
879
|
-
#endif
|
880
|
-
|
881
920
|
/*
|
882
921
|
* call-seq:
|
883
|
-
* conn.backend_pid() ->
|
922
|
+
* conn.backend_pid() -> Integer
|
884
923
|
*
|
885
924
|
* Returns the process ID of the backend server
|
886
925
|
* process for this connection.
|
@@ -941,9 +980,9 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
|
|
941
980
|
* and the PG::Result object will automatically be cleared when the block terminates.
|
942
981
|
* In this instance, <code>conn.exec</code> returns the value of the block.
|
943
982
|
*
|
944
|
-
* #
|
983
|
+
* #sync_exec is implemented on the synchronous command processing API of libpq, whereas
|
945
984
|
* #async_exec is implemented on the asynchronous API.
|
946
|
-
* #
|
985
|
+
* #sync_exec is somewhat faster that #async_exec, but blocks any signals to be processed until
|
947
986
|
* the query is finished. This is most notably visible by a delayed reaction to Control+C.
|
948
987
|
* Both methods ensure that other threads can process while waiting for the server to
|
949
988
|
* complete the request.
|
@@ -955,8 +994,8 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
955
994
|
PGresult *result = NULL;
|
956
995
|
VALUE rb_pgresult;
|
957
996
|
|
958
|
-
/* If called with no parameters, use PQexec */
|
959
|
-
if ( argc == 1 ) {
|
997
|
+
/* If called with no or nil parameters, use PQexec for compatibility */
|
998
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
960
999
|
VALUE query_str = argv[0];
|
961
1000
|
|
962
1001
|
result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
|
@@ -967,11 +1006,10 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
967
1006
|
}
|
968
1007
|
return rb_pgresult;
|
969
1008
|
}
|
1009
|
+
pg_deprecated(("forwarding exec to exec_params is deprecated"));
|
970
1010
|
|
971
1011
|
/* Otherwise, just call #exec_params instead for backward-compatibility */
|
972
|
-
|
973
|
-
return pgconn_exec_params( argc, argv, self );
|
974
|
-
}
|
1012
|
+
return pgconn_exec_params( argc, argv, self );
|
975
1013
|
|
976
1014
|
}
|
977
1015
|
|
@@ -1234,8 +1272,8 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1234
1272
|
* Each element of the +params+ array may be either:
|
1235
1273
|
* a hash of the form:
|
1236
1274
|
* {:value => String (value of bind parameter)
|
1237
|
-
* :type =>
|
1238
|
-
* :format =>
|
1275
|
+
* :type => Integer (oid of type of bind parameter)
|
1276
|
+
* :format => Integer (0 for text, 1 for binary)
|
1239
1277
|
* }
|
1240
1278
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1241
1279
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1254,7 +1292,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1254
1292
|
* for binary.
|
1255
1293
|
*
|
1256
1294
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1257
|
-
* This will type cast the params
|
1295
|
+
* This will type cast the params from various Ruby types before transmission
|
1258
1296
|
* based on the encoders defined by the type map. When a type encoder is used
|
1259
1297
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1260
1298
|
* instead out of the hash form described above.
|
@@ -1274,14 +1312,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1274
1312
|
int resultFormat;
|
1275
1313
|
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1276
1314
|
|
1315
|
+
/* For compatibility we accept 1 to 4 parameters */
|
1277
1316
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1278
1317
|
paramsData.with_types = 1;
|
1279
1318
|
|
1280
1319
|
/*
|
1281
|
-
*
|
1282
|
-
*
|
1320
|
+
* For backward compatibility no or +nil+ for the second parameter
|
1321
|
+
* is passed to #exec
|
1283
1322
|
*/
|
1284
1323
|
if ( NIL_P(paramsData.params) ) {
|
1324
|
+
pg_deprecated(("forwarding exec_params to exec is deprecated"));
|
1285
1325
|
return pgconn_exec( 1, argv, self );
|
1286
1326
|
}
|
1287
1327
|
pgconn_query_assign_typemap( self, ¶msData );
|
@@ -1377,7 +1417,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1377
1417
|
* SQL query. Each element of the +params+ array may be either:
|
1378
1418
|
* a hash of the form:
|
1379
1419
|
* {:value => String (value of bind parameter)
|
1380
|
-
* :format =>
|
1420
|
+
* :format => Integer (0 for text, 1 for binary)
|
1381
1421
|
* }
|
1382
1422
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1383
1423
|
* { :value => <string value>, :format => 0 }
|
@@ -1390,7 +1430,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1390
1430
|
* for binary.
|
1391
1431
|
*
|
1392
1432
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1393
|
-
* This will type cast the params
|
1433
|
+
* This will type cast the params from various Ruby types before transmission
|
1394
1434
|
* based on the encoders defined by the type map. When a type encoder is used
|
1395
1435
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1396
1436
|
* instead out of the hash form described above.
|
@@ -1547,7 +1587,7 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1547
1587
|
int enc_idx;
|
1548
1588
|
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1549
1589
|
|
1550
|
-
|
1590
|
+
StringValueCStr(string);
|
1551
1591
|
enc_idx = ENCODING_GET( singleton ? string : self );
|
1552
1592
|
if( ENCODING_GET(string) != enc_idx ){
|
1553
1593
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
@@ -1646,12 +1686,13 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1646
1686
|
return ret;
|
1647
1687
|
}
|
1648
1688
|
|
1649
|
-
#ifdef HAVE_PQESCAPELITERAL
|
1650
1689
|
/*
|
1651
1690
|
* call-seq:
|
1652
1691
|
* conn.escape_literal( str ) -> String
|
1653
1692
|
*
|
1654
1693
|
* Escape an arbitrary String +str+ as a literal.
|
1694
|
+
*
|
1695
|
+
* Available since PostgreSQL-9.0
|
1655
1696
|
*/
|
1656
1697
|
static VALUE
|
1657
1698
|
pgconn_escape_literal(VALUE self, VALUE string)
|
@@ -1662,7 +1703,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1662
1703
|
VALUE result = Qnil;
|
1663
1704
|
int enc_idx = ENCODING_GET(self);
|
1664
1705
|
|
1665
|
-
|
1706
|
+
StringValueCStr(string);
|
1666
1707
|
if( ENCODING_GET(string) != enc_idx ){
|
1667
1708
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1668
1709
|
}
|
@@ -1682,9 +1723,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1682
1723
|
|
1683
1724
|
return result;
|
1684
1725
|
}
|
1685
|
-
#endif
|
1686
1726
|
|
1687
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
1688
1727
|
/*
|
1689
1728
|
* call-seq:
|
1690
1729
|
* conn.escape_identifier( str ) -> String
|
@@ -1694,6 +1733,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1694
1733
|
* This method does the same as #quote_ident with a String argument,
|
1695
1734
|
* but it doesn't support an Array argument and it makes use of libpq
|
1696
1735
|
* to process the string.
|
1736
|
+
*
|
1737
|
+
* Available since PostgreSQL-9.0
|
1697
1738
|
*/
|
1698
1739
|
static VALUE
|
1699
1740
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
@@ -1704,7 +1745,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1704
1745
|
VALUE result = Qnil;
|
1705
1746
|
int enc_idx = ENCODING_GET(self);
|
1706
1747
|
|
1707
|
-
|
1748
|
+
StringValueCStr(string);
|
1708
1749
|
if( ENCODING_GET(string) != enc_idx ){
|
1709
1750
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1710
1751
|
}
|
@@ -1724,9 +1765,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1724
1765
|
|
1725
1766
|
return result;
|
1726
1767
|
}
|
1727
|
-
#endif
|
1728
1768
|
|
1729
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
1730
1769
|
/*
|
1731
1770
|
* call-seq:
|
1732
1771
|
* conn.set_single_row_mode -> self
|
@@ -1763,6 +1802,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1763
1802
|
* end
|
1764
1803
|
* end
|
1765
1804
|
*
|
1805
|
+
* Available since PostgreSQL-9.2
|
1766
1806
|
*/
|
1767
1807
|
static VALUE
|
1768
1808
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1779,22 +1819,60 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1779
1819
|
|
1780
1820
|
return self;
|
1781
1821
|
}
|
1782
|
-
|
1822
|
+
|
1823
|
+
static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
1824
|
+
|
1825
|
+
/*
|
1826
|
+
* call-seq:
|
1827
|
+
* conn.send_query(sql) -> nil
|
1828
|
+
*
|
1829
|
+
* Sends SQL query request specified by _sql_ to PostgreSQL for
|
1830
|
+
* asynchronous processing, and immediately returns.
|
1831
|
+
* On failure, it raises a PG::Error.
|
1832
|
+
*
|
1833
|
+
* For backward compatibility, if you pass more than one parameter to this method,
|
1834
|
+
* it will call #send_query_params for you. New code should explicitly use #send_query_params if
|
1835
|
+
* argument placeholders are used.
|
1836
|
+
*
|
1837
|
+
*/
|
1838
|
+
static VALUE
|
1839
|
+
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
1840
|
+
{
|
1841
|
+
PGconn *conn = pg_get_pgconn(self);
|
1842
|
+
VALUE error;
|
1843
|
+
|
1844
|
+
/* If called with no or nil parameters, use PQexec for compatibility */
|
1845
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
1846
|
+
if(gvl_PQsendQuery(conn, pg_cstr_enc(argv[0], ENCODING_GET(self))) == 0) {
|
1847
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1848
|
+
rb_iv_set(error, "@connection", self);
|
1849
|
+
rb_exc_raise(error);
|
1850
|
+
}
|
1851
|
+
return Qnil;
|
1852
|
+
}
|
1853
|
+
|
1854
|
+
pg_deprecated(("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
|
1855
|
+
|
1856
|
+
/* If called with parameters, and optionally result_format,
|
1857
|
+
* use PQsendQueryParams
|
1858
|
+
*/
|
1859
|
+
return pgconn_send_query_params( argc, argv, self);
|
1860
|
+
}
|
1783
1861
|
|
1784
1862
|
/*
|
1785
1863
|
* call-seq:
|
1786
|
-
* conn.
|
1864
|
+
* conn.send_query_params(sql, params [, result_format [, type_map ]] ) -> nil
|
1787
1865
|
*
|
1788
1866
|
* Sends SQL query request specified by _sql_ to PostgreSQL for
|
1789
1867
|
* asynchronous processing, and immediately returns.
|
1790
1868
|
* On failure, it raises a PG::Error.
|
1791
1869
|
*
|
1792
|
-
* +params+ is an
|
1870
|
+
* +params+ is an array of the bind parameters for the SQL query.
|
1793
1871
|
* Each element of the +params+ array may be either:
|
1794
1872
|
* a hash of the form:
|
1795
1873
|
* {:value => String (value of bind parameter)
|
1796
|
-
* :type =>
|
1797
|
-
* :format =>
|
1874
|
+
* :type => Integer (oid of type of bind parameter)
|
1875
|
+
* :format => Integer (0 for text, 1 for binary)
|
1798
1876
|
* }
|
1799
1877
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1800
1878
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1813,14 +1891,14 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1813
1891
|
* for binary.
|
1814
1892
|
*
|
1815
1893
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1816
|
-
* This will type cast the params
|
1894
|
+
* This will type cast the params from various Ruby types before transmission
|
1817
1895
|
* based on the encoders defined by the type map. When a type encoder is used
|
1818
1896
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1819
1897
|
* instead out of the hash form described above.
|
1820
1898
|
*
|
1821
1899
|
*/
|
1822
1900
|
static VALUE
|
1823
|
-
|
1901
|
+
pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
1824
1902
|
{
|
1825
1903
|
PGconn *conn = pg_get_pgconn(self);
|
1826
1904
|
int result;
|
@@ -1830,23 +1908,9 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1830
1908
|
int resultFormat;
|
1831
1909
|
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1832
1910
|
|
1833
|
-
rb_scan_args(argc, argv, "
|
1911
|
+
rb_scan_args(argc, argv, "22", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1834
1912
|
paramsData.with_types = 1;
|
1835
1913
|
|
1836
|
-
/* If called with no parameters, use PQsendQuery */
|
1837
|
-
if(NIL_P(paramsData.params)) {
|
1838
|
-
if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
|
1839
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1840
|
-
rb_iv_set(error, "@connection", self);
|
1841
|
-
rb_exc_raise(error);
|
1842
|
-
}
|
1843
|
-
return Qnil;
|
1844
|
-
}
|
1845
|
-
|
1846
|
-
/* If called with parameters, and optionally result_format,
|
1847
|
-
* use PQsendQueryParams
|
1848
|
-
*/
|
1849
|
-
|
1850
1914
|
pgconn_query_assign_typemap( self, ¶msData );
|
1851
1915
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1852
1916
|
nParams = alloc_query_params( ¶msData );
|
@@ -1940,7 +2004,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1940
2004
|
* SQL query. Each element of the +params+ array may be either:
|
1941
2005
|
* a hash of the form:
|
1942
2006
|
* {:value => String (value of bind parameter)
|
1943
|
-
* :format =>
|
2007
|
+
* :format => Integer (0 for text, 1 for binary)
|
1944
2008
|
* }
|
1945
2009
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1946
2010
|
* { :value => <string value>, :format => 0 }
|
@@ -1953,7 +2017,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1953
2017
|
* for binary.
|
1954
2018
|
*
|
1955
2019
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1956
|
-
* This will type cast the params
|
2020
|
+
* This will type cast the params from various Ruby types before transmission
|
1957
2021
|
* based on the encoders defined by the type map. When a type encoder is used
|
1958
2022
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1959
2023
|
* instead out of the hash form described above.
|
@@ -2203,7 +2267,6 @@ pgconn_flush(self)
|
|
2203
2267
|
static VALUE
|
2204
2268
|
pgconn_cancel(VALUE self)
|
2205
2269
|
{
|
2206
|
-
#ifdef HAVE_PQGETCANCEL
|
2207
2270
|
char errbuf[256];
|
2208
2271
|
PGcancel *cancel;
|
2209
2272
|
VALUE retval;
|
@@ -2221,9 +2284,6 @@ pgconn_cancel(VALUE self)
|
|
2221
2284
|
|
2222
2285
|
PQfreeCancel(cancel);
|
2223
2286
|
return retval;
|
2224
|
-
#else
|
2225
|
-
rb_notimplement();
|
2226
|
-
#endif
|
2227
2287
|
}
|
2228
2288
|
|
2229
2289
|
|
@@ -2267,69 +2327,25 @@ pgconn_notifies(VALUE self)
|
|
2267
2327
|
return hash;
|
2268
2328
|
}
|
2269
2329
|
|
2270
|
-
/* Win32 + Ruby 1.8 */
|
2271
|
-
#if !defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
|
2272
|
-
|
2273
|
-
/*
|
2274
|
-
* Duplicate the sockets from libpq and create temporary CRT FDs
|
2275
|
-
*/
|
2276
|
-
void create_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2277
|
-
{
|
2278
|
-
int i;
|
2279
|
-
crt_set->fd_count = os_set->fd_count;
|
2280
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2281
|
-
WSAPROTOCOL_INFO wsa_pi;
|
2282
|
-
/* dupicate the SOCKET */
|
2283
|
-
int r = WSADuplicateSocket(os_set->fd_array[i], GetCurrentProcessId(), &wsa_pi);
|
2284
|
-
SOCKET s = WSASocket(wsa_pi.iAddressFamily, wsa_pi.iSocketType, wsa_pi.iProtocol, &wsa_pi, 0, 0);
|
2285
|
-
/* create the CRT fd so ruby can get back to the SOCKET */
|
2286
|
-
int fd = _open_osfhandle(s, O_RDWR|O_BINARY);
|
2287
|
-
os_set->fd_array[i] = s;
|
2288
|
-
crt_set->fd_array[i] = fd;
|
2289
|
-
}
|
2290
|
-
}
|
2291
|
-
|
2292
|
-
/*
|
2293
|
-
* Clean up the CRT FDs from create_crt_fd()
|
2294
|
-
*/
|
2295
|
-
void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2296
|
-
{
|
2297
|
-
int i;
|
2298
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2299
|
-
/* cleanup the CRT fd */
|
2300
|
-
_close(crt_set->fd_array[i]);
|
2301
|
-
/* cleanup the duplicated SOCKET */
|
2302
|
-
closesocket(os_set->fd_array[i]);
|
2303
|
-
}
|
2304
|
-
}
|
2305
|
-
#endif
|
2306
|
-
|
2307
2330
|
/* Win32 + Ruby 1.9+ */
|
2308
|
-
#if defined(
|
2331
|
+
#if defined( _WIN32 )
|
2309
2332
|
/*
|
2310
2333
|
* On Windows, use platform-specific strategies to wait for the socket
|
2311
|
-
* instead of
|
2334
|
+
* instead of rb_wait_for_single_fd().
|
2312
2335
|
*/
|
2313
2336
|
|
2314
2337
|
int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
2315
2338
|
|
2316
|
-
/* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
|
2317
|
-
* and does not wait (nor sleep) any time even if timeout is given.
|
2318
|
-
* Instead use the Winsock events and rb_w32_wait_events(). */
|
2319
|
-
|
2320
2339
|
static void *
|
2321
|
-
wait_socket_readable(
|
2340
|
+
wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
|
2322
2341
|
{
|
2323
|
-
|
2342
|
+
PGconn *conn = this->pgconn;
|
2324
2343
|
void *retval;
|
2325
2344
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2326
2345
|
DWORD timeout_milisec = INFINITE;
|
2327
2346
|
DWORD wait_ret;
|
2328
2347
|
WSAEVENT hEvent;
|
2329
2348
|
|
2330
|
-
if ( sd < 0 )
|
2331
|
-
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
2332
|
-
|
2333
2349
|
hEvent = WSACreateEvent();
|
2334
2350
|
|
2335
2351
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
@@ -2344,7 +2360,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2344
2360
|
}
|
2345
2361
|
|
2346
2362
|
while ( !(retval=is_readable(conn)) ) {
|
2347
|
-
if ( WSAEventSelect(
|
2363
|
+
if ( WSAEventSelect(this->socket, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
|
2348
2364
|
WSACloseEvent( hEvent );
|
2349
2365
|
rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
|
2350
2366
|
}
|
@@ -2393,46 +2409,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2393
2409
|
|
2394
2410
|
#else
|
2395
2411
|
|
2396
|
-
/* non Win32
|
2412
|
+
/* non Win32 */
|
2397
2413
|
|
2398
2414
|
static void *
|
2399
|
-
wait_socket_readable(
|
2415
|
+
wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
|
2400
2416
|
{
|
2401
|
-
|
2417
|
+
PGconn *conn = this->pgconn;
|
2402
2418
|
int ret;
|
2403
2419
|
void *retval;
|
2404
|
-
rb_fdset_t sd_rset;
|
2405
2420
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2406
|
-
#ifdef _WIN32
|
2407
|
-
rb_fdset_t crt_sd_rset;
|
2408
|
-
#endif
|
2409
|
-
|
2410
|
-
if ( sd < 0 )
|
2411
|
-
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
2412
2421
|
|
2413
2422
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
2414
2423
|
if ( PQconsumeInput(conn) == 0 )
|
2415
2424
|
rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
|
2416
2425
|
|
2417
|
-
rb_fd_init( &sd_rset );
|
2418
|
-
|
2419
2426
|
if ( ptimeout ) {
|
2420
2427
|
gettimeofday(&currtime, NULL);
|
2421
2428
|
timeradd(&currtime, ptimeout, &aborttime);
|
2422
2429
|
}
|
2423
2430
|
|
2424
2431
|
while ( !(retval=is_readable(conn)) ) {
|
2425
|
-
rb_fd_zero( &sd_rset );
|
2426
|
-
rb_fd_set( sd, &sd_rset );
|
2427
|
-
|
2428
|
-
#ifdef _WIN32
|
2429
|
-
/* Ruby's FD_SET is modified on win32 to convert a file descriptor
|
2430
|
-
* to osfhandle, but we already get a osfhandle from PQsocket().
|
2431
|
-
* Therefore it's overwritten here. */
|
2432
|
-
sd_rset.fd_array[0] = sd;
|
2433
|
-
create_crt_fd(&sd_rset, &crt_sd_rset);
|
2434
|
-
#endif
|
2435
|
-
|
2436
2432
|
if ( ptimeout ) {
|
2437
2433
|
gettimeofday(&currtime, NULL);
|
2438
2434
|
timersub(&aborttime, &currtime, &waittime);
|
@@ -2441,35 +2437,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2441
2437
|
/* Is the given timeout valid? */
|
2442
2438
|
if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
|
2443
2439
|
/* Wait for the socket to become readable before checking again */
|
2444
|
-
ret =
|
2440
|
+
ret = rb_wait_for_single_fd( this->socket, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
|
2445
2441
|
} else {
|
2446
2442
|
ret = 0;
|
2447
2443
|
}
|
2448
2444
|
|
2449
|
-
|
2450
|
-
#ifdef _WIN32
|
2451
|
-
cleanup_crt_fd(&sd_rset, &crt_sd_rset);
|
2452
|
-
#endif
|
2453
|
-
|
2454
2445
|
if ( ret < 0 ){
|
2455
|
-
|
2456
|
-
rb_sys_fail( "rb_thread_select()" );
|
2446
|
+
rb_sys_fail( "rb_wait_for_single_fd()" );
|
2457
2447
|
}
|
2458
2448
|
|
2459
2449
|
/* Return false if the select() timed out */
|
2460
2450
|
if ( ret == 0 ){
|
2461
|
-
rb_fd_term( &sd_rset );
|
2462
2451
|
return NULL;
|
2463
2452
|
}
|
2464
2453
|
|
2465
2454
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
2466
2455
|
if ( PQconsumeInput(conn) == 0 ){
|
2467
|
-
rb_fd_term( &sd_rset );
|
2468
2456
|
rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
|
2469
2457
|
}
|
2470
2458
|
}
|
2471
2459
|
|
2472
|
-
rb_fd_term( &sd_rset );
|
2473
2460
|
return retval;
|
2474
2461
|
}
|
2475
2462
|
|
@@ -2484,27 +2471,20 @@ notify_readable(PGconn *conn)
|
|
2484
2471
|
|
2485
2472
|
/*
|
2486
2473
|
* call-seq:
|
2487
|
-
* conn.wait_for_notify( [ timeout ] ) -> String
|
2488
|
-
* conn.wait_for_notify( [ timeout ] ) { |event, pid| block }
|
2489
|
-
* conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } # PostgreSQL 9.0
|
2474
|
+
* conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } -> String
|
2490
2475
|
*
|
2491
2476
|
* Blocks while waiting for notification(s), or until the optional
|
2492
2477
|
* _timeout_ is reached, whichever comes first. _timeout_ is
|
2493
2478
|
* measured in seconds and can be fractional.
|
2494
2479
|
*
|
2495
|
-
* Returns +nil+ if _timeout_ is reached, the name of the NOTIFY
|
2496
|
-
*
|
2497
|
-
*
|
2498
|
-
*
|
2499
|
-
* Under PostgreSQL 9.0 and later, if the notification is sent with
|
2500
|
-
* the optional +payload+ string, it will be given to the block as the
|
2501
|
-
* third argument.
|
2502
|
-
*
|
2480
|
+
* Returns +nil+ if _timeout_ is reached, the name of the NOTIFY event otherwise.
|
2481
|
+
* If used in block form, passes the name of the NOTIFY +event+, the generating
|
2482
|
+
* +pid+ and the optional +payload+ string into the block.
|
2503
2483
|
*/
|
2504
2484
|
static VALUE
|
2505
2485
|
pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
2506
2486
|
{
|
2507
|
-
|
2487
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2508
2488
|
PGnotify *pnotification;
|
2509
2489
|
struct timeval timeout;
|
2510
2490
|
struct timeval *ptimeout = NULL;
|
@@ -2520,7 +2500,7 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2520
2500
|
ptimeout = &timeout;
|
2521
2501
|
}
|
2522
2502
|
|
2523
|
-
pnotification = (PGnotify*) wait_socket_readable(
|
2503
|
+
pnotification = (PGnotify*) wait_socket_readable( this, ptimeout, notify_readable);
|
2524
2504
|
|
2525
2505
|
/* Return nil if the select timed out */
|
2526
2506
|
if ( !pnotification ) return Qnil;
|
@@ -2528,12 +2508,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2528
2508
|
relname = rb_tainted_str_new2( pnotification->relname );
|
2529
2509
|
PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
|
2530
2510
|
be_pid = INT2NUM( pnotification->be_pid );
|
2531
|
-
#ifdef HAVE_ST_NOTIFY_EXTRA
|
2532
2511
|
if ( *pnotification->extra ) {
|
2533
2512
|
extra = rb_tainted_str_new2( pnotification->extra );
|
2534
2513
|
PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
|
2535
2514
|
}
|
2536
|
-
#endif
|
2537
2515
|
PQfreemem( pnotification );
|
2538
2516
|
|
2539
2517
|
if ( rb_block_given_p() )
|
@@ -2552,9 +2530,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2552
2530
|
* not sent (false is only possible if the connection
|
2553
2531
|
* is in nonblocking mode, and this command would block).
|
2554
2532
|
*
|
2555
|
-
*
|
2556
|
-
* This encodes the
|
2557
|
-
*
|
2533
|
+
* _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
|
2534
|
+
* This encodes the data fields given as _buffer_ from an Array of Strings to
|
2535
|
+
* PostgreSQL's COPY text format inclusive proper escaping. Optionally
|
2536
|
+
* the encoder can type cast the fields from various Ruby types in one step,
|
2558
2537
|
* if PG::TextEncoder::CopyRow#type_map is set accordingly.
|
2559
2538
|
*
|
2560
2539
|
* Raises an exception if an error occurs.
|
@@ -2659,15 +2638,18 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2659
2638
|
|
2660
2639
|
/*
|
2661
2640
|
* call-seq:
|
2662
|
-
* conn.get_copy_data( [ async = false [, decoder = nil ]] ) ->
|
2641
|
+
* conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
|
2663
2642
|
*
|
2664
|
-
* Return
|
2643
|
+
* Return one row of data, +nil+
|
2665
2644
|
* if the copy is done, or +false+ if the call would
|
2666
2645
|
* block (only possible if _async_ is true).
|
2667
2646
|
*
|
2668
|
-
*
|
2669
|
-
*
|
2670
|
-
*
|
2647
|
+
* If _decoder_ is not set or +nil+, data is returned as binary string.
|
2648
|
+
*
|
2649
|
+
* If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
|
2650
|
+
* PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
|
2651
|
+
* COPY text format to an Array of Strings.
|
2652
|
+
* Optionally the decoder can type cast the single fields to various Ruby types in one step,
|
2671
2653
|
* if PG::TextDecoder::CopyRow#type_map is set accordingly.
|
2672
2654
|
*
|
2673
2655
|
* See also #copy_data.
|
@@ -2724,7 +2706,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2724
2706
|
|
2725
2707
|
/*
|
2726
2708
|
* call-seq:
|
2727
|
-
* conn.set_error_verbosity( verbosity ) ->
|
2709
|
+
* conn.set_error_verbosity( verbosity ) -> Integer
|
2728
2710
|
*
|
2729
2711
|
* Sets connection's verbosity to _verbosity_ and returns
|
2730
2712
|
* the previous setting. Available settings are:
|
@@ -2968,11 +2950,9 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
|
|
2968
2950
|
Check_Type(str, T_STRING);
|
2969
2951
|
|
2970
2952
|
if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
|
2971
|
-
rb_raise(rb_ePGerror, "
|
2953
|
+
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
2972
2954
|
}
|
2973
|
-
#ifdef M17N_SUPPORTED
|
2974
2955
|
pgconn_set_internal_encoding_index( self );
|
2975
|
-
#endif
|
2976
2956
|
|
2977
2957
|
return Qnil;
|
2978
2958
|
}
|
@@ -3098,11 +3078,7 @@ get_result_readable(PGconn *conn)
|
|
3098
3078
|
*/
|
3099
3079
|
static VALUE
|
3100
3080
|
pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
3101
|
-
|
3102
|
-
|
3103
|
-
/* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
|
3104
|
-
* and does not wait (nor sleep) any time even if timeout is given.
|
3105
|
-
* Instead use the Winsock events and rb_w32_wait_events(). */
|
3081
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
3106
3082
|
|
3107
3083
|
struct timeval timeout;
|
3108
3084
|
struct timeval *ptimeout = NULL;
|
@@ -3117,7 +3093,7 @@ pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
|
3117
3093
|
ptimeout = &timeout;
|
3118
3094
|
}
|
3119
3095
|
|
3120
|
-
ret = wait_socket_readable(
|
3096
|
+
ret = wait_socket_readable( this, ptimeout, get_result_readable);
|
3121
3097
|
|
3122
3098
|
if( !ret )
|
3123
3099
|
return Qfalse;
|
@@ -3170,24 +3146,89 @@ pgconn_get_last_result(VALUE self)
|
|
3170
3146
|
|
3171
3147
|
/*
|
3172
3148
|
* call-seq:
|
3173
|
-
* conn.
|
3174
|
-
* conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
|
3149
|
+
* conn.discard_results()
|
3175
3150
|
*
|
3176
|
-
*
|
3151
|
+
* Silently discard any prior query result that application didn't eat.
|
3152
|
+
* This is done prior of Connection#exec and sibling methods and can
|
3153
|
+
* be called explicitly when using the async API.
|
3154
|
+
*/
|
3155
|
+
static VALUE
|
3156
|
+
pgconn_discard_results(VALUE self)
|
3157
|
+
{
|
3158
|
+
PGconn *conn = pg_get_pgconn(self);
|
3159
|
+
|
3160
|
+
PGresult *cur;
|
3161
|
+
while ((cur = gvl_PQgetResult(conn)) != NULL) {
|
3162
|
+
int status = PQresultStatus(cur);
|
3163
|
+
PQclear(cur);
|
3164
|
+
if (status == PGRES_COPY_IN){
|
3165
|
+
gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
|
3166
|
+
}
|
3167
|
+
if (status == PGRES_COPY_OUT){
|
3168
|
+
char *buffer = NULL;
|
3169
|
+
while( gvl_PQgetCopyData(conn, &buffer, 0) > 0)
|
3170
|
+
PQfreemem(buffer);
|
3171
|
+
}
|
3172
|
+
}
|
3173
|
+
|
3174
|
+
return Qnil;
|
3175
|
+
}
|
3176
|
+
|
3177
|
+
/*
|
3178
|
+
* call-seq:
|
3179
|
+
* conn.async_exec(sql) -> PG::Result
|
3180
|
+
* conn.async_exec(sql) {|pg_result| block }
|
3181
|
+
*
|
3182
|
+
* This function has the same behavior as #sync_exec,
|
3177
3183
|
* but is implemented using the asynchronous command
|
3178
3184
|
* processing API of libpq.
|
3185
|
+
*
|
3186
|
+
* Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
|
3187
|
+
* However #async_exec has two advantages:
|
3188
|
+
*
|
3189
|
+
* 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
|
3190
|
+
* 2. Ruby VM gets notified about IO blocked operations.
|
3191
|
+
* It can therefore schedule thing like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
|
3179
3192
|
*/
|
3180
3193
|
static VALUE
|
3181
3194
|
pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
3182
3195
|
{
|
3183
3196
|
VALUE rb_pgresult = Qnil;
|
3184
3197
|
|
3185
|
-
|
3198
|
+
pgconn_discard_results( self );
|
3199
|
+
pgconn_send_query( argc, argv, self );
|
3186
3200
|
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3187
|
-
pgconn_get_last_result( self );
|
3201
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3188
3202
|
|
3189
|
-
|
3190
|
-
|
3203
|
+
if ( rb_block_given_p() ) {
|
3204
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3205
|
+
}
|
3206
|
+
return rb_pgresult;
|
3207
|
+
}
|
3208
|
+
|
3209
|
+
|
3210
|
+
/*
|
3211
|
+
* call-seq:
|
3212
|
+
* conn.async_exec_params(sql, params [, result_format [, type_map ]] ) -> nil
|
3213
|
+
* conn.async_exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
|
3214
|
+
*
|
3215
|
+
* This function has the same behavior as #sync_exec_params, but is implemented using the asynchronous command processing API of libpq.
|
3216
|
+
* See #async_exec for the differences between the two API variants.
|
3217
|
+
*/
|
3218
|
+
static VALUE
|
3219
|
+
pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
3220
|
+
{
|
3221
|
+
VALUE rb_pgresult = Qnil;
|
3222
|
+
|
3223
|
+
pgconn_discard_results( self );
|
3224
|
+
/* If called with no or nil parameters, use PQsendQuery for compatibility */
|
3225
|
+
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
3226
|
+
pg_deprecated(("forwarding async_exec_params to async_exec is deprecated"));
|
3227
|
+
pgconn_send_query( argc, argv, self );
|
3228
|
+
} else {
|
3229
|
+
pgconn_send_query_params( argc, argv, self );
|
3230
|
+
}
|
3231
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3191
3232
|
rb_pgresult = pgconn_get_last_result( self );
|
3192
3233
|
|
3193
3234
|
if ( rb_block_given_p() ) {
|
@@ -3197,15 +3238,111 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3197
3238
|
}
|
3198
3239
|
|
3199
3240
|
|
3200
|
-
|
3201
|
-
|
3241
|
+
/*
|
3242
|
+
* call-seq:
|
3243
|
+
* conn.async_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
3244
|
+
*
|
3245
|
+
* This function has the same behavior as #sync_prepare, but is implemented using the asynchronous command processing API of libpq.
|
3246
|
+
* See #async_exec for the differences between the two API variants.
|
3247
|
+
*/
|
3248
|
+
static VALUE
|
3249
|
+
pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
3250
|
+
{
|
3251
|
+
VALUE rb_pgresult = Qnil;
|
3252
|
+
|
3253
|
+
pgconn_discard_results( self );
|
3254
|
+
pgconn_send_prepare( argc, argv, self );
|
3255
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3256
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3257
|
+
|
3258
|
+
if ( rb_block_given_p() ) {
|
3259
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3260
|
+
}
|
3261
|
+
return rb_pgresult;
|
3262
|
+
}
|
3263
|
+
|
3264
|
+
|
3265
|
+
/*
|
3266
|
+
* call-seq:
|
3267
|
+
* conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
|
3268
|
+
* conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
|
3269
|
+
*
|
3270
|
+
* This function has the same behavior as #sync_exec_prepared, but is implemented using the asynchronous command processing API of libpq.
|
3271
|
+
* See #async_exec for the differences between the two API variants.
|
3272
|
+
*/
|
3273
|
+
static VALUE
|
3274
|
+
pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
3275
|
+
{
|
3276
|
+
VALUE rb_pgresult = Qnil;
|
3277
|
+
|
3278
|
+
pgconn_discard_results( self );
|
3279
|
+
pgconn_send_query_prepared( argc, argv, self );
|
3280
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3281
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3282
|
+
|
3283
|
+
if ( rb_block_given_p() ) {
|
3284
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3285
|
+
}
|
3286
|
+
return rb_pgresult;
|
3287
|
+
}
|
3288
|
+
|
3202
3289
|
|
3290
|
+
/*
|
3291
|
+
* call-seq:
|
3292
|
+
* conn.async_describe_portal( portal_name ) -> PG::Result
|
3293
|
+
*
|
3294
|
+
* This function has the same behavior as #sync_describe_portal, but is implemented using the asynchronous command processing API of libpq.
|
3295
|
+
* See #async_exec for the differences between the two API variants.
|
3296
|
+
*/
|
3297
|
+
static VALUE
|
3298
|
+
pgconn_async_describe_portal(VALUE self, VALUE portal)
|
3299
|
+
{
|
3300
|
+
VALUE rb_pgresult = Qnil;
|
3301
|
+
|
3302
|
+
pgconn_discard_results( self );
|
3303
|
+
pgconn_send_describe_portal( self, portal );
|
3304
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3305
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3306
|
+
|
3307
|
+
if ( rb_block_given_p() ) {
|
3308
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3309
|
+
}
|
3310
|
+
return rb_pgresult;
|
3311
|
+
}
|
3312
|
+
|
3313
|
+
|
3314
|
+
/*
|
3315
|
+
* call-seq:
|
3316
|
+
* conn.async_describe_prepared( statement_name ) -> PG::Result
|
3317
|
+
*
|
3318
|
+
* This function has the same behavior as #sync_describe_prepared, but is implemented using the asynchronous command processing API of libpq.
|
3319
|
+
* See #async_exec for the differences between the two API variants.
|
3320
|
+
*/
|
3321
|
+
static VALUE
|
3322
|
+
pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
3323
|
+
{
|
3324
|
+
VALUE rb_pgresult = Qnil;
|
3325
|
+
|
3326
|
+
pgconn_discard_results( self );
|
3327
|
+
pgconn_send_describe_prepared( self, stmt_name );
|
3328
|
+
pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
|
3329
|
+
rb_pgresult = pgconn_get_last_result( self );
|
3330
|
+
|
3331
|
+
if ( rb_block_given_p() ) {
|
3332
|
+
return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
|
3333
|
+
}
|
3334
|
+
return rb_pgresult;
|
3335
|
+
}
|
3336
|
+
|
3337
|
+
|
3338
|
+
#ifdef HAVE_PQSSLATTRIBUTE
|
3203
3339
|
/*
|
3204
3340
|
* call-seq:
|
3205
3341
|
* conn.ssl_in_use? -> Boolean
|
3206
3342
|
*
|
3207
3343
|
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3208
3344
|
*
|
3345
|
+
* Available since PostgreSQL-9.5
|
3209
3346
|
*/
|
3210
3347
|
static VALUE
|
3211
3348
|
pgconn_ssl_in_use(VALUE self)
|
@@ -3238,6 +3375,8 @@ pgconn_ssl_in_use(VALUE self)
|
|
3238
3375
|
*
|
3239
3376
|
*
|
3240
3377
|
* See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
|
3378
|
+
*
|
3379
|
+
* Available since PostgreSQL-9.5
|
3241
3380
|
*/
|
3242
3381
|
static VALUE
|
3243
3382
|
pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
@@ -3256,6 +3395,7 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
|
3256
3395
|
*
|
3257
3396
|
* See also #ssl_attribute
|
3258
3397
|
*
|
3398
|
+
* Available since PostgreSQL-9.5
|
3259
3399
|
*/
|
3260
3400
|
static VALUE
|
3261
3401
|
pgconn_ssl_attribute_names(VALUE self)
|
@@ -3280,7 +3420,7 @@ pgconn_ssl_attribute_names(VALUE self)
|
|
3280
3420
|
|
3281
3421
|
/*
|
3282
3422
|
* call-seq:
|
3283
|
-
* conn.lo_creat( [mode] ) ->
|
3423
|
+
* conn.lo_creat( [mode] ) -> Integer
|
3284
3424
|
*
|
3285
3425
|
* Creates a large object with mode _mode_. Returns a large object Oid.
|
3286
3426
|
* On failure, it raises PG::Error.
|
@@ -3307,7 +3447,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
|
3307
3447
|
|
3308
3448
|
/*
|
3309
3449
|
* call-seq:
|
3310
|
-
* conn.lo_create( oid ) ->
|
3450
|
+
* conn.lo_create( oid ) -> Integer
|
3311
3451
|
*
|
3312
3452
|
* Creates a large object with oid _oid_. Returns the large object Oid.
|
3313
3453
|
* On failure, it raises PG::Error.
|
@@ -3328,7 +3468,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
|
3328
3468
|
|
3329
3469
|
/*
|
3330
3470
|
* call-seq:
|
3331
|
-
* conn.lo_import(file) ->
|
3471
|
+
* conn.lo_import(file) -> Integer
|
3332
3472
|
*
|
3333
3473
|
* Import a file to a large object. Returns a large object Oid.
|
3334
3474
|
*
|
@@ -3373,7 +3513,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
|
|
3373
3513
|
|
3374
3514
|
/*
|
3375
3515
|
* call-seq:
|
3376
|
-
* conn.lo_open( oid, [mode] ) ->
|
3516
|
+
* conn.lo_open( oid, [mode] ) -> Integer
|
3377
3517
|
*
|
3378
3518
|
* Open a large object of _oid_. Returns a large object descriptor
|
3379
3519
|
* instance on success. The _mode_ argument specifies the mode for
|
@@ -3404,7 +3544,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
|
|
3404
3544
|
|
3405
3545
|
/*
|
3406
3546
|
* call-seq:
|
3407
|
-
* conn.lo_write( lo_desc, buffer ) ->
|
3547
|
+
* conn.lo_write( lo_desc, buffer ) -> Integer
|
3408
3548
|
*
|
3409
3549
|
* Writes the string _buffer_ to the large object _lo_desc_.
|
3410
3550
|
* Returns the number of bytes written.
|
@@ -3471,7 +3611,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3471
3611
|
|
3472
3612
|
/*
|
3473
3613
|
* call-seq:
|
3474
|
-
* conn.lo_lseek( lo_desc, offset, whence ) ->
|
3614
|
+
* conn.lo_lseek( lo_desc, offset, whence ) -> Integer
|
3475
3615
|
*
|
3476
3616
|
* Move the large object pointer _lo_desc_ to offset _offset_.
|
3477
3617
|
* Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
|
@@ -3493,7 +3633,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
|
|
3493
3633
|
|
3494
3634
|
/*
|
3495
3635
|
* call-seq:
|
3496
|
-
* conn.lo_tell( lo_desc ) ->
|
3636
|
+
* conn.lo_tell( lo_desc ) -> Integer
|
3497
3637
|
*
|
3498
3638
|
* Returns the current position of the large object _lo_desc_.
|
3499
3639
|
*/
|
@@ -3566,8 +3706,6 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3566
3706
|
}
|
3567
3707
|
|
3568
3708
|
|
3569
|
-
#ifdef M17N_SUPPORTED
|
3570
|
-
|
3571
3709
|
void
|
3572
3710
|
pgconn_set_internal_encoding_index( VALUE self )
|
3573
3711
|
{
|
@@ -3718,7 +3856,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3718
3856
|
if (( enc = rb_default_internal_encoding() )) {
|
3719
3857
|
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3720
3858
|
if ( pgconn_set_client_encoding_async(self, encname) != 0 )
|
3721
|
-
|
3859
|
+
rb_warning( "Failed to set the default_internal encoding to %s: '%s'",
|
3722
3860
|
encname, PQerrorMessage(conn) );
|
3723
3861
|
pgconn_set_internal_encoding_index( self );
|
3724
3862
|
return rb_enc_from_encoding( enc );
|
@@ -3729,8 +3867,6 @@ pgconn_set_default_encoding( VALUE self )
|
|
3729
3867
|
}
|
3730
3868
|
|
3731
3869
|
|
3732
|
-
#endif /* M17N_SUPPORTED */
|
3733
|
-
|
3734
3870
|
/*
|
3735
3871
|
* call-seq:
|
3736
3872
|
* res.type_map_for_queries = typemap
|
@@ -3909,6 +4045,20 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
3909
4045
|
return this->decoder_for_get_copy_data;
|
3910
4046
|
}
|
3911
4047
|
|
4048
|
+
/*
|
4049
|
+
* call-seq:
|
4050
|
+
* res.guess_result_memsize = enabled
|
4051
|
+
*
|
4052
|
+
* This method is for testing only and will probably be removed in the future.
|
4053
|
+
*/
|
4054
|
+
static VALUE
|
4055
|
+
pgconn_guess_result_memsize_set(VALUE self, VALUE enable)
|
4056
|
+
{
|
4057
|
+
t_pg_connection *this = pg_get_connection( self );
|
4058
|
+
this->guess_result_memsize = RTEST(enable);
|
4059
|
+
return enable;
|
4060
|
+
}
|
4061
|
+
|
3912
4062
|
|
3913
4063
|
/*
|
3914
4064
|
* Document-class: PG::Connection
|
@@ -3939,9 +4089,7 @@ init_pg_connection()
|
|
3939
4089
|
rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
3940
4090
|
rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
|
3941
4091
|
rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
|
3942
|
-
#ifdef HAVE_PQPING
|
3943
4092
|
rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
|
3944
|
-
#endif
|
3945
4093
|
|
3946
4094
|
/****** PG::Connection INSTANCE METHODS: Connection Control ******/
|
3947
4095
|
rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
|
@@ -3971,43 +4119,42 @@ init_pg_connection()
|
|
3971
4119
|
rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
|
3972
4120
|
rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
|
3973
4121
|
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
|
3974
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
3975
4122
|
rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
|
3976
|
-
#endif
|
3977
4123
|
rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
|
3978
4124
|
rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
|
3979
4125
|
rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
|
3980
4126
|
/* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
|
3981
4127
|
|
3982
4128
|
/****** PG::Connection INSTANCE METHODS: Command Execution ******/
|
3983
|
-
rb_define_method(rb_cPGconn, "
|
3984
|
-
|
3985
|
-
rb_define_method(rb_cPGconn, "
|
3986
|
-
rb_define_method(rb_cPGconn, "
|
3987
|
-
rb_define_method(rb_cPGconn, "
|
3988
|
-
rb_define_method(rb_cPGconn, "
|
3989
|
-
rb_define_method(rb_cPGconn, "describe_portal", pgconn_describe_portal, 1);
|
4129
|
+
rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
|
4130
|
+
rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
|
4131
|
+
rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
|
4132
|
+
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
|
4133
|
+
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
|
4134
|
+
rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
|
3990
4135
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
3991
4136
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
3992
4137
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
3993
|
-
#ifdef HAVE_PQESCAPELITERAL
|
3994
4138
|
rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
|
3995
|
-
#endif
|
3996
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
3997
4139
|
rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
|
3998
|
-
#endif
|
3999
4140
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
4000
4141
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
4001
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
4002
4142
|
rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
|
4003
|
-
#endif
|
4004
4143
|
|
4005
4144
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
4006
4145
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
4146
|
+
rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
|
4147
|
+
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
4148
|
+
rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
|
4149
|
+
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4007
4150
|
rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
|
4151
|
+
rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
|
4008
4152
|
rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
|
4153
|
+
rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
|
4009
4154
|
rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
|
4155
|
+
rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
|
4010
4156
|
rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
|
4157
|
+
rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
|
4011
4158
|
rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
|
4012
4159
|
rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
|
4013
4160
|
rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
|
@@ -4015,6 +4162,7 @@ init_pg_connection()
|
|
4015
4162
|
rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
|
4016
4163
|
rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
|
4017
4164
|
rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
|
4165
|
+
rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
|
4018
4166
|
|
4019
4167
|
/****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
|
4020
4168
|
rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
|
@@ -4031,6 +4179,7 @@ init_pg_connection()
|
|
4031
4179
|
rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
|
4032
4180
|
rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
|
4033
4181
|
rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
|
4182
|
+
rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
|
4034
4183
|
|
4035
4184
|
/****** PG::Connection INSTANCE METHODS: Notice Processing ******/
|
4036
4185
|
rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
|
@@ -4045,9 +4194,10 @@ init_pg_connection()
|
|
4045
4194
|
rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
|
4046
4195
|
rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
|
4047
4196
|
rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
4048
|
-
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
4049
|
-
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4050
4197
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
|
4198
|
+
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
4199
|
+
rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
|
4200
|
+
#endif
|
4051
4201
|
|
4052
4202
|
#ifdef HAVE_PQSSLATTRIBUTE
|
4053
4203
|
rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
|
@@ -4083,12 +4233,10 @@ init_pg_connection()
|
|
4083
4233
|
rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
|
4084
4234
|
rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
|
4085
4235
|
|
4086
|
-
#ifdef M17N_SUPPORTED
|
4087
4236
|
rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
|
4088
4237
|
rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
|
4089
4238
|
rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
|
4090
4239
|
rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
|
4091
|
-
#endif /* M17N_SUPPORTED */
|
4092
4240
|
|
4093
4241
|
rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
|
4094
4242
|
rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);
|