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