pg 1.1.4 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +63 -0
- data/Manifest.txt +3 -2
- data/README-Windows.rdoc +4 -4
- data/README.ja.rdoc +1 -2
- data/README.rdoc +43 -8
- data/Rakefile +3 -3
- data/Rakefile.cross +6 -3
- data/ext/errorcodes.def +64 -0
- data/ext/errorcodes.txt +18 -2
- data/ext/extconf.rb +6 -6
- data/ext/pg.c +132 -95
- data/ext/pg.h +20 -18
- data/ext/pg_binary_decoder.c +9 -9
- data/ext/pg_binary_encoder.c +13 -12
- data/ext/pg_coder.c +5 -5
- data/ext/pg_connection.c +388 -298
- data/ext/pg_copy_coder.c +5 -3
- data/ext/pg_record_coder.c +490 -0
- data/ext/pg_result.c +269 -123
- data/ext/pg_text_decoder.c +14 -8
- data/ext/pg_text_encoder.c +180 -48
- data/ext/pg_tuple.c +14 -6
- data/ext/pg_type_map.c +1 -1
- data/ext/pg_type_map_all_strings.c +4 -4
- data/ext/pg_type_map_by_class.c +4 -3
- data/ext/pg_type_map_by_column.c +7 -6
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +3 -2
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/{util.c → pg_util.c} +5 -5
- data/ext/{util.h → pg_util.h} +0 -0
- data/lib/pg.rb +2 -3
- data/lib/pg/basic_type_mapping.rb +79 -16
- data/lib/pg/binary_decoder.rb +1 -0
- data/lib/pg/coder.rb +22 -1
- data/lib/pg/connection.rb +2 -2
- data/lib/pg/constants.rb +1 -0
- data/lib/pg/exceptions.rb +1 -0
- data/lib/pg/result.rb +13 -1
- data/lib/pg/text_decoder.rb +2 -3
- data/lib/pg/text_encoder.rb +8 -18
- data/lib/pg/type_map_by_column.rb +2 -1
- data/spec/helpers.rb +10 -8
- data/spec/pg/basic_type_mapping_spec.rb +150 -13
- data/spec/pg/connection_spec.rb +89 -50
- data/spec/pg/result_spec.rb +193 -3
- data/spec/pg/tuple_spec.rb +55 -2
- data/spec/pg/type_map_by_column_spec.rb +5 -1
- data/spec/pg/type_spec.rb +180 -6
- metadata +17 -15
- 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,14 @@ 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
|
-
|
104
|
-
|
105
|
-
|
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;
|
106
107
|
|
107
108
|
#if defined(_WIN32)
|
108
109
|
/* File descriptor to be used for rb_w32_unwrap_io_handle() */
|
@@ -128,10 +129,16 @@ typedef struct {
|
|
128
129
|
*/
|
129
130
|
t_typemap *p_typemap;
|
130
131
|
|
132
|
+
/* Ruby encoding index of the client/internal encoding */
|
133
|
+
int enc_idx : PG_ENC_IDX_BITS;
|
134
|
+
|
131
135
|
/* 0 = PGresult is cleared by PG::Result#clear or by the GC
|
132
136
|
* 1 = PGresult is cleared internally by libpq
|
133
137
|
*/
|
134
|
-
int autoclear;
|
138
|
+
unsigned int autoclear : 1;
|
139
|
+
|
140
|
+
/* flags controlling Symbol/String field names */
|
141
|
+
unsigned int flags : 2;
|
135
142
|
|
136
143
|
/* Number of fields in fnames[] .
|
137
144
|
* Set to -1 if fnames[] is not yet initialized.
|
@@ -147,7 +154,7 @@ typedef struct {
|
|
147
154
|
/* Hash with fnames[] to field number mapping. */
|
148
155
|
VALUE field_map;
|
149
156
|
|
150
|
-
/* List of field names as frozen String objects.
|
157
|
+
/* List of field names as frozen String or Symbol objects.
|
151
158
|
* Only valid if nfields != -1
|
152
159
|
*/
|
153
160
|
VALUE fnames[0];
|
@@ -163,6 +170,10 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
|
163
170
|
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
164
171
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
165
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
|
+
|
166
177
|
#define PG_CODER_TIMESTAMP_DB_UTC 0x0
|
167
178
|
#define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
|
168
179
|
#define PG_CODER_TIMESTAMP_APP_UTC 0x0
|
@@ -275,6 +286,7 @@ void init_pg_type_map_by_oid _(( void ));
|
|
275
286
|
void init_pg_type_map_in_ruby _(( void ));
|
276
287
|
void init_pg_coder _(( void ));
|
277
288
|
void init_pg_copycoder _(( void ));
|
289
|
+
void init_pg_recordcoder _(( void ));
|
278
290
|
void init_pg_text_encoder _(( void ));
|
279
291
|
void init_pg_text_decoder _(( void ));
|
280
292
|
void init_pg_binary_encoder _(( void ));
|
@@ -305,11 +317,6 @@ char *pg_rb_str_ensure_capa _(( VALUE, long, char *,
|
|
305
317
|
(curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
|
306
318
|
)
|
307
319
|
|
308
|
-
#define PG_RB_TAINTED_STR_NEW( str, curr_ptr, end_ptr ) ( \
|
309
|
-
(str) = rb_tainted_str_new( NULL, 0 ), \
|
310
|
-
(curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
|
311
|
-
)
|
312
|
-
|
313
320
|
VALUE pg_typemap_fit_to_result _(( VALUE, VALUE ));
|
314
321
|
VALUE pg_typemap_fit_to_query _(( VALUE, VALUE ));
|
315
322
|
int pg_typemap_fit_to_copy_get _(( VALUE ));
|
@@ -333,12 +340,7 @@ VALUE pg_tuple_new _(( VALUE, int ));
|
|
333
340
|
static inline t_pg_result *
|
334
341
|
pgresult_get_this( VALUE self )
|
335
342
|
{
|
336
|
-
|
337
|
-
|
338
|
-
if( this == NULL )
|
339
|
-
rb_raise(rb_ePGerror, "result has been cleared");
|
340
|
-
|
341
|
-
return this;
|
343
|
+
return RTYPEDDATA_DATA(self);
|
342
344
|
}
|
343
345
|
|
344
346
|
|
data/ext/pg_binary_decoder.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
#include "ruby/version.h"
|
8
8
|
#include "pg.h"
|
9
|
-
#include "
|
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
|
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 =
|
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
|
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 =
|
116
|
+
VALUE out_value = rb_str_new(NULL, encoded_len);
|
117
117
|
|
118
118
|
base64_encode( RSTRING_PTR(out_value), val, len );
|
119
119
|
|
data/ext/pg_binary_encoder.c
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
7
7
|
#include "pg.h"
|
8
|
-
#include "
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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::
|
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::
|
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
@@ -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 );
|
data/ext/pg_connection.c
CHANGED
@@ -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
|
@@ -152,7 +153,6 @@ pgconn_gc_mark( t_pg_connection *this )
|
|
152
153
|
rb_gc_mark( this->type_map_for_queries );
|
153
154
|
rb_gc_mark( this->type_map_for_results );
|
154
155
|
rb_gc_mark( this->trace_stream );
|
155
|
-
rb_gc_mark( this->external_encoding );
|
156
156
|
rb_gc_mark( this->encoder_for_put_copy_data );
|
157
157
|
rb_gc_mark( this->decoder_for_get_copy_data );
|
158
158
|
}
|
@@ -200,8 +200,6 @@ pgconn_s_allocate( VALUE klass )
|
|
200
200
|
this->encoder_for_put_copy_data = Qnil;
|
201
201
|
this->decoder_for_get_copy_data = Qnil;
|
202
202
|
this->trace_stream = Qnil;
|
203
|
-
this->external_encoding = Qnil;
|
204
|
-
this->guess_result_memsize = 1;
|
205
203
|
|
206
204
|
return self;
|
207
205
|
}
|
@@ -218,32 +216,27 @@ pgconn_s_allocate( VALUE klass )
|
|
218
216
|
*
|
219
217
|
* Create a connection to the specified server.
|
220
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:
|
221
226
|
* [+host+]
|
222
227
|
* server hostname
|
223
|
-
* [+hostaddr+]
|
224
|
-
* server address (avoids hostname lookup, overrides +host+)
|
225
228
|
* [+port+]
|
226
229
|
* server port number
|
230
|
+
* [+options+]
|
231
|
+
* backend options
|
232
|
+
* [+tty+]
|
233
|
+
* (ignored in newer versions of PostgreSQL)
|
227
234
|
* [+dbname+]
|
228
235
|
* connecting database name
|
229
236
|
* [+user+]
|
230
237
|
* login user name
|
231
238
|
* [+password+]
|
232
239
|
* login password
|
233
|
-
* [+connect_timeout+]
|
234
|
-
* maximum time to wait for connection to succeed
|
235
|
-
* [+options+]
|
236
|
-
* backend options
|
237
|
-
* [+tty+]
|
238
|
-
* (ignored in newer versions of PostgreSQL)
|
239
|
-
* [+sslmode+]
|
240
|
-
* (disable|allow|prefer|require)
|
241
|
-
* [+krbsrvname+]
|
242
|
-
* kerberos service name
|
243
|
-
* [+gsslib+]
|
244
|
-
* GSS library to use for GSSAPI authentication
|
245
|
-
* [+service+]
|
246
|
-
* service name to use for additional parameters
|
247
240
|
*
|
248
241
|
* Examples:
|
249
242
|
*
|
@@ -259,7 +252,7 @@ pgconn_s_allocate( VALUE klass )
|
|
259
252
|
* # As an Array
|
260
253
|
* PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
|
261
254
|
*
|
262
|
-
* 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
|
263
256
|
* connection will have its +client_encoding+ set accordingly.
|
264
257
|
*
|
265
258
|
* Raises a PG::Error if the connection fails.
|
@@ -298,14 +291,16 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
298
291
|
* PG::Connection.connect_start(connection_string) -> conn
|
299
292
|
* PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn
|
300
293
|
*
|
301
|
-
* This is an asynchronous version of PG::Connection.
|
294
|
+
* This is an asynchronous version of PG::Connection.new.
|
302
295
|
*
|
303
296
|
* Use #connect_poll to poll the status of the connection.
|
304
297
|
*
|
305
298
|
* NOTE: this does *not* set the connection's +client_encoding+ for you if
|
306
|
-
* 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,
|
307
300
|
* call #internal_encoding=. You can also set it automatically by setting
|
308
|
-
* ENV['PGCLIENTENCODING']
|
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].
|
309
304
|
*
|
310
305
|
*/
|
311
306
|
static VALUE
|
@@ -348,6 +343,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
348
343
|
*
|
349
344
|
* Check server status.
|
350
345
|
*
|
346
|
+
* See PG::Connection.new for a description of the parameters.
|
347
|
+
*
|
351
348
|
* Returns one of:
|
352
349
|
* [+PQPING_OK+]
|
353
350
|
* server is accepting connections
|
@@ -357,8 +354,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
357
354
|
* could not establish connection
|
358
355
|
* [+PQPING_NO_ATTEMPT+]
|
359
356
|
* connection not attempted (bad params)
|
360
|
-
*
|
361
|
-
* Available since PostgreSQL-9.1
|
362
357
|
*/
|
363
358
|
static VALUE
|
364
359
|
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
@@ -429,7 +424,8 @@ pgconn_s_conndefaults(VALUE self)
|
|
429
424
|
* Return value is the encrypted password.
|
430
425
|
* The caller can assume the string doesn't contain any special characters that would require escaping.
|
431
426
|
*
|
432
|
-
* 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].
|
433
429
|
*/
|
434
430
|
static VALUE
|
435
431
|
pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
@@ -448,10 +444,6 @@ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
448
444
|
if ( encrypted ) {
|
449
445
|
rval = rb_str_new2( encrypted );
|
450
446
|
PQfreemem( encrypted );
|
451
|
-
|
452
|
-
OBJ_INFECT( rval, password );
|
453
|
-
OBJ_INFECT( rval, username );
|
454
|
-
OBJ_INFECT( rval, algorithm );
|
455
447
|
} else {
|
456
448
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
457
449
|
}
|
@@ -484,9 +476,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
484
476
|
rval = rb_str_new2( encrypted );
|
485
477
|
PQfreemem( encrypted );
|
486
478
|
|
487
|
-
OBJ_INFECT( rval, password );
|
488
|
-
OBJ_INFECT( rval, username );
|
489
|
-
|
490
479
|
return rval;
|
491
480
|
}
|
492
481
|
|
@@ -632,7 +621,7 @@ pgconn_db(VALUE self)
|
|
632
621
|
{
|
633
622
|
char *db = PQdb(pg_get_pgconn(self));
|
634
623
|
if (!db) return Qnil;
|
635
|
-
return
|
624
|
+
return rb_str_new2(db);
|
636
625
|
}
|
637
626
|
|
638
627
|
/*
|
@@ -646,7 +635,7 @@ pgconn_user(VALUE self)
|
|
646
635
|
{
|
647
636
|
char *user = PQuser(pg_get_pgconn(self));
|
648
637
|
if (!user) return Qnil;
|
649
|
-
return
|
638
|
+
return rb_str_new2(user);
|
650
639
|
}
|
651
640
|
|
652
641
|
/*
|
@@ -660,7 +649,7 @@ pgconn_pass(VALUE self)
|
|
660
649
|
{
|
661
650
|
char *user = PQpass(pg_get_pgconn(self));
|
662
651
|
if (!user) return Qnil;
|
663
|
-
return
|
652
|
+
return rb_str_new2(user);
|
664
653
|
}
|
665
654
|
|
666
655
|
/*
|
@@ -674,7 +663,7 @@ pgconn_host(VALUE self)
|
|
674
663
|
{
|
675
664
|
char *host = PQhost(pg_get_pgconn(self));
|
676
665
|
if (!host) return Qnil;
|
677
|
-
return
|
666
|
+
return rb_str_new2(host);
|
678
667
|
}
|
679
668
|
|
680
669
|
/*
|
@@ -701,7 +690,7 @@ pgconn_tty(VALUE self)
|
|
701
690
|
{
|
702
691
|
char *tty = PQtty(pg_get_pgconn(self));
|
703
692
|
if (!tty) return Qnil;
|
704
|
-
return
|
693
|
+
return rb_str_new2(tty);
|
705
694
|
}
|
706
695
|
|
707
696
|
/*
|
@@ -715,7 +704,7 @@ pgconn_options(VALUE self)
|
|
715
704
|
{
|
716
705
|
char *options = PQoptions(pg_get_pgconn(self));
|
717
706
|
if (!options) return Qnil;
|
718
|
-
return
|
707
|
+
return rb_str_new2(options);
|
719
708
|
}
|
720
709
|
|
721
710
|
|
@@ -796,7 +785,7 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
|
|
796
785
|
if(ret == NULL)
|
797
786
|
return Qnil;
|
798
787
|
else
|
799
|
-
return
|
788
|
+
return rb_str_new2(ret);
|
800
789
|
}
|
801
790
|
|
802
791
|
/*
|
@@ -841,7 +830,7 @@ pgconn_error_message(VALUE self)
|
|
841
830
|
{
|
842
831
|
char *error = PQerrorMessage(pg_get_pgconn(self));
|
843
832
|
if (!error) return Qnil;
|
844
|
-
return
|
833
|
+
return rb_str_new2(error);
|
845
834
|
}
|
846
835
|
|
847
836
|
/*
|
@@ -865,6 +854,8 @@ static VALUE
|
|
865
854
|
pgconn_socket(VALUE self)
|
866
855
|
{
|
867
856
|
int sd;
|
857
|
+
pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
|
858
|
+
|
868
859
|
if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
|
869
860
|
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
870
861
|
return INT2NUM(sd);
|
@@ -961,32 +952,23 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
|
|
961
952
|
|
962
953
|
/*
|
963
954
|
* call-seq:
|
964
|
-
* conn.
|
965
|
-
* conn.
|
966
|
-
*
|
967
|
-
* Sends SQL query request specified by _sql_ to PostgreSQL.
|
968
|
-
* On success, it returns a PG::Result instance with all result rows and columns.
|
969
|
-
* On failure, it raises a PG::Error.
|
955
|
+
* conn.sync_exec(sql) -> PG::Result
|
956
|
+
* conn.sync_exec(sql) {|pg_result| block }
|
970
957
|
*
|
971
|
-
*
|
972
|
-
*
|
973
|
-
* 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.
|
974
960
|
*
|
975
|
-
*
|
976
|
-
*
|
977
|
-
* 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:
|
978
963
|
*
|
979
|
-
* #
|
980
|
-
*
|
981
|
-
*
|
982
|
-
* the query is finished. This is most notably visible by a delayed reaction to Control+C.
|
983
|
-
* Both methods ensure that other threads can process while waiting for the server to
|
984
|
-
* 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
|
985
967
|
*/
|
986
968
|
static VALUE
|
987
969
|
pgconn_exec(int argc, VALUE *argv, VALUE self)
|
988
970
|
{
|
989
|
-
|
971
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
990
972
|
PGresult *result = NULL;
|
991
973
|
VALUE rb_pgresult;
|
992
974
|
|
@@ -994,7 +976,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
994
976
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
995
977
|
VALUE query_str = argv[0];
|
996
978
|
|
997
|
-
result = gvl_PQexec(
|
979
|
+
result = gvl_PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx));
|
998
980
|
rb_pgresult = pg_new_result(result, self);
|
999
981
|
pg_result_check(rb_pgresult);
|
1000
982
|
if (rb_block_given_p()) {
|
@@ -1256,57 +1238,23 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1256
1238
|
|
1257
1239
|
/*
|
1258
1240
|
* call-seq:
|
1259
|
-
* conn.
|
1260
|
-
* conn.
|
1261
|
-
*
|
1262
|
-
* Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
|
1263
|
-
* for parameters.
|
1264
|
-
*
|
1265
|
-
* Returns a PG::Result instance on success. On failure, it raises a PG::Error.
|
1266
|
-
*
|
1267
|
-
* +params+ is an array of the bind parameters for the SQL query.
|
1268
|
-
* Each element of the +params+ array may be either:
|
1269
|
-
* a hash of the form:
|
1270
|
-
* {:value => String (value of bind parameter)
|
1271
|
-
* :type => Integer (oid of type of bind parameter)
|
1272
|
-
* :format => Integer (0 for text, 1 for binary)
|
1273
|
-
* }
|
1274
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1275
|
-
* { :value => <string value>, :type => 0, :format => 0 }
|
1276
|
-
*
|
1277
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1278
|
-
* inside the SQL query. The 0th element of the +params+ array is bound
|
1279
|
-
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
1280
|
-
*
|
1281
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1282
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1283
|
-
* explicit casts in the query to ensure that the right type is used.
|
1284
|
-
*
|
1285
|
-
* For example: "SELECT $1::int"
|
1286
|
-
*
|
1287
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1288
|
-
* for binary.
|
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 }
|
1289
1243
|
*
|
1290
|
-
*
|
1291
|
-
*
|
1292
|
-
*
|
1293
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1294
|
-
* instead out of the hash form described above.
|
1295
|
-
*
|
1296
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1297
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1298
|
-
* 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.
|
1299
1247
|
*/
|
1300
1248
|
static VALUE
|
1301
1249
|
pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
1302
1250
|
{
|
1303
|
-
|
1251
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1304
1252
|
PGresult *result = NULL;
|
1305
1253
|
VALUE rb_pgresult;
|
1306
1254
|
VALUE command, in_res_fmt;
|
1307
1255
|
int nParams;
|
1308
1256
|
int resultFormat;
|
1309
|
-
struct query_params_data paramsData = {
|
1257
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1310
1258
|
|
1311
1259
|
/* For compatibility we accept 1 to 4 parameters */
|
1312
1260
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
@@ -1325,7 +1273,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1325
1273
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1326
1274
|
nParams = alloc_query_params( ¶msData );
|
1327
1275
|
|
1328
|
-
result = gvl_PQexecParams(
|
1276
|
+
result = gvl_PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1329
1277
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1330
1278
|
|
1331
1279
|
free_query_params( ¶msData );
|
@@ -1342,28 +1290,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1342
1290
|
|
1343
1291
|
/*
|
1344
1292
|
* call-seq:
|
1345
|
-
* conn.
|
1346
|
-
*
|
1347
|
-
* Prepares statement _sql_ with name _name_ to be executed later.
|
1348
|
-
* Returns a PG::Result instance on success.
|
1349
|
-
* On failure, it raises a PG::Error.
|
1350
|
-
*
|
1351
|
-
* +param_types+ is an optional parameter to specify the Oids of the
|
1352
|
-
* types of the parameters.
|
1353
|
-
*
|
1354
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1355
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1356
|
-
* explicit casts in the query to ensure that the right type is used.
|
1357
|
-
*
|
1358
|
-
* For example: "SELECT $1::int"
|
1293
|
+
* conn.sync_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
1359
1294
|
*
|
1360
|
-
*
|
1361
|
-
*
|
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.
|
1362
1298
|
*/
|
1363
1299
|
static VALUE
|
1364
1300
|
pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
1365
1301
|
{
|
1366
|
-
|
1302
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1367
1303
|
PGresult *result = NULL;
|
1368
1304
|
VALUE rb_pgresult;
|
1369
1305
|
VALUE name, command, in_paramtypes;
|
@@ -1373,7 +1309,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1373
1309
|
Oid *paramTypes = NULL;
|
1374
1310
|
const char *name_cstr;
|
1375
1311
|
const char *command_cstr;
|
1376
|
-
int enc_idx =
|
1312
|
+
int enc_idx = this->enc_idx;
|
1377
1313
|
|
1378
1314
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1379
1315
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1391,7 +1327,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1391
1327
|
paramTypes[i] = NUM2UINT(param);
|
1392
1328
|
}
|
1393
1329
|
}
|
1394
|
-
result = gvl_PQprepare(
|
1330
|
+
result = gvl_PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1395
1331
|
|
1396
1332
|
xfree(paramTypes);
|
1397
1333
|
|
@@ -1402,49 +1338,23 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1402
1338
|
|
1403
1339
|
/*
|
1404
1340
|
* call-seq:
|
1405
|
-
* conn.
|
1406
|
-
* conn.
|
1407
|
-
*
|
1408
|
-
* Execute prepared named statement specified by _statement_name_.
|
1409
|
-
* Returns a PG::Result instance on success.
|
1410
|
-
* On failure, it raises a PG::Error.
|
1411
|
-
*
|
1412
|
-
* +params+ is an array of the optional bind parameters for the
|
1413
|
-
* SQL query. Each element of the +params+ array may be either:
|
1414
|
-
* a hash of the form:
|
1415
|
-
* {:value => String (value of bind parameter)
|
1416
|
-
* :format => Integer (0 for text, 1 for binary)
|
1417
|
-
* }
|
1418
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1419
|
-
* { :value => <string value>, :format => 0 }
|
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 }
|
1420
1343
|
*
|
1421
|
-
*
|
1422
|
-
*
|
1423
|
-
* to
|
1424
|
-
*
|
1425
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1426
|
-
* for binary.
|
1427
|
-
*
|
1428
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1429
|
-
* This will type cast the params from various Ruby types before transmission
|
1430
|
-
* based on the encoders defined by the type map. When a type encoder is used
|
1431
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1432
|
-
* instead out of the hash form described above.
|
1433
|
-
*
|
1434
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1435
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1436
|
-
* 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.
|
1437
1347
|
*/
|
1438
1348
|
static VALUE
|
1439
1349
|
pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
1440
1350
|
{
|
1441
|
-
|
1351
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1442
1352
|
PGresult *result = NULL;
|
1443
1353
|
VALUE rb_pgresult;
|
1444
1354
|
VALUE name, in_res_fmt;
|
1445
1355
|
int nParams;
|
1446
1356
|
int resultFormat;
|
1447
|
-
struct query_params_data paramsData = {
|
1357
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1448
1358
|
|
1449
1359
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1450
1360
|
paramsData.with_types = 0;
|
@@ -1457,7 +1367,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1457
1367
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1458
1368
|
nParams = alloc_query_params( ¶msData );
|
1459
1369
|
|
1460
|
-
result = gvl_PQexecPrepared(
|
1370
|
+
result = gvl_PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1461
1371
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1462
1372
|
resultFormat);
|
1463
1373
|
|
@@ -1474,25 +1384,26 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1474
1384
|
|
1475
1385
|
/*
|
1476
1386
|
* call-seq:
|
1477
|
-
* conn.
|
1387
|
+
* conn.sync_describe_prepared( statement_name ) -> PG::Result
|
1478
1388
|
*
|
1479
|
-
*
|
1480
|
-
*
|
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.
|
1481
1392
|
*/
|
1482
1393
|
static VALUE
|
1483
1394
|
pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
1484
1395
|
{
|
1485
1396
|
PGresult *result;
|
1486
1397
|
VALUE rb_pgresult;
|
1487
|
-
|
1398
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1488
1399
|
const char *stmt;
|
1489
1400
|
if(NIL_P(stmt_name)) {
|
1490
1401
|
stmt = NULL;
|
1491
1402
|
}
|
1492
1403
|
else {
|
1493
|
-
stmt = pg_cstr_enc(stmt_name,
|
1404
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1494
1405
|
}
|
1495
|
-
result = gvl_PQdescribePrepared(
|
1406
|
+
result = gvl_PQdescribePrepared(this->pgconn, stmt);
|
1496
1407
|
rb_pgresult = pg_new_result(result, self);
|
1497
1408
|
pg_result_check(rb_pgresult);
|
1498
1409
|
return rb_pgresult;
|
@@ -1501,9 +1412,11 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1501
1412
|
|
1502
1413
|
/*
|
1503
1414
|
* call-seq:
|
1504
|
-
* conn.
|
1415
|
+
* conn.sync_describe_portal( portal_name ) -> PG::Result
|
1505
1416
|
*
|
1506
|
-
*
|
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.
|
1507
1420
|
*/
|
1508
1421
|
static VALUE
|
1509
1422
|
pgconn_describe_portal(self, stmt_name)
|
@@ -1511,15 +1424,15 @@ pgconn_describe_portal(self, stmt_name)
|
|
1511
1424
|
{
|
1512
1425
|
PGresult *result;
|
1513
1426
|
VALUE rb_pgresult;
|
1514
|
-
|
1427
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1515
1428
|
const char *stmt;
|
1516
1429
|
if(NIL_P(stmt_name)) {
|
1517
1430
|
stmt = NULL;
|
1518
1431
|
}
|
1519
1432
|
else {
|
1520
|
-
stmt = pg_cstr_enc(stmt_name,
|
1433
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1521
1434
|
}
|
1522
|
-
result = gvl_PQdescribePortal(
|
1435
|
+
result = gvl_PQdescribePortal(this->pgconn, stmt);
|
1523
1436
|
rb_pgresult = pg_new_result(result, self);
|
1524
1437
|
pg_result_check(rb_pgresult);
|
1525
1438
|
return rb_pgresult;
|
@@ -1566,13 +1479,15 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1566
1479
|
* Consider using exec_params, which avoids the need for passing values
|
1567
1480
|
* inside of SQL commands.
|
1568
1481
|
*
|
1569
|
-
*
|
1482
|
+
* Character encoding of escaped string will be equal to client encoding of connection.
|
1570
1483
|
*
|
1571
1484
|
* NOTE: This class version of this method can only be used safely in client
|
1572
1485
|
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1573
1486
|
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1574
1487
|
* results if used in programs that use multiple database connections; use the
|
1575
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.
|
1576
1491
|
*/
|
1577
1492
|
static VALUE
|
1578
1493
|
pgconn_s_escape(VALUE self, VALUE string)
|
@@ -1584,7 +1499,7 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1584
1499
|
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1585
1500
|
|
1586
1501
|
StringValueCStr(string);
|
1587
|
-
enc_idx =
|
1502
|
+
enc_idx = singleton ? ENCODING_GET(string) : pg_get_connection(self)->enc_idx;
|
1588
1503
|
if( ENCODING_GET(string) != enc_idx ){
|
1589
1504
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1590
1505
|
}
|
@@ -1601,7 +1516,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1601
1516
|
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1602
1517
|
}
|
1603
1518
|
rb_str_set_len(result, size);
|
1604
|
-
OBJ_INFECT(result, string);
|
1605
1519
|
|
1606
1520
|
return result;
|
1607
1521
|
}
|
@@ -1647,7 +1561,6 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
|
|
1647
1561
|
}
|
1648
1562
|
|
1649
1563
|
ret = rb_str_new((char*)to, to_len - 1);
|
1650
|
-
OBJ_INFECT(ret, str);
|
1651
1564
|
PQfreemem(to);
|
1652
1565
|
return ret;
|
1653
1566
|
}
|
@@ -1677,7 +1590,6 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1677
1590
|
to = PQunescapeBytea(from, &to_len);
|
1678
1591
|
|
1679
1592
|
ret = rb_str_new((char*)to, to_len);
|
1680
|
-
OBJ_INFECT(ret, str);
|
1681
1593
|
PQfreemem(to);
|
1682
1594
|
return ret;
|
1683
1595
|
}
|
@@ -1688,33 +1600,32 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1688
1600
|
*
|
1689
1601
|
* Escape an arbitrary String +str+ as a literal.
|
1690
1602
|
*
|
1691
|
-
*
|
1603
|
+
* See also PG::TextEncoder::QuotedLiteral for a type cast integrated version of this function.
|
1692
1604
|
*/
|
1693
1605
|
static VALUE
|
1694
1606
|
pgconn_escape_literal(VALUE self, VALUE string)
|
1695
1607
|
{
|
1696
|
-
|
1608
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1697
1609
|
char *escaped = NULL;
|
1698
1610
|
VALUE error;
|
1699
1611
|
VALUE result = Qnil;
|
1700
|
-
int enc_idx =
|
1612
|
+
int enc_idx = this->enc_idx;
|
1701
1613
|
|
1702
1614
|
StringValueCStr(string);
|
1703
1615
|
if( ENCODING_GET(string) != enc_idx ){
|
1704
1616
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1705
1617
|
}
|
1706
1618
|
|
1707
|
-
escaped = PQescapeLiteral(
|
1619
|
+
escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1708
1620
|
if (escaped == NULL)
|
1709
1621
|
{
|
1710
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1622
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1711
1623
|
rb_iv_set(error, "@connection", self);
|
1712
1624
|
rb_exc_raise(error);
|
1713
1625
|
return Qnil;
|
1714
1626
|
}
|
1715
1627
|
result = rb_str_new2(escaped);
|
1716
1628
|
PQfreemem(escaped);
|
1717
|
-
OBJ_INFECT(result, string);
|
1718
1629
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1719
1630
|
|
1720
1631
|
return result;
|
@@ -1729,34 +1640,31 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1729
1640
|
* This method does the same as #quote_ident with a String argument,
|
1730
1641
|
* but it doesn't support an Array argument and it makes use of libpq
|
1731
1642
|
* to process the string.
|
1732
|
-
*
|
1733
|
-
* Available since PostgreSQL-9.0
|
1734
1643
|
*/
|
1735
1644
|
static VALUE
|
1736
1645
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
1737
1646
|
{
|
1738
|
-
|
1647
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1739
1648
|
char *escaped = NULL;
|
1740
1649
|
VALUE error;
|
1741
1650
|
VALUE result = Qnil;
|
1742
|
-
int enc_idx =
|
1651
|
+
int enc_idx = this->enc_idx;
|
1743
1652
|
|
1744
1653
|
StringValueCStr(string);
|
1745
1654
|
if( ENCODING_GET(string) != enc_idx ){
|
1746
1655
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1747
1656
|
}
|
1748
1657
|
|
1749
|
-
escaped = PQescapeIdentifier(
|
1658
|
+
escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1750
1659
|
if (escaped == NULL)
|
1751
1660
|
{
|
1752
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1661
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1753
1662
|
rb_iv_set(error, "@connection", self);
|
1754
1663
|
rb_exc_raise(error);
|
1755
1664
|
return Qnil;
|
1756
1665
|
}
|
1757
1666
|
result = rb_str_new2(escaped);
|
1758
1667
|
PQfreemem(escaped);
|
1759
|
-
OBJ_INFECT(result, string);
|
1760
1668
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1761
1669
|
|
1762
1670
|
return result;
|
@@ -1797,8 +1705,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1797
1705
|
* # do something with the received row
|
1798
1706
|
* end
|
1799
1707
|
* end
|
1800
|
-
*
|
1801
|
-
* Available since PostgreSQL-9.2
|
1802
1708
|
*/
|
1803
1709
|
static VALUE
|
1804
1710
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1834,13 +1740,13 @@ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
|
1834
1740
|
static VALUE
|
1835
1741
|
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
1836
1742
|
{
|
1837
|
-
|
1743
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1838
1744
|
VALUE error;
|
1839
1745
|
|
1840
1746
|
/* If called with no or nil parameters, use PQexec for compatibility */
|
1841
1747
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
1842
|
-
if(gvl_PQsendQuery(
|
1843
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
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));
|
1844
1750
|
rb_iv_set(error, "@connection", self);
|
1845
1751
|
rb_exc_raise(error);
|
1846
1752
|
}
|
@@ -1886,7 +1792,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1886
1792
|
* The optional +result_format+ should be 0 for text results, 1
|
1887
1793
|
* for binary.
|
1888
1794
|
*
|
1889
|
-
* 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).
|
1890
1796
|
* This will type cast the params from various Ruby types before transmission
|
1891
1797
|
* based on the encoders defined by the type map. When a type encoder is used
|
1892
1798
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -1896,13 +1802,13 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1896
1802
|
static VALUE
|
1897
1803
|
pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
1898
1804
|
{
|
1899
|
-
|
1805
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1900
1806
|
int result;
|
1901
1807
|
VALUE command, in_res_fmt;
|
1902
1808
|
VALUE error;
|
1903
1809
|
int nParams;
|
1904
1810
|
int resultFormat;
|
1905
|
-
struct query_params_data paramsData = {
|
1811
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1906
1812
|
|
1907
1813
|
rb_scan_args(argc, argv, "22", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1908
1814
|
paramsData.with_types = 1;
|
@@ -1911,13 +1817,13 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
1911
1817
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1912
1818
|
nParams = alloc_query_params( ¶msData );
|
1913
1819
|
|
1914
|
-
result = gvl_PQsendQueryParams(
|
1820
|
+
result = gvl_PQsendQueryParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1915
1821
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1916
1822
|
|
1917
1823
|
free_query_params( ¶msData );
|
1918
1824
|
|
1919
1825
|
if(result == 0) {
|
1920
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1826
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1921
1827
|
rb_iv_set(error, "@connection", self);
|
1922
1828
|
rb_exc_raise(error);
|
1923
1829
|
}
|
@@ -1947,7 +1853,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
1947
1853
|
static VALUE
|
1948
1854
|
pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
1949
1855
|
{
|
1950
|
-
|
1856
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1951
1857
|
int result;
|
1952
1858
|
VALUE name, command, in_paramtypes;
|
1953
1859
|
VALUE param;
|
@@ -1957,7 +1863,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1957
1863
|
Oid *paramTypes = NULL;
|
1958
1864
|
const char *name_cstr;
|
1959
1865
|
const char *command_cstr;
|
1960
|
-
int enc_idx =
|
1866
|
+
int enc_idx = this->enc_idx;
|
1961
1867
|
|
1962
1868
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1963
1869
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1975,12 +1881,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1975
1881
|
paramTypes[i] = NUM2UINT(param);
|
1976
1882
|
}
|
1977
1883
|
}
|
1978
|
-
result = gvl_PQsendPrepare(
|
1884
|
+
result = gvl_PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1979
1885
|
|
1980
1886
|
xfree(paramTypes);
|
1981
1887
|
|
1982
1888
|
if(result == 0) {
|
1983
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1889
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1984
1890
|
rb_iv_set(error, "@connection", self);
|
1985
1891
|
rb_exc_raise(error);
|
1986
1892
|
}
|
@@ -2012,7 +1918,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
2012
1918
|
* The optional +result_format+ should be 0 for text results, 1
|
2013
1919
|
* for binary.
|
2014
1920
|
*
|
2015
|
-
* 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).
|
2016
1922
|
* This will type cast the params from various Ruby types before transmission
|
2017
1923
|
* based on the encoders defined by the type map. When a type encoder is used
|
2018
1924
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -2022,13 +1928,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
2022
1928
|
static VALUE
|
2023
1929
|
pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
2024
1930
|
{
|
2025
|
-
|
1931
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2026
1932
|
int result;
|
2027
1933
|
VALUE name, in_res_fmt;
|
2028
1934
|
VALUE error;
|
2029
1935
|
int nParams;
|
2030
1936
|
int resultFormat;
|
2031
|
-
struct query_params_data paramsData = {
|
1937
|
+
struct query_params_data paramsData = { this->enc_idx };
|
2032
1938
|
|
2033
1939
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
2034
1940
|
paramsData.with_types = 0;
|
@@ -2042,14 +1948,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
2042
1948
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
2043
1949
|
nParams = alloc_query_params( ¶msData );
|
2044
1950
|
|
2045
|
-
result = gvl_PQsendQueryPrepared(
|
1951
|
+
result = gvl_PQsendQueryPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
2046
1952
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
2047
1953
|
resultFormat);
|
2048
1954
|
|
2049
1955
|
free_query_params( ¶msData );
|
2050
1956
|
|
2051
1957
|
if(result == 0) {
|
2052
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1958
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2053
1959
|
rb_iv_set(error, "@connection", self);
|
2054
1960
|
rb_exc_raise(error);
|
2055
1961
|
}
|
@@ -2067,10 +1973,10 @@ static VALUE
|
|
2067
1973
|
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
2068
1974
|
{
|
2069
1975
|
VALUE error;
|
2070
|
-
|
1976
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2071
1977
|
/* returns 0 on failure */
|
2072
|
-
if(gvl_PQsendDescribePrepared(
|
2073
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
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));
|
2074
1980
|
rb_iv_set(error, "@connection", self);
|
2075
1981
|
rb_exc_raise(error);
|
2076
1982
|
}
|
@@ -2089,10 +1995,10 @@ static VALUE
|
|
2089
1995
|
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
2090
1996
|
{
|
2091
1997
|
VALUE error;
|
2092
|
-
|
1998
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2093
1999
|
/* returns 0 on failure */
|
2094
|
-
if(gvl_PQsendDescribePortal(
|
2095
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
2000
|
+
if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
|
2001
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2096
2002
|
rb_iv_set(error, "@connection", self);
|
2097
2003
|
rb_exc_raise(error);
|
2098
2004
|
}
|
@@ -2293,7 +2199,7 @@ pgconn_cancel(VALUE self)
|
|
2293
2199
|
static VALUE
|
2294
2200
|
pgconn_notifies(VALUE self)
|
2295
2201
|
{
|
2296
|
-
|
2202
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2297
2203
|
PGnotify *notification;
|
2298
2204
|
VALUE hash;
|
2299
2205
|
VALUE sym_relname, sym_be_pid, sym_extra;
|
@@ -2303,17 +2209,17 @@ pgconn_notifies(VALUE self)
|
|
2303
2209
|
sym_be_pid = ID2SYM(rb_intern("be_pid"));
|
2304
2210
|
sym_extra = ID2SYM(rb_intern("extra"));
|
2305
2211
|
|
2306
|
-
notification = gvl_PQnotifies(
|
2212
|
+
notification = gvl_PQnotifies(this->pgconn);
|
2307
2213
|
if (notification == NULL) {
|
2308
2214
|
return Qnil;
|
2309
2215
|
}
|
2310
2216
|
|
2311
2217
|
hash = rb_hash_new();
|
2312
|
-
relname =
|
2218
|
+
relname = rb_str_new2(notification->relname);
|
2313
2219
|
be_pid = INT2NUM(notification->be_pid);
|
2314
|
-
extra =
|
2315
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2316
|
-
PG_ENCODING_SET_NOCHECK( extra,
|
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 );
|
2317
2223
|
|
2318
2224
|
rb_hash_aset(hash, sym_relname, relname);
|
2319
2225
|
rb_hash_aset(hash, sym_be_pid, be_pid);
|
@@ -2486,7 +2392,7 @@ notify_readable(PGconn *conn)
|
|
2486
2392
|
static VALUE
|
2487
2393
|
pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
2488
2394
|
{
|
2489
|
-
|
2395
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2490
2396
|
PGnotify *pnotification;
|
2491
2397
|
struct timeval timeout;
|
2492
2398
|
struct timeval *ptimeout = NULL;
|
@@ -2502,17 +2408,17 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2502
2408
|
ptimeout = &timeout;
|
2503
2409
|
}
|
2504
2410
|
|
2505
|
-
pnotification = (PGnotify*) wait_socket_readable(
|
2411
|
+
pnotification = (PGnotify*) wait_socket_readable( this->pgconn, ptimeout, notify_readable);
|
2506
2412
|
|
2507
2413
|
/* Return nil if the select timed out */
|
2508
2414
|
if ( !pnotification ) return Qnil;
|
2509
2415
|
|
2510
|
-
relname =
|
2511
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2416
|
+
relname = rb_str_new2( pnotification->relname );
|
2417
|
+
PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
|
2512
2418
|
be_pid = INT2NUM( pnotification->be_pid );
|
2513
2419
|
if ( *pnotification->extra ) {
|
2514
|
-
extra =
|
2515
|
-
PG_ENCODING_SET_NOCHECK( extra,
|
2420
|
+
extra = rb_str_new2( pnotification->extra );
|
2421
|
+
PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
|
2516
2422
|
}
|
2517
2423
|
PQfreemem( pnotification );
|
2518
2424
|
|
@@ -2572,7 +2478,7 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2572
2478
|
|
2573
2479
|
if( p_coder ){
|
2574
2480
|
t_pg_coder_enc_func enc_func;
|
2575
|
-
int enc_idx =
|
2481
|
+
int enc_idx = this->enc_idx;
|
2576
2482
|
|
2577
2483
|
enc_func = pg_coder_enc_func( p_coder );
|
2578
2484
|
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
@@ -2622,16 +2528,16 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2622
2528
|
VALUE error;
|
2623
2529
|
int ret;
|
2624
2530
|
const char *error_message = NULL;
|
2625
|
-
|
2531
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2626
2532
|
|
2627
2533
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2628
2534
|
error_message = NULL;
|
2629
2535
|
else
|
2630
|
-
error_message = pg_cstr_enc(str,
|
2536
|
+
error_message = pg_cstr_enc(str, this->enc_idx);
|
2631
2537
|
|
2632
|
-
ret = gvl_PQputCopyEnd(
|
2538
|
+
ret = gvl_PQputCopyEnd(this->pgconn, error_message);
|
2633
2539
|
if(ret == -1) {
|
2634
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
2540
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
2635
2541
|
rb_iv_set(error, "@connection", self);
|
2636
2542
|
rb_exc_raise(error);
|
2637
2543
|
}
|
@@ -2697,9 +2603,9 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2697
2603
|
|
2698
2604
|
if( p_coder ){
|
2699
2605
|
t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, p_coder->format );
|
2700
|
-
result = dec_func( p_coder, buffer, ret, 0, 0,
|
2606
|
+
result = dec_func( p_coder, buffer, ret, 0, 0, this->enc_idx );
|
2701
2607
|
} else {
|
2702
|
-
result =
|
2608
|
+
result = rb_str_new(buffer, ret);
|
2703
2609
|
}
|
2704
2610
|
|
2705
2611
|
PQfreemem(buffer);
|
@@ -2712,9 +2618,16 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2712
2618
|
*
|
2713
2619
|
* Sets connection's verbosity to _verbosity_ and returns
|
2714
2620
|
* the previous setting. Available settings are:
|
2621
|
+
*
|
2715
2622
|
* * PQERRORS_TERSE
|
2716
2623
|
* * PQERRORS_DEFAULT
|
2717
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].
|
2718
2631
|
*/
|
2719
2632
|
static VALUE
|
2720
2633
|
pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
@@ -2724,6 +2637,37 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
|
2724
2637
|
return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
|
2725
2638
|
}
|
2726
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
|
+
|
2727
2671
|
/*
|
2728
2672
|
* call-seq:
|
2729
2673
|
* conn.trace( stream ) -> nil
|
@@ -2742,7 +2686,7 @@ pgconn_trace(VALUE self, VALUE stream)
|
|
2742
2686
|
VALUE new_file;
|
2743
2687
|
t_pg_connection *this = pg_get_connection_safe( self );
|
2744
2688
|
|
2745
|
-
if(rb_respond_to(stream,rb_intern("fileno"))
|
2689
|
+
if(!rb_respond_to(stream,rb_intern("fileno")))
|
2746
2690
|
rb_raise(rb_eArgError, "stream does not respond to method: fileno");
|
2747
2691
|
|
2748
2692
|
fileno = rb_funcall(stream, rb_intern("fileno"), 0);
|
@@ -2875,8 +2819,8 @@ notice_processor_proxy(void *arg, const char *message)
|
|
2875
2819
|
t_pg_connection *this = pg_get_connection( self );
|
2876
2820
|
|
2877
2821
|
if (this->notice_receiver != Qnil) {
|
2878
|
-
VALUE message_str =
|
2879
|
-
PG_ENCODING_SET_NOCHECK( message_str,
|
2822
|
+
VALUE message_str = rb_str_new2(message);
|
2823
|
+
PG_ENCODING_SET_NOCHECK( message_str, this->enc_idx );
|
2880
2824
|
rb_funcall(this->notice_receiver, rb_intern("call"), 1, message_str);
|
2881
2825
|
}
|
2882
2826
|
return;
|
@@ -2934,7 +2878,7 @@ static VALUE
|
|
2934
2878
|
pgconn_get_client_encoding(VALUE self)
|
2935
2879
|
{
|
2936
2880
|
char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self)));
|
2937
|
-
return
|
2881
|
+
return rb_str_new2(encoding);
|
2938
2882
|
}
|
2939
2883
|
|
2940
2884
|
|
@@ -3046,14 +2990,12 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
|
3046
2990
|
int enc_idx;
|
3047
2991
|
|
3048
2992
|
if( rb_obj_is_kind_of(self, rb_cPGconn) ){
|
3049
|
-
enc_idx =
|
2993
|
+
enc_idx = pg_get_connection(self)->enc_idx;
|
3050
2994
|
}else{
|
3051
2995
|
enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
|
3052
2996
|
}
|
3053
2997
|
pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
|
3054
2998
|
|
3055
|
-
OBJ_INFECT(ret, str_or_array);
|
3056
|
-
|
3057
2999
|
return ret;
|
3058
3000
|
}
|
3059
3001
|
|
@@ -3178,19 +3120,30 @@ pgconn_discard_results(VALUE self)
|
|
3178
3120
|
|
3179
3121
|
/*
|
3180
3122
|
* call-seq:
|
3181
|
-
* conn.
|
3182
|
-
* conn.
|
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.
|
3183
3129
|
*
|
3184
|
-
*
|
3185
|
-
*
|
3186
|
-
*
|
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.
|
3187
3133
|
*
|
3188
|
-
*
|
3189
|
-
*
|
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.
|
3190
3137
|
*
|
3191
|
-
*
|
3192
|
-
*
|
3193
|
-
*
|
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].
|
3194
3147
|
*/
|
3195
3148
|
static VALUE
|
3196
3149
|
pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
@@ -3211,11 +3164,53 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3211
3164
|
|
3212
3165
|
/*
|
3213
3166
|
* call-seq:
|
3214
|
-
* conn.
|
3215
|
-
* conn.
|
3167
|
+
* conn.exec_params(sql, params [, result_format [, type_map ]] ) -> nil
|
3168
|
+
* conn.exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
|
3216
3169
|
*
|
3217
|
-
*
|
3218
|
-
*
|
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].
|
3219
3214
|
*/
|
3220
3215
|
static VALUE
|
3221
3216
|
pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
@@ -3242,10 +3237,25 @@ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
|
3242
3237
|
|
3243
3238
|
/*
|
3244
3239
|
* call-seq:
|
3245
|
-
* conn.
|
3240
|
+
* conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
3246
3241
|
*
|
3247
|
-
*
|
3248
|
-
*
|
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].
|
3249
3259
|
*/
|
3250
3260
|
static VALUE
|
3251
3261
|
pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
@@ -3266,11 +3276,40 @@ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
|
3266
3276
|
|
3267
3277
|
/*
|
3268
3278
|
* call-seq:
|
3269
|
-
* conn.
|
3270
|
-
* conn.
|
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 }
|
3271
3281
|
*
|
3272
|
-
*
|
3273
|
-
*
|
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].
|
3274
3313
|
*/
|
3275
3314
|
static VALUE
|
3276
3315
|
pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
@@ -3291,10 +3330,11 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
3291
3330
|
|
3292
3331
|
/*
|
3293
3332
|
* call-seq:
|
3294
|
-
* conn.
|
3333
|
+
* conn.describe_portal( portal_name ) -> PG::Result
|
3295
3334
|
*
|
3296
|
-
*
|
3297
|
-
*
|
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].
|
3298
3338
|
*/
|
3299
3339
|
static VALUE
|
3300
3340
|
pgconn_async_describe_portal(VALUE self, VALUE portal)
|
@@ -3315,10 +3355,11 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
|
|
3315
3355
|
|
3316
3356
|
/*
|
3317
3357
|
* call-seq:
|
3318
|
-
* conn.
|
3358
|
+
* conn.describe_prepared( statement_name ) -> PG::Result
|
3319
3359
|
*
|
3320
|
-
*
|
3321
|
-
*
|
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].
|
3322
3363
|
*/
|
3323
3364
|
static VALUE
|
3324
3365
|
pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
@@ -3342,7 +3383,7 @@ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
|
3342
3383
|
* call-seq:
|
3343
3384
|
* conn.ssl_in_use? -> Boolean
|
3344
3385
|
*
|
3345
|
-
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3386
|
+
* Returns +true+ if the connection uses SSL/TLS, +false+ if not.
|
3346
3387
|
*
|
3347
3388
|
* Available since PostgreSQL-9.5
|
3348
3389
|
*/
|
@@ -3376,7 +3417,7 @@ pgconn_ssl_in_use(VALUE self)
|
|
3376
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".
|
3377
3418
|
*
|
3378
3419
|
*
|
3379
|
-
* See also #ssl_attribute_names and
|
3420
|
+
* See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
|
3380
3421
|
*
|
3381
3422
|
* Available since PostgreSQL-9.5
|
3382
3423
|
*/
|
@@ -3604,7 +3645,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3604
3645
|
return Qnil;
|
3605
3646
|
}
|
3606
3647
|
|
3607
|
-
str =
|
3648
|
+
str = rb_str_new(buffer, ret);
|
3608
3649
|
xfree(buffer);
|
3609
3650
|
|
3610
3651
|
return str;
|
@@ -3708,12 +3749,15 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3708
3749
|
}
|
3709
3750
|
|
3710
3751
|
|
3711
|
-
void
|
3752
|
+
static void
|
3712
3753
|
pgconn_set_internal_encoding_index( VALUE self )
|
3713
3754
|
{
|
3714
|
-
|
3715
|
-
|
3716
|
-
|
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;
|
3717
3761
|
}
|
3718
3762
|
|
3719
3763
|
/*
|
@@ -3756,7 +3800,6 @@ static VALUE pgconn_external_encoding(VALUE self);
|
|
3756
3800
|
static VALUE
|
3757
3801
|
pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
3758
3802
|
{
|
3759
|
-
VALUE enc_inspect;
|
3760
3803
|
if (NIL_P(enc)) {
|
3761
3804
|
pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
|
3762
3805
|
return enc;
|
@@ -3777,11 +3820,6 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3777
3820
|
pgconn_set_internal_encoding_index( self );
|
3778
3821
|
return enc;
|
3779
3822
|
}
|
3780
|
-
|
3781
|
-
enc_inspect = rb_inspect(enc);
|
3782
|
-
rb_raise( rb_ePGerror, "unknown encoding: %s", StringValueCStr(enc_inspect) );
|
3783
|
-
|
3784
|
-
return Qnil;
|
3785
3823
|
}
|
3786
3824
|
|
3787
3825
|
|
@@ -3800,14 +3838,9 @@ pgconn_external_encoding(VALUE self)
|
|
3800
3838
|
rb_encoding *enc = NULL;
|
3801
3839
|
const char *pg_encname = NULL;
|
3802
3840
|
|
3803
|
-
/* Use cached value if found */
|
3804
|
-
if ( RTEST(this->external_encoding) ) return this->external_encoding;
|
3805
|
-
|
3806
3841
|
pg_encname = PQparameterStatus( this->pgconn, "server_encoding" );
|
3807
3842
|
enc = pg_get_pg_encname_as_rb_encoding( pg_encname );
|
3808
|
-
|
3809
|
-
|
3810
|
-
return this->external_encoding;
|
3843
|
+
return rb_enc_from_encoding( enc );
|
3811
3844
|
}
|
3812
3845
|
|
3813
3846
|
|
@@ -3825,9 +3858,10 @@ pgconn_set_client_encoding_async1( VALUE args )
|
|
3825
3858
|
|
3826
3859
|
|
3827
3860
|
static VALUE
|
3828
|
-
pgconn_set_client_encoding_async2( VALUE arg )
|
3861
|
+
pgconn_set_client_encoding_async2( VALUE arg, VALUE ex )
|
3829
3862
|
{
|
3830
3863
|
UNUSED(arg);
|
3864
|
+
UNUSED(ex);
|
3831
3865
|
return 1;
|
3832
3866
|
}
|
3833
3867
|
|
@@ -4049,16 +4083,54 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
4049
4083
|
|
4050
4084
|
/*
|
4051
4085
|
* call-seq:
|
4052
|
-
*
|
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
|
4053
4117
|
*
|
4054
|
-
*
|
4118
|
+
* Get type of field names.
|
4119
|
+
*
|
4120
|
+
* See description at #field_name_type=
|
4055
4121
|
*/
|
4056
4122
|
static VALUE
|
4057
|
-
|
4123
|
+
pgconn_field_name_type_get(VALUE self)
|
4058
4124
|
{
|
4059
4125
|
t_pg_connection *this = pg_get_connection( self );
|
4060
|
-
|
4061
|
-
|
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
|
+
}
|
4062
4134
|
}
|
4063
4135
|
|
4064
4136
|
|
@@ -4072,8 +4144,13 @@ init_pg_connection()
|
|
4072
4144
|
sym_type = ID2SYM(rb_intern("type"));
|
4073
4145
|
sym_format = ID2SYM(rb_intern("format"));
|
4074
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"));
|
4075
4150
|
|
4076
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" ); */
|
4077
4154
|
rb_include_module(rb_cPGconn, rb_mPGconstants);
|
4078
4155
|
|
4079
4156
|
/****** PG::Connection CLASS METHODS ******/
|
@@ -4134,6 +4211,22 @@ init_pg_connection()
|
|
4134
4211
|
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
|
4135
4212
|
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
|
4136
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
|
+
|
4137
4230
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
4138
4231
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
4139
4232
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
@@ -4146,17 +4239,10 @@ init_pg_connection()
|
|
4146
4239
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
4147
4240
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
4148
4241
|
rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
|
4149
|
-
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
4150
|
-
rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
|
4151
|
-
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4152
4242
|
rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
|
4153
|
-
rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
|
4154
4243
|
rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
|
4155
|
-
rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
|
4156
4244
|
rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
|
4157
|
-
rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
|
4158
4245
|
rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
|
4159
|
-
rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
|
4160
4246
|
rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
|
4161
4247
|
rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
|
4162
4248
|
rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
|
@@ -4179,9 +4265,11 @@ init_pg_connection()
|
|
4179
4265
|
|
4180
4266
|
/****** PG::Connection INSTANCE METHODS: Control Functions ******/
|
4181
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
|
4182
4271
|
rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
|
4183
4272
|
rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
|
4184
|
-
rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
|
4185
4273
|
|
4186
4274
|
/****** PG::Connection INSTANCE METHODS: Notice Processing ******/
|
4187
4275
|
rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
|
@@ -4248,5 +4336,7 @@ init_pg_connection()
|
|
4248
4336
|
rb_define_method(rb_cPGconn, "encoder_for_put_copy_data", pgconn_encoder_for_put_copy_data_get, 0);
|
4249
4337
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data=", pgconn_decoder_for_get_copy_data_set, 1);
|
4250
4338
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data", pgconn_decoder_for_get_copy_data_get, 0);
|
4251
|
-
}
|
4252
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
|
+
}
|