pg 0.18.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) 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 +200 -0
  6. data/Manifest.txt +5 -18
  7. data/README-Windows.rdoc +15 -26
  8. data/README.rdoc +27 -10
  9. data/Rakefile +33 -24
  10. data/Rakefile.cross +57 -39
  11. data/ext/errorcodes.def +37 -0
  12. data/ext/errorcodes.rb +1 -1
  13. data/ext/errorcodes.txt +16 -1
  14. data/ext/extconf.rb +29 -35
  15. data/ext/gvl_wrappers.c +4 -0
  16. data/ext/gvl_wrappers.h +27 -39
  17. data/ext/pg.c +27 -53
  18. data/ext/pg.h +66 -83
  19. data/ext/pg_binary_decoder.c +75 -6
  20. data/ext/pg_binary_encoder.c +14 -12
  21. data/ext/pg_coder.c +83 -13
  22. data/ext/pg_connection.c +627 -351
  23. data/ext/pg_copy_coder.c +44 -9
  24. data/ext/pg_result.c +364 -134
  25. data/ext/pg_text_decoder.c +605 -46
  26. data/ext/pg_text_encoder.c +95 -76
  27. data/ext/pg_tuple.c +541 -0
  28. data/ext/pg_type_map.c +20 -13
  29. data/ext/pg_type_map_by_column.c +7 -7
  30. data/ext/pg_type_map_by_mri_type.c +2 -2
  31. data/ext/pg_type_map_in_ruby.c +4 -7
  32. data/ext/util.c +7 -7
  33. data/ext/util.h +3 -3
  34. data/lib/pg/basic_type_mapping.rb +105 -45
  35. data/lib/pg/binary_decoder.rb +22 -0
  36. data/lib/pg/coder.rb +1 -1
  37. data/lib/pg/connection.rb +109 -39
  38. data/lib/pg/constants.rb +1 -1
  39. data/lib/pg/exceptions.rb +1 -1
  40. data/lib/pg/result.rb +11 -6
  41. data/lib/pg/text_decoder.rb +25 -20
  42. data/lib/pg/text_encoder.rb +43 -1
  43. data/lib/pg/tuple.rb +30 -0
  44. data/lib/pg/type_map_by_column.rb +1 -1
  45. data/lib/pg.rb +21 -11
  46. data/spec/helpers.rb +50 -25
  47. data/spec/pg/basic_type_mapping_spec.rb +287 -30
  48. data/spec/pg/connection_spec.rb +695 -282
  49. data/spec/pg/connection_sync_spec.rb +41 -0
  50. data/spec/pg/result_spec.rb +59 -17
  51. data/spec/pg/tuple_spec.rb +280 -0
  52. data/spec/pg/type_map_by_class_spec.rb +3 -3
  53. data/spec/pg/type_map_by_column_spec.rb +1 -1
  54. data/spec/pg/type_map_by_mri_type_spec.rb +2 -2
  55. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  56. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  57. data/spec/pg/type_map_spec.rb +1 -1
  58. data/spec/pg/type_spec.rb +319 -35
  59. data/spec/pg_spec.rb +2 -2
  60. data.tar.gz.sig +0 -0
  61. metadata +68 -68
  62. metadata.gz.sig +0 -0
  63. data/sample/array_insert.rb +0 -20
  64. data/sample/async_api.rb +0 -106
  65. data/sample/async_copyto.rb +0 -39
  66. data/sample/async_mixed.rb +0 -56
  67. data/sample/check_conn.rb +0 -21
  68. data/sample/copyfrom.rb +0 -81
  69. data/sample/copyto.rb +0 -19
  70. data/sample/cursor.rb +0 -21
  71. data/sample/disk_usage_report.rb +0 -186
  72. data/sample/issue-119.rb +0 -94
  73. data/sample/losample.rb +0 -69
  74. data/sample/minimal-testcase.rb +0 -17
  75. data/sample/notify_wait.rb +0 -72
  76. data/sample/pg_statistics.rb +0 -294
  77. data/sample/replication_monitor.rb +0 -231
  78. data/sample/test_binary_values.rb +0 -33
  79. data/sample/wal_shipper.rb +0 -434
  80. 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$
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,16 +77,15 @@ 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)
99
- int ruby_sd = NUM2INT(rb_funcall( socket_io, rb_intern("fileno"), 0 ));
100
- if( rb_w32_unwrap_io_handle(ruby_sd) ){
87
+ #if defined(_WIN32)
88
+ if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
101
89
  rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
102
90
  }
103
91
  #endif
@@ -141,6 +129,16 @@ pgconn_make_conninfo_array( const PQconninfoOption *options )
141
129
  return ary;
142
130
  }
143
131
 
132
+ static const char *pg_cstr_enc(VALUE str, int enc_idx){
133
+ const char *ptr = StringValueCStr(str);
134
+ if( ENCODING_GET(str) == enc_idx ){
135
+ return ptr;
136
+ } else {
137
+ str = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
138
+ return StringValueCStr(str);
139
+ }
140
+ }
141
+
144
142
 
145
143
  /*
146
144
  * GC Mark function
@@ -166,6 +164,10 @@ pgconn_gc_mark( t_pg_connection *this )
166
164
  static void
167
165
  pgconn_gc_free( t_pg_connection *this )
168
166
  {
167
+ #if defined(_WIN32)
168
+ if ( RTEST(this->socket_io) )
169
+ rb_w32_unwrap_io_handle( this->ruby_sd );
170
+ #endif
169
171
  if (this->pgconn != NULL)
170
172
  PQfinish( this->pgconn );
171
173
 
@@ -199,6 +201,7 @@ pgconn_s_allocate( VALUE klass )
199
201
  this->decoder_for_get_copy_data = Qnil;
200
202
  this->trace_stream = Qnil;
201
203
  this->external_encoding = Qnil;
204
+ this->guess_result_memsize = 1;
202
205
 
203
206
  return self;
204
207
  }
@@ -281,9 +284,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
281
284
  rb_exc_raise(error);
282
285
  }
283
286
 
284
- #ifdef M17N_SUPPORTED
285
287
  pgconn_set_default_encoding( self );
286
- #endif
287
288
 
288
289
  if (rb_block_given_p()) {
289
290
  return rb_ensure(rb_yield, self, pgconn_finish, self);
@@ -339,12 +340,11 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
339
340
  return rb_conn;
340
341
  }
341
342
 
342
- #ifdef HAVE_PQPING
343
343
  /*
344
344
  * 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
345
+ * PG::Connection.ping(connection_hash) -> Integer
346
+ * PG::Connection.ping(connection_string) -> Integer
347
+ * PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
348
348
  *
349
349
  * Check server status.
350
350
  *
@@ -357,6 +357,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
357
357
  * could not establish connection
358
358
  * [+PQPING_NO_ATTEMPT+]
359
359
  * connection not attempted (bad params)
360
+ *
361
+ * Available since PostgreSQL-9.1
360
362
  */
361
363
  static VALUE
362
364
  pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
@@ -369,11 +371,10 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
369
371
 
370
372
  return INT2FIX((int)ping);
371
373
  }
372
- #endif
373
374
 
374
375
 
375
376
  /*
376
- * Document-method: conndefaults
377
+ * Document-method: PG::Connection.conndefaults
377
378
  *
378
379
  * call-seq:
379
380
  * PG::Connection.conndefaults() -> Array
@@ -408,16 +409,65 @@ pgconn_s_conndefaults(VALUE self)
408
409
  }
409
410
 
410
411
 
412
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
411
413
  /*
412
414
  * call-seq:
413
- * PG::Connection.encrypt_password( password, username ) -> String
415
+ * conn.encrypt_password( password, username, algorithm=nil ) -> String
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
+ * This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
418
+ * 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.
419
+ * Instead, use this function to convert the password to encrypted form before it is sent.
420
+ *
421
+ * The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
422
+ * +algorithm+ specifies the encryption algorithm to use to encrypt the password.
423
+ * 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).
424
+ * Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
425
+ * If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
426
+ * That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
427
+ * 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
428
  *
420
429
  * Return value is the encrypted password.
430
+ * The caller can assume the string doesn't contain any special characters that would require escaping.
431
+ *
432
+ * Available since PostgreSQL-10
433
+ */
434
+ static VALUE
435
+ pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
436
+ {
437
+ char *encrypted = NULL;
438
+ VALUE rval = Qnil;
439
+ VALUE password, username, algorithm;
440
+ PGconn *conn = pg_get_pgconn(self);
441
+
442
+ rb_scan_args( argc, argv, "21", &password, &username, &algorithm );
443
+
444
+ Check_Type(password, T_STRING);
445
+ Check_Type(username, T_STRING);
446
+
447
+ encrypted = gvl_PQencryptPasswordConn(conn, StringValueCStr(password), StringValueCStr(username), RTEST(algorithm) ? StringValueCStr(algorithm) : NULL);
448
+ if ( encrypted ) {
449
+ rval = rb_str_new2( encrypted );
450
+ PQfreemem( encrypted );
451
+
452
+ OBJ_INFECT( rval, password );
453
+ OBJ_INFECT( rval, username );
454
+ OBJ_INFECT( rval, algorithm );
455
+ } else {
456
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
457
+ }
458
+
459
+ return rval;
460
+ }
461
+ #endif
462
+
463
+
464
+ /*
465
+ * call-seq:
466
+ * PG::Connection.encrypt_password( password, username ) -> String
467
+ *
468
+ * This is an older, deprecated version of #encrypt_password.
469
+ * The difference is that this function always uses +md5+ as the encryption algorithm.
470
+ *
421
471
  */
422
472
  static VALUE
423
473
  pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
@@ -447,7 +497,7 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
447
497
 
448
498
  /*
449
499
  * call-seq:
450
- * conn.connect_poll() -> Fixnum
500
+ * conn.connect_poll() -> Integer
451
501
  *
452
502
  * Returns one of:
453
503
  * [+PGRES_POLLING_READING+]
@@ -556,7 +606,7 @@ pgconn_reset_start(VALUE self)
556
606
 
557
607
  /*
558
608
  * call-seq:
559
- * conn.reset_poll -> Fixnum
609
+ * conn.reset_poll -> Integer
560
610
  *
561
611
  * Checks the status of a connection reset operation.
562
612
  * See #connect_start and #connect_poll for
@@ -603,7 +653,7 @@ pgconn_user(VALUE self)
603
653
  * call-seq:
604
654
  * conn.pass()
605
655
  *
606
- * Returns the authenticated user name.
656
+ * Returns the authenticated password.
607
657
  */
608
658
  static VALUE
609
659
  pgconn_pass(VALUE self)
@@ -627,22 +677,6 @@ pgconn_host(VALUE self)
627
677
  return rb_tainted_str_new2(host);
628
678
  }
629
679
 
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
680
  /*
647
681
  * call-seq:
648
682
  * conn.port()
@@ -692,6 +726,7 @@ pgconn_options(VALUE self)
692
726
  *
693
727
  * Returns the connection options used by a live connection.
694
728
  *
729
+ * Available since PostgreSQL-9.3
695
730
  */
696
731
  static VALUE
697
732
  pgconn_conninfo( VALUE self )
@@ -811,7 +846,9 @@ pgconn_error_message(VALUE self)
811
846
 
812
847
  /*
813
848
  * call-seq:
814
- * conn.socket() -> Fixnum
849
+ * conn.socket() -> Integer
850
+ *
851
+ * This method is deprecated. Please use the more portable method #socket_io .
815
852
  *
816
853
  * Returns the socket's file descriptor for this connection.
817
854
  * <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
@@ -821,7 +858,7 @@ pgconn_error_message(VALUE self)
821
858
  * creates an IO that's associated with the connection object itself,
822
859
  * and so won't go out of scope until the connection does.
823
860
  *
824
- * *Note:* On Windows the file descriptor is not really usable,
861
+ * *Note:* On Windows the file descriptor is not usable,
825
862
  * since it can not be used to build a Ruby IO object.
826
863
  */
827
864
  static VALUE
@@ -833,22 +870,17 @@ pgconn_socket(VALUE self)
833
870
  return INT2NUM(sd);
834
871
  }
835
872
 
836
-
837
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
838
-
839
873
  /*
840
874
  * call-seq:
841
875
  * conn.socket_io() -> IO
842
876
  *
843
- * Fetch a memoized IO object created from the Connection's underlying socket.
877
+ * Fetch a memorized IO object created from the Connection's underlying socket.
844
878
  * This object can be used for IO.select to wait for events while running
845
879
  * asynchronous API calls.
846
880
  *
847
881
  * Using this instead of #socket avoids the problem of the underlying connection
848
882
  * 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+.
883
+ * goes out of scope. In contrast to #socket, it also works on Windows.
852
884
  */
853
885
  static VALUE
854
886
  pgconn_socket_io(VALUE self)
@@ -865,16 +897,15 @@ pgconn_socket_io(VALUE self)
865
897
 
866
898
  #ifdef _WIN32
867
899
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
900
+ this->ruby_sd = ruby_sd;
868
901
  #else
869
902
  ruby_sd = sd;
870
903
  #endif
871
904
 
872
905
  socket_io = rb_funcall( rb_cIO, rb_intern("for_fd"), 1, INT2NUM(ruby_sd) );
873
906
 
874
- /* Disable autoclose feature, when supported */
875
- if( rb_respond_to(socket_io, id_autoclose) ){
876
- rb_funcall( socket_io, id_autoclose, 1, Qfalse );
877
- }
907
+ /* Disable autoclose feature */
908
+ rb_funcall( socket_io, id_autoclose, 1, Qfalse );
878
909
 
879
910
  this->socket_io = socket_io;
880
911
  }
@@ -882,11 +913,9 @@ pgconn_socket_io(VALUE self)
882
913
  return socket_io;
883
914
  }
884
915
 
885
- #endif
886
-
887
916
  /*
888
917
  * call-seq:
889
- * conn.backend_pid() -> Fixnum
918
+ * conn.backend_pid() -> Integer
890
919
  *
891
920
  * Returns the process ID of the backend server
892
921
  * process for this connection.
@@ -936,7 +965,7 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
936
965
  * conn.exec(sql) {|pg_result| block }
937
966
  *
938
967
  * Sends SQL query request specified by _sql_ to PostgreSQL.
939
- * Returns a PG::Result instance on success.
968
+ * On success, it returns a PG::Result instance with all result rows and columns.
940
969
  * On failure, it raises a PG::Error.
941
970
  *
942
971
  * For backward compatibility, if you pass more than one parameter to this method,
@@ -947,9 +976,9 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
947
976
  * and the PG::Result object will automatically be cleared when the block terminates.
948
977
  * In this instance, <code>conn.exec</code> returns the value of the block.
949
978
  *
950
- * #exec is implemented on the synchronous command processing API of libpq, whereas
979
+ * #sync_exec is implemented on the synchronous command processing API of libpq, whereas
951
980
  * #async_exec is implemented on the asynchronous API.
952
- * #exec is somewhat faster that #async_exec, but blocks any signals to be processed until
981
+ * #sync_exec is somewhat faster that #async_exec, but blocks any signals to be processed until
953
982
  * the query is finished. This is most notably visible by a delayed reaction to Control+C.
954
983
  * Both methods ensure that other threads can process while waiting for the server to
955
984
  * complete the request.
@@ -961,11 +990,11 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
961
990
  PGresult *result = NULL;
962
991
  VALUE rb_pgresult;
963
992
 
964
- /* If called with no parameters, use PQexec */
965
- if ( argc == 1 ) {
966
- Check_Type(argv[0], T_STRING);
993
+ /* If called with no or nil parameters, use PQexec for compatibility */
994
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
995
+ VALUE query_str = argv[0];
967
996
 
968
- result = gvl_PQexec(conn, StringValueCStr(argv[0]));
997
+ result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
969
998
  rb_pgresult = pg_new_result(result, self);
970
999
  pg_result_check(rb_pgresult);
971
1000
  if (rb_block_given_p()) {
@@ -973,11 +1002,10 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
973
1002
  }
974
1003
  return rb_pgresult;
975
1004
  }
1005
+ pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
976
1006
 
977
1007
  /* Otherwise, just call #exec_params instead for backward-compatibility */
978
- else {
979
- return pgconn_exec_params( argc, argv, self );
980
- }
1008
+ return pgconn_exec_params( argc, argv, self );
981
1009
 
982
1010
  }
983
1011
 
@@ -994,6 +1022,10 @@ struct query_params_data {
994
1022
  * Filled by caller
995
1023
  */
996
1024
 
1025
+ /* The character encoding index of the connection. Any strings
1026
+ * given as query parameters are converted to this encoding.
1027
+ */
1028
+ int enc_idx;
997
1029
  /* Is the query function to execute one with types array? */
998
1030
  int with_types;
999
1031
  /* Array of query params from user space */
@@ -1154,7 +1186,7 @@ alloc_query_params(struct query_params_data *paramsData)
1154
1186
  VALUE intermediate;
1155
1187
 
1156
1188
  /* 1st pass for retiving the required memory space */
1157
- int len = enc_func(conv, param_value, NULL, &intermediate);
1189
+ int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
1158
1190
 
1159
1191
  if( len == -1 ){
1160
1192
  /* The intermediate value is a String that can be used directly. */
@@ -1178,7 +1210,7 @@ alloc_query_params(struct query_params_data *paramsData)
1178
1210
  }
1179
1211
 
1180
1212
  /* 2nd pass for writing the data to prepared buffer */
1181
- len = enc_func(conv, param_value, typecast_buf, &intermediate);
1213
+ len = enc_func(conv, param_value, typecast_buf, &intermediate, paramsData->enc_idx);
1182
1214
  paramsData->values[i] = typecast_buf;
1183
1215
  if( paramsData->formats[i] == 0 ){
1184
1216
  /* text format strings must be zero terminated and lengths are ignored */
@@ -1236,8 +1268,8 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1236
1268
  * Each element of the +params+ array may be either:
1237
1269
  * a hash of the form:
1238
1270
  * {:value => String (value of bind parameter)
1239
- * :type => Fixnum (oid of type of bind parameter)
1240
- * :format => Fixnum (0 for text, 1 for binary)
1271
+ * :type => Integer (oid of type of bind parameter)
1272
+ * :format => Integer (0 for text, 1 for binary)
1241
1273
  * }
1242
1274
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1243
1275
  * { :value => <string value>, :type => 0, :format => 0 }
@@ -1256,7 +1288,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1256
1288
  * for binary.
1257
1289
  *
1258
1290
  * 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
1291
+ * This will type cast the params from various Ruby types before transmission
1260
1292
  * based on the encoders defined by the type map. When a type encoder is used
1261
1293
  * the format and oid of a given bind parameter are retrieved from the encoder
1262
1294
  * instead out of the hash form described above.
@@ -1274,16 +1306,18 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1274
1306
  VALUE command, in_res_fmt;
1275
1307
  int nParams;
1276
1308
  int resultFormat;
1277
- struct query_params_data paramsData;
1309
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1278
1310
 
1311
+ /* For compatibility we accept 1 to 4 parameters */
1279
1312
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1280
1313
  paramsData.with_types = 1;
1281
1314
 
1282
1315
  /*
1283
- * Handle the edge-case where the caller is coming from #exec, but passed an explict +nil+
1284
- * for the second parameter.
1316
+ * For backward compatibility no or +nil+ for the second parameter
1317
+ * is passed to #exec
1285
1318
  */
1286
1319
  if ( NIL_P(paramsData.params) ) {
1320
+ pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
1287
1321
  return pgconn_exec( 1, argv, self );
1288
1322
  }
1289
1323
  pgconn_query_assign_typemap( self, &paramsData );
@@ -1291,7 +1325,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1291
1325
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1292
1326
  nParams = alloc_query_params( &paramsData );
1293
1327
 
1294
- result = gvl_PQexecParams(conn, StringValueCStr(command), nParams, paramsData.types,
1328
+ result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1295
1329
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1296
1330
 
1297
1331
  free_query_params( &paramsData );
@@ -1337,10 +1371,13 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1337
1371
  int i = 0;
1338
1372
  int nParams = 0;
1339
1373
  Oid *paramTypes = NULL;
1374
+ const char *name_cstr;
1375
+ const char *command_cstr;
1376
+ int enc_idx = ENCODING_GET(self);
1340
1377
 
1341
1378
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1342
- Check_Type(name, T_STRING);
1343
- Check_Type(command, T_STRING);
1379
+ name_cstr = pg_cstr_enc(name, enc_idx);
1380
+ command_cstr = pg_cstr_enc(command, enc_idx);
1344
1381
 
1345
1382
  if(! NIL_P(in_paramtypes)) {
1346
1383
  Check_Type(in_paramtypes, T_ARRAY);
@@ -1354,8 +1391,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1354
1391
  paramTypes[i] = NUM2UINT(param);
1355
1392
  }
1356
1393
  }
1357
- result = gvl_PQprepare(conn, StringValueCStr(name), StringValueCStr(command),
1358
- nParams, paramTypes);
1394
+ result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1359
1395
 
1360
1396
  xfree(paramTypes);
1361
1397
 
@@ -1377,7 +1413,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1377
1413
  * SQL query. Each element of the +params+ array may be either:
1378
1414
  * a hash of the form:
1379
1415
  * {:value => String (value of bind parameter)
1380
- * :format => Fixnum (0 for text, 1 for binary)
1416
+ * :format => Integer (0 for text, 1 for binary)
1381
1417
  * }
1382
1418
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1383
1419
  * { :value => <string value>, :format => 0 }
@@ -1390,7 +1426,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1390
1426
  * for binary.
1391
1427
  *
1392
1428
  * 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
1429
+ * This will type cast the params from various Ruby types before transmission
1394
1430
  * based on the encoders defined by the type map. When a type encoder is used
1395
1431
  * the format and oid of a given bind parameter are retrieved from the encoder
1396
1432
  * instead out of the hash form described above.
@@ -1408,11 +1444,10 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1408
1444
  VALUE name, in_res_fmt;
1409
1445
  int nParams;
1410
1446
  int resultFormat;
1411
- struct query_params_data paramsData;
1447
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1412
1448
 
1413
1449
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1414
1450
  paramsData.with_types = 0;
1415
- Check_Type(name, T_STRING);
1416
1451
 
1417
1452
  if(NIL_P(paramsData.params)) {
1418
1453
  paramsData.params = rb_ary_new2(0);
@@ -1422,7 +1457,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1422
1457
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1423
1458
  nParams = alloc_query_params( &paramsData );
1424
1459
 
1425
- result = gvl_PQexecPrepared(conn, StringValueCStr(name), nParams,
1460
+ result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1426
1461
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1427
1462
  resultFormat);
1428
1463
 
@@ -1450,13 +1485,12 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1450
1485
  PGresult *result;
1451
1486
  VALUE rb_pgresult;
1452
1487
  PGconn *conn = pg_get_pgconn(self);
1453
- char *stmt;
1454
- if(stmt_name == Qnil) {
1488
+ const char *stmt;
1489
+ if(NIL_P(stmt_name)) {
1455
1490
  stmt = NULL;
1456
1491
  }
1457
1492
  else {
1458
- Check_Type(stmt_name, T_STRING);
1459
- stmt = StringValueCStr(stmt_name);
1493
+ stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1460
1494
  }
1461
1495
  result = gvl_PQdescribePrepared(conn, stmt);
1462
1496
  rb_pgresult = pg_new_result(result, self);
@@ -1478,13 +1512,12 @@ pgconn_describe_portal(self, stmt_name)
1478
1512
  PGresult *result;
1479
1513
  VALUE rb_pgresult;
1480
1514
  PGconn *conn = pg_get_pgconn(self);
1481
- char *stmt;
1482
- if(stmt_name == Qnil) {
1515
+ const char *stmt;
1516
+ if(NIL_P(stmt_name)) {
1483
1517
  stmt = NULL;
1484
1518
  }
1485
1519
  else {
1486
- Check_Type(stmt_name, T_STRING);
1487
- stmt = StringValueCStr(stmt_name);
1520
+ stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1488
1521
  }
1489
1522
  result = gvl_PQdescribePortal(conn, stmt);
1490
1523
  rb_pgresult = pg_new_result(result, self);
@@ -1526,10 +1559,6 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1526
1559
  * call-seq:
1527
1560
  * conn.escape_string( str ) -> String
1528
1561
  *
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
1562
  * Returns a SQL-safe version of the String _str_.
1534
1563
  * This is the preferred way to make strings safe for inclusion in
1535
1564
  * SQL queries.
@@ -1538,32 +1567,41 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1538
1567
  * inside of SQL commands.
1539
1568
  *
1540
1569
  * Encoding of escaped string will be equal to client encoding of connection.
1570
+ *
1571
+ * NOTE: This class version of this method can only be used safely in client
1572
+ * programs that use a single PostgreSQL connection at a time (in this case it can
1573
+ * find out what it needs to know "behind the scenes"). It might give the wrong
1574
+ * results if used in programs that use multiple database connections; use the
1575
+ * same method on the connection object in such cases.
1541
1576
  */
1542
1577
  static VALUE
1543
1578
  pgconn_s_escape(VALUE self, VALUE string)
1544
1579
  {
1545
- char *escaped;
1546
1580
  size_t size;
1547
1581
  int error;
1548
1582
  VALUE result;
1583
+ int enc_idx;
1584
+ int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
1549
1585
 
1550
- Check_Type(string, T_STRING);
1586
+ StringValueCStr(string);
1587
+ enc_idx = ENCODING_GET( singleton ? string : self );
1588
+ if( ENCODING_GET(string) != enc_idx ){
1589
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1590
+ }
1551
1591
 
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,
1592
+ result = rb_str_new(NULL, RSTRING_LEN(string) * 2 + 1);
1593
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1594
+ if( !singleton ) {
1595
+ size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1555
1596
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1556
1597
  if(error) {
1557
- xfree(escaped);
1558
1598
  rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1559
1599
  }
1560
1600
  } else {
1561
- size = PQescapeString(escaped, RSTRING_PTR(string), RSTRING_LENINT(string));
1601
+ size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1562
1602
  }
1563
- result = rb_str_new(escaped, size);
1564
- xfree(escaped);
1603
+ rb_str_set_len(result, size);
1565
1604
  OBJ_INFECT(result, string);
1566
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET( rb_obj_class(self) == rb_cPGconn ? self : string ));
1567
1605
 
1568
1606
  return result;
1569
1607
  }
@@ -1572,13 +1610,6 @@ pgconn_s_escape(VALUE self, VALUE string)
1572
1610
  * call-seq:
1573
1611
  * conn.escape_bytea( string ) -> String
1574
1612
  *
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
1613
  * Escapes binary data for use within an SQL command with the type +bytea+.
1583
1614
  *
1584
1615
  * Certain byte values must be escaped (but all byte values may be escaped)
@@ -1591,6 +1622,12 @@ pgconn_s_escape(VALUE self, VALUE string)
1591
1622
  *
1592
1623
  * Consider using exec_params, which avoids the need for passing values inside of
1593
1624
  * SQL commands.
1625
+ *
1626
+ * NOTE: This class version of this method can only be used safely in client
1627
+ * programs that use a single PostgreSQL connection at a time (in this case it can
1628
+ * find out what it needs to know "behind the scenes"). It might give the wrong
1629
+ * results if used in programs that use multiple database connections; use the
1630
+ * same method on the connection object in such cases.
1594
1631
  */
1595
1632
  static VALUE
1596
1633
  pgconn_s_escape_bytea(VALUE self, VALUE str)
@@ -1603,7 +1640,7 @@ pgconn_s_escape_bytea(VALUE self, VALUE str)
1603
1640
  from = (unsigned char*)RSTRING_PTR(str);
1604
1641
  from_len = RSTRING_LEN(str);
1605
1642
 
1606
- if(rb_obj_class(self) == rb_cPGconn) {
1643
+ if ( rb_obj_is_kind_of(self, rb_cPGconn) ) {
1607
1644
  to = PQescapeByteaConn(pg_get_pgconn(self), from, from_len, &to_len);
1608
1645
  } else {
1609
1646
  to = PQescapeBytea( from, from_len, &to_len);
@@ -1645,12 +1682,13 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
1645
1682
  return ret;
1646
1683
  }
1647
1684
 
1648
- #ifdef HAVE_PQESCAPELITERAL
1649
1685
  /*
1650
1686
  * call-seq:
1651
1687
  * conn.escape_literal( str ) -> String
1652
1688
  *
1653
1689
  * Escape an arbitrary String +str+ as a literal.
1690
+ *
1691
+ * Available since PostgreSQL-9.0
1654
1692
  */
1655
1693
  static VALUE
1656
1694
  pgconn_escape_literal(VALUE self, VALUE string)
@@ -1659,8 +1697,12 @@ pgconn_escape_literal(VALUE self, VALUE string)
1659
1697
  char *escaped = NULL;
1660
1698
  VALUE error;
1661
1699
  VALUE result = Qnil;
1700
+ int enc_idx = ENCODING_GET(self);
1662
1701
 
1663
- Check_Type(string, T_STRING);
1702
+ StringValueCStr(string);
1703
+ if( ENCODING_GET(string) != enc_idx ){
1704
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1705
+ }
1664
1706
 
1665
1707
  escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1666
1708
  if (escaped == NULL)
@@ -1673,21 +1715,22 @@ pgconn_escape_literal(VALUE self, VALUE string)
1673
1715
  result = rb_str_new2(escaped);
1674
1716
  PQfreemem(escaped);
1675
1717
  OBJ_INFECT(result, string);
1676
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET(self));
1718
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1677
1719
 
1678
1720
  return result;
1679
1721
  }
1680
- #endif
1681
1722
 
1682
- #ifdef HAVE_PQESCAPEIDENTIFIER
1683
1723
  /*
1684
1724
  * call-seq:
1685
1725
  * conn.escape_identifier( str ) -> String
1686
1726
  *
1687
1727
  * Escape an arbitrary String +str+ as an identifier.
1688
1728
  *
1689
- * This method does the same as #quote_ident, but uses libpq to
1690
- * process the string.
1729
+ * This method does the same as #quote_ident with a String argument,
1730
+ * but it doesn't support an Array argument and it makes use of libpq
1731
+ * to process the string.
1732
+ *
1733
+ * Available since PostgreSQL-9.0
1691
1734
  */
1692
1735
  static VALUE
1693
1736
  pgconn_escape_identifier(VALUE self, VALUE string)
@@ -1696,8 +1739,12 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1696
1739
  char *escaped = NULL;
1697
1740
  VALUE error;
1698
1741
  VALUE result = Qnil;
1742
+ int enc_idx = ENCODING_GET(self);
1699
1743
 
1700
- Check_Type(string, T_STRING);
1744
+ StringValueCStr(string);
1745
+ if( ENCODING_GET(string) != enc_idx ){
1746
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1747
+ }
1701
1748
 
1702
1749
  escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1703
1750
  if (escaped == NULL)
@@ -1710,13 +1757,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1710
1757
  result = rb_str_new2(escaped);
1711
1758
  PQfreemem(escaped);
1712
1759
  OBJ_INFECT(result, string);
1713
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET(self));
1760
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1714
1761
 
1715
1762
  return result;
1716
1763
  }
1717
- #endif
1718
1764
 
1719
- #ifdef HAVE_PQSETSINGLEROWMODE
1720
1765
  /*
1721
1766
  * call-seq:
1722
1767
  * conn.set_single_row_mode -> self
@@ -1753,6 +1798,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1753
1798
  * end
1754
1799
  * end
1755
1800
  *
1801
+ * Available since PostgreSQL-9.2
1756
1802
  */
1757
1803
  static VALUE
1758
1804
  pgconn_set_single_row_mode(VALUE self)
@@ -1769,22 +1815,60 @@ pgconn_set_single_row_mode(VALUE self)
1769
1815
 
1770
1816
  return self;
1771
1817
  }
1772
- #endif
1818
+
1819
+ static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1820
+
1821
+ /*
1822
+ * call-seq:
1823
+ * conn.send_query(sql) -> nil
1824
+ *
1825
+ * Sends SQL query request specified by _sql_ to PostgreSQL for
1826
+ * asynchronous processing, and immediately returns.
1827
+ * On failure, it raises a PG::Error.
1828
+ *
1829
+ * For backward compatibility, if you pass more than one parameter to this method,
1830
+ * it will call #send_query_params for you. New code should explicitly use #send_query_params if
1831
+ * argument placeholders are used.
1832
+ *
1833
+ */
1834
+ static VALUE
1835
+ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1836
+ {
1837
+ PGconn *conn = pg_get_pgconn(self);
1838
+ VALUE error;
1839
+
1840
+ /* If called with no or nil parameters, use PQexec for compatibility */
1841
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1842
+ if(gvl_PQsendQuery(conn, pg_cstr_enc(argv[0], ENCODING_GET(self))) == 0) {
1843
+ error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1844
+ rb_iv_set(error, "@connection", self);
1845
+ rb_exc_raise(error);
1846
+ }
1847
+ return Qnil;
1848
+ }
1849
+
1850
+ pg_deprecated(2, ("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
1851
+
1852
+ /* If called with parameters, and optionally result_format,
1853
+ * use PQsendQueryParams
1854
+ */
1855
+ return pgconn_send_query_params( argc, argv, self);
1856
+ }
1773
1857
 
1774
1858
  /*
1775
1859
  * call-seq:
1776
- * conn.send_query(sql [, params, result_format[, type_map ]] ) -> nil
1860
+ * conn.send_query_params(sql, params [, result_format [, type_map ]] ) -> nil
1777
1861
  *
1778
1862
  * Sends SQL query request specified by _sql_ to PostgreSQL for
1779
1863
  * asynchronous processing, and immediately returns.
1780
1864
  * On failure, it raises a PG::Error.
1781
1865
  *
1782
- * +params+ is an optional array of the bind parameters for the SQL query.
1866
+ * +params+ is an array of the bind parameters for the SQL query.
1783
1867
  * Each element of the +params+ array may be either:
1784
1868
  * a hash of the form:
1785
1869
  * {:value => String (value of bind parameter)
1786
- * :type => Fixnum (oid of type of bind parameter)
1787
- * :format => Fixnum (0 for text, 1 for binary)
1870
+ * :type => Integer (oid of type of bind parameter)
1871
+ * :format => Integer (0 for text, 1 for binary)
1788
1872
  * }
1789
1873
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1790
1874
  * { :value => <string value>, :type => 0, :format => 0 }
@@ -1803,14 +1887,14 @@ pgconn_set_single_row_mode(VALUE self)
1803
1887
  * for binary.
1804
1888
  *
1805
1889
  * 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
1890
+ * This will type cast the params from various Ruby types before transmission
1807
1891
  * based on the encoders defined by the type map. When a type encoder is used
1808
1892
  * the format and oid of a given bind parameter are retrieved from the encoder
1809
1893
  * instead out of the hash form described above.
1810
1894
  *
1811
1895
  */
1812
1896
  static VALUE
1813
- pgconn_send_query(int argc, VALUE *argv, VALUE self)
1897
+ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1814
1898
  {
1815
1899
  PGconn *conn = pg_get_pgconn(self);
1816
1900
  int result;
@@ -1818,31 +1902,16 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1818
1902
  VALUE error;
1819
1903
  int nParams;
1820
1904
  int resultFormat;
1821
- struct query_params_data paramsData;
1905
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1822
1906
 
1823
- rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1907
+ rb_scan_args(argc, argv, "22", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1824
1908
  paramsData.with_types = 1;
1825
- Check_Type(command, T_STRING);
1826
-
1827
- /* If called with no parameters, use PQsendQuery */
1828
- if(NIL_P(paramsData.params)) {
1829
- if(gvl_PQsendQuery(conn,StringValueCStr(command)) == 0) {
1830
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1831
- rb_iv_set(error, "@connection", self);
1832
- rb_exc_raise(error);
1833
- }
1834
- return Qnil;
1835
- }
1836
-
1837
- /* If called with parameters, and optionally result_format,
1838
- * use PQsendQueryParams
1839
- */
1840
1909
 
1841
1910
  pgconn_query_assign_typemap( self, &paramsData );
1842
1911
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1843
1912
  nParams = alloc_query_params( &paramsData );
1844
1913
 
1845
- result = gvl_PQsendQueryParams(conn, StringValueCStr(command), nParams, paramsData.types,
1914
+ result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1846
1915
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1847
1916
 
1848
1917
  free_query_params( &paramsData );
@@ -1886,10 +1955,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1886
1955
  int i = 0;
1887
1956
  int nParams = 0;
1888
1957
  Oid *paramTypes = NULL;
1958
+ const char *name_cstr;
1959
+ const char *command_cstr;
1960
+ int enc_idx = ENCODING_GET(self);
1889
1961
 
1890
1962
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1891
- Check_Type(name, T_STRING);
1892
- Check_Type(command, T_STRING);
1963
+ name_cstr = pg_cstr_enc(name, enc_idx);
1964
+ command_cstr = pg_cstr_enc(command, enc_idx);
1893
1965
 
1894
1966
  if(! NIL_P(in_paramtypes)) {
1895
1967
  Check_Type(in_paramtypes, T_ARRAY);
@@ -1903,8 +1975,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1903
1975
  paramTypes[i] = NUM2UINT(param);
1904
1976
  }
1905
1977
  }
1906
- result = gvl_PQsendPrepare(conn, StringValueCStr(name), StringValueCStr(command),
1907
- nParams, paramTypes);
1978
+ result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1908
1979
 
1909
1980
  xfree(paramTypes);
1910
1981
 
@@ -1929,7 +2000,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1929
2000
  * SQL query. Each element of the +params+ array may be either:
1930
2001
  * a hash of the form:
1931
2002
  * {:value => String (value of bind parameter)
1932
- * :format => Fixnum (0 for text, 1 for binary)
2003
+ * :format => Integer (0 for text, 1 for binary)
1933
2004
  * }
1934
2005
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1935
2006
  * { :value => <string value>, :format => 0 }
@@ -1942,7 +2013,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1942
2013
  * for binary.
1943
2014
  *
1944
2015
  * 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
2016
+ * This will type cast the params from various Ruby types before transmission
1946
2017
  * based on the encoders defined by the type map. When a type encoder is used
1947
2018
  * the format and oid of a given bind parameter are retrieved from the encoder
1948
2019
  * instead out of the hash form described above.
@@ -1957,11 +2028,10 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1957
2028
  VALUE error;
1958
2029
  int nParams;
1959
2030
  int resultFormat;
1960
- struct query_params_data paramsData;
2031
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1961
2032
 
1962
2033
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1963
2034
  paramsData.with_types = 0;
1964
- Check_Type(name, T_STRING);
1965
2035
 
1966
2036
  if(NIL_P(paramsData.params)) {
1967
2037
  paramsData.params = rb_ary_new2(0);
@@ -1972,7 +2042,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1972
2042
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1973
2043
  nParams = alloc_query_params( &paramsData );
1974
2044
 
1975
- result = gvl_PQsendQueryPrepared(conn, StringValueCStr(name), nParams,
2045
+ result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1976
2046
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1977
2047
  resultFormat);
1978
2048
 
@@ -1999,7 +2069,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
1999
2069
  VALUE error;
2000
2070
  PGconn *conn = pg_get_pgconn(self);
2001
2071
  /* returns 0 on failure */
2002
- if(gvl_PQsendDescribePrepared(conn,StringValueCStr(stmt_name)) == 0) {
2072
+ if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
2003
2073
  error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
2004
2074
  rb_iv_set(error, "@connection", self);
2005
2075
  rb_exc_raise(error);
@@ -2021,7 +2091,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
2021
2091
  VALUE error;
2022
2092
  PGconn *conn = pg_get_pgconn(self);
2023
2093
  /* returns 0 on failure */
2024
- if(gvl_PQsendDescribePortal(conn,StringValueCStr(portal)) == 0) {
2094
+ if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
2025
2095
  error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
2026
2096
  rb_iv_set(error, "@connection", self);
2027
2097
  rb_exc_raise(error);
@@ -2193,7 +2263,6 @@ pgconn_flush(self)
2193
2263
  static VALUE
2194
2264
  pgconn_cancel(VALUE self)
2195
2265
  {
2196
- #ifdef HAVE_PQGETCANCEL
2197
2266
  char errbuf[256];
2198
2267
  PGcancel *cancel;
2199
2268
  VALUE retval;
@@ -2211,9 +2280,6 @@ pgconn_cancel(VALUE self)
2211
2280
 
2212
2281
  PQfreeCancel(cancel);
2213
2282
  return retval;
2214
- #else
2215
- rb_notimplement();
2216
- #endif
2217
2283
  }
2218
2284
 
2219
2285
 
@@ -2257,56 +2323,15 @@ pgconn_notifies(VALUE self)
2257
2323
  return hash;
2258
2324
  }
2259
2325
 
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
2326
  /* Win32 + Ruby 1.9+ */
2298
- #if defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
2327
+ #if defined( _WIN32 )
2299
2328
  /*
2300
2329
  * On Windows, use platform-specific strategies to wait for the socket
2301
- * instead of rb_thread_select().
2330
+ * instead of rb_wait_for_single_fd().
2302
2331
  */
2303
2332
 
2304
2333
  int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2305
2334
 
2306
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2307
- * and does not wait (nor sleep) any time even if timeout is given.
2308
- * Instead use the Winsock events and rb_w32_wait_events(). */
2309
-
2310
2335
  static void *
2311
2336
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2312
2337
  {
@@ -2383,7 +2408,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2383
2408
 
2384
2409
  #else
2385
2410
 
2386
- /* non Win32 or Win32+Ruby-1.8 */
2411
+ /* non Win32 */
2387
2412
 
2388
2413
  static void *
2389
2414
  wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
@@ -2391,11 +2416,7 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2391
2416
  int sd = PQsocket( conn );
2392
2417
  int ret;
2393
2418
  void *retval;
2394
- rb_fdset_t sd_rset;
2395
2419
  struct timeval aborttime={0,0}, currtime, waittime;
2396
- #ifdef _WIN32
2397
- rb_fdset_t crt_sd_rset;
2398
- #endif
2399
2420
 
2400
2421
  if ( sd < 0 )
2401
2422
  rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
@@ -2404,25 +2425,12 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2404
2425
  if ( PQconsumeInput(conn) == 0 )
2405
2426
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2406
2427
 
2407
- rb_fd_init( &sd_rset );
2408
-
2409
2428
  if ( ptimeout ) {
2410
2429
  gettimeofday(&currtime, NULL);
2411
2430
  timeradd(&currtime, ptimeout, &aborttime);
2412
2431
  }
2413
2432
 
2414
2433
  while ( !(retval=is_readable(conn)) ) {
2415
- rb_fd_zero( &sd_rset );
2416
- rb_fd_set( sd, &sd_rset );
2417
-
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
2434
  if ( ptimeout ) {
2427
2435
  gettimeofday(&currtime, NULL);
2428
2436
  timersub(&aborttime, &currtime, &waittime);
@@ -2431,35 +2439,26 @@ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readabl
2431
2439
  /* Is the given timeout valid? */
2432
2440
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2433
2441
  /* Wait for the socket to become readable before checking again */
2434
- ret = rb_thread_fd_select( sd+1, &sd_rset, NULL, NULL, ptimeout ? &waittime : NULL );
2442
+ ret = rb_wait_for_single_fd( sd, RB_WAITFD_IN, ptimeout ? &waittime : NULL );
2435
2443
  } else {
2436
2444
  ret = 0;
2437
2445
  }
2438
2446
 
2439
-
2440
- #ifdef _WIN32
2441
- cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2442
- #endif
2443
-
2444
2447
  if ( ret < 0 ){
2445
- rb_fd_term( &sd_rset );
2446
- rb_sys_fail( "rb_thread_select()" );
2448
+ rb_sys_fail( "rb_wait_for_single_fd()" );
2447
2449
  }
2448
2450
 
2449
2451
  /* Return false if the select() timed out */
2450
2452
  if ( ret == 0 ){
2451
- rb_fd_term( &sd_rset );
2452
2453
  return NULL;
2453
2454
  }
2454
2455
 
2455
2456
  /* Check for connection errors (PQisBusy is true on connection errors) */
2456
2457
  if ( PQconsumeInput(conn) == 0 ){
2457
- rb_fd_term( &sd_rset );
2458
2458
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2459
2459
  }
2460
2460
  }
2461
2461
 
2462
- rb_fd_term( &sd_rset );
2463
2462
  return retval;
2464
2463
  }
2465
2464
 
@@ -2474,22 +2473,15 @@ notify_readable(PGconn *conn)
2474
2473
 
2475
2474
  /*
2476
2475
  * call-seq:
2477
- * conn.wait_for_notify( [ timeout ] ) -> String
2478
- * conn.wait_for_notify( [ timeout ] ) { |event, pid| block }
2479
- * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } # PostgreSQL 9.0
2476
+ * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } -> String
2480
2477
  *
2481
2478
  * Blocks while waiting for notification(s), or until the optional
2482
2479
  * _timeout_ is reached, whichever comes first. _timeout_ is
2483
2480
  * measured in seconds and can be fractional.
2484
2481
  *
2485
- * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY
2486
- * event otherwise. If used in block form, passes the name of the
2487
- * NOTIFY +event+ and the generating +pid+ into the block.
2488
- *
2489
- * Under PostgreSQL 9.0 and later, if the notification is sent with
2490
- * the optional +payload+ string, it will be given to the block as the
2491
- * third argument.
2492
- *
2482
+ * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY event otherwise.
2483
+ * If used in block form, passes the name of the NOTIFY +event+, the generating
2484
+ * +pid+ and the optional +payload+ string into the block.
2493
2485
  */
2494
2486
  static VALUE
2495
2487
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
@@ -2518,12 +2510,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2518
2510
  relname = rb_tainted_str_new2( pnotification->relname );
2519
2511
  PG_ENCODING_SET_NOCHECK( relname, ENCODING_GET(self) );
2520
2512
  be_pid = INT2NUM( pnotification->be_pid );
2521
- #ifdef HAVE_ST_NOTIFY_EXTRA
2522
2513
  if ( *pnotification->extra ) {
2523
2514
  extra = rb_tainted_str_new2( pnotification->extra );
2524
2515
  PG_ENCODING_SET_NOCHECK( extra, ENCODING_GET(self) );
2525
2516
  }
2526
- #endif
2527
2517
  PQfreemem( pnotification );
2528
2518
 
2529
2519
  if ( rb_block_given_p() )
@@ -2542,9 +2532,10 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2542
2532
  * not sent (false is only possible if the connection
2543
2533
  * is in nonblocking mode, and this command would block).
2544
2534
  *
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,
2535
+ * _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2536
+ * This encodes the data fields given as _buffer_ from an Array of Strings to
2537
+ * PostgreSQL's COPY text format inclusive proper escaping. Optionally
2538
+ * the encoder can type cast the fields from various Ruby types in one step,
2548
2539
  * if PG::TextEncoder::CopyRow#type_map is set accordingly.
2549
2540
  *
2550
2541
  * Raises an exception if an error occurs.
@@ -2581,16 +2572,17 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2581
2572
 
2582
2573
  if( p_coder ){
2583
2574
  t_pg_coder_enc_func enc_func;
2575
+ int enc_idx = ENCODING_GET(self);
2584
2576
 
2585
2577
  enc_func = pg_coder_enc_func( p_coder );
2586
- len = enc_func( p_coder, value, NULL, &intermediate );
2578
+ len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
2587
2579
 
2588
2580
  if( len == -1 ){
2589
2581
  /* The intermediate value is a String that can be used directly. */
2590
2582
  buffer = intermediate;
2591
2583
  } else {
2592
2584
  buffer = rb_str_new(NULL, len);
2593
- len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate);
2585
+ len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate, enc_idx);
2594
2586
  rb_str_set_len( buffer, len );
2595
2587
  }
2596
2588
  }
@@ -2629,13 +2621,13 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2629
2621
  VALUE str;
2630
2622
  VALUE error;
2631
2623
  int ret;
2632
- char *error_message = NULL;
2624
+ const char *error_message = NULL;
2633
2625
  PGconn *conn = pg_get_pgconn(self);
2634
2626
 
2635
2627
  if (rb_scan_args(argc, argv, "01", &str) == 0)
2636
2628
  error_message = NULL;
2637
2629
  else
2638
- error_message = StringValueCStr(str);
2630
+ error_message = pg_cstr_enc(str, ENCODING_GET(self));
2639
2631
 
2640
2632
  ret = gvl_PQputCopyEnd(conn, error_message);
2641
2633
  if(ret == -1) {
@@ -2648,15 +2640,18 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2648
2640
 
2649
2641
  /*
2650
2642
  * call-seq:
2651
- * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> String
2643
+ * conn.get_copy_data( [ async = false [, decoder = nil ]] ) -> Object
2652
2644
  *
2653
- * Return a string containing one row of data, +nil+
2645
+ * Return one row of data, +nil+
2654
2646
  * if the copy is done, or +false+ if the call would
2655
2647
  * block (only possible if _async_ is true).
2656
2648
  *
2657
- * decoder can be a PG::Coder derivation (typically PG::TextDecoder::CopyRow).
2658
- * This decodes the received data fields as Array of Strings. Optionally
2659
- * the decoder can type cast the fields to various Ruby types in one step,
2649
+ * If _decoder_ is not set or +nil+, data is returned as binary string.
2650
+ *
2651
+ * If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
2652
+ * PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
2653
+ * COPY text format to an Array of Strings.
2654
+ * Optionally the decoder can type cast the single fields to various Ruby types in one step,
2660
2655
  * if PG::TextDecoder::CopyRow#type_map is set accordingly.
2661
2656
  *
2662
2657
  * See also #copy_data.
@@ -2713,7 +2708,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2713
2708
 
2714
2709
  /*
2715
2710
  * call-seq:
2716
- * conn.set_error_verbosity( verbosity ) -> Fixnum
2711
+ * conn.set_error_verbosity( verbosity ) -> Integer
2717
2712
  *
2718
2713
  * Sets connection's verbosity to _verbosity_ and returns
2719
2714
  * the previous setting. Available settings are:
@@ -2956,12 +2951,10 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
2956
2951
 
2957
2952
  Check_Type(str, T_STRING);
2958
2953
 
2959
- if ( (PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2960
- rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValueCStr(str));
2954
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2955
+ rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2961
2956
  }
2962
- #ifdef M17N_SUPPORTED
2963
2957
  pgconn_set_internal_encoding_index( self );
2964
- #endif
2965
2958
 
2966
2959
  return Qnil;
2967
2960
  }
@@ -3012,8 +3005,10 @@ pgconn_transaction(VALUE self)
3012
3005
 
3013
3006
  /*
3014
3007
  * call-seq:
3015
- * PG::Connection.quote_ident( str ) -> String
3016
3008
  * conn.quote_ident( str ) -> String
3009
+ * conn.quote_ident( array ) -> String
3010
+ * PG::Connection.quote_ident( str ) -> String
3011
+ * PG::Connection.quote_ident( array ) -> String
3017
3012
  *
3018
3013
  * Returns a string that is safe for inclusion in a SQL query as an
3019
3014
  * identifier. Note: this is not a quote function for values, but for
@@ -3023,40 +3018,41 @@ pgconn_transaction(VALUE self)
3023
3018
  * The identifier <tt>FOO</tt> is folded to lower case, so it actually
3024
3019
  * means <tt>foo</tt>. If you really want to access the case-sensitive
3025
3020
  * field name <tt>FOO</tt>, use this function like
3026
- * <tt>PG::Connection.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
3021
+ * <tt>conn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
3027
3022
  * (with double-quotes). PostgreSQL will see the double-quotes, and
3028
3023
  * it will not fold to lower case.
3029
3024
  *
3030
3025
  * Similarly, this function also protects against special characters,
3031
3026
  * and other things that might allow SQL injection if the identifier
3032
3027
  * comes from an untrusted source.
3028
+ *
3029
+ * If the parameter is an Array, then all it's values are separately quoted
3030
+ * and then joined by a "." character. This can be used for identifiers in
3031
+ * the form "schema"."table"."column" .
3032
+ *
3033
+ * This method is functional identical to the encoder PG::TextEncoder::Identifier .
3034
+ *
3035
+ * If the instance method form is used and the input string character encoding
3036
+ * is different to the connection encoding, then the string is converted to this
3037
+ * encoding, so that the returned string is always encoded as PG::Connection#internal_encoding .
3038
+ *
3039
+ * In the singleton form (PG::Connection.quote_ident) the character encoding
3040
+ * of the result string is set to the character encoding of the input string.
3033
3041
  */
3034
3042
  static VALUE
3035
- pgconn_s_quote_ident(VALUE self, VALUE in_str)
3043
+ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
3036
3044
  {
3037
3045
  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 ));
3046
+ int enc_idx;
3047
+
3048
+ if( rb_obj_is_kind_of(self, rb_cPGconn) ){
3049
+ enc_idx = ENCODING_GET( self );
3050
+ }else{
3051
+ enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
3052
+ }
3053
+ pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
3054
+
3055
+ OBJ_INFECT(ret, str_or_array);
3060
3056
 
3061
3057
  return ret;
3062
3058
  }
@@ -3086,10 +3082,6 @@ static VALUE
3086
3082
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
3087
3083
  PGconn *conn = pg_get_pgconn( self );
3088
3084
 
3089
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
3090
- * and does not wait (nor sleep) any time even if timeout is given.
3091
- * Instead use the Winsock events and rb_w32_wait_events(). */
3092
-
3093
3085
  struct timeval timeout;
3094
3086
  struct timeval *ptimeout = NULL;
3095
3087
  VALUE timeout_in;
@@ -3156,24 +3148,186 @@ pgconn_get_last_result(VALUE self)
3156
3148
 
3157
3149
  /*
3158
3150
  * call-seq:
3159
- * conn.async_exec(sql [, params, result_format ] ) -> PG::Result
3160
- * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
3151
+ * conn.discard_results()
3152
+ *
3153
+ * Silently discard any prior query result that application didn't eat.
3154
+ * This is done prior of Connection#exec and sibling methods and can
3155
+ * be called explicitly when using the async API.
3156
+ */
3157
+ static VALUE
3158
+ pgconn_discard_results(VALUE self)
3159
+ {
3160
+ PGconn *conn = pg_get_pgconn(self);
3161
+
3162
+ PGresult *cur;
3163
+ while ((cur = gvl_PQgetResult(conn)) != NULL) {
3164
+ int status = PQresultStatus(cur);
3165
+ PQclear(cur);
3166
+ if (status == PGRES_COPY_IN){
3167
+ gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
3168
+ }
3169
+ if (status == PGRES_COPY_OUT){
3170
+ char *buffer = NULL;
3171
+ while( gvl_PQgetCopyData(conn, &buffer, 0) > 0)
3172
+ PQfreemem(buffer);
3173
+ }
3174
+ }
3175
+
3176
+ return Qnil;
3177
+ }
3178
+
3179
+ /*
3180
+ * call-seq:
3181
+ * conn.async_exec(sql) -> PG::Result
3182
+ * conn.async_exec(sql) {|pg_result| block }
3161
3183
  *
3162
- * This function has the same behavior as #exec,
3184
+ * This function has the same behavior as #sync_exec,
3163
3185
  * but is implemented using the asynchronous command
3164
3186
  * processing API of libpq.
3187
+ *
3188
+ * Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed.
3189
+ * However #async_exec has two advantages:
3190
+ *
3191
+ * 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
3192
+ * 2. Ruby VM gets notified about IO blocked operations.
3193
+ * It can therefore schedule thing like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
3165
3194
  */
3166
3195
  static VALUE
3167
3196
  pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3168
3197
  {
3169
3198
  VALUE rb_pgresult = Qnil;
3170
3199
 
3171
- /* remove any remaining results from the queue */
3200
+ pgconn_discard_results( self );
3201
+ pgconn_send_query( argc, argv, self );
3172
3202
  pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3173
- pgconn_get_last_result( self );
3203
+ rb_pgresult = pgconn_get_last_result( self );
3174
3204
 
3175
- pgconn_send_query( argc, argv, self );
3176
- pgconn_block( 0, NULL, self );
3205
+ if ( rb_block_given_p() ) {
3206
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3207
+ }
3208
+ return rb_pgresult;
3209
+ }
3210
+
3211
+
3212
+ /*
3213
+ * call-seq:
3214
+ * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) -> nil
3215
+ * conn.async_exec_params(sql, params [, result_format [, type_map ]] ) {|pg_result| block }
3216
+ *
3217
+ * This function has the same behavior as #sync_exec_params, but is implemented using the asynchronous command processing API of libpq.
3218
+ * See #async_exec for the differences between the two API variants.
3219
+ */
3220
+ static VALUE
3221
+ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
3222
+ {
3223
+ VALUE rb_pgresult = Qnil;
3224
+
3225
+ pgconn_discard_results( self );
3226
+ /* If called with no or nil parameters, use PQsendQuery for compatibility */
3227
+ if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
3228
+ pg_deprecated(3, ("forwarding async_exec_params to async_exec is deprecated"));
3229
+ pgconn_send_query( argc, argv, self );
3230
+ } else {
3231
+ pgconn_send_query_params( argc, argv, self );
3232
+ }
3233
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3234
+ rb_pgresult = pgconn_get_last_result( self );
3235
+
3236
+ if ( rb_block_given_p() ) {
3237
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3238
+ }
3239
+ return rb_pgresult;
3240
+ }
3241
+
3242
+
3243
+ /*
3244
+ * call-seq:
3245
+ * conn.async_prepare(stmt_name, sql [, param_types ] ) -> PG::Result
3246
+ *
3247
+ * This function has the same behavior as #sync_prepare, but is implemented using the asynchronous command processing API of libpq.
3248
+ * See #async_exec for the differences between the two API variants.
3249
+ */
3250
+ static VALUE
3251
+ pgconn_async_prepare(int argc, VALUE *argv, VALUE self)
3252
+ {
3253
+ VALUE rb_pgresult = Qnil;
3254
+
3255
+ pgconn_discard_results( self );
3256
+ pgconn_send_prepare( argc, argv, self );
3257
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3258
+ rb_pgresult = pgconn_get_last_result( self );
3259
+
3260
+ if ( rb_block_given_p() ) {
3261
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3262
+ }
3263
+ return rb_pgresult;
3264
+ }
3265
+
3266
+
3267
+ /*
3268
+ * call-seq:
3269
+ * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) -> PG::Result
3270
+ * conn.async_exec_prepared(statement_name [, params, result_format[, type_map]] ) {|pg_result| block }
3271
+ *
3272
+ * This function has the same behavior as #sync_exec_prepared, but is implemented using the asynchronous command processing API of libpq.
3273
+ * See #async_exec for the differences between the two API variants.
3274
+ */
3275
+ static VALUE
3276
+ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3277
+ {
3278
+ VALUE rb_pgresult = Qnil;
3279
+
3280
+ pgconn_discard_results( self );
3281
+ pgconn_send_query_prepared( argc, argv, self );
3282
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3283
+ rb_pgresult = pgconn_get_last_result( self );
3284
+
3285
+ if ( rb_block_given_p() ) {
3286
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3287
+ }
3288
+ return rb_pgresult;
3289
+ }
3290
+
3291
+
3292
+ /*
3293
+ * call-seq:
3294
+ * conn.async_describe_portal( portal_name ) -> PG::Result
3295
+ *
3296
+ * This function has the same behavior as #sync_describe_portal, but is implemented using the asynchronous command processing API of libpq.
3297
+ * See #async_exec for the differences between the two API variants.
3298
+ */
3299
+ static VALUE
3300
+ pgconn_async_describe_portal(VALUE self, VALUE portal)
3301
+ {
3302
+ VALUE rb_pgresult = Qnil;
3303
+
3304
+ pgconn_discard_results( self );
3305
+ pgconn_send_describe_portal( self, portal );
3306
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3307
+ rb_pgresult = pgconn_get_last_result( self );
3308
+
3309
+ if ( rb_block_given_p() ) {
3310
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3311
+ }
3312
+ return rb_pgresult;
3313
+ }
3314
+
3315
+
3316
+ /*
3317
+ * call-seq:
3318
+ * conn.async_describe_prepared( statement_name ) -> PG::Result
3319
+ *
3320
+ * This function has the same behavior as #sync_describe_prepared, but is implemented using the asynchronous command processing API of libpq.
3321
+ * See #async_exec for the differences between the two API variants.
3322
+ */
3323
+ static VALUE
3324
+ pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3325
+ {
3326
+ VALUE rb_pgresult = Qnil;
3327
+
3328
+ pgconn_discard_results( self );
3329
+ pgconn_send_describe_prepared( self, stmt_name );
3330
+ pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3177
3331
  rb_pgresult = pgconn_get_last_result( self );
3178
3332
 
3179
3333
  if ( rb_block_given_p() ) {
@@ -3182,13 +3336,93 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3182
3336
  return rb_pgresult;
3183
3337
  }
3184
3338
 
3339
+
3340
+ #ifdef HAVE_PQSSLATTRIBUTE
3341
+ /*
3342
+ * call-seq:
3343
+ * conn.ssl_in_use? -> Boolean
3344
+ *
3345
+ * Returns +true+ if the connection uses SSL, +false+ if not.
3346
+ *
3347
+ * Available since PostgreSQL-9.5
3348
+ */
3349
+ static VALUE
3350
+ pgconn_ssl_in_use(VALUE self)
3351
+ {
3352
+ return PQsslInUse(pg_get_pgconn(self)) ? Qtrue : Qfalse;
3353
+ }
3354
+
3355
+
3356
+ /*
3357
+ * call-seq:
3358
+ * conn.ssl_attribute(attribute_name) -> String
3359
+ *
3360
+ * Returns SSL-related information about the connection.
3361
+ *
3362
+ * The list of available attributes varies depending on the SSL library being used,
3363
+ * and the type of connection. If an attribute is not available, returns nil.
3364
+ *
3365
+ * The following attributes are commonly available:
3366
+ *
3367
+ * [+library+]
3368
+ * Name of the SSL implementation in use. (Currently, only "OpenSSL" is implemented)
3369
+ * [+protocol+]
3370
+ * 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.
3371
+ * [+key_bits+]
3372
+ * Number of key bits used by the encryption algorithm.
3373
+ * [+cipher+]
3374
+ * A short name of the ciphersuite used, e.g. "DHE-RSA-DES-CBC3-SHA". The names are specific to each SSL implementation.
3375
+ * [+compression+]
3376
+ * 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".
3377
+ *
3378
+ *
3379
+ * See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
3380
+ *
3381
+ * Available since PostgreSQL-9.5
3382
+ */
3383
+ static VALUE
3384
+ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3385
+ {
3386
+ const char *p_attr;
3387
+
3388
+ p_attr = PQsslAttribute(pg_get_pgconn(self), StringValueCStr(attribute_name));
3389
+ return p_attr ? rb_str_new_cstr(p_attr) : Qnil;
3390
+ }
3391
+
3392
+ /*
3393
+ * call-seq:
3394
+ * conn.ssl_attribute_names -> Array<String>
3395
+ *
3396
+ * Return an array of SSL attribute names available.
3397
+ *
3398
+ * See also #ssl_attribute
3399
+ *
3400
+ * Available since PostgreSQL-9.5
3401
+ */
3402
+ static VALUE
3403
+ pgconn_ssl_attribute_names(VALUE self)
3404
+ {
3405
+ int i;
3406
+ const char * const * p_list = PQsslAttributeNames(pg_get_pgconn(self));
3407
+ VALUE ary = rb_ary_new();
3408
+
3409
+ for ( i = 0; p_list[i]; i++ ) {
3410
+ rb_ary_push( ary, rb_str_new_cstr( p_list[i] ));
3411
+ }
3412
+ return ary;
3413
+ }
3414
+
3415
+
3416
+ #endif
3417
+
3418
+
3185
3419
  /**************************************************************************
3186
3420
  * LARGE OBJECT SUPPORT
3187
3421
  **************************************************************************/
3188
3422
 
3189
3423
  /*
3190
3424
  * call-seq:
3191
- * conn.lo_creat( [mode] ) -> Fixnum
3425
+ * conn.lo_creat( [mode] ) -> Integer
3192
3426
  *
3193
3427
  * Creates a large object with mode _mode_. Returns a large object Oid.
3194
3428
  * On failure, it raises PG::Error.
@@ -3215,7 +3449,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3215
3449
 
3216
3450
  /*
3217
3451
  * call-seq:
3218
- * conn.lo_create( oid ) -> Fixnum
3452
+ * conn.lo_create( oid ) -> Integer
3219
3453
  *
3220
3454
  * Creates a large object with oid _oid_. Returns the large object Oid.
3221
3455
  * On failure, it raises PG::Error.
@@ -3236,7 +3470,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3236
3470
 
3237
3471
  /*
3238
3472
  * call-seq:
3239
- * conn.lo_import(file) -> Fixnum
3473
+ * conn.lo_import(file) -> Integer
3240
3474
  *
3241
3475
  * Import a file to a large object. Returns a large object Oid.
3242
3476
  *
@@ -3281,7 +3515,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3281
3515
 
3282
3516
  /*
3283
3517
  * call-seq:
3284
- * conn.lo_open( oid, [mode] ) -> Fixnum
3518
+ * conn.lo_open( oid, [mode] ) -> Integer
3285
3519
  *
3286
3520
  * Open a large object of _oid_. Returns a large object descriptor
3287
3521
  * instance on success. The _mode_ argument specifies the mode for
@@ -3312,7 +3546,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3312
3546
 
3313
3547
  /*
3314
3548
  * call-seq:
3315
- * conn.lo_write( lo_desc, buffer ) -> Fixnum
3549
+ * conn.lo_write( lo_desc, buffer ) -> Integer
3316
3550
  *
3317
3551
  * Writes the string _buffer_ to the large object _lo_desc_.
3318
3552
  * Returns the number of bytes written.
@@ -3379,7 +3613,7 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3379
3613
 
3380
3614
  /*
3381
3615
  * call-seq:
3382
- * conn.lo_lseek( lo_desc, offset, whence ) -> Fixnum
3616
+ * conn.lo_lseek( lo_desc, offset, whence ) -> Integer
3383
3617
  *
3384
3618
  * Move the large object pointer _lo_desc_ to offset _offset_.
3385
3619
  * Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
@@ -3401,7 +3635,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3401
3635
 
3402
3636
  /*
3403
3637
  * call-seq:
3404
- * conn.lo_tell( lo_desc ) -> Fixnum
3638
+ * conn.lo_tell( lo_desc ) -> Integer
3405
3639
  *
3406
3640
  * Returns the current position of the large object _lo_desc_.
3407
3641
  */
@@ -3474,8 +3708,6 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3474
3708
  }
3475
3709
 
3476
3710
 
3477
- #ifdef M17N_SUPPORTED
3478
-
3479
3711
  void
3480
3712
  pgconn_set_internal_encoding_index( VALUE self )
3481
3713
  {
@@ -3537,7 +3769,7 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
3537
3769
  rb_encoding *rbenc = rb_to_encoding( enc );
3538
3770
  const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc );
3539
3771
 
3540
- if ( PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
3772
+ if ( gvl_PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) {
3541
3773
  VALUE server_encoding = pgconn_external_encoding( self );
3542
3774
  rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s",
3543
3775
  rb_enc_name(rb_to_encoding(server_encoding)), name );
@@ -3579,6 +3811,34 @@ pgconn_external_encoding(VALUE self)
3579
3811
  }
3580
3812
 
3581
3813
 
3814
+ static VALUE
3815
+ pgconn_set_client_encoding_async1( VALUE args )
3816
+ {
3817
+ VALUE self = ((VALUE*)args)[0];
3818
+ VALUE encname = ((VALUE*)args)[1];
3819
+ VALUE query_format = rb_str_new_cstr("set client_encoding to '%s'");
3820
+ VALUE query = rb_funcall(query_format, rb_intern("%"), 1, encname);
3821
+
3822
+ pgconn_async_exec(1, &query, self);
3823
+ return 0;
3824
+ }
3825
+
3826
+
3827
+ static VALUE
3828
+ pgconn_set_client_encoding_async2( VALUE arg )
3829
+ {
3830
+ UNUSED(arg);
3831
+ return 1;
3832
+ }
3833
+
3834
+
3835
+ static VALUE
3836
+ pgconn_set_client_encoding_async( VALUE self, const char *encname )
3837
+ {
3838
+ VALUE args[] = { self, rb_str_new_cstr(encname) };
3839
+ return rb_rescue(pgconn_set_client_encoding_async1, (VALUE)&args, pgconn_set_client_encoding_async2, Qnil);
3840
+ }
3841
+
3582
3842
 
3583
3843
  /*
3584
3844
  * call-seq:
@@ -3597,8 +3857,8 @@ pgconn_set_default_encoding( VALUE self )
3597
3857
 
3598
3858
  if (( enc = rb_default_internal_encoding() )) {
3599
3859
  encname = pg_get_rb_encoding_as_pg_encoding( enc );
3600
- if ( PQsetClientEncoding(conn, encname) != 0 )
3601
- rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
3860
+ if ( pgconn_set_client_encoding_async(self, encname) != 0 )
3861
+ rb_warning( "Failed to set the default_internal encoding to %s: '%s'",
3602
3862
  encname, PQerrorMessage(conn) );
3603
3863
  pgconn_set_internal_encoding_index( self );
3604
3864
  return rb_enc_from_encoding( enc );
@@ -3609,8 +3869,6 @@ pgconn_set_default_encoding( VALUE self )
3609
3869
  }
3610
3870
 
3611
3871
 
3612
- #endif /* M17N_SUPPORTED */
3613
-
3614
3872
  /*
3615
3873
  * call-seq:
3616
3874
  * res.type_map_for_queries = typemap
@@ -3729,7 +3987,7 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE typemap)
3729
3987
  *
3730
3988
  * Returns either:
3731
3989
  * * a kind of PG::Coder
3732
- * * +nil+ - type encoding is disabled, returned data will be a String.
3990
+ * * +nil+ - type encoding is disabled, data must be a String.
3733
3991
  *
3734
3992
  */
3735
3993
  static VALUE
@@ -3789,7 +4047,24 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
3789
4047
  return this->decoder_for_get_copy_data;
3790
4048
  }
3791
4049
 
4050
+ /*
4051
+ * call-seq:
4052
+ * res.guess_result_memsize = enabled
4053
+ *
4054
+ * This method is for testing only and will probably be removed in the future.
4055
+ */
4056
+ static VALUE
4057
+ pgconn_guess_result_memsize_set(VALUE self, VALUE enable)
4058
+ {
4059
+ t_pg_connection *this = pg_get_connection( self );
4060
+ this->guess_result_memsize = RTEST(enable);
4061
+ return enable;
4062
+ }
3792
4063
 
4064
+
4065
+ /*
4066
+ * Document-class: PG::Connection
4067
+ */
3793
4068
  void
3794
4069
  init_pg_connection()
3795
4070
  {
@@ -3816,9 +4091,7 @@ init_pg_connection()
3816
4091
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
3817
4092
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
3818
4093
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3819
- #ifdef HAVE_PQPING
3820
4094
  rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
3821
- #endif
3822
4095
 
3823
4096
  /****** PG::Connection INSTANCE METHODS: Connection Control ******/
3824
4097
  rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
@@ -3835,9 +4108,6 @@ init_pg_connection()
3835
4108
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
3836
4109
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
3837
4110
  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
4111
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
3842
4112
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
3843
4113
  #ifdef HAVE_PQCONNINFO
@@ -3851,43 +4121,42 @@ init_pg_connection()
3851
4121
  rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
3852
4122
  rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
3853
4123
  rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
3854
- #if !defined(_WIN32) || defined(HAVE_RB_W32_WRAP_IO_HANDLE)
3855
4124
  rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
3856
- #endif
3857
4125
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
3858
4126
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
3859
4127
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
3860
4128
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
3861
4129
 
3862
4130
  /****** PG::Connection INSTANCE METHODS: Command Execution ******/
3863
- rb_define_method(rb_cPGconn, "exec", pgconn_exec, -1);
3864
- rb_define_alias(rb_cPGconn, "query", "exec");
3865
- rb_define_method(rb_cPGconn, "exec_params", pgconn_exec_params, -1);
3866
- rb_define_method(rb_cPGconn, "prepare", pgconn_prepare, -1);
3867
- rb_define_method(rb_cPGconn, "exec_prepared", pgconn_exec_prepared, -1);
3868
- rb_define_method(rb_cPGconn, "describe_prepared", pgconn_describe_prepared, 1);
3869
- rb_define_method(rb_cPGconn, "describe_portal", pgconn_describe_portal, 1);
4131
+ rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
4132
+ rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
4133
+ rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
4134
+ rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
4135
+ rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
4136
+ rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
3870
4137
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
3871
4138
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
3872
4139
  rb_define_alias(rb_cPGconn, "escape", "escape_string");
3873
- #ifdef HAVE_PQESCAPELITERAL
3874
4140
  rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
3875
- #endif
3876
- #ifdef HAVE_PQESCAPEIDENTIFIER
3877
4141
  rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
3878
- #endif
3879
4142
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
3880
4143
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
3881
- #ifdef HAVE_PQSETSINGLEROWMODE
3882
4144
  rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
3883
- #endif
3884
4145
 
3885
4146
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
3886
4147
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
4148
+ rb_define_method(rb_cPGconn, "send_query_params", pgconn_send_query_params, -1);
4149
+ rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
4150
+ rb_define_method(rb_cPGconn, "async_exec_params", pgconn_async_exec_params, -1);
4151
+ rb_define_alias(rb_cPGconn, "async_query", "async_exec");
3887
4152
  rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
4153
+ rb_define_method(rb_cPGconn, "async_prepare", pgconn_async_prepare, -1);
3888
4154
  rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4155
+ rb_define_method(rb_cPGconn, "async_exec_prepared", pgconn_async_exec_prepared, -1);
3889
4156
  rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
4157
+ rb_define_method(rb_cPGconn, "async_describe_prepared", pgconn_async_describe_prepared, 1);
3890
4158
  rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
4159
+ rb_define_method(rb_cPGconn, "async_describe_portal", pgconn_async_describe_portal, 1);
3891
4160
  rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
3892
4161
  rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
3893
4162
  rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
@@ -3895,6 +4164,7 @@ init_pg_connection()
3895
4164
  rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
3896
4165
  rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
3897
4166
  rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
4167
+ rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
3898
4168
 
3899
4169
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
3900
4170
  rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
@@ -3911,6 +4181,7 @@ init_pg_connection()
3911
4181
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
3912
4182
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
3913
4183
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4184
+ rb_define_method(rb_cPGconn, "guess_result_memsize=", pgconn_guess_result_memsize_set, 1);
3914
4185
 
3915
4186
  /****** PG::Connection INSTANCE METHODS: Notice Processing ******/
3916
4187
  rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
@@ -3925,9 +4196,16 @@ init_pg_connection()
3925
4196
  rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
3926
4197
  rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
3927
4198
  rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
3928
- rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
3929
- rb_define_alias(rb_cPGconn, "async_query", "async_exec");
3930
4199
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
4200
+ #ifdef HAVE_PQENCRYPTPASSWORDCONN
4201
+ rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
4202
+ #endif
4203
+
4204
+ #ifdef HAVE_PQSSLATTRIBUTE
4205
+ rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
4206
+ rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
4207
+ rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
4208
+ #endif
3931
4209
 
3932
4210
  /****** PG::Connection INSTANCE METHODS: Large Object Support ******/
3933
4211
  rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
@@ -3957,12 +4235,10 @@ init_pg_connection()
3957
4235
  rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
3958
4236
  rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
3959
4237
 
3960
- #ifdef M17N_SUPPORTED
3961
4238
  rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
3962
4239
  rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
3963
4240
  rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
3964
4241
  rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
3965
- #endif /* M17N_SUPPORTED */
3966
4242
 
3967
4243
  rb_define_method(rb_cPGconn, "type_map_for_queries=", pgconn_type_map_for_queries_set, 1);
3968
4244
  rb_define_method(rb_cPGconn, "type_map_for_queries", pgconn_type_map_for_queries_get, 0);