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