pg 0.21.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
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);