pg 1.0.0 → 1.2.3

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