pg 0.18.4 → 1.0.0

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