pg 0.14.1 → 0.15.0.pre.432

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,38 @@
1
+ == v0.15.0 [YYYY-MM-DD] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Bugfixes:
4
+
5
+ - Fix segfault in PG::Result#field_values when called with non String value.
6
+ - Fix encoding of messages delivered by notice callbacks.
7
+ - Fix text encoding for Connection#wait_for_notify and Connection#notifies.
8
+ - Fix 'Bad file descriptor' problems under Windows: wrong behaviour of
9
+ #wait_for_notify() and timeout handling of #block on Ruby 1.9.
10
+
11
+ Documentation fixes:
12
+
13
+ - conn#socket() can not be used with IO.for_fd() on Windows.
14
+
15
+ Enhancements:
16
+
17
+ - Add single row mode of PostgreSQL 9.2.
18
+ - Set fallback_application_name to programm name $0. Thanks to Will Leinweber
19
+ for the patch.
20
+ - Release Ruby's GVL while calls to blocking libpq functions to allow better
21
+ concurrency in threaded applications.
22
+ - Refactor different variants of waiting for the connection socket.
23
+ - Make use of rb_thread_fd_select() on Ruby 1.9 and avoid deprecated
24
+ rb_thread_select().
25
+ - Add an example of how to insert array data using a prepared statement (#145).
26
+ - Add continous integration tests on travis-ci.org.
27
+ - Add PG::Result#each_value for looping over result sets by row. Thanks to
28
+ Aaron Patterson for the patch.
29
+
30
+ Specs:
31
+
32
+ - Fix various specs to run on older PostgreSQL and Ruby versions.
33
+ - Avoid fork() in specs to allow usage on Windows and JRuby.
34
+
35
+
1
36
  == v0.14.1 [2012-09-02] Michael Granger <ged@FaerieMUD.org>
2
37
 
3
38
  Important bugfix:
@@ -13,6 +13,8 @@ README.rdoc
13
13
  Rakefile
14
14
  Rakefile.cross
15
15
  ext/extconf.rb
16
+ ext/gvl_wrappers.c
17
+ ext/gvl_wrappers.h
16
18
  ext/pg.c
17
19
  ext/pg.h
18
20
  ext/pg_connection.c
@@ -25,6 +27,7 @@ lib/pg/connection.rb
25
27
  lib/pg/constants.rb
26
28
  lib/pg/exceptions.rb
27
29
  lib/pg/result.rb
30
+ sample/array_insert.rb
28
31
  sample/async_api.rb
29
32
  sample/async_copyto.rb
30
33
  sample/async_mixed.rb
@@ -1,3 +1,5 @@
1
+ {<img src="https://travis-ci.org/ged/ruby-pg.png?branch=master" alt="Build Status" />}[https://travis-ci.org/ged/ruby-pg]
2
+
1
3
  = pg
2
4
 
3
5
  * https://bitbucket.org/ged/ruby-pg
@@ -11,14 +13,14 @@ It works with {PostgreSQL 8.3 and later}[http://bit.ly/6AfPhm].
11
13
  A small example usage:
12
14
 
13
15
  #!/usr/bin/env ruby
14
-
16
+
15
17
  require 'pg'
16
-
18
+
17
19
  # Output a table of current connections to the DB
18
20
  conn = PG.connect( dbname: 'sales' )
19
21
  conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
20
22
  puts " PID | User | Query"
21
- result.each do |row|
23
+ result.each do |row|
22
24
  puts " %7d | %-16s | %s " %
23
25
  row.values_at('procpid', 'usename', 'current_query')
24
26
  end
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  # Cross-compilation constants
21
21
  OPENSSL_VERSION = ENV['OPENSSL_VERSION'] || '1.0.1c'
22
- POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '9.1.4'
22
+ POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '9.2.2'
23
23
 
24
24
  COMPILE_HOME = Pathname( "./build" ).expand_path
25
25
  STATIC_SOURCESDIR = COMPILE_HOME + 'sources'
@@ -172,7 +172,7 @@ file STATIC_POSTGRESQL_BUILDDIR => POSTGRESQL_TARBALL do |t|
172
172
  STATIC_POSTGRESQL_BUILDDIR.mkpath
173
173
  run 'tar', '-xjf', POSTGRESQL_TARBALL.to_s, '-C', STATIC_POSTGRESQL_BUILDDIR.parent.to_s
174
174
  mv POSTGRESQL_SHLIB_MAKEFILE, POSTGRESQL_SHLIB_MF_ORIG
175
-
175
+
176
176
  POSTGRESQL_PATCHES.each do |patchfile|
177
177
  puts " applying patch #{patchfile}..."
178
178
  run 'patch', '-Np1', '-d', STATIC_POSTGRESQL_BUILDDIR.to_s,
@@ -32,7 +32,9 @@ dir_config 'pg'
32
32
  if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
33
33
  $stderr.puts "Using config values from %s" % [ pgconfig ]
34
34
  $CPPFLAGS << " -I%s" % [ `"#{pgconfig}" --includedir`.chomp ]
35
- $LDFLAGS << " -L%s" % [ `"#{pgconfig}" --libdir`.chomp ]
35
+
36
+ libdir = `"#{pgconfig}" --libdir`.chomp
37
+ $LDFLAGS << " -L%s -Wl,-rpath,%s" % [ libdir, libdir ]
36
38
  else
37
39
  $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
38
40
  " --with-pg-config=/path/to/pg_config"
@@ -65,9 +67,13 @@ have_func 'pg_char_to_encoding'
65
67
  have_func 'PQsetClientEncoding'
66
68
  have_func 'PQlibVersion'
67
69
  have_func 'PQping'
70
+ have_func 'PQsetSingleRowMode'
68
71
 
69
72
  have_func 'rb_encdb_alias'
70
73
  have_func 'rb_enc_alias'
74
+ have_func 'rb_thread_call_without_gvl'
75
+ have_func 'rb_thread_call_with_gvl'
76
+ have_func 'rb_thread_fd_select'
71
77
 
72
78
  have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
73
79
  have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
@@ -0,0 +1,13 @@
1
+ /*
2
+ * gvl_wrappers.c - Wrapper functions for locking/unlocking the Ruby GVL
3
+ *
4
+ */
5
+
6
+ #include "pg.h"
7
+
8
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
9
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
10
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
11
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
12
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON );
13
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB );
@@ -0,0 +1,185 @@
1
+ /*
2
+ * gvl_wrappers.h - Wrapper functions for locking/unlocking the Ruby GVL
3
+ *
4
+ * These are some obscure preprocessor directives that allow to generate
5
+ * drop-in replacement wrapper functions in a declarative manner.
6
+ * These wrapper functions ensure that ruby's GVL is released on each
7
+ * function call and reacquired at the end of the call or in callbacks.
8
+ * This way blocking functions calls don't block concurrent ruby threads.
9
+ *
10
+ * The wrapper of each function is prefixed by "gvl_".
11
+ *
12
+ * Use "gcc -E" to retrieve the generated code.
13
+ */
14
+
15
+ #ifndef __gvl_wrappers_h
16
+ #define __gvl_wrappers_h
17
+
18
+ #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
19
+ extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
20
+ #endif
21
+
22
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
23
+ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
24
+ rb_unblock_function_t *ubf, void *data2);
25
+ #endif
26
+
27
+ #define DEFINE_PARAM_LIST1(type, name) \
28
+ name,
29
+
30
+ #define DEFINE_PARAM_LIST2(type, name) \
31
+ p->params.name,
32
+
33
+ #define DEFINE_PARAM_LIST3(type, name) \
34
+ type name,
35
+
36
+ #define DEFINE_PARAM_DECL(type, name) \
37
+ type name;
38
+
39
+ #define DEFINE_GVL_WRAPPER_STRUCT(name, when_non_void, rettype, lastparamtype, lastparamname) \
40
+ struct gvl_wrapper_##name##_params { \
41
+ struct { \
42
+ FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_DECL) \
43
+ lastparamtype lastparamname; \
44
+ } params; \
45
+ when_non_void( rettype retval; ) \
46
+ };
47
+
48
+ #define DEFINE_GVL_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
49
+ static void * gvl_##name##_skeleton( void *data ){ \
50
+ struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
51
+ when_non_void( p->retval = ) \
52
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \
53
+ return NULL; \
54
+ }
55
+
56
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
57
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
58
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
59
+ struct gvl_wrapper_##name##_params params = { \
60
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
61
+ }; \
62
+ rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
63
+ when_non_void( return params.retval; ) \
64
+ }
65
+ #else
66
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
67
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
68
+ return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
69
+ }
70
+ #endif
71
+
72
+ #define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
73
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
74
+
75
+ #define DEFINE_GVLCB_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
76
+ static void * gvl_##name##_skeleton( void *data ){ \
77
+ struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
78
+ when_non_void( p->retval = ) \
79
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \
80
+ return NULL; \
81
+ }
82
+
83
+ #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
84
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
85
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
86
+ struct gvl_wrapper_##name##_params params = { \
87
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
88
+ }; \
89
+ rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
90
+ when_non_void( return params.retval; ) \
91
+ }
92
+ #else
93
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
94
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
95
+ return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
96
+ }
97
+ #endif
98
+
99
+ #define GVL_TYPE_VOID(string)
100
+ #define GVL_TYPE_NONVOID(string) string
101
+
102
+
103
+ /*
104
+ * Definitions of blocking functions and their parameters
105
+ */
106
+
107
+ #define FOR_EACH_PARAM_OF_PQexec(param) \
108
+ param(PGconn *, conn)
109
+
110
+ #define FOR_EACH_PARAM_OF_PQexecParams(param) \
111
+ param(PGconn *, conn) \
112
+ param(const char *, command) \
113
+ param(int, nParams) \
114
+ param(const Oid *, paramTypes) \
115
+ param(const char * const *, paramValues) \
116
+ param(const int *, paramLengths) \
117
+ param(const int *, paramFormats)
118
+
119
+ #define FOR_EACH_PARAM_OF_PQexecPrepared(param) \
120
+ param(PGconn *, conn) \
121
+ param(const char *, stmtName) \
122
+ param(int, nParams) \
123
+ param(const char * const *, paramValues) \
124
+ param(const int *, paramLengths) \
125
+ param(const int *, paramFormats)
126
+
127
+ #define FOR_EACH_PARAM_OF_PQprepare(param) \
128
+ param(PGconn *, conn) \
129
+ param(const char *, stmtName) \
130
+ param(const char *, query) \
131
+ param(int, nParams)
132
+
133
+ #define FOR_EACH_PARAM_OF_PQdescribePrepared(param) \
134
+ param(PGconn *, conn)
135
+
136
+ #define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
137
+ param(PGconn *, conn)
138
+
139
+ #define FOR_EACH_PARAM_OF_PQgetResult(param)
140
+
141
+ #define FOR_EACH_PARAM_OF_PQputCopyData(param) \
142
+ param(PGconn *, conn) \
143
+ param(const char *, buffer)
144
+
145
+ #define FOR_EACH_PARAM_OF_PQputCopyEnd(param) \
146
+ param(PGconn *, conn)
147
+
148
+ #define FOR_EACH_PARAM_OF_PQgetCopyData(param) \
149
+ param(PGconn *, conn) \
150
+ param(char **, buffer)
151
+
152
+ /* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
153
+ #define FOR_EACH_BLOCKING_FUNCTION(function) \
154
+ function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
155
+ function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
156
+ function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
157
+ function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
158
+ function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
159
+ function(PQdescribePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
160
+ function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
161
+ function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
162
+ function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
163
+ function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
164
+
165
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
166
+
167
+
168
+ /*
169
+ * Definitions of callback functions and their parameters
170
+ */
171
+
172
+ #define FOR_EACH_PARAM_OF_notice_processor_proxy(param) \
173
+ param(void *, arg)
174
+
175
+ #define FOR_EACH_PARAM_OF_notice_receiver_proxy(param) \
176
+ param(void *, arg)
177
+
178
+ /* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
179
+ #define FOR_EACH_CALLBACK_FUNCTION(function) \
180
+ function(notice_processor_proxy, GVL_TYPE_VOID, void, const char *, message) \
181
+ function(notice_receiver_proxy, GVL_TYPE_VOID, void, const PGresult *, result) \
182
+
183
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_STUB_DECL );
184
+
185
+ #endif /* end __gvl_wrappers_h */
data/ext/pg.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg.c - Toplevel extension
3
- * $Id: pg.c,v a965926418dd 2012/05/07 15:01:03 ged $
3
+ * $Id: pg.c,v d0c5d5f7f1e8 2012/12/26 21:09:28 kanis $
4
4
  *
5
5
  * Author/s:
6
6
  *
@@ -129,7 +129,7 @@ static ID s_id_index;
129
129
 
130
130
  /*
131
131
  * Get the index of encoding +val+.
132
- * :FIXME: Look into replacing this with rb_enc_get_index() since 1.9.1 isn't really
132
+ * :FIXME: Look into replacing this with rb_enc_get_index() since 1.9.1 isn't really
133
133
  * used anymore.
134
134
  */
135
135
  int
@@ -174,7 +174,7 @@ pg_find_or_create_johab(void)
174
174
  * - returns ASCII-8BIT if the client encoding is unknown.
175
175
  */
176
176
  rb_encoding *
177
- pg_get_pg_encoding_as_rb_encoding( int enc_id )
177
+ pg_get_pg_encoding_as_rb_encoding( int enc_id )
178
178
  {
179
179
  rb_encoding *enc;
180
180
 
@@ -409,7 +409,7 @@ Init_pg_ext()
409
409
  rb_define_const(rb_mPGconstants, "PGRES_EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY));
410
410
  /* #result_status constant: Successful completion of a command returning no data. */
411
411
  rb_define_const(rb_mPGconstants, "PGRES_COMMAND_OK", INT2FIX(PGRES_COMMAND_OK));
412
- /* #result_status constant: Successful completion of a command returning data
412
+ /* #result_status constant: Successful completion of a command returning data
413
413
  (such as a SELECT or SHOW). */
414
414
  rb_define_const(rb_mPGconstants, "PGRES_TUPLES_OK", INT2FIX(PGRES_TUPLES_OK));
415
415
  /* #result_status constant: Copy Out (from server) data transfer started. */
@@ -426,6 +426,10 @@ Init_pg_ext()
426
426
  #ifdef HAVE_CONST_PGRES_COPY_BOTH
427
427
  rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
428
428
  #endif
429
+ /* #result_status constant: Single tuple from larger resultset. */
430
+ #ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
431
+ rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
432
+ #endif
429
433
 
430
434
  /****** Result CONSTANTS: result error field codes ******/
431
435
 
@@ -509,7 +513,7 @@ Init_pg_ext()
509
513
  /* Add the constants to the toplevel namespace */
510
514
  rb_include_module( rb_mPG, rb_mPGconstants );
511
515
 
512
- #ifdef M17N_SUPPORTED
516
+ #ifdef M17N_SUPPORTED
513
517
  enc_pg2ruby = st_init_numtable();
514
518
  s_id_index = rb_intern("@encoding");
515
519
  #endif
data/ext/pg.h CHANGED
@@ -77,6 +77,7 @@ __declspec(dllexport)
77
77
  typedef long suseconds_t;
78
78
  #endif
79
79
 
80
+ #include "gvl_wrappers.h"
80
81
 
81
82
  /***************************************************************************
82
83
  * Globals
@@ -119,5 +120,7 @@ int pg_enc_get_index _(( VALUE ));
119
120
  rb_encoding *pg_conn_enc_get _(( PGconn * ));
120
121
  #endif /* M17N_SUPPORTED */
121
122
 
123
+ void notice_receiver_proxy(void *arg, const PGresult *result);
124
+ void notice_processor_proxy(void *arg, const char *message);
122
125
 
123
126
  #endif /* end __pg_h */
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_connection.c - PG::Connection class extension
3
- * $Id: pg_connection.c,v de900bfaff1a 2012/07/03 14:38:38 kanis $
3
+ * $Id: pg_connection.c,v 7c313c2355b7 2013/02/03 18:37:06 ged $
4
4
  *
5
5
  */
6
6
 
@@ -8,10 +8,10 @@
8
8
 
9
9
 
10
10
  /********************************************************************
11
- *
11
+ *
12
12
  * Document-class: PG::Connection
13
13
  *
14
- * The class to access PostgreSQL RDBMS, based on the libpq interface,
14
+ * The class to access PostgreSQL RDBMS, based on the libpq interface,
15
15
  * provides convenient OO methods to interact with PostgreSQL.
16
16
  *
17
17
  * For example, to send query to the database on the localhost:
@@ -35,6 +35,15 @@ static VALUE pgconn_finish( VALUE );
35
35
  static VALUE pgconn_set_default_encoding( VALUE self );
36
36
  #endif
37
37
 
38
+ #ifndef HAVE_RB_THREAD_FD_SELECT
39
+ #define rb_fdset_t fd_set
40
+ #define rb_fd_init(f)
41
+ #define rb_fd_zero(f) FD_ZERO(f)
42
+ #define rb_fd_set(n, f) FD_SET(n, f)
43
+ #define rb_fd_term(f)
44
+ #define rb_thread_fd_select rb_thread_select
45
+ #endif
46
+
38
47
  /*
39
48
  * Global functions
40
49
  */
@@ -92,7 +101,7 @@ pgconn_gc_free( PGconn *conn )
92
101
 
93
102
  /*
94
103
  * Document-method: allocate
95
- *
104
+ *
96
105
  * call-seq:
97
106
  * PG::Connection.allocate -> conn
98
107
  */
@@ -111,9 +120,9 @@ pgconn_s_allocate( VALUE klass )
111
120
  * PG::Connection.new(connection_hash) -> conn
112
121
  * PG::Connection.new(connection_string) -> conn
113
122
  * PG::Connection.new(host, port, options, tty, dbname, user, password) -> conn
114
- *
123
+ *
115
124
  * Create a connection to the specified server.
116
- *
125
+ *
117
126
  * [+host+]
118
127
  * server hostname
119
128
  * [+hostaddr+]
@@ -140,24 +149,24 @@ pgconn_s_allocate( VALUE klass )
140
149
  * GSS library to use for GSSAPI authentication
141
150
  * [+service+]
142
151
  * service name to use for additional parameters
143
- *
152
+ *
144
153
  * Examples:
145
- *
154
+ *
146
155
  * # Connect using all defaults
147
156
  * PG::Connection.new
148
157
  *
149
158
  * # As a Hash
150
159
  * PG::Connection.new( :dbname => 'test', :port => 5432 )
151
- *
160
+ *
152
161
  * # As a String
153
162
  * PG::Connection.new( "dbname=test port=5432" )
154
- *
163
+ *
155
164
  * # As an Array
156
165
  * PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
157
- *
166
+ *
158
167
  * If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the
159
168
  * connection will have its +client_encoding+ set accordingly.
160
- *
169
+ *
161
170
  * Raises a PG::Error if the connection fails.
162
171
  */
163
172
  static VALUE
@@ -202,11 +211,11 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
202
211
  *
203
212
  * Use #connect_poll to poll the status of the connection.
204
213
  *
205
- * NOTE: this does *not* set the connection's +client_encoding+ for you if
206
- * Encoding.default_internal is set. To set it after the connection is established,
207
- * call #internal_encoding=. You can also set it automatically by setting
214
+ * NOTE: this does *not* set the connection's +client_encoding+ for you if
215
+ * Encoding.default_internal is set. To set it after the connection is established,
216
+ * call #internal_encoding=. You can also set it automatically by setting
208
217
  * ENV['PGCLIENTENCODING'], or include the 'options' connection parameter.
209
- *
218
+ *
210
219
  */
211
220
  static VALUE
212
221
  pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
@@ -266,7 +275,6 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
266
275
  {
267
276
  PGPing ping;
268
277
  VALUE conninfo;
269
- VALUE error;
270
278
 
271
279
  conninfo = rb_funcall2( klass, rb_intern("parse_connect_args"), argc, argv );
272
280
  ping = PQping( StringValuePtr(conninfo) );
@@ -333,7 +341,7 @@ pgconn_s_conndefaults(VALUE self)
333
341
  *
334
342
  * This function is intended to be used by client applications that
335
343
  * send commands like: +ALTER USER joe PASSWORD 'pwd'+.
336
- * The arguments are the cleartext password, and the SQL name
344
+ * The arguments are the cleartext password, and the SQL name
337
345
  * of the user it is for.
338
346
  *
339
347
  * Return value is the encrypted password.
@@ -439,7 +447,7 @@ pgconn_finished_p( VALUE self )
439
447
  * call-seq:
440
448
  * conn.reset()
441
449
  *
442
- * Resets the backend connection. This method closes the
450
+ * Resets the backend connection. This method closes the
443
451
  * backend connection and tries to re-connect.
444
452
  */
445
453
  static VALUE
@@ -456,7 +464,7 @@ pgconn_reset(VALUE self)
456
464
  * Initiate a connection reset in a nonblocking manner.
457
465
  * This will close the current connection and attempt to
458
466
  * reconnect using the same connection parameters.
459
- * Use #reset_poll to check the status of the
467
+ * Use #reset_poll to check the status of the
460
468
  * connection reset.
461
469
  */
462
470
  static VALUE
@@ -617,14 +625,14 @@ pgconn_transaction_status(VALUE self)
617
625
  * _param_name_ is one of
618
626
  * * +server_version+
619
627
  * * +server_encoding+
620
- * * +client_encoding+
628
+ * * +client_encoding+
621
629
  * * +is_superuser+
622
630
  * * +session_authorization+
623
631
  * * +DateStyle+
624
632
  * * +TimeZone+
625
633
  * * +integer_datetimes+
626
634
  * * +standard_conforming_strings+
627
- *
635
+ *
628
636
  * Returns nil if the value of the parameter is not known.
629
637
  */
630
638
  static VALUE
@@ -641,8 +649,8 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
641
649
  * call-seq:
642
650
  * conn.protocol_version -> Integer
643
651
  *
644
- * The 3.0 protocol will normally be used when communicating with PostgreSQL 7.4
645
- * or later servers; pre-7.4 servers support only protocol 2.0. (Protocol 1.0 is
652
+ * The 3.0 protocol will normally be used when communicating with PostgreSQL 7.4
653
+ * or later servers; pre-7.4 servers support only protocol 2.0. (Protocol 1.0 is
646
654
  * obsolete and not supported by libpq.)
647
655
  */
648
656
  static VALUE
@@ -651,16 +659,16 @@ pgconn_protocol_version(VALUE self)
651
659
  return INT2NUM(PQprotocolVersion(pg_get_pgconn(self)));
652
660
  }
653
661
 
654
- /*
655
- * call-seq:
662
+ /*
663
+ * call-seq:
656
664
  * conn.server_version -> Integer
657
- *
665
+ *
658
666
  * The number is formed by converting the major, minor, and revision
659
667
  * numbers into two-decimal-digit numbers and appending them together.
660
668
  * For example, version 7.4.2 will be returned as 70402, and version
661
669
  * 8.1 will be returned as 80100 (leading zeroes are not shown). Zero
662
670
  * is returned if the connection is bad.
663
- *
671
+ *
664
672
  */
665
673
  static VALUE
666
674
  pgconn_server_version(VALUE self)
@@ -687,6 +695,15 @@ pgconn_error_message(VALUE self)
687
695
  * conn.socket() -> Fixnum
688
696
  *
689
697
  * Returns the socket's file descriptor for this connection.
698
+ * <tt>IO.for_fd()</tt> can be used to build a proper IO object to the socket.
699
+ * If you do so, you will likely also want to set <tt>autoclose=false</tt>
700
+ * on it to prevent Ruby from closing the socket to PostgreSQL if it
701
+ * goes out of scope. Alternatively, you can use #socket_io, which
702
+ * creates an IO that's associated with the connection object itself,
703
+ * and so won't go out of scope until the connection does.
704
+ *
705
+ * *Note:* On Windows the file descriptor is not really usable,
706
+ * since it can not be used to build a Ruby IO object.
690
707
  */
691
708
  static VALUE
692
709
  pgconn_socket(VALUE self)
@@ -742,16 +759,64 @@ pgconn_connection_used_password(VALUE self)
742
759
  /* :TODO: get_ssl */
743
760
 
744
761
 
762
+ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
763
+
745
764
  /*
746
765
  * call-seq:
747
- * conn.exec(sql [, params, result_format ] ) -> PG::Result
748
- * conn.exec(sql [, params, result_format ] ) {|pg_result| block }
766
+ * conn.exec(sql) -> PG::Result
767
+ * conn.exec(sql) {|pg_result| block }
749
768
  *
750
769
  * Sends SQL query request specified by _sql_ to PostgreSQL.
751
770
  * Returns a PG::Result instance on success.
752
771
  * On failure, it raises a PG::Error.
753
772
  *
754
- * +params+ is an optional array of the bind parameters for the SQL query.
773
+ * For backward compatibility, if you pass more than one parameter to this method,
774
+ * it will call #exec_params for you. New code should explicitly use #exec_params if
775
+ * argument placeholders are used.
776
+ *
777
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
778
+ * and the PG::Result object will automatically be cleared when the block terminates.
779
+ * In this instance, <code>conn.exec</code> returns the value of the block.
780
+ */
781
+ static VALUE
782
+ pgconn_exec(int argc, VALUE *argv, VALUE self)
783
+ {
784
+ PGconn *conn = pg_get_pgconn(self);
785
+ PGresult *result = NULL;
786
+ VALUE rb_pgresult;
787
+
788
+ /* If called with no parameters, use PQexec */
789
+ if ( argc == 1 ) {
790
+ Check_Type(argv[0], T_STRING);
791
+
792
+ result = gvl_PQexec(conn, StringValuePtr(argv[0]));
793
+ rb_pgresult = pg_new_result(result, self);
794
+ pg_result_check(rb_pgresult);
795
+ if (rb_block_given_p()) {
796
+ return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult);
797
+ }
798
+ return rb_pgresult;
799
+ }
800
+
801
+ /* Otherwise, just call #exec_params instead for backward-compatibility */
802
+ else {
803
+ return pgconn_exec_params( argc, argv, self );
804
+ }
805
+
806
+ }
807
+
808
+
809
+ /*
810
+ * call-seq:
811
+ * conn.exec_params(sql, params[, result_format ] ) -> PG::Result
812
+ * conn.exec_params(sql, params[, result_format ] ) {|pg_result| block }
813
+ *
814
+ * Sends SQL query request specified by +sql+ to PostgreSQL using placeholders
815
+ * for parameters.
816
+ *
817
+ * Returns a PG::Result instance on success. On failure, it raises a PG::Error.
818
+ *
819
+ * +params+ is an array of the bind parameters for the SQL query.
755
820
  * Each element of the +params+ array may be either:
756
821
  * a hash of the form:
757
822
  * {:value => String (value of bind parameter)
@@ -760,11 +825,11 @@ pgconn_connection_used_password(VALUE self)
760
825
  * }
761
826
  * or, it may be a String. If it is a string, that is equivalent to the hash:
762
827
  * { :value => <string value>, :type => 0, :format => 0 }
763
- *
828
+ *
764
829
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
765
830
  * inside the SQL query. The 0th element of the +params+ array is bound
766
831
  * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
767
- *
832
+ *
768
833
  * If the types are not specified, they will be inferred by PostgreSQL.
769
834
  * Instead of specifying type oids, it's recommended to simply add
770
835
  * explicit casts in the query to ensure that the right type is used.
@@ -774,12 +839,12 @@ pgconn_connection_used_password(VALUE self)
774
839
  * The optional +result_format+ should be 0 for text results, 1
775
840
  * for binary.
776
841
  *
777
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
778
- * and the PG::Result object will automatically be cleared when the block terminates.
842
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
843
+ * and the PG::Result object will automatically be cleared when the block terminates.
779
844
  * In this instance, <code>conn.exec</code> returns the value of the block.
780
845
  */
781
846
  static VALUE
782
- pgconn_exec(int argc, VALUE *argv, VALUE self)
847
+ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
783
848
  {
784
849
  PGconn *conn = pg_get_pgconn(self);
785
850
  PGresult *result = NULL;
@@ -799,25 +864,17 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
799
864
 
800
865
  rb_scan_args(argc, argv, "12", &command, &params, &in_res_fmt);
801
866
 
802
- Check_Type(command, T_STRING);
803
-
804
- /* If called with no parameters, use PQexec */
805
- if(NIL_P(params)) {
806
- result = PQexec(conn, StringValuePtr(command));
807
- rb_pgresult = pg_new_result(result, self);
808
- pg_result_check(rb_pgresult);
809
- if (rb_block_given_p()) {
810
- return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult);
867
+ /*
868
+ * Handle the edge-case where the caller is coming from #exec, but passed an explict +nil+
869
+ * for the second parameter.
870
+ */
871
+ if ( NIL_P(params) ) {
872
+ return pgconn_exec( 1, argv, self );
811
873
  }
812
- return rb_pgresult;
813
- }
814
874
 
815
- /* If called with parameters, and optionally result_format,
816
- * use PQexecParams
817
- */
818
875
  Check_Type(params, T_ARRAY);
819
876
 
820
- if(NIL_P(in_res_fmt)) {
877
+ if ( NIL_P(in_res_fmt) ) {
821
878
  resultFormat = 0;
822
879
  }
823
880
  else {
@@ -826,15 +883,17 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
826
883
 
827
884
  gc_array = rb_ary_new();
828
885
  rb_gc_register_address(&gc_array);
886
+
829
887
  sym_type = ID2SYM(rb_intern("type"));
830
888
  sym_value = ID2SYM(rb_intern("value"));
831
889
  sym_format = ID2SYM(rb_intern("format"));
832
890
  nParams = (int)RARRAY_LEN(params);
833
- paramTypes = ALLOC_N(Oid, nParams);
891
+ paramTypes = ALLOC_N(Oid, nParams);
834
892
  paramValues = ALLOC_N(char *, nParams);
835
893
  paramLengths = ALLOC_N(int, nParams);
836
894
  paramFormats = ALLOC_N(int, nParams);
837
- for(i = 0; i < nParams; i++) {
895
+
896
+ for ( i = 0; i < nParams; i++ ) {
838
897
  param = rb_ary_entry(params, i);
839
898
  if (TYPE(param) == T_HASH) {
840
899
  param_type = rb_hash_aref(param, sym_type);
@@ -877,7 +936,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
877
936
  paramFormats[i] = NUM2INT(param_format);
878
937
  }
879
938
 
880
- result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
939
+ result = gvl_PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
881
940
  (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
882
941
 
883
942
  rb_gc_unregister_address(&gc_array);
@@ -889,10 +948,11 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
889
948
 
890
949
  rb_pgresult = pg_new_result(result, self);
891
950
  pg_result_check(rb_pgresult);
951
+
892
952
  if (rb_block_given_p()) {
893
- return rb_ensure(rb_yield, rb_pgresult,
894
- pg_result_clear, rb_pgresult);
953
+ return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult);
895
954
  }
955
+
896
956
  return rb_pgresult;
897
957
  }
898
958
 
@@ -904,7 +964,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
904
964
  * Returns a PG::Result instance on success.
905
965
  * On failure, it raises a PG::Error.
906
966
  *
907
- * +param_types+ is an optional parameter to specify the Oids of the
967
+ * +param_types+ is an optional parameter to specify the Oids of the
908
968
  * types of the parameters.
909
969
  *
910
970
  * If the types are not specified, they will be inferred by PostgreSQL.
@@ -912,7 +972,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
912
972
  * explicit casts in the query to ensure that the right type is used.
913
973
  *
914
974
  * For example: "SELECT $1::int"
915
- *
975
+ *
916
976
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
917
977
  * inside the SQL query.
918
978
  */
@@ -935,7 +995,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
935
995
  if(! NIL_P(in_paramtypes)) {
936
996
  Check_Type(in_paramtypes, T_ARRAY);
937
997
  nParams = (int)RARRAY_LEN(in_paramtypes);
938
- paramTypes = ALLOC_N(Oid, nParams);
998
+ paramTypes = ALLOC_N(Oid, nParams);
939
999
  for(i = 0; i < nParams; i++) {
940
1000
  param = rb_ary_entry(in_paramtypes, i);
941
1001
  Check_Type(param, T_FIXNUM);
@@ -945,7 +1005,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
945
1005
  paramTypes[i] = NUM2INT(param);
946
1006
  }
947
1007
  }
948
- result = PQprepare(conn, StringValuePtr(name), StringValuePtr(command),
1008
+ result = gvl_PQprepare(conn, StringValuePtr(name), StringValuePtr(command),
949
1009
  nParams, paramTypes);
950
1010
 
951
1011
  xfree(paramTypes);
@@ -964,7 +1024,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
964
1024
  * Returns a PG::Result instance on success.
965
1025
  * On failure, it raises a PG::Error.
966
1026
  *
967
- * +params+ is an array of the optional bind parameters for the
1027
+ * +params+ is an array of the optional bind parameters for the
968
1028
  * SQL query. Each element of the +params+ array may be either:
969
1029
  * a hash of the form:
970
1030
  * {:value => String (value of bind parameter)
@@ -972,7 +1032,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
972
1032
  * }
973
1033
  * or, it may be a String. If it is a string, that is equivalent to the hash:
974
1034
  * { :value => <string value>, :format => 0 }
975
- *
1035
+ *
976
1036
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
977
1037
  * inside the SQL query. The 0th element of the +params+ array is bound
978
1038
  * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
@@ -980,8 +1040,8 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
980
1040
  * The optional +result_format+ should be 0 for text results, 1
981
1041
  * for binary.
982
1042
  *
983
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
984
- * and the PG::Result object will automatically be cleared when the block terminates.
1043
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
1044
+ * and the PG::Result object will automatically be cleared when the block terminates.
985
1045
  * In this instance, <code>conn.exec_prepared</code> returns the value of the block.
986
1046
  */
987
1047
  static VALUE
@@ -1064,8 +1124,8 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1064
1124
  paramFormats[i] = NUM2INT(param_format);
1065
1125
  }
1066
1126
 
1067
- result = PQexecPrepared(conn, StringValuePtr(name), nParams,
1068
- (const char * const *)paramValues, paramLengths, paramFormats,
1127
+ result = gvl_PQexecPrepared(conn, StringValuePtr(name), nParams,
1128
+ (const char * const *)paramValues, paramLengths, paramFormats,
1069
1129
  resultFormat);
1070
1130
 
1071
1131
  rb_gc_unregister_address(&gc_array);
@@ -1077,7 +1137,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1077
1137
  rb_pgresult = pg_new_result(result, self);
1078
1138
  pg_result_check(rb_pgresult);
1079
1139
  if (rb_block_given_p()) {
1080
- return rb_ensure(rb_yield, rb_pgresult,
1140
+ return rb_ensure(rb_yield, rb_pgresult,
1081
1141
  pg_result_clear, rb_pgresult);
1082
1142
  }
1083
1143
  return rb_pgresult;
@@ -1104,7 +1164,7 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1104
1164
  Check_Type(stmt_name, T_STRING);
1105
1165
  stmt = StringValuePtr(stmt_name);
1106
1166
  }
1107
- result = PQdescribePrepared(conn, stmt);
1167
+ result = gvl_PQdescribePrepared(conn, stmt);
1108
1168
  rb_pgresult = pg_new_result(result, self);
1109
1169
  pg_result_check(rb_pgresult);
1110
1170
  return rb_pgresult;
@@ -1132,7 +1192,7 @@ pgconn_describe_portal(self, stmt_name)
1132
1192
  Check_Type(stmt_name, T_STRING);
1133
1193
  stmt = StringValuePtr(stmt_name);
1134
1194
  }
1135
- result = PQdescribePortal(conn, stmt);
1195
+ result = gvl_PQdescribePortal(conn, stmt);
1136
1196
  rb_pgresult = pg_new_result(result, self);
1137
1197
  pg_result_check(rb_pgresult);
1138
1198
  return rb_pgresult;
@@ -1175,12 +1235,12 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1175
1235
  * Connection instance method for versions of 8.1 and higher of libpq
1176
1236
  * uses PQescapeStringConn, which is safer. Avoid calling as a class method,
1177
1237
  * the class method uses the deprecated PQescapeString() API function.
1178
- *
1238
+ *
1179
1239
  * Returns a SQL-safe version of the String _str_.
1180
- * This is the preferred way to make strings safe for inclusion in
1240
+ * This is the preferred way to make strings safe for inclusion in
1181
1241
  * SQL queries.
1182
- *
1183
- * Consider using exec_params, which avoids the need for passing values
1242
+ *
1243
+ * Consider using exec_params, which avoids the need for passing values
1184
1244
  * inside of SQL commands.
1185
1245
  *
1186
1246
  * Encoding of escaped string will be equal to client encoding of connection.
@@ -1192,7 +1252,7 @@ pgconn_s_escape(VALUE self, VALUE string)
1192
1252
  size_t size;
1193
1253
  int error;
1194
1254
  VALUE result;
1195
- #ifdef M17N_SUPPORTED
1255
+ #ifdef M17N_SUPPORTED
1196
1256
  rb_encoding* enc;
1197
1257
  #endif
1198
1258
 
@@ -1200,7 +1260,7 @@ pgconn_s_escape(VALUE self, VALUE string)
1200
1260
 
1201
1261
  escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1);
1202
1262
  if(rb_obj_class(self) == rb_cPGconn) {
1203
- size = PQescapeStringConn(pg_get_pgconn(self), escaped,
1263
+ size = PQescapeStringConn(pg_get_pgconn(self), escaped,
1204
1264
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1205
1265
  if(error) {
1206
1266
  xfree(escaped);
@@ -1227,7 +1287,7 @@ pgconn_s_escape(VALUE self, VALUE string)
1227
1287
 
1228
1288
  /*
1229
1289
  * call-seq:
1230
- * conn.escape_bytea( string ) -> String
1290
+ * conn.escape_bytea( string ) -> String
1231
1291
  *
1232
1292
  * Connection instance method for versions of 8.1 and higher of libpq
1233
1293
  * uses PQescapeByteaConn, which is safer. Avoid calling as a class method,
@@ -1237,16 +1297,16 @@ pgconn_s_escape(VALUE self, VALUE string)
1237
1297
  * class method.
1238
1298
  *
1239
1299
  * Escapes binary data for use within an SQL command with the type +bytea+.
1240
- *
1300
+ *
1241
1301
  * Certain byte values must be escaped (but all byte values may be escaped)
1242
1302
  * when used as part of a +bytea+ literal in an SQL statement. In general, to
1243
1303
  * escape a byte, it is converted into the three digit octal number equal to
1244
1304
  * the octet value, and preceded by two backslashes. The single quote (') and
1245
1305
  * backslash (\) characters have special alternative escape sequences.
1246
- * #escape_bytea performs this operation, escaping only the minimally required
1306
+ * #escape_bytea performs this operation, escaping only the minimally required
1247
1307
  * bytes.
1248
- *
1249
- * Consider using exec_params, which avoids the need for passing values inside of
1308
+ *
1309
+ * Consider using exec_params, which avoids the need for passing values inside of
1250
1310
  * SQL commands.
1251
1311
  */
1252
1312
  static VALUE
@@ -1368,6 +1428,61 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1368
1428
  }
1369
1429
  #endif
1370
1430
 
1431
+ #ifdef HAVE_PQSETSINGLEROWMODE
1432
+ /*
1433
+ * call-seq:
1434
+ * conn.set_single_row_mode -> self
1435
+ *
1436
+ * To enter single-row mode, call this method immediately after a successful
1437
+ * call of send_query (or a sibling function). This mode selection is effective
1438
+ * only for the currently executing query.
1439
+ * Then call Connection#get_result repeatedly, until it returns nil.
1440
+ *
1441
+ * Each (but the last) received Result has exactly one row and a
1442
+ * Result#result_status of PGRES_SINGLE_TUPLE. The last row has
1443
+ * zero rows and is used to indicate a successful execution of the query.
1444
+ * All of these Result objects will contain the same row description data
1445
+ * (column names, types, etc) that an ordinary Result object for the query
1446
+ * would have.
1447
+ *
1448
+ * *Caution:* While processing a query, the server may return some rows and
1449
+ * then encounter an error, causing the query to be aborted. Ordinarily, pg
1450
+ * discards any such rows and reports only the error. But in single-row mode,
1451
+ * those rows will have already been returned to the application. Hence, the
1452
+ * application will see some Result objects followed by an Error raised in get_result.
1453
+ * For proper transactional behavior, the application must be designed to discard
1454
+ * or undo whatever has been done with the previously-processed rows, if the query
1455
+ * ultimately fails.
1456
+ *
1457
+ * Example:
1458
+ * conn.send_query( "your SQL command" )
1459
+ * conn.set_single_row_mode
1460
+ * loop do
1461
+ * res = conn.get_result or break
1462
+ * res.check
1463
+ * res.each do |row|
1464
+ * # do something with the received row
1465
+ * end
1466
+ * end
1467
+ *
1468
+ */
1469
+ static VALUE
1470
+ pgconn_set_single_row_mode(VALUE self)
1471
+ {
1472
+ PGconn *conn = pg_get_pgconn(self);
1473
+ VALUE error;
1474
+
1475
+ if( PQsetSingleRowMode(conn) == 0 )
1476
+ {
1477
+ error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1478
+ rb_iv_set(error, "@connection", self);
1479
+ rb_exc_raise(error);
1480
+ }
1481
+
1482
+ return self;
1483
+ }
1484
+ #endif
1485
+
1371
1486
  /*
1372
1487
  * call-seq:
1373
1488
  * conn.send_query(sql [, params, result_format ] ) -> nil
@@ -1385,11 +1500,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1385
1500
  * }
1386
1501
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1387
1502
  * { :value => <string value>, :type => 0, :format => 0 }
1388
- *
1503
+ *
1389
1504
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1390
1505
  * inside the SQL query. The 0th element of the +params+ array is bound
1391
1506
  * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1392
- *
1507
+ *
1393
1508
  * If the types are not specified, they will be inferred by PostgreSQL.
1394
1509
  * Instead of specifying type oids, it's recommended to simply add
1395
1510
  * explicit casts in the query to ensure that the right type is used.
@@ -1449,7 +1564,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1449
1564
  sym_value = ID2SYM(rb_intern("value"));
1450
1565
  sym_format = ID2SYM(rb_intern("format"));
1451
1566
  nParams = (int)RARRAY_LEN(params);
1452
- paramTypes = ALLOC_N(Oid, nParams);
1567
+ paramTypes = ALLOC_N(Oid, nParams);
1453
1568
  paramValues = ALLOC_N(char *, nParams);
1454
1569
  paramLengths = ALLOC_N(int, nParams);
1455
1570
  paramFormats = ALLOC_N(int, nParams);
@@ -1496,10 +1611,10 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1496
1611
  paramFormats[i] = NUM2INT(param_format);
1497
1612
  }
1498
1613
 
1499
- result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
1614
+ result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
1500
1615
  (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
1501
1616
 
1502
- rb_gc_unregister_address(&gc_array);
1617
+ rb_gc_unregister_address(&gc_array);
1503
1618
 
1504
1619
  xfree(paramTypes);
1505
1620
  xfree(paramValues);
@@ -1522,7 +1637,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1522
1637
  * Sends prepare command asynchronously, and returns immediately.
1523
1638
  * On failure, it raises a PG::Error.
1524
1639
  *
1525
- * +param_types+ is an optional parameter to specify the Oids of the
1640
+ * +param_types+ is an optional parameter to specify the Oids of the
1526
1641
  * types of the parameters.
1527
1642
  *
1528
1643
  * If the types are not specified, they will be inferred by PostgreSQL.
@@ -1530,7 +1645,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1530
1645
  * explicit casts in the query to ensure that the right type is used.
1531
1646
  *
1532
1647
  * For example: "SELECT $1::int"
1533
- *
1648
+ *
1534
1649
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1535
1650
  * inside the SQL query.
1536
1651
  */
@@ -1553,7 +1668,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1553
1668
  if(! NIL_P(in_paramtypes)) {
1554
1669
  Check_Type(in_paramtypes, T_ARRAY);
1555
1670
  nParams = (int)RARRAY_LEN(in_paramtypes);
1556
- paramTypes = ALLOC_N(Oid, nParams);
1671
+ paramTypes = ALLOC_N(Oid, nParams);
1557
1672
  for(i = 0; i < nParams; i++) {
1558
1673
  param = rb_ary_entry(in_paramtypes, i);
1559
1674
  Check_Type(param, T_FIXNUM);
@@ -1585,7 +1700,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1585
1700
  * asynchronously, and returns immediately.
1586
1701
  * On failure, it raises a PG::Error.
1587
1702
  *
1588
- * +params+ is an array of the optional bind parameters for the
1703
+ * +params+ is an array of the optional bind parameters for the
1589
1704
  * SQL query. Each element of the +params+ array may be either:
1590
1705
  * a hash of the form:
1591
1706
  * {:value => String (value of bind parameter)
@@ -1593,7 +1708,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1593
1708
  * }
1594
1709
  * or, it may be a String. If it is a string, that is equivalent to the hash:
1595
1710
  * { :value => <string value>, :format => 0 }
1596
- *
1711
+ *
1597
1712
  * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1598
1713
  * inside the SQL query. The 0th element of the +params+ array is bound
1599
1714
  * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
@@ -1681,8 +1796,8 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1681
1796
  paramFormats[i] = NUM2INT(param_format);
1682
1797
  }
1683
1798
 
1684
- result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
1685
- (const char * const *)paramValues, paramLengths, paramFormats,
1799
+ result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
1800
+ (const char * const *)paramValues, paramLengths, paramFormats,
1686
1801
  resultFormat);
1687
1802
 
1688
1803
  rb_gc_unregister_address(&gc_array);
@@ -1703,7 +1818,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1703
1818
  * call-seq:
1704
1819
  * conn.send_describe_prepared( statement_name ) -> nil
1705
1820
  *
1706
- * Asynchronously send _command_ to the server. Does not block.
1821
+ * Asynchronously send _command_ to the server. Does not block.
1707
1822
  * Use in combination with +conn.get_result+.
1708
1823
  */
1709
1824
  static VALUE
@@ -1725,7 +1840,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
1725
1840
  * call-seq:
1726
1841
  * conn.send_describe_portal( portal_name ) -> nil
1727
1842
  *
1728
- * Asynchronously send _command_ to the server. Does not block.
1843
+ * Asynchronously send _command_ to the server. Does not block.
1729
1844
  * Use in combination with +conn.get_result+.
1730
1845
  */
1731
1846
  static VALUE
@@ -1755,8 +1870,8 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
1755
1870
  * Note: call this function repeatedly until it returns +nil+, or else
1756
1871
  * you will not be able to issue further commands.
1757
1872
  *
1758
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1759
- * and the PG::Result object will automatically be cleared when the block terminates.
1873
+ * If the optional code block is given, it will be passed <i>result</i> as an argument,
1874
+ * and the PG::Result object will automatically be cleared when the block terminates.
1760
1875
  * In this instance, <code>conn.exec</code> returns the value of the block.
1761
1876
  */
1762
1877
  static VALUE
@@ -1766,7 +1881,7 @@ pgconn_get_result(VALUE self)
1766
1881
  PGresult *result;
1767
1882
  VALUE rb_pgresult;
1768
1883
 
1769
- result = PQgetResult(conn);
1884
+ result = gvl_PQgetResult(conn);
1770
1885
  if(result == NULL)
1771
1886
  return Qnil;
1772
1887
  rb_pgresult = pg_new_result(result, self);
@@ -1818,7 +1933,7 @@ pgconn_is_busy(self)
1818
1933
  * call-seq:
1819
1934
  * conn.setnonblocking(Boolean) -> nil
1820
1935
  *
1821
- * Sets the nonblocking status of the connection.
1936
+ * Sets the nonblocking status of the connection.
1822
1937
  * In the blocking state, calls to #send_query
1823
1938
  * will block until the message is sent to the server,
1824
1939
  * but will not wait for the query results.
@@ -1826,7 +1941,7 @@ pgconn_is_busy(self)
1826
1941
  * will return an error if the socket is not ready for
1827
1942
  * writing.
1828
1943
  * Note: This function does not affect #exec, because
1829
- * that function doesn't return until the server has
1944
+ * that function doesn't return until the server has
1830
1945
  * processed the query and returned the results.
1831
1946
  * Returns +nil+.
1832
1947
  */
@@ -1959,6 +2074,10 @@ pgconn_notifies(VALUE self)
1959
2074
  relname = rb_tainted_str_new2(notification->relname);
1960
2075
  be_pid = INT2NUM(notification->be_pid);
1961
2076
  extra = rb_tainted_str_new2(notification->extra);
2077
+ #ifdef M17N_SUPPORTED
2078
+ ENCODING_SET( relname, rb_enc_to_index(pg_conn_enc_get( conn )) );
2079
+ ENCODING_SET( extra, rb_enc_to_index(pg_conn_enc_get( conn )) );
2080
+ #endif
1962
2081
 
1963
2082
  rb_hash_aset(hash, sym_relname, relname);
1964
2083
  rb_hash_aset(hash, sym_be_pid, be_pid);
@@ -1968,9 +2087,10 @@ pgconn_notifies(VALUE self)
1968
2087
  return hash;
1969
2088
  }
1970
2089
 
2090
+ /* Win32 + Ruby 1.8 */
2091
+ #if !defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
1971
2092
 
1972
- #ifdef _WIN32
1973
- /*
2093
+ /*
1974
2094
  * Duplicate the sockets from libpq and create temporary CRT FDs
1975
2095
  */
1976
2096
  void create_crt_fd(fd_set *os_set, fd_set *crt_set)
@@ -2004,6 +2124,149 @@ void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
2004
2124
  }
2005
2125
  #endif
2006
2126
 
2127
+ /* Win32 + Ruby 1.9+ */
2128
+ #if defined( HAVE_RUBY_VM_H ) && defined( _WIN32 )
2129
+ /*
2130
+ * On Windows, use platform-specific strategies to wait for the socket
2131
+ * instead of rb_thread_select().
2132
+ */
2133
+
2134
+ int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2135
+
2136
+ /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2137
+ * and does not wait (nor sleep) any time even if timeout is given.
2138
+ * Instead use the Winsock events and rb_w32_wait_events(). */
2139
+
2140
+ static void *
2141
+ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *) )
2142
+ {
2143
+ int sd = PQsocket( conn );
2144
+ void *retval;
2145
+ DWORD timeout_milisec = INFINITE;
2146
+ DWORD wait_ret;
2147
+ WSAEVENT hEvent;
2148
+
2149
+ if ( sd < 0 )
2150
+ rb_bug( "PQsocket(conn): couldn't fetch the connection's socket!" );
2151
+
2152
+ hEvent = WSACreateEvent();
2153
+
2154
+ if ( ptimeout ) {
2155
+ timeout_milisec = (DWORD)( ptimeout->tv_sec * 1e3 + ptimeout->tv_usec / 1e3 );
2156
+ }
2157
+
2158
+ /* Check for connection errors (PQisBusy is true on connection errors) */
2159
+ if( PQconsumeInput(conn) == 0 ) {
2160
+ WSACloseEvent( hEvent );
2161
+ rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2162
+ }
2163
+
2164
+ while ( !(retval=is_readable(conn)) ) {
2165
+ if ( WSAEventSelect(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
2166
+ WSACloseEvent( hEvent );
2167
+ rb_raise( rb_ePGerror, "WSAEventSelect socket error: %d", WSAGetLastError() );
2168
+ }
2169
+
2170
+ wait_ret = rb_w32_wait_events( &hEvent, 1, timeout_milisec );
2171
+
2172
+ if ( wait_ret == WAIT_TIMEOUT ) {
2173
+ WSACloseEvent( hEvent );
2174
+ return NULL;
2175
+ } else if ( wait_ret == WAIT_OBJECT_0 ) {
2176
+ /* The event we were waiting for. */
2177
+ } else if ( wait_ret == WAIT_FAILED ) {
2178
+ WSACloseEvent( hEvent );
2179
+ rb_raise( rb_ePGerror, "Wait on socket error (WaitForMultipleObjects): %d", GetLastError() );
2180
+ } else {
2181
+ WSACloseEvent( hEvent );
2182
+ rb_raise( rb_ePGerror, "Wait on socket abandoned (WaitForMultipleObjects)" );
2183
+ }
2184
+
2185
+ /* Check for connection errors (PQisBusy is true on connection errors) */
2186
+ if ( PQconsumeInput(conn) == 0 ) {
2187
+ WSACloseEvent( hEvent );
2188
+ rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2189
+ }
2190
+ }
2191
+
2192
+ WSACloseEvent( hEvent );
2193
+ return retval;
2194
+ }
2195
+
2196
+ #else
2197
+
2198
+ /* non Win32 or Win32+Ruby-1.8 */
2199
+
2200
+ static void *
2201
+ wait_socket_readable( PGconn *conn, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2202
+ {
2203
+ int sd = PQsocket( conn );
2204
+ int ret;
2205
+ void *retval;
2206
+ rb_fdset_t sd_rset;
2207
+ #ifdef _WIN32
2208
+ rb_fdset_t crt_sd_rset;
2209
+ #endif
2210
+
2211
+ if ( sd < 0 )
2212
+ rb_bug( "PQsocket(conn): couldn't fetch the connection's socket!" );
2213
+
2214
+ /* Check for connection errors (PQisBusy is true on connection errors) */
2215
+ if ( PQconsumeInput(conn) == 0 )
2216
+ rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2217
+
2218
+ rb_fd_init( &sd_rset );
2219
+
2220
+ while ( !(retval=is_readable(conn)) ) {
2221
+ rb_fd_zero( &sd_rset );
2222
+ rb_fd_set( sd, &sd_rset );
2223
+
2224
+ #ifdef _WIN32
2225
+ /* Ruby's FD_SET is modified on win32 to convert a file descriptor
2226
+ * to osfhandle, but we already get a osfhandle from PQsocket().
2227
+ * Therefore it's overwritten here. */
2228
+ sd_rset.fd_array[0] = sd;
2229
+ create_crt_fd(&sd_rset, &crt_sd_rset);
2230
+ #endif
2231
+
2232
+ /* Wait for the socket to become readable before checking again */
2233
+ ret = rb_thread_fd_select( sd+1, &sd_rset, NULL, NULL, ptimeout );
2234
+
2235
+ #ifdef _WIN32
2236
+ cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2237
+ #endif
2238
+
2239
+ if ( ret < 0 ){
2240
+ rb_fd_term( &sd_rset );
2241
+ rb_sys_fail( "rb_thread_select()" );
2242
+ }
2243
+
2244
+ /* Return false if the select() timed out */
2245
+ if ( ret == 0 ){
2246
+ rb_fd_term( &sd_rset );
2247
+ return NULL;
2248
+ }
2249
+
2250
+ /* Check for connection errors (PQisBusy is true on connection errors) */
2251
+ if ( PQconsumeInput(conn) == 0 ){
2252
+ rb_fd_term( &sd_rset );
2253
+ rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2254
+ }
2255
+ }
2256
+
2257
+ rb_fd_term( &sd_rset );
2258
+ return retval;
2259
+ }
2260
+
2261
+
2262
+ #endif
2263
+
2264
+ static void *
2265
+ notify_readable(PGconn *conn)
2266
+ {
2267
+ return (void*)PQnotifies(conn);
2268
+ }
2269
+
2007
2270
  /*
2008
2271
  * call-seq:
2009
2272
  * conn.wait_for_notify( [ timeout ] ) -> String
@@ -2017,30 +2280,21 @@ void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
2017
2280
  * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY
2018
2281
  * event otherwise. If used in block form, passes the name of the
2019
2282
  * NOTIFY +event+ and the generating +pid+ into the block.
2020
- *
2283
+ *
2021
2284
  * Under PostgreSQL 9.0 and later, if the notification is sent with
2022
2285
  * the optional +payload+ string, it will be given to the block as the
2023
2286
  * third argument.
2024
- *
2287
+ *
2025
2288
  */
2026
2289
  static VALUE
2027
2290
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2028
2291
  {
2029
2292
  PGconn *conn = pg_get_pgconn( self );
2030
- PGnotify *notification;
2031
- int sd = PQsocket( conn );
2032
- int ret;
2293
+ PGnotify *pnotification;
2033
2294
  struct timeval timeout;
2034
2295
  struct timeval *ptimeout = NULL;
2035
2296
  VALUE timeout_in = Qnil, relname = Qnil, be_pid = Qnil, extra = Qnil;
2036
2297
  double timeout_sec;
2037
- fd_set sd_rset;
2038
- #ifdef _WIN32
2039
- fd_set crt_sd_rset;
2040
- #endif
2041
-
2042
- if ( sd < 0 )
2043
- rb_bug( "PQsocket(conn): couldn't fetch the connection's socket!" );
2044
2298
 
2045
2299
  rb_scan_args( argc, argv, "01", &timeout_in );
2046
2300
 
@@ -2051,43 +2305,25 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2051
2305
  ptimeout = &timeout;
2052
2306
  }
2053
2307
 
2054
- /* Check for notifications */
2055
- while ( (notification = PQnotifies(conn)) == NULL ) {
2056
- FD_ZERO( &sd_rset );
2057
- FD_SET( sd, &sd_rset );
2058
-
2059
- #ifdef _WIN32
2060
- create_crt_fd(&sd_rset, &crt_sd_rset);
2061
- #endif
2308
+ pnotification = (PGnotify*) wait_socket_readable( conn, ptimeout, notify_readable);
2062
2309
 
2063
- /* Wait for the socket to become readable before checking again */
2064
- ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout );
2310
+ /* Return nil if the select timed out */
2311
+ if ( !pnotification ) return Qnil;
2065
2312
 
2066
- #ifdef _WIN32
2067
- cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2313
+ relname = rb_tainted_str_new2( pnotification->relname );
2314
+ #ifdef M17N_SUPPORTED
2315
+ ENCODING_SET( relname, rb_enc_to_index(pg_conn_enc_get( conn )) );
2068
2316
  #endif
2069
-
2070
- if ( ret < 0 )
2071
- rb_sys_fail( 0 );
2072
-
2073
- /* Return nil if the select timed out */
2074
- if ( ret == 0 ) return Qnil;
2075
-
2076
- /* Read the socket */
2077
- if ( (ret = PQconsumeInput(conn)) != 1 )
2078
- rb_raise( rb_ePGerror, "PQconsumeInput == %d: %s", ret, PQerrorMessage(conn) );
2079
- }
2080
-
2081
- relname = rb_tainted_str_new2( notification->relname );
2082
- ASSOCIATE_INDEX( relname, self );
2083
- be_pid = INT2NUM( notification->be_pid );
2317
+ be_pid = INT2NUM( pnotification->be_pid );
2084
2318
  #ifdef HAVE_ST_NOTIFY_EXTRA
2085
- if ( *notification->extra ) {
2086
- extra = rb_tainted_str_new2( notification->extra );
2087
- ASSOCIATE_INDEX( extra, self );
2319
+ if ( *pnotification->extra ) {
2320
+ extra = rb_tainted_str_new2( pnotification->extra );
2321
+ #ifdef M17N_SUPPORTED
2322
+ ENCODING_SET( extra, rb_enc_to_index(pg_conn_enc_get( conn )) );
2323
+ #endif
2088
2324
  }
2089
2325
  #endif
2090
- PQfreemem( notification );
2326
+ PQfreemem( pnotification );
2091
2327
 
2092
2328
  if ( rb_block_given_p() )
2093
2329
  rb_yield_values( 3, relname, be_pid, extra );
@@ -2116,7 +2352,7 @@ pgconn_put_copy_data(self, buffer)
2116
2352
  PGconn *conn = pg_get_pgconn(self);
2117
2353
  Check_Type(buffer, T_STRING);
2118
2354
 
2119
- ret = PQputCopyData(conn, RSTRING_PTR(buffer), (int)RSTRING_LEN(buffer));
2355
+ ret = gvl_PQputCopyData(conn, RSTRING_PTR(buffer), (int)RSTRING_LEN(buffer));
2120
2356
  if(ret == -1) {
2121
2357
  error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2122
2358
  rb_iv_set(error, "@connection", self);
@@ -2138,7 +2374,7 @@ pgconn_put_copy_data(self, buffer)
2138
2374
  * Returns true if the end-of-data was sent, false if it was
2139
2375
  * not sent (false is only possible if the connection
2140
2376
  * is in nonblocking mode, and this command would block).
2141
- */
2377
+ */
2142
2378
  static VALUE
2143
2379
  pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2144
2380
  {
@@ -2153,7 +2389,7 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2153
2389
  else
2154
2390
  error_message = StringValuePtr(str);
2155
2391
 
2156
- ret = PQputCopyEnd(conn, error_message);
2392
+ ret = gvl_PQputCopyEnd(conn, error_message);
2157
2393
  if(ret == -1) {
2158
2394
  error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2159
2395
  rb_iv_set(error, "@connection", self);
@@ -2167,7 +2403,7 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2167
2403
  * conn.get_copy_data( [ async = false ] ) -> String
2168
2404
  *
2169
2405
  * Return a string containing one row of data, +nil+
2170
- * if the copy is done, or +false+ if the call would
2406
+ * if the copy is done, or +false+ if the call would
2171
2407
  * block (only possible if _async_ is true).
2172
2408
  *
2173
2409
  */
@@ -2187,7 +2423,7 @@ pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2187
2423
  else
2188
2424
  async = (async_in == Qfalse || async_in == Qnil) ? 0 : 1;
2189
2425
 
2190
- ret = PQgetCopyData(conn, &buffer, async);
2426
+ ret = gvl_PQgetCopyData(conn, &buffer, async);
2191
2427
  if(ret == -2) { /* error */
2192
2428
  error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2193
2429
  rb_iv_set(error, "@connection", self);
@@ -2225,8 +2461,8 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2225
2461
  /*
2226
2462
  * call-seq:
2227
2463
  * conn.trace( stream ) -> nil
2228
- *
2229
- * Enables tracing message passing between backend. The
2464
+ *
2465
+ * Enables tracing message passing between backend. The
2230
2466
  * trace message will be written to the stream _stream_,
2231
2467
  * which must implement a method +fileno+ that returns
2232
2468
  * a writable file descriptor.
@@ -2269,7 +2505,7 @@ pgconn_trace(VALUE self, VALUE stream)
2269
2505
  /*
2270
2506
  * call-seq:
2271
2507
  * conn.untrace() -> nil
2272
- *
2508
+ *
2273
2509
  * Disables the message tracing.
2274
2510
  */
2275
2511
  static VALUE
@@ -2288,15 +2524,20 @@ pgconn_untrace(VALUE self)
2288
2524
  * Notice callback proxy function -- delegate the callback to the
2289
2525
  * currently-registered Ruby notice_receiver object.
2290
2526
  */
2291
- static void
2527
+ void
2292
2528
  notice_receiver_proxy(void *arg, const PGresult *result)
2293
2529
  {
2294
2530
  VALUE proc;
2295
2531
  VALUE self = (VALUE)arg;
2296
2532
 
2297
2533
  if ((proc = rb_iv_get(self, "@notice_receiver")) != Qnil) {
2298
- rb_funcall(proc, rb_intern("call"), 1,
2299
- Data_Wrap_Struct(rb_cPGresult, NULL, NULL, (PGresult*)result));
2534
+ VALUE val = Data_Wrap_Struct(rb_cPGresult, NULL, NULL, (PGresult*)result);
2535
+ #ifdef M17N_SUPPORTED
2536
+ PGconn *conn = pg_get_pgconn( self );
2537
+ rb_encoding *enc = pg_conn_enc_get( conn );
2538
+ ENCODING_SET( val, rb_enc_to_index(enc) );
2539
+ #endif
2540
+ rb_funcall(proc, rb_intern("call"), 1, val);
2300
2541
  }
2301
2542
  return;
2302
2543
  }
@@ -2313,15 +2554,15 @@ notice_receiver_proxy(void *arg, const PGresult *result)
2313
2554
  * application can override this behavior by supplying its own handling
2314
2555
  * function.
2315
2556
  *
2316
- * For historical reasons, there are two levels of notice handling, called the
2317
- * notice receiver and notice processor. The default behavior is for the notice
2318
- * receiver to format the notice and pass a string to the notice processor for
2319
- * printing. However, an application that chooses to provide its own notice
2320
- * receiver will typically ignore the notice processor layer and just do all
2557
+ * For historical reasons, there are two levels of notice handling, called the
2558
+ * notice receiver and notice processor. The default behavior is for the notice
2559
+ * receiver to format the notice and pass a string to the notice processor for
2560
+ * printing. However, an application that chooses to provide its own notice
2561
+ * receiver will typically ignore the notice processor layer and just do all
2321
2562
  * the work in the notice receiver.
2322
2563
  *
2323
2564
  * This function takes a new block to act as the handler, which should
2324
- * accept a single parameter that will be a PG::Result object, and returns
2565
+ * accept a single parameter that will be a PG::Result object, and returns
2325
2566
  * the Proc object previously set, or +nil+ if it was previously the default.
2326
2567
  *
2327
2568
  * If you pass no arguments, it will reset the handler to the default.
@@ -2336,8 +2577,8 @@ pgconn_set_notice_receiver(VALUE self)
2336
2577
  VALUE proc, old_proc;
2337
2578
  PGconn *conn = pg_get_pgconn(self);
2338
2579
 
2339
- /* If default_notice_receiver is unset, assume that the current
2340
- * notice receiver is the default, and save it to a global variable.
2580
+ /* If default_notice_receiver is unset, assume that the current
2581
+ * notice receiver is the default, and save it to a global variable.
2341
2582
  * This should not be a problem because the default receiver is
2342
2583
  * always the same, so won't vary among connections.
2343
2584
  */
@@ -2347,7 +2588,7 @@ pgconn_set_notice_receiver(VALUE self)
2347
2588
  old_proc = rb_iv_get(self, "@notice_receiver");
2348
2589
  if( rb_block_given_p() ) {
2349
2590
  proc = rb_block_proc();
2350
- PQsetNoticeReceiver(conn, notice_receiver_proxy, (void *)self);
2591
+ PQsetNoticeReceiver(conn, gvl_notice_receiver_proxy, (void *)self);
2351
2592
  } else {
2352
2593
  /* if no block is given, set back to default */
2353
2594
  proc = Qnil;
@@ -2363,14 +2604,20 @@ pgconn_set_notice_receiver(VALUE self)
2363
2604
  * Notice callback proxy function -- delegate the callback to the
2364
2605
  * currently-registered Ruby notice_processor object.
2365
2606
  */
2366
- static void
2607
+ void
2367
2608
  notice_processor_proxy(void *arg, const char *message)
2368
2609
  {
2369
2610
  VALUE proc;
2370
2611
  VALUE self = (VALUE)arg;
2371
2612
 
2372
2613
  if ((proc = rb_iv_get(self, "@notice_processor")) != Qnil) {
2373
- rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(message));
2614
+ VALUE message_str = rb_tainted_str_new2(message);
2615
+ #ifdef M17N_SUPPORTED
2616
+ PGconn *conn = pg_get_pgconn( self );
2617
+ rb_encoding *enc = pg_conn_enc_get( conn );
2618
+ ENCODING_SET( message_str, rb_enc_to_index(enc) );
2619
+ #endif
2620
+ rb_funcall(proc, rb_intern("call"), 1, message_str);
2374
2621
  }
2375
2622
  return;
2376
2623
  }
@@ -2382,9 +2629,9 @@ notice_processor_proxy(void *arg, const char *message)
2382
2629
  * See #set_notice_receiver for the desription of what this and the
2383
2630
  * notice_processor methods do.
2384
2631
  *
2385
- * This function takes a new block to act as the notice processor and returns
2632
+ * This function takes a new block to act as the notice processor and returns
2386
2633
  * the Proc object previously set, or +nil+ if it was previously the default.
2387
- * The block should accept a single PG::Result object.
2634
+ * The block should accept a single String object.
2388
2635
  *
2389
2636
  * If you pass no arguments, it will reset the handler to the default.
2390
2637
  */
@@ -2394,8 +2641,8 @@ pgconn_set_notice_processor(VALUE self)
2394
2641
  VALUE proc, old_proc;
2395
2642
  PGconn *conn = pg_get_pgconn(self);
2396
2643
 
2397
- /* If default_notice_processor is unset, assume that the current
2398
- * notice processor is the default, and save it to a global variable.
2644
+ /* If default_notice_processor is unset, assume that the current
2645
+ * notice processor is the default, and save it to a global variable.
2399
2646
  * This should not be a problem because the default processor is
2400
2647
  * always the same, so won't vary among connections.
2401
2648
  */
@@ -2405,7 +2652,7 @@ pgconn_set_notice_processor(VALUE self)
2405
2652
  old_proc = rb_iv_get(self, "@notice_processor");
2406
2653
  if( rb_block_given_p() ) {
2407
2654
  proc = rb_block_proc();
2408
- PQsetNoticeProcessor(conn, notice_processor_proxy, (void *)self);
2655
+ PQsetNoticeProcessor(conn, gvl_notice_processor_proxy, (void *)self);
2409
2656
  } else {
2410
2657
  /* if no block is given, set back to default */
2411
2658
  proc = Qnil;
@@ -2420,7 +2667,7 @@ pgconn_set_notice_processor(VALUE self)
2420
2667
  /*
2421
2668
  * call-seq:
2422
2669
  * conn.get_client_encoding() -> String
2423
- *
2670
+ *
2424
2671
  * Returns the client encoding as a String.
2425
2672
  */
2426
2673
  static VALUE
@@ -2434,7 +2681,7 @@ pgconn_get_client_encoding(VALUE self)
2434
2681
  /*
2435
2682
  * call-seq:
2436
2683
  * conn.set_client_encoding( encoding )
2437
- *
2684
+ *
2438
2685
  * Sets the client encoding to the _encoding_ String.
2439
2686
  */
2440
2687
  static VALUE
@@ -2456,7 +2703,7 @@ pgconn_set_client_encoding(VALUE self, VALUE str)
2456
2703
  * conn.transaction { |conn| ... } -> nil
2457
2704
  *
2458
2705
  * Executes a +BEGIN+ at the start of the block,
2459
- * and a +COMMIT+ at the end of the block, or
2706
+ * and a +COMMIT+ at the end of the block, or
2460
2707
  * +ROLLBACK+ if any exception occurs.
2461
2708
  */
2462
2709
  static VALUE
@@ -2468,18 +2715,18 @@ pgconn_transaction(VALUE self)
2468
2715
  int status;
2469
2716
 
2470
2717
  if (rb_block_given_p()) {
2471
- result = PQexec(conn, "BEGIN");
2718
+ result = gvl_PQexec(conn, "BEGIN");
2472
2719
  rb_pgresult = pg_new_result(result, self);
2473
2720
  pg_result_check(rb_pgresult);
2474
2721
  rb_protect(rb_yield, self, &status);
2475
2722
  if(status == 0) {
2476
- result = PQexec(conn, "COMMIT");
2723
+ result = gvl_PQexec(conn, "COMMIT");
2477
2724
  rb_pgresult = pg_new_result(result, self);
2478
2725
  pg_result_check(rb_pgresult);
2479
2726
  }
2480
2727
  else {
2481
2728
  /* exception occurred, ROLLBACK and re-raise */
2482
- result = PQexec(conn, "ROLLBACK");
2729
+ result = gvl_PQexec(conn, "ROLLBACK");
2483
2730
  rb_pgresult = pg_new_result(result, self);
2484
2731
  pg_result_check(rb_pgresult);
2485
2732
  rb_jump_tag(status);
@@ -2502,7 +2749,7 @@ pgconn_transaction(VALUE self)
2502
2749
  * Returns a string that is safe for inclusion in a SQL query as an
2503
2750
  * identifier. Note: this is not a quote function for values, but for
2504
2751
  * identifiers.
2505
- *
2752
+ *
2506
2753
  * For example, in a typical SQL query: <tt>SELECT FOO FROM MYTABLE</tt>
2507
2754
  * The identifier <tt>FOO</tt> is folded to lower case, so it actually
2508
2755
  * means <tt>foo</tt>. If you really want to access the case-sensitive
@@ -2510,7 +2757,7 @@ pgconn_transaction(VALUE self)
2510
2757
  * <tt>PG::Connection.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
2511
2758
  * (with double-quotes). PostgreSQL will see the double-quotes, and
2512
2759
  * it will not fold to lower case.
2513
- *
2760
+ *
2514
2761
  * Similarly, this function also protects against special characters,
2515
2762
  * and other things that might allow SQL injection if the identifier
2516
2763
  * comes from an untrusted source.
@@ -2528,13 +2775,13 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
2528
2775
  UNUSED( self );
2529
2776
 
2530
2777
  if(strlen(str) >= NAMEDATALEN) {
2531
- rb_raise(rb_eArgError,
2778
+ rb_raise(rb_eArgError,
2532
2779
  "Input string is longer than NAMEDATALEN-1 (%d)",
2533
2780
  NAMEDATALEN-1);
2534
2781
  }
2535
2782
  buffer[j++] = '"';
2536
2783
  for(i = 0; i < strlen(str) && str[i]; i++) {
2537
- if(str[i] == '"')
2784
+ if(str[i] == '"')
2538
2785
  buffer[j++] = '"';
2539
2786
  buffer[j++] = str[i];
2540
2787
  }
@@ -2545,169 +2792,39 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
2545
2792
  }
2546
2793
 
2547
2794
 
2548
- #ifndef _WIN32
2795
+ static void *
2796
+ get_result_readable(PGconn *conn)
2797
+ {
2798
+ return PQisBusy(conn) ? NULL : (void*)1;
2799
+ }
2800
+
2549
2801
 
2550
2802
  /*
2551
2803
  * call-seq:
2552
2804
  * conn.block( [ timeout ] ) -> Boolean
2553
2805
  *
2554
- * Blocks until the server is no longer busy, or until the
2806
+ * Blocks until the server is no longer busy, or until the
2555
2807
  * optional _timeout_ is reached, whichever comes first.
2556
2808
  * _timeout_ is measured in seconds and can be fractional.
2557
- *
2809
+ *
2558
2810
  * Returns +false+ if _timeout_ is reached, +true+ otherwise.
2559
- *
2811
+ *
2560
2812
  * If +true+ is returned, +conn.is_busy+ will return +false+
2561
2813
  * and +conn.get_result+ will not block.
2562
2814
  */
2563
2815
  static VALUE
2564
2816
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
2565
2817
  PGconn *conn = pg_get_pgconn( self );
2566
- int sd = PQsocket( conn );
2567
- int ret;
2568
2818
 
2569
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2819
+ /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2570
2820
  * and does not wait (nor sleep) any time even if timeout is given.
2571
2821
  * Instead use the Winsock events and rb_w32_wait_events(). */
2572
2822
 
2573
2823
  struct timeval timeout;
2574
2824
  struct timeval *ptimeout = NULL;
2575
- fd_set sd_rset;
2576
- VALUE timeout_in;
2577
- double timeout_sec;
2578
-
2579
- if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2580
- timeout_sec = NUM2DBL( timeout_in );
2581
- timeout.tv_sec = (time_t)timeout_sec;
2582
- timeout.tv_usec = (suseconds_t)((timeout_sec - (long)timeout_sec) * 1e6);
2583
- ptimeout = &timeout;
2584
- }
2585
-
2586
- /* Check for connection errors (PQisBusy is true on connection errors) */
2587
- if ( PQconsumeInput(conn) == 0 )
2588
- rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2589
-
2590
- while ( PQisBusy(conn) ) {
2591
- FD_ZERO( &sd_rset );
2592
- FD_SET( sd, &sd_rset );
2593
-
2594
- if ( (ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout )) < 0 )
2595
- rb_sys_fail( "rb_thread_select()" ); /* Raises */
2596
-
2597
- /* Return false if there was a timeout argument and the select() timed out */
2598
- if ( ret == 0 && argc )
2599
- return Qfalse;
2600
-
2601
- /* Check for connection errors (PQisBusy is true on connection errors) */
2602
- if ( PQconsumeInput(conn) == 0 )
2603
- rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) );
2604
- }
2605
-
2606
- return Qtrue;
2607
- }
2608
-
2609
-
2610
- #else /* _WIN32 */
2611
-
2612
- /*
2613
- * Win32 PG::Connection#block -- on Windows, use platform-specific strategies to wait for the socket
2614
- * instead of rb_thread_select().
2615
- */
2616
-
2617
- /* Win32 + Ruby 1.9+ */
2618
- #ifdef HAVE_RUBY_VM_H
2619
-
2620
- int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2621
-
2622
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2623
- * and does not wait (nor sleep) any time even if timeout is given.
2624
- * Instead use the Winsock events and rb_w32_wait_events(). */
2625
-
2626
- static VALUE
2627
- pgconn_block( int argc, VALUE *argv, VALUE self ) {
2628
- PGconn *conn = pg_get_pgconn( self );
2629
- int sd = PQsocket( conn );
2630
- int ret;
2631
-
2632
- DWORD timeout_milisec = INFINITY;
2633
- DWORD wait_ret;
2634
- WSAEVENT hEvent;
2635
- VALUE timeout_in;
2636
- double timeout_sec;
2637
-
2638
- hEvent = WSACreateEvent();
2639
-
2640
- if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2641
- timeout_sec = NUM2DBL( timeout_in );
2642
- timeout_milisec = (DWORD)( (timeout_sec - (DWORD)timeout_sec) * 1e3 );
2643
- }
2644
-
2645
- /* Check for connection errors (PQisBusy is true on connection errors) */
2646
- if( PQconsumeInput(conn) == 0 ) {
2647
- WSACloseEvent( hEvent );
2648
- rb_raise( rb_ePGerror, PQerrorMessage(conn) );
2649
- }
2650
-
2651
- while ( PQisBusy(conn) ) {
2652
- if ( WSAEventSelect(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
2653
- WSACloseEvent( hEvent );
2654
- rb_raise( rb_ePGerror, "WSAEventSelect socket error: %d", WSAGetLastError() );
2655
- }
2656
-
2657
- wait_ret = rb_w32_wait_events( &hEvent, 1, 100 );
2658
-
2659
- if ( wait_ret == WAIT_TIMEOUT ) {
2660
- ret = 0;
2661
- } else if ( wait_ret == WAIT_OBJECT_0 ) {
2662
- ret = 1;
2663
- } else if ( wait_ret == WAIT_FAILED ) {
2664
- WSACloseEvent( hEvent );
2665
- rb_raise( rb_ePGerror, "Wait on socket error (WaitForMultipleObjects): %d", GetLastError() );
2666
- } else {
2667
- WSACloseEvent( hEvent );
2668
- rb_raise( rb_ePGerror, "Wait on socket abandoned (WaitForMultipleObjects)" );
2669
- }
2670
-
2671
- /* Return false if there was a timeout argument and the select() timed out */
2672
- if ( ret == 0 && argc ) {
2673
- WSACloseEvent( hEvent );
2674
- return Qfalse;
2675
- }
2676
-
2677
- /* Check for connection errors (PQisBusy is true on connection errors) */
2678
- if ( PQconsumeInput(conn) == 0 ) {
2679
- WSACloseEvent( hEvent );
2680
- rb_raise( rb_ePGerror, PQerrorMessage(conn) );
2681
- }
2682
- }
2683
-
2684
- WSACloseEvent( hEvent );
2685
-
2686
- return Qtrue;
2687
- }
2688
-
2689
- #else /* Win32 + Ruby < 1.9 */
2690
-
2691
- static VALUE
2692
- pgconn_block( int argc, VALUE *argv, VALUE self ) {
2693
- PGconn *conn = pg_get_pgconn( self );
2694
- int sd = PQsocket( conn );
2695
- int ret;
2696
-
2697
- struct timeval timeout;
2698
- struct timeval *ptimeout = NULL;
2699
- fd_set sd_rset;
2700
- fd_set crt_sd_rset;
2701
2825
  VALUE timeout_in;
2702
2826
  double timeout_sec;
2703
-
2704
- /* Always set a timeout, as rb_thread_select() sometimes
2705
- * doesn't return when a second ruby thread is running although data
2706
- * could be read. So we use timeout-based polling instead.
2707
- */
2708
- timeout.tv_sec = 0;
2709
- timeout.tv_usec = 10000; /* 10ms */
2710
- ptimeout = &timeout;
2827
+ void *ret;
2711
2828
 
2712
2829
  if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2713
2830
  timeout_sec = NUM2DBL( timeout_in );
@@ -2716,33 +2833,14 @@ pgconn_block( int argc, VALUE *argv, VALUE self ) {
2716
2833
  ptimeout = &timeout;
2717
2834
  }
2718
2835
 
2719
- /* Check for connection errors (PQisBusy is true on connection errors) */
2720
- if( PQconsumeInput(conn) == 0 )
2721
- rb_raise( rb_ePGerror, PQerrorMessage(conn) );
2836
+ ret = wait_socket_readable( conn, ptimeout, get_result_readable);
2722
2837
 
2723
- while ( PQisBusy(conn) ) {
2724
- FD_ZERO( &sd_rset );
2725
- FD_SET( sd, &sd_rset );
2726
-
2727
- create_crt_fd( &sd_rset, &crt_sd_rset );
2728
- ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout );
2729
- cleanup_crt_fd( &sd_rset, &crt_sd_rset );
2730
-
2731
- /* Return false if there was a timeout argument and the select() timed out */
2732
- if ( ret == 0 && argc )
2733
- return Qfalse;
2734
-
2735
- /* Check for connection errors (PQisBusy is true on connection errors) */
2736
- if ( PQconsumeInput(conn) == 0 )
2737
- rb_raise( rb_ePGerror, PQerrorMessage(conn) );
2738
- }
2838
+ if( !ret )
2839
+ return Qfalse;
2739
2840
 
2740
2841
  return Qtrue;
2741
2842
  }
2742
2843
 
2743
- #endif /* Ruby 1.9 */
2744
- #endif /* Win32 */
2745
-
2746
2844
 
2747
2845
  /*
2748
2846
  * call-seq:
@@ -2767,7 +2865,7 @@ pgconn_get_last_result(VALUE self)
2767
2865
 
2768
2866
 
2769
2867
  cur = prev = NULL;
2770
- while ((cur = PQgetResult(conn)) != NULL) {
2868
+ while ((cur = gvl_PQgetResult(conn)) != NULL) {
2771
2869
  int status;
2772
2870
 
2773
2871
  if (prev) PQclear(prev);
@@ -2793,8 +2891,8 @@ pgconn_get_last_result(VALUE self)
2793
2891
  * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
2794
2892
  *
2795
2893
  * This function has the same behavior as #exec,
2796
- * except that it's implemented using asynchronous command
2797
- * processing and ruby's +rb_thread_select+ in order to
2894
+ * except that it's implemented using asynchronous command
2895
+ * processing and ruby's +rb_thread_select+ in order to
2798
2896
  * allow other threads to process while waiting for the
2799
2897
  * server to complete the request.
2800
2898
  */
@@ -2922,7 +3020,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
2922
3020
  * call-seq:
2923
3021
  * conn.lo_open( oid, [mode] ) -> Fixnum
2924
3022
  *
2925
- * Open a large object of _oid_. Returns a large object descriptor
3023
+ * Open a large object of _oid_. Returns a large object descriptor
2926
3024
  * instance on success. The _mode_ argument specifies the mode for
2927
3025
  * the opened large object,which is either +INV_READ+, or +INV_WRITE+.
2928
3026
  *
@@ -2968,7 +3066,7 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
2968
3066
  if( RSTRING_LEN(buffer) < 0) {
2969
3067
  rb_raise(rb_ePGerror, "write buffer zero string");
2970
3068
  }
2971
- if((n = lo_write(conn, fd, StringValuePtr(buffer),
3069
+ if((n = lo_write(conn, fd, StringValuePtr(buffer),
2972
3070
  RSTRING_LEN(buffer))) < 0) {
2973
3071
  rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
2974
3072
  }
@@ -3250,7 +3348,7 @@ init_pg_connection()
3250
3348
  {
3251
3349
  rb_cPGconn = rb_define_class_under( rb_mPG, "Connection", rb_cObject );
3252
3350
  rb_include_module(rb_cPGconn, rb_mPGconstants);
3253
-
3351
+
3254
3352
  /****** PG::Connection CLASS METHODS ******/
3255
3353
  rb_define_alloc_func( rb_cPGconn, pgconn_s_allocate );
3256
3354
 
@@ -3304,6 +3402,7 @@ init_pg_connection()
3304
3402
  /****** PG::Connection INSTANCE METHODS: Command Execution ******/
3305
3403
  rb_define_method(rb_cPGconn, "exec", pgconn_exec, -1);
3306
3404
  rb_define_alias(rb_cPGconn, "query", "exec");
3405
+ rb_define_method(rb_cPGconn, "exec_params", pgconn_exec_params, -1);
3307
3406
  rb_define_method(rb_cPGconn, "prepare", pgconn_prepare, -1);
3308
3407
  rb_define_method(rb_cPGconn, "exec_prepared", pgconn_exec_prepared, -1);
3309
3408
  rb_define_method(rb_cPGconn, "describe_prepared", pgconn_describe_prepared, 1);
@@ -3319,6 +3418,9 @@ init_pg_connection()
3319
3418
  #endif
3320
3419
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
3321
3420
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
3421
+ #ifdef HAVE_PQSETSINGLEROWMODE
3422
+ rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
3423
+ #endif
3322
3424
 
3323
3425
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
3324
3426
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
@@ -3404,4 +3506,3 @@ init_pg_connection()
3404
3506
 
3405
3507
  }
3406
3508
 
3407
-