pg 1.1.0 → 1.2.3
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 +110 -1
- data/Manifest.txt +3 -2
- data/README-Windows.rdoc +4 -4
- data/README.ja.rdoc +1 -2
- data/README.rdoc +44 -9
- data/Rakefile +8 -6
- data/Rakefile.cross +57 -56
- data/ext/errorcodes.def +68 -0
- data/ext/errorcodes.txt +19 -2
- data/ext/extconf.rb +6 -6
- data/ext/pg.c +138 -99
- data/ext/pg.h +34 -26
- data/ext/pg_binary_decoder.c +20 -16
- data/ext/pg_binary_encoder.c +13 -12
- data/ext/pg_coder.c +21 -9
- data/ext/pg_connection.c +413 -321
- data/ext/pg_copy_coder.c +6 -3
- data/ext/pg_record_coder.c +491 -0
- data/ext/pg_result.c +282 -128
- 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 +9 -4
- 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 +5 -5
- data/lib/pg/basic_type_mapping.rb +81 -18
- 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 +19 -19
- data/spec/pg/basic_type_mapping_spec.rb +141 -19
- data/spec/pg/connection_spec.rb +239 -93
- data/spec/pg/result_spec.rb +194 -4
- data/spec/pg/tuple_spec.rb +55 -2
- data/spec/pg/type_map_by_class_spec.rb +1 -1
- data/spec/pg/type_map_by_column_spec.rb +5 -1
- data/spec/pg/type_map_by_oid_spec.rb +2 -2
- data/spec/pg/type_spec.rb +180 -6
- metadata +41 -47
- metadata.gz.sig +0 -0
data/ext/pg.h
CHANGED
@@ -21,9 +21,6 @@
|
|
21
21
|
#include "ruby/st.h"
|
22
22
|
#include "ruby/encoding.h"
|
23
23
|
|
24
|
-
/* exported by ruby-1.9.3+ but not declared */
|
25
|
-
extern int rb_enc_alias(const char *, const char *);
|
26
|
-
|
27
24
|
#define PG_ENCODING_SET_NOCHECK(obj,i) \
|
28
25
|
do { \
|
29
26
|
if ((i) < ENCODING_INLINE_MAX) \
|
@@ -81,6 +78,8 @@ typedef long suseconds_t;
|
|
81
78
|
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
|
82
79
|
#endif
|
83
80
|
|
81
|
+
#define PG_ENC_IDX_BITS 28
|
82
|
+
|
84
83
|
/* The data behind each PG::Connection object */
|
85
84
|
typedef struct {
|
86
85
|
PGconn *pgconn;
|
@@ -97,18 +96,19 @@ typedef struct {
|
|
97
96
|
VALUE type_map_for_results;
|
98
97
|
/* IO object internally used for the trace stream */
|
99
98
|
VALUE trace_stream;
|
100
|
-
/* Cached Encoding object */
|
101
|
-
VALUE external_encoding;
|
102
99
|
/* Kind of PG::Coder object for casting ruby values to COPY rows */
|
103
100
|
VALUE encoder_for_put_copy_data;
|
104
101
|
/* Kind of PG::Coder object for casting COPY rows to ruby values */
|
105
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;
|
106
107
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
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
|
112
112
|
} t_pg_connection;
|
113
113
|
|
114
114
|
typedef struct pg_coder t_pg_coder;
|
@@ -129,10 +129,16 @@ typedef struct {
|
|
129
129
|
*/
|
130
130
|
t_typemap *p_typemap;
|
131
131
|
|
132
|
+
/* Ruby encoding index of the client/internal encoding */
|
133
|
+
int enc_idx : PG_ENC_IDX_BITS;
|
134
|
+
|
132
135
|
/* 0 = PGresult is cleared by PG::Result#clear or by the GC
|
133
136
|
* 1 = PGresult is cleared internally by libpq
|
134
137
|
*/
|
135
|
-
int autoclear;
|
138
|
+
unsigned int autoclear : 1;
|
139
|
+
|
140
|
+
/* flags controlling Symbol/String field names */
|
141
|
+
unsigned int flags : 2;
|
136
142
|
|
137
143
|
/* Number of fields in fnames[] .
|
138
144
|
* Set to -1 if fnames[] is not yet initialized.
|
@@ -148,7 +154,7 @@ typedef struct {
|
|
148
154
|
/* Hash with fnames[] to field number mapping. */
|
149
155
|
VALUE field_map;
|
150
156
|
|
151
|
-
/* List of field names as frozen String objects.
|
157
|
+
/* List of field names as frozen String or Symbol objects.
|
152
158
|
* Only valid if nfields != -1
|
153
159
|
*/
|
154
160
|
VALUE fnames[0];
|
@@ -164,6 +170,10 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
|
164
170
|
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
165
171
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
166
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
|
+
|
167
177
|
#define PG_CODER_TIMESTAMP_DB_UTC 0x0
|
168
178
|
#define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
|
169
179
|
#define PG_CODER_TIMESTAMP_APP_UTC 0x0
|
@@ -276,6 +286,7 @@ void init_pg_type_map_by_oid _(( void ));
|
|
276
286
|
void init_pg_type_map_in_ruby _(( void ));
|
277
287
|
void init_pg_coder _(( void ));
|
278
288
|
void init_pg_copycoder _(( void ));
|
289
|
+
void init_pg_recordcoder _(( void ));
|
279
290
|
void init_pg_text_encoder _(( void ));
|
280
291
|
void init_pg_text_decoder _(( void ));
|
281
292
|
void init_pg_binary_encoder _(( void ));
|
@@ -293,6 +304,7 @@ VALUE pg_obj_to_i _(( VALUE ));
|
|
293
304
|
VALUE pg_tmbc_allocate _(( void ));
|
294
305
|
void pg_coder_init_encoder _(( VALUE ));
|
295
306
|
void pg_coder_init_decoder _(( VALUE ));
|
307
|
+
void pg_coder_mark _(( t_pg_coder * ));
|
296
308
|
char *pg_rb_str_ensure_capa _(( VALUE, long, char *, char ** ));
|
297
309
|
|
298
310
|
#define PG_RB_STR_ENSURE_CAPA( str, expand_len, curr_ptr, end_ptr ) \
|
@@ -306,11 +318,6 @@ char *pg_rb_str_ensure_capa _(( VALUE, long, char *,
|
|
306
318
|
(curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
|
307
319
|
)
|
308
320
|
|
309
|
-
#define PG_RB_TAINTED_STR_NEW( str, curr_ptr, end_ptr ) ( \
|
310
|
-
(str) = rb_tainted_str_new( NULL, 0 ), \
|
311
|
-
(curr_ptr) = (end_ptr) = RSTRING_PTR(str) \
|
312
|
-
)
|
313
|
-
|
314
321
|
VALUE pg_typemap_fit_to_result _(( VALUE, VALUE ));
|
315
322
|
VALUE pg_typemap_fit_to_query _(( VALUE, VALUE ));
|
316
323
|
int pg_typemap_fit_to_copy_get _(( VALUE ));
|
@@ -334,12 +341,7 @@ VALUE pg_tuple_new _(( VALUE, int ));
|
|
334
341
|
static inline t_pg_result *
|
335
342
|
pgresult_get_this( VALUE self )
|
336
343
|
{
|
337
|
-
|
338
|
-
|
339
|
-
if( this == NULL )
|
340
|
-
rb_raise(rb_ePGerror, "result has been cleared");
|
341
|
-
|
342
|
-
return this;
|
344
|
+
return RTYPEDDATA_DATA(self);
|
343
345
|
}
|
344
346
|
|
345
347
|
|
@@ -351,10 +353,16 @@ rb_encoding *pg_conn_enc_get _(( PGconn * ));
|
|
351
353
|
void notice_receiver_proxy(void *arg, const PGresult *result);
|
352
354
|
void notice_processor_proxy(void *arg, const char *message);
|
353
355
|
|
354
|
-
/* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set
|
355
|
-
|
356
|
+
/* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set
|
357
|
+
*
|
358
|
+
* message_id identifies the warning, so that it's reported only once.
|
359
|
+
*/
|
360
|
+
#define pg_deprecated(message_id, format_args) \
|
356
361
|
do { \
|
357
|
-
if( !pg_skip_deprecation_warning )
|
362
|
+
if( !(pg_skip_deprecation_warning & (1 << message_id)) ){ \
|
363
|
+
pg_skip_deprecation_warning |= 1 << message_id; \
|
364
|
+
rb_warning format_args; \
|
365
|
+
} \
|
358
366
|
} while(0);
|
359
367
|
|
360
368
|
#endif /* end __pg_h */
|
data/ext/pg_binary_decoder.c
CHANGED
@@ -1,12 +1,12 @@
|
|
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 "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
|
|
@@ -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
|
-
|
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
|
-
|
175
|
-
|
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
|
-
|
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(
|
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
|
}
|
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
@@ -61,11 +61,23 @@ pg_coder_init_decoder( VALUE self )
|
|
61
61
|
rb_iv_set( self, "@name", Qnil );
|
62
62
|
}
|
63
63
|
|
64
|
+
void
|
65
|
+
pg_coder_mark(t_pg_coder *this)
|
66
|
+
{
|
67
|
+
rb_gc_mark(this->coder_obj);
|
68
|
+
}
|
69
|
+
|
70
|
+
static void
|
71
|
+
pg_composite_coder_mark(t_pg_composite_coder *this)
|
72
|
+
{
|
73
|
+
pg_coder_mark(&this->comp);
|
74
|
+
}
|
75
|
+
|
64
76
|
static VALUE
|
65
77
|
pg_simple_encoder_allocate( VALUE klass )
|
66
78
|
{
|
67
79
|
t_pg_coder *this;
|
68
|
-
VALUE self = Data_Make_Struct( klass, t_pg_coder,
|
80
|
+
VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
|
69
81
|
pg_coder_init_encoder( self );
|
70
82
|
return self;
|
71
83
|
}
|
@@ -74,7 +86,7 @@ static VALUE
|
|
74
86
|
pg_composite_encoder_allocate( VALUE klass )
|
75
87
|
{
|
76
88
|
t_pg_composite_coder *this;
|
77
|
-
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder,
|
89
|
+
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
|
78
90
|
pg_coder_init_encoder( self );
|
79
91
|
this->elem = NULL;
|
80
92
|
this->needs_quotation = 1;
|
@@ -87,7 +99,7 @@ static VALUE
|
|
87
99
|
pg_simple_decoder_allocate( VALUE klass )
|
88
100
|
{
|
89
101
|
t_pg_coder *this;
|
90
|
-
VALUE self = Data_Make_Struct( klass, t_pg_coder,
|
102
|
+
VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
|
91
103
|
pg_coder_init_decoder( self );
|
92
104
|
return self;
|
93
105
|
}
|
@@ -96,7 +108,7 @@ static VALUE
|
|
96
108
|
pg_composite_decoder_allocate( VALUE klass )
|
97
109
|
{
|
98
110
|
t_pg_composite_coder *this;
|
99
|
-
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder,
|
111
|
+
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
|
100
112
|
pg_coder_init_decoder( self );
|
101
113
|
this->elem = NULL;
|
102
114
|
this->needs_quotation = 1;
|
@@ -145,7 +157,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
|
145
157
|
|
146
158
|
if( len == -1 ){
|
147
159
|
/* The intermediate value is a String that can be used directly. */
|
148
|
-
OBJ_INFECT(intermediate, value);
|
149
160
|
return intermediate;
|
150
161
|
}
|
151
162
|
|
@@ -157,7 +168,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
|
|
157
168
|
rb_obj_classname( self ), len, len2 );
|
158
169
|
}
|
159
170
|
rb_str_set_len( res, len2 );
|
160
|
-
OBJ_INFECT(res, value);
|
161
171
|
|
162
172
|
RB_GC_GUARD(intermediate);
|
163
173
|
|
@@ -204,7 +214,6 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
204
214
|
}
|
205
215
|
|
206
216
|
res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
|
207
|
-
OBJ_INFECT(res, argv[0]);
|
208
217
|
|
209
218
|
return res;
|
210
219
|
}
|
@@ -400,6 +409,11 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
400
409
|
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
|
401
410
|
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
|
402
411
|
|
412
|
+
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
|
413
|
+
rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
|
414
|
+
if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
|
415
|
+
rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
|
416
|
+
|
403
417
|
rb_define_const( coder_klass, "CFUNC", cfunc_obj );
|
404
418
|
|
405
419
|
RB_GC_GUARD(cfunc_obj);
|
@@ -512,8 +526,6 @@ init_pg_coder()
|
|
512
526
|
* This accessor is only used in PG::Coder#inspect .
|
513
527
|
*/
|
514
528
|
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
529
|
|
518
530
|
/* Document-class: PG::SimpleCoder < PG::Coder */
|
519
531
|
rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );
|
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id
|
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
|
-
|
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,9 +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->socket = -1;
|
202
|
-
this->guess_result_memsize = 1;
|
203
203
|
|
204
204
|
return self;
|
205
205
|
}
|
@@ -216,32 +216,27 @@ pgconn_s_allocate( VALUE klass )
|
|
216
216
|
*
|
217
217
|
* Create a connection to the specified server.
|
218
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:
|
219
226
|
* [+host+]
|
220
227
|
* server hostname
|
221
|
-
* [+hostaddr+]
|
222
|
-
* server address (avoids hostname lookup, overrides +host+)
|
223
228
|
* [+port+]
|
224
229
|
* server port number
|
230
|
+
* [+options+]
|
231
|
+
* backend options
|
232
|
+
* [+tty+]
|
233
|
+
* (ignored in newer versions of PostgreSQL)
|
225
234
|
* [+dbname+]
|
226
235
|
* connecting database name
|
227
236
|
* [+user+]
|
228
237
|
* login user name
|
229
238
|
* [+password+]
|
230
239
|
* login password
|
231
|
-
* [+connect_timeout+]
|
232
|
-
* maximum time to wait for connection to succeed
|
233
|
-
* [+options+]
|
234
|
-
* backend options
|
235
|
-
* [+tty+]
|
236
|
-
* (ignored in newer versions of PostgreSQL)
|
237
|
-
* [+sslmode+]
|
238
|
-
* (disable|allow|prefer|require)
|
239
|
-
* [+krbsrvname+]
|
240
|
-
* kerberos service name
|
241
|
-
* [+gsslib+]
|
242
|
-
* GSS library to use for GSSAPI authentication
|
243
|
-
* [+service+]
|
244
|
-
* service name to use for additional parameters
|
245
240
|
*
|
246
241
|
* Examples:
|
247
242
|
*
|
@@ -257,7 +252,7 @@ pgconn_s_allocate( VALUE klass )
|
|
257
252
|
* # As an Array
|
258
253
|
* PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
|
259
254
|
*
|
260
|
-
* 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
|
261
256
|
* connection will have its +client_encoding+ set accordingly.
|
262
257
|
*
|
263
258
|
* Raises a PG::Error if the connection fails.
|
@@ -272,6 +267,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
272
267
|
this = pg_get_connection( self );
|
273
268
|
conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
|
274
269
|
this->pgconn = gvl_PQconnectdb(StringValueCStr(conninfo));
|
270
|
+
|
275
271
|
if(this->pgconn == NULL)
|
276
272
|
rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate structure");
|
277
273
|
|
@@ -281,10 +277,6 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
281
277
|
rb_exc_raise(error);
|
282
278
|
}
|
283
279
|
|
284
|
-
this->socket = PQsocket( this->pgconn );
|
285
|
-
if ( this->socket < 0 )
|
286
|
-
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
287
|
-
|
288
280
|
pgconn_set_default_encoding( self );
|
289
281
|
|
290
282
|
if (rb_block_given_p()) {
|
@@ -299,14 +291,16 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
299
291
|
* PG::Connection.connect_start(connection_string) -> conn
|
300
292
|
* PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn
|
301
293
|
*
|
302
|
-
* This is an asynchronous version of PG::Connection.
|
294
|
+
* This is an asynchronous version of PG::Connection.new.
|
303
295
|
*
|
304
296
|
* Use #connect_poll to poll the status of the connection.
|
305
297
|
*
|
306
298
|
* NOTE: this does *not* set the connection's +client_encoding+ for you if
|
307
|
-
* 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,
|
308
300
|
* call #internal_encoding=. You can also set it automatically by setting
|
309
|
-
* 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].
|
310
304
|
*
|
311
305
|
*/
|
312
306
|
static VALUE
|
@@ -335,10 +329,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
335
329
|
rb_exc_raise(error);
|
336
330
|
}
|
337
331
|
|
338
|
-
this->socket = PQsocket( this->pgconn );
|
339
|
-
if ( this->socket < 0 )
|
340
|
-
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
341
|
-
|
342
332
|
if ( rb_block_given_p() ) {
|
343
333
|
return rb_ensure( rb_yield, rb_conn, pgconn_finish, rb_conn );
|
344
334
|
}
|
@@ -353,6 +343,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
353
343
|
*
|
354
344
|
* Check server status.
|
355
345
|
*
|
346
|
+
* See PG::Connection.new for a description of the parameters.
|
347
|
+
*
|
356
348
|
* Returns one of:
|
357
349
|
* [+PQPING_OK+]
|
358
350
|
* server is accepting connections
|
@@ -362,8 +354,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
362
354
|
* could not establish connection
|
363
355
|
* [+PQPING_NO_ATTEMPT+]
|
364
356
|
* connection not attempted (bad params)
|
365
|
-
*
|
366
|
-
* Available since PostgreSQL-9.1
|
367
357
|
*/
|
368
358
|
static VALUE
|
369
359
|
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
@@ -434,7 +424,8 @@ pgconn_s_conndefaults(VALUE self)
|
|
434
424
|
* Return value is the encrypted password.
|
435
425
|
* The caller can assume the string doesn't contain any special characters that would require escaping.
|
436
426
|
*
|
437
|
-
* 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].
|
438
429
|
*/
|
439
430
|
static VALUE
|
440
431
|
pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
@@ -453,10 +444,6 @@ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
|
|
453
444
|
if ( encrypted ) {
|
454
445
|
rval = rb_str_new2( encrypted );
|
455
446
|
PQfreemem( encrypted );
|
456
|
-
|
457
|
-
OBJ_INFECT( rval, password );
|
458
|
-
OBJ_INFECT( rval, username );
|
459
|
-
OBJ_INFECT( rval, algorithm );
|
460
447
|
} else {
|
461
448
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
462
449
|
}
|
@@ -489,9 +476,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
489
476
|
rval = rb_str_new2( encrypted );
|
490
477
|
PQfreemem( encrypted );
|
491
478
|
|
492
|
-
OBJ_INFECT( rval, password );
|
493
|
-
OBJ_INFECT( rval, username );
|
494
|
-
|
495
479
|
return rval;
|
496
480
|
}
|
497
481
|
|
@@ -637,7 +621,7 @@ pgconn_db(VALUE self)
|
|
637
621
|
{
|
638
622
|
char *db = PQdb(pg_get_pgconn(self));
|
639
623
|
if (!db) return Qnil;
|
640
|
-
return
|
624
|
+
return rb_str_new2(db);
|
641
625
|
}
|
642
626
|
|
643
627
|
/*
|
@@ -651,7 +635,7 @@ pgconn_user(VALUE self)
|
|
651
635
|
{
|
652
636
|
char *user = PQuser(pg_get_pgconn(self));
|
653
637
|
if (!user) return Qnil;
|
654
|
-
return
|
638
|
+
return rb_str_new2(user);
|
655
639
|
}
|
656
640
|
|
657
641
|
/*
|
@@ -665,7 +649,7 @@ pgconn_pass(VALUE self)
|
|
665
649
|
{
|
666
650
|
char *user = PQpass(pg_get_pgconn(self));
|
667
651
|
if (!user) return Qnil;
|
668
|
-
return
|
652
|
+
return rb_str_new2(user);
|
669
653
|
}
|
670
654
|
|
671
655
|
/*
|
@@ -679,7 +663,7 @@ pgconn_host(VALUE self)
|
|
679
663
|
{
|
680
664
|
char *host = PQhost(pg_get_pgconn(self));
|
681
665
|
if (!host) return Qnil;
|
682
|
-
return
|
666
|
+
return rb_str_new2(host);
|
683
667
|
}
|
684
668
|
|
685
669
|
/*
|
@@ -706,7 +690,7 @@ pgconn_tty(VALUE self)
|
|
706
690
|
{
|
707
691
|
char *tty = PQtty(pg_get_pgconn(self));
|
708
692
|
if (!tty) return Qnil;
|
709
|
-
return
|
693
|
+
return rb_str_new2(tty);
|
710
694
|
}
|
711
695
|
|
712
696
|
/*
|
@@ -720,7 +704,7 @@ pgconn_options(VALUE self)
|
|
720
704
|
{
|
721
705
|
char *options = PQoptions(pg_get_pgconn(self));
|
722
706
|
if (!options) return Qnil;
|
723
|
-
return
|
707
|
+
return rb_str_new2(options);
|
724
708
|
}
|
725
709
|
|
726
710
|
|
@@ -801,7 +785,7 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
|
|
801
785
|
if(ret == NULL)
|
802
786
|
return Qnil;
|
803
787
|
else
|
804
|
-
return
|
788
|
+
return rb_str_new2(ret);
|
805
789
|
}
|
806
790
|
|
807
791
|
/*
|
@@ -846,7 +830,7 @@ pgconn_error_message(VALUE self)
|
|
846
830
|
{
|
847
831
|
char *error = PQerrorMessage(pg_get_pgconn(self));
|
848
832
|
if (!error) return Qnil;
|
849
|
-
return
|
833
|
+
return rb_str_new2(error);
|
850
834
|
}
|
851
835
|
|
852
836
|
/*
|
@@ -870,6 +854,8 @@ static VALUE
|
|
870
854
|
pgconn_socket(VALUE self)
|
871
855
|
{
|
872
856
|
int sd;
|
857
|
+
pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
|
858
|
+
|
873
859
|
if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
|
874
860
|
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
875
861
|
return INT2NUM(sd);
|
@@ -902,6 +888,7 @@ pgconn_socket_io(VALUE self)
|
|
902
888
|
|
903
889
|
#ifdef _WIN32
|
904
890
|
ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
|
891
|
+
this->ruby_sd = ruby_sd;
|
905
892
|
#else
|
906
893
|
ruby_sd = sd;
|
907
894
|
#endif
|
@@ -965,32 +952,23 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
|
|
965
952
|
|
966
953
|
/*
|
967
954
|
* call-seq:
|
968
|
-
* conn.
|
969
|
-
* conn.
|
955
|
+
* conn.sync_exec(sql) -> PG::Result
|
956
|
+
* conn.sync_exec(sql) {|pg_result| block }
|
970
957
|
*
|
971
|
-
*
|
972
|
-
*
|
973
|
-
* On failure, it raises a PG::Error.
|
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
|
-
* argument placeholders are used.
|
978
|
-
*
|
979
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
980
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
981
|
-
* 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:
|
982
963
|
*
|
983
|
-
* #
|
984
|
-
*
|
985
|
-
*
|
986
|
-
* the query is finished. This is most notably visible by a delayed reaction to Control+C.
|
987
|
-
* Both methods ensure that other threads can process while waiting for the server to
|
988
|
-
* 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
|
989
967
|
*/
|
990
968
|
static VALUE
|
991
969
|
pgconn_exec(int argc, VALUE *argv, VALUE self)
|
992
970
|
{
|
993
|
-
|
971
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
994
972
|
PGresult *result = NULL;
|
995
973
|
VALUE rb_pgresult;
|
996
974
|
|
@@ -998,7 +976,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
998
976
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
999
977
|
VALUE query_str = argv[0];
|
1000
978
|
|
1001
|
-
result = gvl_PQexec(
|
979
|
+
result = gvl_PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx));
|
1002
980
|
rb_pgresult = pg_new_result(result, self);
|
1003
981
|
pg_result_check(rb_pgresult);
|
1004
982
|
if (rb_block_given_p()) {
|
@@ -1006,7 +984,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
1006
984
|
}
|
1007
985
|
return rb_pgresult;
|
1008
986
|
}
|
1009
|
-
pg_deprecated(("forwarding exec to exec_params is deprecated"));
|
987
|
+
pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
|
1010
988
|
|
1011
989
|
/* Otherwise, just call #exec_params instead for backward-compatibility */
|
1012
990
|
return pgconn_exec_params( argc, argv, self );
|
@@ -1260,57 +1238,23 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1260
1238
|
|
1261
1239
|
/*
|
1262
1240
|
* call-seq:
|
1263
|
-
* conn.
|
1264
|
-
* conn.
|
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 }
|
1265
1243
|
*
|
1266
|
-
*
|
1267
|
-
* for
|
1268
|
-
*
|
1269
|
-
* Returns a PG::Result instance on success. On failure, it raises a PG::Error.
|
1270
|
-
*
|
1271
|
-
* +params+ is an array of the bind parameters for the SQL query.
|
1272
|
-
* Each element of the +params+ array may be either:
|
1273
|
-
* a hash of the form:
|
1274
|
-
* {:value => String (value of bind parameter)
|
1275
|
-
* :type => Integer (oid of type of bind parameter)
|
1276
|
-
* :format => Integer (0 for text, 1 for binary)
|
1277
|
-
* }
|
1278
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1279
|
-
* { :value => <string value>, :type => 0, :format => 0 }
|
1280
|
-
*
|
1281
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1282
|
-
* inside the SQL query. The 0th element of the +params+ array is bound
|
1283
|
-
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
1284
|
-
*
|
1285
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1286
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1287
|
-
* explicit casts in the query to ensure that the right type is used.
|
1288
|
-
*
|
1289
|
-
* For example: "SELECT $1::int"
|
1290
|
-
*
|
1291
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1292
|
-
* for binary.
|
1293
|
-
*
|
1294
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1295
|
-
* This will type cast the params from various Ruby types before transmission
|
1296
|
-
* based on the encoders defined by the type map. When a type encoder is used
|
1297
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1298
|
-
* instead out of the hash form described above.
|
1299
|
-
*
|
1300
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1301
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1302
|
-
* 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.
|
1303
1247
|
*/
|
1304
1248
|
static VALUE
|
1305
1249
|
pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
1306
1250
|
{
|
1307
|
-
|
1251
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1308
1252
|
PGresult *result = NULL;
|
1309
1253
|
VALUE rb_pgresult;
|
1310
1254
|
VALUE command, in_res_fmt;
|
1311
1255
|
int nParams;
|
1312
1256
|
int resultFormat;
|
1313
|
-
struct query_params_data paramsData = {
|
1257
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1314
1258
|
|
1315
1259
|
/* For compatibility we accept 1 to 4 parameters */
|
1316
1260
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
@@ -1321,7 +1265,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1321
1265
|
* is passed to #exec
|
1322
1266
|
*/
|
1323
1267
|
if ( NIL_P(paramsData.params) ) {
|
1324
|
-
pg_deprecated(("forwarding exec_params to exec is deprecated"));
|
1268
|
+
pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
|
1325
1269
|
return pgconn_exec( 1, argv, self );
|
1326
1270
|
}
|
1327
1271
|
pgconn_query_assign_typemap( self, ¶msData );
|
@@ -1329,7 +1273,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1329
1273
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1330
1274
|
nParams = alloc_query_params( ¶msData );
|
1331
1275
|
|
1332
|
-
result = gvl_PQexecParams(
|
1276
|
+
result = gvl_PQexecParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1333
1277
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1334
1278
|
|
1335
1279
|
free_query_params( ¶msData );
|
@@ -1346,28 +1290,16 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1346
1290
|
|
1347
1291
|
/*
|
1348
1292
|
* call-seq:
|
1349
|
-
* conn.
|
1293
|
+
* conn.sync_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
1350
1294
|
*
|
1351
|
-
*
|
1352
|
-
*
|
1353
|
-
*
|
1354
|
-
*
|
1355
|
-
* +param_types+ is an optional parameter to specify the Oids of the
|
1356
|
-
* types of the parameters.
|
1357
|
-
*
|
1358
|
-
* If the types are not specified, they will be inferred by PostgreSQL.
|
1359
|
-
* Instead of specifying type oids, it's recommended to simply add
|
1360
|
-
* explicit casts in the query to ensure that the right type is used.
|
1361
|
-
*
|
1362
|
-
* For example: "SELECT $1::int"
|
1363
|
-
*
|
1364
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1365
|
-
* 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.
|
1366
1298
|
*/
|
1367
1299
|
static VALUE
|
1368
1300
|
pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
1369
1301
|
{
|
1370
|
-
|
1302
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1371
1303
|
PGresult *result = NULL;
|
1372
1304
|
VALUE rb_pgresult;
|
1373
1305
|
VALUE name, command, in_paramtypes;
|
@@ -1377,7 +1309,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1377
1309
|
Oid *paramTypes = NULL;
|
1378
1310
|
const char *name_cstr;
|
1379
1311
|
const char *command_cstr;
|
1380
|
-
int enc_idx =
|
1312
|
+
int enc_idx = this->enc_idx;
|
1381
1313
|
|
1382
1314
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1383
1315
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1395,7 +1327,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1395
1327
|
paramTypes[i] = NUM2UINT(param);
|
1396
1328
|
}
|
1397
1329
|
}
|
1398
|
-
result = gvl_PQprepare(
|
1330
|
+
result = gvl_PQprepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1399
1331
|
|
1400
1332
|
xfree(paramTypes);
|
1401
1333
|
|
@@ -1406,49 +1338,23 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1406
1338
|
|
1407
1339
|
/*
|
1408
1340
|
* call-seq:
|
1409
|
-
* conn.
|
1410
|
-
* conn.
|
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 }
|
1411
1343
|
*
|
1412
|
-
*
|
1413
|
-
*
|
1414
|
-
*
|
1415
|
-
*
|
1416
|
-
* +params+ is an array of the optional bind parameters for the
|
1417
|
-
* SQL query. Each element of the +params+ array may be either:
|
1418
|
-
* a hash of the form:
|
1419
|
-
* {:value => String (value of bind parameter)
|
1420
|
-
* :format => Integer (0 for text, 1 for binary)
|
1421
|
-
* }
|
1422
|
-
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1423
|
-
* { :value => <string value>, :format => 0 }
|
1424
|
-
*
|
1425
|
-
* PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
|
1426
|
-
* inside the SQL query. The 0th element of the +params+ array is bound
|
1427
|
-
* to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
|
1428
|
-
*
|
1429
|
-
* The optional +result_format+ should be 0 for text results, 1
|
1430
|
-
* for binary.
|
1431
|
-
*
|
1432
|
-
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1433
|
-
* This will type cast the params from various Ruby types before transmission
|
1434
|
-
* based on the encoders defined by the type map. When a type encoder is used
|
1435
|
-
* the format and oid of a given bind parameter are retrieved from the encoder
|
1436
|
-
* instead out of the hash form described above.
|
1437
|
-
*
|
1438
|
-
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1439
|
-
* and the PG::Result object will automatically be cleared when the block terminates.
|
1440
|
-
* 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.
|
1441
1347
|
*/
|
1442
1348
|
static VALUE
|
1443
1349
|
pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
1444
1350
|
{
|
1445
|
-
|
1351
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1446
1352
|
PGresult *result = NULL;
|
1447
1353
|
VALUE rb_pgresult;
|
1448
1354
|
VALUE name, in_res_fmt;
|
1449
1355
|
int nParams;
|
1450
1356
|
int resultFormat;
|
1451
|
-
struct query_params_data paramsData = {
|
1357
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1452
1358
|
|
1453
1359
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1454
1360
|
paramsData.with_types = 0;
|
@@ -1461,7 +1367,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1461
1367
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1462
1368
|
nParams = alloc_query_params( ¶msData );
|
1463
1369
|
|
1464
|
-
result = gvl_PQexecPrepared(
|
1370
|
+
result = gvl_PQexecPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1465
1371
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1466
1372
|
resultFormat);
|
1467
1373
|
|
@@ -1478,25 +1384,26 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1478
1384
|
|
1479
1385
|
/*
|
1480
1386
|
* call-seq:
|
1481
|
-
* conn.
|
1387
|
+
* conn.sync_describe_prepared( statement_name ) -> PG::Result
|
1482
1388
|
*
|
1483
|
-
*
|
1484
|
-
*
|
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.
|
1485
1392
|
*/
|
1486
1393
|
static VALUE
|
1487
1394
|
pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
1488
1395
|
{
|
1489
1396
|
PGresult *result;
|
1490
1397
|
VALUE rb_pgresult;
|
1491
|
-
|
1398
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1492
1399
|
const char *stmt;
|
1493
1400
|
if(NIL_P(stmt_name)) {
|
1494
1401
|
stmt = NULL;
|
1495
1402
|
}
|
1496
1403
|
else {
|
1497
|
-
stmt = pg_cstr_enc(stmt_name,
|
1404
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1498
1405
|
}
|
1499
|
-
result = gvl_PQdescribePrepared(
|
1406
|
+
result = gvl_PQdescribePrepared(this->pgconn, stmt);
|
1500
1407
|
rb_pgresult = pg_new_result(result, self);
|
1501
1408
|
pg_result_check(rb_pgresult);
|
1502
1409
|
return rb_pgresult;
|
@@ -1505,9 +1412,11 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1505
1412
|
|
1506
1413
|
/*
|
1507
1414
|
* call-seq:
|
1508
|
-
* conn.
|
1415
|
+
* conn.sync_describe_portal( portal_name ) -> PG::Result
|
1509
1416
|
*
|
1510
|
-
*
|
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.
|
1511
1420
|
*/
|
1512
1421
|
static VALUE
|
1513
1422
|
pgconn_describe_portal(self, stmt_name)
|
@@ -1515,15 +1424,15 @@ pgconn_describe_portal(self, stmt_name)
|
|
1515
1424
|
{
|
1516
1425
|
PGresult *result;
|
1517
1426
|
VALUE rb_pgresult;
|
1518
|
-
|
1427
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1519
1428
|
const char *stmt;
|
1520
1429
|
if(NIL_P(stmt_name)) {
|
1521
1430
|
stmt = NULL;
|
1522
1431
|
}
|
1523
1432
|
else {
|
1524
|
-
stmt = pg_cstr_enc(stmt_name,
|
1433
|
+
stmt = pg_cstr_enc(stmt_name, this->enc_idx);
|
1525
1434
|
}
|
1526
|
-
result = gvl_PQdescribePortal(
|
1435
|
+
result = gvl_PQdescribePortal(this->pgconn, stmt);
|
1527
1436
|
rb_pgresult = pg_new_result(result, self);
|
1528
1437
|
pg_result_check(rb_pgresult);
|
1529
1438
|
return rb_pgresult;
|
@@ -1570,13 +1479,15 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1570
1479
|
* Consider using exec_params, which avoids the need for passing values
|
1571
1480
|
* inside of SQL commands.
|
1572
1481
|
*
|
1573
|
-
*
|
1482
|
+
* Character encoding of escaped string will be equal to client encoding of connection.
|
1574
1483
|
*
|
1575
1484
|
* NOTE: This class version of this method can only be used safely in client
|
1576
1485
|
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1577
1486
|
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1578
1487
|
* results if used in programs that use multiple database connections; use the
|
1579
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.
|
1580
1491
|
*/
|
1581
1492
|
static VALUE
|
1582
1493
|
pgconn_s_escape(VALUE self, VALUE string)
|
@@ -1588,7 +1499,7 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1588
1499
|
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1589
1500
|
|
1590
1501
|
StringValueCStr(string);
|
1591
|
-
enc_idx =
|
1502
|
+
enc_idx = singleton ? ENCODING_GET(string) : pg_get_connection(self)->enc_idx;
|
1592
1503
|
if( ENCODING_GET(string) != enc_idx ){
|
1593
1504
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1594
1505
|
}
|
@@ -1605,7 +1516,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1605
1516
|
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1606
1517
|
}
|
1607
1518
|
rb_str_set_len(result, size);
|
1608
|
-
OBJ_INFECT(result, string);
|
1609
1519
|
|
1610
1520
|
return result;
|
1611
1521
|
}
|
@@ -1651,7 +1561,6 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
|
|
1651
1561
|
}
|
1652
1562
|
|
1653
1563
|
ret = rb_str_new((char*)to, to_len - 1);
|
1654
|
-
OBJ_INFECT(ret, str);
|
1655
1564
|
PQfreemem(to);
|
1656
1565
|
return ret;
|
1657
1566
|
}
|
@@ -1681,7 +1590,6 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1681
1590
|
to = PQunescapeBytea(from, &to_len);
|
1682
1591
|
|
1683
1592
|
ret = rb_str_new((char*)to, to_len);
|
1684
|
-
OBJ_INFECT(ret, str);
|
1685
1593
|
PQfreemem(to);
|
1686
1594
|
return ret;
|
1687
1595
|
}
|
@@ -1692,33 +1600,32 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1692
1600
|
*
|
1693
1601
|
* Escape an arbitrary String +str+ as a literal.
|
1694
1602
|
*
|
1695
|
-
*
|
1603
|
+
* See also PG::TextEncoder::QuotedLiteral for a type cast integrated version of this function.
|
1696
1604
|
*/
|
1697
1605
|
static VALUE
|
1698
1606
|
pgconn_escape_literal(VALUE self, VALUE string)
|
1699
1607
|
{
|
1700
|
-
|
1608
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1701
1609
|
char *escaped = NULL;
|
1702
1610
|
VALUE error;
|
1703
1611
|
VALUE result = Qnil;
|
1704
|
-
int enc_idx =
|
1612
|
+
int enc_idx = this->enc_idx;
|
1705
1613
|
|
1706
1614
|
StringValueCStr(string);
|
1707
1615
|
if( ENCODING_GET(string) != enc_idx ){
|
1708
1616
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1709
1617
|
}
|
1710
1618
|
|
1711
|
-
escaped = PQescapeLiteral(
|
1619
|
+
escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1712
1620
|
if (escaped == NULL)
|
1713
1621
|
{
|
1714
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1622
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1715
1623
|
rb_iv_set(error, "@connection", self);
|
1716
1624
|
rb_exc_raise(error);
|
1717
1625
|
return Qnil;
|
1718
1626
|
}
|
1719
1627
|
result = rb_str_new2(escaped);
|
1720
1628
|
PQfreemem(escaped);
|
1721
|
-
OBJ_INFECT(result, string);
|
1722
1629
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1723
1630
|
|
1724
1631
|
return result;
|
@@ -1733,34 +1640,31 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1733
1640
|
* This method does the same as #quote_ident with a String argument,
|
1734
1641
|
* but it doesn't support an Array argument and it makes use of libpq
|
1735
1642
|
* to process the string.
|
1736
|
-
*
|
1737
|
-
* Available since PostgreSQL-9.0
|
1738
1643
|
*/
|
1739
1644
|
static VALUE
|
1740
1645
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
1741
1646
|
{
|
1742
|
-
|
1647
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1743
1648
|
char *escaped = NULL;
|
1744
1649
|
VALUE error;
|
1745
1650
|
VALUE result = Qnil;
|
1746
|
-
int enc_idx =
|
1651
|
+
int enc_idx = this->enc_idx;
|
1747
1652
|
|
1748
1653
|
StringValueCStr(string);
|
1749
1654
|
if( ENCODING_GET(string) != enc_idx ){
|
1750
1655
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1751
1656
|
}
|
1752
1657
|
|
1753
|
-
escaped = PQescapeIdentifier(
|
1658
|
+
escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1754
1659
|
if (escaped == NULL)
|
1755
1660
|
{
|
1756
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
1661
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
1757
1662
|
rb_iv_set(error, "@connection", self);
|
1758
1663
|
rb_exc_raise(error);
|
1759
1664
|
return Qnil;
|
1760
1665
|
}
|
1761
1666
|
result = rb_str_new2(escaped);
|
1762
1667
|
PQfreemem(escaped);
|
1763
|
-
OBJ_INFECT(result, string);
|
1764
1668
|
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1765
1669
|
|
1766
1670
|
return result;
|
@@ -1801,8 +1705,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1801
1705
|
* # do something with the received row
|
1802
1706
|
* end
|
1803
1707
|
* end
|
1804
|
-
*
|
1805
|
-
* Available since PostgreSQL-9.2
|
1806
1708
|
*/
|
1807
1709
|
static VALUE
|
1808
1710
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1838,20 +1740,20 @@ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
|
|
1838
1740
|
static VALUE
|
1839
1741
|
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
1840
1742
|
{
|
1841
|
-
|
1743
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1842
1744
|
VALUE error;
|
1843
1745
|
|
1844
1746
|
/* If called with no or nil parameters, use PQexec for compatibility */
|
1845
1747
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
1846
|
-
if(gvl_PQsendQuery(
|
1847
|
-
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));
|
1848
1750
|
rb_iv_set(error, "@connection", self);
|
1849
1751
|
rb_exc_raise(error);
|
1850
1752
|
}
|
1851
1753
|
return Qnil;
|
1852
1754
|
}
|
1853
1755
|
|
1854
|
-
pg_deprecated(("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
|
1756
|
+
pg_deprecated(2, ("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
|
1855
1757
|
|
1856
1758
|
/* If called with parameters, and optionally result_format,
|
1857
1759
|
* use PQsendQueryParams
|
@@ -1890,7 +1792,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1890
1792
|
* The optional +result_format+ should be 0 for text results, 1
|
1891
1793
|
* for binary.
|
1892
1794
|
*
|
1893
|
-
* 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).
|
1894
1796
|
* This will type cast the params from various Ruby types before transmission
|
1895
1797
|
* based on the encoders defined by the type map. When a type encoder is used
|
1896
1798
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -1900,13 +1802,13 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1900
1802
|
static VALUE
|
1901
1803
|
pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
1902
1804
|
{
|
1903
|
-
|
1805
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1904
1806
|
int result;
|
1905
1807
|
VALUE command, in_res_fmt;
|
1906
1808
|
VALUE error;
|
1907
1809
|
int nParams;
|
1908
1810
|
int resultFormat;
|
1909
|
-
struct query_params_data paramsData = {
|
1811
|
+
struct query_params_data paramsData = { this->enc_idx };
|
1910
1812
|
|
1911
1813
|
rb_scan_args(argc, argv, "22", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1912
1814
|
paramsData.with_types = 1;
|
@@ -1915,13 +1817,13 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
1915
1817
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1916
1818
|
nParams = alloc_query_params( ¶msData );
|
1917
1819
|
|
1918
|
-
result = gvl_PQsendQueryParams(
|
1820
|
+
result = gvl_PQsendQueryParams(this->pgconn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1919
1821
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1920
1822
|
|
1921
1823
|
free_query_params( ¶msData );
|
1922
1824
|
|
1923
1825
|
if(result == 0) {
|
1924
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1826
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1925
1827
|
rb_iv_set(error, "@connection", self);
|
1926
1828
|
rb_exc_raise(error);
|
1927
1829
|
}
|
@@ -1951,7 +1853,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
|
|
1951
1853
|
static VALUE
|
1952
1854
|
pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
1953
1855
|
{
|
1954
|
-
|
1856
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
1955
1857
|
int result;
|
1956
1858
|
VALUE name, command, in_paramtypes;
|
1957
1859
|
VALUE param;
|
@@ -1961,7 +1863,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1961
1863
|
Oid *paramTypes = NULL;
|
1962
1864
|
const char *name_cstr;
|
1963
1865
|
const char *command_cstr;
|
1964
|
-
int enc_idx =
|
1866
|
+
int enc_idx = this->enc_idx;
|
1965
1867
|
|
1966
1868
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1967
1869
|
name_cstr = pg_cstr_enc(name, enc_idx);
|
@@ -1979,12 +1881,12 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1979
1881
|
paramTypes[i] = NUM2UINT(param);
|
1980
1882
|
}
|
1981
1883
|
}
|
1982
|
-
result = gvl_PQsendPrepare(
|
1884
|
+
result = gvl_PQsendPrepare(this->pgconn, name_cstr, command_cstr, nParams, paramTypes);
|
1983
1885
|
|
1984
1886
|
xfree(paramTypes);
|
1985
1887
|
|
1986
1888
|
if(result == 0) {
|
1987
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1889
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
1988
1890
|
rb_iv_set(error, "@connection", self);
|
1989
1891
|
rb_exc_raise(error);
|
1990
1892
|
}
|
@@ -2016,7 +1918,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
2016
1918
|
* The optional +result_format+ should be 0 for text results, 1
|
2017
1919
|
* for binary.
|
2018
1920
|
*
|
2019
|
-
* 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).
|
2020
1922
|
* This will type cast the params from various Ruby types before transmission
|
2021
1923
|
* based on the encoders defined by the type map. When a type encoder is used
|
2022
1924
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
@@ -2026,13 +1928,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
2026
1928
|
static VALUE
|
2027
1929
|
pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
2028
1930
|
{
|
2029
|
-
|
1931
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2030
1932
|
int result;
|
2031
1933
|
VALUE name, in_res_fmt;
|
2032
1934
|
VALUE error;
|
2033
1935
|
int nParams;
|
2034
1936
|
int resultFormat;
|
2035
|
-
struct query_params_data paramsData = {
|
1937
|
+
struct query_params_data paramsData = { this->enc_idx };
|
2036
1938
|
|
2037
1939
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
2038
1940
|
paramsData.with_types = 0;
|
@@ -2046,14 +1948,14 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
2046
1948
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
2047
1949
|
nParams = alloc_query_params( ¶msData );
|
2048
1950
|
|
2049
|
-
result = gvl_PQsendQueryPrepared(
|
1951
|
+
result = gvl_PQsendQueryPrepared(this->pgconn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
2050
1952
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
2051
1953
|
resultFormat);
|
2052
1954
|
|
2053
1955
|
free_query_params( ¶msData );
|
2054
1956
|
|
2055
1957
|
if(result == 0) {
|
2056
|
-
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(
|
1958
|
+
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
|
2057
1959
|
rb_iv_set(error, "@connection", self);
|
2058
1960
|
rb_exc_raise(error);
|
2059
1961
|
}
|
@@ -2071,10 +1973,10 @@ static VALUE
|
|
2071
1973
|
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
2072
1974
|
{
|
2073
1975
|
VALUE error;
|
2074
|
-
|
1976
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2075
1977
|
/* returns 0 on failure */
|
2076
|
-
if(gvl_PQsendDescribePrepared(
|
2077
|
-
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));
|
2078
1980
|
rb_iv_set(error, "@connection", self);
|
2079
1981
|
rb_exc_raise(error);
|
2080
1982
|
}
|
@@ -2093,10 +1995,10 @@ static VALUE
|
|
2093
1995
|
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
2094
1996
|
{
|
2095
1997
|
VALUE error;
|
2096
|
-
|
1998
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2097
1999
|
/* returns 0 on failure */
|
2098
|
-
if(gvl_PQsendDescribePortal(
|
2099
|
-
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));
|
2100
2002
|
rb_iv_set(error, "@connection", self);
|
2101
2003
|
rb_exc_raise(error);
|
2102
2004
|
}
|
@@ -2297,7 +2199,7 @@ pgconn_cancel(VALUE self)
|
|
2297
2199
|
static VALUE
|
2298
2200
|
pgconn_notifies(VALUE self)
|
2299
2201
|
{
|
2300
|
-
|
2202
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2301
2203
|
PGnotify *notification;
|
2302
2204
|
VALUE hash;
|
2303
2205
|
VALUE sym_relname, sym_be_pid, sym_extra;
|
@@ -2307,17 +2209,17 @@ pgconn_notifies(VALUE self)
|
|
2307
2209
|
sym_be_pid = ID2SYM(rb_intern("be_pid"));
|
2308
2210
|
sym_extra = ID2SYM(rb_intern("extra"));
|
2309
2211
|
|
2310
|
-
notification = gvl_PQnotifies(
|
2212
|
+
notification = gvl_PQnotifies(this->pgconn);
|
2311
2213
|
if (notification == NULL) {
|
2312
2214
|
return Qnil;
|
2313
2215
|
}
|
2314
2216
|
|
2315
2217
|
hash = rb_hash_new();
|
2316
|
-
relname =
|
2218
|
+
relname = rb_str_new2(notification->relname);
|
2317
2219
|
be_pid = INT2NUM(notification->be_pid);
|
2318
|
-
extra =
|
2319
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2320
|
-
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 );
|
2321
2223
|
|
2322
2224
|
rb_hash_aset(hash, sym_relname, relname);
|
2323
2225
|
rb_hash_aset(hash, sym_be_pid, be_pid);
|
@@ -2337,15 +2239,18 @@ pgconn_notifies(VALUE self)
|
|
2337
2239
|
int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
2338
2240
|
|
2339
2241
|
static void *
|
2340
|
-
wait_socket_readable(
|
2242
|
+
wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
|
2341
2243
|
{
|
2342
|
-
|
2244
|
+
int sd = PQsocket( conn );
|
2343
2245
|
void *retval;
|
2344
2246
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2345
2247
|
DWORD timeout_milisec = INFINITE;
|
2346
2248
|
DWORD wait_ret;
|
2347
2249
|
WSAEVENT hEvent;
|
2348
2250
|
|
2251
|
+
if ( sd < 0 )
|
2252
|
+
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
2253
|
+
|
2349
2254
|
hEvent = WSACreateEvent();
|
2350
2255
|
|
2351
2256
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
@@ -2360,7 +2265,7 @@ wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*i
|
|
2360
2265
|
}
|
2361
2266
|
|
2362
2267
|
while ( !(retval=is_readable(conn)) ) {
|
2363
|
-
if ( WSAEventSelect(
|
2268
|
+
if ( WSAEventSelect(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
|
2364
2269
|
WSACloseEvent( hEvent );
|
2365
2270
|
rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
|
2366
2271
|
}
|
@@ -2412,13 +2317,16 @@ wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*i
|
|
2412
2317
|
/* non Win32 */
|
2413
2318
|
|
2414
2319
|
static void *
|
2415
|
-
wait_socket_readable(
|
2320
|
+
wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
|
2416
2321
|
{
|
2417
|
-
|
2322
|
+
int sd = PQsocket( conn );
|
2418
2323
|
int ret;
|
2419
2324
|
void *retval;
|
2420
2325
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2421
2326
|
|
2327
|
+
if ( sd < 0 )
|
2328
|
+
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
2329
|
+
|
2422
2330
|
/* Check for connection errors (PQisBusy is true on connection errors) */
|
2423
2331
|
if ( PQconsumeInput(conn) == 0 )
|
2424
2332
|
rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
|
@@ -2437,7 +2345,7 @@ wait_socket_readable( t_pg_connection *this, struct timeval *ptimeout, void *(*i
|
|
2437
2345
|
/* Is the given timeout valid? */
|
2438
2346
|
if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
|
2439
2347
|
/* Wait for the socket to become readable before checking again */
|
2440
|
-
ret = rb_wait_for_single_fd(
|
2348
|
+
ret = rb_wait_for_single_fd( sd, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
|
2441
2349
|
} else {
|
2442
2350
|
ret = 0;
|
2443
2351
|
}
|
@@ -2500,17 +2408,17 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2500
2408
|
ptimeout = &timeout;
|
2501
2409
|
}
|
2502
2410
|
|
2503
|
-
pnotification = (PGnotify*) wait_socket_readable( this, ptimeout, notify_readable);
|
2411
|
+
pnotification = (PGnotify*) wait_socket_readable( this->pgconn, ptimeout, notify_readable);
|
2504
2412
|
|
2505
2413
|
/* Return nil if the select timed out */
|
2506
2414
|
if ( !pnotification ) return Qnil;
|
2507
2415
|
|
2508
|
-
relname =
|
2509
|
-
PG_ENCODING_SET_NOCHECK( relname,
|
2416
|
+
relname = rb_str_new2( pnotification->relname );
|
2417
|
+
PG_ENCODING_SET_NOCHECK( relname, this->enc_idx );
|
2510
2418
|
be_pid = INT2NUM( pnotification->be_pid );
|
2511
2419
|
if ( *pnotification->extra ) {
|
2512
|
-
extra =
|
2513
|
-
PG_ENCODING_SET_NOCHECK( extra,
|
2420
|
+
extra = rb_str_new2( pnotification->extra );
|
2421
|
+
PG_ENCODING_SET_NOCHECK( extra, this->enc_idx );
|
2514
2422
|
}
|
2515
2423
|
PQfreemem( pnotification );
|
2516
2424
|
|
@@ -2570,7 +2478,7 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2570
2478
|
|
2571
2479
|
if( p_coder ){
|
2572
2480
|
t_pg_coder_enc_func enc_func;
|
2573
|
-
int enc_idx =
|
2481
|
+
int enc_idx = this->enc_idx;
|
2574
2482
|
|
2575
2483
|
enc_func = pg_coder_enc_func( p_coder );
|
2576
2484
|
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
@@ -2620,16 +2528,16 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2620
2528
|
VALUE error;
|
2621
2529
|
int ret;
|
2622
2530
|
const char *error_message = NULL;
|
2623
|
-
|
2531
|
+
t_pg_connection *this = pg_get_connection_safe( self );
|
2624
2532
|
|
2625
2533
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2626
2534
|
error_message = NULL;
|
2627
2535
|
else
|
2628
|
-
error_message = pg_cstr_enc(str,
|
2536
|
+
error_message = pg_cstr_enc(str, this->enc_idx);
|
2629
2537
|
|
2630
|
-
ret = gvl_PQputCopyEnd(
|
2538
|
+
ret = gvl_PQputCopyEnd(this->pgconn, error_message);
|
2631
2539
|
if(ret == -1) {
|
2632
|
-
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(
|
2540
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
|
2633
2541
|
rb_iv_set(error, "@connection", self);
|
2634
2542
|
rb_exc_raise(error);
|
2635
2543
|
}
|
@@ -2695,9 +2603,9 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2695
2603
|
|
2696
2604
|
if( p_coder ){
|
2697
2605
|
t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, p_coder->format );
|
2698
|
-
result = dec_func( p_coder, buffer, ret, 0, 0,
|
2606
|
+
result = dec_func( p_coder, buffer, ret, 0, 0, this->enc_idx );
|
2699
2607
|
} else {
|
2700
|
-
result =
|
2608
|
+
result = rb_str_new(buffer, ret);
|
2701
2609
|
}
|
2702
2610
|
|
2703
2611
|
PQfreemem(buffer);
|
@@ -2710,9 +2618,16 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2710
2618
|
*
|
2711
2619
|
* Sets connection's verbosity to _verbosity_ and returns
|
2712
2620
|
* the previous setting. Available settings are:
|
2621
|
+
*
|
2713
2622
|
* * PQERRORS_TERSE
|
2714
2623
|
* * PQERRORS_DEFAULT
|
2715
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].
|
2716
2631
|
*/
|
2717
2632
|
static VALUE
|
2718
2633
|
pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
@@ -2722,6 +2637,37 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
|
|
2722
2637
|
return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
|
2723
2638
|
}
|
2724
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
|
+
|
2725
2671
|
/*
|
2726
2672
|
* call-seq:
|
2727
2673
|
* conn.trace( stream ) -> nil
|
@@ -2740,7 +2686,7 @@ pgconn_trace(VALUE self, VALUE stream)
|
|
2740
2686
|
VALUE new_file;
|
2741
2687
|
t_pg_connection *this = pg_get_connection_safe( self );
|
2742
2688
|
|
2743
|
-
if(rb_respond_to(stream,rb_intern("fileno"))
|
2689
|
+
if(!rb_respond_to(stream,rb_intern("fileno")))
|
2744
2690
|
rb_raise(rb_eArgError, "stream does not respond to method: fileno");
|
2745
2691
|
|
2746
2692
|
fileno = rb_funcall(stream, rb_intern("fileno"), 0);
|
@@ -2873,8 +2819,8 @@ notice_processor_proxy(void *arg, const char *message)
|
|
2873
2819
|
t_pg_connection *this = pg_get_connection( self );
|
2874
2820
|
|
2875
2821
|
if (this->notice_receiver != Qnil) {
|
2876
|
-
VALUE message_str =
|
2877
|
-
PG_ENCODING_SET_NOCHECK( message_str,
|
2822
|
+
VALUE message_str = rb_str_new2(message);
|
2823
|
+
PG_ENCODING_SET_NOCHECK( message_str, this->enc_idx );
|
2878
2824
|
rb_funcall(this->notice_receiver, rb_intern("call"), 1, message_str);
|
2879
2825
|
}
|
2880
2826
|
return;
|
@@ -2932,7 +2878,7 @@ static VALUE
|
|
2932
2878
|
pgconn_get_client_encoding(VALUE self)
|
2933
2879
|
{
|
2934
2880
|
char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self)));
|
2935
|
-
return
|
2881
|
+
return rb_str_new2(encoding);
|
2936
2882
|
}
|
2937
2883
|
|
2938
2884
|
|
@@ -3044,14 +2990,12 @@ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
|
3044
2990
|
int enc_idx;
|
3045
2991
|
|
3046
2992
|
if( rb_obj_is_kind_of(self, rb_cPGconn) ){
|
3047
|
-
enc_idx =
|
2993
|
+
enc_idx = pg_get_connection(self)->enc_idx;
|
3048
2994
|
}else{
|
3049
2995
|
enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
|
3050
2996
|
}
|
3051
2997
|
pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
|
3052
2998
|
|
3053
|
-
OBJ_INFECT(ret, str_or_array);
|
3054
|
-
|
3055
2999
|
return ret;
|
3056
3000
|
}
|
3057
3001
|
|
@@ -3078,7 +3022,7 @@ get_result_readable(PGconn *conn)
|
|
3078
3022
|
*/
|
3079
3023
|
static VALUE
|
3080
3024
|
pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
3081
|
-
|
3025
|
+
PGconn *conn = pg_get_pgconn( self );
|
3082
3026
|
|
3083
3027
|
struct timeval timeout;
|
3084
3028
|
struct timeval *ptimeout = NULL;
|
@@ -3093,7 +3037,7 @@ pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
|
3093
3037
|
ptimeout = &timeout;
|
3094
3038
|
}
|
3095
3039
|
|
3096
|
-
ret = wait_socket_readable(
|
3040
|
+
ret = wait_socket_readable( conn, ptimeout, get_result_readable);
|
3097
3041
|
|
3098
3042
|
if( !ret )
|
3099
3043
|
return Qfalse;
|
@@ -3176,19 +3120,30 @@ pgconn_discard_results(VALUE self)
|
|
3176
3120
|
|
3177
3121
|
/*
|
3178
3122
|
* call-seq:
|
3179
|
-
* conn.
|
3180
|
-
* conn.
|
3123
|
+
* conn.exec(sql) -> PG::Result
|
3124
|
+
* conn.exec(sql) {|pg_result| block }
|
3181
3125
|
*
|
3182
|
-
*
|
3183
|
-
*
|
3184
|
-
*
|
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.
|
3185
3129
|
*
|
3186
|
-
*
|
3187
|
-
*
|
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.
|
3188
3133
|
*
|
3189
|
-
*
|
3190
|
-
*
|
3191
|
-
*
|
3134
|
+
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
3135
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
3136
|
+
* In this instance, <code>conn.exec</code> returns the value of the block.
|
3137
|
+
*
|
3138
|
+
* #exec is an alias for #async_exec which is almost identical to #sync_exec .
|
3139
|
+
* #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
|
3140
|
+
* #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
|
3141
|
+
* Both methods ensure that other threads can process while waiting for the server to
|
3142
|
+
* complete the request, but #sync_exec blocks all signals to be processed until the query is finished.
|
3143
|
+
* This is most notably visible by a delayed reaction to Control+C.
|
3144
|
+
* It's not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.
|
3145
|
+
*
|
3146
|
+
* See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQEXEC].
|
3192
3147
|
*/
|
3193
3148
|
static VALUE
|
3194
3149
|
pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
@@ -3209,11 +3164,53 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3209
3164
|
|
3210
3165
|
/*
|
3211
3166
|
* call-seq:
|
3212
|
-
* conn.
|
3213
|
-
* 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 }
|
3214
3169
|
*
|
3215
|
-
*
|
3216
|
-
*
|
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].
|
3217
3214
|
*/
|
3218
3215
|
static VALUE
|
3219
3216
|
pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
@@ -3223,7 +3220,7 @@ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
|
3223
3220
|
pgconn_discard_results( self );
|
3224
3221
|
/* If called with no or nil parameters, use PQsendQuery for compatibility */
|
3225
3222
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
3226
|
-
pg_deprecated(("forwarding async_exec_params to async_exec is deprecated"));
|
3223
|
+
pg_deprecated(3, ("forwarding async_exec_params to async_exec is deprecated"));
|
3227
3224
|
pgconn_send_query( argc, argv, self );
|
3228
3225
|
} else {
|
3229
3226
|
pgconn_send_query_params( argc, argv, self );
|
@@ -3240,10 +3237,25 @@ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
|
3240
3237
|
|
3241
3238
|
/*
|
3242
3239
|
* call-seq:
|
3243
|
-
* conn.
|
3240
|
+
* conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
3244
3241
|
*
|
3245
|
-
*
|
3246
|
-
*
|
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].
|
3247
3259
|
*/
|
3248
3260
|
static VALUE
|
3249
3261
|
pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
@@ -3264,11 +3276,40 @@ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
|
|
3264
3276
|
|
3265
3277
|
/*
|
3266
3278
|
* call-seq:
|
3267
|
-
* conn.
|
3268
|
-
* 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 }
|
3269
3281
|
*
|
3270
|
-
*
|
3271
|
-
*
|
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].
|
3272
3313
|
*/
|
3273
3314
|
static VALUE
|
3274
3315
|
pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
@@ -3289,10 +3330,11 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
3289
3330
|
|
3290
3331
|
/*
|
3291
3332
|
* call-seq:
|
3292
|
-
* conn.
|
3333
|
+
* conn.describe_portal( portal_name ) -> PG::Result
|
3293
3334
|
*
|
3294
|
-
*
|
3295
|
-
*
|
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].
|
3296
3338
|
*/
|
3297
3339
|
static VALUE
|
3298
3340
|
pgconn_async_describe_portal(VALUE self, VALUE portal)
|
@@ -3313,10 +3355,11 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
|
|
3313
3355
|
|
3314
3356
|
/*
|
3315
3357
|
* call-seq:
|
3316
|
-
* conn.
|
3358
|
+
* conn.describe_prepared( statement_name ) -> PG::Result
|
3317
3359
|
*
|
3318
|
-
*
|
3319
|
-
*
|
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].
|
3320
3363
|
*/
|
3321
3364
|
static VALUE
|
3322
3365
|
pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
@@ -3340,7 +3383,7 @@ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
|
|
3340
3383
|
* call-seq:
|
3341
3384
|
* conn.ssl_in_use? -> Boolean
|
3342
3385
|
*
|
3343
|
-
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3386
|
+
* Returns +true+ if the connection uses SSL/TLS, +false+ if not.
|
3344
3387
|
*
|
3345
3388
|
* Available since PostgreSQL-9.5
|
3346
3389
|
*/
|
@@ -3374,7 +3417,7 @@ pgconn_ssl_in_use(VALUE self)
|
|
3374
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".
|
3375
3418
|
*
|
3376
3419
|
*
|
3377
|
-
* 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].
|
3378
3421
|
*
|
3379
3422
|
* Available since PostgreSQL-9.5
|
3380
3423
|
*/
|
@@ -3602,7 +3645,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3602
3645
|
return Qnil;
|
3603
3646
|
}
|
3604
3647
|
|
3605
|
-
str =
|
3648
|
+
str = rb_str_new(buffer, ret);
|
3606
3649
|
xfree(buffer);
|
3607
3650
|
|
3608
3651
|
return str;
|
@@ -3706,12 +3749,15 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3706
3749
|
}
|
3707
3750
|
|
3708
3751
|
|
3709
|
-
void
|
3752
|
+
static void
|
3710
3753
|
pgconn_set_internal_encoding_index( VALUE self )
|
3711
3754
|
{
|
3712
|
-
|
3713
|
-
|
3714
|
-
|
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;
|
3715
3761
|
}
|
3716
3762
|
|
3717
3763
|
/*
|
@@ -3754,7 +3800,6 @@ static VALUE pgconn_external_encoding(VALUE self);
|
|
3754
3800
|
static VALUE
|
3755
3801
|
pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
3756
3802
|
{
|
3757
|
-
VALUE enc_inspect;
|
3758
3803
|
if (NIL_P(enc)) {
|
3759
3804
|
pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
|
3760
3805
|
return enc;
|
@@ -3775,11 +3820,6 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3775
3820
|
pgconn_set_internal_encoding_index( self );
|
3776
3821
|
return enc;
|
3777
3822
|
}
|
3778
|
-
|
3779
|
-
enc_inspect = rb_inspect(enc);
|
3780
|
-
rb_raise( rb_ePGerror, "unknown encoding: %s", StringValueCStr(enc_inspect) );
|
3781
|
-
|
3782
|
-
return Qnil;
|
3783
3823
|
}
|
3784
3824
|
|
3785
3825
|
|
@@ -3798,14 +3838,9 @@ pgconn_external_encoding(VALUE self)
|
|
3798
3838
|
rb_encoding *enc = NULL;
|
3799
3839
|
const char *pg_encname = NULL;
|
3800
3840
|
|
3801
|
-
/* Use cached value if found */
|
3802
|
-
if ( RTEST(this->external_encoding) ) return this->external_encoding;
|
3803
|
-
|
3804
3841
|
pg_encname = PQparameterStatus( this->pgconn, "server_encoding" );
|
3805
3842
|
enc = pg_get_pg_encname_as_rb_encoding( pg_encname );
|
3806
|
-
|
3807
|
-
|
3808
|
-
return this->external_encoding;
|
3843
|
+
return rb_enc_from_encoding( enc );
|
3809
3844
|
}
|
3810
3845
|
|
3811
3846
|
|
@@ -3823,9 +3858,10 @@ pgconn_set_client_encoding_async1( VALUE args )
|
|
3823
3858
|
|
3824
3859
|
|
3825
3860
|
static VALUE
|
3826
|
-
pgconn_set_client_encoding_async2( VALUE arg )
|
3861
|
+
pgconn_set_client_encoding_async2( VALUE arg, VALUE ex )
|
3827
3862
|
{
|
3828
3863
|
UNUSED(arg);
|
3864
|
+
UNUSED(ex);
|
3829
3865
|
return 1;
|
3830
3866
|
}
|
3831
3867
|
|
@@ -4047,16 +4083,54 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
4047
4083
|
|
4048
4084
|
/*
|
4049
4085
|
* call-seq:
|
4050
|
-
*
|
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=
|
4051
4098
|
*
|
4052
|
-
* This method is for testing only and will probably be removed in the future.
|
4053
4099
|
*/
|
4054
4100
|
static VALUE
|
4055
|
-
|
4101
|
+
pgconn_field_name_type_set(VALUE self, VALUE sym)
|
4056
4102
|
{
|
4057
4103
|
t_pg_connection *this = pg_get_connection( self );
|
4058
|
-
|
4059
|
-
|
4104
|
+
|
4105
|
+
this->flags &= ~PG_RESULT_FIELD_NAMES_MASK;
|
4106
|
+
if( sym == sym_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_SYMBOL;
|
4107
|
+
else if ( sym == sym_static_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_STATIC_SYMBOL;
|
4108
|
+
else if ( sym == sym_string );
|
4109
|
+
else rb_raise(rb_eArgError, "invalid argument %+"PRIsVALUE, sym);
|
4110
|
+
|
4111
|
+
return sym;
|
4112
|
+
}
|
4113
|
+
|
4114
|
+
/*
|
4115
|
+
* call-seq:
|
4116
|
+
* conn.field_name_type -> Symbol
|
4117
|
+
*
|
4118
|
+
* Get type of field names.
|
4119
|
+
*
|
4120
|
+
* See description at #field_name_type=
|
4121
|
+
*/
|
4122
|
+
static VALUE
|
4123
|
+
pgconn_field_name_type_get(VALUE self)
|
4124
|
+
{
|
4125
|
+
t_pg_connection *this = pg_get_connection( self );
|
4126
|
+
|
4127
|
+
if( this->flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
|
4128
|
+
return sym_symbol;
|
4129
|
+
} else if( this->flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
|
4130
|
+
return sym_static_symbol;
|
4131
|
+
} else {
|
4132
|
+
return sym_string;
|
4133
|
+
}
|
4060
4134
|
}
|
4061
4135
|
|
4062
4136
|
|
@@ -4070,8 +4144,13 @@ init_pg_connection()
|
|
4070
4144
|
sym_type = ID2SYM(rb_intern("type"));
|
4071
4145
|
sym_format = ID2SYM(rb_intern("format"));
|
4072
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"));
|
4073
4150
|
|
4074
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" ); */
|
4075
4154
|
rb_include_module(rb_cPGconn, rb_mPGconstants);
|
4076
4155
|
|
4077
4156
|
/****** PG::Connection CLASS METHODS ******/
|
@@ -4132,6 +4211,22 @@ init_pg_connection()
|
|
4132
4211
|
rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
|
4133
4212
|
rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
|
4134
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
|
+
|
4135
4230
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
4136
4231
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
4137
4232
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
@@ -4144,17 +4239,10 @@ init_pg_connection()
|
|
4144
4239
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
4145
4240
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
4146
4241
|
rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
|
4147
|
-
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
4148
|
-
rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
|
4149
|
-
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
4150
4242
|
rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
|
4151
|
-
rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
|
4152
4243
|
rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
|
4153
|
-
rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
|
4154
4244
|
rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
|
4155
|
-
rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
|
4156
4245
|
rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
|
4157
|
-
rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
|
4158
4246
|
rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
|
4159
4247
|
rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
|
4160
4248
|
rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
|
@@ -4177,9 +4265,11 @@ init_pg_connection()
|
|
4177
4265
|
|
4178
4266
|
/****** PG::Connection INSTANCE METHODS: Control Functions ******/
|
4179
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
|
4180
4271
|
rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
|
4181
4272
|
rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
|
4182
|
-
rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
|
4183
4273
|
|
4184
4274
|
/****** PG::Connection INSTANCE METHODS: Notice Processing ******/
|
4185
4275
|
rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
|
@@ -4246,5 +4336,7 @@ init_pg_connection()
|
|
4246
4336
|
rb_define_method(rb_cPGconn, "encoder_for_put_copy_data", pgconn_encoder_for_put_copy_data_get, 0);
|
4247
4337
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data=", pgconn_decoder_for_get_copy_data_set, 1);
|
4248
4338
|
rb_define_method(rb_cPGconn, "decoder_for_get_copy_data", pgconn_decoder_for_get_copy_data_get, 0);
|
4249
|
-
}
|
4250
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
|
+
}
|