pg 0.18.4 → 1.0.0
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/BSDL +2 -2
- data/ChangeLog +689 -5
- data/History.rdoc +84 -0
- data/Manifest.txt +0 -18
- data/README.rdoc +13 -10
- data/Rakefile +16 -19
- data/Rakefile.cross +21 -24
- data/ext/errorcodes.def +33 -0
- data/ext/errorcodes.txt +15 -1
- data/ext/extconf.rb +21 -33
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +27 -39
- data/ext/pg.c +18 -50
- data/ext/pg.h +13 -80
- data/ext/pg_binary_encoder.c +8 -8
- data/ext/pg_coder.c +31 -10
- data/ext/pg_connection.c +340 -225
- data/ext/pg_copy_coder.c +34 -4
- data/ext/pg_result.c +24 -22
- data/ext/pg_text_encoder.c +62 -42
- data/ext/pg_type_map.c +14 -7
- data/lib/pg/basic_type_mapping.rb +35 -8
- data/lib/pg/connection.rb +53 -12
- data/lib/pg/result.rb +10 -5
- data/lib/pg/text_decoder.rb +7 -0
- data/lib/pg/text_encoder.rb +8 -0
- data/lib/pg.rb +18 -10
- data/spec/helpers.rb +8 -15
- data/spec/pg/basic_type_mapping_spec.rb +54 -0
- data/spec/pg/connection_spec.rb +384 -209
- data/spec/pg/result_spec.rb +14 -7
- data/spec/pg/type_map_by_class_spec.rb +2 -2
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_spec.rb +83 -3
- data/spec/pg_spec.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +55 -64
- metadata.gz.sig +0 -0
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -186
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -294
- data/sample/replication_monitor.rb +0 -231
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -320
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id: pg_connection.c,v
|
3
|
+
* $Id: pg_connection.c,v 1f0926bfa9a5 2018/01/04 18:14:32 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -18,19 +18,8 @@ static PQnoticeReceiver default_notice_receiver = NULL;
|
|
18
18
|
static PQnoticeProcessor default_notice_processor = NULL;
|
19
19
|
|
20
20
|
static VALUE pgconn_finish( VALUE );
|
21
|
-
#ifdef M17N_SUPPORTED
|
22
21
|
static VALUE pgconn_set_default_encoding( VALUE self );
|
23
22
|
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
|
34
23
|
|
35
24
|
/*
|
36
25
|
* Global functions
|
@@ -52,7 +41,7 @@ pg_get_connection( VALUE self )
|
|
52
41
|
* Fetch the PG::Connection object data pointer and check it's
|
53
42
|
* PGconn data pointer for sanity.
|
54
43
|
*/
|
55
|
-
t_pg_connection *
|
44
|
+
static t_pg_connection *
|
56
45
|
pg_get_connection_safe( VALUE self )
|
57
46
|
{
|
58
47
|
t_pg_connection *this;
|
@@ -88,14 +77,14 @@ pg_get_pgconn( VALUE self )
|
|
88
77
|
/*
|
89
78
|
* Close the associated socket IO object if there is one.
|
90
79
|
*/
|
91
|
-
void
|
80
|
+
static void
|
92
81
|
pgconn_close_socket_io( VALUE self )
|
93
82
|
{
|
94
83
|
t_pg_connection *this = pg_get_connection( self );
|
95
84
|
VALUE socket_io = this->socket_io;
|
96
85
|
|
97
86
|
if ( RTEST(socket_io) ) {
|
98
|
-
#if defined(_WIN32)
|
87
|
+
#if defined(_WIN32)
|
99
88
|
int ruby_sd = NUM2INT(rb_funcall( socket_io, rb_intern("fileno"), 0 ));
|
100
89
|
if( rb_w32_unwrap_io_handle(ruby_sd) ){
|
101
90
|
rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
|
@@ -141,6 +130,16 @@ pgconn_make_conninfo_array( const PQconninfoOption *options )
|
|
141
130
|
return ary;
|
142
131
|
}
|
143
132
|
|
133
|
+
static const char *pg_cstr_enc(VALUE str, int enc_idx){
|
134
|
+
const char *ptr = StringValueCStr(str);
|
135
|
+
if( ENCODING_GET(str) == enc_idx ){
|
136
|
+
return ptr;
|
137
|
+
} else {
|
138
|
+
str = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
|
139
|
+
return StringValueCStr(str);
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
144
143
|
|
145
144
|
/*
|
146
145
|
* GC Mark function
|
@@ -281,9 +280,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
281
280
|
rb_exc_raise(error);
|
282
281
|
}
|
283
282
|
|
284
|
-
#ifdef M17N_SUPPORTED
|
285
283
|
pgconn_set_default_encoding( self );
|
286
|
-
#endif
|
287
284
|
|
288
285
|
if (rb_block_given_p()) {
|
289
286
|
return rb_ensure(rb_yield, self, pgconn_finish, self);
|
@@ -339,12 +336,11 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
339
336
|
return rb_conn;
|
340
337
|
}
|
341
338
|
|
342
|
-
#ifdef HAVE_PQPING
|
343
339
|
/*
|
344
340
|
* call-seq:
|
345
|
-
* PG::Connection.ping(connection_hash) ->
|
346
|
-
* PG::Connection.ping(connection_string) ->
|
347
|
-
* PG::Connection.ping(host, port, options, tty, dbname, login, password) ->
|
341
|
+
* PG::Connection.ping(connection_hash) -> Integer
|
342
|
+
* PG::Connection.ping(connection_string) -> Integer
|
343
|
+
* PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
|
348
344
|
*
|
349
345
|
* Check server status.
|
350
346
|
*
|
@@ -357,6 +353,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
357
353
|
* could not establish connection
|
358
354
|
* [+PQPING_NO_ATTEMPT+]
|
359
355
|
* connection not attempted (bad params)
|
356
|
+
*
|
357
|
+
* Available since PostgreSQL-9.1
|
360
358
|
*/
|
361
359
|
static VALUE
|
362
360
|
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
@@ -369,11 +367,10 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
|
369
367
|
|
370
368
|
return INT2FIX((int)ping);
|
371
369
|
}
|
372
|
-
#endif
|
373
370
|
|
374
371
|
|
375
372
|
/*
|
376
|
-
* Document-method: conndefaults
|
373
|
+
* Document-method: PG::Connection.conndefaults
|
377
374
|
*
|
378
375
|
* call-seq:
|
379
376
|
* PG::Connection.conndefaults() -> Array
|
@@ -408,16 +405,65 @@ pgconn_s_conndefaults(VALUE self)
|
|
408
405
|
}
|
409
406
|
|
410
407
|
|
408
|
+
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
411
409
|
/*
|
412
410
|
* call-seq:
|
413
|
-
*
|
411
|
+
* conn.encrypt_password( password, username, algorithm=nil ) -> String
|
414
412
|
*
|
415
|
-
* This function is intended to be used by client applications that
|
416
|
-
* send
|
417
|
-
*
|
418
|
-
*
|
413
|
+
* This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
|
414
|
+
* 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.
|
415
|
+
* Instead, use this function to convert the password to encrypted form before it is sent.
|
416
|
+
*
|
417
|
+
* The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
|
418
|
+
* +algorithm+ specifies the encryption algorithm to use to encrypt the password.
|
419
|
+
* 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).
|
420
|
+
* Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
|
421
|
+
* If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
|
422
|
+
* That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
|
423
|
+
* 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.
|
419
424
|
*
|
420
425
|
* Return value is the encrypted password.
|
426
|
+
* The caller can assume the string doesn't contain any special characters that would require escaping.
|
427
|
+
*
|
428
|
+
* Available since PostgreSQL-10
|
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
|
+
|
448
|
+
OBJ_INFECT( rval, password );
|
449
|
+
OBJ_INFECT( rval, username );
|
450
|
+
OBJ_INFECT( rval, algorithm );
|
451
|
+
} else {
|
452
|
+
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
453
|
+
}
|
454
|
+
|
455
|
+
return rval;
|
456
|
+
}
|
457
|
+
#endif
|
458
|
+
|
459
|
+
|
460
|
+
/*
|
461
|
+
* call-seq:
|
462
|
+
* PG::Connection.encrypt_password( password, username ) -> String
|
463
|
+
*
|
464
|
+
* This is an older, deprecated version of #encrypt_password.
|
465
|
+
* The difference is that this function always uses +md5+ as the encryption algorithm.
|
466
|
+
*
|
421
467
|
*/
|
422
468
|
static VALUE
|
423
469
|
pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
@@ -447,7 +493,7 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
447
493
|
|
448
494
|
/*
|
449
495
|
* call-seq:
|
450
|
-
* conn.connect_poll() ->
|
496
|
+
* conn.connect_poll() -> Integer
|
451
497
|
*
|
452
498
|
* Returns one of:
|
453
499
|
* [+PGRES_POLLING_READING+]
|
@@ -556,7 +602,7 @@ pgconn_reset_start(VALUE self)
|
|
556
602
|
|
557
603
|
/*
|
558
604
|
* call-seq:
|
559
|
-
* conn.reset_poll ->
|
605
|
+
* conn.reset_poll -> Integer
|
560
606
|
*
|
561
607
|
* Checks the status of a connection reset operation.
|
562
608
|
* See #connect_start and #connect_poll for
|
@@ -603,7 +649,7 @@ pgconn_user(VALUE self)
|
|
603
649
|
* call-seq:
|
604
650
|
* conn.pass()
|
605
651
|
*
|
606
|
-
* Returns the authenticated
|
652
|
+
* Returns the authenticated password.
|
607
653
|
*/
|
608
654
|
static VALUE
|
609
655
|
pgconn_pass(VALUE self)
|
@@ -676,6 +722,7 @@ pgconn_options(VALUE self)
|
|
676
722
|
*
|
677
723
|
* Returns the connection options used by a live connection.
|
678
724
|
*
|
725
|
+
* Available since PostgreSQL-9.3
|
679
726
|
*/
|
680
727
|
static VALUE
|
681
728
|
pgconn_conninfo( VALUE self )
|
@@ -795,7 +842,9 @@ pgconn_error_message(VALUE self)
|
|
795
842
|
|
796
843
|
/*
|
797
844
|
* call-seq:
|
798
|
-
* conn.socket() ->
|
845
|
+
* conn.socket() -> Integer
|
846
|
+
*
|
847
|
+
* This method is deprecated. Please use the more portable method #socket_io .
|
799
848
|
*
|
800
849
|
* Returns the socket's file descriptor for this connection.
|
801
850
|
* <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
|
@@ -805,7 +854,7 @@ pgconn_error_message(VALUE self)
|
|
805
854
|
* creates an IO that's associated with the connection object itself,
|
806
855
|
* and so won't go out of scope until the connection does.
|
807
856
|
*
|
808
|
-
* *Note:* On Windows the file descriptor is not
|
857
|
+
* *Note:* On Windows the file descriptor is not usable,
|
809
858
|
* since it can not be used to build a Ruby IO object.
|
810
859
|
*/
|
811
860
|
static VALUE
|
@@ -817,22 +866,17 @@ pgconn_socket(VALUE self)
|
|
817
866
|
return INT2NUM(sd);
|
818
867
|
}
|
819
868
|
|
820
|
-
|
821
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
822
|
-
|
823
869
|
/*
|
824
870
|
* call-seq:
|
825
871
|
* conn.socket_io() -> IO
|
826
872
|
*
|
827
|
-
* Fetch a
|
873
|
+
* Fetch a memorized IO object created from the Connection's underlying socket.
|
828
874
|
* This object can be used for IO.select to wait for events while running
|
829
875
|
* asynchronous API calls.
|
830
876
|
*
|
831
877
|
* Using this instead of #socket avoids the problem of the underlying connection
|
832
878
|
* being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt>
|
833
|
-
* goes out of scope.
|
834
|
-
*
|
835
|
-
* This method can also be used on Windows but requires Ruby-2.0+.
|
879
|
+
* goes out of scope. In contrast to #socket, it also works on Windows.
|
836
880
|
*/
|
837
881
|
static VALUE
|
838
882
|
pgconn_socket_io(VALUE self)
|
@@ -866,11 +910,9 @@ pgconn_socket_io(VALUE self)
|
|
866
910
|
return socket_io;
|
867
911
|
}
|
868
912
|
|
869
|
-
#endif
|
870
|
-
|
871
913
|
/*
|
872
914
|
* call-seq:
|
873
|
-
* conn.backend_pid() ->
|
915
|
+
* conn.backend_pid() -> Integer
|
874
916
|
*
|
875
917
|
* Returns the process ID of the backend server
|
876
918
|
* process for this connection.
|
@@ -947,9 +989,9 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
947
989
|
|
948
990
|
/* If called with no parameters, use PQexec */
|
949
991
|
if ( argc == 1 ) {
|
950
|
-
|
992
|
+
VALUE query_str = argv[0];
|
951
993
|
|
952
|
-
result = gvl_PQexec(conn,
|
994
|
+
result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
|
953
995
|
rb_pgresult = pg_new_result(result, self);
|
954
996
|
pg_result_check(rb_pgresult);
|
955
997
|
if (rb_block_given_p()) {
|
@@ -978,6 +1020,10 @@ struct query_params_data {
|
|
978
1020
|
* Filled by caller
|
979
1021
|
*/
|
980
1022
|
|
1023
|
+
/* The character encoding index of the connection. Any strings
|
1024
|
+
* given as query parameters are converted to this encoding.
|
1025
|
+
*/
|
1026
|
+
int enc_idx;
|
981
1027
|
/* Is the query function to execute one with types array? */
|
982
1028
|
int with_types;
|
983
1029
|
/* Array of query params from user space */
|
@@ -1138,7 +1184,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1138
1184
|
VALUE intermediate;
|
1139
1185
|
|
1140
1186
|
/* 1st pass for retiving the required memory space */
|
1141
|
-
int len = enc_func(conv, param_value, NULL, &intermediate);
|
1187
|
+
int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
|
1142
1188
|
|
1143
1189
|
if( len == -1 ){
|
1144
1190
|
/* The intermediate value is a String that can be used directly. */
|
@@ -1162,7 +1208,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1162
1208
|
}
|
1163
1209
|
|
1164
1210
|
/* 2nd pass for writing the data to prepared buffer */
|
1165
|
-
len = enc_func(conv, param_value, typecast_buf, &intermediate);
|
1211
|
+
len = enc_func(conv, param_value, typecast_buf, &intermediate, paramsData->enc_idx);
|
1166
1212
|
paramsData->values[i] = typecast_buf;
|
1167
1213
|
if( paramsData->formats[i] == 0 ){
|
1168
1214
|
/* text format strings must be zero terminated and lengths are ignored */
|
@@ -1220,8 +1266,8 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1220
1266
|
* Each element of the +params+ array may be either:
|
1221
1267
|
* a hash of the form:
|
1222
1268
|
* {:value => String (value of bind parameter)
|
1223
|
-
* :type =>
|
1224
|
-
* :format =>
|
1269
|
+
* :type => Integer (oid of type of bind parameter)
|
1270
|
+
* :format => Integer (0 for text, 1 for binary)
|
1225
1271
|
* }
|
1226
1272
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1227
1273
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1240,7 +1286,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1240
1286
|
* for binary.
|
1241
1287
|
*
|
1242
1288
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1243
|
-
* This will type cast the params
|
1289
|
+
* This will type cast the params from various Ruby types before transmission
|
1244
1290
|
* based on the encoders defined by the type map. When a type encoder is used
|
1245
1291
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1246
1292
|
* instead out of the hash form described above.
|
@@ -1258,7 +1304,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1258
1304
|
VALUE command, in_res_fmt;
|
1259
1305
|
int nParams;
|
1260
1306
|
int resultFormat;
|
1261
|
-
struct query_params_data paramsData;
|
1307
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1262
1308
|
|
1263
1309
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1264
1310
|
paramsData.with_types = 1;
|
@@ -1275,7 +1321,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1275
1321
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1276
1322
|
nParams = alloc_query_params( ¶msData );
|
1277
1323
|
|
1278
|
-
result = gvl_PQexecParams(conn,
|
1324
|
+
result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1279
1325
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1280
1326
|
|
1281
1327
|
free_query_params( ¶msData );
|
@@ -1321,10 +1367,13 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1321
1367
|
int i = 0;
|
1322
1368
|
int nParams = 0;
|
1323
1369
|
Oid *paramTypes = NULL;
|
1370
|
+
const char *name_cstr;
|
1371
|
+
const char *command_cstr;
|
1372
|
+
int enc_idx = ENCODING_GET(self);
|
1324
1373
|
|
1325
1374
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1326
|
-
|
1327
|
-
|
1375
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1376
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1328
1377
|
|
1329
1378
|
if(! NIL_P(in_paramtypes)) {
|
1330
1379
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1338,8 +1387,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1338
1387
|
paramTypes[i] = NUM2UINT(param);
|
1339
1388
|
}
|
1340
1389
|
}
|
1341
|
-
result = gvl_PQprepare(conn,
|
1342
|
-
nParams, paramTypes);
|
1390
|
+
result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1343
1391
|
|
1344
1392
|
xfree(paramTypes);
|
1345
1393
|
|
@@ -1361,7 +1409,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1361
1409
|
* SQL query. Each element of the +params+ array may be either:
|
1362
1410
|
* a hash of the form:
|
1363
1411
|
* {:value => String (value of bind parameter)
|
1364
|
-
* :format =>
|
1412
|
+
* :format => Integer (0 for text, 1 for binary)
|
1365
1413
|
* }
|
1366
1414
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1367
1415
|
* { :value => <string value>, :format => 0 }
|
@@ -1374,7 +1422,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1374
1422
|
* for binary.
|
1375
1423
|
*
|
1376
1424
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1377
|
-
* This will type cast the params
|
1425
|
+
* This will type cast the params from various Ruby types before transmission
|
1378
1426
|
* based on the encoders defined by the type map. When a type encoder is used
|
1379
1427
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1380
1428
|
* instead out of the hash form described above.
|
@@ -1392,11 +1440,10 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1392
1440
|
VALUE name, in_res_fmt;
|
1393
1441
|
int nParams;
|
1394
1442
|
int resultFormat;
|
1395
|
-
struct query_params_data paramsData;
|
1443
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1396
1444
|
|
1397
1445
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1398
1446
|
paramsData.with_types = 0;
|
1399
|
-
Check_Type(name, T_STRING);
|
1400
1447
|
|
1401
1448
|
if(NIL_P(paramsData.params)) {
|
1402
1449
|
paramsData.params = rb_ary_new2(0);
|
@@ -1406,7 +1453,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1406
1453
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1407
1454
|
nParams = alloc_query_params( ¶msData );
|
1408
1455
|
|
1409
|
-
result = gvl_PQexecPrepared(conn,
|
1456
|
+
result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1410
1457
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1411
1458
|
resultFormat);
|
1412
1459
|
|
@@ -1434,13 +1481,12 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1434
1481
|
PGresult *result;
|
1435
1482
|
VALUE rb_pgresult;
|
1436
1483
|
PGconn *conn = pg_get_pgconn(self);
|
1437
|
-
char *stmt;
|
1438
|
-
if(stmt_name
|
1484
|
+
const char *stmt;
|
1485
|
+
if(NIL_P(stmt_name)) {
|
1439
1486
|
stmt = NULL;
|
1440
1487
|
}
|
1441
1488
|
else {
|
1442
|
-
|
1443
|
-
stmt = StringValueCStr(stmt_name);
|
1489
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1444
1490
|
}
|
1445
1491
|
result = gvl_PQdescribePrepared(conn, stmt);
|
1446
1492
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1462,13 +1508,12 @@ pgconn_describe_portal(self, stmt_name)
|
|
1462
1508
|
PGresult *result;
|
1463
1509
|
VALUE rb_pgresult;
|
1464
1510
|
PGconn *conn = pg_get_pgconn(self);
|
1465
|
-
char *stmt;
|
1466
|
-
if(stmt_name
|
1511
|
+
const char *stmt;
|
1512
|
+
if(NIL_P(stmt_name)) {
|
1467
1513
|
stmt = NULL;
|
1468
1514
|
}
|
1469
1515
|
else {
|
1470
|
-
|
1471
|
-
stmt = StringValueCStr(stmt_name);
|
1516
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1472
1517
|
}
|
1473
1518
|
result = gvl_PQdescribePortal(conn, stmt);
|
1474
1519
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1510,10 +1555,6 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1510
1555
|
* call-seq:
|
1511
1556
|
* conn.escape_string( str ) -> String
|
1512
1557
|
*
|
1513
|
-
* Connection instance method for versions of 8.1 and higher of libpq
|
1514
|
-
* uses PQescapeStringConn, which is safer. Avoid calling as a class method,
|
1515
|
-
* the class method uses the deprecated PQescapeString() API function.
|
1516
|
-
*
|
1517
1558
|
* Returns a SQL-safe version of the String _str_.
|
1518
1559
|
* This is the preferred way to make strings safe for inclusion in
|
1519
1560
|
* SQL queries.
|
@@ -1522,32 +1563,41 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1522
1563
|
* inside of SQL commands.
|
1523
1564
|
*
|
1524
1565
|
* Encoding of escaped string will be equal to client encoding of connection.
|
1566
|
+
*
|
1567
|
+
* NOTE: This class version of this method can only be used safely in client
|
1568
|
+
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1569
|
+
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1570
|
+
* results if used in programs that use multiple database connections; use the
|
1571
|
+
* same method on the connection object in such cases.
|
1525
1572
|
*/
|
1526
1573
|
static VALUE
|
1527
1574
|
pgconn_s_escape(VALUE self, VALUE string)
|
1528
1575
|
{
|
1529
|
-
char *escaped;
|
1530
1576
|
size_t size;
|
1531
1577
|
int error;
|
1532
1578
|
VALUE result;
|
1579
|
+
int enc_idx;
|
1580
|
+
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1533
1581
|
|
1534
1582
|
Check_Type(string, T_STRING);
|
1583
|
+
enc_idx = ENCODING_GET( singleton ? string : self );
|
1584
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1585
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1586
|
+
}
|
1535
1587
|
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1588
|
+
result = rb_str_new(NULL, RSTRING_LEN(string) * 2 + 1);
|
1589
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1590
|
+
if( !singleton ) {
|
1591
|
+
size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
|
1539
1592
|
RSTRING_PTR(string), RSTRING_LEN(string), &error);
|
1540
1593
|
if(error) {
|
1541
|
-
xfree(escaped);
|
1542
1594
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
|
1543
1595
|
}
|
1544
1596
|
} else {
|
1545
|
-
size = PQescapeString(
|
1597
|
+
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1546
1598
|
}
|
1547
|
-
result
|
1548
|
-
xfree(escaped);
|
1599
|
+
rb_str_set_len(result, size);
|
1549
1600
|
OBJ_INFECT(result, string);
|
1550
|
-
PG_ENCODING_SET_NOCHECK(result, ENCODING_GET( rb_obj_is_kind_of(self, rb_cPGconn) ? self : string ));
|
1551
1601
|
|
1552
1602
|
return result;
|
1553
1603
|
}
|
@@ -1556,13 +1606,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1556
1606
|
* call-seq:
|
1557
1607
|
* conn.escape_bytea( string ) -> String
|
1558
1608
|
*
|
1559
|
-
* Connection instance method for versions of 8.1 and higher of libpq
|
1560
|
-
* uses PQescapeByteaConn, which is safer. Avoid calling as a class method,
|
1561
|
-
* the class method uses the deprecated PQescapeBytea() API function.
|
1562
|
-
*
|
1563
|
-
* Use the instance method version of this function, it is safer than the
|
1564
|
-
* class method.
|
1565
|
-
*
|
1566
1609
|
* Escapes binary data for use within an SQL command with the type +bytea+.
|
1567
1610
|
*
|
1568
1611
|
* Certain byte values must be escaped (but all byte values may be escaped)
|
@@ -1575,6 +1618,12 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1575
1618
|
*
|
1576
1619
|
* Consider using exec_params, which avoids the need for passing values inside of
|
1577
1620
|
* SQL commands.
|
1621
|
+
*
|
1622
|
+
* NOTE: This class version of this method can only be used safely in client
|
1623
|
+
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1624
|
+
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1625
|
+
* results if used in programs that use multiple database connections; use the
|
1626
|
+
* same method on the connection object in such cases.
|
1578
1627
|
*/
|
1579
1628
|
static VALUE
|
1580
1629
|
pgconn_s_escape_bytea(VALUE self, VALUE str)
|
@@ -1629,12 +1678,13 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1629
1678
|
return ret;
|
1630
1679
|
}
|
1631
1680
|
|
1632
|
-
#ifdef HAVE_PQESCAPELITERAL
|
1633
1681
|
/*
|
1634
1682
|
* call-seq:
|
1635
1683
|
* conn.escape_literal( str ) -> String
|
1636
1684
|
*
|
1637
1685
|
* Escape an arbitrary String +str+ as a literal.
|
1686
|
+
*
|
1687
|
+
* Available since PostgreSQL-9.0
|
1638
1688
|
*/
|
1639
1689
|
static VALUE
|
1640
1690
|
pgconn_escape_literal(VALUE self, VALUE string)
|
@@ -1643,8 +1693,12 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1643
1693
|
char *escaped = NULL;
|
1644
1694
|
VALUE error;
|
1645
1695
|
VALUE result = Qnil;
|
1696
|
+
int enc_idx = ENCODING_GET(self);
|
1646
1697
|
|
1647
1698
|
Check_Type(string, T_STRING);
|
1699
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1700
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1701
|
+
}
|
1648
1702
|
|
1649
1703
|
escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1650
1704
|
if (escaped == NULL)
|
@@ -1657,21 +1711,22 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1657
1711
|
result = rb_str_new2(escaped);
|
1658
1712
|
PQfreemem(escaped);
|
1659
1713
|
OBJ_INFECT(result, string);
|
1660
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1714
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1661
1715
|
|
1662
1716
|
return result;
|
1663
1717
|
}
|
1664
|
-
#endif
|
1665
1718
|
|
1666
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
1667
1719
|
/*
|
1668
1720
|
* call-seq:
|
1669
1721
|
* conn.escape_identifier( str ) -> String
|
1670
1722
|
*
|
1671
1723
|
* Escape an arbitrary String +str+ as an identifier.
|
1672
1724
|
*
|
1673
|
-
* This method does the same as #quote_ident
|
1674
|
-
*
|
1725
|
+
* This method does the same as #quote_ident with a String argument,
|
1726
|
+
* but it doesn't support an Array argument and it makes use of libpq
|
1727
|
+
* to process the string.
|
1728
|
+
*
|
1729
|
+
* Available since PostgreSQL-9.0
|
1675
1730
|
*/
|
1676
1731
|
static VALUE
|
1677
1732
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
@@ -1680,8 +1735,12 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1680
1735
|
char *escaped = NULL;
|
1681
1736
|
VALUE error;
|
1682
1737
|
VALUE result = Qnil;
|
1738
|
+
int enc_idx = ENCODING_GET(self);
|
1683
1739
|
|
1684
1740
|
Check_Type(string, T_STRING);
|
1741
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1742
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1743
|
+
}
|
1685
1744
|
|
1686
1745
|
escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1687
1746
|
if (escaped == NULL)
|
@@ -1694,13 +1753,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1694
1753
|
result = rb_str_new2(escaped);
|
1695
1754
|
PQfreemem(escaped);
|
1696
1755
|
OBJ_INFECT(result, string);
|
1697
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1756
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1698
1757
|
|
1699
1758
|
return result;
|
1700
1759
|
}
|
1701
|
-
#endif
|
1702
1760
|
|
1703
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
1704
1761
|
/*
|
1705
1762
|
* call-seq:
|
1706
1763
|
* conn.set_single_row_mode -> self
|
@@ -1737,6 +1794,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1737
1794
|
* end
|
1738
1795
|
* end
|
1739
1796
|
*
|
1797
|
+
* Available since PostgreSQL-9.2
|
1740
1798
|
*/
|
1741
1799
|
static VALUE
|
1742
1800
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1753,7 +1811,6 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1753
1811
|
|
1754
1812
|
return self;
|
1755
1813
|
}
|
1756
|
-
#endif
|
1757
1814
|
|
1758
1815
|
/*
|
1759
1816
|
* call-seq:
|
@@ -1767,8 +1824,8 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1767
1824
|
* Each element of the +params+ array may be either:
|
1768
1825
|
* a hash of the form:
|
1769
1826
|
* {:value => String (value of bind parameter)
|
1770
|
-
* :type =>
|
1771
|
-
* :format =>
|
1827
|
+
* :type => Integer (oid of type of bind parameter)
|
1828
|
+
* :format => Integer (0 for text, 1 for binary)
|
1772
1829
|
* }
|
1773
1830
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1774
1831
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1787,7 +1844,7 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1787
1844
|
* for binary.
|
1788
1845
|
*
|
1789
1846
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1790
|
-
* This will type cast the params
|
1847
|
+
* This will type cast the params from various Ruby types before transmission
|
1791
1848
|
* based on the encoders defined by the type map. When a type encoder is used
|
1792
1849
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1793
1850
|
* instead out of the hash form described above.
|
@@ -1802,15 +1859,14 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1802
1859
|
VALUE error;
|
1803
1860
|
int nParams;
|
1804
1861
|
int resultFormat;
|
1805
|
-
struct query_params_data paramsData;
|
1862
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1806
1863
|
|
1807
1864
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1808
1865
|
paramsData.with_types = 1;
|
1809
|
-
Check_Type(command, T_STRING);
|
1810
1866
|
|
1811
1867
|
/* If called with no parameters, use PQsendQuery */
|
1812
1868
|
if(NIL_P(paramsData.params)) {
|
1813
|
-
if(gvl_PQsendQuery(conn,
|
1869
|
+
if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
|
1814
1870
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1815
1871
|
rb_iv_set(error, "@connection", self);
|
1816
1872
|
rb_exc_raise(error);
|
@@ -1826,7 +1882,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1826
1882
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1827
1883
|
nParams = alloc_query_params( ¶msData );
|
1828
1884
|
|
1829
|
-
result = gvl_PQsendQueryParams(conn,
|
1885
|
+
result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1830
1886
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1831
1887
|
|
1832
1888
|
free_query_params( ¶msData );
|
@@ -1870,10 +1926,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1870
1926
|
int i = 0;
|
1871
1927
|
int nParams = 0;
|
1872
1928
|
Oid *paramTypes = NULL;
|
1929
|
+
const char *name_cstr;
|
1930
|
+
const char *command_cstr;
|
1931
|
+
int enc_idx = ENCODING_GET(self);
|
1873
1932
|
|
1874
1933
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1875
|
-
|
1876
|
-
|
1934
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1935
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1877
1936
|
|
1878
1937
|
if(! NIL_P(in_paramtypes)) {
|
1879
1938
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1887,8 +1946,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1887
1946
|
paramTypes[i] = NUM2UINT(param);
|
1888
1947
|
}
|
1889
1948
|
}
|
1890
|
-
result = gvl_PQsendPrepare(conn,
|
1891
|
-
nParams, paramTypes);
|
1949
|
+
result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1892
1950
|
|
1893
1951
|
xfree(paramTypes);
|
1894
1952
|
|
@@ -1913,7 +1971,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1913
1971
|
* SQL query. Each element of the +params+ array may be either:
|
1914
1972
|
* a hash of the form:
|
1915
1973
|
* {:value => String (value of bind parameter)
|
1916
|
-
* :format =>
|
1974
|
+
* :format => Integer (0 for text, 1 for binary)
|
1917
1975
|
* }
|
1918
1976
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1919
1977
|
* { :value => <string value>, :format => 0 }
|
@@ -1926,7 +1984,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1926
1984
|
* for binary.
|
1927
1985
|
*
|
1928
1986
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1929
|
-
* This will type cast the params
|
1987
|
+
* This will type cast the params from various Ruby types before transmission
|
1930
1988
|
* based on the encoders defined by the type map. When a type encoder is used
|
1931
1989
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1932
1990
|
* instead out of the hash form described above.
|
@@ -1941,11 +1999,10 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1941
1999
|
VALUE error;
|
1942
2000
|
int nParams;
|
1943
2001
|
int resultFormat;
|
1944
|
-
struct query_params_data paramsData;
|
2002
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1945
2003
|
|
1946
2004
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1947
2005
|
paramsData.with_types = 0;
|
1948
|
-
Check_Type(name, T_STRING);
|
1949
2006
|
|
1950
2007
|
if(NIL_P(paramsData.params)) {
|
1951
2008
|
paramsData.params = rb_ary_new2(0);
|
@@ -1956,7 +2013,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1956
2013
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1957
2014
|
nParams = alloc_query_params( ¶msData );
|
1958
2015
|
|
1959
|
-
result = gvl_PQsendQueryPrepared(conn,
|
2016
|
+
result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1960
2017
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1961
2018
|
resultFormat);
|
1962
2019
|
|
@@ -1983,7 +2040,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1983
2040
|
VALUE error;
|
1984
2041
|
PGconn *conn = pg_get_pgconn(self);
|
1985
2042
|
/* returns 0 on failure */
|
1986
|
-
if(gvl_PQsendDescribePrepared(conn,
|
2043
|
+
if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
|
1987
2044
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1988
2045
|
rb_iv_set(error, "@connection", self);
|
1989
2046
|
rb_exc_raise(error);
|
@@ -2005,7 +2062,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
2005
2062
|
VALUE error;
|
2006
2063
|
PGconn *conn = pg_get_pgconn(self);
|
2007
2064
|
/* returns 0 on failure */
|
2008
|
-
if(gvl_PQsendDescribePortal(conn,
|
2065
|
+
if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
|
2009
2066
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
2010
2067
|
rb_iv_set(error, "@connection", self);
|
2011
2068
|
rb_exc_raise(error);
|
@@ -2177,7 +2234,6 @@ pgconn_flush(self)
|
|
2177
2234
|
static VALUE
|
2178
2235
|
pgconn_cancel(VALUE self)
|
2179
2236
|
{
|
2180
|
-
#ifdef HAVE_PQGETCANCEL
|
2181
2237
|
char errbuf[256];
|
2182
2238
|
PGcancel *cancel;
|
2183
2239
|
VALUE retval;
|
@@ -2195,9 +2251,6 @@ pgconn_cancel(VALUE self)
|
|
2195
2251
|
|
2196
2252
|
PQfreeCancel(cancel);
|
2197
2253
|
return retval;
|
2198
|
-
#else
|
2199
|
-
rb_notimplement();
|
2200
|
-
#endif
|
2201
2254
|
}
|
2202
2255
|
|
2203
2256
|
|
@@ -2241,45 +2294,8 @@ pgconn_notifies(VALUE self)
|
|
2241
2294
|
return hash;
|
2242
2295
|
}
|
2243
2296
|
|
2244
|
-
/* Win32 + Ruby 1.8 */
|
2245
|
-
#if !defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
|
2246
|
-
|
2247
|
-
/*
|
2248
|
-
* Duplicate the sockets from libpq and create temporary CRT FDs
|
2249
|
-
*/
|
2250
|
-
void create_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2251
|
-
{
|
2252
|
-
int i;
|
2253
|
-
crt_set->fd_count = os_set->fd_count;
|
2254
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2255
|
-
WSAPROTOCOL_INFO wsa_pi;
|
2256
|
-
/* dupicate the SOCKET */
|
2257
|
-
int r = WSADuplicateSocket(os_set->fd_array[i], GetCurrentProcessId(), &wsa_pi);
|
2258
|
-
SOCKET s = WSASocket(wsa_pi.iAddressFamily, wsa_pi.iSocketType, wsa_pi.iProtocol, &wsa_pi, 0, 0);
|
2259
|
-
/* create the CRT fd so ruby can get back to the SOCKET */
|
2260
|
-
int fd = _open_osfhandle(s, O_RDWR|O_BINARY);
|
2261
|
-
os_set->fd_array[i] = s;
|
2262
|
-
crt_set->fd_array[i] = fd;
|
2263
|
-
}
|
2264
|
-
}
|
2265
|
-
|
2266
|
-
/*
|
2267
|
-
* Clean up the CRT FDs from create_crt_fd()
|
2268
|
-
*/
|
2269
|
-
void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2270
|
-
{
|
2271
|
-
int i;
|
2272
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2273
|
-
/* cleanup the CRT fd */
|
2274
|
-
_close(crt_set->fd_array[i]);
|
2275
|
-
/* cleanup the duplicated SOCKET */
|
2276
|
-
closesocket(os_set->fd_array[i]);
|
2277
|
-
}
|
2278
|
-
}
|
2279
|
-
#endif
|
2280
|
-
|
2281
2297
|
/* Win32 + Ruby 1.9+ */
|
2282
|
-
#if defined(
|
2298
|
+
#if defined( _WIN32 )
|
2283
2299
|
/*
|
2284
2300
|
* On Windows, use platform-specific strategies to wait for the socket
|
2285
2301
|
* instead of rb_thread_select().
|
@@ -2367,7 +2383,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2367
2383
|
|
2368
2384
|
#else
|
2369
2385
|
|
2370
|
-
/* non Win32
|
2386
|
+
/* non Win32 */
|
2371
2387
|
|
2372
2388
|
static void *
|
2373
2389
|
wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
|
@@ -2377,9 +2393,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2377
2393
|
void *retval;
|
2378
2394
|
rb_fdset_t sd_rset;
|
2379
2395
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2380
|
-
#ifdef _WIN32
|
2381
|
-
rb_fdset_t crt_sd_rset;
|
2382
|
-
#endif
|
2383
2396
|
|
2384
2397
|
if ( sd < 0 )
|
2385
2398
|
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
@@ -2399,14 +2412,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2399
2412
|
rb_fd_zero( &sd_rset );
|
2400
2413
|
rb_fd_set( sd, &sd_rset );
|
2401
2414
|
|
2402
|
-
#ifdef _WIN32
|
2403
|
-
/* Ruby's FD_SET is modified on win32 to convert a file descriptor
|
2404
|
-
* to osfhandle, but we already get a osfhandle from PQsocket().
|
2405
|
-
* Therefore it's overwritten here. */
|
2406
|
-
sd_rset.fd_array[0] = sd;
|
2407
|
-
create_crt_fd(&sd_rset, &crt_sd_rset);
|
2408
|
-
#endif
|
2409
|
-
|
2410
2415
|
if ( ptimeout ) {
|
2411
2416
|
gettimeofday(&currtime, NULL);
|
2412
2417
|
timersub(&aborttime, &currtime, &waittime);
|
@@ -2420,11 +2425,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2420
2425
|
ret = 0;
|
2421
2426
|
}
|
2422
2427
|
|
2423
|
-
|
2424
|
-
#ifdef _WIN32
|
2425
|
-
cleanup_crt_fd(&sd_rset, &crt_sd_rset);
|
2426
|
-
#endif
|
2427
|
-
|
2428
2428
|
if ( ret < 0 ){
|
2429
2429
|
rb_fd_term( &sd_rset );
|
2430
2430
|
rb_sys_fail( "rb_thread_select()" );
|
@@ -2502,12 +2502,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2502
2502
|
relname = rb_tainted_str_new2( pnotification->relname );
|
2503
2503
|
PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
|
2504
2504
|
be_pid = INT2NUM( pnotification->be_pid );
|
2505
|
-
#ifdef HAVE_ST_NOTIFY_EXTRA
|
2506
2505
|
if ( *pnotification->extra ) {
|
2507
2506
|
extra = rb_tainted_str_new2( pnotification->extra );
|
2508
2507
|
PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
|
2509
2508
|
}
|
2510
|
-
#endif
|
2511
2509
|
PQfreemem( pnotification );
|
2512
2510
|
|
2513
2511
|
if ( rb_block_given_p() )
|
@@ -2526,9 +2524,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2526
2524
|
* not sent (false is only possible if the connection
|
2527
2525
|
* is in nonblocking mode, and this command would block).
|
2528
2526
|
*
|
2529
|
-
*
|
2530
|
-
* This encodes the
|
2531
|
-
*
|
2527
|
+
* _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
|
2528
|
+
* This encodes the data fields given as _buffer_ from an Array of Strings to
|
2529
|
+
* PostgreSQL's COPY text format inclusive proper escaping. Optionally
|
2530
|
+
* the encoder can type cast the fields from various Ruby types in one step,
|
2532
2531
|
* if PG::TextEncoder::CopyRow#type_map is set accordingly.
|
2533
2532
|
*
|
2534
2533
|
* Raises an exception if an error occurs.
|
@@ -2565,16 +2564,17 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2565
2564
|
|
2566
2565
|
if( p_coder ){
|
2567
2566
|
t_pg_coder_enc_func enc_func;
|
2567
|
+
int enc_idx = ENCODING_GET(self);
|
2568
2568
|
|
2569
2569
|
enc_func = pg_coder_enc_func( p_coder );
|
2570
|
-
len = enc_func( p_coder, value, NULL, &intermediate );
|
2570
|
+
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
2571
2571
|
|
2572
2572
|
if( len == -1 ){
|
2573
2573
|
/* The intermediate value is a String that can be used directly. */
|
2574
2574
|
buffer = intermediate;
|
2575
2575
|
} else {
|
2576
2576
|
buffer = rb_str_new(NULL, len);
|
2577
|
-
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate);
|
2577
|
+
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate, enc_idx);
|
2578
2578
|
rb_str_set_len( buffer, len );
|
2579
2579
|
}
|
2580
2580
|
}
|
@@ -2613,13 +2613,13 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2613
2613
|
VALUE str;
|
2614
2614
|
VALUE error;
|
2615
2615
|
int ret;
|
2616
|
-
char *error_message = NULL;
|
2616
|
+
const char *error_message = NULL;
|
2617
2617
|
PGconn *conn = pg_get_pgconn(self);
|
2618
2618
|
|
2619
2619
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2620
2620
|
error_message = NULL;
|
2621
2621
|
else
|
2622
|
-
error_message =
|
2622
|
+
error_message = pg_cstr_enc(str, ENCODING_GET(self));
|
2623
2623
|
|
2624
2624
|
ret = gvl_PQputCopyEnd(conn, error_message);
|
2625
2625
|
if(ret == -1) {
|
@@ -2638,8 +2638,9 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2638
2638
|
* if the copy is done, or +false+ if the call would
|
2639
2639
|
* block (only possible if _async_ is true).
|
2640
2640
|
*
|
2641
|
-
*
|
2642
|
-
* This decodes the received data fields
|
2641
|
+
* _decoder_ can be a PG::Coder derivation (typically PG::TextDecoder::CopyRow).
|
2642
|
+
* This decodes the received data fields from PostgreSQL's COPY text format to an
|
2643
|
+
* Array of Strings. Optionally
|
2643
2644
|
* the decoder can type cast the fields to various Ruby types in one step,
|
2644
2645
|
* if PG::TextDecoder::CopyRow#type_map is set accordingly.
|
2645
2646
|
*
|
@@ -2697,7 +2698,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2697
2698
|
|
2698
2699
|
/*
|
2699
2700
|
* call-seq:
|
2700
|
-
* conn.set_error_verbosity( verbosity ) ->
|
2701
|
+
* conn.set_error_verbosity( verbosity ) -> Integer
|
2701
2702
|
*
|
2702
2703
|
* Sets connection's verbosity to _verbosity_ and returns
|
2703
2704
|
* the previous setting. Available settings are:
|
@@ -2940,12 +2941,10 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
|
|
2940
2941
|
|
2941
2942
|
Check_Type(str, T_STRING);
|
2942
2943
|
|
2943
|
-
if ( (
|
2944
|
-
rb_raise(rb_ePGerror, "
|
2944
|
+
if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
|
2945
|
+
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
2945
2946
|
}
|
2946
|
-
#ifdef M17N_SUPPORTED
|
2947
2947
|
pgconn_set_internal_encoding_index( self );
|
2948
|
-
#endif
|
2949
2948
|
|
2950
2949
|
return Qnil;
|
2951
2950
|
}
|
@@ -2996,10 +2995,10 @@ pgconn_transaction(VALUE self)
|
|
2996
2995
|
|
2997
2996
|
/*
|
2998
2997
|
* call-seq:
|
2999
|
-
* PG::Connection.quote_ident( str ) -> String
|
3000
|
-
* PG::Connection.quote_ident( array ) -> String
|
3001
2998
|
* conn.quote_ident( str ) -> String
|
3002
2999
|
* conn.quote_ident( array ) -> String
|
3000
|
+
* PG::Connection.quote_ident( str ) -> String
|
3001
|
+
* PG::Connection.quote_ident( array ) -> String
|
3003
3002
|
*
|
3004
3003
|
* Returns a string that is safe for inclusion in a SQL query as an
|
3005
3004
|
* identifier. Note: this is not a quote function for values, but for
|
@@ -3009,7 +3008,7 @@ pgconn_transaction(VALUE self)
|
|
3009
3008
|
* The identifier <tt>FOO</tt> is folded to lower case, so it actually
|
3010
3009
|
* means <tt>foo</tt>. If you really want to access the case-sensitive
|
3011
3010
|
* field name <tt>FOO</tt>, use this function like
|
3012
|
-
* <tt>
|
3011
|
+
* <tt>conn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
|
3013
3012
|
* (with double-quotes). PostgreSQL will see the double-quotes, and
|
3014
3013
|
* it will not fold to lower case.
|
3015
3014
|
*
|
@@ -3023,15 +3022,27 @@ pgconn_transaction(VALUE self)
|
|
3023
3022
|
*
|
3024
3023
|
* This method is functional identical to the encoder PG::TextEncoder::Identifier .
|
3025
3024
|
*
|
3025
|
+
* If the instance method form is used and the input string character encoding
|
3026
|
+
* is different to the connection encoding, then the string is converted to this
|
3027
|
+
* encoding, so that the returned string is always encoded as PG::Connection#internal_encoding .
|
3028
|
+
*
|
3029
|
+
* In the singleton form (PG::Connection.quote_ident) the character encoding
|
3030
|
+
* of the result string is set to the character encoding of the input string.
|
3026
3031
|
*/
|
3027
3032
|
static VALUE
|
3028
|
-
pgconn_s_quote_ident(VALUE self, VALUE
|
3033
|
+
pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
3029
3034
|
{
|
3030
3035
|
VALUE ret;
|
3031
|
-
|
3036
|
+
int enc_idx;
|
3037
|
+
|
3038
|
+
if( rb_obj_is_kind_of(self, rb_cPGconn) ){
|
3039
|
+
enc_idx = ENCODING_GET( self );
|
3040
|
+
}else{
|
3041
|
+
enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
|
3042
|
+
}
|
3043
|
+
pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
|
3032
3044
|
|
3033
|
-
OBJ_INFECT(ret,
|
3034
|
-
PG_ENCODING_SET_NOCHECK(ret, ENCODING_GET( rb_obj_is_kind_of(self, rb_cPGconn) ? self : in_str ));
|
3045
|
+
OBJ_INFECT(ret, str_or_array);
|
3035
3046
|
|
3036
3047
|
return ret;
|
3037
3048
|
}
|
@@ -3157,13 +3168,93 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3157
3168
|
return rb_pgresult;
|
3158
3169
|
}
|
3159
3170
|
|
3171
|
+
|
3172
|
+
#ifdef HAVE_PQSSLATTRIBUTE
|
3173
|
+
/*
|
3174
|
+
* call-seq:
|
3175
|
+
* conn.ssl_in_use? -> Boolean
|
3176
|
+
*
|
3177
|
+
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3178
|
+
*
|
3179
|
+
* Available since PostgreSQL-9.5
|
3180
|
+
*/
|
3181
|
+
static VALUE
|
3182
|
+
pgconn_ssl_in_use(VALUE self)
|
3183
|
+
{
|
3184
|
+
return PQsslInUse(pg_get_pgconn(self)) ? Qtrue : Qfalse;
|
3185
|
+
}
|
3186
|
+
|
3187
|
+
|
3188
|
+
/*
|
3189
|
+
* call-seq:
|
3190
|
+
* conn.ssl_attribute(attribute_name) -> String
|
3191
|
+
*
|
3192
|
+
* Returns SSL-related information about the connection.
|
3193
|
+
*
|
3194
|
+
* The list of available attributes varies depending on the SSL library being used,
|
3195
|
+
* and the type of connection. If an attribute is not available, returns nil.
|
3196
|
+
*
|
3197
|
+
* The following attributes are commonly available:
|
3198
|
+
*
|
3199
|
+
* [+library+]
|
3200
|
+
* Name of the SSL implementation in use. (Currently, only "OpenSSL" is implemented)
|
3201
|
+
* [+protocol+]
|
3202
|
+
* SSL/TLS version in use. Common values are "SSLv2", "SSLv3", "TLSv1", "TLSv1.1" and "TLSv1.2", but an implementation may return other strings if some other protocol is used.
|
3203
|
+
* [+key_bits+]
|
3204
|
+
* Number of key bits used by the encryption algorithm.
|
3205
|
+
* [+cipher+]
|
3206
|
+
* A short name of the ciphersuite used, e.g. "DHE-RSA-DES-CBC3-SHA". The names are specific to each SSL implementation.
|
3207
|
+
* [+compression+]
|
3208
|
+
* 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".
|
3209
|
+
*
|
3210
|
+
*
|
3211
|
+
* See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
|
3212
|
+
*
|
3213
|
+
* Available since PostgreSQL-9.5
|
3214
|
+
*/
|
3215
|
+
static VALUE
|
3216
|
+
pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
3217
|
+
{
|
3218
|
+
const char *p_attr;
|
3219
|
+
|
3220
|
+
p_attr = PQsslAttribute(pg_get_pgconn(self), StringValueCStr(attribute_name));
|
3221
|
+
return p_attr ? rb_str_new_cstr(p_attr) : Qnil;
|
3222
|
+
}
|
3223
|
+
|
3224
|
+
/*
|
3225
|
+
* call-seq:
|
3226
|
+
* conn.ssl_attribute_names -> Array<String>
|
3227
|
+
*
|
3228
|
+
* Return an array of SSL attribute names available.
|
3229
|
+
*
|
3230
|
+
* See also #ssl_attribute
|
3231
|
+
*
|
3232
|
+
* Available since PostgreSQL-9.5
|
3233
|
+
*/
|
3234
|
+
static VALUE
|
3235
|
+
pgconn_ssl_attribute_names(VALUE self)
|
3236
|
+
{
|
3237
|
+
int i;
|
3238
|
+
const char * const * p_list = PQsslAttributeNames(pg_get_pgconn(self));
|
3239
|
+
VALUE ary = rb_ary_new();
|
3240
|
+
|
3241
|
+
for ( i = 0; p_list[i]; i++ ) {
|
3242
|
+
rb_ary_push( ary, rb_str_new_cstr( p_list[i] ));
|
3243
|
+
}
|
3244
|
+
return ary;
|
3245
|
+
}
|
3246
|
+
|
3247
|
+
|
3248
|
+
#endif
|
3249
|
+
|
3250
|
+
|
3160
3251
|
/**************************************************************************
|
3161
3252
|
* LARGE OBJECT SUPPORT
|
3162
3253
|
**************************************************************************/
|
3163
3254
|
|
3164
3255
|
/*
|
3165
3256
|
* call-seq:
|
3166
|
-
* conn.lo_creat( [mode] ) ->
|
3257
|
+
* conn.lo_creat( [mode] ) -> Integer
|
3167
3258
|
*
|
3168
3259
|
* Creates a large object with mode _mode_. Returns a large object Oid.
|
3169
3260
|
* On failure, it raises PG::Error.
|
@@ -3190,7 +3281,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
|
3190
3281
|
|
3191
3282
|
/*
|
3192
3283
|
* call-seq:
|
3193
|
-
* conn.lo_create( oid ) ->
|
3284
|
+
* conn.lo_create( oid ) -> Integer
|
3194
3285
|
*
|
3195
3286
|
* Creates a large object with oid _oid_. Returns the large object Oid.
|
3196
3287
|
* On failure, it raises PG::Error.
|
@@ -3211,7 +3302,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
|
3211
3302
|
|
3212
3303
|
/*
|
3213
3304
|
* call-seq:
|
3214
|
-
* conn.lo_import(file) ->
|
3305
|
+
* conn.lo_import(file) -> Integer
|
3215
3306
|
*
|
3216
3307
|
* Import a file to a large object. Returns a large object Oid.
|
3217
3308
|
*
|
@@ -3256,7 +3347,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
|
|
3256
3347
|
|
3257
3348
|
/*
|
3258
3349
|
* call-seq:
|
3259
|
-
* conn.lo_open( oid, [mode] ) ->
|
3350
|
+
* conn.lo_open( oid, [mode] ) -> Integer
|
3260
3351
|
*
|
3261
3352
|
* Open a large object of _oid_. Returns a large object descriptor
|
3262
3353
|
* instance on success. The _mode_ argument specifies the mode for
|
@@ -3287,7 +3378,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
|
|
3287
3378
|
|
3288
3379
|
/*
|
3289
3380
|
* call-seq:
|
3290
|
-
* conn.lo_write( lo_desc, buffer ) ->
|
3381
|
+
* conn.lo_write( lo_desc, buffer ) -> Integer
|
3291
3382
|
*
|
3292
3383
|
* Writes the string _buffer_ to the large object _lo_desc_.
|
3293
3384
|
* Returns the number of bytes written.
|
@@ -3354,7 +3445,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3354
3445
|
|
3355
3446
|
/*
|
3356
3447
|
* call-seq:
|
3357
|
-
* conn.lo_lseek( lo_desc, offset, whence ) ->
|
3448
|
+
* conn.lo_lseek( lo_desc, offset, whence ) -> Integer
|
3358
3449
|
*
|
3359
3450
|
* Move the large object pointer _lo_desc_ to offset _offset_.
|
3360
3451
|
* Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
|
@@ -3376,7 +3467,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
|
|
3376
3467
|
|
3377
3468
|
/*
|
3378
3469
|
* call-seq:
|
3379
|
-
* conn.lo_tell( lo_desc ) ->
|
3470
|
+
* conn.lo_tell( lo_desc ) -> Integer
|
3380
3471
|
*
|
3381
3472
|
* Returns the current position of the large object _lo_desc_.
|
3382
3473
|
*/
|
@@ -3449,8 +3540,6 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3449
3540
|
}
|
3450
3541
|
|
3451
3542
|
|
3452
|
-
#ifdef M17N_SUPPORTED
|
3453
|
-
|
3454
3543
|
void
|
3455
3544
|
pgconn_set_internal_encoding_index( VALUE self )
|
3456
3545
|
{
|
@@ -3512,7 +3601,7 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3512
3601
|
rb_encoding *rbenc = rb_to_encoding( enc );
|
3513
3602
|
const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc );
|
3514
3603
|
|
3515
|
-
if (
|
3604
|
+
if ( gvl_PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
|
3516
3605
|
VALUE server_encoding = pgconn_external_encoding( self );
|
3517
3606
|
rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s",
|
3518
3607
|
rb_enc_name(rb_to_encoding(server_encoding)), name );
|
@@ -3554,6 +3643,34 @@ pgconn_external_encoding(VALUE self)
|
|
3554
3643
|
}
|
3555
3644
|
|
3556
3645
|
|
3646
|
+
static VALUE
|
3647
|
+
pgconn_set_client_encoding_async1( VALUE args )
|
3648
|
+
{
|
3649
|
+
VALUE self = ((VALUE*)args)[0];
|
3650
|
+
VALUE encname = ((VALUE*)args)[1];
|
3651
|
+
VALUE query_format = rb_str_new_cstr("set client_encoding to '%s'");
|
3652
|
+
VALUE query = rb_funcall(query_format, rb_intern("%"), 1, encname);
|
3653
|
+
|
3654
|
+
pgconn_async_exec(1, &query, self);
|
3655
|
+
return 0;
|
3656
|
+
}
|
3657
|
+
|
3658
|
+
|
3659
|
+
static VALUE
|
3660
|
+
pgconn_set_client_encoding_async2( VALUE arg )
|
3661
|
+
{
|
3662
|
+
UNUSED(arg);
|
3663
|
+
return 1;
|
3664
|
+
}
|
3665
|
+
|
3666
|
+
|
3667
|
+
static VALUE
|
3668
|
+
pgconn_set_client_encoding_async( VALUE self, const char *encname )
|
3669
|
+
{
|
3670
|
+
VALUE args[] = { self, rb_str_new_cstr(encname) };
|
3671
|
+
return rb_rescue(pgconn_set_client_encoding_async1, (VALUE)&args, pgconn_set_client_encoding_async2, Qnil);
|
3672
|
+
}
|
3673
|
+
|
3557
3674
|
|
3558
3675
|
/*
|
3559
3676
|
* call-seq:
|
@@ -3572,7 +3689,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3572
3689
|
|
3573
3690
|
if (( enc = rb_default_internal_encoding() )) {
|
3574
3691
|
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3575
|
-
if (
|
3692
|
+
if ( pgconn_set_client_encoding_async(self, encname) != 0 )
|
3576
3693
|
rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
|
3577
3694
|
encname, PQerrorMessage(conn) );
|
3578
3695
|
pgconn_set_internal_encoding_index( self );
|
@@ -3584,8 +3701,6 @@ pgconn_set_default_encoding( VALUE self )
|
|
3584
3701
|
}
|
3585
3702
|
|
3586
3703
|
|
3587
|
-
#endif /* M17N_SUPPORTED */
|
3588
|
-
|
3589
3704
|
/*
|
3590
3705
|
* call-seq:
|
3591
3706
|
* res.type_map_for_queries = typemap
|
@@ -3704,7 +3819,7 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE typemap)
|
|
3704
3819
|
*
|
3705
3820
|
* Returns either:
|
3706
3821
|
* * a kind of PG::Coder
|
3707
|
-
* * +nil+ - type encoding is disabled,
|
3822
|
+
* * +nil+ - type encoding is disabled, data must be a String.
|
3708
3823
|
*
|
3709
3824
|
*/
|
3710
3825
|
static VALUE
|
@@ -3765,6 +3880,9 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
3765
3880
|
}
|
3766
3881
|
|
3767
3882
|
|
3883
|
+
/*
|
3884
|
+
* Document-class: PG::Connection
|
3885
|
+
*/
|
3768
3886
|
void
|
3769
3887
|
init_pg_connection()
|
3770
3888
|
{
|
@@ -3791,9 +3909,7 @@ init_pg_connection()
|
|
3791
3909
|
rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
3792
3910
|
rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
|
3793
3911
|
rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
|
3794
|
-
#ifdef HAVE_PQPING
|
3795
3912
|
rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
|
3796
|
-
#endif
|
3797
3913
|
|
3798
3914
|
/****** PG::Connection INSTANCE METHODS: Connection Control ******/
|
3799
3915
|
rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
|
@@ -3823,9 +3939,7 @@ init_pg_connection()
|
|
3823
3939
|
rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
|
3824
3940
|
rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
|
3825
3941
|
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
|
3826
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
3827
3942
|
rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
|
3828
|
-
#endif
|
3829
3943
|
rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
|
3830
3944
|
rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
|
3831
3945
|
rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
|
@@ -3842,17 +3956,11 @@ init_pg_connection()
|
|
3842
3956
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
3843
3957
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
3844
3958
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
3845
|
-
#ifdef HAVE_PQESCAPELITERAL
|
3846
3959
|
rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
|
3847
|
-
#endif
|
3848
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
3849
3960
|
rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
|
3850
|
-
#endif
|
3851
3961
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
3852
3962
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
3853
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
3854
3963
|
rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
|
3855
|
-
#endif
|
3856
3964
|
|
3857
3965
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
3858
3966
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
@@ -3900,6 +4008,15 @@ init_pg_connection()
|
|
3900
4008
|
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
3901
4009
|
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
3902
4010
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
|
4011
|
+
#ifdef HAVE_PQENCRYPTPASSWORDCONN
|
4012
|
+
rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
|
4013
|
+
#endif
|
4014
|
+
|
4015
|
+
#ifdef HAVE_PQSSLATTRIBUTE
|
4016
|
+
rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
|
4017
|
+
rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
|
4018
|
+
rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
|
4019
|
+
#endif
|
3903
4020
|
|
3904
4021
|
/****** PG::Connection INSTANCE METHODS: Large Object Support ******/
|
3905
4022
|
rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
|
@@ -3929,12 +4046,10 @@ init_pg_connection()
|
|
3929
4046
|
rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
|
3930
4047
|
rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
|
3931
4048
|
|
3932
|
-
#ifdef M17N_SUPPORTED
|
3933
4049
|
rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
|
3934
4050
|
rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
|
3935
4051
|
rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
|
3936
4052
|
rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
|
3937
|
-
#endif /* M17N_SUPPORTED */
|
3938
4053
|
|
3939
4054
|
rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
|
3940
4055
|
rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);
|