pg 0.21.0 → 1.1.4

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 (55) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +98 -0
  5. data/Manifest.txt +5 -1
  6. data/README.rdoc +14 -4
  7. data/Rakefile +4 -5
  8. data/Rakefile.cross +17 -21
  9. data/ext/errorcodes.def +12 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +4 -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 +23 -50
  16. data/ext/pg.h +51 -81
  17. data/ext/pg_binary_decoder.c +73 -6
  18. data/ext/pg_coder.c +52 -3
  19. data/ext/pg_connection.c +369 -219
  20. data/ext/pg_copy_coder.c +10 -5
  21. data/ext/pg_result.c +343 -119
  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/util.c +6 -6
  26. data/ext/util.h +2 -2
  27. data/lib/pg.rb +5 -7
  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 -3
  32. data/lib/pg/constants.rb +1 -1
  33. data/lib/pg/exceptions.rb +1 -1
  34. data/lib/pg/result.rb +1 -1
  35. data/lib/pg/text_decoder.rb +19 -23
  36. data/lib/pg/text_encoder.rb +35 -1
  37. data/lib/pg/tuple.rb +30 -0
  38. data/lib/pg/type_map_by_column.rb +1 -1
  39. data/spec/helpers.rb +49 -21
  40. data/spec/pg/basic_type_mapping_spec.rb +230 -27
  41. data/spec/pg/connection_spec.rb +473 -277
  42. data/spec/pg/connection_sync_spec.rb +41 -0
  43. data/spec/pg/result_spec.rb +48 -13
  44. data/spec/pg/tuple_spec.rb +280 -0
  45. data/spec/pg/type_map_by_class_spec.rb +1 -1
  46. data/spec/pg/type_map_by_column_spec.rb +1 -1
  47. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  48. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  49. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  50. data/spec/pg/type_map_spec.rb +1 -1
  51. data/spec/pg/type_spec.rb +184 -12
  52. data/spec/pg_spec.rb +2 -2
  53. metadata +37 -33
  54. metadata.gz.sig +0 -0
  55. data/lib/pg/deprecated_constants.rb +0 -21
@@ -1,9 +1,10 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_decoder.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
+ #include "ruby/version.h"
7
8
  #include "pg.h"
8
9
  #include "util.h"
9
10
  #ifdef HAVE_INTTYPES_H
@@ -21,7 +22,7 @@ VALUE rb_mPG_BinaryDecoder;
21
22
  *
22
23
  */
23
24
  static VALUE
24
- pg_bin_dec_boolean(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
25
+ pg_bin_dec_boolean(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
25
26
  {
26
27
  if (len < 1) {
27
28
  rb_raise( rb_eTypeError, "wrong data for binary boolean converter in tuple %d field %d", tuple, field);
@@ -37,7 +38,7 @@ pg_bin_dec_boolean(t_pg_coder *conv, char *val, int len, int tuple, int field, i
37
38
  *
38
39
  */
39
40
  static VALUE
40
- pg_bin_dec_integer(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
41
+ pg_bin_dec_integer(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
41
42
  {
42
43
  switch( len ){
43
44
  case 2:
@@ -59,7 +60,7 @@ pg_bin_dec_integer(t_pg_coder *conv, char *val, int len, int tuple, int field, i
59
60
  *
60
61
  */
61
62
  static VALUE
62
- pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
63
+ pg_bin_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
63
64
  {
64
65
  union {
65
66
  float f;
@@ -91,7 +92,7 @@ pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int
91
92
  *
92
93
  */
93
94
  VALUE
94
- pg_bin_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
95
+ pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
95
96
  {
96
97
  VALUE ret;
97
98
  ret = rb_tainted_str_new( val, len );
@@ -106,7 +107,7 @@ pg_bin_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int
106
107
  *
107
108
  */
108
109
  static VALUE
109
- pg_bin_dec_to_base64(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
110
+ pg_bin_dec_to_base64(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
110
111
  {
111
112
  t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
112
113
  t_pg_coder_dec_func dec_func = pg_coder_dec_func(this->elem, this->comp.format);
@@ -130,6 +131,70 @@ pg_bin_dec_to_base64(t_pg_coder *conv, char *val, int len, int tuple, int field,
130
131
  return out_value;
131
132
  }
132
133
 
134
+ #define PG_INT64_MIN (-0x7FFFFFFFFFFFFFFFL - 1)
135
+ #define PG_INT64_MAX 0x7FFFFFFFFFFFFFFFL
136
+
137
+ /*
138
+ * Document-class: PG::BinaryDecoder::Timestamp < PG::SimpleDecoder
139
+ *
140
+ * This is a decoder class for conversion of PostgreSQL binary timestamps
141
+ * to Ruby Time objects.
142
+ *
143
+ * The following flags can be used to specify timezone interpretation:
144
+ * * +PG::Coder::TIMESTAMP_DB_UTC+ : Interpret timestamp as UTC time (default)
145
+ * * +PG::Coder::TIMESTAMP_DB_LOCAL+ : Interpret timestamp as local time
146
+ * * +PG::Coder::TIMESTAMP_APP_UTC+ : Return timestamp as UTC time (default)
147
+ * * +PG::Coder::TIMESTAMP_APP_LOCAL+ : Return timestamp as local time
148
+ *
149
+ * Example:
150
+ * deco = PG::BinaryDecoder::Timestamp.new(flags: PG::Coder::TIMESTAMP_DB_UTC | PG::Coder::TIMESTAMP_APP_LOCAL)
151
+ * deco.decode("\0"*8) # => 2000-01-01 01:00:00 +0100
152
+ */
153
+ static VALUE
154
+ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
155
+ {
156
+ int64_t timestamp;
157
+ int64_t sec;
158
+ int64_t nsec;
159
+ VALUE t;
160
+
161
+ if( len != sizeof(timestamp) ){
162
+ rb_raise( rb_eTypeError, "wrong data for timestamp converter in tuple %d field %d length %d", tuple, field, len);
163
+ }
164
+
165
+ timestamp = read_nbo64(val);
166
+
167
+ switch(timestamp){
168
+ case PG_INT64_MAX:
169
+ return rb_str_new2("infinity");
170
+ case PG_INT64_MIN:
171
+ return rb_str_new2("-infinity");
172
+ default:
173
+ /* PostgreSQL's timestamp is based on year 2000 and Ruby's time is based on 1970.
174
+ * Adjust the 30 years difference. */
175
+ sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
176
+ nsec = (timestamp % 1000000) * 1000;
177
+
178
+ #if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T) && defined(SIZEOF_TIME_T) && SIZEOF_TIME_T >= 8
179
+ /* Fast path for time conversion */
180
+ {
181
+ struct timespec ts = {sec, nsec};
182
+ t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
183
+ }
184
+ #else
185
+ t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(sec), LL2NUM(nsec / 1000));
186
+ if( !(conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL) ) {
187
+ t = rb_funcall(t, rb_intern("utc"), 0);
188
+ }
189
+ #endif
190
+ if( conv->flags & PG_CODER_TIMESTAMP_DB_LOCAL ) {
191
+ /* interpret it as local time */
192
+ t = rb_funcall(t, rb_intern("-"), 1, rb_funcall(t, rb_intern("utc_offset"), 0));
193
+ }
194
+ return t;
195
+ }
196
+ }
197
+
133
198
  /*
134
199
  * Document-class: PG::BinaryDecoder::String < PG::SimpleDecoder
135
200
  *
@@ -156,6 +221,8 @@ init_pg_binary_decoder()
156
221
  pg_define_coder( "String", pg_text_dec_string, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
157
222
  /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Bytea", rb_cPG_SimpleDecoder ); */
158
223
  pg_define_coder( "Bytea", pg_bin_dec_bytea, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
224
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Timestamp", rb_cPG_SimpleDecoder ); */
225
+ pg_define_coder( "Timestamp", pg_bin_dec_timestamp, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
159
226
 
160
227
  /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "ToBase64", rb_cPG_CompositeDecoder ); */
161
228
  pg_define_coder( "ToBase64", pg_bin_dec_to_base64, rb_cPG_CompositeDecoder, rb_mPG_BinaryDecoder );
@@ -38,6 +38,7 @@ pg_coder_init_encoder( VALUE self )
38
38
  this->coder_obj = self;
39
39
  this->oid = 0;
40
40
  this->format = 0;
41
+ this->flags = 0;
41
42
  rb_iv_set( self, "@name", Qnil );
42
43
  }
43
44
 
@@ -56,6 +57,7 @@ pg_coder_init_decoder( VALUE self )
56
57
  this->coder_obj = self;
57
58
  this->oid = 0;
58
59
  this->format = 0;
60
+ this->flags = 0;
59
61
  rb_iv_set( self, "@name", Qnil );
60
62
  }
61
63
 
@@ -192,7 +194,11 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
192
194
  if( NIL_P(argv[0]) )
193
195
  return Qnil;
194
196
 
195
- val = StringValuePtr(argv[0]);
197
+ if( this->format == 0 ){
198
+ val = StringValueCStr(argv[0]);
199
+ }else{
200
+ val = StringValuePtr(argv[0]);
201
+ }
196
202
  if( !this->dec_func ){
197
203
  rb_raise(rb_eRuntimeError, "no decoder function defined");
198
204
  }
@@ -265,6 +271,36 @@ pg_coder_format_get(VALUE self)
265
271
  return INT2NUM(this->format);
266
272
  }
267
273
 
274
+ /*
275
+ * call-seq:
276
+ * coder.flags = Integer
277
+ *
278
+ * Set coder specific bitwise OR-ed flags.
279
+ * See the particular en- or decoder description for available flags.
280
+ *
281
+ * The default is +0+.
282
+ */
283
+ static VALUE
284
+ pg_coder_flags_set(VALUE self, VALUE flags)
285
+ {
286
+ t_pg_coder *this = DATA_PTR(self);
287
+ this->flags = NUM2INT(flags);
288
+ return flags;
289
+ }
290
+
291
+ /*
292
+ * call-seq:
293
+ * coder.flags -> Integer
294
+ *
295
+ * Get current bitwise OR-ed coder flags.
296
+ */
297
+ static VALUE
298
+ pg_coder_flags_get(VALUE self)
299
+ {
300
+ t_pg_coder *this = DATA_PTR(self);
301
+ return INT2NUM(this->flags);
302
+ }
303
+
268
304
  /*
269
305
  * call-seq:
270
306
  * coder.needs_quotation = Boolean
@@ -403,14 +439,14 @@ pg_coder_enc_func(t_pg_coder *this)
403
439
  }
404
440
 
405
441
  static VALUE
406
- pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
442
+ pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
407
443
  {
408
444
  VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
409
445
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
410
446
  }
411
447
 
412
448
  static VALUE
413
- pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
449
+ pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
414
450
  {
415
451
  VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
416
452
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
@@ -457,6 +493,19 @@ init_pg_coder()
457
493
  rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
458
494
  rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
459
495
  rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
496
+ rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
497
+ rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
498
+
499
+ /* define flags to be used with PG::Coder#flags= */
500
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
501
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
502
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
503
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
504
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
505
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
506
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
507
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
508
+
460
509
  /*
461
510
  * Name of the coder or the corresponding data type.
462
511
  *
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_connection.c - PG::Connection class extension
3
- * $Id: pg_connection.c,v 2e17f315848e 2017/01/14 20:05:06 lars $
3
+ * $Id$
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,9 +84,8 @@ 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)
99
- int ruby_sd = NUM2INT(rb_funcall( socket_io, rb_intern("fileno"), 0 ));
100
- if( rb_w32_unwrap_io_handle(ruby_sd) ){
87
+ #if defined(_WIN32)
88
+ if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
101
89
  rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
102
90
  }
103
91
  #endif
@@ -176,6 +164,10 @@ pgconn_gc_mark( t_pg_connection *this )
176
164
  static void
177
165
  pgconn_gc_free( t_pg_connection *this )
178
166
  {
167
+ #if defined(_WIN32)
168
+ if ( RTEST(this->socket_io) )
169
+ rb_w32_unwrap_io_handle( this->ruby_sd );
170
+ #endif
179
171
  if (this->pgconn != NULL)
180
172
  PQfinish( this->pgconn );
181
173
 
@@ -209,6 +201,7 @@ pgconn_s_allocate( VALUE klass )
209
201
  this->decoder_for_get_copy_data = Qnil;
210
202
  this->trace_stream = Qnil;
211
203
  this->external_encoding = Qnil;
204
+ this->guess_result_memsize = 1;
212
205
 
213
206
  return self;
214
207
  }
@@ -291,9 +284,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
291
284
  rb_exc_raise(error);
292
285
  }
293
286
 
294
- #ifdef M17N_SUPPORTED
295
287
  pgconn_set_default_encoding( self );
296
- #endif
297
288
 
298
289
  if (rb_block_given_p()) {
299
290
  return rb_ensure(rb_yield, self, pgconn_finish, self);
@@ -349,7 +340,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
349
340
  return rb_conn;
350
341
  }
351
342
 
352
- #ifdef HAVE_PQPING
353
343
  /*
354
344
  * call-seq:
355
345
  * PG::Connection.ping(connection_hash) -> Integer
@@ -367,6 +357,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
367
357
  * could not establish connection
368
358
  * [+PQPING_NO_ATTEMPT+]
369
359
  * connection not attempted (bad params)
360
+ *
361
+ * Available since PostgreSQL-9.1
370
362
  */
371
363
  static VALUE
372
364
  pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
@@ -379,7 +371,6 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
379
371
 
380
372
  return INT2FIX((int)ping);
381
373
  }
382
- #endif
383
374
 
384
375
 
385
376
  /*
@@ -418,16 +409,65 @@ pgconn_s_conndefaults(VALUE self)
418
409
  }
419
410
 
420
411
 
412
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
421
413
  /*
422
414
  * call-seq:
423
- * PG::Connection.encrypt_password( password, username ) -> String
415
+ * conn.encrypt_password( password, username, algorithm=nil ) -> String
416
+ *
417
+ * This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
418
+ * 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.
419
+ * Instead, use this function to convert the password to encrypted form before it is sent.
424
420
  *
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.
421
+ * The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
422
+ * +algorithm+ specifies the encryption algorithm to use to encrypt the password.
423
+ * 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).
424
+ * Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
425
+ * If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
426
+ * That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
427
+ * 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
428
  *
430
429
  * Return value is the encrypted password.
430
+ * The caller can assume the string doesn't contain any special characters that would require escaping.
431
+ *
432
+ * Available since PostgreSQL-10
433
+ */
434
+ static VALUE
435
+ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
436
+ {
437
+ char *encrypted = NULL;
438
+ VALUE rval = Qnil;
439
+ VALUE password, username, algorithm;
440
+ PGconn *conn = pg_get_pgconn(self);
441
+
442
+ rb_scan_args( argc, argv, "21", &password, &username, &algorithm );
443
+
444
+ Check_Type(password, T_STRING);
445
+ Check_Type(username, T_STRING);
446
+
447
+ encrypted = gvl_PQencryptPasswordConn(conn, StringValueCStr(password), StringValueCStr(username), RTEST(algorithm) ? StringValueCStr(algorithm) : NULL);
448
+ if ( encrypted ) {
449
+ rval = rb_str_new2( encrypted );
450
+ PQfreemem( encrypted );
451
+
452
+ OBJ_INFECT( rval, password );
453
+ OBJ_INFECT( rval, username );
454
+ OBJ_INFECT( rval, algorithm );
455
+ } else {
456
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
457
+ }
458
+
459
+ return rval;
460
+ }
461
+ #endif
462
+
463
+
464
+ /*
465
+ * call-seq:
466
+ * PG::Connection.encrypt_password( password, username ) -> String
467
+ *
468
+ * This is an older, deprecated version of #encrypt_password.
469
+ * The difference is that this function always uses +md5+ as the encryption algorithm.
470
+ *
431
471
  */
432
472
  static VALUE
433
473
  pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
@@ -613,7 +653,7 @@ pgconn_user(VALUE self)
613
653
  * call-seq:
614
654
  * conn.pass()
615
655
  *
616
- * Returns the authenticated user name.
656
+ * Returns the authenticated password.
617
657
  */
618
658
  static VALUE
619
659
  pgconn_pass(VALUE self)
@@ -686,6 +726,7 @@ pgconn_options(VALUE self)
686
726
  *
687
727
  * Returns the connection options used by a live connection.
688
728
  *
729
+ * Available since PostgreSQL-9.3
689
730
  */
690
731
  static VALUE
691
732
  pgconn_conninfo( VALUE self )
@@ -807,6 +848,8 @@ pgconn_error_message(VALUE self)
807
848
  * call-seq:
808
849
  * conn.socket() -> Integer
809
850
  *
851
+ * This method is deprecated. Please use the more portable method #socket_io .
852
+ *
810
853
  * Returns the socket's file descriptor for this connection.
811
854
  * <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
812
855
  * If you do so, you will likely also want to set <tt>autoclose=false</tt>
@@ -815,7 +858,7 @@ pgconn_error_message(VALUE self)
815
858
  * creates an IO that's associated with the connection object itself,
816
859
  * and so won't go out of scope until the connection does.
817
860
  *
818
- * *Note:* On Windows the file descriptor is not really usable,
861
+ * *Note:* On Windows the file descriptor is not usable,
819
862
  * since it can not be used to build a Ruby IO object.
820
863
  */
821
864
  static VALUE
@@ -827,22 +870,17 @@ pgconn_socket(VALUE self)
827
870
  return INT2NUM(sd);
828
871
  }
829
872
 
830
-
831
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
832
-
833
873
  /*
834
874
  * call-seq:
835
875
  * conn.socket_io() -> IO
836
876
  *
837
- * Fetch a memoized IO object created from the Connection's underlying socket.
877
+ * Fetch a memorized IO object created from the Connection's underlying socket.
838
878
  * This object can be used for IO.select to wait for events while running
839
879
  * asynchronous API calls.
840
880
  *
841
881
  * Using this instead of #socket avoids the problem of the underlying connection
842
882
  * 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+.
883
+ * goes out of scope. In contrast to #socket, it also works on Windows.
846
884
  */
847
885
  static VALUE
848
886
  pgconn_socket_io(VALUE self)
@@ -859,16 +897,15 @@ pgconn_socket_io(VALUE self)
859
897
 
860
898
  #ifdef _WIN32
861
899
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
900
+ this->ruby_sd = ruby_sd;
862
901
  #else
863
902
  ruby_sd = sd;
864
903
  #endif
865
904
 
866
905
  socket_io = rb_funcall( rb_cIO, rb_intern("for_fd"), 1, INT2NUM(ruby_sd) );
867
906
 
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
- }
907
+ /* Disable autoclose feature */
908
+ rb_funcall( socket_io, id_autoclose, 1, Qfalse );
872
909
 
873
910
  this->socket_io = socket_io;
874
911
  }
@@ -876,8 +913,6 @@ pgconn_socket_io(VALUE self)
876
913
  return socket_io;
877
914
  }
878
915
 
879
- #endif
880
-
881
916
  /*
882
917
  * call-seq:
883
918
  * conn.backend_pid() -> Integer
@@ -930,7 +965,7 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
930
965
  * conn.exec(sql) {|pg_result| block }
931
966
  *
932
967
  * Sends SQL query request specified by _sql_ to PostgreSQL.
933
- * Returns a PG::Result instance on success.
968
+ * On success, it returns a PG::Result instance with all result rows and columns.
934
969
  * On failure, it raises a PG::Error.
935
970
  *
936
971
  * For backward compatibility, if you pass more than one parameter to this method,
@@ -941,9 +976,9 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
941
976
  * and the PG::Result object will automatically be cleared when the block terminates.
942
977
  * In this instance, <code>conn.exec</code> returns the value of the block.
943
978
  *
944
- * #exec is implemented on the synchronous command processing API of libpq, whereas
979
+ * #sync_exec is implemented on the synchronous command processing API of libpq, whereas
945
980
  * #async_exec is implemented on the asynchronous API.
946
- * #exec is somewhat faster that #async_exec, but blocks any signals to be processed until
981
+ * #sync_exec is somewhat faster that #async_exec, but blocks any signals to be processed until
947
982
  * the query is finished. This is most notably visible by a delayed reaction to Control+C.
948
983
  * Both methods ensure that other threads can process while waiting for the server to
949
984
  * complete the request.
@@ -955,8 +990,8 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
955
990
  PGresult *result = NULL;
956
991
  VALUE rb_pgresult;
957
992
 
958
- /* If called with no parameters, use PQexec */
959
- if ( argc == 1 ) {
993
+ /* If called with no or nil parameters, use PQexec for compatibility */
994
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
960
995
  VALUE query_str = argv[0];
961
996
 
962
997
  result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
@@ -967,11 +1002,10 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
967
1002
  }
968
1003
  return rb_pgresult;
969
1004
  }
1005
+ pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
970
1006
 
971
1007
  /* Otherwise, just call #exec_params instead for backward-compatibility */
972
- else {
973
- return pgconn_exec_params( argc, argv, self );
974
- }
1008
+ return pgconn_exec_params( argc, argv, self );
975
1009
 
976
1010
  }
977
1011
 
@@ -1254,7 +1288,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1254
1288
  * for binary.
1255
1289
  *
1256
1290
  * 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
1291
+ * This will type cast the params from various Ruby types before transmission
1258
1292
  * based on the encoders defined by the type map. When a type encoder is used
1259
1293
  * the format and oid of a given bind parameter are retrieved from the encoder
1260
1294
  * instead out of the hash form described above.
@@ -1274,14 +1308,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1274
1308
  int resultFormat;
1275
1309
  struct query_params_data paramsData = { ENCODING_GET(self) };
1276
1310
 
1311
+ /* For compatibility we accept 1 to 4 parameters */
1277
1312
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1278
1313
  paramsData.with_types = 1;
1279
1314
 
1280
1315
  /*
1281
- * Handle the edge-case where the caller is coming from #exec, but passed an explict +nil+
1282
- * for the second parameter.
1316
+ * For backward compatibility no or +nil+ for the second parameter
1317
+ * is passed to #exec
1283
1318
  */
1284
1319
  if ( NIL_P(paramsData.params) ) {
1320
+ pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
1285
1321
  return pgconn_exec( 1, argv, self );
1286
1322
  }
1287
1323
  pgconn_query_assign_typemap( self, &paramsData );
@@ -1390,7 +1426,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1390
1426
  * for binary.
1391
1427
  *
1392
1428
  * 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
1429
+ * This will type cast the params from various Ruby types before transmission
1394
1430
  * based on the encoders defined by the type map. When a type encoder is used
1395
1431
  * the format and oid of a given bind parameter are retrieved from the encoder
1396
1432
  * instead out of the hash form described above.
@@ -1547,7 +1583,7 @@ pgconn_s_escape(VALUE self, VALUE string)
1547
1583
  int enc_idx;
1548
1584
  int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
1549
1585
 
1550
- Check_Type(string, T_STRING);
1586
+ StringValueCStr(string);
1551
1587
  enc_idx = ENCODING_GET( singleton ? string : self );
1552
1588
  if( ENCODING_GET(string) != enc_idx ){
1553
1589
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
@@ -1646,12 +1682,13 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
1646
1682
  return ret;
1647
1683
  }
1648
1684
 
1649
- #ifdef HAVE_PQESCAPELITERAL
1650
1685
  /*
1651
1686
  * call-seq:
1652
1687
  * conn.escape_literal( str ) -> String
1653
1688
  *
1654
1689
  * Escape an arbitrary String +str+ as a literal.
1690
+ *
1691
+ * Available since PostgreSQL-9.0
1655
1692
  */
1656
1693
  static VALUE
1657
1694
  pgconn_escape_literal(VALUE self, VALUE string)
@@ -1662,7 +1699,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
1662
1699
  VALUE result = Qnil;
1663
1700
  int enc_idx = ENCODING_GET(self);
1664
1701
 
1665
- Check_Type(string, T_STRING);
1702
+ StringValueCStr(string);
1666
1703
  if( ENCODING_GET(string) != enc_idx ){
1667
1704
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1668
1705
  }
@@ -1682,9 +1719,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
1682
1719
 
1683
1720
  return result;
1684
1721
  }
1685
- #endif
1686
1722
 
1687
- #ifdef HAVE_PQESCAPEIDENTIFIER
1688
1723
  /*
1689
1724
  * call-seq:
1690
1725
  * conn.escape_identifier( str ) -> String
@@ -1694,6 +1729,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1694
1729
  * This method does the same as #quote_ident with a String argument,
1695
1730
  * but it doesn't support an Array argument and it makes use of libpq
1696
1731
  * to process the string.
1732
+ *
1733
+ * Available since PostgreSQL-9.0
1697
1734
  */
1698
1735
  static VALUE
1699
1736
  pgconn_escape_identifier(VALUE self, VALUE string)
@@ -1704,7 +1741,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1704
1741
  VALUE result = Qnil;
1705
1742
  int enc_idx = ENCODING_GET(self);
1706
1743
 
1707
- Check_Type(string, T_STRING);
1744
+ StringValueCStr(string);
1708
1745
  if( ENCODING_GET(string) != enc_idx ){
1709
1746
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1710
1747
  }
@@ -1724,9 +1761,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1724
1761
 
1725
1762
  return result;
1726
1763
  }
1727
- #endif
1728
1764
 
1729
- #ifdef HAVE_PQSETSINGLEROWMODE
1730
1765
  /*
1731
1766
  * call-seq:
1732
1767
  * conn.set_single_row_mode -> self
@@ -1763,6 +1798,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1763
1798
  * end
1764
1799
  * end
1765
1800
  *
1801
+ * Available since PostgreSQL-9.2
1766
1802
  */
1767
1803
  static VALUE
1768
1804
  pgconn_set_single_row_mode(VALUE self)
@@ -1779,17 +1815,55 @@ pgconn_set_single_row_mode(VALUE self)
1779
1815
 
1780
1816
  return self;
1781
1817
  }
1782
- #endif
1818
+
1819
+ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1783
1820
 
1784
1821
  /*
1785
1822
  * call-seq:
1786
- * conn.send_query(sql [, params, result_format[, type_map ]] ) -> nil
1823
+ * conn.send_query(sql) -> nil
1787
1824
  *
1788
1825
  * Sends SQL query request specified by _sql_ to PostgreSQL for
1789
1826
  * asynchronous processing, and immediately returns.
1790
1827
  * On failure, it raises a PG::Error.
1791
1828
  *
1792
- * +params+ is an optional array of the bind parameters for the SQL query.
1829
+ * For backward compatibility, if you pass more than one parameter to this method,
1830
+ * it will call #send_query_params for you. New code should explicitly use #send_query_params if
1831
+ * argument placeholders are used.
1832
+ *
1833
+ */
1834
+ static VALUE
1835
+ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1836
+ {
1837
+ PGconn *conn = pg_get_pgconn(self);
1838
+ VALUE error;
1839
+
1840
+ /* If called with no or nil parameters, use PQexec for compatibility */
1841
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1842
+ if(gvl_PQsendQuery(conn, pg_cstr_enc(argv[0], ENCODING_GET(self))) == 0) {
1843
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1844
+ rb_iv_set(error, "@connection", self);
1845
+ rb_exc_raise(error);
1846
+ }
1847
+ return Qnil;
1848
+ }
1849
+
1850
+ pg_deprecated(2, ("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
1851
+
1852
+ /* If called with parameters, and optionally result_format,
1853
+ * use PQsendQueryParams
1854
+ */
1855
+ return pgconn_send_query_params( argc, argv, self);
1856
+ }
1857
+
1858
+ /*
1859
+ * call-seq:
1860
+ * conn.send_query_params(sql, params [, result_format [, type_map ]] ) -> nil
1861
+ *
1862
+ * Sends SQL query request specified by _sql_ to PostgreSQL for
1863
+ * asynchronous processing, and immediately returns.
1864
+ * On failure, it raises a PG::Error.
1865
+ *
1866
+ * +params+ is an array of the bind parameters for the SQL query.
1793
1867
  * Each element of the +params+ array may be either:
1794
1868
  * a hash of the form:
1795
1869
  * {:value => String (value of bind parameter)
@@ -1813,14 +1887,14 @@ pgconn_set_single_row_mode(VALUE self)
1813
1887
  * for binary.
1814
1888
  *
1815
1889
  * 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
1890
+ * This will type cast the params from various Ruby types before transmission
1817
1891
  * based on the encoders defined by the type map. When a type encoder is used
1818
1892
  * the format and oid of a given bind parameter are retrieved from the encoder
1819
1893
  * instead out of the hash form described above.
1820
1894
  *
1821
1895
  */
1822
1896
  static VALUE
1823
- pgconn_send_query(int argc, VALUE *argv, VALUE self)
1897
+ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1824
1898
  {
1825
1899
  PGconn *conn = pg_get_pgconn(self);
1826
1900
  int result;
@@ -1830,23 +1904,9 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1830
1904
  int resultFormat;
1831
1905
  struct query_params_data paramsData = { ENCODING_GET(self) };
1832
1906
 
1833
- rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1907
+ rb_scan_args(argc, argv, "22", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1834
1908
  paramsData.with_types = 1;
1835
1909
 
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
1910
  pgconn_query_assign_typemap( self, &paramsData );
1851
1911
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1852
1912
  nParams = alloc_query_params( &paramsData );
@@ -1953,7 +2013,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1953
2013
  * for binary.
1954
2014
  *
1955
2015
  * 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
2016
+ * This will type cast the params from various Ruby types before transmission
1957
2017
  * based on the encoders defined by the type map. When a type encoder is used
1958
2018
  * the format and oid of a given bind parameter are retrieved from the encoder
1959
2019
  * instead out of the hash form described above.
@@ -2203,7 +2263,6 @@ pgconn_flush(self)
2203
2263
  static VALUE
2204
2264
  pgconn_cancel(VALUE self)
2205
2265
  {
2206
- #ifdef HAVE_PQGETCANCEL
2207
2266
  char errbuf[256];
2208
2267
  PGcancel *cancel;
2209
2268
  VALUE retval;
@@ -2221,9 +2280,6 @@ pgconn_cancel(VALUE self)
2221
2280
 
2222
2281
  PQfreeCancel(cancel);
2223
2282
  return retval;
2224
- #else
2225
- rb_notimplement();
2226
- #endif
2227
2283
  }
2228
2284
 
2229
2285
 
@@ -2267,56 +2323,15 @@ pgconn_notifies(VALUE self)
2267
2323
  return hash;
2268
2324
  }
2269
2325
 
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
2326
  /* Win32 + Ruby 1.9+ */
2308
- #if defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
2327
+ #if defined( _WIN32 )
2309
2328
  /*
2310
2329
  * On Windows, use platform-specific strategies to wait for the socket
2311
- * instead of rb_thread_select().
2330
+ * instead of rb_wait_for_single_fd().
2312
2331
  */
2313
2332
 
2314
2333
  int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2315
2334
 
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
2335
  static void *
2321
2336
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2322
2337
  {
@@ -2393,7 +2408,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2393
2408
 
2394
2409
  #else
2395
2410
 
2396
- /* non Win32 or Win32+Ruby-1.8 */
2411
+ /* non Win32 */
2397
2412
 
2398
2413
  static void *
2399
2414
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
@@ -2401,11 +2416,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2401
2416
  int sd = PQsocket( conn );
2402
2417
  int ret;
2403
2418
  void *retval;
2404
- rb_fdset_t sd_rset;
2405
2419
  struct timeval aborttime={0,0}, currtime, waittime;
2406
- #ifdef _WIN32
2407
- rb_fdset_t crt_sd_rset;
2408
- #endif
2409
2420
 
2410
2421
  if ( sd < 0 )
2411
2422
  rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
@@ -2414,25 +2425,12 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2414
2425
  if ( PQconsumeInput(conn) == 0 )
2415
2426
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2416
2427
 
2417
- rb_fd_init( &sd_rset );
2418
-
2419
2428
  if ( ptimeout ) {
2420
2429
  gettimeofday(&currtime, NULL);
2421
2430
  timeradd(&currtime, ptimeout, &aborttime);
2422
2431
  }
2423
2432
 
2424
2433
  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
2434
  if ( ptimeout ) {
2437
2435
  gettimeofday(&currtime, NULL);
2438
2436
  timersub(&aborttime, &currtime, &waittime);
@@ -2441,35 +2439,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2441
2439
  /* Is the given timeout valid? */
2442
2440
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2443
2441
  /* 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 );
2442
+ ret = rb_wait_for_single_fd( sd, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
2445
2443
  } else {
2446
2444
  ret = 0;
2447
2445
  }
2448
2446
 
2449
-
2450
- #ifdef _WIN32
2451
- cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2452
- #endif
2453
-
2454
2447
  if ( ret < 0 ){
2455
- rb_fd_term( &sd_rset );
2456
- rb_sys_fail( "rb_thread_select()" );
2448
+ rb_sys_fail( "rb_wait_for_single_fd()" );
2457
2449
  }
2458
2450
 
2459
2451
  /* Return false if the select() timed out */
2460
2452
  if ( ret == 0 ){
2461
- rb_fd_term( &sd_rset );
2462
2453
  return NULL;
2463
2454
  }
2464
2455
 
2465
2456
  /* Check for connection errors (PQisBusy is true on connection errors) */
2466
2457
  if ( PQconsumeInput(conn) == 0 ){
2467
- rb_fd_term( &sd_rset );
2468
2458
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2469
2459
  }
2470
2460
  }
2471
2461
 
2472
- rb_fd_term( &sd_rset );
2473
2462
  return retval;
2474
2463
  }
2475
2464
 
@@ -2484,22 +2473,15 @@ notify_readable(PGconn *conn)
2484
2473
 
2485
2474
  /*
2486
2475
  * 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
2476
+ * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } -> String
2490
2477
  *
2491
2478
  * Blocks while waiting for notification(s), or until the optional
2492
2479
  * _timeout_ is reached, whichever comes first. _timeout_ is
2493
2480
  * measured in seconds and can be fractional.
2494
2481
  *
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
- *
2482
+ * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY event otherwise.
2483
+ * If used in block form, passes the name of the NOTIFY +event+, the generating
2484
+ * +pid+ and the optional +payload+ string into the block.
2503
2485
  */
2504
2486
  static VALUE
2505
2487
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
@@ -2528,12 +2510,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2528
2510
  relname = rb_tainted_str_new2( pnotification->relname );
2529
2511
  PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2530
2512
  be_pid = INT2NUM( pnotification->be_pid );
2531
- #ifdef HAVE_ST_NOTIFY_EXTRA
2532
2513
  if ( *pnotification->extra ) {
2533
2514
  extra = rb_tainted_str_new2( pnotification->extra );
2534
2515
  PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
2535
2516
  }
2536
- #endif
2537
2517
  PQfreemem( pnotification );
2538
2518
 
2539
2519
  if ( rb_block_given_p() )
@@ -2552,9 +2532,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2552
2532
  * not sent (false is only possible if the connection
2553
2533
  * is in nonblocking mode, and this command would block).
2554
2534
  *
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,
2535
+ * _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2536
+ * This encodes the data fields given as _buffer_ from an Array of Strings to
2537
+ * PostgreSQL's COPY text format inclusive proper escaping. Optionally
2538
+ * the encoder can type cast the fields from various Ruby types in one step,
2558
2539
  * if PG::TextEncoder::CopyRow#type_map is set accordingly.
2559
2540
  *
2560
2541
  * Raises an exception if an error occurs.
@@ -2659,15 +2640,18 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2659
2640
 
2660
2641
  /*
2661
2642
  * call-seq:
2662
- * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> String
2643
+ * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
2663
2644
  *
2664
- * Return a string containing one row of data, +nil+
2645
+ * Return one row of data, +nil+
2665
2646
  * if the copy is done, or +false+ if the call would
2666
2647
  * block (only possible if _async_ is true).
2667
2648
  *
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,
2649
+ * If _decoder_ is not set or +nil+, data is returned as binary string.
2650
+ *
2651
+ * If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
2652
+ * PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
2653
+ * COPY text format to an Array of Strings.
2654
+ * Optionally the decoder can type cast the single fields to various Ruby types in one step,
2671
2655
  * if PG::TextDecoder::CopyRow#type_map is set accordingly.
2672
2656
  *
2673
2657
  * See also #copy_data.
@@ -2968,11 +2952,9 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
2968
2952
  Check_Type(str, T_STRING);
2969
2953
 
2970
2954
  if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2971
- rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValueCStr(str));
2955
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2972
2956
  }
2973
- #ifdef M17N_SUPPORTED
2974
2957
  pgconn_set_internal_encoding_index( self );
2975
- #endif
2976
2958
 
2977
2959
  return Qnil;
2978
2960
  }
@@ -3100,10 +3082,6 @@ static VALUE
3100
3082
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
3101
3083
  PGconn *conn = pg_get_pgconn( self );
3102
3084
 
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(). */
3106
-
3107
3085
  struct timeval timeout;
3108
3086
  struct timeval *ptimeout = NULL;
3109
3087
  VALUE timeout_in;
@@ -3170,24 +3148,89 @@ pgconn_get_last_result(VALUE self)
3170
3148
 
3171
3149
  /*
3172
3150
  * call-seq:
3173
- * conn.async_exec(sql [, params, result_format ] ) -> PG::Result
3174
- * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
3151
+ * conn.discard_results()
3175
3152
  *
3176
- * This function has the same behavior as #exec,
3153
+ * Silently discard any prior query result that application didn't eat.
3154
+ * This is done prior of Connection#exec and sibling methods and can
3155
+ * be called explicitly when using the async API.
3156
+ */
3157
+ static VALUE
3158
+ pgconn_discard_results(VALUE self)
3159
+ {
3160
+ PGconn *conn = pg_get_pgconn(self);
3161
+
3162
+ PGresult *cur;
3163
+ while ((cur = gvl_PQgetResult(conn)) != NULL) {
3164
+ int status = PQresultStatus(cur);
3165
+ PQclear(cur);
3166
+ if (status == PGRES_COPY_IN){
3167
+ gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
3168
+ }
3169
+ if (status == PGRES_COPY_OUT){
3170
+ char *buffer = NULL;
3171
+ while( gvl_PQgetCopyData(conn, &buffer, 0) > 0)
3172
+ PQfreemem(buffer);
3173
+ }
3174
+ }
3175
+
3176
+ return Qnil;
3177
+ }
3178
+
3179
+ /*
3180
+ * call-seq:
3181
+ * conn.async_exec(sql) -> PG::Result
3182
+ * conn.async_exec(sql) {|pg_result| block }
3183
+ *
3184
+ * This function has the same behavior as #sync_exec,
3177
3185
  * but is implemented using the asynchronous command
3178
3186
  * processing API of libpq.
3187
+ *
3188
+ * Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
3189
+ * However #async_exec has two advantages:
3190
+ *
3191
+ * 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
3192
+ * 2. Ruby VM gets notified about IO blocked operations.
3193
+ * It can therefore schedule thing like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
3179
3194
  */
3180
3195
  static VALUE
3181
3196
  pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3182
3197
  {
3183
3198
  VALUE rb_pgresult = Qnil;
3184
3199
 
3185
- /* remove any remaining results from the queue */
3200
+ pgconn_discard_results( self );
3201
+ pgconn_send_query( argc, argv, self );
3186
3202
  pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3187
- pgconn_get_last_result( self );
3203
+ rb_pgresult = pgconn_get_last_result( self );
3188
3204
 
3189
- pgconn_send_query( argc, argv, self );
3190
- pgconn_block( 0, NULL, self );
3205
+ if ( rb_block_given_p() ) {
3206
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3207
+ }
3208
+ return rb_pgresult;
3209
+ }
3210
+
3211
+
3212
+ /*
3213
+ * call-seq:
3214
+ * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) -> nil
3215
+ * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
3216
+ *
3217
+ * This function has the same behavior as #sync_exec_params, but is implemented using the asynchronous command processing API of libpq.
3218
+ * See #async_exec for the differences between the two API variants.
3219
+ */
3220
+ static VALUE
3221
+ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
3222
+ {
3223
+ VALUE rb_pgresult = Qnil;
3224
+
3225
+ pgconn_discard_results( self );
3226
+ /* If called with no or nil parameters, use PQsendQuery for compatibility */
3227
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
3228
+ pg_deprecated(3, ("forwarding async_exec_params to async_exec is deprecated"));
3229
+ pgconn_send_query( argc, argv, self );
3230
+ } else {
3231
+ pgconn_send_query_params( argc, argv, self );
3232
+ }
3233
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3191
3234
  rb_pgresult = pgconn_get_last_result( self );
3192
3235
 
3193
3236
  if ( rb_block_given_p() ) {
@@ -3197,15 +3240,111 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3197
3240
  }
3198
3241
 
3199
3242
 
3200
- #ifdef HAVE_PQSSLATTRIBUTE
3201
- /* Since PostgreSQL-9.5: */
3243
+ /*
3244
+ * call-seq:
3245
+ * conn.async_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
3246
+ *
3247
+ * This function has the same behavior as #sync_prepare, but is implemented using the asynchronous command processing API of libpq.
3248
+ * See #async_exec for the differences between the two API variants.
3249
+ */
3250
+ static VALUE
3251
+ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
3252
+ {
3253
+ VALUE rb_pgresult = Qnil;
3254
+
3255
+ pgconn_discard_results( self );
3256
+ pgconn_send_prepare( argc, argv, self );
3257
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3258
+ rb_pgresult = pgconn_get_last_result( self );
3259
+
3260
+ if ( rb_block_given_p() ) {
3261
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3262
+ }
3263
+ return rb_pgresult;
3264
+ }
3265
+
3266
+
3267
+ /*
3268
+ * call-seq:
3269
+ * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
3270
+ * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
3271
+ *
3272
+ * This function has the same behavior as #sync_exec_prepared, but is implemented using the asynchronous command processing API of libpq.
3273
+ * See #async_exec for the differences between the two API variants.
3274
+ */
3275
+ static VALUE
3276
+ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3277
+ {
3278
+ VALUE rb_pgresult = Qnil;
3279
+
3280
+ pgconn_discard_results( self );
3281
+ pgconn_send_query_prepared( argc, argv, self );
3282
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3283
+ rb_pgresult = pgconn_get_last_result( self );
3202
3284
 
3285
+ if ( rb_block_given_p() ) {
3286
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3287
+ }
3288
+ return rb_pgresult;
3289
+ }
3290
+
3291
+
3292
+ /*
3293
+ * call-seq:
3294
+ * conn.async_describe_portal( portal_name ) -> PG::Result
3295
+ *
3296
+ * This function has the same behavior as #sync_describe_portal, but is implemented using the asynchronous command processing API of libpq.
3297
+ * See #async_exec for the differences between the two API variants.
3298
+ */
3299
+ static VALUE
3300
+ pgconn_async_describe_portal(VALUE self, VALUE portal)
3301
+ {
3302
+ VALUE rb_pgresult = Qnil;
3303
+
3304
+ pgconn_discard_results( self );
3305
+ pgconn_send_describe_portal( self, portal );
3306
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3307
+ rb_pgresult = pgconn_get_last_result( self );
3308
+
3309
+ if ( rb_block_given_p() ) {
3310
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3311
+ }
3312
+ return rb_pgresult;
3313
+ }
3314
+
3315
+
3316
+ /*
3317
+ * call-seq:
3318
+ * conn.async_describe_prepared( statement_name ) -> PG::Result
3319
+ *
3320
+ * This function has the same behavior as #sync_describe_prepared, but is implemented using the asynchronous command processing API of libpq.
3321
+ * See #async_exec for the differences between the two API variants.
3322
+ */
3323
+ static VALUE
3324
+ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3325
+ {
3326
+ VALUE rb_pgresult = Qnil;
3327
+
3328
+ pgconn_discard_results( self );
3329
+ pgconn_send_describe_prepared( self, stmt_name );
3330
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3331
+ rb_pgresult = pgconn_get_last_result( self );
3332
+
3333
+ if ( rb_block_given_p() ) {
3334
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3335
+ }
3336
+ return rb_pgresult;
3337
+ }
3338
+
3339
+
3340
+ #ifdef HAVE_PQSSLATTRIBUTE
3203
3341
  /*
3204
3342
  * call-seq:
3205
3343
  * conn.ssl_in_use? -> Boolean
3206
3344
  *
3207
3345
  * Returns +true+ if the connection uses SSL, +false+ if not.
3208
3346
  *
3347
+ * Available since PostgreSQL-9.5
3209
3348
  */
3210
3349
  static VALUE
3211
3350
  pgconn_ssl_in_use(VALUE self)
@@ -3238,6 +3377,8 @@ pgconn_ssl_in_use(VALUE self)
3238
3377
  *
3239
3378
  *
3240
3379
  * See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
3380
+ *
3381
+ * Available since PostgreSQL-9.5
3241
3382
  */
3242
3383
  static VALUE
3243
3384
  pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
@@ -3256,6 +3397,7 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3256
3397
  *
3257
3398
  * See also #ssl_attribute
3258
3399
  *
3400
+ * Available since PostgreSQL-9.5
3259
3401
  */
3260
3402
  static VALUE
3261
3403
  pgconn_ssl_attribute_names(VALUE self)
@@ -3566,8 +3708,6 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3566
3708
  }
3567
3709
 
3568
3710
 
3569
- #ifdef M17N_SUPPORTED
3570
-
3571
3711
  void
3572
3712
  pgconn_set_internal_encoding_index( VALUE self )
3573
3713
  {
@@ -3718,7 +3858,7 @@ pgconn_set_default_encoding( VALUE self )
3718
3858
  if (( enc = rb_default_internal_encoding() )) {
3719
3859
  encname = pg_get_rb_encoding_as_pg_encoding( enc );
3720
3860
  if ( pgconn_set_client_encoding_async(self, encname) != 0 )
3721
- rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
3861
+ rb_warning( "Failed to set the default_internal encoding to %s: '%s'",
3722
3862
  encname, PQerrorMessage(conn) );
3723
3863
  pgconn_set_internal_encoding_index( self );
3724
3864
  return rb_enc_from_encoding( enc );
@@ -3729,8 +3869,6 @@ pgconn_set_default_encoding( VALUE self )
3729
3869
  }
3730
3870
 
3731
3871
 
3732
- #endif /* M17N_SUPPORTED */
3733
-
3734
3872
  /*
3735
3873
  * call-seq:
3736
3874
  * res.type_map_for_queries = typemap
@@ -3909,6 +4047,20 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
3909
4047
  return this->decoder_for_get_copy_data;
3910
4048
  }
3911
4049
 
4050
+ /*
4051
+ * call-seq:
4052
+ * res.guess_result_memsize = enabled
4053
+ *
4054
+ * This method is for testing only and will probably be removed in the future.
4055
+ */
4056
+ static VALUE
4057
+ pgconn_guess_result_memsize_set(VALUE self, VALUE enable)
4058
+ {
4059
+ t_pg_connection *this = pg_get_connection( self );
4060
+ this->guess_result_memsize = RTEST(enable);
4061
+ return enable;
4062
+ }
4063
+
3912
4064
 
3913
4065
  /*
3914
4066
  * Document-class: PG::Connection
@@ -3939,9 +4091,7 @@ init_pg_connection()
3939
4091
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
3940
4092
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
3941
4093
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3942
- #ifdef HAVE_PQPING
3943
4094
  rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
3944
- #endif
3945
4095
 
3946
4096
  /****** PG::Connection INSTANCE METHODS: Connection Control ******/
3947
4097
  rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
@@ -3971,43 +4121,42 @@ init_pg_connection()
3971
4121
  rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
3972
4122
  rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
3973
4123
  rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
3974
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
3975
4124
  rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
3976
- #endif
3977
4125
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
3978
4126
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
3979
4127
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
3980
4128
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
3981
4129
 
3982
4130
  /****** 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);
4131
+ rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
4132
+ rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
4133
+ rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
4134
+ rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
4135
+ rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
4136
+ rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
3990
4137
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
3991
4138
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
3992
4139
  rb_define_alias(rb_cPGconn, "escape", "escape_string");
3993
- #ifdef HAVE_PQESCAPELITERAL
3994
4140
  rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
3995
- #endif
3996
- #ifdef HAVE_PQESCAPEIDENTIFIER
3997
4141
  rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
3998
- #endif
3999
4142
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4000
4143
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4001
- #ifdef HAVE_PQSETSINGLEROWMODE
4002
4144
  rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
4003
- #endif
4004
4145
 
4005
4146
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
4006
4147
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
4148
+ rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
4149
+ rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
4150
+ rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
4151
+ rb_define_alias(rb_cPGconn, "async_query", "async_exec");
4007
4152
  rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
4153
+ rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
4008
4154
  rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4155
+ rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
4009
4156
  rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
4157
+ rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
4010
4158
  rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
4159
+ rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
4011
4160
  rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
4012
4161
  rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
4013
4162
  rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
@@ -4015,6 +4164,7 @@ init_pg_connection()
4015
4164
  rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
4016
4165
  rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
4017
4166
  rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
4167
+ rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
4018
4168
 
4019
4169
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
4020
4170
  rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
@@ -4031,6 +4181,7 @@ init_pg_connection()
4031
4181
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
4032
4182
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4033
4183
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4184
+ rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
4034
4185
 
4035
4186
  /****** PG::Connection INSTANCE METHODS: Notice Processing ******/
4036
4187
  rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
@@ -4045,9 +4196,10 @@ init_pg_connection()
4045
4196
  rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
4046
4197
  rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
4047
4198
  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
4199
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
4200
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
4201
+ rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
4202
+ #endif
4051
4203
 
4052
4204
  #ifdef HAVE_PQSSLATTRIBUTE
4053
4205
  rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
@@ -4083,12 +4235,10 @@ init_pg_connection()
4083
4235
  rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
4084
4236
  rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
4085
4237
 
4086
- #ifdef M17N_SUPPORTED
4087
4238
  rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
4088
4239
  rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
4089
4240
  rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
4090
4241
  rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
4091
- #endif /* M17N_SUPPORTED */
4092
4242
 
4093
4243
  rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
4094
4244
  rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);