pg 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +0 -6595
  5. data/History.rdoc +70 -0
  6. data/Manifest.txt +3 -2
  7. data/README-Windows.rdoc +4 -4
  8. data/README.ja.rdoc +1 -2
  9. data/README.rdoc +43 -8
  10. data/Rakefile +4 -4
  11. data/Rakefile.cross +7 -4
  12. data/ext/errorcodes.def +68 -0
  13. data/ext/errorcodes.txt +19 -2
  14. data/ext/extconf.rb +6 -6
  15. data/ext/pg.c +132 -95
  16. data/ext/pg.h +24 -17
  17. data/ext/pg_binary_decoder.c +20 -16
  18. data/ext/pg_binary_encoder.c +13 -12
  19. data/ext/pg_coder.c +5 -5
  20. data/ext/pg_connection.c +395 -301
  21. data/ext/pg_copy_coder.c +5 -3
  22. data/ext/pg_record_coder.c +490 -0
  23. data/ext/pg_result.c +272 -124
  24. data/ext/pg_text_decoder.c +14 -8
  25. data/ext/pg_text_encoder.c +180 -48
  26. data/ext/pg_tuple.c +14 -6
  27. data/ext/pg_type_map.c +1 -1
  28. data/ext/pg_type_map_all_strings.c +4 -4
  29. data/ext/pg_type_map_by_class.c +4 -3
  30. data/ext/pg_type_map_by_column.c +7 -6
  31. data/ext/pg_type_map_by_mri_type.c +1 -1
  32. data/ext/pg_type_map_by_oid.c +3 -2
  33. data/ext/pg_type_map_in_ruby.c +1 -1
  34. data/ext/{util.c → pg_util.c} +5 -5
  35. data/ext/{util.h → pg_util.h} +0 -0
  36. data/lib/pg.rb +2 -3
  37. data/lib/pg/basic_type_mapping.rb +79 -16
  38. data/lib/pg/binary_decoder.rb +1 -0
  39. data/lib/pg/coder.rb +22 -1
  40. data/lib/pg/connection.rb +2 -2
  41. data/lib/pg/constants.rb +1 -0
  42. data/lib/pg/exceptions.rb +1 -0
  43. data/lib/pg/result.rb +13 -1
  44. data/lib/pg/text_decoder.rb +2 -3
  45. data/lib/pg/text_encoder.rb +8 -18
  46. data/lib/pg/type_map_by_column.rb +2 -1
  47. data/spec/helpers.rb +17 -16
  48. data/spec/pg/basic_type_mapping_spec.rb +151 -14
  49. data/spec/pg/connection_spec.rb +117 -55
  50. data/spec/pg/result_spec.rb +193 -3
  51. data/spec/pg/tuple_spec.rb +55 -2
  52. data/spec/pg/type_map_by_column_spec.rb +5 -1
  53. data/spec/pg/type_spec.rb +180 -6
  54. metadata +40 -45
  55. metadata.gz.sig +0 -0
data/ext/pg.h CHANGED
@@ -78,6 +78,8 @@ typedef long suseconds_t;
78
78
  #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
79
79
  #endif
80
80
 
81
+ #define PG_ENC_IDX_BITS 28
82
+
81
83
  /* The data behind each PG::Connection object */
82
84
  typedef struct {
83
85
  PGconn *pgconn;
@@ -94,15 +96,19 @@ typedef struct {
94
96
  VALUE type_map_for_results;
95
97
  /* IO object internally used for the trace stream */
96
98
  VALUE trace_stream;
97
- /* Cached Encoding object */
98
- VALUE external_encoding;
99
99
  /* Kind of PG::Coder object for casting ruby values to COPY rows */
100
100
  VALUE encoder_for_put_copy_data;
101
101
  /* Kind of PG::Coder object for casting COPY rows to ruby values */
102
102
  VALUE decoder_for_get_copy_data;
103
+ /* Ruby encoding index of the client/internal encoding */
104
+ int enc_idx : PG_ENC_IDX_BITS;
105
+ /* flags controlling Symbol/String field names */
106
+ unsigned int flags : 2;
103
107
 
104
- /* enable/disable guessing size of PGresult's allocated memory */
105
- int guess_result_memsize;
108
+ #if defined(_WIN32)
109
+ /* File descriptor to be used for rb_w32_unwrap_io_handle() */
110
+ int ruby_sd;
111
+ #endif
106
112
  } t_pg_connection;
107
113
 
108
114
  typedef struct pg_coder t_pg_coder;
@@ -123,10 +129,16 @@ typedef struct {
123
129
  */
124
130
  t_typemap *p_typemap;
125
131
 
132
+ /* Ruby encoding index of the client/internal encoding */
133
+ int enc_idx : PG_ENC_IDX_BITS;
134
+
126
135
  /* 0 = PGresult is cleared by PG::Result#clear or by the GC
127
136
  * 1 = PGresult is cleared internally by libpq
128
137
  */
129
- int autoclear;
138
+ unsigned int autoclear : 1;
139
+
140
+ /* flags controlling Symbol/String field names */
141
+ unsigned int flags : 2;
130
142
 
131
143
  /* Number of fields in fnames[] .
132
144
  * Set to -1 if fnames[] is not yet initialized.
@@ -142,7 +154,7 @@ typedef struct {
142
154
  /* Hash with fnames[] to field number mapping. */
143
155
  VALUE field_map;
144
156
 
145
- /* List of field names as frozen String objects.
157
+ /* List of field names as frozen String or Symbol objects.
146
158
  * Only valid if nfields != -1
147
159
  */
148
160
  VALUE fnames[0];
@@ -158,6 +170,10 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
158
170
  typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
159
171
  typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
160
172
 
173
+ #define PG_RESULT_FIELD_NAMES_MASK 0x03
174
+ #define PG_RESULT_FIELD_NAMES_SYMBOL 0x01
175
+ #define PG_RESULT_FIELD_NAMES_STATIC_SYMBOL 0x02
176
+
161
177
  #define PG_CODER_TIMESTAMP_DB_UTC 0x0
162
178
  #define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
163
179
  #define PG_CODER_TIMESTAMP_APP_UTC 0x0
@@ -270,6 +286,7 @@ void init_pg_type_map_by_oid _(( void ));
270
286
  void init_pg_type_map_in_ruby _(( void ));
271
287
  void init_pg_coder _(( void ));
272
288
  void init_pg_copycoder _(( void ));
289
+ void init_pg_recordcoder _(( void ));
273
290
  void init_pg_text_encoder _(( void ));
274
291
  void init_pg_text_decoder _(( void ));
275
292
  void init_pg_binary_encoder _(( void ));
@@ -300,11 +317,6 @@ char *pg_rb_str_ensure_capa _(( VALUE, long, char *,
300
317
  (curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
301
318
  )
302
319
 
303
- #define PG_RB_TAINTED_STR_NEW( str, curr_ptr, end_ptr ) ( \
304
- (str) = rb_tainted_str_new( NULL, 0 ), \
305
- (curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
306
- )
307
-
308
320
  VALUE pg_typemap_fit_to_result _(( VALUE, VALUE ));
309
321
  VALUE pg_typemap_fit_to_query _(( VALUE, VALUE ));
310
322
  int pg_typemap_fit_to_copy_get _(( VALUE ));
@@ -328,12 +340,7 @@ VALUE pg_tuple_new _(( VALUE, int ));
328
340
  static inline t_pg_result *
329
341
  pgresult_get_this( VALUE self )
330
342
  {
331
- t_pg_result *this = RTYPEDDATA_DATA(self);
332
-
333
- if( this == NULL )
334
- rb_raise(rb_ePGerror, "result has been cleared");
335
-
336
- return this;
343
+ return RTYPEDDATA_DATA(self);
337
344
  }
338
345
 
339
346
 
@@ -1,12 +1,12 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_decoder.c,v 5d166a4d0441 2018/07/29 12:03:00 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "ruby/version.h"
8
8
  #include "pg.h"
9
- #include "util.h"
9
+ #include "pg_util.h"
10
10
  #ifdef HAVE_INTTYPES_H
11
11
  #include <inttypes.h>
12
12
  #endif
@@ -17,8 +17,8 @@ VALUE rb_mPG_BinaryDecoder;
17
17
  /*
18
18
  * Document-class: PG::BinaryDecoder::Boolean < PG::SimpleDecoder
19
19
  *
20
- * This is a decoder class for conversion of PostgreSQL binary bool type
21
- * to Ruby true or false objects.
20
+ * This is a decoder class for conversion of PostgreSQL binary +bool+ type
21
+ * to Ruby +true+ or +false+ objects.
22
22
  *
23
23
  */
24
24
  static VALUE
@@ -33,7 +33,7 @@ pg_bin_dec_boolean(t_pg_coder *conv, const char *val, int len, int tuple, int fi
33
33
  /*
34
34
  * Document-class: PG::BinaryDecoder::Integer < PG::SimpleDecoder
35
35
  *
36
- * This is a decoder class for conversion of PostgreSQL binary int2, int4 and int8 types
36
+ * This is a decoder class for conversion of PostgreSQL binary +int2+, +int4+ and +int8+ types
37
37
  * to Ruby Integer objects.
38
38
  *
39
39
  */
@@ -55,7 +55,7 @@ pg_bin_dec_integer(t_pg_coder *conv, const char *val, int len, int tuple, int fi
55
55
  /*
56
56
  * Document-class: PG::BinaryDecoder::Float < PG::SimpleDecoder
57
57
  *
58
- * This is a decoder class for conversion of PostgreSQL binary float4 and float8 types
58
+ * This is a decoder class for conversion of PostgreSQL binary +float4+ and +float8+ types
59
59
  * to Ruby Float objects.
60
60
  *
61
61
  */
@@ -87,7 +87,7 @@ pg_bin_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
87
87
  * Document-class: PG::BinaryDecoder::Bytea < PG::SimpleDecoder
88
88
  *
89
89
  * This decoder class delivers the data received from the server as binary String object.
90
- * It is therefore suitable for conversion of PostgreSQL bytea data as well as any other
90
+ * It is therefore suitable for conversion of PostgreSQL +bytea+ data as well as any other
91
91
  * data in binary format.
92
92
  *
93
93
  */
@@ -95,7 +95,7 @@ VALUE
95
95
  pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
96
96
  {
97
97
  VALUE ret;
98
- ret = rb_tainted_str_new( val, len );
98
+ ret = rb_str_new( val, len );
99
99
  PG_ENCODING_SET_NOCHECK( ret, rb_ascii8bit_encindex() );
100
100
  return ret;
101
101
  }
@@ -103,7 +103,7 @@ pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
103
103
  /*
104
104
  * Document-class: PG::BinaryDecoder::ToBase64 < PG::CompositeDecoder
105
105
  *
106
- * This is a decoder class for conversion of binary (bytea) to base64 data.
106
+ * This is a decoder class for conversion of binary +bytea+ to base64 data.
107
107
  *
108
108
  */
109
109
  static VALUE
@@ -113,7 +113,7 @@ pg_bin_dec_to_base64(t_pg_coder *conv, const char *val, int len, int tuple, int
113
113
  t_pg_coder_dec_func dec_func = pg_coder_dec_func(this->elem, this->comp.format);
114
114
  int encoded_len = BASE64_ENCODED_SIZE(len);
115
115
  /* create a buffer of the encoded length */
116
- VALUE out_value = rb_tainted_str_new(NULL, encoded_len);
116
+ VALUE out_value = rb_str_new(NULL, encoded_len);
117
117
 
118
118
  base64_encode( RSTRING_PTR(out_value), val, len );
119
119
 
@@ -154,7 +154,8 @@ static VALUE
154
154
  pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
155
155
  {
156
156
  int64_t timestamp;
157
- struct timespec ts;
157
+ int64_t sec;
158
+ int64_t nsec;
158
159
  VALUE t;
159
160
 
160
161
  if( len != sizeof(timestamp) ){
@@ -171,14 +172,17 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
171
172
  default:
172
173
  /* PostgreSQL's timestamp is based on year 2000 and Ruby's time is based on 1970.
173
174
  * Adjust the 30 years difference. */
174
- ts.tv_sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
175
- ts.tv_nsec = (timestamp % 1000000) * 1000;
175
+ sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
176
+ nsec = (timestamp % 1000000) * 1000;
176
177
 
177
- #if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T)
178
+ #if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T) && defined(SIZEOF_TIME_T) && SIZEOF_TIME_T >= 8
178
179
  /* Fast path for time conversion */
179
- t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
180
+ {
181
+ struct timespec ts = {sec, nsec};
182
+ t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
183
+ }
180
184
  #else
181
- t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(ts.tv_sec), LL2NUM(ts.tv_nsec / 1000));
185
+ t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(sec), LL2NUM(nsec / 1000));
182
186
  if( !(conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL) ) {
183
187
  t = rb_funcall(t, rb_intern("utc"), 0);
184
188
  }
@@ -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
  *
@@ -145,7 +145,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
145
145
 
146
146
  if( len == -1 ){
147
147
  /* The intermediate value is a String that can be used directly. */
148
- OBJ_INFECT(intermediate, value);
149
148
  return intermediate;
150
149
  }
151
150
 
@@ -157,7 +156,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
157
156
  rb_obj_classname( self ), len, len2 );
158
157
  }
159
158
  rb_str_set_len( res, len2 );
160
- OBJ_INFECT(res, value);
161
159
 
162
160
  RB_GC_GUARD(intermediate);
163
161
 
@@ -204,7 +202,6 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
204
202
  }
205
203
 
206
204
  res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
207
- OBJ_INFECT(res, argv[0]);
208
205
 
209
206
  return res;
210
207
  }
@@ -400,6 +397,11 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
400
397
  if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
401
398
  rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
402
399
 
400
+ if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
401
+ rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
402
+ if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
403
+ rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
404
+
403
405
  rb_define_const( coder_klass, "CFUNC", cfunc_obj );
404
406
 
405
407
  RB_GC_GUARD(cfunc_obj);
@@ -512,8 +514,6 @@ init_pg_coder()
512
514
  * This accessor is only used in PG::Coder#inspect .
513
515
  */
514
516
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
515
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
516
- rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
517
517
 
518
518
  /* Document-class: PG::SimpleCoder < PG::Coder */
519
519
  rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_connection.c - PG::Connection class extension
3
- * $Id: pg_connection.c,v b49f54dc755b 2018/09/01 12:52:41 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -13,13 +13,14 @@
13
13
  VALUE rb_cPGconn;
14
14
  static ID s_id_encode;
15
15
  static VALUE sym_type, sym_format, sym_value;
16
+ static VALUE sym_symbol, sym_string, sym_static_symbol;
16
17
 
17
18
  static PQnoticeReceiver default_notice_receiver = NULL;
18
19
  static PQnoticeProcessor default_notice_processor = NULL;
19
20
 
20
21
  static VALUE pgconn_finish( VALUE );
21
22
  static VALUE pgconn_set_default_encoding( VALUE self );
22
- void pgconn_set_internal_encoding_index( VALUE );
23
+ static void pgconn_set_internal_encoding_index( VALUE );
23
24
 
24
25
  /*
25
26
  * Global functions
@@ -85,8 +86,7 @@ pgconn_close_socket_io( VALUE self )
85
86
 
86
87
  if ( RTEST(socket_io) ) {
87
88
  #if defined(_WIN32)
88
- int ruby_sd = NUM2INT(rb_funcall( socket_io, rb_intern("fileno"), 0 ));
89
- if( rb_w32_unwrap_io_handle(ruby_sd) ){
89
+ if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
90
90
  rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
91
91
  }
92
92
  #endif
@@ -153,7 +153,6 @@ pgconn_gc_mark( t_pg_connection *this )
153
153
  rb_gc_mark( this->type_map_for_queries );
154
154
  rb_gc_mark( this->type_map_for_results );
155
155
  rb_gc_mark( this->trace_stream );
156
- rb_gc_mark( this->external_encoding );
157
156
  rb_gc_mark( this->encoder_for_put_copy_data );
158
157
  rb_gc_mark( this->decoder_for_get_copy_data );
159
158
  }
@@ -165,6 +164,10 @@ pgconn_gc_mark( t_pg_connection *this )
165
164
  static void
166
165
  pgconn_gc_free( t_pg_connection *this )
167
166
  {
167
+ #if defined(_WIN32)
168
+ if ( RTEST(this->socket_io) )
169
+ rb_w32_unwrap_io_handle( this->ruby_sd );
170
+ #endif
168
171
  if (this->pgconn != NULL)
169
172
  PQfinish( this->pgconn );
170
173
 
@@ -197,8 +200,6 @@ pgconn_s_allocate( VALUE klass )
197
200
  this->encoder_for_put_copy_data = Qnil;
198
201
  this->decoder_for_get_copy_data = Qnil;
199
202
  this->trace_stream = Qnil;
200
- this->external_encoding = Qnil;
201
- this->guess_result_memsize = 1;
202
203
 
203
204
  return self;
204
205
  }
@@ -215,32 +216,27 @@ pgconn_s_allocate( VALUE klass )
215
216
  *
216
217
  * Create a connection to the specified server.
217
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:
218
226
  * [+host+]
219
227
  * server hostname
220
- * [+hostaddr+]
221
- * server address (avoids hostname lookup, overrides +host+)
222
228
  * [+port+]
223
229
  * server port number
230
+ * [+options+]
231
+ * backend options
232
+ * [+tty+]
233
+ * (ignored in newer versions of PostgreSQL)
224
234
  * [+dbname+]
225
235
  * connecting database name
226
236
  * [+user+]
227
237
  * login user name
228
238
  * [+password+]
229
239
  * login password
230
- * [+connect_timeout+]
231
- * maximum time to wait for connection to succeed
232
- * [+options+]
233
- * backend options
234
- * [+tty+]
235
- * (ignored in newer versions of PostgreSQL)
236
- * [+sslmode+]
237
- * (disable|allow|prefer|require)
238
- * [+krbsrvname+]
239
- * kerberos service name
240
- * [+gsslib+]
241
- * GSS library to use for GSSAPI authentication
242
- * [+service+]
243
- * service name to use for additional parameters
244
240
  *
245
241
  * Examples:
246
242
  *
@@ -256,7 +252,7 @@ pgconn_s_allocate( VALUE klass )
256
252
  * # As an Array
257
253
  * PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
258
254
  *
259
- * 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
260
256
  * connection will have its +client_encoding+ set accordingly.
261
257
  *
262
258
  * Raises a PG::Error if the connection fails.
@@ -295,14 +291,16 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
295
291
  * PG::Connection.connect_start(connection_string) -> conn
296
292
  * PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn
297
293
  *
298
- * This is an asynchronous version of PG::Connection.connect().
294
+ * This is an asynchronous version of PG::Connection.new.
299
295
  *
300
296
  * Use #connect_poll to poll the status of the connection.
301
297
  *
302
298
  * NOTE: this does *not* set the connection's +client_encoding+ for you if
303
- * 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,
304
300
  * call #internal_encoding=. You can also set it automatically by setting
305
- * 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].
306
304
  *
307
305
  */
308
306
  static VALUE
@@ -345,6 +343,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
345
343
  *
346
344
  * Check server status.
347
345
  *
346
+ * See PG::Connection.new for a description of the parameters.
347
+ *
348
348
  * Returns one of:
349
349
  * [+PQPING_OK+]
350
350
  * server is accepting connections
@@ -354,8 +354,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
354
354
  * could not establish connection
355
355
  * [+PQPING_NO_ATTEMPT+]
356
356
  * connection not attempted (bad params)
357
- *
358
- * Available since PostgreSQL-9.1
359
357
  */
360
358
  static VALUE
361
359
  pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
@@ -426,7 +424,8 @@ pgconn_s_conndefaults(VALUE self)
426
424
  * Return value is the encrypted password.
427
425
  * The caller can assume the string doesn't contain any special characters that would require escaping.
428
426
  *
429
- * Available since PostgreSQL-10
427
+ * Available since PostgreSQL-10.
428
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
430
429
  */
431
430
  static VALUE
432
431
  pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
@@ -445,10 +444,6 @@ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
445
444
  if ( encrypted ) {
446
445
  rval = rb_str_new2( encrypted );
447
446
  PQfreemem( encrypted );
448
-
449
- OBJ_INFECT( rval, password );
450
- OBJ_INFECT( rval, username );
451
- OBJ_INFECT( rval, algorithm );
452
447
  } else {
453
448
  rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
454
449
  }
@@ -481,9 +476,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
481
476
  rval = rb_str_new2( encrypted );
482
477
  PQfreemem( encrypted );
483
478
 
484
- OBJ_INFECT( rval, password );
485
- OBJ_INFECT( rval, username );
486
-
487
479
  return rval;
488
480
  }
489
481
 
@@ -629,7 +621,7 @@ pgconn_db(VALUE self)
629
621
  {
630
622
  char *db = PQdb(pg_get_pgconn(self));
631
623
  if (!db) return Qnil;
632
- return rb_tainted_str_new2(db);
624
+ return rb_str_new2(db);
633
625
  }
634
626
 
635
627
  /*
@@ -643,7 +635,7 @@ pgconn_user(VALUE self)
643
635
  {
644
636
  char *user = PQuser(pg_get_pgconn(self));
645
637
  if (!user) return Qnil;
646
- return rb_tainted_str_new2(user);
638
+ return rb_str_new2(user);
647
639
  }
648
640
 
649
641
  /*
@@ -657,7 +649,7 @@ pgconn_pass(VALUE self)
657
649
  {
658
650
  char *user = PQpass(pg_get_pgconn(self));
659
651
  if (!user) return Qnil;
660
- return rb_tainted_str_new2(user);
652
+ return rb_str_new2(user);
661
653
  }
662
654
 
663
655
  /*
@@ -671,7 +663,7 @@ pgconn_host(VALUE self)
671
663
  {
672
664
  char *host = PQhost(pg_get_pgconn(self));
673
665
  if (!host) return Qnil;
674
- return rb_tainted_str_new2(host);
666
+ return rb_str_new2(host);
675
667
  }
676
668
 
677
669
  /*
@@ -698,7 +690,7 @@ pgconn_tty(VALUE self)
698
690
  {
699
691
  char *tty = PQtty(pg_get_pgconn(self));
700
692
  if (!tty) return Qnil;
701
- return rb_tainted_str_new2(tty);
693
+ return rb_str_new2(tty);
702
694
  }
703
695
 
704
696
  /*
@@ -712,7 +704,7 @@ pgconn_options(VALUE self)
712
704
  {
713
705
  char *options = PQoptions(pg_get_pgconn(self));
714
706
  if (!options) return Qnil;
715
- return rb_tainted_str_new2(options);
707
+ return rb_str_new2(options);
716
708
  }
717
709
 
718
710
 
@@ -793,7 +785,7 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
793
785
  if(ret == NULL)
794
786
  return Qnil;
795
787
  else
796
- return rb_tainted_str_new2(ret);
788
+ return rb_str_new2(ret);
797
789
  }
798
790
 
799
791
  /*
@@ -838,7 +830,7 @@ pgconn_error_message(VALUE self)
838
830
  {
839
831
  char *error = PQerrorMessage(pg_get_pgconn(self));
840
832
  if (!error) return Qnil;
841
- return rb_tainted_str_new2(error);
833
+ return rb_str_new2(error);
842
834
  }
843
835
 
844
836
  /*
@@ -862,6 +854,8 @@ static VALUE
862
854
  pgconn_socket(VALUE self)
863
855
  {
864
856
  int sd;
857
+ pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
858
+
865
859
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
866
860
  rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
867
861
  return INT2NUM(sd);
@@ -894,6 +888,7 @@ pgconn_socket_io(VALUE self)
894
888
 
895
889
  #ifdef _WIN32
896
890
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
891
+ this->ruby_sd = ruby_sd;
897
892
  #else
898
893
  ruby_sd = sd;
899
894
  #endif
@@ -957,32 +952,23 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
957
952
 
958
953
  /*
959
954
  * call-seq:
960
- * conn.exec(sql) -> PG::Result
961
- * conn.exec(sql) {|pg_result| block }
955
+ * conn.sync_exec(sql) -> PG::Result
956
+ * conn.sync_exec(sql) {|pg_result| block }
962
957
  *
963
- * Sends SQL query request specified by _sql_ to PostgreSQL.
964
- * Returns a PG::Result instance on success.
965
- * On failure, it raises a PG::Error.
966
- *
967
- * For backward compatibility, if you pass more than one parameter to this method,
968
- * it will call #exec_params for you. New code should explicitly use #exec_params if
969
- * 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.
970
960
  *
971
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
972
- * and the PG::Result object will automatically be cleared when the block terminates.
973
- * 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:
974
963
  *
975
- * #sync_exec is implemented on the synchronous command processing API of libpq, whereas
976
- * #async_exec is implemented on the asynchronous API.
977
- * #sync_exec is somewhat faster that #async_exec, but blocks any signals to be processed until
978
- * the query is finished. This is most notably visible by a delayed reaction to Control+C.
979
- * Both methods ensure that other threads can process while waiting for the server to
980
- * 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
981
967
  */
982
968
  static VALUE
983
969
  pgconn_exec(int argc, VALUE *argv, VALUE self)
984
970
  {
985
- PGconn *conn = pg_get_pgconn(self);
971
+ t_pg_connection *this = pg_get_connection_safe( self );
986
972
  PGresult *result = NULL;
987
973
  VALUE rb_pgresult;
988
974
 
@@ -990,7 +976,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
990
976
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
991
977
  VALUE query_str = argv[0];
992
978
 
993
- 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));
994
980
  rb_pgresult = pg_new_result(result, self);
995
981
  pg_result_check(rb_pgresult);
996
982
  if (rb_block_given_p()) {
@@ -1252,57 +1238,23 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1252
1238
 
1253
1239
  /*
1254
1240
  * call-seq:
1255
- * conn.exec_params(sql, params[, result_format[, type_map]] ) -> PG::Result
1256
- * conn.exec_params(sql, params[, result_format[, type_map]] ) {|pg_result| block }
1257
- *
1258
- * Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
1259
- * for parameters.
1241
+ * conn.sync_exec_params(sql, params[, result_format[, type_map]] ) -> PG::Result
1242
+ * conn.sync_exec_params(sql, params[, result_format[, type_map]] ) {|pg_result| block }
1260
1243
  *
1261
- * Returns a PG::Result instance on success. On failure, it raises a PG::Error.
1262
- *
1263
- * +params+ is an array of the bind parameters for the SQL query.
1264
- * Each element of the +params+ array may be either:
1265
- * a hash of the form:
1266
- * {:value => String (value of bind parameter)
1267
- * :type => Integer (oid of type of bind parameter)
1268
- * :format => Integer (0 for text, 1 for binary)
1269
- * }
1270
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1271
- * { :value => <string value>, :type => 0, :format => 0 }
1272
- *
1273
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1274
- * inside the SQL query. The 0th element of the +params+ array is bound
1275
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1276
- *
1277
- * If the types are not specified, they will be inferred by PostgreSQL.
1278
- * Instead of specifying type oids, it's recommended to simply add
1279
- * explicit casts in the query to ensure that the right type is used.
1280
- *
1281
- * For example: "SELECT $1::int"
1282
- *
1283
- * The optional +result_format+ should be 0 for text results, 1
1284
- * for binary.
1285
- *
1286
- * type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1287
- * This will type cast the params from various Ruby types before transmission
1288
- * based on the encoders defined by the type map. When a type encoder is used
1289
- * the format and oid of a given bind parameter are retrieved from the encoder
1290
- * instead out of the hash form described above.
1291
- *
1292
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1293
- * and the PG::Result object will automatically be cleared when the block terminates.
1294
- * 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.
1295
1247
  */
1296
1248
  static VALUE
1297
1249
  pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1298
1250
  {
1299
- PGconn *conn = pg_get_pgconn(self);
1251
+ t_pg_connection *this = pg_get_connection_safe( self );
1300
1252
  PGresult *result = NULL;
1301
1253
  VALUE rb_pgresult;
1302
1254
  VALUE command, in_res_fmt;
1303
1255
  int nParams;
1304
1256
  int resultFormat;
1305
- struct query_params_data paramsData = { ENCODING_GET(self) };
1257
+ struct query_params_data paramsData = { this->enc_idx };
1306
1258
 
1307
1259
  /* For compatibility we accept 1 to 4 parameters */
1308
1260
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
@@ -1321,7 +1273,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1321
1273
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1322
1274
  nParams = alloc_query_params( &paramsData );
1323
1275
 
1324
- result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1276
+ result = gvl_PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1325
1277
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1326
1278
 
1327
1279
  free_query_params( &paramsData );
@@ -1338,28 +1290,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1338
1290
 
1339
1291
  /*
1340
1292
  * call-seq:
1341
- * conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
1342
- *
1343
- * Prepares statement _sql_ with name _name_ to be executed later.
1344
- * Returns a PG::Result instance on success.
1345
- * On failure, it raises a PG::Error.
1293
+ * conn.sync_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
1346
1294
  *
1347
- * +param_types+ is an optional parameter to specify the Oids of the
1348
- * types of the parameters.
1349
- *
1350
- * If the types are not specified, they will be inferred by PostgreSQL.
1351
- * Instead of specifying type oids, it's recommended to simply add
1352
- * explicit casts in the query to ensure that the right type is used.
1353
- *
1354
- * For example: "SELECT $1::int"
1355
- *
1356
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1357
- * inside the SQL query.
1295
+ * This function has the same behavior as #async_prepare, but is implemented using the synchronous command processing API of libpq.
1296
+ * See #async_exec for the differences between the two API variants.
1297
+ * It's not recommended to use explicit sync or async variants but #prepare instead, unless you have a good reason to do so.
1358
1298
  */
1359
1299
  static VALUE
1360
1300
  pgconn_prepare(int argc, VALUE *argv, VALUE self)
1361
1301
  {
1362
- PGconn *conn = pg_get_pgconn(self);
1302
+ t_pg_connection *this = pg_get_connection_safe( self );
1363
1303
  PGresult *result = NULL;
1364
1304
  VALUE rb_pgresult;
1365
1305
  VALUE name, command, in_paramtypes;
@@ -1369,7 +1309,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1369
1309
  Oid *paramTypes = NULL;
1370
1310
  const char *name_cstr;
1371
1311
  const char *command_cstr;
1372
- int enc_idx = ENCODING_GET(self);
1312
+ int enc_idx = this->enc_idx;
1373
1313
 
1374
1314
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1375
1315
  name_cstr = pg_cstr_enc(name, enc_idx);
@@ -1387,7 +1327,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1387
1327
  paramTypes[i] = NUM2UINT(param);
1388
1328
  }
1389
1329
  }
1390
- result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1330
+ result = gvl_PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
1391
1331
 
1392
1332
  xfree(paramTypes);
1393
1333
 
@@ -1398,49 +1338,23 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1398
1338
 
1399
1339
  /*
1400
1340
  * call-seq:
1401
- * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
1402
- * conn.exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
1403
- *
1404
- * Execute prepared named statement specified by _statement_name_.
1405
- * Returns a PG::Result instance on success.
1406
- * On failure, it raises a PG::Error.
1407
- *
1408
- * +params+ is an array of the optional bind parameters for the
1409
- * SQL query. Each element of the +params+ array may be either:
1410
- * a hash of the form:
1411
- * {:value => String (value of bind parameter)
1412
- * :format => Integer (0 for text, 1 for binary)
1413
- * }
1414
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1415
- * { :value => <string value>, :format => 0 }
1416
- *
1417
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1418
- * inside the SQL query. The 0th element of the +params+ array is bound
1419
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1420
- *
1421
- * The optional +result_format+ should be 0 for text results, 1
1422
- * for binary.
1341
+ * conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
1342
+ * conn.sync_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
1423
1343
  *
1424
- * type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1425
- * This will type cast the params from various Ruby types before transmission
1426
- * based on the encoders defined by the type map. When a type encoder is used
1427
- * the format and oid of a given bind parameter are retrieved from the encoder
1428
- * instead out of the hash form described above.
1429
- *
1430
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1431
- * and the PG::Result object will automatically be cleared when the block terminates.
1432
- * In this instance, <code>conn.exec_prepared</code> returns the value of the block.
1344
+ * This function has the same behavior as #async_exec_prepared, but is implemented using the synchronous command processing API of libpq.
1345
+ * See #async_exec for the differences between the two API variants.
1346
+ * It's not recommended to use explicit sync or async variants but #exec_prepared instead, unless you have a good reason to do so.
1433
1347
  */
1434
1348
  static VALUE
1435
1349
  pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1436
1350
  {
1437
- PGconn *conn = pg_get_pgconn(self);
1351
+ t_pg_connection *this = pg_get_connection_safe( self );
1438
1352
  PGresult *result = NULL;
1439
1353
  VALUE rb_pgresult;
1440
1354
  VALUE name, in_res_fmt;
1441
1355
  int nParams;
1442
1356
  int resultFormat;
1443
- struct query_params_data paramsData = { ENCODING_GET(self) };
1357
+ struct query_params_data paramsData = { this->enc_idx };
1444
1358
 
1445
1359
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1446
1360
  paramsData.with_types = 0;
@@ -1453,7 +1367,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1453
1367
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1454
1368
  nParams = alloc_query_params( &paramsData );
1455
1369
 
1456
- result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1370
+ result = gvl_PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1457
1371
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1458
1372
  resultFormat);
1459
1373
 
@@ -1470,25 +1384,26 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1470
1384
 
1471
1385
  /*
1472
1386
  * call-seq:
1473
- * conn.describe_prepared( statement_name ) -> PG::Result
1387
+ * conn.sync_describe_prepared( statement_name ) -> PG::Result
1474
1388
  *
1475
- * Retrieve information about the prepared statement
1476
- * _statement_name_.
1389
+ * This function has the same behavior as #async_describe_prepared, but is implemented using the synchronous command processing API of libpq.
1390
+ * See #async_exec for the differences between the two API variants.
1391
+ * It's not recommended to use explicit sync or async variants but #describe_prepared instead, unless you have a good reason to do so.
1477
1392
  */
1478
1393
  static VALUE
1479
1394
  pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1480
1395
  {
1481
1396
  PGresult *result;
1482
1397
  VALUE rb_pgresult;
1483
- PGconn *conn = pg_get_pgconn(self);
1398
+ t_pg_connection *this = pg_get_connection_safe( self );
1484
1399
  const char *stmt;
1485
1400
  if(NIL_P(stmt_name)) {
1486
1401
  stmt = NULL;
1487
1402
  }
1488
1403
  else {
1489
- stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1404
+ stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1490
1405
  }
1491
- result = gvl_PQdescribePrepared(conn, stmt);
1406
+ result = gvl_PQdescribePrepared(this->pgconn, stmt);
1492
1407
  rb_pgresult = pg_new_result(result, self);
1493
1408
  pg_result_check(rb_pgresult);
1494
1409
  return rb_pgresult;
@@ -1497,9 +1412,11 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1497
1412
 
1498
1413
  /*
1499
1414
  * call-seq:
1500
- * conn.describe_portal( portal_name ) -> PG::Result
1415
+ * conn.sync_describe_portal( portal_name ) -> PG::Result
1501
1416
  *
1502
- * Retrieve information about the portal _portal_name_.
1417
+ * This function has the same behavior as #async_describe_portal, but is implemented using the synchronous command processing API of libpq.
1418
+ * See #async_exec for the differences between the two API variants.
1419
+ * It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
1503
1420
  */
1504
1421
  static VALUE
1505
1422
  pgconn_describe_portal(self, stmt_name)
@@ -1507,15 +1424,15 @@ pgconn_describe_portal(self, stmt_name)
1507
1424
  {
1508
1425
  PGresult *result;
1509
1426
  VALUE rb_pgresult;
1510
- PGconn *conn = pg_get_pgconn(self);
1427
+ t_pg_connection *this = pg_get_connection_safe( self );
1511
1428
  const char *stmt;
1512
1429
  if(NIL_P(stmt_name)) {
1513
1430
  stmt = NULL;
1514
1431
  }
1515
1432
  else {
1516
- stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1433
+ stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1517
1434
  }
1518
- result = gvl_PQdescribePortal(conn, stmt);
1435
+ result = gvl_PQdescribePortal(this->pgconn, stmt);
1519
1436
  rb_pgresult = pg_new_result(result, self);
1520
1437
  pg_result_check(rb_pgresult);
1521
1438
  return rb_pgresult;
@@ -1562,13 +1479,15 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1562
1479
  * Consider using exec_params, which avoids the need for passing values
1563
1480
  * inside of SQL commands.
1564
1481
  *
1565
- * Encoding of escaped string will be equal to client encoding of connection.
1482
+ * Character encoding of escaped string will be equal to client encoding of connection.
1566
1483
  *
1567
1484
  * NOTE: This class version of this method can only be used safely in client
1568
1485
  * programs that use a single PostgreSQL connection at a time (in this case it can
1569
1486
  * find out what it needs to know "behind the scenes"). It might give the wrong
1570
1487
  * results if used in programs that use multiple database connections; use the
1571
1488
  * same method on the connection object in such cases.
1489
+ *
1490
+ * See also convenience functions #escape_literal and #escape_identifier which also add proper quotes around the string.
1572
1491
  */
1573
1492
  static VALUE
1574
1493
  pgconn_s_escape(VALUE self, VALUE string)
@@ -1580,7 +1499,7 @@ pgconn_s_escape(VALUE self, VALUE string)
1580
1499
  int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
1581
1500
 
1582
1501
  StringValueCStr(string);
1583
- enc_idx = ENCODING_GET( singleton ? string : self );
1502
+ enc_idx = singleton ? ENCODING_GET(string) : pg_get_connection(self)->enc_idx;
1584
1503
  if( ENCODING_GET(string) != enc_idx ){
1585
1504
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1586
1505
  }
@@ -1597,7 +1516,6 @@ pgconn_s_escape(VALUE self, VALUE string)
1597
1516
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1598
1517
  }
1599
1518
  rb_str_set_len(result, size);
1600
- OBJ_INFECT(result, string);
1601
1519
 
1602
1520
  return result;
1603
1521
  }
@@ -1643,7 +1561,6 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
1643
1561
  }
1644
1562
 
1645
1563
  ret = rb_str_new((char*)to, to_len - 1);
1646
- OBJ_INFECT(ret, str);
1647
1564
  PQfreemem(to);
1648
1565
  return ret;
1649
1566
  }
@@ -1673,7 +1590,6 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
1673
1590
  to = PQunescapeBytea(from, &to_len);
1674
1591
 
1675
1592
  ret = rb_str_new((char*)to, to_len);
1676
- OBJ_INFECT(ret, str);
1677
1593
  PQfreemem(to);
1678
1594
  return ret;
1679
1595
  }
@@ -1684,33 +1600,32 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
1684
1600
  *
1685
1601
  * Escape an arbitrary String +str+ as a literal.
1686
1602
  *
1687
- * Available since PostgreSQL-9.0
1603
+ * See also PG::TextEncoder::QuotedLiteral for a type cast integrated version of this function.
1688
1604
  */
1689
1605
  static VALUE
1690
1606
  pgconn_escape_literal(VALUE self, VALUE string)
1691
1607
  {
1692
- PGconn *conn = pg_get_pgconn(self);
1608
+ t_pg_connection *this = pg_get_connection_safe( self );
1693
1609
  char *escaped = NULL;
1694
1610
  VALUE error;
1695
1611
  VALUE result = Qnil;
1696
- int enc_idx = ENCODING_GET(self);
1612
+ int enc_idx = this->enc_idx;
1697
1613
 
1698
1614
  StringValueCStr(string);
1699
1615
  if( ENCODING_GET(string) != enc_idx ){
1700
1616
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1701
1617
  }
1702
1618
 
1703
- escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1619
+ escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1704
1620
  if (escaped == NULL)
1705
1621
  {
1706
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1622
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1707
1623
  rb_iv_set(error, "@connection", self);
1708
1624
  rb_exc_raise(error);
1709
1625
  return Qnil;
1710
1626
  }
1711
1627
  result = rb_str_new2(escaped);
1712
1628
  PQfreemem(escaped);
1713
- OBJ_INFECT(result, string);
1714
1629
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
1715
1630
 
1716
1631
  return result;
@@ -1725,34 +1640,31 @@ pgconn_escape_literal(VALUE self, VALUE string)
1725
1640
  * This method does the same as #quote_ident with a String argument,
1726
1641
  * but it doesn't support an Array argument and it makes use of libpq
1727
1642
  * to process the string.
1728
- *
1729
- * Available since PostgreSQL-9.0
1730
1643
  */
1731
1644
  static VALUE
1732
1645
  pgconn_escape_identifier(VALUE self, VALUE string)
1733
1646
  {
1734
- PGconn *conn = pg_get_pgconn(self);
1647
+ t_pg_connection *this = pg_get_connection_safe( self );
1735
1648
  char *escaped = NULL;
1736
1649
  VALUE error;
1737
1650
  VALUE result = Qnil;
1738
- int enc_idx = ENCODING_GET(self);
1651
+ int enc_idx = this->enc_idx;
1739
1652
 
1740
1653
  StringValueCStr(string);
1741
1654
  if( ENCODING_GET(string) != enc_idx ){
1742
1655
  string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1743
1656
  }
1744
1657
 
1745
- escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1658
+ escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1746
1659
  if (escaped == NULL)
1747
1660
  {
1748
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1661
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1749
1662
  rb_iv_set(error, "@connection", self);
1750
1663
  rb_exc_raise(error);
1751
1664
  return Qnil;
1752
1665
  }
1753
1666
  result = rb_str_new2(escaped);
1754
1667
  PQfreemem(escaped);
1755
- OBJ_INFECT(result, string);
1756
1668
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
1757
1669
 
1758
1670
  return result;
@@ -1793,8 +1705,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1793
1705
  * # do something with the received row
1794
1706
  * end
1795
1707
  * end
1796
- *
1797
- * Available since PostgreSQL-9.2
1798
1708
  */
1799
1709
  static VALUE
1800
1710
  pgconn_set_single_row_mode(VALUE self)
@@ -1830,13 +1740,13 @@ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1830
1740
  static VALUE
1831
1741
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1832
1742
  {
1833
- PGconn *conn = pg_get_pgconn(self);
1743
+ t_pg_connection *this = pg_get_connection_safe( self );
1834
1744
  VALUE error;
1835
1745
 
1836
1746
  /* If called with no or nil parameters, use PQexec for compatibility */
1837
1747
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1838
- if(gvl_PQsendQuery(conn, pg_cstr_enc(argv[0], ENCODING_GET(self))) == 0) {
1839
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
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));
1840
1750
  rb_iv_set(error, "@connection", self);
1841
1751
  rb_exc_raise(error);
1842
1752
  }
@@ -1882,7 +1792,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1882
1792
  * The optional +result_format+ should be 0 for text results, 1
1883
1793
  * for binary.
1884
1794
  *
1885
- * type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1795
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1886
1796
  * This will type cast the params from various Ruby types before transmission
1887
1797
  * based on the encoders defined by the type map. When a type encoder is used
1888
1798
  * the format and oid of a given bind parameter are retrieved from the encoder
@@ -1892,13 +1802,13 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1892
1802
  static VALUE
1893
1803
  pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1894
1804
  {
1895
- PGconn *conn = pg_get_pgconn(self);
1805
+ t_pg_connection *this = pg_get_connection_safe( self );
1896
1806
  int result;
1897
1807
  VALUE command, in_res_fmt;
1898
1808
  VALUE error;
1899
1809
  int nParams;
1900
1810
  int resultFormat;
1901
- struct query_params_data paramsData = { ENCODING_GET(self) };
1811
+ struct query_params_data paramsData = { this->enc_idx };
1902
1812
 
1903
1813
  rb_scan_args(argc, argv, "22", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1904
1814
  paramsData.with_types = 1;
@@ -1907,13 +1817,13 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1907
1817
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1908
1818
  nParams = alloc_query_params( &paramsData );
1909
1819
 
1910
- 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,
1911
1821
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1912
1822
 
1913
1823
  free_query_params( &paramsData );
1914
1824
 
1915
1825
  if(result == 0) {
1916
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1826
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1917
1827
  rb_iv_set(error, "@connection", self);
1918
1828
  rb_exc_raise(error);
1919
1829
  }
@@ -1943,7 +1853,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1943
1853
  static VALUE
1944
1854
  pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1945
1855
  {
1946
- PGconn *conn = pg_get_pgconn(self);
1856
+ t_pg_connection *this = pg_get_connection_safe( self );
1947
1857
  int result;
1948
1858
  VALUE name, command, in_paramtypes;
1949
1859
  VALUE param;
@@ -1953,7 +1863,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1953
1863
  Oid *paramTypes = NULL;
1954
1864
  const char *name_cstr;
1955
1865
  const char *command_cstr;
1956
- int enc_idx = ENCODING_GET(self);
1866
+ int enc_idx = this->enc_idx;
1957
1867
 
1958
1868
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1959
1869
  name_cstr = pg_cstr_enc(name, enc_idx);
@@ -1971,12 +1881,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1971
1881
  paramTypes[i] = NUM2UINT(param);
1972
1882
  }
1973
1883
  }
1974
- result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1884
+ result = gvl_PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
1975
1885
 
1976
1886
  xfree(paramTypes);
1977
1887
 
1978
1888
  if(result == 0) {
1979
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1889
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1980
1890
  rb_iv_set(error, "@connection", self);
1981
1891
  rb_exc_raise(error);
1982
1892
  }
@@ -2008,7 +1918,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
2008
1918
  * The optional +result_format+ should be 0 for text results, 1
2009
1919
  * for binary.
2010
1920
  *
2011
- * type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
1921
+ * +type_map+ can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
2012
1922
  * This will type cast the params from various Ruby types before transmission
2013
1923
  * based on the encoders defined by the type map. When a type encoder is used
2014
1924
  * the format and oid of a given bind parameter are retrieved from the encoder
@@ -2018,13 +1928,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
2018
1928
  static VALUE
2019
1929
  pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2020
1930
  {
2021
- PGconn *conn = pg_get_pgconn(self);
1931
+ t_pg_connection *this = pg_get_connection_safe( self );
2022
1932
  int result;
2023
1933
  VALUE name, in_res_fmt;
2024
1934
  VALUE error;
2025
1935
  int nParams;
2026
1936
  int resultFormat;
2027
- struct query_params_data paramsData = { ENCODING_GET(self) };
1937
+ struct query_params_data paramsData = { this->enc_idx };
2028
1938
 
2029
1939
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
2030
1940
  paramsData.with_types = 0;
@@ -2038,14 +1948,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2038
1948
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
2039
1949
  nParams = alloc_query_params( &paramsData );
2040
1950
 
2041
- 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,
2042
1952
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
2043
1953
  resultFormat);
2044
1954
 
2045
1955
  free_query_params( &paramsData );
2046
1956
 
2047
1957
  if(result == 0) {
2048
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1958
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2049
1959
  rb_iv_set(error, "@connection", self);
2050
1960
  rb_exc_raise(error);
2051
1961
  }
@@ -2063,10 +1973,10 @@ static VALUE
2063
1973
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2064
1974
  {
2065
1975
  VALUE error;
2066
- PGconn *conn = pg_get_pgconn(self);
1976
+ t_pg_connection *this = pg_get_connection_safe( self );
2067
1977
  /* returns 0 on failure */
2068
- if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
2069
- 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));
2070
1980
  rb_iv_set(error, "@connection", self);
2071
1981
  rb_exc_raise(error);
2072
1982
  }
@@ -2085,10 +1995,10 @@ static VALUE
2085
1995
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2086
1996
  {
2087
1997
  VALUE error;
2088
- PGconn *conn = pg_get_pgconn(self);
1998
+ t_pg_connection *this = pg_get_connection_safe( self );
2089
1999
  /* returns 0 on failure */
2090
- if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
2091
- 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));
2092
2002
  rb_iv_set(error, "@connection", self);
2093
2003
  rb_exc_raise(error);
2094
2004
  }
@@ -2289,7 +2199,7 @@ pgconn_cancel(VALUE self)
2289
2199
  static VALUE
2290
2200
  pgconn_notifies(VALUE self)
2291
2201
  {
2292
- PGconn* conn = pg_get_pgconn(self);
2202
+ t_pg_connection *this = pg_get_connection_safe( self );
2293
2203
  PGnotify *notification;
2294
2204
  VALUE hash;
2295
2205
  VALUE sym_relname, sym_be_pid, sym_extra;
@@ -2299,17 +2209,17 @@ pgconn_notifies(VALUE self)
2299
2209
  sym_be_pid = ID2SYM(rb_intern("be_pid"));
2300
2210
  sym_extra = ID2SYM(rb_intern("extra"));
2301
2211
 
2302
- notification = gvl_PQnotifies(conn);
2212
+ notification = gvl_PQnotifies(this->pgconn);
2303
2213
  if (notification == NULL) {
2304
2214
  return Qnil;
2305
2215
  }
2306
2216
 
2307
2217
  hash = rb_hash_new();
2308
- relname = rb_tainted_str_new2(notification->relname);
2218
+ relname = rb_str_new2(notification->relname);
2309
2219
  be_pid = INT2NUM(notification->be_pid);
2310
- extra = rb_tainted_str_new2(notification->extra);
2311
- PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2312
- 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 );
2313
2223
 
2314
2224
  rb_hash_aset(hash, sym_relname, relname);
2315
2225
  rb_hash_aset(hash, sym_be_pid, be_pid);
@@ -2482,7 +2392,7 @@ notify_readable(PGconn *conn)
2482
2392
  static VALUE
2483
2393
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2484
2394
  {
2485
- PGconn *conn = pg_get_pgconn( self );
2395
+ t_pg_connection *this = pg_get_connection_safe( self );
2486
2396
  PGnotify *pnotification;
2487
2397
  struct timeval timeout;
2488
2398
  struct timeval *ptimeout = NULL;
@@ -2498,17 +2408,17 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2498
2408
  ptimeout = &timeout;
2499
2409
  }
2500
2410
 
2501
- pnotification = (PGnotify*) wait_socket_readable( conn, ptimeout, notify_readable);
2411
+ pnotification = (PGnotify*) wait_socket_readable( this->pgconn, ptimeout, notify_readable);
2502
2412
 
2503
2413
  /* Return nil if the select timed out */
2504
2414
  if ( !pnotification ) return Qnil;
2505
2415
 
2506
- relname = rb_tainted_str_new2( pnotification->relname );
2507
- PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2416
+ relname = rb_str_new2( pnotification->relname );
2417
+ PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
2508
2418
  be_pid = INT2NUM( pnotification->be_pid );
2509
2419
  if ( *pnotification->extra ) {
2510
- extra = rb_tainted_str_new2( pnotification->extra );
2511
- PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
2420
+ extra = rb_str_new2( pnotification->extra );
2421
+ PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
2512
2422
  }
2513
2423
  PQfreemem( pnotification );
2514
2424
 
@@ -2568,7 +2478,7 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2568
2478
 
2569
2479
  if( p_coder ){
2570
2480
  t_pg_coder_enc_func enc_func;
2571
- int enc_idx = ENCODING_GET(self);
2481
+ int enc_idx = this->enc_idx;
2572
2482
 
2573
2483
  enc_func = pg_coder_enc_func( p_coder );
2574
2484
  len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
@@ -2618,16 +2528,16 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2618
2528
  VALUE error;
2619
2529
  int ret;
2620
2530
  const char *error_message = NULL;
2621
- PGconn *conn = pg_get_pgconn(self);
2531
+ t_pg_connection *this = pg_get_connection_safe( self );
2622
2532
 
2623
2533
  if (rb_scan_args(argc, argv, "01", &str) == 0)
2624
2534
  error_message = NULL;
2625
2535
  else
2626
- error_message = pg_cstr_enc(str, ENCODING_GET(self));
2536
+ error_message = pg_cstr_enc(str, this->enc_idx);
2627
2537
 
2628
- ret = gvl_PQputCopyEnd(conn, error_message);
2538
+ ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2629
2539
  if(ret == -1) {
2630
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2540
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2631
2541
  rb_iv_set(error, "@connection", self);
2632
2542
  rb_exc_raise(error);
2633
2543
  }
@@ -2693,9 +2603,9 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2693
2603
 
2694
2604
  if( p_coder ){
2695
2605
  t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, p_coder->format );
2696
- 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 );
2697
2607
  } else {
2698
- result = rb_tainted_str_new(buffer, ret);
2608
+ result = rb_str_new(buffer, ret);
2699
2609
  }
2700
2610
 
2701
2611
  PQfreemem(buffer);
@@ -2708,9 +2618,16 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2708
2618
  *
2709
2619
  * Sets connection's verbosity to _verbosity_ and returns
2710
2620
  * the previous setting. Available settings are:
2621
+ *
2711
2622
  * * PQERRORS_TERSE
2712
2623
  * * PQERRORS_DEFAULT
2713
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].
2714
2631
  */
2715
2632
  static VALUE
2716
2633
  pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
@@ -2720,6 +2637,37 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2720
2637
  return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
2721
2638
  }
2722
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
+
2723
2671
  /*
2724
2672
  * call-seq:
2725
2673
  * conn.trace( stream ) -> nil
@@ -2738,7 +2686,7 @@ pgconn_trace(VALUE self, VALUE stream)
2738
2686
  VALUE new_file;
2739
2687
  t_pg_connection *this = pg_get_connection_safe( self );
2740
2688
 
2741
- if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
2689
+ if(!rb_respond_to(stream,rb_intern("fileno")))
2742
2690
  rb_raise(rb_eArgError, "stream does not respond to method: fileno");
2743
2691
 
2744
2692
  fileno = rb_funcall(stream, rb_intern("fileno"), 0);
@@ -2871,8 +2819,8 @@ notice_processor_proxy(void *arg, const char *message)
2871
2819
  t_pg_connection *this = pg_get_connection( self );
2872
2820
 
2873
2821
  if (this->notice_receiver != Qnil) {
2874
- VALUE message_str = rb_tainted_str_new2(message);
2875
- 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 );
2876
2824
  rb_funcall(this->notice_receiver, rb_intern("call"), 1, message_str);
2877
2825
  }
2878
2826
  return;
@@ -2930,7 +2878,7 @@ static VALUE
2930
2878
  pgconn_get_client_encoding(VALUE self)
2931
2879
  {
2932
2880
  char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self)));
2933
- return rb_tainted_str_new2(encoding);
2881
+ return rb_str_new2(encoding);
2934
2882
  }
2935
2883
 
2936
2884
 
@@ -3042,14 +2990,12 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
3042
2990
  int enc_idx;
3043
2991
 
3044
2992
  if( rb_obj_is_kind_of(self, rb_cPGconn) ){
3045
- enc_idx = ENCODING_GET( self );
2993
+ enc_idx = pg_get_connection(self)->enc_idx;
3046
2994
  }else{
3047
2995
  enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
3048
2996
  }
3049
2997
  pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
3050
2998
 
3051
- OBJ_INFECT(ret, str_or_array);
3052
-
3053
2999
  return ret;
3054
3000
  }
3055
3001
 
@@ -3174,19 +3120,30 @@ pgconn_discard_results(VALUE self)
3174
3120
 
3175
3121
  /*
3176
3122
  * call-seq:
3177
- * conn.async_exec(sql) -> PG::Result
3178
- * conn.async_exec(sql) {|pg_result| block }
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.
3179
3129
  *
3180
- * This function has the same behavior as #sync_exec,
3181
- * but is implemented using the asynchronous command
3182
- * processing API of libpq.
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.
3183
3133
  *
3184
- * Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
3185
- * However #async_exec has two advantages:
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.
3186
3137
  *
3187
- * 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
3188
- * 2. Ruby VM gets notified about IO blocked operations.
3189
- * It can therefore schedule thing like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
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].
3190
3147
  */
3191
3148
  static VALUE
3192
3149
  pgconn_async_exec(int argc, VALUE *argv, VALUE self)
@@ -3207,11 +3164,53 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3207
3164
 
3208
3165
  /*
3209
3166
  * call-seq:
3210
- * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) -> nil
3211
- * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
3167
+ * conn.exec_params(sql, params [, result_format [, type_map ]] ) -> nil
3168
+ * conn.exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
3212
3169
  *
3213
- * This function has the same behavior as #sync_exec_params, but is implemented using the asynchronous command processing API of libpq.
3214
- * See #async_exec for the differences between the two API variants.
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].
3215
3214
  */
3216
3215
  static VALUE
3217
3216
  pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
@@ -3238,10 +3237,25 @@ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
3238
3237
 
3239
3238
  /*
3240
3239
  * call-seq:
3241
- * conn.async_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
3240
+ * conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
3242
3241
  *
3243
- * This function has the same behavior as #sync_prepare, but is implemented using the asynchronous command processing API of libpq.
3244
- * See #async_exec for the differences between the two API variants.
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].
3245
3259
  */
3246
3260
  static VALUE
3247
3261
  pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
@@ -3262,11 +3276,40 @@ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
3262
3276
 
3263
3277
  /*
3264
3278
  * call-seq:
3265
- * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
3266
- * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
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 }
3267
3281
  *
3268
- * This function has the same behavior as #sync_exec_prepared, but is implemented using the asynchronous command processing API of libpq.
3269
- * See #async_exec for the differences between the two API variants.
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].
3270
3313
  */
3271
3314
  static VALUE
3272
3315
  pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
@@ -3287,10 +3330,11 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3287
3330
 
3288
3331
  /*
3289
3332
  * call-seq:
3290
- * conn.async_describe_portal( portal_name ) -> PG::Result
3333
+ * conn.describe_portal( portal_name ) -> PG::Result
3291
3334
  *
3292
- * This function has the same behavior as #sync_describe_portal, but is implemented using the asynchronous command processing API of libpq.
3293
- * See #async_exec for the differences between the two API variants.
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].
3294
3338
  */
3295
3339
  static VALUE
3296
3340
  pgconn_async_describe_portal(VALUE self, VALUE portal)
@@ -3311,10 +3355,11 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
3311
3355
 
3312
3356
  /*
3313
3357
  * call-seq:
3314
- * conn.async_describe_prepared( statement_name ) -> PG::Result
3358
+ * conn.describe_prepared( statement_name ) -> PG::Result
3315
3359
  *
3316
- * This function has the same behavior as #sync_describe_prepared, but is implemented using the asynchronous command processing API of libpq.
3317
- * See #async_exec for the differences between the two API variants.
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].
3318
3363
  */
3319
3364
  static VALUE
3320
3365
  pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
@@ -3338,7 +3383,7 @@ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3338
3383
  * call-seq:
3339
3384
  * conn.ssl_in_use? -> Boolean
3340
3385
  *
3341
- * Returns +true+ if the connection uses SSL, +false+ if not.
3386
+ * Returns +true+ if the connection uses SSL/TLS, +false+ if not.
3342
3387
  *
3343
3388
  * Available since PostgreSQL-9.5
3344
3389
  */
@@ -3372,7 +3417,7 @@ pgconn_ssl_in_use(VALUE self)
3372
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".
3373
3418
  *
3374
3419
  *
3375
- * 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].
3376
3421
  *
3377
3422
  * Available since PostgreSQL-9.5
3378
3423
  */
@@ -3600,7 +3645,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3600
3645
  return Qnil;
3601
3646
  }
3602
3647
 
3603
- str = rb_tainted_str_new(buffer, ret);
3648
+ str = rb_str_new(buffer, ret);
3604
3649
  xfree(buffer);
3605
3650
 
3606
3651
  return str;
@@ -3704,12 +3749,15 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3704
3749
  }
3705
3750
 
3706
3751
 
3707
- void
3752
+ static void
3708
3753
  pgconn_set_internal_encoding_index( VALUE self )
3709
3754
  {
3710
- PGconn *conn = pg_get_pgconn(self);
3711
- rb_encoding *enc = pg_conn_enc_get( conn );
3712
- 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;
3713
3761
  }
3714
3762
 
3715
3763
  /*
@@ -3752,7 +3800,6 @@ static VALUE pgconn_external_encoding(VALUE self);
3752
3800
  static VALUE
3753
3801
  pgconn_internal_encoding_set(VALUE self, VALUE enc)
3754
3802
  {
3755
- VALUE enc_inspect;
3756
3803
  if (NIL_P(enc)) {
3757
3804
  pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
3758
3805
  return enc;
@@ -3773,11 +3820,6 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
3773
3820
  pgconn_set_internal_encoding_index( self );
3774
3821
  return enc;
3775
3822
  }
3776
-
3777
- enc_inspect = rb_inspect(enc);
3778
- rb_raise( rb_ePGerror, "unknown encoding: %s", StringValueCStr(enc_inspect) );
3779
-
3780
- return Qnil;
3781
3823
  }
3782
3824
 
3783
3825
 
@@ -3796,14 +3838,9 @@ pgconn_external_encoding(VALUE self)
3796
3838
  rb_encoding *enc = NULL;
3797
3839
  const char *pg_encname = NULL;
3798
3840
 
3799
- /* Use cached value if found */
3800
- if ( RTEST(this->external_encoding) ) return this->external_encoding;
3801
-
3802
3841
  pg_encname = PQparameterStatus( this->pgconn, "server_encoding" );
3803
3842
  enc = pg_get_pg_encname_as_rb_encoding( pg_encname );
3804
- this->external_encoding = rb_enc_from_encoding( enc );
3805
-
3806
- return this->external_encoding;
3843
+ return rb_enc_from_encoding( enc );
3807
3844
  }
3808
3845
 
3809
3846
 
@@ -3821,9 +3858,10 @@ pgconn_set_client_encoding_async1( VALUE args )
3821
3858
 
3822
3859
 
3823
3860
  static VALUE
3824
- pgconn_set_client_encoding_async2( VALUE arg )
3861
+ pgconn_set_client_encoding_async2( VALUE arg, VALUE ex )
3825
3862
  {
3826
3863
  UNUSED(arg);
3864
+ UNUSED(ex);
3827
3865
  return 1;
3828
3866
  }
3829
3867
 
@@ -4045,16 +4083,54 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
4045
4083
 
4046
4084
  /*
4047
4085
  * call-seq:
4048
- * res.guess_result_memsize = enabled
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
4049
4117
  *
4050
- * This method is for testing only and will probably be removed in the future.
4118
+ * Get type of field names.
4119
+ *
4120
+ * See description at #field_name_type=
4051
4121
  */
4052
4122
  static VALUE
4053
- pgconn_guess_result_memsize_set(VALUE self, VALUE enable)
4123
+ pgconn_field_name_type_get(VALUE self)
4054
4124
  {
4055
4125
  t_pg_connection *this = pg_get_connection( self );
4056
- this->guess_result_memsize = RTEST(enable);
4057
- return enable;
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
+ }
4058
4134
  }
4059
4135
 
4060
4136
 
@@ -4068,8 +4144,13 @@ init_pg_connection()
4068
4144
  sym_type = ID2SYM(rb_intern("type"));
4069
4145
  sym_format = ID2SYM(rb_intern("format"));
4070
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"));
4071
4150
 
4072
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" ); */
4073
4154
  rb_include_module(rb_cPGconn, rb_mPGconstants);
4074
4155
 
4075
4156
  /****** PG::Connection CLASS METHODS ******/
@@ -4130,6 +4211,22 @@ init_pg_connection()
4130
4211
  rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
4131
4212
  rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
4132
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
+
4133
4230
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
4134
4231
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
4135
4232
  rb_define_alias(rb_cPGconn, "escape", "escape_string");
@@ -4142,17 +4239,10 @@ init_pg_connection()
4142
4239
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
4143
4240
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
4144
4241
  rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
4145
- rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
4146
- rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
4147
- rb_define_alias(rb_cPGconn, "async_query", "async_exec");
4148
4242
  rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
4149
- rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
4150
4243
  rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4151
- rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
4152
4244
  rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
4153
- rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
4154
4245
  rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
4155
- rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
4156
4246
  rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
4157
4247
  rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
4158
4248
  rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
@@ -4175,9 +4265,11 @@ init_pg_connection()
4175
4265
 
4176
4266
  /****** PG::Connection INSTANCE METHODS: Control Functions ******/
4177
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
4178
4271
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4179
4272
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4180
- rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
4181
4273
 
4182
4274
  /****** PG::Connection INSTANCE METHODS: Notice Processing ******/
4183
4275
  rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
@@ -4244,5 +4336,7 @@ init_pg_connection()
4244
4336
  rb_define_method(rb_cPGconn, "encoder_for_put_copy_data", pgconn_encoder_for_put_copy_data_get, 0);
4245
4337
  rb_define_method(rb_cPGconn, "decoder_for_get_copy_data=", pgconn_decoder_for_get_copy_data_set, 1);
4246
4338
  rb_define_method(rb_cPGconn, "decoder_for_get_copy_data", pgconn_decoder_for_get_copy_data_get, 0);
4247
- }
4248
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
+ }