pg 0.21.0 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +0 -6595
  5. data/History.rdoc +184 -0
  6. data/Manifest.txt +8 -3
  7. data/README-Windows.rdoc +4 -4
  8. data/README.ja.rdoc +1 -2
  9. data/README.rdoc +58 -13
  10. data/Rakefile +10 -9
  11. data/Rakefile.cross +68 -71
  12. data/ext/errorcodes.def +76 -0
  13. data/ext/errorcodes.rb +1 -1
  14. data/ext/errorcodes.txt +21 -2
  15. data/ext/extconf.rb +18 -36
  16. data/ext/gvl_wrappers.c +4 -0
  17. data/ext/gvl_wrappers.h +23 -39
  18. data/ext/pg.c +154 -144
  19. data/ext/pg.h +68 -95
  20. data/ext/pg_binary_decoder.c +82 -15
  21. data/ext/pg_binary_encoder.c +13 -12
  22. data/ext/pg_coder.c +73 -12
  23. data/ext/pg_connection.c +699 -459
  24. data/ext/pg_copy_coder.c +16 -8
  25. data/ext/pg_record_coder.c +491 -0
  26. data/ext/pg_result.c +571 -195
  27. data/ext/pg_text_decoder.c +606 -40
  28. data/ext/pg_text_encoder.c +185 -54
  29. data/ext/pg_tuple.c +549 -0
  30. data/ext/pg_type_map.c +1 -1
  31. data/ext/pg_type_map_all_strings.c +4 -4
  32. data/ext/pg_type_map_by_class.c +9 -4
  33. data/ext/pg_type_map_by_column.c +7 -6
  34. data/ext/pg_type_map_by_mri_type.c +1 -1
  35. data/ext/pg_type_map_by_oid.c +3 -2
  36. data/ext/pg_type_map_in_ruby.c +1 -1
  37. data/ext/{util.c → pg_util.c} +10 -10
  38. data/ext/{util.h → pg_util.h} +2 -2
  39. data/lib/pg.rb +8 -10
  40. data/lib/pg/basic_type_mapping.rb +121 -25
  41. data/lib/pg/binary_decoder.rb +23 -0
  42. data/lib/pg/coder.rb +23 -2
  43. data/lib/pg/connection.rb +28 -4
  44. data/lib/pg/constants.rb +2 -1
  45. data/lib/pg/exceptions.rb +2 -1
  46. data/lib/pg/result.rb +14 -2
  47. data/lib/pg/text_decoder.rb +21 -26
  48. data/lib/pg/text_encoder.rb +32 -8
  49. data/lib/pg/tuple.rb +30 -0
  50. data/lib/pg/type_map_by_column.rb +3 -2
  51. data/spec/helpers.rb +61 -33
  52. data/spec/pg/basic_type_mapping_spec.rb +362 -37
  53. data/spec/pg/connection_spec.rb +602 -329
  54. data/spec/pg/connection_sync_spec.rb +41 -0
  55. data/spec/pg/result_spec.rb +242 -17
  56. data/spec/pg/tuple_spec.rb +333 -0
  57. data/spec/pg/type_map_by_class_spec.rb +2 -2
  58. data/spec/pg/type_map_by_column_spec.rb +6 -2
  59. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  60. data/spec/pg/type_map_by_oid_spec.rb +3 -3
  61. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  62. data/spec/pg/type_map_spec.rb +1 -1
  63. data/spec/pg/type_spec.rb +364 -18
  64. data/spec/pg_spec.rb +2 -2
  65. metadata +48 -43
  66. metadata.gz.sig +0 -0
  67. data/lib/pg/deprecated_constants.rb +0 -21
@@ -1,11 +1,11 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
- #include "util.h"
8
+ #include "pg_util.h"
9
9
  #ifdef HAVE_INTTYPES_H
10
10
  #include <inttypes.h>
11
11
  #endif
@@ -25,11 +25,12 @@ static int
25
25
  pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
26
26
  {
27
27
  char mybool;
28
- switch(value){
29
- case Qtrue : mybool = 1; break;
30
- case Qfalse : mybool = 0; break;
31
- default :
32
- rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
28
+ if (value == Qtrue) {
29
+ mybool = 1;
30
+ } else if (value == Qfalse) {
31
+ mybool = 0;
32
+ } else {
33
+ rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
33
34
  }
34
35
  if(out) *out = mybool;
35
36
  return 1;
@@ -38,7 +39,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
38
39
  /*
39
40
  * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
40
41
  *
41
- * This is the encoder class for the PostgreSQL int2 type.
42
+ * This is the encoder class for the PostgreSQL +int2+ (alias +smallint+) type.
42
43
  *
43
44
  * Non-Number values are expected to have method +to_i+ defined.
44
45
  *
@@ -55,9 +56,9 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
55
56
  }
56
57
 
57
58
  /*
58
- * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
59
+ * Document-class: PG::BinaryEncoder::Int4 < PG::SimpleEncoder
59
60
  *
60
- * This is the encoder class for the PostgreSQL int4 type.
61
+ * This is the encoder class for the PostgreSQL +int4+ (alias +integer+) type.
61
62
  *
62
63
  * Non-Number values are expected to have method +to_i+ defined.
63
64
  *
@@ -74,9 +75,9 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
74
75
  }
75
76
 
76
77
  /*
77
- * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
78
+ * Document-class: PG::BinaryEncoder::Int8 < PG::SimpleEncoder
78
79
  *
79
- * This is the encoder class for the PostgreSQL int8 type.
80
+ * This is the encoder class for the PostgreSQL +int8+ (alias +bigint+) type.
80
81
  *
81
82
  * Non-Number values are expected to have method +to_i+ defined.
82
83
  *
data/ext/pg_coder.c CHANGED
@@ -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,14 +57,27 @@ 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
 
64
+ void
65
+ pg_coder_mark(t_pg_coder *this)
66
+ {
67
+ rb_gc_mark(this->coder_obj);
68
+ }
69
+
70
+ static void
71
+ pg_composite_coder_mark(t_pg_composite_coder *this)
72
+ {
73
+ pg_coder_mark(&this->comp);
74
+ }
75
+
62
76
  static VALUE
63
77
  pg_simple_encoder_allocate( VALUE klass )
64
78
  {
65
79
  t_pg_coder *this;
66
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
80
+ VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
67
81
  pg_coder_init_encoder( self );
68
82
  return self;
69
83
  }
@@ -72,7 +86,7 @@ static VALUE
72
86
  pg_composite_encoder_allocate( VALUE klass )
73
87
  {
74
88
  t_pg_composite_coder *this;
75
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
89
+ VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
76
90
  pg_coder_init_encoder( self );
77
91
  this->elem = NULL;
78
92
  this->needs_quotation = 1;
@@ -85,7 +99,7 @@ static VALUE
85
99
  pg_simple_decoder_allocate( VALUE klass )
86
100
  {
87
101
  t_pg_coder *this;
88
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
102
+ VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
89
103
  pg_coder_init_decoder( self );
90
104
  return self;
91
105
  }
@@ -94,7 +108,7 @@ static VALUE
94
108
  pg_composite_decoder_allocate( VALUE klass )
95
109
  {
96
110
  t_pg_composite_coder *this;
97
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
111
+ VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
98
112
  pg_coder_init_decoder( self );
99
113
  this->elem = NULL;
100
114
  this->needs_quotation = 1;
@@ -143,7 +157,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
143
157
 
144
158
  if( len == -1 ){
145
159
  /* The intermediate value is a String that can be used directly. */
146
- OBJ_INFECT(intermediate, value);
147
160
  return intermediate;
148
161
  }
149
162
 
@@ -155,7 +168,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
155
168
  rb_obj_classname( self ), len, len2 );
156
169
  }
157
170
  rb_str_set_len( res, len2 );
158
- OBJ_INFECT(res, value);
159
171
 
160
172
  RB_GC_GUARD(intermediate);
161
173
 
@@ -192,13 +204,16 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
192
204
  if( NIL_P(argv[0]) )
193
205
  return Qnil;
194
206
 
195
- val = StringValuePtr(argv[0]);
207
+ if( this->format == 0 ){
208
+ val = StringValueCStr(argv[0]);
209
+ }else{
210
+ val = StringValuePtr(argv[0]);
211
+ }
196
212
  if( !this->dec_func ){
197
213
  rb_raise(rb_eRuntimeError, "no decoder function defined");
198
214
  }
199
215
 
200
216
  res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
201
- OBJ_INFECT(res, argv[0]);
202
217
 
203
218
  return res;
204
219
  }
@@ -265,6 +280,36 @@ pg_coder_format_get(VALUE self)
265
280
  return INT2NUM(this->format);
266
281
  }
267
282
 
283
+ /*
284
+ * call-seq:
285
+ * coder.flags = Integer
286
+ *
287
+ * Set coder specific bitwise OR-ed flags.
288
+ * See the particular en- or decoder description for available flags.
289
+ *
290
+ * The default is +0+.
291
+ */
292
+ static VALUE
293
+ pg_coder_flags_set(VALUE self, VALUE flags)
294
+ {
295
+ t_pg_coder *this = DATA_PTR(self);
296
+ this->flags = NUM2INT(flags);
297
+ return flags;
298
+ }
299
+
300
+ /*
301
+ * call-seq:
302
+ * coder.flags -> Integer
303
+ *
304
+ * Get current bitwise OR-ed coder flags.
305
+ */
306
+ static VALUE
307
+ pg_coder_flags_get(VALUE self)
308
+ {
309
+ t_pg_coder *this = DATA_PTR(self);
310
+ return INT2NUM(this->flags);
311
+ }
312
+
268
313
  /*
269
314
  * call-seq:
270
315
  * coder.needs_quotation = Boolean
@@ -364,6 +409,11 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
364
409
  if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
365
410
  rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
366
411
 
412
+ if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
413
+ rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
414
+ if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
415
+ rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
416
+
367
417
  rb_define_const( coder_klass, "CFUNC", cfunc_obj );
368
418
 
369
419
  RB_GC_GUARD(cfunc_obj);
@@ -403,14 +453,14 @@ pg_coder_enc_func(t_pg_coder *this)
403
453
  }
404
454
 
405
455
  static VALUE
406
- pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
456
+ pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
407
457
  {
408
458
  VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
409
459
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
410
460
  }
411
461
 
412
462
  static VALUE
413
- pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
463
+ pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
414
464
  {
415
465
  VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
416
466
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
@@ -457,14 +507,25 @@ init_pg_coder()
457
507
  rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
458
508
  rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
459
509
  rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
510
+ rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
511
+ rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
512
+
513
+ /* define flags to be used with PG::Coder#flags= */
514
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
515
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
516
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
517
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
518
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
519
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
520
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
521
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
522
+
460
523
  /*
461
524
  * Name of the coder or the corresponding data type.
462
525
  *
463
526
  * This accessor is only used in PG::Coder#inspect .
464
527
  */
465
528
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
466
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
467
- rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
468
529
 
469
530
  /* Document-class: PG::SimpleCoder < PG::Coder */
470
531
  rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );
data/ext/pg_connection.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_connection.c - PG::Connection class extension
3
- * $Id: pg_connection.c,v 2e17f315848e 2017/01/14 20:05:06 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -13,24 +13,14 @@
13
13
  VALUE rb_cPGconn;
14
14
  static ID s_id_encode;
15
15
  static VALUE sym_type, sym_format, sym_value;
16
+ static VALUE sym_symbol, sym_string, sym_static_symbol;
16
17
 
17
18
  static PQnoticeReceiver default_notice_receiver = NULL;
18
19
  static PQnoticeProcessor default_notice_processor = NULL;
19
20
 
20
21
  static VALUE pgconn_finish( VALUE );
21
- #ifdef M17N_SUPPORTED
22
22
  static VALUE pgconn_set_default_encoding( VALUE self );
23
- 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
23
+ static void pgconn_set_internal_encoding_index( VALUE );
34
24
 
35
25
  /*
36
26
  * Global functions
@@ -95,9 +85,8 @@ pgconn_close_socket_io( VALUE self )
95
85
  VALUE socket_io = this->socket_io;
96
86
 
97
87
  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) ){
88
+ #if defined(_WIN32)
89
+ if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
101
90
  rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
102
91
  }
103
92
  #endif
@@ -164,7 +153,6 @@ pgconn_gc_mark( t_pg_connection *this )
164
153
  rb_gc_mark( this->type_map_for_queries );
165
154
  rb_gc_mark( this->type_map_for_results );
166
155
  rb_gc_mark( this->trace_stream );
167
- rb_gc_mark( this->external_encoding );
168
156
  rb_gc_mark( this->encoder_for_put_copy_data );
169
157
  rb_gc_mark( this->decoder_for_get_copy_data );
170
158
  }
@@ -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
 
@@ -208,7 +200,6 @@ pgconn_s_allocate( VALUE klass )
208
200
  this->encoder_for_put_copy_data = Qnil;
209
201
  this->decoder_for_get_copy_data = Qnil;
210
202
  this->trace_stream = Qnil;
211
- this->external_encoding = Qnil;
212
203
 
213
204
  return self;
214
205
  }
@@ -225,32 +216,27 @@ pgconn_s_allocate( VALUE klass )
225
216
  *
226
217
  * Create a connection to the specified server.
227
218
  *
219
+ * +connection_hash+ must be a ruby Hash with connection parameters.
220
+ * See the {list of valid parameters}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS] in the PostgreSQL documentation.
221
+ *
222
+ * There are two accepted formats for +connection_string+: plain <code>keyword = value</code> strings and URIs.
223
+ * See the documentation of {connection strings}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING].
224
+ *
225
+ * The positional parameter form has the same functionality except that the missing parameters will always take on default values. The parameters are:
228
226
  * [+host+]
229
227
  * server hostname
230
- * [+hostaddr+]
231
- * server address (avoids hostname lookup, overrides +host+)
232
228
  * [+port+]
233
229
  * server port number
230
+ * [+options+]
231
+ * backend options
232
+ * [+tty+]
233
+ * (ignored in newer versions of PostgreSQL)
234
234
  * [+dbname+]
235
235
  * connecting database name
236
236
  * [+user+]
237
237
  * login user name
238
238
  * [+password+]
239
239
  * login password
240
- * [+connect_timeout+]
241
- * maximum time to wait for connection to succeed
242
- * [+options+]
243
- * backend options
244
- * [+tty+]
245
- * (ignored in newer versions of PostgreSQL)
246
- * [+sslmode+]
247
- * (disable|allow|prefer|require)
248
- * [+krbsrvname+]
249
- * kerberos service name
250
- * [+gsslib+]
251
- * GSS library to use for GSSAPI authentication
252
- * [+service+]
253
- * service name to use for additional parameters
254
240
  *
255
241
  * Examples:
256
242
  *
@@ -266,7 +252,7 @@ pgconn_s_allocate( VALUE klass )
266
252
  * # As an Array
267
253
  * PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
268
254
  *
269
- * If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the
255
+ * If the Ruby default internal encoding is set (i.e., <code>Encoding.default_internal != nil</code>), the
270
256
  * connection will have its +client_encoding+ set accordingly.
271
257
  *
272
258
  * Raises a PG::Error if the connection fails.
@@ -291,9 +277,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
291
277
  rb_exc_raise(error);
292
278
  }
293
279
 
294
- #ifdef M17N_SUPPORTED
295
280
  pgconn_set_default_encoding( self );
296
- #endif
297
281
 
298
282
  if (rb_block_given_p()) {
299
283
  return rb_ensure(rb_yield, self, pgconn_finish, self);
@@ -307,14 +291,16 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
307
291
  * PG::Connection.connect_start(connection_string) -> conn
308
292
  * PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn
309
293
  *
310
- * This is an asynchronous version of PG::Connection.connect().
294
+ * This is an asynchronous version of PG::Connection.new.
311
295
  *
312
296
  * Use #connect_poll to poll the status of the connection.
313
297
  *
314
298
  * NOTE: this does *not* set the connection's +client_encoding+ for you if
315
- * Encoding.default_internal is set. To set it after the connection is established,
299
+ * +Encoding.default_internal+ is set. To set it after the connection is established,
316
300
  * call #internal_encoding=. You can also set it automatically by setting
317
- * ENV['PGCLIENTENCODING'], or include the 'options' connection parameter.
301
+ * <code>ENV['PGCLIENTENCODING']</code>, or include the 'options' connection parameter.
302
+ *
303
+ * See also the 'sample' directory of this gem and the corresponding {libpq functions}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS].
318
304
  *
319
305
  */
320
306
  static VALUE
@@ -349,7 +335,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
349
335
  return rb_conn;
350
336
  }
351
337
 
352
- #ifdef HAVE_PQPING
353
338
  /*
354
339
  * call-seq:
355
340
  * PG::Connection.ping(connection_hash) -> Integer
@@ -358,6 +343,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
358
343
  *
359
344
  * Check server status.
360
345
  *
346
+ * See PG::Connection.new for a description of the parameters.
347
+ *
361
348
  * Returns one of:
362
349
  * [+PQPING_OK+]
363
350
  * server is accepting connections
@@ -379,7 +366,6 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
379
366
 
380
367
  return INT2FIX((int)ping);
381
368
  }
382
- #endif
383
369
 
384
370
 
385
371
  /*
@@ -418,16 +404,62 @@ pgconn_s_conndefaults(VALUE self)
418
404
  }
419
405
 
420
406
 
407
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
421
408
  /*
422
409
  * call-seq:
423
- * PG::Connection.encrypt_password( password, username ) -> String
410
+ * conn.encrypt_password( password, username, algorithm=nil ) -> String
411
+ *
412
+ * This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
413
+ * 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.
414
+ * Instead, use this function to convert the password to encrypted form before it is sent.
424
415
  *
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.
416
+ * The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
417
+ * +algorithm+ specifies the encryption algorithm to use to encrypt the password.
418
+ * 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).
419
+ * Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
420
+ * If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
421
+ * That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
422
+ * 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
423
  *
430
424
  * Return value is the encrypted password.
425
+ * The caller can assume the string doesn't contain any special characters that would require escaping.
426
+ *
427
+ * Available since PostgreSQL-10.
428
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
429
+ */
430
+ static VALUE
431
+ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
432
+ {
433
+ char *encrypted = NULL;
434
+ VALUE rval = Qnil;
435
+ VALUE password, username, algorithm;
436
+ PGconn *conn = pg_get_pgconn(self);
437
+
438
+ rb_scan_args( argc, argv, "21", &password, &username, &algorithm );
439
+
440
+ Check_Type(password, T_STRING);
441
+ Check_Type(username, T_STRING);
442
+
443
+ encrypted = gvl_PQencryptPasswordConn(conn, StringValueCStr(password), StringValueCStr(username), RTEST(algorithm) ? StringValueCStr(algorithm) : NULL);
444
+ if ( encrypted ) {
445
+ rval = rb_str_new2( encrypted );
446
+ PQfreemem( encrypted );
447
+ } else {
448
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
449
+ }
450
+
451
+ return rval;
452
+ }
453
+ #endif
454
+
455
+
456
+ /*
457
+ * call-seq:
458
+ * PG::Connection.encrypt_password( password, username ) -> String
459
+ *
460
+ * This is an older, deprecated version of #encrypt_password.
461
+ * The difference is that this function always uses +md5+ as the encryption algorithm.
462
+ *
431
463
  */
432
464
  static VALUE
433
465
  pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
@@ -444,9 +476,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
444
476
  rval = rb_str_new2( encrypted );
445
477
  PQfreemem( encrypted );
446
478
 
447
- OBJ_INFECT( rval, password );
448
- OBJ_INFECT( rval, username );
449
-
450
479
  return rval;
451
480
  }
452
481
 
@@ -592,7 +621,7 @@ pgconn_db(VALUE self)
592
621
  {
593
622
  char *db = PQdb(pg_get_pgconn(self));
594
623
  if (!db) return Qnil;
595
- return rb_tainted_str_new2(db);
624
+ return rb_str_new2(db);
596
625
  }
597
626
 
598
627
  /*
@@ -606,21 +635,21 @@ pgconn_user(VALUE self)
606
635
  {
607
636
  char *user = PQuser(pg_get_pgconn(self));
608
637
  if (!user) return Qnil;
609
- return rb_tainted_str_new2(user);
638
+ return rb_str_new2(user);
610
639
  }
611
640
 
612
641
  /*
613
642
  * call-seq:
614
643
  * conn.pass()
615
644
  *
616
- * Returns the authenticated user name.
645
+ * Returns the authenticated password.
617
646
  */
618
647
  static VALUE
619
648
  pgconn_pass(VALUE self)
620
649
  {
621
650
  char *user = PQpass(pg_get_pgconn(self));
622
651
  if (!user) return Qnil;
623
- return rb_tainted_str_new2(user);
652
+ return rb_str_new2(user);
624
653
  }
625
654
 
626
655
  /*
@@ -634,7 +663,7 @@ pgconn_host(VALUE self)
634
663
  {
635
664
  char *host = PQhost(pg_get_pgconn(self));
636
665
  if (!host) return Qnil;
637
- return rb_tainted_str_new2(host);
666
+ return rb_str_new2(host);
638
667
  }
639
668
 
640
669
  /*
@@ -661,7 +690,7 @@ pgconn_tty(VALUE self)
661
690
  {
662
691
  char *tty = PQtty(pg_get_pgconn(self));
663
692
  if (!tty) return Qnil;
664
- return rb_tainted_str_new2(tty);
693
+ return rb_str_new2(tty);
665
694
  }
666
695
 
667
696
  /*
@@ -675,7 +704,7 @@ pgconn_options(VALUE self)
675
704
  {
676
705
  char *options = PQoptions(pg_get_pgconn(self));
677
706
  if (!options) return Qnil;
678
- return rb_tainted_str_new2(options);
707
+ return rb_str_new2(options);
679
708
  }
680
709
 
681
710
 
@@ -686,6 +715,7 @@ pgconn_options(VALUE self)
686
715
  *
687
716
  * Returns the connection options used by a live connection.
688
717
  *
718
+ * Available since PostgreSQL-9.3
689
719
  */
690
720
  static VALUE
691
721
  pgconn_conninfo( VALUE self )
@@ -755,7 +785,7 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
755
785
  if(ret == NULL)
756
786
  return Qnil;
757
787
  else
758
- return rb_tainted_str_new2(ret);
788
+ return rb_str_new2(ret);
759
789
  }
760
790
 
761
791
  /*
@@ -800,13 +830,15 @@ pgconn_error_message(VALUE self)
800
830
  {
801
831
  char *error = PQerrorMessage(pg_get_pgconn(self));
802
832
  if (!error) return Qnil;
803
- return rb_tainted_str_new2(error);
833
+ return rb_str_new2(error);
804
834
  }
805
835
 
806
836
  /*
807
837
  * call-seq:
808
838
  * conn.socket() -> Integer
809
839
  *
840
+ * This method is deprecated. Please use the more portable method #socket_io .
841
+ *
810
842
  * Returns the socket's file descriptor for this connection.
811
843
  * <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
812
844
  * If you do so, you will likely also want to set <tt>autoclose=false</tt>
@@ -815,34 +847,31 @@ pgconn_error_message(VALUE self)
815
847
  * creates an IO that's associated with the connection object itself,
816
848
  * and so won't go out of scope until the connection does.
817
849
  *
818
- * *Note:* On Windows the file descriptor is not really usable,
850
+ * *Note:* On Windows the file descriptor is not usable,
819
851
  * since it can not be used to build a Ruby IO object.
820
852
  */
821
853
  static VALUE
822
854
  pgconn_socket(VALUE self)
823
855
  {
824
856
  int sd;
857
+ pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
858
+
825
859
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
826
860
  rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
827
861
  return INT2NUM(sd);
828
862
  }
829
863
 
830
-
831
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
832
-
833
864
  /*
834
865
  * call-seq:
835
866
  * conn.socket_io() -> IO
836
867
  *
837
- * Fetch a memoized IO object created from the Connection's underlying socket.
868
+ * Fetch a memorized IO object created from the Connection's underlying socket.
838
869
  * This object can be used for IO.select to wait for events while running
839
870
  * asynchronous API calls.
840
871
  *
841
872
  * Using this instead of #socket avoids the problem of the underlying connection
842
873
  * 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+.
874
+ * goes out of scope. In contrast to #socket, it also works on Windows.
846
875
  */
847
876
  static VALUE
848
877
  pgconn_socket_io(VALUE self)
@@ -859,16 +888,15 @@ pgconn_socket_io(VALUE self)
859
888
 
860
889
  #ifdef _WIN32
861
890
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
891
+ this->ruby_sd = ruby_sd;
862
892
  #else
863
893
  ruby_sd = sd;
864
894
  #endif
865
895
 
866
896
  socket_io = rb_funcall( rb_cIO, rb_intern("for_fd"), 1, INT2NUM(ruby_sd) );
867
897
 
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
- }
898
+ /* Disable autoclose feature */
899
+ rb_funcall( socket_io, id_autoclose, 1, Qfalse );
872
900
 
873
901
  this->socket_io = socket_io;
874
902
  }
@@ -876,8 +904,6 @@ pgconn_socket_io(VALUE self)
876
904
  return socket_io;
877
905
  }
878
906
 
879
- #endif
880
-
881
907
  /*
882
908
  * call-seq:
883
909
  * conn.backend_pid() -> Integer
@@ -926,40 +952,31 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
926
952
 
927
953
  /*
928
954
  * call-seq:
929
- * conn.exec(sql) -> PG::Result
930
- * conn.exec(sql) {|pg_result| block }
931
- *
932
- * Sends SQL query request specified by _sql_ to PostgreSQL.
933
- * Returns a PG::Result instance on success.
934
- * On failure, it raises a PG::Error.
955
+ * conn.sync_exec(sql) -> PG::Result
956
+ * conn.sync_exec(sql) {|pg_result| block }
935
957
  *
936
- * For backward compatibility, if you pass more than one parameter to this method,
937
- * it will call #exec_params for you. New code should explicitly use #exec_params if
938
- * argument placeholders are used.
958
+ * This function has the same behavior as #async_exec, but is implemented using the synchronous command processing API of libpq.
959
+ * It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
939
960
  *
940
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
941
- * and the PG::Result object will automatically be cleared when the block terminates.
942
- * In this instance, <code>conn.exec</code> returns the value of the block.
961
+ * Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
962
+ * However #async_exec has two advantages:
943
963
  *
944
- * #exec is implemented on the synchronous command processing API of libpq, whereas
945
- * #async_exec is implemented on the asynchronous API.
946
- * #exec is somewhat faster that #async_exec, but blocks any signals to be processed until
947
- * the query is finished. This is most notably visible by a delayed reaction to Control+C.
948
- * Both methods ensure that other threads can process while waiting for the server to
949
- * complete the request.
964
+ * 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
965
+ * 2. Ruby VM gets notified about IO blocked operations.
966
+ * It can therefore schedule things like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
950
967
  */
951
968
  static VALUE
952
969
  pgconn_exec(int argc, VALUE *argv, VALUE self)
953
970
  {
954
- PGconn *conn = pg_get_pgconn(self);
971
+ t_pg_connection *this = pg_get_connection_safe( self );
955
972
  PGresult *result = NULL;
956
973
  VALUE rb_pgresult;
957
974
 
958
- /* If called with no parameters, use PQexec */
959
- if ( argc == 1 ) {
975
+ /* If called with no or nil parameters, use PQexec for compatibility */
976
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
960
977
  VALUE query_str = argv[0];
961
978
 
962
- result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
979
+ result = gvl_PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx));
963
980
  rb_pgresult = pg_new_result(result, self);
964
981
  pg_result_check(rb_pgresult);
965
982
  if (rb_block_given_p()) {
@@ -967,11 +984,10 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
967
984
  }
968
985
  return rb_pgresult;
969
986
  }
987
+ pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
970
988
 
971
989
  /* Otherwise, just call #exec_params instead for backward-compatibility */
972
- else {
973
- return pgconn_exec_params( argc, argv, self );
974
- }
990
+ return pgconn_exec_params( argc, argv, self );
975
991
 
976
992
  }
977
993
 
@@ -1222,66 +1238,34 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1222
1238
 
1223
1239
  /*
1224
1240
  * call-seq:
1225
- * conn.exec_params(sql, params[, result_format[, type_map]] ) -> PG::Result
1226
- * conn.exec_params(sql, params[, result_format[, type_map]] ) {|pg_result| block }
1227
- *
1228
- * Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
1229
- * for parameters.
1230
- *
1231
- * Returns a PG::Result instance on success. On failure, it raises a PG::Error.
1232
- *
1233
- * +params+ is an array of the bind parameters for the SQL query.
1234
- * Each element of the +params+ array may be either:
1235
- * a hash of the form:
1236
- * {:value => String (value of bind parameter)
1237
- * :type => Integer (oid of type of bind parameter)
1238
- * :format => Integer (0 for text, 1 for binary)
1239
- * }
1240
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1241
- * { :value => <string value>, :type => 0, :format => 0 }
1242
- *
1243
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1244
- * inside the SQL query. The 0th element of the +params+ array is bound
1245
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1246
- *
1247
- * If the types are not specified, they will be inferred by PostgreSQL.
1248
- * Instead of specifying type oids, it's recommended to simply add
1249
- * explicit casts in the query to ensure that the right type is used.
1241
+ * conn.sync_exec_params(sql, params[, result_format[, type_map]] ) -> PG::Result
1242
+ * conn.sync_exec_params(sql, params[, result_format[, type_map]] ) {|pg_result| block }
1250
1243
  *
1251
- * For example: "SELECT $1::int"
1252
- *
1253
- * The optional +result_format+ should be 0 for text results, 1
1254
- * for binary.
1255
- *
1256
- * 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
1258
- * based on the encoders defined by the type map. When a type encoder is used
1259
- * the format and oid of a given bind parameter are retrieved from the encoder
1260
- * instead out of the hash form described above.
1261
- *
1262
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1263
- * and the PG::Result object will automatically be cleared when the block terminates.
1264
- * In this instance, <code>conn.exec</code> returns the value of the block.
1244
+ * This function has the same behavior as #async_exec_params, but is implemented using the synchronous command processing API of libpq.
1245
+ * See #async_exec for the differences between the two API variants.
1246
+ * It's not recommended to use explicit sync or async variants but #exec_params instead, unless you have a good reason to do so.
1265
1247
  */
1266
1248
  static VALUE
1267
1249
  pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1268
1250
  {
1269
- PGconn *conn = pg_get_pgconn(self);
1251
+ t_pg_connection *this = pg_get_connection_safe( self );
1270
1252
  PGresult *result = NULL;
1271
1253
  VALUE rb_pgresult;
1272
1254
  VALUE command, in_res_fmt;
1273
1255
  int nParams;
1274
1256
  int resultFormat;
1275
- struct query_params_data paramsData = { ENCODING_GET(self) };
1257
+ struct query_params_data paramsData = { this->enc_idx };
1276
1258
 
1259
+ /* For compatibility we accept 1 to 4 parameters */
1277
1260
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1278
1261
  paramsData.with_types = 1;
1279
1262
 
1280
1263
  /*
1281
- * Handle the edge-case where the caller is coming from #exec, but passed an explict +nil+
1282
- * for the second parameter.
1264
+ * For backward compatibility no or +nil+ for the second parameter
1265
+ * is passed to #exec
1283
1266
  */
1284
1267
  if ( NIL_P(paramsData.params) ) {
1268
+ pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
1285
1269
  return pgconn_exec( 1, argv, self );
1286
1270
  }
1287
1271
  pgconn_query_assign_typemap( self, &paramsData );
@@ -1289,7 +1273,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1289
1273
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1290
1274
  nParams = alloc_query_params( &paramsData );
1291
1275
 
1292
- result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1276
+ result = gvl_PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1293
1277
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1294
1278
 
1295
1279
  free_query_params( &paramsData );
@@ -1306,28 +1290,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1306
1290
 
1307
1291
  /*
1308
1292
  * call-seq:
1309
- * conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
1310
- *
1311
- * Prepares statement _sql_ with name _name_ to be executed later.
1312
- * Returns a PG::Result instance on success.
1313
- * On failure, it raises a PG::Error.
1314
- *
1315
- * +param_types+ is an optional parameter to specify the Oids of the
1316
- * types of the parameters.
1317
- *
1318
- * If the types are not specified, they will be inferred by PostgreSQL.
1319
- * Instead of specifying type oids, it's recommended to simply add
1320
- * explicit casts in the query to ensure that the right type is used.
1321
- *
1322
- * For example: "SELECT $1::int"
1293
+ * conn.sync_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
1323
1294
  *
1324
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1325
- * inside the SQL query.
1295
+ * This function has the same behavior as #async_prepare, but is implemented using the synchronous command processing API of libpq.
1296
+ * See #async_exec for the differences between the two API variants.
1297
+ * It's not recommended to use explicit sync or async variants but #prepare instead, unless you have a good reason to do so.
1326
1298
  */
1327
1299
  static VALUE
1328
1300
  pgconn_prepare(int argc, VALUE *argv, VALUE self)
1329
1301
  {
1330
- PGconn *conn = pg_get_pgconn(self);
1302
+ t_pg_connection *this = pg_get_connection_safe( self );
1331
1303
  PGresult *result = NULL;
1332
1304
  VALUE rb_pgresult;
1333
1305
  VALUE name, command, in_paramtypes;
@@ -1337,7 +1309,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1337
1309
  Oid *paramTypes = NULL;
1338
1310
  const char *name_cstr;
1339
1311
  const char *command_cstr;
1340
- int enc_idx = ENCODING_GET(self);
1312
+ int enc_idx = this->enc_idx;
1341
1313
 
1342
1314
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1343
1315
  name_cstr = pg_cstr_enc(name, enc_idx);
@@ -1355,7 +1327,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1355
1327
  paramTypes[i] = NUM2UINT(param);
1356
1328
  }
1357
1329
  }
1358
- result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1330
+ result = gvl_PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
1359
1331
 
1360
1332
  xfree(paramTypes);
1361
1333
 
@@ -1366,49 +1338,23 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1366
1338
 
1367
1339
  /*
1368
1340
  * call-seq:
1369
- * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
1370
- * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
1371
- *
1372
- * Execute prepared named statement specified by _statement_name_.
1373
- * Returns a PG::Result instance on success.
1374
- * On failure, it raises a PG::Error.
1375
- *
1376
- * +params+ is an array of the optional bind parameters for the
1377
- * SQL query. Each element of the +params+ array may be either:
1378
- * a hash of the form:
1379
- * {:value => String (value of bind parameter)
1380
- * :format => Integer (0 for text, 1 for binary)
1381
- * }
1382
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1383
- * { :value => <string value>, :format => 0 }
1384
- *
1385
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1386
- * inside the SQL query. The 0th element of the +params+ array is bound
1387
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1388
- *
1389
- * The optional +result_format+ should be 0 for text results, 1
1390
- * for binary.
1391
- *
1392
- * 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
1394
- * based on the encoders defined by the type map. When a type encoder is used
1395
- * the format and oid of a given bind parameter are retrieved from the encoder
1396
- * instead out of the hash form described above.
1341
+ * conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
1342
+ * conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
1397
1343
  *
1398
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1399
- * and the PG::Result object will automatically be cleared when the block terminates.
1400
- * In this instance, <code>conn.exec_prepared</code> returns the value of the block.
1344
+ * This function has the same behavior as #async_exec_prepared, but is implemented using the synchronous command processing API of libpq.
1345
+ * See #async_exec for the differences between the two API variants.
1346
+ * It's not recommended to use explicit sync or async variants but #exec_prepared instead, unless you have a good reason to do so.
1401
1347
  */
1402
1348
  static VALUE
1403
1349
  pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1404
1350
  {
1405
- PGconn *conn = pg_get_pgconn(self);
1351
+ t_pg_connection *this = pg_get_connection_safe( self );
1406
1352
  PGresult *result = NULL;
1407
1353
  VALUE rb_pgresult;
1408
1354
  VALUE name, in_res_fmt;
1409
1355
  int nParams;
1410
1356
  int resultFormat;
1411
- struct query_params_data paramsData = { ENCODING_GET(self) };
1357
+ struct query_params_data paramsData = { this->enc_idx };
1412
1358
 
1413
1359
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1414
1360
  paramsData.with_types = 0;
@@ -1421,7 +1367,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1421
1367
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1422
1368
  nParams = alloc_query_params( &paramsData );
1423
1369
 
1424
- result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1370
+ result = gvl_PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1425
1371
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1426
1372
  resultFormat);
1427
1373
 
@@ -1438,25 +1384,26 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1438
1384
 
1439
1385
  /*
1440
1386
  * call-seq:
1441
- * conn.describe_prepared( statement_name ) -> PG::Result
1387
+ * conn.sync_describe_prepared( statement_name ) -> PG::Result
1442
1388
  *
1443
- * Retrieve information about the prepared statement
1444
- * _statement_name_.
1389
+ * This function has the same behavior as #async_describe_prepared, but is implemented using the synchronous command processing API of libpq.
1390
+ * See #async_exec for the differences between the two API variants.
1391
+ * It's not recommended to use explicit sync or async variants but #describe_prepared instead, unless you have a good reason to do so.
1445
1392
  */
1446
1393
  static VALUE
1447
1394
  pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1448
1395
  {
1449
1396
  PGresult *result;
1450
1397
  VALUE rb_pgresult;
1451
- PGconn *conn = pg_get_pgconn(self);
1398
+ t_pg_connection *this = pg_get_connection_safe( self );
1452
1399
  const char *stmt;
1453
1400
  if(NIL_P(stmt_name)) {
1454
1401
  stmt = NULL;
1455
1402
  }
1456
1403
  else {
1457
- stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1404
+ stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1458
1405
  }
1459
- result = gvl_PQdescribePrepared(conn, stmt);
1406
+ result = gvl_PQdescribePrepared(this->pgconn, stmt);
1460
1407
  rb_pgresult = pg_new_result(result, self);
1461
1408
  pg_result_check(rb_pgresult);
1462
1409
  return rb_pgresult;
@@ -1465,9 +1412,11 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1465
1412
 
1466
1413
  /*
1467
1414
  * call-seq:
1468
- * conn.describe_portal( portal_name ) -> PG::Result
1415
+ * conn.sync_describe_portal( portal_name ) -> PG::Result
1469
1416
  *
1470
- * Retrieve information about the portal _portal_name_.
1417
+ * This function has the same behavior as #async_describe_portal, but is implemented using the synchronous command processing API of libpq.
1418
+ * See #async_exec for the differences between the two API variants.
1419
+ * It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
1471
1420
  */
1472
1421
  static VALUE
1473
1422
  pgconn_describe_portal(self, stmt_name)
@@ -1475,15 +1424,15 @@ pgconn_describe_portal(self, stmt_name)
1475
1424
  {
1476
1425
  PGresult *result;
1477
1426
  VALUE rb_pgresult;
1478
- PGconn *conn = pg_get_pgconn(self);
1427
+ t_pg_connection *this = pg_get_connection_safe( self );
1479
1428
  const char *stmt;
1480
1429
  if(NIL_P(stmt_name)) {
1481
1430
  stmt = NULL;
1482
1431
  }
1483
1432
  else {
1484
- stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1433
+ stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1485
1434
  }
1486
- result = gvl_PQdescribePortal(conn, stmt);
1435
+ result = gvl_PQdescribePortal(this->pgconn, stmt);
1487
1436
  rb_pgresult = pg_new_result(result, self);
1488
1437
  pg_result_check(rb_pgresult);
1489
1438
  return rb_pgresult;
@@ -1530,13 +1479,15 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1530
1479
  * Consider using exec_params, which avoids the need for passing values
1531
1480
  * inside of SQL commands.
1532
1481
  *
1533
- * Encoding of escaped string will be equal to client encoding of connection.
1482
+ * Character encoding of escaped string will be equal to client encoding of connection.
1534
1483
  *
1535
1484
  * NOTE: This class version of this method can only be used safely in client
1536
1485
  * programs that use a single PostgreSQL connection at a time (in this case it can
1537
1486
  * find out what it needs to know "behind the scenes"). It might give the wrong
1538
1487
  * results if used in programs that use multiple database connections; use the
1539
1488
  * same method on the connection object in such cases.
1489
+ *
1490
+ * See also convenience functions #escape_literal and #escape_identifier which also add proper quotes around the string.
1540
1491
  */
1541
1492
  static VALUE
1542
1493
  pgconn_s_escape(VALUE self, VALUE string)
@@ -1547,8 +1498,8 @@ pgconn_s_escape(VALUE self, VALUE string)
1547
1498
  int enc_idx;
1548
1499
  int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
1549
1500
 
1550
- Check_Type(string, T_STRING);
1551
- enc_idx = ENCODING_GET( singleton ? string : self );
1501
+ StringValueCStr(string);
1502
+ enc_idx = singleton ? ENCODING_GET(string) : pg_get_connection(self)->enc_idx;
1552
1503
  if( ENCODING_GET(string) != enc_idx ){
1553
1504
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1554
1505
  }
@@ -1565,7 +1516,6 @@ pgconn_s_escape(VALUE self, VALUE string)
1565
1516
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1566
1517
  }
1567
1518
  rb_str_set_len(result, size);
1568
- OBJ_INFECT(result, string);
1569
1519
 
1570
1520
  return result;
1571
1521
  }
@@ -1611,7 +1561,6 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
1611
1561
  }
1612
1562
 
1613
1563
  ret = rb_str_new((char*)to, to_len - 1);
1614
- OBJ_INFECT(ret, str);
1615
1564
  PQfreemem(to);
1616
1565
  return ret;
1617
1566
  }
@@ -1641,50 +1590,47 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
1641
1590
  to = PQunescapeBytea(from, &to_len);
1642
1591
 
1643
1592
  ret = rb_str_new((char*)to, to_len);
1644
- OBJ_INFECT(ret, str);
1645
1593
  PQfreemem(to);
1646
1594
  return ret;
1647
1595
  }
1648
1596
 
1649
- #ifdef HAVE_PQESCAPELITERAL
1650
1597
  /*
1651
1598
  * call-seq:
1652
1599
  * conn.escape_literal( str ) -> String
1653
1600
  *
1654
1601
  * Escape an arbitrary String +str+ as a literal.
1602
+ *
1603
+ * See also PG::TextEncoder::QuotedLiteral for a type cast integrated version of this function.
1655
1604
  */
1656
1605
  static VALUE
1657
1606
  pgconn_escape_literal(VALUE self, VALUE string)
1658
1607
  {
1659
- PGconn *conn = pg_get_pgconn(self);
1608
+ t_pg_connection *this = pg_get_connection_safe( self );
1660
1609
  char *escaped = NULL;
1661
1610
  VALUE error;
1662
1611
  VALUE result = Qnil;
1663
- int enc_idx = ENCODING_GET(self);
1612
+ int enc_idx = this->enc_idx;
1664
1613
 
1665
- Check_Type(string, T_STRING);
1614
+ StringValueCStr(string);
1666
1615
  if( ENCODING_GET(string) != enc_idx ){
1667
1616
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1668
1617
  }
1669
1618
 
1670
- escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1619
+ escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1671
1620
  if (escaped == NULL)
1672
1621
  {
1673
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1622
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1674
1623
  rb_iv_set(error, "@connection", self);
1675
1624
  rb_exc_raise(error);
1676
1625
  return Qnil;
1677
1626
  }
1678
1627
  result = rb_str_new2(escaped);
1679
1628
  PQfreemem(escaped);
1680
- OBJ_INFECT(result, string);
1681
1629
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
1682
1630
 
1683
1631
  return result;
1684
1632
  }
1685
- #endif
1686
1633
 
1687
- #ifdef HAVE_PQESCAPEIDENTIFIER
1688
1634
  /*
1689
1635
  * call-seq:
1690
1636
  * conn.escape_identifier( str ) -> String
@@ -1698,35 +1644,32 @@ pgconn_escape_literal(VALUE self, VALUE string)
1698
1644
  static VALUE
1699
1645
  pgconn_escape_identifier(VALUE self, VALUE string)
1700
1646
  {
1701
- PGconn *conn = pg_get_pgconn(self);
1647
+ t_pg_connection *this = pg_get_connection_safe( self );
1702
1648
  char *escaped = NULL;
1703
1649
  VALUE error;
1704
1650
  VALUE result = Qnil;
1705
- int enc_idx = ENCODING_GET(self);
1651
+ int enc_idx = this->enc_idx;
1706
1652
 
1707
- Check_Type(string, T_STRING);
1653
+ StringValueCStr(string);
1708
1654
  if( ENCODING_GET(string) != enc_idx ){
1709
1655
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1710
1656
  }
1711
1657
 
1712
- escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1658
+ escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1713
1659
  if (escaped == NULL)
1714
1660
  {
1715
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1661
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1716
1662
  rb_iv_set(error, "@connection", self);
1717
1663
  rb_exc_raise(error);
1718
1664
  return Qnil;
1719
1665
  }
1720
1666
  result = rb_str_new2(escaped);
1721
1667
  PQfreemem(escaped);
1722
- OBJ_INFECT(result, string);
1723
1668
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
1724
1669
 
1725
1670
  return result;
1726
1671
  }
1727
- #endif
1728
1672
 
1729
- #ifdef HAVE_PQSETSINGLEROWMODE
1730
1673
  /*
1731
1674
  * call-seq:
1732
1675
  * conn.set_single_row_mode -> self
@@ -1762,7 +1705,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1762
1705
  * # do something with the received row
1763
1706
  * end
1764
1707
  * end
1765
- *
1766
1708
  */
1767
1709
  static VALUE
1768
1710
  pgconn_set_single_row_mode(VALUE self)
@@ -1779,17 +1721,55 @@ pgconn_set_single_row_mode(VALUE self)
1779
1721
 
1780
1722
  return self;
1781
1723
  }
1782
- #endif
1724
+
1725
+ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1726
+
1727
+ /*
1728
+ * call-seq:
1729
+ * conn.send_query(sql) -> nil
1730
+ *
1731
+ * Sends SQL query request specified by _sql_ to PostgreSQL for
1732
+ * asynchronous processing, and immediately returns.
1733
+ * On failure, it raises a PG::Error.
1734
+ *
1735
+ * For backward compatibility, if you pass more than one parameter to this method,
1736
+ * it will call #send_query_params for you. New code should explicitly use #send_query_params if
1737
+ * argument placeholders are used.
1738
+ *
1739
+ */
1740
+ static VALUE
1741
+ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1742
+ {
1743
+ t_pg_connection *this = pg_get_connection_safe( self );
1744
+ VALUE error;
1745
+
1746
+ /* If called with no or nil parameters, use PQexec for compatibility */
1747
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1748
+ if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0) {
1749
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1750
+ rb_iv_set(error, "@connection", self);
1751
+ rb_exc_raise(error);
1752
+ }
1753
+ return Qnil;
1754
+ }
1755
+
1756
+ pg_deprecated(2, ("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
1757
+
1758
+ /* If called with parameters, and optionally result_format,
1759
+ * use PQsendQueryParams
1760
+ */
1761
+ return pgconn_send_query_params( argc, argv, self);
1762
+ }
1783
1763
 
1784
1764
  /*
1785
1765
  * call-seq:
1786
- * conn.send_query(sql [, params, result_format[, type_map ]] ) -> nil
1766
+ * conn.send_query_params(sql, params [, result_format [, type_map ]] ) -> nil
1787
1767
  *
1788
1768
  * Sends SQL query request specified by _sql_ to PostgreSQL for
1789
1769
  * asynchronous processing, and immediately returns.
1790
1770
  * On failure, it raises a PG::Error.
1791
1771
  *
1792
- * +params+ is an optional array of the bind parameters for the SQL query.
1772
+ * +params+ is an array of the bind parameters for the SQL query.
1793
1773
  * Each element of the +params+ array may be either:
1794
1774
  * a hash of the form:
1795
1775
  * {:value => String (value of bind parameter)
@@ -1812,52 +1792,38 @@ pgconn_set_single_row_mode(VALUE self)
1812
1792
  * The optional +result_format+ should be 0 for text results, 1
1813
1793
  * for binary.
1814
1794
  *
1815
- * 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
1795
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1796
+ * This will type cast the params from various Ruby types before transmission
1817
1797
  * based on the encoders defined by the type map. When a type encoder is used
1818
1798
  * the format and oid of a given bind parameter are retrieved from the encoder
1819
1799
  * instead out of the hash form described above.
1820
1800
  *
1821
1801
  */
1822
1802
  static VALUE
1823
- pgconn_send_query(int argc, VALUE *argv, VALUE self)
1803
+ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1824
1804
  {
1825
- PGconn *conn = pg_get_pgconn(self);
1805
+ t_pg_connection *this = pg_get_connection_safe( self );
1826
1806
  int result;
1827
1807
  VALUE command, in_res_fmt;
1828
1808
  VALUE error;
1829
1809
  int nParams;
1830
1810
  int resultFormat;
1831
- struct query_params_data paramsData = { ENCODING_GET(self) };
1811
+ struct query_params_data paramsData = { this->enc_idx };
1832
1812
 
1833
- rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1813
+ rb_scan_args(argc, argv, "22", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1834
1814
  paramsData.with_types = 1;
1835
1815
 
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
1816
  pgconn_query_assign_typemap( self, &paramsData );
1851
1817
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1852
1818
  nParams = alloc_query_params( &paramsData );
1853
1819
 
1854
- result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1820
+ result = gvl_PQsendQueryParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1855
1821
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1856
1822
 
1857
1823
  free_query_params( &paramsData );
1858
1824
 
1859
1825
  if(result == 0) {
1860
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1826
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1861
1827
  rb_iv_set(error, "@connection", self);
1862
1828
  rb_exc_raise(error);
1863
1829
  }
@@ -1887,7 +1853,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1887
1853
  static VALUE
1888
1854
  pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1889
1855
  {
1890
- PGconn *conn = pg_get_pgconn(self);
1856
+ t_pg_connection *this = pg_get_connection_safe( self );
1891
1857
  int result;
1892
1858
  VALUE name, command, in_paramtypes;
1893
1859
  VALUE param;
@@ -1897,7 +1863,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1897
1863
  Oid *paramTypes = NULL;
1898
1864
  const char *name_cstr;
1899
1865
  const char *command_cstr;
1900
- int enc_idx = ENCODING_GET(self);
1866
+ int enc_idx = this->enc_idx;
1901
1867
 
1902
1868
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1903
1869
  name_cstr = pg_cstr_enc(name, enc_idx);
@@ -1915,12 +1881,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1915
1881
  paramTypes[i] = NUM2UINT(param);
1916
1882
  }
1917
1883
  }
1918
- result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1884
+ result = gvl_PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
1919
1885
 
1920
1886
  xfree(paramTypes);
1921
1887
 
1922
1888
  if(result == 0) {
1923
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1889
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1924
1890
  rb_iv_set(error, "@connection", self);
1925
1891
  rb_exc_raise(error);
1926
1892
  }
@@ -1952,8 +1918,8 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1952
1918
  * The optional +result_format+ should be 0 for text results, 1
1953
1919
  * for binary.
1954
1920
  *
1955
- * 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
1921
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1922
+ * This will type cast the params from various Ruby types before transmission
1957
1923
  * based on the encoders defined by the type map. When a type encoder is used
1958
1924
  * the format and oid of a given bind parameter are retrieved from the encoder
1959
1925
  * instead out of the hash form described above.
@@ -1962,13 +1928,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1962
1928
  static VALUE
1963
1929
  pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1964
1930
  {
1965
- PGconn *conn = pg_get_pgconn(self);
1931
+ t_pg_connection *this = pg_get_connection_safe( self );
1966
1932
  int result;
1967
1933
  VALUE name, in_res_fmt;
1968
1934
  VALUE error;
1969
1935
  int nParams;
1970
1936
  int resultFormat;
1971
- struct query_params_data paramsData = { ENCODING_GET(self) };
1937
+ struct query_params_data paramsData = { this->enc_idx };
1972
1938
 
1973
1939
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1974
1940
  paramsData.with_types = 0;
@@ -1982,14 +1948,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1982
1948
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1983
1949
  nParams = alloc_query_params( &paramsData );
1984
1950
 
1985
- result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1951
+ result = gvl_PQsendQueryPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1986
1952
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1987
1953
  resultFormat);
1988
1954
 
1989
1955
  free_query_params( &paramsData );
1990
1956
 
1991
1957
  if(result == 0) {
1992
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1958
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1993
1959
  rb_iv_set(error, "@connection", self);
1994
1960
  rb_exc_raise(error);
1995
1961
  }
@@ -2007,10 +1973,10 @@ static VALUE
2007
1973
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2008
1974
  {
2009
1975
  VALUE error;
2010
- PGconn *conn = pg_get_pgconn(self);
1976
+ t_pg_connection *this = pg_get_connection_safe( self );
2011
1977
  /* returns 0 on failure */
2012
- if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
2013
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1978
+ if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0) {
1979
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2014
1980
  rb_iv_set(error, "@connection", self);
2015
1981
  rb_exc_raise(error);
2016
1982
  }
@@ -2029,10 +1995,10 @@ static VALUE
2029
1995
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2030
1996
  {
2031
1997
  VALUE error;
2032
- PGconn *conn = pg_get_pgconn(self);
1998
+ t_pg_connection *this = pg_get_connection_safe( self );
2033
1999
  /* returns 0 on failure */
2034
- if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
2035
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
2000
+ if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
2001
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2036
2002
  rb_iv_set(error, "@connection", self);
2037
2003
  rb_exc_raise(error);
2038
2004
  }
@@ -2203,7 +2169,6 @@ pgconn_flush(self)
2203
2169
  static VALUE
2204
2170
  pgconn_cancel(VALUE self)
2205
2171
  {
2206
- #ifdef HAVE_PQGETCANCEL
2207
2172
  char errbuf[256];
2208
2173
  PGcancel *cancel;
2209
2174
  VALUE retval;
@@ -2221,9 +2186,6 @@ pgconn_cancel(VALUE self)
2221
2186
 
2222
2187
  PQfreeCancel(cancel);
2223
2188
  return retval;
2224
- #else
2225
- rb_notimplement();
2226
- #endif
2227
2189
  }
2228
2190
 
2229
2191
 
@@ -2237,7 +2199,7 @@ pgconn_cancel(VALUE self)
2237
2199
  static VALUE
2238
2200
  pgconn_notifies(VALUE self)
2239
2201
  {
2240
- PGconn* conn = pg_get_pgconn(self);
2202
+ t_pg_connection *this = pg_get_connection_safe( self );
2241
2203
  PGnotify *notification;
2242
2204
  VALUE hash;
2243
2205
  VALUE sym_relname, sym_be_pid, sym_extra;
@@ -2247,17 +2209,17 @@ pgconn_notifies(VALUE self)
2247
2209
  sym_be_pid = ID2SYM(rb_intern("be_pid"));
2248
2210
  sym_extra = ID2SYM(rb_intern("extra"));
2249
2211
 
2250
- notification = gvl_PQnotifies(conn);
2212
+ notification = gvl_PQnotifies(this->pgconn);
2251
2213
  if (notification == NULL) {
2252
2214
  return Qnil;
2253
2215
  }
2254
2216
 
2255
2217
  hash = rb_hash_new();
2256
- relname = rb_tainted_str_new2(notification->relname);
2218
+ relname = rb_str_new2(notification->relname);
2257
2219
  be_pid = INT2NUM(notification->be_pid);
2258
- extra = rb_tainted_str_new2(notification->extra);
2259
- PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2260
- PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
2220
+ extra = rb_str_new2(notification->extra);
2221
+ PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
2222
+ PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
2261
2223
 
2262
2224
  rb_hash_aset(hash, sym_relname, relname);
2263
2225
  rb_hash_aset(hash, sym_be_pid, be_pid);
@@ -2267,56 +2229,15 @@ pgconn_notifies(VALUE self)
2267
2229
  return hash;
2268
2230
  }
2269
2231
 
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
2232
  /* Win32 + Ruby 1.9+ */
2308
- #if defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
2233
+ #if defined( _WIN32 )
2309
2234
  /*
2310
2235
  * On Windows, use platform-specific strategies to wait for the socket
2311
- * instead of rb_thread_select().
2236
+ * instead of rb_wait_for_single_fd().
2312
2237
  */
2313
2238
 
2314
2239
  int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2315
2240
 
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
2241
  static void *
2321
2242
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2322
2243
  {
@@ -2393,7 +2314,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2393
2314
 
2394
2315
  #else
2395
2316
 
2396
- /* non Win32 or Win32+Ruby-1.8 */
2317
+ /* non Win32 */
2397
2318
 
2398
2319
  static void *
2399
2320
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
@@ -2401,11 +2322,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2401
2322
  int sd = PQsocket( conn );
2402
2323
  int ret;
2403
2324
  void *retval;
2404
- rb_fdset_t sd_rset;
2405
2325
  struct timeval aborttime={0,0}, currtime, waittime;
2406
- #ifdef _WIN32
2407
- rb_fdset_t crt_sd_rset;
2408
- #endif
2409
2326
 
2410
2327
  if ( sd < 0 )
2411
2328
  rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
@@ -2414,25 +2331,12 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2414
2331
  if ( PQconsumeInput(conn) == 0 )
2415
2332
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2416
2333
 
2417
- rb_fd_init( &sd_rset );
2418
-
2419
2334
  if ( ptimeout ) {
2420
2335
  gettimeofday(&currtime, NULL);
2421
2336
  timeradd(&currtime, ptimeout, &aborttime);
2422
2337
  }
2423
2338
 
2424
2339
  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
2340
  if ( ptimeout ) {
2437
2341
  gettimeofday(&currtime, NULL);
2438
2342
  timersub(&aborttime, &currtime, &waittime);
@@ -2441,35 +2345,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2441
2345
  /* Is the given timeout valid? */
2442
2346
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2443
2347
  /* 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 );
2348
+ ret = rb_wait_for_single_fd( sd, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
2445
2349
  } else {
2446
2350
  ret = 0;
2447
2351
  }
2448
2352
 
2449
-
2450
- #ifdef _WIN32
2451
- cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2452
- #endif
2453
-
2454
2353
  if ( ret < 0 ){
2455
- rb_fd_term( &sd_rset );
2456
- rb_sys_fail( "rb_thread_select()" );
2354
+ rb_sys_fail( "rb_wait_for_single_fd()" );
2457
2355
  }
2458
2356
 
2459
2357
  /* Return false if the select() timed out */
2460
2358
  if ( ret == 0 ){
2461
- rb_fd_term( &sd_rset );
2462
2359
  return NULL;
2463
2360
  }
2464
2361
 
2465
2362
  /* Check for connection errors (PQisBusy is true on connection errors) */
2466
2363
  if ( PQconsumeInput(conn) == 0 ){
2467
- rb_fd_term( &sd_rset );
2468
2364
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2469
2365
  }
2470
2366
  }
2471
2367
 
2472
- rb_fd_term( &sd_rset );
2473
2368
  return retval;
2474
2369
  }
2475
2370
 
@@ -2484,27 +2379,20 @@ notify_readable(PGconn *conn)
2484
2379
 
2485
2380
  /*
2486
2381
  * 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
2382
+ * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } -> String
2490
2383
  *
2491
2384
  * Blocks while waiting for notification(s), or until the optional
2492
2385
  * _timeout_ is reached, whichever comes first. _timeout_ is
2493
2386
  * measured in seconds and can be fractional.
2494
2387
  *
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
- *
2388
+ * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY event otherwise.
2389
+ * If used in block form, passes the name of the NOTIFY +event+, the generating
2390
+ * +pid+ and the optional +payload+ string into the block.
2503
2391
  */
2504
2392
  static VALUE
2505
2393
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2506
2394
  {
2507
- PGconn *conn = pg_get_pgconn( self );
2395
+ t_pg_connection *this = pg_get_connection_safe( self );
2508
2396
  PGnotify *pnotification;
2509
2397
  struct timeval timeout;
2510
2398
  struct timeval *ptimeout = NULL;
@@ -2520,20 +2408,18 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2520
2408
  ptimeout = &timeout;
2521
2409
  }
2522
2410
 
2523
- pnotification = (PGnotify*) wait_socket_readable( conn, ptimeout, notify_readable);
2411
+ pnotification = (PGnotify*) wait_socket_readable( this->pgconn, ptimeout, notify_readable);
2524
2412
 
2525
2413
  /* Return nil if the select timed out */
2526
2414
  if ( !pnotification ) return Qnil;
2527
2415
 
2528
- relname = rb_tainted_str_new2( pnotification->relname );
2529
- PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2416
+ relname = rb_str_new2( pnotification->relname );
2417
+ PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
2530
2418
  be_pid = INT2NUM( pnotification->be_pid );
2531
- #ifdef HAVE_ST_NOTIFY_EXTRA
2532
2419
  if ( *pnotification->extra ) {
2533
- extra = rb_tainted_str_new2( pnotification->extra );
2534
- PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
2420
+ extra = rb_str_new2( pnotification->extra );
2421
+ PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
2535
2422
  }
2536
- #endif
2537
2423
  PQfreemem( pnotification );
2538
2424
 
2539
2425
  if ( rb_block_given_p() )
@@ -2552,9 +2438,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2552
2438
  * not sent (false is only possible if the connection
2553
2439
  * is in nonblocking mode, and this command would block).
2554
2440
  *
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,
2441
+ * _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2442
+ * This encodes the data fields given as _buffer_ from an Array of Strings to
2443
+ * PostgreSQL's COPY text format inclusive proper escaping. Optionally
2444
+ * the encoder can type cast the fields from various Ruby types in one step,
2558
2445
  * if PG::TextEncoder::CopyRow#type_map is set accordingly.
2559
2446
  *
2560
2447
  * Raises an exception if an error occurs.
@@ -2591,7 +2478,7 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2591
2478
 
2592
2479
  if( p_coder ){
2593
2480
  t_pg_coder_enc_func enc_func;
2594
- int enc_idx = ENCODING_GET(self);
2481
+ int enc_idx = this->enc_idx;
2595
2482
 
2596
2483
  enc_func = pg_coder_enc_func( p_coder );
2597
2484
  len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
@@ -2641,16 +2528,16 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2641
2528
  VALUE error;
2642
2529
  int ret;
2643
2530
  const char *error_message = NULL;
2644
- PGconn *conn = pg_get_pgconn(self);
2531
+ t_pg_connection *this = pg_get_connection_safe( self );
2645
2532
 
2646
2533
  if (rb_scan_args(argc, argv, "01", &str) == 0)
2647
2534
  error_message = NULL;
2648
2535
  else
2649
- error_message = pg_cstr_enc(str, ENCODING_GET(self));
2536
+ error_message = pg_cstr_enc(str, this->enc_idx);
2650
2537
 
2651
- ret = gvl_PQputCopyEnd(conn, error_message);
2538
+ ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2652
2539
  if(ret == -1) {
2653
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2540
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2654
2541
  rb_iv_set(error, "@connection", self);
2655
2542
  rb_exc_raise(error);
2656
2543
  }
@@ -2659,15 +2546,18 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2659
2546
 
2660
2547
  /*
2661
2548
  * call-seq:
2662
- * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> String
2549
+ * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
2663
2550
  *
2664
- * Return a string containing one row of data, +nil+
2551
+ * Return one row of data, +nil+
2665
2552
  * if the copy is done, or +false+ if the call would
2666
2553
  * block (only possible if _async_ is true).
2667
2554
  *
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,
2555
+ * If _decoder_ is not set or +nil+, data is returned as binary string.
2556
+ *
2557
+ * If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
2558
+ * PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
2559
+ * COPY text format to an Array of Strings.
2560
+ * Optionally the decoder can type cast the single fields to various Ruby types in one step,
2671
2561
  * if PG::TextDecoder::CopyRow#type_map is set accordingly.
2672
2562
  *
2673
2563
  * See also #copy_data.
@@ -2713,9 +2603,9 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2713
2603
 
2714
2604
  if( p_coder ){
2715
2605
  t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, p_coder->format );
2716
- result = dec_func( p_coder, buffer, ret, 0, 0, ENCODING_GET(self) );
2606
+ result = dec_func( p_coder, buffer, ret, 0, 0, this->enc_idx );
2717
2607
  } else {
2718
- result = rb_tainted_str_new(buffer, ret);
2608
+ result = rb_str_new(buffer, ret);
2719
2609
  }
2720
2610
 
2721
2611
  PQfreemem(buffer);
@@ -2728,9 +2618,16 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2728
2618
  *
2729
2619
  * Sets connection's verbosity to _verbosity_ and returns
2730
2620
  * the previous setting. Available settings are:
2621
+ *
2731
2622
  * * PQERRORS_TERSE
2732
2623
  * * PQERRORS_DEFAULT
2733
2624
  * * PQERRORS_VERBOSE
2625
+ * * PQERRORS_SQLSTATE
2626
+ *
2627
+ * Changing the verbosity does not affect the messages available from already-existing PG::Result objects, only subsequently-created ones.
2628
+ * (But see PG::Result#verbose_error_message if you want to print a previous error with a different verbosity.)
2629
+ *
2630
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORVERBOSITY].
2734
2631
  */
2735
2632
  static VALUE
2736
2633
  pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
@@ -2740,6 +2637,37 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2740
2637
  return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
2741
2638
  }
2742
2639
 
2640
+ #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
2641
+ /*
2642
+ * call-seq:
2643
+ * conn.set_error_context_visibility( context_visibility ) -> Integer
2644
+ *
2645
+ * Sets connection's context display mode to _context_visibility_ and returns
2646
+ * the previous setting. Available settings are:
2647
+ * * PQSHOW_CONTEXT_NEVER
2648
+ * * PQSHOW_CONTEXT_ERRORS
2649
+ * * PQSHOW_CONTEXT_ALWAYS
2650
+ *
2651
+ * This mode controls whether the CONTEXT field is included in messages (unless the verbosity setting is TERSE, in which case CONTEXT is never shown).
2652
+ * The NEVER mode never includes CONTEXT, while ALWAYS always includes it if available.
2653
+ * In ERRORS mode (the default), CONTEXT fields are included only for error messages, not for notices and warnings.
2654
+ *
2655
+ * Changing this mode does not affect the messages available from already-existing PG::Result objects, only subsequently-created ones.
2656
+ * (But see PG::Result#verbose_error_message if you want to print a previous error with a different display mode.)
2657
+ *
2658
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY].
2659
+ *
2660
+ * Available since PostgreSQL-9.6
2661
+ */
2662
+ static VALUE
2663
+ pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
2664
+ {
2665
+ PGconn *conn = pg_get_pgconn(self);
2666
+ PGContextVisibility context_visibility = NUM2INT(in_context_visibility);
2667
+ return INT2FIX(PQsetErrorContextVisibility(conn, context_visibility));
2668
+ }
2669
+ #endif
2670
+
2743
2671
  /*
2744
2672
  * call-seq:
2745
2673
  * conn.trace( stream ) -> nil
@@ -2758,7 +2686,7 @@ pgconn_trace(VALUE self, VALUE stream)
2758
2686
  VALUE new_file;
2759
2687
  t_pg_connection *this = pg_get_connection_safe( self );
2760
2688
 
2761
- if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
2689
+ if(!rb_respond_to(stream,rb_intern("fileno")))
2762
2690
  rb_raise(rb_eArgError, "stream does not respond to method: fileno");
2763
2691
 
2764
2692
  fileno = rb_funcall(stream, rb_intern("fileno"), 0);
@@ -2891,8 +2819,8 @@ notice_processor_proxy(void *arg, const char *message)
2891
2819
  t_pg_connection *this = pg_get_connection( self );
2892
2820
 
2893
2821
  if (this->notice_receiver != Qnil) {
2894
- VALUE message_str = rb_tainted_str_new2(message);
2895
- PG_ENCODING_SET_NOCHECK( message_str, ENCODING_GET(self) );
2822
+ VALUE message_str = rb_str_new2(message);
2823
+ PG_ENCODING_SET_NOCHECK( message_str, this->enc_idx );
2896
2824
  rb_funcall(this->notice_receiver, rb_intern("call"), 1, message_str);
2897
2825
  }
2898
2826
  return;
@@ -2950,7 +2878,7 @@ static VALUE
2950
2878
  pgconn_get_client_encoding(VALUE self)
2951
2879
  {
2952
2880
  char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self)));
2953
- return rb_tainted_str_new2(encoding);
2881
+ return rb_str_new2(encoding);
2954
2882
  }
2955
2883
 
2956
2884
 
@@ -2968,11 +2896,9 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
2968
2896
  Check_Type(str, T_STRING);
2969
2897
 
2970
2898
  if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2971
- rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValueCStr(str));
2899
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2972
2900
  }
2973
- #ifdef M17N_SUPPORTED
2974
2901
  pgconn_set_internal_encoding_index( self );
2975
- #endif
2976
2902
 
2977
2903
  return Qnil;
2978
2904
  }
@@ -3064,14 +2990,12 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
3064
2990
  int enc_idx;
3065
2991
 
3066
2992
  if( rb_obj_is_kind_of(self, rb_cPGconn) ){
3067
- enc_idx = ENCODING_GET( self );
2993
+ enc_idx = pg_get_connection(self)->enc_idx;
3068
2994
  }else{
3069
2995
  enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
3070
2996
  }
3071
2997
  pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
3072
2998
 
3073
- OBJ_INFECT(ret, str_or_array);
3074
-
3075
2999
  return ret;
3076
3000
  }
3077
3001
 
@@ -3100,10 +3024,6 @@ static VALUE
3100
3024
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
3101
3025
  PGconn *conn = pg_get_pgconn( self );
3102
3026
 
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
3027
  struct timeval timeout;
3108
3028
  struct timeval *ptimeout = NULL;
3109
3029
  VALUE timeout_in;
@@ -3170,24 +3090,142 @@ pgconn_get_last_result(VALUE self)
3170
3090
 
3171
3091
  /*
3172
3092
  * call-seq:
3173
- * conn.async_exec(sql [, params, result_format ] ) -> PG::Result
3174
- * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
3093
+ * conn.discard_results()
3175
3094
  *
3176
- * This function has the same behavior as #exec,
3177
- * but is implemented using the asynchronous command
3178
- * processing API of libpq.
3095
+ * Silently discard any prior query result that application didn't eat.
3096
+ * This is done prior of Connection#exec and sibling methods and can
3097
+ * be called explicitly when using the async API.
3098
+ */
3099
+ static VALUE
3100
+ pgconn_discard_results(VALUE self)
3101
+ {
3102
+ PGconn *conn = pg_get_pgconn(self);
3103
+
3104
+ PGresult *cur;
3105
+ while ((cur = gvl_PQgetResult(conn)) != NULL) {
3106
+ int status = PQresultStatus(cur);
3107
+ PQclear(cur);
3108
+ if (status == PGRES_COPY_IN){
3109
+ gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
3110
+ }
3111
+ if (status == PGRES_COPY_OUT){
3112
+ char *buffer = NULL;
3113
+ while( gvl_PQgetCopyData(conn, &buffer, 0) > 0)
3114
+ PQfreemem(buffer);
3115
+ }
3116
+ }
3117
+
3118
+ return Qnil;
3119
+ }
3120
+
3121
+ /*
3122
+ * call-seq:
3123
+ * conn.exec(sql) -> PG::Result
3124
+ * conn.exec(sql) {|pg_result| block }
3125
+ *
3126
+ * Sends SQL query request specified by _sql_ to PostgreSQL.
3127
+ * On success, it returns a PG::Result instance with all result rows and columns.
3128
+ * On failure, it raises a PG::Error.
3129
+ *
3130
+ * For backward compatibility, if you pass more than one parameter to this method,
3131
+ * it will call #exec_params for you. New code should explicitly use #exec_params if
3132
+ * argument placeholders are used.
3133
+ *
3134
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
3135
+ * and the PG::Result object will automatically be cleared when the block terminates.
3136
+ * In this instance, <code>conn.exec</code> returns the value of the block.
3137
+ *
3138
+ * #exec is an alias for #async_exec which is almost identical to #sync_exec .
3139
+ * #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
3140
+ * #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
3141
+ * Both methods ensure that other threads can process while waiting for the server to
3142
+ * complete the request, but #sync_exec blocks all signals to be processed until the query is finished.
3143
+ * This is most notably visible by a delayed reaction to Control+C.
3144
+ * It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
3145
+ *
3146
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXEC].
3179
3147
  */
3180
3148
  static VALUE
3181
3149
  pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3182
3150
  {
3183
3151
  VALUE rb_pgresult = Qnil;
3184
3152
 
3185
- /* remove any remaining results from the queue */
3153
+ pgconn_discard_results( self );
3154
+ pgconn_send_query( argc, argv, self );
3186
3155
  pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3187
- pgconn_get_last_result( self );
3156
+ rb_pgresult = pgconn_get_last_result( self );
3188
3157
 
3189
- pgconn_send_query( argc, argv, self );
3190
- pgconn_block( 0, NULL, self );
3158
+ if ( rb_block_given_p() ) {
3159
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3160
+ }
3161
+ return rb_pgresult;
3162
+ }
3163
+
3164
+
3165
+ /*
3166
+ * call-seq:
3167
+ * conn.exec_params(sql, params [, result_format [, type_map ]] ) -> nil
3168
+ * conn.exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
3169
+ *
3170
+ * Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
3171
+ * for parameters.
3172
+ *
3173
+ * Returns a PG::Result instance on success. On failure, it raises a PG::Error.
3174
+ *
3175
+ * +params+ is an array of the bind parameters for the SQL query.
3176
+ * Each element of the +params+ array may be either:
3177
+ * a hash of the form:
3178
+ * {:value => String (value of bind parameter)
3179
+ * :type => Integer (oid of type of bind parameter)
3180
+ * :format => Integer (0 for text, 1 for binary)
3181
+ * }
3182
+ * or, it may be a String. If it is a string, that is equivalent to the hash:
3183
+ * { :value => <string value>, :type => 0, :format => 0 }
3184
+ *
3185
+ * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
3186
+ * inside the SQL query. The 0th element of the +params+ array is bound
3187
+ * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
3188
+ *
3189
+ * If the types are not specified, they will be inferred by PostgreSQL.
3190
+ * Instead of specifying type oids, it's recommended to simply add
3191
+ * explicit casts in the query to ensure that the right type is used.
3192
+ *
3193
+ * For example: "SELECT $1::int"
3194
+ *
3195
+ * The optional +result_format+ should be 0 for text results, 1
3196
+ * for binary.
3197
+ *
3198
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
3199
+ * This will type cast the params from various Ruby types before transmission
3200
+ * based on the encoders defined by the type map. When a type encoder is used
3201
+ * the format and oid of a given bind parameter are retrieved from the encoder
3202
+ * instead out of the hash form described above.
3203
+ *
3204
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
3205
+ * and the PG::Result object will automatically be cleared when the block terminates.
3206
+ * In this instance, <code>conn.exec</code> returns the value of the block.
3207
+ *
3208
+ * The primary advantage of #exec_params over #exec is that parameter values can be separated from the command string, thus avoiding the need for tedious and error-prone quoting and escaping.
3209
+ * Unlike #exec, #exec_params allows at most one SQL command in the given string.
3210
+ * (There can be semicolons in it, but not more than one nonempty command.)
3211
+ * This is a limitation of the underlying protocol, but has some usefulness as an extra defense against SQL-injection attacks.
3212
+ *
3213
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXECPARAMS].
3214
+ */
3215
+ static VALUE
3216
+ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
3217
+ {
3218
+ VALUE rb_pgresult = Qnil;
3219
+
3220
+ pgconn_discard_results( self );
3221
+ /* If called with no or nil parameters, use PQsendQuery for compatibility */
3222
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
3223
+ pg_deprecated(3, ("forwarding async_exec_params to async_exec is deprecated"));
3224
+ pgconn_send_query( argc, argv, self );
3225
+ } else {
3226
+ pgconn_send_query_params( argc, argv, self );
3227
+ }
3228
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3191
3229
  rb_pgresult = pgconn_get_last_result( self );
3192
3230
 
3193
3231
  if ( rb_block_given_p() ) {
@@ -3197,15 +3235,157 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3197
3235
  }
3198
3236
 
3199
3237
 
3200
- #ifdef HAVE_PQSSLATTRIBUTE
3201
- /* Since PostgreSQL-9.5: */
3238
+ /*
3239
+ * call-seq:
3240
+ * conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
3241
+ *
3242
+ * Prepares statement _sql_ with name _name_ to be executed later.
3243
+ * Returns a PG::Result instance on success.
3244
+ * On failure, it raises a PG::Error.
3245
+ *
3246
+ * +param_types+ is an optional parameter to specify the Oids of the
3247
+ * types of the parameters.
3248
+ *
3249
+ * If the types are not specified, they will be inferred by PostgreSQL.
3250
+ * Instead of specifying type oids, it's recommended to simply add
3251
+ * explicit casts in the query to ensure that the right type is used.
3252
+ *
3253
+ * For example: "SELECT $1::int"
3254
+ *
3255
+ * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
3256
+ * inside the SQL query.
3257
+ *
3258
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQPREPARE].
3259
+ */
3260
+ static VALUE
3261
+ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
3262
+ {
3263
+ VALUE rb_pgresult = Qnil;
3202
3264
 
3265
+ pgconn_discard_results( self );
3266
+ pgconn_send_prepare( argc, argv, self );
3267
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3268
+ rb_pgresult = pgconn_get_last_result( self );
3269
+
3270
+ if ( rb_block_given_p() ) {
3271
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3272
+ }
3273
+ return rb_pgresult;
3274
+ }
3275
+
3276
+
3277
+ /*
3278
+ * call-seq:
3279
+ * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
3280
+ * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
3281
+ *
3282
+ * Execute prepared named statement specified by _statement_name_.
3283
+ * Returns a PG::Result instance on success.
3284
+ * On failure, it raises a PG::Error.
3285
+ *
3286
+ * +params+ is an array of the optional bind parameters for the
3287
+ * SQL query. Each element of the +params+ array may be either:
3288
+ * a hash of the form:
3289
+ * {:value => String (value of bind parameter)
3290
+ * :format => Integer (0 for text, 1 for binary)
3291
+ * }
3292
+ * or, it may be a String. If it is a string, that is equivalent to the hash:
3293
+ * { :value => <string value>, :format => 0 }
3294
+ *
3295
+ * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
3296
+ * inside the SQL query. The 0th element of the +params+ array is bound
3297
+ * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
3298
+ *
3299
+ * The optional +result_format+ should be 0 for text results, 1
3300
+ * for binary.
3301
+ *
3302
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
3303
+ * This will type cast the params from various Ruby types before transmission
3304
+ * based on the encoders defined by the type map. When a type encoder is used
3305
+ * the format and oid of a given bind parameter are retrieved from the encoder
3306
+ * instead out of the hash form described above.
3307
+ *
3308
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
3309
+ * and the PG::Result object will automatically be cleared when the block terminates.
3310
+ * In this instance, <code>conn.exec_prepared</code> returns the value of the block.
3311
+ *
3312
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXECPREPARED].
3313
+ */
3314
+ static VALUE
3315
+ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3316
+ {
3317
+ VALUE rb_pgresult = Qnil;
3318
+
3319
+ pgconn_discard_results( self );
3320
+ pgconn_send_query_prepared( argc, argv, self );
3321
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3322
+ rb_pgresult = pgconn_get_last_result( self );
3323
+
3324
+ if ( rb_block_given_p() ) {
3325
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3326
+ }
3327
+ return rb_pgresult;
3328
+ }
3329
+
3330
+
3331
+ /*
3332
+ * call-seq:
3333
+ * conn.describe_portal( portal_name ) -> PG::Result
3334
+ *
3335
+ * Retrieve information about the portal _portal_name_.
3336
+ *
3337
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL].
3338
+ */
3339
+ static VALUE
3340
+ pgconn_async_describe_portal(VALUE self, VALUE portal)
3341
+ {
3342
+ VALUE rb_pgresult = Qnil;
3343
+
3344
+ pgconn_discard_results( self );
3345
+ pgconn_send_describe_portal( self, portal );
3346
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3347
+ rb_pgresult = pgconn_get_last_result( self );
3348
+
3349
+ if ( rb_block_given_p() ) {
3350
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3351
+ }
3352
+ return rb_pgresult;
3353
+ }
3354
+
3355
+
3356
+ /*
3357
+ * call-seq:
3358
+ * conn.describe_prepared( statement_name ) -> PG::Result
3359
+ *
3360
+ * Retrieve information about the prepared statement _statement_name_.
3361
+ *
3362
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED].
3363
+ */
3364
+ static VALUE
3365
+ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3366
+ {
3367
+ VALUE rb_pgresult = Qnil;
3368
+
3369
+ pgconn_discard_results( self );
3370
+ pgconn_send_describe_prepared( self, stmt_name );
3371
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3372
+ rb_pgresult = pgconn_get_last_result( self );
3373
+
3374
+ if ( rb_block_given_p() ) {
3375
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3376
+ }
3377
+ return rb_pgresult;
3378
+ }
3379
+
3380
+
3381
+ #ifdef HAVE_PQSSLATTRIBUTE
3203
3382
  /*
3204
3383
  * call-seq:
3205
3384
  * conn.ssl_in_use? -> Boolean
3206
3385
  *
3207
- * Returns +true+ if the connection uses SSL, +false+ if not.
3386
+ * Returns +true+ if the connection uses SSL/TLS, +false+ if not.
3208
3387
  *
3388
+ * Available since PostgreSQL-9.5
3209
3389
  */
3210
3390
  static VALUE
3211
3391
  pgconn_ssl_in_use(VALUE self)
@@ -3237,7 +3417,9 @@ pgconn_ssl_in_use(VALUE self)
3237
3417
  * If SSL compression is in use, returns the name of the compression algorithm, or "on" if compression is used but the algorithm is not known. If compression is not in use, returns "off".
3238
3418
  *
3239
3419
  *
3240
- * See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
3420
+ * See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
3421
+ *
3422
+ * Available since PostgreSQL-9.5
3241
3423
  */
3242
3424
  static VALUE
3243
3425
  pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
@@ -3256,6 +3438,7 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3256
3438
  *
3257
3439
  * See also #ssl_attribute
3258
3440
  *
3441
+ * Available since PostgreSQL-9.5
3259
3442
  */
3260
3443
  static VALUE
3261
3444
  pgconn_ssl_attribute_names(VALUE self)
@@ -3462,7 +3645,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3462
3645
  return Qnil;
3463
3646
  }
3464
3647
 
3465
- str = rb_tainted_str_new(buffer, ret);
3648
+ str = rb_str_new(buffer, ret);
3466
3649
  xfree(buffer);
3467
3650
 
3468
3651
  return str;
@@ -3566,14 +3749,15 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3566
3749
  }
3567
3750
 
3568
3751
 
3569
- #ifdef M17N_SUPPORTED
3570
-
3571
- void
3752
+ static void
3572
3753
  pgconn_set_internal_encoding_index( VALUE self )
3573
3754
  {
3574
- PGconn *conn = pg_get_pgconn(self);
3575
- rb_encoding *enc = pg_conn_enc_get( conn );
3576
- PG_ENCODING_SET_NOCHECK( self, rb_enc_to_index(enc));
3755
+ int enc_idx;
3756
+ t_pg_connection *this = pg_get_connection_safe( self );
3757
+ rb_encoding *enc = pg_conn_enc_get( this->pgconn );
3758
+ enc_idx = rb_enc_to_index(enc);
3759
+ if( enc_idx >= (1<<(PG_ENC_IDX_BITS-1)) ) rb_raise(rb_eArgError, "unsupported encoding index %d", enc_idx);
3760
+ this->enc_idx = enc_idx;
3577
3761
  }
3578
3762
 
3579
3763
  /*
@@ -3616,7 +3800,6 @@ static VALUE pgconn_external_encoding(VALUE self);
3616
3800
  static VALUE
3617
3801
  pgconn_internal_encoding_set(VALUE self, VALUE enc)
3618
3802
  {
3619
- VALUE enc_inspect;
3620
3803
  if (NIL_P(enc)) {
3621
3804
  pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
3622
3805
  return enc;
@@ -3637,11 +3820,6 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
3637
3820
  pgconn_set_internal_encoding_index( self );
3638
3821
  return enc;
3639
3822
  }
3640
-
3641
- enc_inspect = rb_inspect(enc);
3642
- rb_raise( rb_ePGerror, "unknown encoding: %s", StringValueCStr(enc_inspect) );
3643
-
3644
- return Qnil;
3645
3823
  }
3646
3824
 
3647
3825
 
@@ -3660,14 +3838,9 @@ pgconn_external_encoding(VALUE self)
3660
3838
  rb_encoding *enc = NULL;
3661
3839
  const char *pg_encname = NULL;
3662
3840
 
3663
- /* Use cached value if found */
3664
- if ( RTEST(this->external_encoding) ) return this->external_encoding;
3665
-
3666
3841
  pg_encname = PQparameterStatus( this->pgconn, "server_encoding" );
3667
3842
  enc = pg_get_pg_encname_as_rb_encoding( pg_encname );
3668
- this->external_encoding = rb_enc_from_encoding( enc );
3669
-
3670
- return this->external_encoding;
3843
+ return rb_enc_from_encoding( enc );
3671
3844
  }
3672
3845
 
3673
3846
 
@@ -3685,9 +3858,10 @@ pgconn_set_client_encoding_async1( VALUE args )
3685
3858
 
3686
3859
 
3687
3860
  static VALUE
3688
- pgconn_set_client_encoding_async2( VALUE arg )
3861
+ pgconn_set_client_encoding_async2( VALUE arg, VALUE ex )
3689
3862
  {
3690
3863
  UNUSED(arg);
3864
+ UNUSED(ex);
3691
3865
  return 1;
3692
3866
  }
3693
3867
 
@@ -3718,7 +3892,7 @@ pgconn_set_default_encoding( VALUE self )
3718
3892
  if (( enc = rb_default_internal_encoding() )) {
3719
3893
  encname = pg_get_rb_encoding_as_pg_encoding( enc );
3720
3894
  if ( pgconn_set_client_encoding_async(self, encname) != 0 )
3721
- rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
3895
+ rb_warning( "Failed to set the default_internal encoding to %s: '%s'",
3722
3896
  encname, PQerrorMessage(conn) );
3723
3897
  pgconn_set_internal_encoding_index( self );
3724
3898
  return rb_enc_from_encoding( enc );
@@ -3729,8 +3903,6 @@ pgconn_set_default_encoding( VALUE self )
3729
3903
  }
3730
3904
 
3731
3905
 
3732
- #endif /* M17N_SUPPORTED */
3733
-
3734
3906
  /*
3735
3907
  * call-seq:
3736
3908
  * res.type_map_for_queries = typemap
@@ -3909,6 +4081,58 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
3909
4081
  return this->decoder_for_get_copy_data;
3910
4082
  }
3911
4083
 
4084
+ /*
4085
+ * call-seq:
4086
+ * conn.field_name_type = Symbol
4087
+ *
4088
+ * Set default type of field names of results retrieved by this connection.
4089
+ * It can be set to one of:
4090
+ * * +:string+ to use String based field names
4091
+ * * +:symbol+ to use Symbol based field names
4092
+ *
4093
+ * The default is +:string+ .
4094
+ *
4095
+ * Settings the type of field names affects only future results.
4096
+ *
4097
+ * See further description at PG::Result#field_name_type=
4098
+ *
4099
+ */
4100
+ static VALUE
4101
+ pgconn_field_name_type_set(VALUE self, VALUE sym)
4102
+ {
4103
+ t_pg_connection *this = pg_get_connection( self );
4104
+
4105
+ this->flags &= ~PG_RESULT_FIELD_NAMES_MASK;
4106
+ if( sym == sym_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_SYMBOL;
4107
+ else if ( sym == sym_static_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_STATIC_SYMBOL;
4108
+ else if ( sym == sym_string );
4109
+ else rb_raise(rb_eArgError, "invalid argument %+"PRIsVALUE, sym);
4110
+
4111
+ return sym;
4112
+ }
4113
+
4114
+ /*
4115
+ * call-seq:
4116
+ * conn.field_name_type -> Symbol
4117
+ *
4118
+ * Get type of field names.
4119
+ *
4120
+ * See description at #field_name_type=
4121
+ */
4122
+ static VALUE
4123
+ pgconn_field_name_type_get(VALUE self)
4124
+ {
4125
+ t_pg_connection *this = pg_get_connection( self );
4126
+
4127
+ if( this->flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
4128
+ return sym_symbol;
4129
+ } else if( this->flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
4130
+ return sym_static_symbol;
4131
+ } else {
4132
+ return sym_string;
4133
+ }
4134
+ }
4135
+
3912
4136
 
3913
4137
  /*
3914
4138
  * Document-class: PG::Connection
@@ -3920,8 +4144,13 @@ init_pg_connection()
3920
4144
  sym_type = ID2SYM(rb_intern("type"));
3921
4145
  sym_format = ID2SYM(rb_intern("format"));
3922
4146
  sym_value = ID2SYM(rb_intern("value"));
4147
+ sym_string = ID2SYM(rb_intern("string"));
4148
+ sym_symbol = ID2SYM(rb_intern("symbol"));
4149
+ sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
3923
4150
 
3924
4151
  rb_cPGconn = rb_define_class_under( rb_mPG, "Connection", rb_cObject );
4152
+ /* Help rdoc to known the Constants module */
4153
+ /* rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" ); */
3925
4154
  rb_include_module(rb_cPGconn, rb_mPGconstants);
3926
4155
 
3927
4156
  /****** PG::Connection CLASS METHODS ******/
@@ -3939,9 +4168,7 @@ init_pg_connection()
3939
4168
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
3940
4169
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
3941
4170
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3942
- #ifdef HAVE_PQPING
3943
4171
  rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
3944
- #endif
3945
4172
 
3946
4173
  /****** PG::Connection INSTANCE METHODS: Connection Control ******/
3947
4174
  rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
@@ -3971,39 +4198,47 @@ init_pg_connection()
3971
4198
  rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
3972
4199
  rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
3973
4200
  rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
3974
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
3975
4201
  rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
3976
- #endif
3977
4202
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
3978
4203
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
3979
4204
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
3980
4205
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
3981
4206
 
3982
4207
  /****** 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);
4208
+ rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
4209
+ rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
4210
+ rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
4211
+ rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
4212
+ rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
4213
+ rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
4214
+
4215
+ rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
4216
+ rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
4217
+ rb_define_method(rb_cPGconn, "prepare", pgconn_async_prepare, -1);
4218
+ rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
4219
+ rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
4220
+ rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
4221
+
4222
+ rb_define_alias(rb_cPGconn, "async_exec", "exec");
4223
+ rb_define_alias(rb_cPGconn, "async_query", "async_exec");
4224
+ rb_define_alias(rb_cPGconn, "async_exec_params", "exec_params");
4225
+ rb_define_alias(rb_cPGconn, "async_prepare", "prepare");
4226
+ rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
4227
+ rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
4228
+ rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
4229
+
3990
4230
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
3991
4231
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
3992
4232
  rb_define_alias(rb_cPGconn, "escape", "escape_string");
3993
- #ifdef HAVE_PQESCAPELITERAL
3994
4233
  rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
3995
- #endif
3996
- #ifdef HAVE_PQESCAPEIDENTIFIER
3997
4234
  rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
3998
- #endif
3999
4235
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4000
4236
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4001
- #ifdef HAVE_PQSETSINGLEROWMODE
4002
4237
  rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
4003
- #endif
4004
4238
 
4005
4239
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
4006
4240
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
4241
+ rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
4007
4242
  rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
4008
4243
  rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4009
4244
  rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
@@ -4015,6 +4250,7 @@ init_pg_connection()
4015
4250
  rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
4016
4251
  rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
4017
4252
  rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
4253
+ rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
4018
4254
 
4019
4255
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
4020
4256
  rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
@@ -4029,6 +4265,9 @@ init_pg_connection()
4029
4265
 
4030
4266
  /****** PG::Connection INSTANCE METHODS: Control Functions ******/
4031
4267
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
4268
+ #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
4269
+ rb_define_method(rb_cPGconn, "set_error_context_visibility", pgconn_set_error_context_visibility, 1 );
4270
+ #endif
4032
4271
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4033
4272
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4034
4273
 
@@ -4045,9 +4284,10 @@ init_pg_connection()
4045
4284
  rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
4046
4285
  rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
4047
4286
  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
4287
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
4288
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
4289
+ rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
4290
+ #endif
4051
4291
 
4052
4292
  #ifdef HAVE_PQSSLATTRIBUTE
4053
4293
  rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
@@ -4083,12 +4323,10 @@ init_pg_connection()
4083
4323
  rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
4084
4324
  rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
4085
4325
 
4086
- #ifdef M17N_SUPPORTED
4087
4326
  rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
4088
4327
  rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
4089
4328
  rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
4090
4329
  rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
4091
- #endif /* M17N_SUPPORTED */
4092
4330
 
4093
4331
  rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
4094
4332
  rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);
@@ -4098,5 +4336,7 @@ init_pg_connection()
4098
4336
  rb_define_method(rb_cPGconn, "encoder_for_put_copy_data", pgconn_encoder_for_put_copy_data_get, 0);
4099
4337
  rb_define_method(rb_cPGconn, "decoder_for_get_copy_data=", pgconn_decoder_for_get_copy_data_set, 1);
4100
4338
  rb_define_method(rb_cPGconn, "decoder_for_get_copy_data", pgconn_decoder_for_get_copy_data_get, 0);
4101
- }
4102
4339
 
4340
+ rb_define_method(rb_cPGconn, "field_name_type=", pgconn_field_name_type_set, 1 );
4341
+ rb_define_method(rb_cPGconn, "field_name_type", pgconn_field_name_type_get, 0 );
4342
+ }