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.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/ChangeLog +218 -1
  4. data/History.rdoc +106 -0
  5. data/Manifest.txt +5 -18
  6. data/README.rdoc +15 -5
  7. data/Rakefile +8 -9
  8. data/Rakefile.cross +19 -22
  9. data/ext/errorcodes.def +17 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +11 -1
  12. data/ext/extconf.rb +14 -32
  13. data/ext/gvl_wrappers.c +4 -0
  14. data/ext/gvl_wrappers.h +23 -39
  15. data/ext/pg.c +19 -48
  16. data/ext/pg.h +46 -81
  17. data/ext/pg_binary_decoder.c +69 -6
  18. data/ext/pg_coder.c +53 -4
  19. data/ext/pg_connection.c +401 -253
  20. data/ext/pg_copy_coder.c +10 -5
  21. data/ext/pg_result.c +359 -131
  22. data/ext/pg_text_decoder.c +597 -37
  23. data/ext/pg_text_encoder.c +6 -7
  24. data/ext/pg_tuple.c +541 -0
  25. data/ext/pg_type_map.c +14 -7
  26. data/ext/util.c +6 -6
  27. data/ext/util.h +2 -2
  28. data/lib/pg/basic_type_mapping.rb +40 -7
  29. data/lib/pg/binary_decoder.rb +22 -0
  30. data/lib/pg/coder.rb +1 -1
  31. data/lib/pg/connection.rb +27 -7
  32. data/lib/pg/constants.rb +1 -1
  33. data/lib/pg/exceptions.rb +1 -1
  34. data/lib/pg/result.rb +6 -5
  35. data/lib/pg/text_decoder.rb +19 -23
  36. data/lib/pg/text_encoder.rb +36 -2
  37. data/lib/pg/tuple.rb +30 -0
  38. data/lib/pg/type_map_by_column.rb +1 -1
  39. data/lib/pg.rb +21 -11
  40. data/spec/helpers.rb +47 -19
  41. data/spec/pg/basic_type_mapping_spec.rb +230 -27
  42. data/spec/pg/connection_spec.rb +402 -275
  43. data/spec/pg/connection_sync_spec.rb +41 -0
  44. data/spec/pg/result_spec.rb +59 -17
  45. data/spec/pg/tuple_spec.rb +280 -0
  46. data/spec/pg/type_map_by_class_spec.rb +2 -2
  47. data/spec/pg/type_map_by_column_spec.rb +1 -1
  48. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  49. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  50. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  51. data/spec/pg/type_map_spec.rb +1 -1
  52. data/spec/pg/type_spec.rb +184 -12
  53. data/spec/pg_spec.rb +2 -2
  54. data.tar.gz.sig +0 -0
  55. metadata +47 -53
  56. metadata.gz.sig +0 -0
  57. data/sample/array_insert.rb +0 -20
  58. data/sample/async_api.rb +0 -106
  59. data/sample/async_copyto.rb +0 -39
  60. data/sample/async_mixed.rb +0 -56
  61. data/sample/check_conn.rb +0 -21
  62. data/sample/copyfrom.rb +0 -81
  63. data/sample/copyto.rb +0 -19
  64. data/sample/cursor.rb +0 -21
  65. data/sample/disk_usage_report.rb +0 -186
  66. data/sample/issue-119.rb +0 -94
  67. data/sample/losample.rb +0 -69
  68. data/sample/minimal-testcase.rb +0 -17
  69. data/sample/notify_wait.rb +0 -72
  70. data/sample/pg_statistics.rb +0 -294
  71. data/sample/replication_monitor.rb +0 -231
  72. data/sample/test_binary_values.rb +0 -33
  73. data/sample/wal_shipper.rb +0 -434
  74. 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 4d9c4ee44d11 2016/09/04 17:32:03 lars $
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) && defined(HAVE_RB_W32_WRAP_IO_HANDLE)
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
- #ifdef M17N_SUPPORTED
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) -> Fixnum
356
- * PG::Connection.ping(connection_string) -> Fixnum
357
- * PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Fixnum
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
- * PG::Connection.encrypt_password( password, username ) -> String
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 commands like: +ALTER USER joe PASSWORD 'pwd'+.
427
- * The arguments are the cleartext password, and the SQL name
428
- * of the user it is for.
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() -> Fixnum
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 -> Fixnum
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 user name.
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() -> Fixnum
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 really usable,
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 memoized IO object created from the Connection's underlying socket.
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, when supported */
869
- if( rb_respond_to(socket_io, id_autoclose) ){
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() -> Fixnum
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
- * #exec is implemented on the synchronous command processing API of libpq, whereas
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
- * #exec is somewhat faster that #async_exec, but blocks any signals to be processed until
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
- else {
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 => Fixnum (oid of type of bind parameter)
1238
- * :format => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1278
1317
  paramsData.with_types = 1;
1279
1318
 
1280
1319
  /*
1281
- * Handle the edge-case where the caller is coming from #exec, but passed an explict +nil+
1282
- * for the second parameter.
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, &paramsData );
@@ -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 => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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
- Check_Type(string, T_STRING);
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
- Check_Type(string, T_STRING);
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
- Check_Type(string, T_STRING);
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
- #endif
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.send_query(sql [, params, result_format[, type_map ]] ) -> nil
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 optional array of the bind parameters for the SQL query.
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 => Fixnum (oid of type of bind parameter)
1797
- * :format => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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
- pgconn_send_query(int argc, VALUE *argv, VALUE self)
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, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1911
+ rb_scan_args(argc, argv, "22", &command, &paramsData.params, &in_res_fmt, &paramsData.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, &paramsData );
1851
1915
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1852
1916
  nParams = alloc_query_params( &paramsData );
@@ -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 => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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( HAVE_RUBY_VM_H ) && defined( _WIN32 )
2331
+ #if defined( _WIN32 )
2309
2332
  /*
2310
2333
  * On Windows, use platform-specific strategies to wait for the socket
2311
- * instead of rb_thread_select().
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( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2340
+ wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2322
2341
  {
2323
- int sd = PQsocket( conn );
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(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
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 or Win32+Ruby-1.8 */
2412
+ /* non Win32 */
2397
2413
 
2398
2414
  static void *
2399
- wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2415
+ wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2400
2416
  {
2401
- int sd = PQsocket( conn );
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 = rb_thread_fd_select( sd+1, &sd_rset, NULL, NULL, ptimeout ? &waittime : NULL );
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
- rb_fd_term( &sd_rset );
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
- * event otherwise. If used in block form, passes the name of the
2497
- * NOTIFY +event+ and the generating +pid+ into the block.
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
- PGconn *conn = pg_get_pgconn( self );
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( conn, ptimeout, notify_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
- * encoder can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2556
- * This encodes the received data fields from an Array of Strings. Optionally
2557
- * the encoder can type cast the fields form various Ruby types in one step,
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 ]] ) -> String
2641
+ * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
2663
2642
  *
2664
- * Return a string containing one row of data, +nil+
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
- * decoder can be a PG::Coder derivation (typically PG::TextDecoder::CopyRow).
2669
- * This decodes the received data fields as Array of Strings. Optionally
2670
- * the decoder can type cast the fields to various Ruby types in one step,
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 ) -> Fixnum
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, "invalid encoding name: %s",StringValueCStr(str));
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
- PGconn *conn = pg_get_pgconn( self );
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( conn, ptimeout, get_result_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.async_exec(sql [, params, result_format ] ) -> PG::Result
3174
- * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
3149
+ * conn.discard_results()
3175
3150
  *
3176
- * This function has the same behavior as #exec,
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
- /* remove any remaining results from the queue */
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
- pgconn_send_query( argc, argv, self );
3190
- pgconn_block( 0, NULL, self );
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
- #ifdef HAVE_PQSSLATTRIBUTE
3201
- /* Since PostgreSQL-9.5: */
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] ) -> Fixnum
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 ) -> Fixnum
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) -> Fixnum
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] ) -> Fixnum
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 ) -> Fixnum
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 ) -> Fixnum
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 ) -> Fixnum
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
- rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
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, "exec", pgconn_exec, -1);
3984
- rb_define_alias(rb_cPGconn, "query", "exec");
3985
- rb_define_method(rb_cPGconn, "exec_params", pgconn_exec_params, -1);
3986
- rb_define_method(rb_cPGconn, "prepare", pgconn_prepare, -1);
3987
- rb_define_method(rb_cPGconn, "exec_prepared", pgconn_exec_prepared, -1);
3988
- rb_define_method(rb_cPGconn, "describe_prepared", pgconn_describe_prepared, 1);
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);