pg 0.18.4 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/BSDL +2 -2
- data/ChangeLog +689 -5
- data/History.rdoc +56 -0
- data/Manifest.txt +1 -18
- data/README.rdoc +13 -9
- data/Rakefile +15 -17
- data/Rakefile.cross +8 -7
- data/ext/errorcodes.def +25 -0
- data/ext/errorcodes.txt +13 -1
- data/ext/extconf.rb +9 -1
- data/ext/gvl_wrappers.h +4 -0
- data/ext/pg.c +4 -3
- data/ext/pg.h +6 -3
- data/ext/pg_binary_encoder.c +8 -8
- data/ext/pg_coder.c +31 -10
- data/ext/pg_connection.c +252 -98
- data/ext/pg_copy_coder.c +34 -4
- data/ext/pg_result.c +20 -14
- 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 +46 -10
- data/lib/pg/deprecated_constants.rb +21 -0
- 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 +21 -9
- data/spec/helpers.rb +6 -9
- data/spec/pg/basic_type_mapping_spec.rb +54 -0
- data/spec/pg/connection_spec.rb +158 -26
- data/spec/pg/result_spec.rb +11 -4
- 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 +82 -2
- data.tar.gz.sig +0 -0
- metadata +50 -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 2e17f315848e 2017/01/14 20:05:06 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -52,7 +52,7 @@ pg_get_connection( VALUE self )
|
|
52
52
|
* Fetch the PG::Connection object data pointer and check it's
|
53
53
|
* PGconn data pointer for sanity.
|
54
54
|
*/
|
55
|
-
t_pg_connection *
|
55
|
+
static t_pg_connection *
|
56
56
|
pg_get_connection_safe( VALUE self )
|
57
57
|
{
|
58
58
|
t_pg_connection *this;
|
@@ -88,7 +88,7 @@ pg_get_pgconn( VALUE self )
|
|
88
88
|
/*
|
89
89
|
* Close the associated socket IO object if there is one.
|
90
90
|
*/
|
91
|
-
void
|
91
|
+
static void
|
92
92
|
pgconn_close_socket_io( VALUE self )
|
93
93
|
{
|
94
94
|
t_pg_connection *this = pg_get_connection( self );
|
@@ -141,6 +141,16 @@ pgconn_make_conninfo_array( const PQconninfoOption *options )
|
|
141
141
|
return ary;
|
142
142
|
}
|
143
143
|
|
144
|
+
static const char *pg_cstr_enc(VALUE str, int enc_idx){
|
145
|
+
const char *ptr = StringValueCStr(str);
|
146
|
+
if( ENCODING_GET(str) == enc_idx ){
|
147
|
+
return ptr;
|
148
|
+
} else {
|
149
|
+
str = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
|
150
|
+
return StringValueCStr(str);
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
144
154
|
|
145
155
|
/*
|
146
156
|
* GC Mark function
|
@@ -342,9 +352,9 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
342
352
|
#ifdef HAVE_PQPING
|
343
353
|
/*
|
344
354
|
* 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) ->
|
355
|
+
* PG::Connection.ping(connection_hash) -> Integer
|
356
|
+
* PG::Connection.ping(connection_string) -> Integer
|
357
|
+
* PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
|
348
358
|
*
|
349
359
|
* Check server status.
|
350
360
|
*
|
@@ -373,7 +383,7 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
|
373
383
|
|
374
384
|
|
375
385
|
/*
|
376
|
-
* Document-method: conndefaults
|
386
|
+
* Document-method: PG::Connection.conndefaults
|
377
387
|
*
|
378
388
|
* call-seq:
|
379
389
|
* PG::Connection.conndefaults() -> Array
|
@@ -447,7 +457,7 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
447
457
|
|
448
458
|
/*
|
449
459
|
* call-seq:
|
450
|
-
* conn.connect_poll() ->
|
460
|
+
* conn.connect_poll() -> Integer
|
451
461
|
*
|
452
462
|
* Returns one of:
|
453
463
|
* [+PGRES_POLLING_READING+]
|
@@ -556,7 +566,7 @@ pgconn_reset_start(VALUE self)
|
|
556
566
|
|
557
567
|
/*
|
558
568
|
* call-seq:
|
559
|
-
* conn.reset_poll ->
|
569
|
+
* conn.reset_poll -> Integer
|
560
570
|
*
|
561
571
|
* Checks the status of a connection reset operation.
|
562
572
|
* See #connect_start and #connect_poll for
|
@@ -795,7 +805,7 @@ pgconn_error_message(VALUE self)
|
|
795
805
|
|
796
806
|
/*
|
797
807
|
* call-seq:
|
798
|
-
* conn.socket() ->
|
808
|
+
* conn.socket() -> Integer
|
799
809
|
*
|
800
810
|
* Returns the socket's file descriptor for this connection.
|
801
811
|
* <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
|
@@ -870,7 +880,7 @@ pgconn_socket_io(VALUE self)
|
|
870
880
|
|
871
881
|
/*
|
872
882
|
* call-seq:
|
873
|
-
* conn.backend_pid() ->
|
883
|
+
* conn.backend_pid() -> Integer
|
874
884
|
*
|
875
885
|
* Returns the process ID of the backend server
|
876
886
|
* process for this connection.
|
@@ -947,9 +957,9 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
947
957
|
|
948
958
|
/* If called with no parameters, use PQexec */
|
949
959
|
if ( argc == 1 ) {
|
950
|
-
|
960
|
+
VALUE query_str = argv[0];
|
951
961
|
|
952
|
-
result = gvl_PQexec(conn,
|
962
|
+
result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
|
953
963
|
rb_pgresult = pg_new_result(result, self);
|
954
964
|
pg_result_check(rb_pgresult);
|
955
965
|
if (rb_block_given_p()) {
|
@@ -978,6 +988,10 @@ struct query_params_data {
|
|
978
988
|
* Filled by caller
|
979
989
|
*/
|
980
990
|
|
991
|
+
/* The character encoding index of the connection. Any strings
|
992
|
+
* given as query parameters are converted to this encoding.
|
993
|
+
*/
|
994
|
+
int enc_idx;
|
981
995
|
/* Is the query function to execute one with types array? */
|
982
996
|
int with_types;
|
983
997
|
/* Array of query params from user space */
|
@@ -1138,7 +1152,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1138
1152
|
VALUE intermediate;
|
1139
1153
|
|
1140
1154
|
/* 1st pass for retiving the required memory space */
|
1141
|
-
int len = enc_func(conv, param_value, NULL, &intermediate);
|
1155
|
+
int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
|
1142
1156
|
|
1143
1157
|
if( len == -1 ){
|
1144
1158
|
/* The intermediate value is a String that can be used directly. */
|
@@ -1162,7 +1176,7 @@ alloc_query_params(struct query_params_data *paramsData)
|
|
1162
1176
|
}
|
1163
1177
|
|
1164
1178
|
/* 2nd pass for writing the data to prepared buffer */
|
1165
|
-
len = enc_func(conv, param_value, typecast_buf, &intermediate);
|
1179
|
+
len = enc_func(conv, param_value, typecast_buf, &intermediate, paramsData->enc_idx);
|
1166
1180
|
paramsData->values[i] = typecast_buf;
|
1167
1181
|
if( paramsData->formats[i] == 0 ){
|
1168
1182
|
/* text format strings must be zero terminated and lengths are ignored */
|
@@ -1220,8 +1234,8 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
|
1220
1234
|
* Each element of the +params+ array may be either:
|
1221
1235
|
* a hash of the form:
|
1222
1236
|
* {:value => String (value of bind parameter)
|
1223
|
-
* :type =>
|
1224
|
-
* :format =>
|
1237
|
+
* :type => Integer (oid of type of bind parameter)
|
1238
|
+
* :format => Integer (0 for text, 1 for binary)
|
1225
1239
|
* }
|
1226
1240
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1227
1241
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1258,7 +1272,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1258
1272
|
VALUE command, in_res_fmt;
|
1259
1273
|
int nParams;
|
1260
1274
|
int resultFormat;
|
1261
|
-
struct query_params_data paramsData;
|
1275
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1262
1276
|
|
1263
1277
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1264
1278
|
paramsData.with_types = 1;
|
@@ -1275,7 +1289,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1275
1289
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1276
1290
|
nParams = alloc_query_params( ¶msData );
|
1277
1291
|
|
1278
|
-
result = gvl_PQexecParams(conn,
|
1292
|
+
result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1279
1293
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1280
1294
|
|
1281
1295
|
free_query_params( ¶msData );
|
@@ -1321,10 +1335,13 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1321
1335
|
int i = 0;
|
1322
1336
|
int nParams = 0;
|
1323
1337
|
Oid *paramTypes = NULL;
|
1338
|
+
const char *name_cstr;
|
1339
|
+
const char *command_cstr;
|
1340
|
+
int enc_idx = ENCODING_GET(self);
|
1324
1341
|
|
1325
1342
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1326
|
-
|
1327
|
-
|
1343
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1344
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1328
1345
|
|
1329
1346
|
if(! NIL_P(in_paramtypes)) {
|
1330
1347
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1338,8 +1355,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1338
1355
|
paramTypes[i] = NUM2UINT(param);
|
1339
1356
|
}
|
1340
1357
|
}
|
1341
|
-
result = gvl_PQprepare(conn,
|
1342
|
-
nParams, paramTypes);
|
1358
|
+
result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1343
1359
|
|
1344
1360
|
xfree(paramTypes);
|
1345
1361
|
|
@@ -1361,7 +1377,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
1361
1377
|
* SQL query. Each element of the +params+ array may be either:
|
1362
1378
|
* a hash of the form:
|
1363
1379
|
* {:value => String (value of bind parameter)
|
1364
|
-
* :format =>
|
1380
|
+
* :format => Integer (0 for text, 1 for binary)
|
1365
1381
|
* }
|
1366
1382
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1367
1383
|
* { :value => <string value>, :format => 0 }
|
@@ -1392,11 +1408,10 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1392
1408
|
VALUE name, in_res_fmt;
|
1393
1409
|
int nParams;
|
1394
1410
|
int resultFormat;
|
1395
|
-
struct query_params_data paramsData;
|
1411
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1396
1412
|
|
1397
1413
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1398
1414
|
paramsData.with_types = 0;
|
1399
|
-
Check_Type(name, T_STRING);
|
1400
1415
|
|
1401
1416
|
if(NIL_P(paramsData.params)) {
|
1402
1417
|
paramsData.params = rb_ary_new2(0);
|
@@ -1406,7 +1421,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1406
1421
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1407
1422
|
nParams = alloc_query_params( ¶msData );
|
1408
1423
|
|
1409
|
-
result = gvl_PQexecPrepared(conn,
|
1424
|
+
result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1410
1425
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1411
1426
|
resultFormat);
|
1412
1427
|
|
@@ -1434,13 +1449,12 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1434
1449
|
PGresult *result;
|
1435
1450
|
VALUE rb_pgresult;
|
1436
1451
|
PGconn *conn = pg_get_pgconn(self);
|
1437
|
-
char *stmt;
|
1438
|
-
if(stmt_name
|
1452
|
+
const char *stmt;
|
1453
|
+
if(NIL_P(stmt_name)) {
|
1439
1454
|
stmt = NULL;
|
1440
1455
|
}
|
1441
1456
|
else {
|
1442
|
-
|
1443
|
-
stmt = StringValueCStr(stmt_name);
|
1457
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1444
1458
|
}
|
1445
1459
|
result = gvl_PQdescribePrepared(conn, stmt);
|
1446
1460
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1462,13 +1476,12 @@ pgconn_describe_portal(self, stmt_name)
|
|
1462
1476
|
PGresult *result;
|
1463
1477
|
VALUE rb_pgresult;
|
1464
1478
|
PGconn *conn = pg_get_pgconn(self);
|
1465
|
-
char *stmt;
|
1466
|
-
if(stmt_name
|
1479
|
+
const char *stmt;
|
1480
|
+
if(NIL_P(stmt_name)) {
|
1467
1481
|
stmt = NULL;
|
1468
1482
|
}
|
1469
1483
|
else {
|
1470
|
-
|
1471
|
-
stmt = StringValueCStr(stmt_name);
|
1484
|
+
stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
|
1472
1485
|
}
|
1473
1486
|
result = gvl_PQdescribePortal(conn, stmt);
|
1474
1487
|
rb_pgresult = pg_new_result(result, self);
|
@@ -1510,10 +1523,6 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1510
1523
|
* call-seq:
|
1511
1524
|
* conn.escape_string( str ) -> String
|
1512
1525
|
*
|
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
1526
|
* Returns a SQL-safe version of the String _str_.
|
1518
1527
|
* This is the preferred way to make strings safe for inclusion in
|
1519
1528
|
* SQL queries.
|
@@ -1522,32 +1531,41 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1522
1531
|
* inside of SQL commands.
|
1523
1532
|
*
|
1524
1533
|
* Encoding of escaped string will be equal to client encoding of connection.
|
1534
|
+
*
|
1535
|
+
* NOTE: This class version of this method can only be used safely in client
|
1536
|
+
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1537
|
+
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1538
|
+
* results if used in programs that use multiple database connections; use the
|
1539
|
+
* same method on the connection object in such cases.
|
1525
1540
|
*/
|
1526
1541
|
static VALUE
|
1527
1542
|
pgconn_s_escape(VALUE self, VALUE string)
|
1528
1543
|
{
|
1529
|
-
char *escaped;
|
1530
1544
|
size_t size;
|
1531
1545
|
int error;
|
1532
1546
|
VALUE result;
|
1547
|
+
int enc_idx;
|
1548
|
+
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1533
1549
|
|
1534
1550
|
Check_Type(string, T_STRING);
|
1551
|
+
enc_idx = ENCODING_GET( singleton ? string : self );
|
1552
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1553
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1554
|
+
}
|
1535
1555
|
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1556
|
+
result = rb_str_new(NULL, RSTRING_LEN(string) * 2 + 1);
|
1557
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1558
|
+
if( !singleton ) {
|
1559
|
+
size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
|
1539
1560
|
RSTRING_PTR(string), RSTRING_LEN(string), &error);
|
1540
1561
|
if(error) {
|
1541
|
-
xfree(escaped);
|
1542
1562
|
rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
|
1543
1563
|
}
|
1544
1564
|
} else {
|
1545
|
-
size = PQescapeString(
|
1565
|
+
size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
|
1546
1566
|
}
|
1547
|
-
result
|
1548
|
-
xfree(escaped);
|
1567
|
+
rb_str_set_len(result, size);
|
1549
1568
|
OBJ_INFECT(result, string);
|
1550
|
-
PG_ENCODING_SET_NOCHECK(result, ENCODING_GET( rb_obj_is_kind_of(self, rb_cPGconn) ? self : string ));
|
1551
1569
|
|
1552
1570
|
return result;
|
1553
1571
|
}
|
@@ -1556,13 +1574,6 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1556
1574
|
* call-seq:
|
1557
1575
|
* conn.escape_bytea( string ) -> String
|
1558
1576
|
*
|
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
1577
|
* Escapes binary data for use within an SQL command with the type +bytea+.
|
1567
1578
|
*
|
1568
1579
|
* Certain byte values must be escaped (but all byte values may be escaped)
|
@@ -1575,6 +1586,12 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1575
1586
|
*
|
1576
1587
|
* Consider using exec_params, which avoids the need for passing values inside of
|
1577
1588
|
* SQL commands.
|
1589
|
+
*
|
1590
|
+
* NOTE: This class version of this method can only be used safely in client
|
1591
|
+
* programs that use a single PostgreSQL connection at a time (in this case it can
|
1592
|
+
* find out what it needs to know "behind the scenes"). It might give the wrong
|
1593
|
+
* results if used in programs that use multiple database connections; use the
|
1594
|
+
* same method on the connection object in such cases.
|
1578
1595
|
*/
|
1579
1596
|
static VALUE
|
1580
1597
|
pgconn_s_escape_bytea(VALUE self, VALUE str)
|
@@ -1643,8 +1660,12 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1643
1660
|
char *escaped = NULL;
|
1644
1661
|
VALUE error;
|
1645
1662
|
VALUE result = Qnil;
|
1663
|
+
int enc_idx = ENCODING_GET(self);
|
1646
1664
|
|
1647
1665
|
Check_Type(string, T_STRING);
|
1666
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1667
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1668
|
+
}
|
1648
1669
|
|
1649
1670
|
escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1650
1671
|
if (escaped == NULL)
|
@@ -1657,7 +1678,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1657
1678
|
result = rb_str_new2(escaped);
|
1658
1679
|
PQfreemem(escaped);
|
1659
1680
|
OBJ_INFECT(result, string);
|
1660
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1681
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1661
1682
|
|
1662
1683
|
return result;
|
1663
1684
|
}
|
@@ -1670,8 +1691,9 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1670
1691
|
*
|
1671
1692
|
* Escape an arbitrary String +str+ as an identifier.
|
1672
1693
|
*
|
1673
|
-
* This method does the same as #quote_ident
|
1674
|
-
*
|
1694
|
+
* This method does the same as #quote_ident with a String argument,
|
1695
|
+
* but it doesn't support an Array argument and it makes use of libpq
|
1696
|
+
* to process the string.
|
1675
1697
|
*/
|
1676
1698
|
static VALUE
|
1677
1699
|
pgconn_escape_identifier(VALUE self, VALUE string)
|
@@ -1680,8 +1702,12 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1680
1702
|
char *escaped = NULL;
|
1681
1703
|
VALUE error;
|
1682
1704
|
VALUE result = Qnil;
|
1705
|
+
int enc_idx = ENCODING_GET(self);
|
1683
1706
|
|
1684
1707
|
Check_Type(string, T_STRING);
|
1708
|
+
if( ENCODING_GET(string) != enc_idx ){
|
1709
|
+
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1710
|
+
}
|
1685
1711
|
|
1686
1712
|
escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1687
1713
|
if (escaped == NULL)
|
@@ -1694,7 +1720,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1694
1720
|
result = rb_str_new2(escaped);
|
1695
1721
|
PQfreemem(escaped);
|
1696
1722
|
OBJ_INFECT(result, string);
|
1697
|
-
PG_ENCODING_SET_NOCHECK(result,
|
1723
|
+
PG_ENCODING_SET_NOCHECK(result, enc_idx);
|
1698
1724
|
|
1699
1725
|
return result;
|
1700
1726
|
}
|
@@ -1767,8 +1793,8 @@ pgconn_set_single_row_mode(VALUE self)
|
|
1767
1793
|
* Each element of the +params+ array may be either:
|
1768
1794
|
* a hash of the form:
|
1769
1795
|
* {:value => String (value of bind parameter)
|
1770
|
-
* :type =>
|
1771
|
-
* :format =>
|
1796
|
+
* :type => Integer (oid of type of bind parameter)
|
1797
|
+
* :format => Integer (0 for text, 1 for binary)
|
1772
1798
|
* }
|
1773
1799
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1774
1800
|
* { :value => <string value>, :type => 0, :format => 0 }
|
@@ -1802,15 +1828,14 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1802
1828
|
VALUE error;
|
1803
1829
|
int nParams;
|
1804
1830
|
int resultFormat;
|
1805
|
-
struct query_params_data paramsData;
|
1831
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1806
1832
|
|
1807
1833
|
rb_scan_args(argc, argv, "13", &command, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1808
1834
|
paramsData.with_types = 1;
|
1809
|
-
Check_Type(command, T_STRING);
|
1810
1835
|
|
1811
1836
|
/* If called with no parameters, use PQsendQuery */
|
1812
1837
|
if(NIL_P(paramsData.params)) {
|
1813
|
-
if(gvl_PQsendQuery(conn,
|
1838
|
+
if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
|
1814
1839
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1815
1840
|
rb_iv_set(error, "@connection", self);
|
1816
1841
|
rb_exc_raise(error);
|
@@ -1826,7 +1851,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1826
1851
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1827
1852
|
nParams = alloc_query_params( ¶msData );
|
1828
1853
|
|
1829
|
-
result = gvl_PQsendQueryParams(conn,
|
1854
|
+
result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
|
1830
1855
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
|
1831
1856
|
|
1832
1857
|
free_query_params( ¶msData );
|
@@ -1870,10 +1895,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1870
1895
|
int i = 0;
|
1871
1896
|
int nParams = 0;
|
1872
1897
|
Oid *paramTypes = NULL;
|
1898
|
+
const char *name_cstr;
|
1899
|
+
const char *command_cstr;
|
1900
|
+
int enc_idx = ENCODING_GET(self);
|
1873
1901
|
|
1874
1902
|
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1875
|
-
|
1876
|
-
|
1903
|
+
name_cstr = pg_cstr_enc(name, enc_idx);
|
1904
|
+
command_cstr = pg_cstr_enc(command, enc_idx);
|
1877
1905
|
|
1878
1906
|
if(! NIL_P(in_paramtypes)) {
|
1879
1907
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1887,8 +1915,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1887
1915
|
paramTypes[i] = NUM2UINT(param);
|
1888
1916
|
}
|
1889
1917
|
}
|
1890
|
-
result = gvl_PQsendPrepare(conn,
|
1891
|
-
nParams, paramTypes);
|
1918
|
+
result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
|
1892
1919
|
|
1893
1920
|
xfree(paramTypes);
|
1894
1921
|
|
@@ -1913,7 +1940,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1913
1940
|
* SQL query. Each element of the +params+ array may be either:
|
1914
1941
|
* a hash of the form:
|
1915
1942
|
* {:value => String (value of bind parameter)
|
1916
|
-
* :format =>
|
1943
|
+
* :format => Integer (0 for text, 1 for binary)
|
1917
1944
|
* }
|
1918
1945
|
* or, it may be a String. If it is a string, that is equivalent to the hash:
|
1919
1946
|
* { :value => <string value>, :format => 0 }
|
@@ -1941,11 +1968,10 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1941
1968
|
VALUE error;
|
1942
1969
|
int nParams;
|
1943
1970
|
int resultFormat;
|
1944
|
-
struct query_params_data paramsData;
|
1971
|
+
struct query_params_data paramsData = { ENCODING_GET(self) };
|
1945
1972
|
|
1946
1973
|
rb_scan_args(argc, argv, "13", &name, ¶msData.params, &in_res_fmt, ¶msData.typemap);
|
1947
1974
|
paramsData.with_types = 0;
|
1948
|
-
Check_Type(name, T_STRING);
|
1949
1975
|
|
1950
1976
|
if(NIL_P(paramsData.params)) {
|
1951
1977
|
paramsData.params = rb_ary_new2(0);
|
@@ -1956,7 +1982,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1956
1982
|
resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
|
1957
1983
|
nParams = alloc_query_params( ¶msData );
|
1958
1984
|
|
1959
|
-
result = gvl_PQsendQueryPrepared(conn,
|
1985
|
+
result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
|
1960
1986
|
(const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
|
1961
1987
|
resultFormat);
|
1962
1988
|
|
@@ -1983,7 +2009,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1983
2009
|
VALUE error;
|
1984
2010
|
PGconn *conn = pg_get_pgconn(self);
|
1985
2011
|
/* returns 0 on failure */
|
1986
|
-
if(gvl_PQsendDescribePrepared(conn,
|
2012
|
+
if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
|
1987
2013
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1988
2014
|
rb_iv_set(error, "@connection", self);
|
1989
2015
|
rb_exc_raise(error);
|
@@ -2005,7 +2031,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
2005
2031
|
VALUE error;
|
2006
2032
|
PGconn *conn = pg_get_pgconn(self);
|
2007
2033
|
/* returns 0 on failure */
|
2008
|
-
if(gvl_PQsendDescribePortal(conn,
|
2034
|
+
if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
|
2009
2035
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
2010
2036
|
rb_iv_set(error, "@connection", self);
|
2011
2037
|
rb_exc_raise(error);
|
@@ -2565,16 +2591,17 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
|
|
2565
2591
|
|
2566
2592
|
if( p_coder ){
|
2567
2593
|
t_pg_coder_enc_func enc_func;
|
2594
|
+
int enc_idx = ENCODING_GET(self);
|
2568
2595
|
|
2569
2596
|
enc_func = pg_coder_enc_func( p_coder );
|
2570
|
-
len = enc_func( p_coder, value, NULL, &intermediate );
|
2597
|
+
len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
|
2571
2598
|
|
2572
2599
|
if( len == -1 ){
|
2573
2600
|
/* The intermediate value is a String that can be used directly. */
|
2574
2601
|
buffer = intermediate;
|
2575
2602
|
} else {
|
2576
2603
|
buffer = rb_str_new(NULL, len);
|
2577
|
-
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate);
|
2604
|
+
len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate, enc_idx);
|
2578
2605
|
rb_str_set_len( buffer, len );
|
2579
2606
|
}
|
2580
2607
|
}
|
@@ -2613,13 +2640,13 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2613
2640
|
VALUE str;
|
2614
2641
|
VALUE error;
|
2615
2642
|
int ret;
|
2616
|
-
char *error_message = NULL;
|
2643
|
+
const char *error_message = NULL;
|
2617
2644
|
PGconn *conn = pg_get_pgconn(self);
|
2618
2645
|
|
2619
2646
|
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2620
2647
|
error_message = NULL;
|
2621
2648
|
else
|
2622
|
-
error_message =
|
2649
|
+
error_message = pg_cstr_enc(str, ENCODING_GET(self));
|
2623
2650
|
|
2624
2651
|
ret = gvl_PQputCopyEnd(conn, error_message);
|
2625
2652
|
if(ret == -1) {
|
@@ -2697,7 +2724,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
|
2697
2724
|
|
2698
2725
|
/*
|
2699
2726
|
* call-seq:
|
2700
|
-
* conn.set_error_verbosity( verbosity ) ->
|
2727
|
+
* conn.set_error_verbosity( verbosity ) -> Integer
|
2701
2728
|
*
|
2702
2729
|
* Sets connection's verbosity to _verbosity_ and returns
|
2703
2730
|
* the previous setting. Available settings are:
|
@@ -2940,7 +2967,7 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
|
|
2940
2967
|
|
2941
2968
|
Check_Type(str, T_STRING);
|
2942
2969
|
|
2943
|
-
if ( (
|
2970
|
+
if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
|
2944
2971
|
rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValueCStr(str));
|
2945
2972
|
}
|
2946
2973
|
#ifdef M17N_SUPPORTED
|
@@ -2996,10 +3023,10 @@ pgconn_transaction(VALUE self)
|
|
2996
3023
|
|
2997
3024
|
/*
|
2998
3025
|
* call-seq:
|
2999
|
-
* PG::Connection.quote_ident( str ) -> String
|
3000
|
-
* PG::Connection.quote_ident( array ) -> String
|
3001
3026
|
* conn.quote_ident( str ) -> String
|
3002
3027
|
* conn.quote_ident( array ) -> String
|
3028
|
+
* PG::Connection.quote_ident( str ) -> String
|
3029
|
+
* PG::Connection.quote_ident( array ) -> String
|
3003
3030
|
*
|
3004
3031
|
* Returns a string that is safe for inclusion in a SQL query as an
|
3005
3032
|
* identifier. Note: this is not a quote function for values, but for
|
@@ -3009,7 +3036,7 @@ pgconn_transaction(VALUE self)
|
|
3009
3036
|
* The identifier <tt>FOO</tt> is folded to lower case, so it actually
|
3010
3037
|
* means <tt>foo</tt>. If you really want to access the case-sensitive
|
3011
3038
|
* field name <tt>FOO</tt>, use this function like
|
3012
|
-
* <tt>
|
3039
|
+
* <tt>conn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
|
3013
3040
|
* (with double-quotes). PostgreSQL will see the double-quotes, and
|
3014
3041
|
* it will not fold to lower case.
|
3015
3042
|
*
|
@@ -3023,15 +3050,27 @@ pgconn_transaction(VALUE self)
|
|
3023
3050
|
*
|
3024
3051
|
* This method is functional identical to the encoder PG::TextEncoder::Identifier .
|
3025
3052
|
*
|
3053
|
+
* If the instance method form is used and the input string character encoding
|
3054
|
+
* is different to the connection encoding, then the string is converted to this
|
3055
|
+
* encoding, so that the returned string is always encoded as PG::Connection#internal_encoding .
|
3056
|
+
*
|
3057
|
+
* In the singleton form (PG::Connection.quote_ident) the character encoding
|
3058
|
+
* of the result string is set to the character encoding of the input string.
|
3026
3059
|
*/
|
3027
3060
|
static VALUE
|
3028
|
-
pgconn_s_quote_ident(VALUE self, VALUE
|
3061
|
+
pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
|
3029
3062
|
{
|
3030
3063
|
VALUE ret;
|
3031
|
-
|
3064
|
+
int enc_idx;
|
3032
3065
|
|
3033
|
-
|
3034
|
-
|
3066
|
+
if( rb_obj_is_kind_of(self, rb_cPGconn) ){
|
3067
|
+
enc_idx = ENCODING_GET( self );
|
3068
|
+
}else{
|
3069
|
+
enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
|
3070
|
+
}
|
3071
|
+
pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
|
3072
|
+
|
3073
|
+
OBJ_INFECT(ret, str_or_array);
|
3035
3074
|
|
3036
3075
|
return ret;
|
3037
3076
|
}
|
@@ -3157,13 +3196,91 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3157
3196
|
return rb_pgresult;
|
3158
3197
|
}
|
3159
3198
|
|
3199
|
+
|
3200
|
+
#ifdef HAVE_PQSSLATTRIBUTE
|
3201
|
+
/* Since PostgreSQL-9.5: */
|
3202
|
+
|
3203
|
+
/*
|
3204
|
+
* call-seq:
|
3205
|
+
* conn.ssl_in_use? -> Boolean
|
3206
|
+
*
|
3207
|
+
* Returns +true+ if the connection uses SSL, +false+ if not.
|
3208
|
+
*
|
3209
|
+
*/
|
3210
|
+
static VALUE
|
3211
|
+
pgconn_ssl_in_use(VALUE self)
|
3212
|
+
{
|
3213
|
+
return PQsslInUse(pg_get_pgconn(self)) ? Qtrue : Qfalse;
|
3214
|
+
}
|
3215
|
+
|
3216
|
+
|
3217
|
+
/*
|
3218
|
+
* call-seq:
|
3219
|
+
* conn.ssl_attribute(attribute_name) -> String
|
3220
|
+
*
|
3221
|
+
* Returns SSL-related information about the connection.
|
3222
|
+
*
|
3223
|
+
* The list of available attributes varies depending on the SSL library being used,
|
3224
|
+
* and the type of connection. If an attribute is not available, returns nil.
|
3225
|
+
*
|
3226
|
+
* The following attributes are commonly available:
|
3227
|
+
*
|
3228
|
+
* [+library+]
|
3229
|
+
* Name of the SSL implementation in use. (Currently, only "OpenSSL" is implemented)
|
3230
|
+
* [+protocol+]
|
3231
|
+
* 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.
|
3232
|
+
* [+key_bits+]
|
3233
|
+
* Number of key bits used by the encryption algorithm.
|
3234
|
+
* [+cipher+]
|
3235
|
+
* A short name of the ciphersuite used, e.g. "DHE-RSA-DES-CBC3-SHA". The names are specific to each SSL implementation.
|
3236
|
+
* [+compression+]
|
3237
|
+
* If SSL compression is in use, returns the name of the compression algorithm, or "on" if compression is used but the algorithm is not known. If compression is not in use, returns "off".
|
3238
|
+
*
|
3239
|
+
*
|
3240
|
+
* See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
|
3241
|
+
*/
|
3242
|
+
static VALUE
|
3243
|
+
pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
|
3244
|
+
{
|
3245
|
+
const char *p_attr;
|
3246
|
+
|
3247
|
+
p_attr = PQsslAttribute(pg_get_pgconn(self), StringValueCStr(attribute_name));
|
3248
|
+
return p_attr ? rb_str_new_cstr(p_attr) : Qnil;
|
3249
|
+
}
|
3250
|
+
|
3251
|
+
/*
|
3252
|
+
* call-seq:
|
3253
|
+
* conn.ssl_attribute_names -> Array<String>
|
3254
|
+
*
|
3255
|
+
* Return an array of SSL attribute names available.
|
3256
|
+
*
|
3257
|
+
* See also #ssl_attribute
|
3258
|
+
*
|
3259
|
+
*/
|
3260
|
+
static VALUE
|
3261
|
+
pgconn_ssl_attribute_names(VALUE self)
|
3262
|
+
{
|
3263
|
+
int i;
|
3264
|
+
const char * const * p_list = PQsslAttributeNames(pg_get_pgconn(self));
|
3265
|
+
VALUE ary = rb_ary_new();
|
3266
|
+
|
3267
|
+
for ( i = 0; p_list[i]; i++ ) {
|
3268
|
+
rb_ary_push( ary, rb_str_new_cstr( p_list[i] ));
|
3269
|
+
}
|
3270
|
+
return ary;
|
3271
|
+
}
|
3272
|
+
|
3273
|
+
|
3274
|
+
#endif
|
3275
|
+
|
3276
|
+
|
3160
3277
|
/**************************************************************************
|
3161
3278
|
* LARGE OBJECT SUPPORT
|
3162
3279
|
**************************************************************************/
|
3163
3280
|
|
3164
3281
|
/*
|
3165
3282
|
* call-seq:
|
3166
|
-
* conn.lo_creat( [mode] ) ->
|
3283
|
+
* conn.lo_creat( [mode] ) -> Integer
|
3167
3284
|
*
|
3168
3285
|
* Creates a large object with mode _mode_. Returns a large object Oid.
|
3169
3286
|
* On failure, it raises PG::Error.
|
@@ -3190,7 +3307,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
|
3190
3307
|
|
3191
3308
|
/*
|
3192
3309
|
* call-seq:
|
3193
|
-
* conn.lo_create( oid ) ->
|
3310
|
+
* conn.lo_create( oid ) -> Integer
|
3194
3311
|
*
|
3195
3312
|
* Creates a large object with oid _oid_. Returns the large object Oid.
|
3196
3313
|
* On failure, it raises PG::Error.
|
@@ -3211,7 +3328,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
|
3211
3328
|
|
3212
3329
|
/*
|
3213
3330
|
* call-seq:
|
3214
|
-
* conn.lo_import(file) ->
|
3331
|
+
* conn.lo_import(file) -> Integer
|
3215
3332
|
*
|
3216
3333
|
* Import a file to a large object. Returns a large object Oid.
|
3217
3334
|
*
|
@@ -3256,7 +3373,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
|
|
3256
3373
|
|
3257
3374
|
/*
|
3258
3375
|
* call-seq:
|
3259
|
-
* conn.lo_open( oid, [mode] ) ->
|
3376
|
+
* conn.lo_open( oid, [mode] ) -> Integer
|
3260
3377
|
*
|
3261
3378
|
* Open a large object of _oid_. Returns a large object descriptor
|
3262
3379
|
* instance on success. The _mode_ argument specifies the mode for
|
@@ -3287,7 +3404,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
|
|
3287
3404
|
|
3288
3405
|
/*
|
3289
3406
|
* call-seq:
|
3290
|
-
* conn.lo_write( lo_desc, buffer ) ->
|
3407
|
+
* conn.lo_write( lo_desc, buffer ) -> Integer
|
3291
3408
|
*
|
3292
3409
|
* Writes the string _buffer_ to the large object _lo_desc_.
|
3293
3410
|
* Returns the number of bytes written.
|
@@ -3354,7 +3471,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
|
3354
3471
|
|
3355
3472
|
/*
|
3356
3473
|
* call-seq:
|
3357
|
-
* conn.lo_lseek( lo_desc, offset, whence ) ->
|
3474
|
+
* conn.lo_lseek( lo_desc, offset, whence ) -> Integer
|
3358
3475
|
*
|
3359
3476
|
* Move the large object pointer _lo_desc_ to offset _offset_.
|
3360
3477
|
* Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
|
@@ -3376,7 +3493,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
|
|
3376
3493
|
|
3377
3494
|
/*
|
3378
3495
|
* call-seq:
|
3379
|
-
* conn.lo_tell( lo_desc ) ->
|
3496
|
+
* conn.lo_tell( lo_desc ) -> Integer
|
3380
3497
|
*
|
3381
3498
|
* Returns the current position of the large object _lo_desc_.
|
3382
3499
|
*/
|
@@ -3512,7 +3629,7 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3512
3629
|
rb_encoding *rbenc = rb_to_encoding( enc );
|
3513
3630
|
const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc );
|
3514
3631
|
|
3515
|
-
if (
|
3632
|
+
if ( gvl_PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
|
3516
3633
|
VALUE server_encoding = pgconn_external_encoding( self );
|
3517
3634
|
rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s",
|
3518
3635
|
rb_enc_name(rb_to_encoding(server_encoding)), name );
|
@@ -3554,6 +3671,34 @@ pgconn_external_encoding(VALUE self)
|
|
3554
3671
|
}
|
3555
3672
|
|
3556
3673
|
|
3674
|
+
static VALUE
|
3675
|
+
pgconn_set_client_encoding_async1( VALUE args )
|
3676
|
+
{
|
3677
|
+
VALUE self = ((VALUE*)args)[0];
|
3678
|
+
VALUE encname = ((VALUE*)args)[1];
|
3679
|
+
VALUE query_format = rb_str_new_cstr("set client_encoding to '%s'");
|
3680
|
+
VALUE query = rb_funcall(query_format, rb_intern("%"), 1, encname);
|
3681
|
+
|
3682
|
+
pgconn_async_exec(1, &query, self);
|
3683
|
+
return 0;
|
3684
|
+
}
|
3685
|
+
|
3686
|
+
|
3687
|
+
static VALUE
|
3688
|
+
pgconn_set_client_encoding_async2( VALUE arg )
|
3689
|
+
{
|
3690
|
+
UNUSED(arg);
|
3691
|
+
return 1;
|
3692
|
+
}
|
3693
|
+
|
3694
|
+
|
3695
|
+
static VALUE
|
3696
|
+
pgconn_set_client_encoding_async( VALUE self, const char *encname )
|
3697
|
+
{
|
3698
|
+
VALUE args[] = { self, rb_str_new_cstr(encname) };
|
3699
|
+
return rb_rescue(pgconn_set_client_encoding_async1, (VALUE)&args, pgconn_set_client_encoding_async2, Qnil);
|
3700
|
+
}
|
3701
|
+
|
3557
3702
|
|
3558
3703
|
/*
|
3559
3704
|
* call-seq:
|
@@ -3572,7 +3717,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3572
3717
|
|
3573
3718
|
if (( enc = rb_default_internal_encoding() )) {
|
3574
3719
|
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3575
|
-
if (
|
3720
|
+
if ( pgconn_set_client_encoding_async(self, encname) != 0 )
|
3576
3721
|
rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
|
3577
3722
|
encname, PQerrorMessage(conn) );
|
3578
3723
|
pgconn_set_internal_encoding_index( self );
|
@@ -3704,7 +3849,7 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE typemap)
|
|
3704
3849
|
*
|
3705
3850
|
* Returns either:
|
3706
3851
|
* * a kind of PG::Coder
|
3707
|
-
* * +nil+ - type encoding is disabled,
|
3852
|
+
* * +nil+ - type encoding is disabled, data must be a String.
|
3708
3853
|
*
|
3709
3854
|
*/
|
3710
3855
|
static VALUE
|
@@ -3765,6 +3910,9 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
|
|
3765
3910
|
}
|
3766
3911
|
|
3767
3912
|
|
3913
|
+
/*
|
3914
|
+
* Document-class: PG::Connection
|
3915
|
+
*/
|
3768
3916
|
void
|
3769
3917
|
init_pg_connection()
|
3770
3918
|
{
|
@@ -3901,6 +4049,12 @@ init_pg_connection()
|
|
3901
4049
|
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
3902
4050
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
|
3903
4051
|
|
4052
|
+
#ifdef HAVE_PQSSLATTRIBUTE
|
4053
|
+
rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
|
4054
|
+
rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
|
4055
|
+
rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
|
4056
|
+
#endif
|
4057
|
+
|
3904
4058
|
/****** PG::Connection INSTANCE METHODS: Large Object Support ******/
|
3905
4059
|
rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
|
3906
4060
|
rb_define_alias(rb_cPGconn, "locreat", "lo_creat");
|