pg 0.18.0 → 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 +1221 -4
- data/History.rdoc +130 -0
- data/Manifest.txt +0 -18
- data/README-Windows.rdoc +15 -26
- data/README.rdoc +16 -10
- data/Rakefile +32 -23
- data/Rakefile.cross +56 -38
- data/ext/errorcodes.def +33 -0
- data/ext/errorcodes.txt +15 -1
- data/ext/extconf.rb +27 -35
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +27 -39
- data/ext/pg.c +19 -51
- data/ext/pg.h +22 -79
- data/ext/pg_binary_decoder.c +3 -1
- data/ext/pg_binary_encoder.c +14 -12
- data/ext/pg_coder.c +31 -10
- data/ext/pg_connection.c +350 -263
- data/ext/pg_copy_coder.c +34 -4
- data/ext/pg_result.c +27 -25
- data/ext/pg_text_decoder.c +9 -10
- data/ext/pg_text_encoder.c +93 -73
- data/ext/pg_type_map.c +20 -13
- data/ext/pg_type_map_by_column.c +7 -7
- data/ext/pg_type_map_by_mri_type.c +2 -2
- data/ext/pg_type_map_in_ruby.c +4 -7
- data/ext/util.c +3 -3
- data/ext/util.h +1 -1
- data/lib/pg/basic_type_mapping.rb +69 -42
- data/lib/pg/connection.rb +89 -38
- data/lib/pg/result.rb +10 -5
- data/lib/pg/text_decoder.rb +12 -3
- data/lib/pg/text_encoder.rb +8 -0
- data/lib/pg.rb +18 -10
- data/spec/helpers.rb +9 -16
- data/spec/pg/basic_type_mapping_spec.rb +58 -4
- data/spec/pg/connection_spec.rb +477 -217
- 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 +145 -33
- data/spec/pg_spec.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +67 -66
- 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
|
412
|
+
*
|
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.
|
414
416
|
*
|
415
|
-
*
|
416
|
-
*
|
417
|
-
*
|
418
|
-
*
|
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)
|
@@ -627,22 +673,6 @@ pgconn_host(VALUE self)
|
|
627
673
|
return rb_tainted_str_new2(host);
|
628
674
|
}
|
629
675
|
|
630
|
-
#ifdef HAVE_PQHOSTADDR
|
631
|
-
/*
|
632
|
-
* call-seq:
|
633
|
-
* conn.hostaddr()
|
634
|
-
*
|
635
|
-
* Returns the server numeric IP address of the connection.
|
636
|
-
*/
|
637
|
-
static VALUE
|
638
|
-
pgconn_hostaddr(VALUE self)
|
639
|
-
{
|
640
|
-
char *hostaddr = PQhostaddr(pg_get_pgconn(self));
|
641
|
-
if (!hostaddr) return Qnil;
|
642
|
-
return rb_tainted_str_new2(hostaddr);
|
643
|
-
}
|
644
|
-
#endif
|
645
|
-
|
646
676
|
/*
|
647
677
|
* call-seq:
|
648
678
|
* conn.port()
|
@@ -692,6 +722,7 @@ pgconn_options(VALUE self)
|
|
692
722
|
*
|
693
723
|
* Returns the connection options used by a live connection.
|
694
724
|
*
|
725
|
+
* Available since PostgreSQL-9.3
|
695
726
|
*/
|
696
727
|
static VALUE
|
697
728
|
pgconn_conninfo( VALUE self )
|
@@ -811,7 +842,9 @@ pgconn_error_message(VALUE self)
|
|
811
842
|
|
812
843
|
/*
|
813
844
|
* call-seq:
|
814
|
-
* conn.socket() ->
|
845
|
+
* conn.socket() -> Integer
|
846
|
+
*
|
847
|
+
* This method is deprecated. Please use the more portable method #socket_io .
|
815
848
|
*
|
816
849
|
* Returns the socket's file descriptor for this connection.
|
817
850
|
* <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
|
@@ -821,7 +854,7 @@ pgconn_error_message(VALUE self)
|
|
821
854
|
* creates an IO that's associated with the connection object itself,
|
822
855
|
* and so won't go out of scope until the connection does.
|
823
856
|
*
|
824
|
-
* *Note:* On Windows the file descriptor is not
|
857
|
+
* *Note:* On Windows the file descriptor is not usable,
|
825
858
|
* since it can not be used to build a Ruby IO object.
|
826
859
|
*/
|
827
860
|
static VALUE
|
@@ -833,22 +866,17 @@ pgconn_socket(VALUE self)
|
|
833
866
|
return INT2NUM(sd);
|
834
867
|
}
|
835
868
|
|
836
|
-
|
837
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
838
|
-
|
839
869
|
/*
|
840
870
|
* call-seq:
|
841
871
|
* conn.socket_io() -> IO
|
842
872
|
*
|
843
|
-
* Fetch a
|
873
|
+
* Fetch a memorized IO object created from the Connection's underlying socket.
|
844
874
|
* This object can be used for IO.select to wait for events while running
|
845
875
|
* asynchronous API calls.
|
846
876
|
*
|
847
877
|
* Using this instead of #socket avoids the problem of the underlying connection
|
848
878
|
* being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt>
|
849
|
-
* goes out of scope.
|
850
|
-
*
|
851
|
-
* 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.
|
852
880
|
*/
|
853
881
|
static VALUE
|
854
882
|
pgconn_socket_io(VALUE self)
|
@@ -882,11 +910,9 @@ pgconn_socket_io(VALUE self)
|
|
882
910
|
return socket_io;
|
883
911
|
}
|
884
912
|
|
885
|
-
#endif
|
886
|
-
|
887
913
|
/*
|
888
914
|
* call-seq:
|
889
|
-
* conn.backend_pid() ->
|
915
|
+
* conn.backend_pid() -> Integer
|
890
916
|
*
|
891
917
|
* Returns the process ID of the backend server
|
892
918
|
* process for this connection.
|
@@ -963,9 +989,9 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
963
989
|
|
964
990
|
/* If called with no parameters, use PQexec */
|
965
991
|
if ( argc == 1 ) {
|
966
|
-
|
992
|
+
VALUE query_str = argv[0];
|
967
993
|
|
968
|
-
result = gvl_PQexec(conn,
|
994
|
+
result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
|
969
995
|
rb_pgresult = pg_new_result(result, self);
|
970
996
|
pg_result_check(rb_pgresult);
|
971
997
|
if (rb_block_given_p()) {
|
@@ -994,6 +1020,10 @@ struct query_params_data {
|
|
994
1020
|
* Filled by caller
|
995
1021
|
*/
|
996
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;
|
997
1027
|
/* Is the query function to execute one with types array? */
|
998
1028
|
int with_types;
|
999
1029
|
/* Array of query params from user space */
|
@@ -1154,7 +1184,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1154
1184
|
VALUE intermediate;
|
1155
1185
|
|
1156
1186
|
/* 1st pass for retiving the required memory space */
|
1157
|
-
int len = enc_func(conv, param_value, NULL, &intermediate);
|
1187
|
+
int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
|
1158
1188
|
|
1159
1189
|
if( len == -1 ){
|
1160
1190
|
/* The intermediate value is a String that can be used directly. */
|
@@ -1178,7 +1208,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1178
1208
|
}
|
1179
1209
|
|
1180
1210
|
/* 2nd pass for writing the data to prepared buffer */
|
1181
|
-
len = enc_func(conv, param_value, typecast_buf, &intermediate);
|
1211
|
+
len = enc_func(conv, param_value, typecast_buf, &intermediate, paramsData->enc_idx);
|
1182
1212
|
paramsData->values[i] = typecast_buf;
|
1183
1213
|
if( paramsData->formats[i] == 0 ){
|
1184
1214
|
/* text format strings must be zero terminated and lengths are ignored */
|
@@ -1236,8 +1266,8 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1236
1266
|
* Each element of the +params+ array may be either:
|
1237
1267
|
* a hash of the form:
|
1238
1268
|
* {:value => String (value of bind parameter)
|
1239
|
-
* :type =>
|
1240
|
-
* :format =>
|
1269
|
+
* :type => Integer (oid of type of bind parameter)
|
1270
|
+
* :format => Integer (0 for text, 1 for binary)
|
1241
1271
|
* }
|
1242
1272
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1243
1273
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1256,7 +1286,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1256
1286
|
* for binary.
|
1257
1287
|
*
|
1258
1288
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1259
|
-
* This will type cast the params
|
1289
|
+
* This will type cast the params from various Ruby types before transmission
|
1260
1290
|
* based on the encoders defined by the type map. When a type encoder is used
|
1261
1291
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1262
1292
|
* instead out of the hash form described above.
|
@@ -1274,7 +1304,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1274
1304
|
VALUE command, in_res_fmt;
|
1275
1305
|
int nParams;
|
1276
1306
|
int resultFormat;
|
1277
|
-
struct query_params_data paramsData;
|
1307
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1278
1308
|
|
1279
1309
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1280
1310
|
paramsData.with_types = 1;
|
@@ -1291,7 +1321,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1291
1321
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1292
1322
|
nParams = alloc_query_params( ¶msData );
|
1293
1323
|
|
1294
|
-
result = gvl_PQexecParams(conn,
|
1324
|
+
result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1295
1325
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1296
1326
|
|
1297
1327
|
free_query_params( ¶msData );
|
@@ -1337,10 +1367,13 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1337
1367
|
int i = 0;
|
1338
1368
|
int nParams = 0;
|
1339
1369
|
Oid *paramTypes = NULL;
|
1370
|
+
const char *name_cstr;
|
1371
|
+
const char *command_cstr;
|
1372
|
+
int enc_idx = ENCODING_GET(self);
|
1340
1373
|
|
1341
1374
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1342
|
-
|
1343
|
-
|
1375
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1376
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1344
1377
|
|
1345
1378
|
if(! NIL_P(in_paramtypes)) {
|
1346
1379
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1354,8 +1387,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1354
1387
|
paramTypes[i] = NUM2UINT(param);
|
1355
1388
|
}
|
1356
1389
|
}
|
1357
|
-
result = gvl_PQprepare(conn,
|
1358
|
-
nParams, paramTypes);
|
1390
|
+
result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1359
1391
|
|
1360
1392
|
xfree(paramTypes);
|
1361
1393
|
|
@@ -1377,7 +1409,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1377
1409
|
* SQL query. Each element of the +params+ array may be either:
|
1378
1410
|
* a hash of the form:
|
1379
1411
|
* {:value => String (value of bind parameter)
|
1380
|
-
* :format =>
|
1412
|
+
* :format => Integer (0 for text, 1 for binary)
|
1381
1413
|
* }
|
1382
1414
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1383
1415
|
* { :value => <string value>, :format => 0 }
|
@@ -1390,7 +1422,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1390
1422
|
* for binary.
|
1391
1423
|
*
|
1392
1424
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1393
|
-
* This will type cast the params
|
1425
|
+
* This will type cast the params from various Ruby types before transmission
|
1394
1426
|
* based on the encoders defined by the type map. When a type encoder is used
|
1395
1427
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1396
1428
|
* instead out of the hash form described above.
|
@@ -1408,11 +1440,10 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1408
1440
|
VALUE name, in_res_fmt;
|
1409
1441
|
int nParams;
|
1410
1442
|
int resultFormat;
|
1411
|
-
struct query_params_data paramsData;
|
1443
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1412
1444
|
|
1413
1445
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1414
1446
|
paramsData.with_types = 0;
|
1415
|
-
Check_Type(name, T_STRING);
|
1416
1447
|
|
1417
1448
|
if(NIL_P(paramsData.params)) {
|
1418
1449
|
paramsData.params = rb_ary_new2(0);
|
@@ -1422,7 +1453,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1422
1453
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1423
1454
|
nParams = alloc_query_params( ¶msData );
|
1424
1455
|
|
1425
|
-
result = gvl_PQexecPrepared(conn,
|
1456
|
+
result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1426
1457
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1427
1458
|
resultFormat);
|
1428
1459
|
|
@@ -1450,13 +1481,12 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1450
1481
|
PGresult *result;
|
1451
1482
|
VALUE rb_pgresult;
|
1452
1483
|
PGconn *conn = pg_get_pgconn(self);
|
1453
|
-
char *stmt;
|
1454
|
-
if(stmt_name
|
1484
|
+
const char *stmt;
|
1485
|
+
if(NIL_P(stmt_name)) {
|
1455
1486
|
stmt = NULL;
|
1456
1487
|
}
|
1457
1488
|
else {
|
1458
|
-
|
1459
|
-
stmt = StringValueCStr(stmt_name);
|
1489
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1460
1490
|
}
|
1461
1491
|
result = gvl_PQdescribePrepared(conn, stmt);
|
1462
1492
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1478,13 +1508,12 @@ pgconn_describe_portal(self, stmt_name)
|
|
1478
1508
|
PGresult *result;
|
1479
1509
|
VALUE rb_pgresult;
|
1480
1510
|
PGconn *conn = pg_get_pgconn(self);
|
1481
|
-
char *stmt;
|
1482
|
-
if(stmt_name
|
1511
|
+
const char *stmt;
|
1512
|
+
if(NIL_P(stmt_name)) {
|
1483
1513
|
stmt = NULL;
|
1484
1514
|
}
|
1485
1515
|
else {
|
1486
|
-
|
1487
|
-
stmt = StringValueCStr(stmt_name);
|
1516
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1488
1517
|
}
|
1489
1518
|
result = gvl_PQdescribePortal(conn, stmt);
|
1490
1519
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1526,10 +1555,6 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1526
1555
|
* call-seq:
|
1527
1556
|
* conn.escape_string( str ) -> String
|
1528
1557
|
*
|
1529
|
-
* Connection instance method for versions of 8.1 and higher of libpq
|
1530
|
-
* uses PQescapeStringConn, which is safer. Avoid calling as a class method,
|
1531
|
-
* the class method uses the deprecated PQescapeString() API function.
|
1532
|
-
*
|
1533
1558
|
* Returns a SQL-safe version of the String _str_.
|
1534
1559
|
* This is the preferred way to make strings safe for inclusion in
|
1535
1560
|
* SQL queries.
|
@@ -1538,32 +1563,41 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1538
1563
|
* inside of SQL commands.
|
1539
1564
|
*
|
1540
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.
|
1541
1572
|
*/
|
1542
1573
|
static VALUE
|
1543
1574
|
pgconn_s_escape(VALUE self, VALUE string)
|
1544
1575
|
{
|
1545
|
-
char *escaped;
|
1546
1576
|
size_t size;
|
1547
1577
|
int error;
|
1548
1578
|
VALUE result;
|
1579
|
+
int enc_idx;
|
1580
|
+
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1549
1581
|
|
1550
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
|
+
}
|
1551
1587
|
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
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),
|
1555
1592
|
RSTRING_PTR(string), RSTRING_LEN(string), &error);
|
1556
1593
|
if(error) {
|
1557
|
-
xfree(escaped);
|
1558
1594
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
|
1559
1595
|
}
|
1560
1596
|
} else {
|
1561
|
-
size = PQescapeString(
|
1597
|
+
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1562
1598
|
}
|
1563
|
-
result
|
1564
|
-
xfree(escaped);
|
1599
|
+
rb_str_set_len(result, size);
|
1565
1600
|
OBJ_INFECT(result, string);
|
1566
|
-
PG_ENCODING_SET_NOCHECK(result, ENCODING_GET( rb_obj_class(self) == rb_cPGconn ? self : string ));
|
1567
1601
|
|
1568
1602
|
return result;
|
1569
1603
|
}
|
@@ -1572,13 +1606,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1572
1606
|
* call-seq:
|
1573
1607
|
* conn.escape_bytea( string ) -> String
|
1574
1608
|
*
|
1575
|
-
* Connection instance method for versions of 8.1 and higher of libpq
|
1576
|
-
* uses PQescapeByteaConn, which is safer. Avoid calling as a class method,
|
1577
|
-
* the class method uses the deprecated PQescapeBytea() API function.
|
1578
|
-
*
|
1579
|
-
* Use the instance method version of this function, it is safer than the
|
1580
|
-
* class method.
|
1581
|
-
*
|
1582
1609
|
* Escapes binary data for use within an SQL command with the type +bytea+.
|
1583
1610
|
*
|
1584
1611
|
* Certain byte values must be escaped (but all byte values may be escaped)
|
@@ -1591,6 +1618,12 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1591
1618
|
*
|
1592
1619
|
* Consider using exec_params, which avoids the need for passing values inside of
|
1593
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.
|
1594
1627
|
*/
|
1595
1628
|
static VALUE
|
1596
1629
|
pgconn_s_escape_bytea(VALUE self, VALUE str)
|
@@ -1603,7 +1636,7 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
|
|
1603
1636
|
from = (unsigned char*)RSTRING_PTR(str);
|
1604
1637
|
from_len = RSTRING_LEN(str);
|
1605
1638
|
|
1606
|
-
if(
|
1639
|
+
if ( rb_obj_is_kind_of(self, rb_cPGconn) ) {
|
1607
1640
|
to = PQescapeByteaConn(pg_get_pgconn(self), from, from_len, &to_len);
|
1608
1641
|
} else {
|
1609
1642
|
to = PQescapeBytea( from, from_len, &to_len);
|
@@ -1645,12 +1678,13 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1645
1678
|
return ret;
|
1646
1679
|
}
|
1647
1680
|
|
1648
|
-
#ifdef HAVE_PQESCAPELITERAL
|
1649
1681
|
/*
|
1650
1682
|
* call-seq:
|
1651
1683
|
* conn.escape_literal( str ) -> String
|
1652
1684
|
*
|
1653
1685
|
* Escape an arbitrary String +str+ as a literal.
|
1686
|
+
*
|
1687
|
+
* Available since PostgreSQL-9.0
|
1654
1688
|
*/
|
1655
1689
|
static VALUE
|
1656
1690
|
pgconn_escape_literal(VALUE self, VALUE string)
|
@@ -1659,8 +1693,12 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1659
1693
|
char *escaped = NULL;
|
1660
1694
|
VALUE error;
|
1661
1695
|
VALUE result = Qnil;
|
1696
|
+
int enc_idx = ENCODING_GET(self);
|
1662
1697
|
|
1663
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
|
+
}
|
1664
1702
|
|
1665
1703
|
escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1666
1704
|
if (escaped == NULL)
|
@@ -1673,21 +1711,22 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1673
1711
|
result = rb_str_new2(escaped);
|
1674
1712
|
PQfreemem(escaped);
|
1675
1713
|
OBJ_INFECT(result, string);
|
1676
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1714
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1677
1715
|
|
1678
1716
|
return result;
|
1679
1717
|
}
|
1680
|
-
#endif
|
1681
1718
|
|
1682
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
1683
1719
|
/*
|
1684
1720
|
* call-seq:
|
1685
1721
|
* conn.escape_identifier( str ) -> String
|
1686
1722
|
*
|
1687
1723
|
* Escape an arbitrary String +str+ as an identifier.
|
1688
1724
|
*
|
1689
|
-
* This method does the same as #quote_ident
|
1690
|
-
*
|
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
|
1691
1730
|
*/
|
1692
1731
|
static VALUE
|
1693
1732
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
@@ -1696,8 +1735,12 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1696
1735
|
char *escaped = NULL;
|
1697
1736
|
VALUE error;
|
1698
1737
|
VALUE result = Qnil;
|
1738
|
+
int enc_idx = ENCODING_GET(self);
|
1699
1739
|
|
1700
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
|
+
}
|
1701
1744
|
|
1702
1745
|
escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1703
1746
|
if (escaped == NULL)
|
@@ -1710,13 +1753,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1710
1753
|
result = rb_str_new2(escaped);
|
1711
1754
|
PQfreemem(escaped);
|
1712
1755
|
OBJ_INFECT(result, string);
|
1713
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1756
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1714
1757
|
|
1715
1758
|
return result;
|
1716
1759
|
}
|
1717
|
-
#endif
|
1718
1760
|
|
1719
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
1720
1761
|
/*
|
1721
1762
|
* call-seq:
|
1722
1763
|
* conn.set_single_row_mode -> self
|
@@ -1753,6 +1794,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1753
1794
|
* end
|
1754
1795
|
* end
|
1755
1796
|
*
|
1797
|
+
* Available since PostgreSQL-9.2
|
1756
1798
|
*/
|
1757
1799
|
static VALUE
|
1758
1800
|
pgconn_set_single_row_mode(VALUE self)
|
@@ -1769,7 +1811,6 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1769
1811
|
|
1770
1812
|
return self;
|
1771
1813
|
}
|
1772
|
-
#endif
|
1773
1814
|
|
1774
1815
|
/*
|
1775
1816
|
* call-seq:
|
@@ -1783,8 +1824,8 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1783
1824
|
* Each element of the +params+ array may be either:
|
1784
1825
|
* a hash of the form:
|
1785
1826
|
* {:value => String (value of bind parameter)
|
1786
|
-
* :type =>
|
1787
|
-
* :format =>
|
1827
|
+
* :type => Integer (oid of type of bind parameter)
|
1828
|
+
* :format => Integer (0 for text, 1 for binary)
|
1788
1829
|
* }
|
1789
1830
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1790
1831
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1803,7 +1844,7 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1803
1844
|
* for binary.
|
1804
1845
|
*
|
1805
1846
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1806
|
-
* This will type cast the params
|
1847
|
+
* This will type cast the params from various Ruby types before transmission
|
1807
1848
|
* based on the encoders defined by the type map. When a type encoder is used
|
1808
1849
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1809
1850
|
* instead out of the hash form described above.
|
@@ -1818,15 +1859,14 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1818
1859
|
VALUE error;
|
1819
1860
|
int nParams;
|
1820
1861
|
int resultFormat;
|
1821
|
-
struct query_params_data paramsData;
|
1862
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1822
1863
|
|
1823
1864
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1824
1865
|
paramsData.with_types = 1;
|
1825
|
-
Check_Type(command, T_STRING);
|
1826
1866
|
|
1827
1867
|
/* If called with no parameters, use PQsendQuery */
|
1828
1868
|
if(NIL_P(paramsData.params)) {
|
1829
|
-
if(gvl_PQsendQuery(conn,
|
1869
|
+
if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
|
1830
1870
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1831
1871
|
rb_iv_set(error, "@connection", self);
|
1832
1872
|
rb_exc_raise(error);
|
@@ -1842,7 +1882,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1842
1882
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1843
1883
|
nParams = alloc_query_params( ¶msData );
|
1844
1884
|
|
1845
|
-
result = gvl_PQsendQueryParams(conn,
|
1885
|
+
result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1846
1886
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1847
1887
|
|
1848
1888
|
free_query_params( ¶msData );
|
@@ -1886,10 +1926,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1886
1926
|
int i = 0;
|
1887
1927
|
int nParams = 0;
|
1888
1928
|
Oid *paramTypes = NULL;
|
1929
|
+
const char *name_cstr;
|
1930
|
+
const char *command_cstr;
|
1931
|
+
int enc_idx = ENCODING_GET(self);
|
1889
1932
|
|
1890
1933
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1891
|
-
|
1892
|
-
|
1934
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1935
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1893
1936
|
|
1894
1937
|
if(! NIL_P(in_paramtypes)) {
|
1895
1938
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1903,8 +1946,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1903
1946
|
paramTypes[i] = NUM2UINT(param);
|
1904
1947
|
}
|
1905
1948
|
}
|
1906
|
-
result = gvl_PQsendPrepare(conn,
|
1907
|
-
nParams, paramTypes);
|
1949
|
+
result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1908
1950
|
|
1909
1951
|
xfree(paramTypes);
|
1910
1952
|
|
@@ -1929,7 +1971,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1929
1971
|
* SQL query. Each element of the +params+ array may be either:
|
1930
1972
|
* a hash of the form:
|
1931
1973
|
* {:value => String (value of bind parameter)
|
1932
|
-
* :format =>
|
1974
|
+
* :format => Integer (0 for text, 1 for binary)
|
1933
1975
|
* }
|
1934
1976
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1935
1977
|
* { :value => <string value>, :format => 0 }
|
@@ -1942,7 +1984,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1942
1984
|
* for binary.
|
1943
1985
|
*
|
1944
1986
|
* type_map can be a PG::TypeMap derivation (such as PG::BasicTypeMapForQueries).
|
1945
|
-
* This will type cast the params
|
1987
|
+
* This will type cast the params from various Ruby types before transmission
|
1946
1988
|
* based on the encoders defined by the type map. When a type encoder is used
|
1947
1989
|
* the format and oid of a given bind parameter are retrieved from the encoder
|
1948
1990
|
* instead out of the hash form described above.
|
@@ -1957,11 +1999,10 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1957
1999
|
VALUE error;
|
1958
2000
|
int nParams;
|
1959
2001
|
int resultFormat;
|
1960
|
-
struct query_params_data paramsData;
|
2002
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1961
2003
|
|
1962
2004
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1963
2005
|
paramsData.with_types = 0;
|
1964
|
-
Check_Type(name, T_STRING);
|
1965
2006
|
|
1966
2007
|
if(NIL_P(paramsData.params)) {
|
1967
2008
|
paramsData.params = rb_ary_new2(0);
|
@@ -1972,7 +2013,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1972
2013
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1973
2014
|
nParams = alloc_query_params( ¶msData );
|
1974
2015
|
|
1975
|
-
result = gvl_PQsendQueryPrepared(conn,
|
2016
|
+
result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1976
2017
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1977
2018
|
resultFormat);
|
1978
2019
|
|
@@ -1999,7 +2040,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1999
2040
|
VALUE error;
|
2000
2041
|
PGconn *conn = pg_get_pgconn(self);
|
2001
2042
|
/* returns 0 on failure */
|
2002
|
-
if(gvl_PQsendDescribePrepared(conn,
|
2043
|
+
if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
|
2003
2044
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
2004
2045
|
rb_iv_set(error, "@connection", self);
|
2005
2046
|
rb_exc_raise(error);
|
@@ -2021,7 +2062,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
2021
2062
|
VALUE error;
|
2022
2063
|
PGconn *conn = pg_get_pgconn(self);
|
2023
2064
|
/* returns 0 on failure */
|
2024
|
-
if(gvl_PQsendDescribePortal(conn,
|
2065
|
+
if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
|
2025
2066
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
2026
2067
|
rb_iv_set(error, "@connection", self);
|
2027
2068
|
rb_exc_raise(error);
|
@@ -2193,7 +2234,6 @@ pgconn_flush(self)
|
|
2193
2234
|
static VALUE
|
2194
2235
|
pgconn_cancel(VALUE self)
|
2195
2236
|
{
|
2196
|
-
#ifdef HAVE_PQGETCANCEL
|
2197
2237
|
char errbuf[256];
|
2198
2238
|
PGcancel *cancel;
|
2199
2239
|
VALUE retval;
|
@@ -2211,9 +2251,6 @@ pgconn_cancel(VALUE self)
|
|
2211
2251
|
|
2212
2252
|
PQfreeCancel(cancel);
|
2213
2253
|
return retval;
|
2214
|
-
#else
|
2215
|
-
rb_notimplement();
|
2216
|
-
#endif
|
2217
2254
|
}
|
2218
2255
|
|
2219
2256
|
|
@@ -2257,45 +2294,8 @@ pgconn_notifies(VALUE self)
|
|
2257
2294
|
return hash;
|
2258
2295
|
}
|
2259
2296
|
|
2260
|
-
/* Win32 + Ruby 1.8 */
|
2261
|
-
#if !defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
|
2262
|
-
|
2263
|
-
/*
|
2264
|
-
* Duplicate the sockets from libpq and create temporary CRT FDs
|
2265
|
-
*/
|
2266
|
-
void create_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2267
|
-
{
|
2268
|
-
int i;
|
2269
|
-
crt_set->fd_count = os_set->fd_count;
|
2270
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2271
|
-
WSAPROTOCOL_INFO wsa_pi;
|
2272
|
-
/* dupicate the SOCKET */
|
2273
|
-
int r = WSADuplicateSocket(os_set->fd_array[i], GetCurrentProcessId(), &wsa_pi);
|
2274
|
-
SOCKET s = WSASocket(wsa_pi.iAddressFamily, wsa_pi.iSocketType, wsa_pi.iProtocol, &wsa_pi, 0, 0);
|
2275
|
-
/* create the CRT fd so ruby can get back to the SOCKET */
|
2276
|
-
int fd = _open_osfhandle(s, O_RDWR|O_BINARY);
|
2277
|
-
os_set->fd_array[i] = s;
|
2278
|
-
crt_set->fd_array[i] = fd;
|
2279
|
-
}
|
2280
|
-
}
|
2281
|
-
|
2282
|
-
/*
|
2283
|
-
* Clean up the CRT FDs from create_crt_fd()
|
2284
|
-
*/
|
2285
|
-
void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
|
2286
|
-
{
|
2287
|
-
int i;
|
2288
|
-
for (i = 0; i < os_set->fd_count; i++) {
|
2289
|
-
/* cleanup the CRT fd */
|
2290
|
-
_close(crt_set->fd_array[i]);
|
2291
|
-
/* cleanup the duplicated SOCKET */
|
2292
|
-
closesocket(os_set->fd_array[i]);
|
2293
|
-
}
|
2294
|
-
}
|
2295
|
-
#endif
|
2296
|
-
|
2297
2297
|
/* Win32 + Ruby 1.9+ */
|
2298
|
-
#if defined(
|
2298
|
+
#if defined( _WIN32 )
|
2299
2299
|
/*
|
2300
2300
|
* On Windows, use platform-specific strategies to wait for the socket
|
2301
2301
|
* instead of rb_thread_select().
|
@@ -2383,7 +2383,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2383
2383
|
|
2384
2384
|
#else
|
2385
2385
|
|
2386
|
-
/* non Win32
|
2386
|
+
/* non Win32 */
|
2387
2387
|
|
2388
2388
|
static void *
|
2389
2389
|
wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
|
@@ -2393,9 +2393,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2393
2393
|
void *retval;
|
2394
2394
|
rb_fdset_t sd_rset;
|
2395
2395
|
struct timeval aborttime={0,0}, currtime, waittime;
|
2396
|
-
#ifdef _WIN32
|
2397
|
-
rb_fdset_t crt_sd_rset;
|
2398
|
-
#endif
|
2399
2396
|
|
2400
2397
|
if ( sd < 0 )
|
2401
2398
|
rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
|
@@ -2415,14 +2412,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2415
2412
|
rb_fd_zero( &sd_rset );
|
2416
2413
|
rb_fd_set( sd, &sd_rset );
|
2417
2414
|
|
2418
|
-
#ifdef _WIN32
|
2419
|
-
/* Ruby's FD_SET is modified on win32 to convert a file descriptor
|
2420
|
-
* to osfhandle, but we already get a osfhandle from PQsocket().
|
2421
|
-
* Therefore it's overwritten here. */
|
2422
|
-
sd_rset.fd_array[0] = sd;
|
2423
|
-
create_crt_fd(&sd_rset, &crt_sd_rset);
|
2424
|
-
#endif
|
2425
|
-
|
2426
2415
|
if ( ptimeout ) {
|
2427
2416
|
gettimeofday(&currtime, NULL);
|
2428
2417
|
timersub(&aborttime, &currtime, &waittime);
|
@@ -2436,11 +2425,6 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
|
|
2436
2425
|
ret = 0;
|
2437
2426
|
}
|
2438
2427
|
|
2439
|
-
|
2440
|
-
#ifdef _WIN32
|
2441
|
-
cleanup_crt_fd(&sd_rset, &crt_sd_rset);
|
2442
|
-
#endif
|
2443
|
-
|
2444
2428
|
if ( ret < 0 ){
|
2445
2429
|
rb_fd_term( &sd_rset );
|
2446
2430
|
rb_sys_fail( "rb_thread_select()" );
|
@@ -2518,12 +2502,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2518
2502
|
relname = rb_tainted_str_new2( pnotification->relname );
|
2519
2503
|
PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
|
2520
2504
|
be_pid = INT2NUM( pnotification->be_pid );
|
2521
|
-
#ifdef HAVE_ST_NOTIFY_EXTRA
|
2522
2505
|
if ( *pnotification->extra ) {
|
2523
2506
|
extra = rb_tainted_str_new2( pnotification->extra );
|
2524
2507
|
PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
|
2525
2508
|
}
|
2526
|
-
#endif
|
2527
2509
|
PQfreemem( pnotification );
|
2528
2510
|
|
2529
2511
|
if ( rb_block_given_p() )
|
@@ -2542,9 +2524,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2542
2524
|
* not sent (false is only possible if the connection
|
2543
2525
|
* is in nonblocking mode, and this command would block).
|
2544
2526
|
*
|
2545
|
-
*
|
2546
|
-
* This encodes the
|
2547
|
-
*
|
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,
|
2548
2531
|
* if PG::TextEncoder::CopyRow#type_map is set accordingly.
|
2549
2532
|
*
|
2550
2533
|
* Raises an exception if an error occurs.
|
@@ -2581,16 +2564,17 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2581
2564
|
|
2582
2565
|
if( p_coder ){
|
2583
2566
|
t_pg_coder_enc_func enc_func;
|
2567
|
+
int enc_idx = ENCODING_GET(self);
|
2584
2568
|
|
2585
2569
|
enc_func = pg_coder_enc_func( p_coder );
|
2586
|
-
len = enc_func( p_coder, value, NULL, &intermediate );
|
2570
|
+
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
2587
2571
|
|
2588
2572
|
if( len == -1 ){
|
2589
2573
|
/* The intermediate value is a String that can be used directly. */
|
2590
2574
|
buffer = intermediate;
|
2591
2575
|
} else {
|
2592
2576
|
buffer = rb_str_new(NULL, len);
|
2593
|
-
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate);
|
2577
|
+
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate, enc_idx);
|
2594
2578
|
rb_str_set_len( buffer, len );
|
2595
2579
|
}
|
2596
2580
|
}
|
@@ -2629,13 +2613,13 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2629
2613
|
VALUE str;
|
2630
2614
|
VALUE error;
|
2631
2615
|
int ret;
|
2632
|
-
char *error_message = NULL;
|
2616
|
+
const char *error_message = NULL;
|
2633
2617
|
PGconn *conn = pg_get_pgconn(self);
|
2634
2618
|
|
2635
2619
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2636
2620
|
error_message = NULL;
|
2637
2621
|
else
|
2638
|
-
error_message =
|
2622
|
+
error_message = pg_cstr_enc(str, ENCODING_GET(self));
|
2639
2623
|
|
2640
2624
|
ret = gvl_PQputCopyEnd(conn, error_message);
|
2641
2625
|
if(ret == -1) {
|
@@ -2654,8 +2638,9 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2654
2638
|
* if the copy is done, or +false+ if the call would
|
2655
2639
|
* block (only possible if _async_ is true).
|
2656
2640
|
*
|
2657
|
-
*
|
2658
|
-
* 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
|
2659
2644
|
* the decoder can type cast the fields to various Ruby types in one step,
|
2660
2645
|
* if PG::TextDecoder::CopyRow#type_map is set accordingly.
|
2661
2646
|
*
|
@@ -2713,7 +2698,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2713
2698
|
|
2714
2699
|
/*
|
2715
2700
|
* call-seq:
|
2716
|
-
* conn.set_error_verbosity( verbosity ) ->
|
2701
|
+
* conn.set_error_verbosity( verbosity ) -> Integer
|
2717
2702
|
*
|
2718
2703
|
* Sets connection's verbosity to _verbosity_ and returns
|
2719
2704
|
* the previous setting. Available settings are:
|
@@ -2956,12 +2941,10 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
|
|
2956
2941
|
|
2957
2942
|
Check_Type(str, T_STRING);
|
2958
2943
|
|
2959
|
-
if ( (
|
2960
|
-
rb_raise(rb_ePGerror, "
|
2944
|
+
if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
|
2945
|
+
rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
|
2961
2946
|
}
|
2962
|
-
#ifdef M17N_SUPPORTED
|
2963
2947
|
pgconn_set_internal_encoding_index( self );
|
2964
|
-
#endif
|
2965
2948
|
|
2966
2949
|
return Qnil;
|
2967
2950
|
}
|
@@ -3012,8 +2995,10 @@ pgconn_transaction(VALUE self)
|
|
3012
2995
|
|
3013
2996
|
/*
|
3014
2997
|
* call-seq:
|
3015
|
-
* PG::Connection.quote_ident( str ) -> String
|
3016
2998
|
* conn.quote_ident( str ) -> String
|
2999
|
+
* conn.quote_ident( array ) -> String
|
3000
|
+
* PG::Connection.quote_ident( str ) -> String
|
3001
|
+
* PG::Connection.quote_ident( array ) -> String
|
3017
3002
|
*
|
3018
3003
|
* Returns a string that is safe for inclusion in a SQL query as an
|
3019
3004
|
* identifier. Note: this is not a quote function for values, but for
|
@@ -3023,40 +3008,41 @@ pgconn_transaction(VALUE self)
|
|
3023
3008
|
* The identifier <tt>FOO</tt> is folded to lower case, so it actually
|
3024
3009
|
* means <tt>foo</tt>. If you really want to access the case-sensitive
|
3025
3010
|
* field name <tt>FOO</tt>, use this function like
|
3026
|
-
* <tt>
|
3011
|
+
* <tt>conn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
|
3027
3012
|
* (with double-quotes). PostgreSQL will see the double-quotes, and
|
3028
3013
|
* it will not fold to lower case.
|
3029
3014
|
*
|
3030
3015
|
* Similarly, this function also protects against special characters,
|
3031
3016
|
* and other things that might allow SQL injection if the identifier
|
3032
3017
|
* comes from an untrusted source.
|
3018
|
+
*
|
3019
|
+
* If the parameter is an Array, then all it's values are separately quoted
|
3020
|
+
* and then joined by a "." character. This can be used for identifiers in
|
3021
|
+
* the form "schema"."table"."column" .
|
3022
|
+
*
|
3023
|
+
* This method is functional identical to the encoder PG::TextEncoder::Identifier .
|
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.
|
3033
3031
|
*/
|
3034
3032
|
static VALUE
|
3035
|
-
pgconn_s_quote_ident(VALUE self, VALUE
|
3033
|
+
pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
3036
3034
|
{
|
3037
3035
|
VALUE ret;
|
3038
|
-
|
3039
|
-
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
NAMEDATALEN-1);
|
3049
|
-
}
|
3050
|
-
buffer[j++] = '"';
|
3051
|
-
for(i = 0; i < str_len && str[i]; i++) {
|
3052
|
-
if(str[i] == '"')
|
3053
|
-
buffer[j++] = '"';
|
3054
|
-
buffer[j++] = str[i];
|
3055
|
-
}
|
3056
|
-
buffer[j++] = '"';
|
3057
|
-
ret = rb_str_new(buffer,j);
|
3058
|
-
OBJ_INFECT(ret, in_str);
|
3059
|
-
PG_ENCODING_SET_NOCHECK(ret, ENCODING_GET( rb_obj_class(self) == rb_cPGconn ? self : in_str ));
|
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);
|
3044
|
+
|
3045
|
+
OBJ_INFECT(ret, str_or_array);
|
3060
3046
|
|
3061
3047
|
return ret;
|
3062
3048
|
}
|
@@ -3182,13 +3168,93 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3182
3168
|
return rb_pgresult;
|
3183
3169
|
}
|
3184
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
|
+
|
3185
3251
|
/**************************************************************************
|
3186
3252
|
* LARGE OBJECT SUPPORT
|
3187
3253
|
**************************************************************************/
|
3188
3254
|
|
3189
3255
|
/*
|
3190
3256
|
* call-seq:
|
3191
|
-
* conn.lo_creat( [mode] ) ->
|
3257
|
+
* conn.lo_creat( [mode] ) -> Integer
|
3192
3258
|
*
|
3193
3259
|
* Creates a large object with mode _mode_. Returns a large object Oid.
|
3194
3260
|
* On failure, it raises PG::Error.
|
@@ -3215,7 +3281,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
|
3215
3281
|
|
3216
3282
|
/*
|
3217
3283
|
* call-seq:
|
3218
|
-
* conn.lo_create( oid ) ->
|
3284
|
+
* conn.lo_create( oid ) -> Integer
|
3219
3285
|
*
|
3220
3286
|
* Creates a large object with oid _oid_. Returns the large object Oid.
|
3221
3287
|
* On failure, it raises PG::Error.
|
@@ -3236,7 +3302,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
|
3236
3302
|
|
3237
3303
|
/*
|
3238
3304
|
* call-seq:
|
3239
|
-
* conn.lo_import(file) ->
|
3305
|
+
* conn.lo_import(file) -> Integer
|
3240
3306
|
*
|
3241
3307
|
* Import a file to a large object. Returns a large object Oid.
|
3242
3308
|
*
|
@@ -3281,7 +3347,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
|
|
3281
3347
|
|
3282
3348
|
/*
|
3283
3349
|
* call-seq:
|
3284
|
-
* conn.lo_open( oid, [mode] ) ->
|
3350
|
+
* conn.lo_open( oid, [mode] ) -> Integer
|
3285
3351
|
*
|
3286
3352
|
* Open a large object of _oid_. Returns a large object descriptor
|
3287
3353
|
* instance on success. The _mode_ argument specifies the mode for
|
@@ -3312,7 +3378,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
|
|
3312
3378
|
|
3313
3379
|
/*
|
3314
3380
|
* call-seq:
|
3315
|
-
* conn.lo_write( lo_desc, buffer ) ->
|
3381
|
+
* conn.lo_write( lo_desc, buffer ) -> Integer
|
3316
3382
|
*
|
3317
3383
|
* Writes the string _buffer_ to the large object _lo_desc_.
|
3318
3384
|
* Returns the number of bytes written.
|
@@ -3379,7 +3445,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3379
3445
|
|
3380
3446
|
/*
|
3381
3447
|
* call-seq:
|
3382
|
-
* conn.lo_lseek( lo_desc, offset, whence ) ->
|
3448
|
+
* conn.lo_lseek( lo_desc, offset, whence ) -> Integer
|
3383
3449
|
*
|
3384
3450
|
* Move the large object pointer _lo_desc_ to offset _offset_.
|
3385
3451
|
* Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
|
@@ -3401,7 +3467,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
|
|
3401
3467
|
|
3402
3468
|
/*
|
3403
3469
|
* call-seq:
|
3404
|
-
* conn.lo_tell( lo_desc ) ->
|
3470
|
+
* conn.lo_tell( lo_desc ) -> Integer
|
3405
3471
|
*
|
3406
3472
|
* Returns the current position of the large object _lo_desc_.
|
3407
3473
|
*/
|
@@ -3474,8 +3540,6 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
|
|
3474
3540
|
}
|
3475
3541
|
|
3476
3542
|
|
3477
|
-
#ifdef M17N_SUPPORTED
|
3478
|
-
|
3479
3543
|
void
|
3480
3544
|
pgconn_set_internal_encoding_index( VALUE self )
|
3481
3545
|
{
|
@@ -3537,7 +3601,7 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3537
3601
|
rb_encoding *rbenc = rb_to_encoding( enc );
|
3538
3602
|
const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc );
|
3539
3603
|
|
3540
|
-
if (
|
3604
|
+
if ( gvl_PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
|
3541
3605
|
VALUE server_encoding = pgconn_external_encoding( self );
|
3542
3606
|
rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s",
|
3543
3607
|
rb_enc_name(rb_to_encoding(server_encoding)), name );
|
@@ -3579,6 +3643,34 @@ pgconn_external_encoding(VALUE self)
|
|
3579
3643
|
}
|
3580
3644
|
|
3581
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
|
+
|
3582
3674
|
|
3583
3675
|
/*
|
3584
3676
|
* call-seq:
|
@@ -3597,7 +3689,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3597
3689
|
|
3598
3690
|
if (( enc = rb_default_internal_encoding() )) {
|
3599
3691
|
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3600
|
-
if (
|
3692
|
+
if ( pgconn_set_client_encoding_async(self, encname) != 0 )
|
3601
3693
|
rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
|
3602
3694
|
encname, PQerrorMessage(conn) );
|
3603
3695
|
pgconn_set_internal_encoding_index( self );
|
@@ -3609,8 +3701,6 @@ pgconn_set_default_encoding( VALUE self )
|
|
3609
3701
|
}
|
3610
3702
|
|
3611
3703
|
|
3612
|
-
#endif /* M17N_SUPPORTED */
|
3613
|
-
|
3614
3704
|
/*
|
3615
3705
|
* call-seq:
|
3616
3706
|
* res.type_map_for_queries = typemap
|
@@ -3729,7 +3819,7 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE typemap)
|
|
3729
3819
|
*
|
3730
3820
|
* Returns either:
|
3731
3821
|
* * a kind of PG::Coder
|
3732
|
-
* * +nil+ - type encoding is disabled,
|
3822
|
+
* * +nil+ - type encoding is disabled, data must be a String.
|
3733
3823
|
*
|
3734
3824
|
*/
|
3735
3825
|
static VALUE
|
@@ -3790,6 +3880,9 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
3790
3880
|
}
|
3791
3881
|
|
3792
3882
|
|
3883
|
+
/*
|
3884
|
+
* Document-class: PG::Connection
|
3885
|
+
*/
|
3793
3886
|
void
|
3794
3887
|
init_pg_connection()
|
3795
3888
|
{
|
@@ -3816,9 +3909,7 @@ init_pg_connection()
|
|
3816
3909
|
rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
3817
3910
|
rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
|
3818
3911
|
rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
|
3819
|
-
#ifdef HAVE_PQPING
|
3820
3912
|
rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
|
3821
|
-
#endif
|
3822
3913
|
|
3823
3914
|
/****** PG::Connection INSTANCE METHODS: Connection Control ******/
|
3824
3915
|
rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
|
@@ -3835,9 +3926,6 @@ init_pg_connection()
|
|
3835
3926
|
rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
|
3836
3927
|
rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
|
3837
3928
|
rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
|
3838
|
-
#ifdef HAVE_PQHOSTADDR
|
3839
|
-
rb_define_method(rb_cPGconn, "hostaddr", pgconn_hostaddr, 0);
|
3840
|
-
#endif
|
3841
3929
|
rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
|
3842
3930
|
rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
|
3843
3931
|
#ifdef HAVE_PQCONNINFO
|
@@ -3851,9 +3939,7 @@ init_pg_connection()
|
|
3851
3939
|
rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
|
3852
3940
|
rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
|
3853
3941
|
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
|
3854
|
-
#if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
|
3855
3942
|
rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
|
3856
|
-
#endif
|
3857
3943
|
rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
|
3858
3944
|
rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
|
3859
3945
|
rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
|
@@ -3870,17 +3956,11 @@ init_pg_connection()
|
|
3870
3956
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
3871
3957
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
3872
3958
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
3873
|
-
#ifdef HAVE_PQESCAPELITERAL
|
3874
3959
|
rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
|
3875
|
-
#endif
|
3876
|
-
#ifdef HAVE_PQESCAPEIDENTIFIER
|
3877
3960
|
rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
|
3878
|
-
#endif
|
3879
3961
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
3880
3962
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
3881
|
-
#ifdef HAVE_PQSETSINGLEROWMODE
|
3882
3963
|
rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
|
3883
|
-
#endif
|
3884
3964
|
|
3885
3965
|
/****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
|
3886
3966
|
rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
|
@@ -3928,6 +4008,15 @@ init_pg_connection()
|
|
3928
4008
|
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
3929
4009
|
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
3930
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
|
3931
4020
|
|
3932
4021
|
/****** PG::Connection INSTANCE METHODS: Large Object Support ******/
|
3933
4022
|
rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
|
@@ -3957,12 +4046,10 @@ init_pg_connection()
|
|
3957
4046
|
rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
|
3958
4047
|
rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
|
3959
4048
|
|
3960
|
-
#ifdef M17N_SUPPORTED
|
3961
4049
|
rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
|
3962
4050
|
rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
|
3963
4051
|
rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
|
3964
4052
|
rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
|
3965
|
-
#endif /* M17N_SUPPORTED */
|
3966
4053
|
|
3967
4054
|
rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
|
3968
4055
|
rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);
|