pg 0.18.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/BSDL +2 -2
  4. data/ChangeLog +1221 -4
  5. data/History.rdoc +130 -0
  6. data/Manifest.txt +0 -18
  7. data/README-Windows.rdoc +15 -26
  8. data/README.rdoc +16 -10
  9. data/Rakefile +32 -23
  10. data/Rakefile.cross +56 -38
  11. data/ext/errorcodes.def +33 -0
  12. data/ext/errorcodes.txt +15 -1
  13. data/ext/extconf.rb +27 -35
  14. data/ext/gvl_wrappers.c +4 -0
  15. data/ext/gvl_wrappers.h +27 -39
  16. data/ext/pg.c +19 -51
  17. data/ext/pg.h +22 -79
  18. data/ext/pg_binary_decoder.c +3 -1
  19. data/ext/pg_binary_encoder.c +14 -12
  20. data/ext/pg_coder.c +31 -10
  21. data/ext/pg_connection.c +350 -263
  22. data/ext/pg_copy_coder.c +34 -4
  23. data/ext/pg_result.c +27 -25
  24. data/ext/pg_text_decoder.c +9 -10
  25. data/ext/pg_text_encoder.c +93 -73
  26. data/ext/pg_type_map.c +20 -13
  27. data/ext/pg_type_map_by_column.c +7 -7
  28. data/ext/pg_type_map_by_mri_type.c +2 -2
  29. data/ext/pg_type_map_in_ruby.c +4 -7
  30. data/ext/util.c +3 -3
  31. data/ext/util.h +1 -1
  32. data/lib/pg/basic_type_mapping.rb +69 -42
  33. data/lib/pg/connection.rb +89 -38
  34. data/lib/pg/result.rb +10 -5
  35. data/lib/pg/text_decoder.rb +12 -3
  36. data/lib/pg/text_encoder.rb +8 -0
  37. data/lib/pg.rb +18 -10
  38. data/spec/helpers.rb +9 -16
  39. data/spec/pg/basic_type_mapping_spec.rb +58 -4
  40. data/spec/pg/connection_spec.rb +477 -217
  41. data/spec/pg/result_spec.rb +14 -7
  42. data/spec/pg/type_map_by_class_spec.rb +2 -2
  43. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  44. data/spec/pg/type_spec.rb +145 -33
  45. data/spec/pg_spec.rb +1 -1
  46. data.tar.gz.sig +0 -0
  47. metadata +67 -66
  48. metadata.gz.sig +0 -0
  49. data/sample/array_insert.rb +0 -20
  50. data/sample/async_api.rb +0 -106
  51. data/sample/async_copyto.rb +0 -39
  52. data/sample/async_mixed.rb +0 -56
  53. data/sample/check_conn.rb +0 -21
  54. data/sample/copyfrom.rb +0 -81
  55. data/sample/copyto.rb +0 -19
  56. data/sample/cursor.rb +0 -21
  57. data/sample/disk_usage_report.rb +0 -186
  58. data/sample/issue-119.rb +0 -94
  59. data/sample/losample.rb +0 -69
  60. data/sample/minimal-testcase.rb +0 -17
  61. data/sample/notify_wait.rb +0 -72
  62. data/sample/pg_statistics.rb +0 -294
  63. data/sample/replication_monitor.rb +0 -231
  64. data/sample/test_binary_values.rb +0 -33
  65. data/sample/wal_shipper.rb +0 -434
  66. 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 a7befacdef4e 2014/12/12 20:57:14 lars $
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) && defined(HAVE_RB_W32_WRAP_IO_HANDLE)
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) -> Fixnum
346
- * PG::Connection.ping(connection_string) -> Fixnum
347
- * PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Fixnum
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
- * PG::Connection.encrypt_password( password, username ) -> String
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
- * This function is intended to be used by client applications that
416
- * send commands like: +ALTER USER joe PASSWORD 'pwd'+.
417
- * The arguments are the cleartext password, and the SQL name
418
- * of the user it is for.
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() -> Fixnum
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 -> Fixnum
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 user name.
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() -> Fixnum
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 really usable,
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 memoized IO object created from the Connection's underlying socket.
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() -> Fixnum
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
- Check_Type(argv[0], T_STRING);
992
+ VALUE query_str = argv[0];
967
993
 
968
- result = gvl_PQexec(conn, StringValueCStr(argv[0]));
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 => Fixnum (oid of type of bind parameter)
1240
- * :format => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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, &paramsData.params, &in_res_fmt, &paramsData.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( &paramsData );
1293
1323
 
1294
- result = gvl_PQexecParams(conn, StringValueCStr(command), nParams, paramsData.types,
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( &paramsData );
@@ -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
- Check_Type(name, T_STRING);
1343
- Check_Type(command, T_STRING);
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, StringValueCStr(name), StringValueCStr(command),
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 => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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, &paramsData.params, &in_res_fmt, &paramsData.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( &paramsData );
1424
1455
 
1425
- result = gvl_PQexecPrepared(conn, StringValueCStr(name), nParams,
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 == Qnil) {
1484
+ const char *stmt;
1485
+ if(NIL_P(stmt_name)) {
1455
1486
  stmt = NULL;
1456
1487
  }
1457
1488
  else {
1458
- Check_Type(stmt_name, T_STRING);
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 == Qnil) {
1511
+ const char *stmt;
1512
+ if(NIL_P(stmt_name)) {
1483
1513
  stmt = NULL;
1484
1514
  }
1485
1515
  else {
1486
- Check_Type(stmt_name, T_STRING);
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
- escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1);
1553
- if(rb_obj_class(self) == rb_cPGconn) {
1554
- size = PQescapeStringConn(pg_get_pgconn(self), escaped,
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(escaped, RSTRING_PTR(string), RSTRING_LENINT(string));
1597
+ size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1562
1598
  }
1563
- result = rb_str_new(escaped, size);
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(rb_obj_class(self) == rb_cPGconn) {
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, ENCODING_GET(self));
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, but uses libpq to
1690
- * process the string.
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, ENCODING_GET(self));
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 => Fixnum (oid of type of bind parameter)
1787
- * :format => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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, &paramsData.params, &in_res_fmt, &paramsData.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,StringValueCStr(command)) == 0) {
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( &paramsData );
1844
1884
 
1845
- result = gvl_PQsendQueryParams(conn, StringValueCStr(command), nParams, paramsData.types,
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( &paramsData );
@@ -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
- Check_Type(name, T_STRING);
1892
- Check_Type(command, T_STRING);
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, StringValueCStr(name), StringValueCStr(command),
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 => Fixnum (0 for text, 1 for binary)
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 form various Ruby types before transmission
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, &paramsData.params, &in_res_fmt, &paramsData.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( &paramsData );
1974
2015
 
1975
- result = gvl_PQsendQueryPrepared(conn, StringValueCStr(name), nParams,
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,StringValueCStr(stmt_name)) == 0) {
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,StringValueCStr(portal)) == 0) {
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( HAVE_RUBY_VM_H ) && defined( _WIN32 )
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 or Win32+Ruby-1.8 */
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
- * encoder can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2546
- * This encodes the received data fields from an Array of Strings. Optionally
2547
- * the encoder can type cast the fields form various Ruby types in one step,
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 = StringValueCStr(str);
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
- * decoder can be a PG::Coder derivation (typically PG::TextDecoder::CopyRow).
2658
- * This decodes the received data fields as Array of Strings. Optionally
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 ) -> Fixnum
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 ( (PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2960
- rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValueCStr(str));
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>PG::Connection.quote_ident('FOO')</tt>, which will return <tt>"FOO"</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 in_str)
3033
+ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
3036
3034
  {
3037
3035
  VALUE ret;
3038
- char *str = StringValuePtr(in_str);
3039
- /* result size at most NAMEDATALEN*2 plus surrounding
3040
- * double-quotes. */
3041
- char buffer[NAMEDATALEN*2+2];
3042
- unsigned int i=0,j=0;
3043
- unsigned int str_len = RSTRING_LENINT(in_str);
3044
-
3045
- if(str_len >= NAMEDATALEN) {
3046
- rb_raise(rb_eArgError,
3047
- "Input string is longer than NAMEDATALEN-1 (%d)",
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] ) -> Fixnum
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 ) -> Fixnum
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) -> Fixnum
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] ) -> Fixnum
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 ) -> Fixnum
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 ) -> Fixnum
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 ) -> Fixnum
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 ( PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
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 ( PQsetClientEncoding(conn, encname) != 0 )
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, returned data will be a String.
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);