pg 1.3.0.rc1-x86-mingw32 → 1.3.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/pg_connection.c CHANGED
@@ -249,68 +249,13 @@ pgconn_s_allocate( VALUE klass )
249
249
  return self;
250
250
  }
251
251
 
252
-
253
- /*
254
- * Document-method: new
255
- *
256
- * call-seq:
257
- * PG::Connection.new -> conn
258
- * PG::Connection.new(connection_hash) -> conn
259
- * PG::Connection.new(connection_string) -> conn
260
- * PG::Connection.new(host, port, options, tty, dbname, user, password) -> conn
261
- *
262
- * Create a connection to the specified server.
263
- *
264
- * +connection_hash+ must be a ruby Hash with connection parameters.
265
- * See the {list of valid parameters}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS] in the PostgreSQL documentation.
266
- *
267
- * There are two accepted formats for +connection_string+: plain <code>keyword = value</code> strings and URIs.
268
- * See the documentation of {connection strings}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING].
269
- *
270
- * The positional parameter form has the same functionality except that the missing parameters will always take on default values. The parameters are:
271
- * [+host+]
272
- * server hostname
273
- * [+port+]
274
- * server port number
275
- * [+options+]
276
- * backend options
277
- * [+tty+]
278
- * (ignored in all versions of PostgreSQL)
279
- * [+dbname+]
280
- * connecting database name
281
- * [+user+]
282
- * login user name
283
- * [+password+]
284
- * login password
285
- *
286
- * Examples:
287
- *
288
- * # Connect using all defaults
289
- * PG::Connection.new
290
- *
291
- * # As a Hash
292
- * PG::Connection.new( dbname: 'test', port: 5432 )
293
- *
294
- * # As a String
295
- * PG::Connection.new( "dbname=test port=5432" )
296
- *
297
- * # As an Array
298
- * PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
299
- *
300
- * # As an URI
301
- * PG::Connection.new( "postgresql://user:pass@pgsql.example.com:5432/testdb?sslmode=require" )
302
- *
303
- * If the Ruby default internal encoding is set (i.e., <code>Encoding.default_internal != nil</code>), the
304
- * connection will have its +client_encoding+ set accordingly.
305
- *
306
- * Raises a PG::Error if the connection fails.
307
- */
308
252
  static VALUE
309
- pgconn_init(int argc, VALUE *argv, VALUE self)
253
+ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
310
254
  {
311
255
  t_pg_connection *this;
312
256
  VALUE conninfo;
313
257
  VALUE error;
258
+ VALUE self = pgconn_s_allocate( klass );
314
259
 
315
260
  this = pg_get_connection( self );
316
261
  conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
@@ -383,28 +328,8 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
383
328
  return rb_conn;
384
329
  }
385
330
 
386
- /*
387
- * call-seq:
388
- * PG::Connection.ping(connection_hash) -> Integer
389
- * PG::Connection.ping(connection_string) -> Integer
390
- * PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
391
- *
392
- * Check server status.
393
- *
394
- * See PG::Connection.new for a description of the parameters.
395
- *
396
- * Returns one of:
397
- * [+PQPING_OK+]
398
- * server is accepting connections
399
- * [+PQPING_REJECT+]
400
- * server is alive but rejecting connections
401
- * [+PQPING_NO_RESPONSE+]
402
- * could not establish connection
403
- * [+PQPING_NO_ATTEMPT+]
404
- * connection not attempted (bad params)
405
- */
406
331
  static VALUE
407
- pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
332
+ pgconn_s_sync_ping( int argc, VALUE *argv, VALUE klass )
408
333
  {
409
334
  PGPing ping;
410
335
  VALUE conninfo;
@@ -453,30 +378,8 @@ pgconn_s_conndefaults(VALUE self)
453
378
 
454
379
 
455
380
  #ifdef HAVE_PQENCRYPTPASSWORDCONN
456
- /*
457
- * call-seq:
458
- * conn.encrypt_password( password, username, algorithm=nil ) -> String
459
- *
460
- * This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
461
- * 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.
462
- * Instead, use this function to convert the password to encrypted form before it is sent.
463
- *
464
- * The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
465
- * +algorithm+ specifies the encryption algorithm to use to encrypt the password.
466
- * 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).
467
- * Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
468
- * If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
469
- * That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
470
- * 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.
471
- *
472
- * Return value is the encrypted password.
473
- * The caller can assume the string doesn't contain any special characters that would require escaping.
474
- *
475
- * Available since PostgreSQL-10.
476
- * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
477
- */
478
381
  static VALUE
479
- pgconn_encrypt_password(int argc, VALUE *argv, VALUE self)
382
+ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
480
383
  {
481
384
  char *encrypted = NULL;
482
385
  VALUE rval = Qnil;
@@ -571,6 +474,11 @@ pgconn_connect_poll(VALUE self)
571
474
  {
572
475
  PostgresPollingStatusType status;
573
476
  status = gvl_PQconnectPoll(pg_get_pgconn(self));
477
+
478
+ if ( status == PGRES_POLLING_FAILED ) {
479
+ pgconn_close_socket_io(self);
480
+ }
481
+
574
482
  return INT2FIX((int)status);
575
483
  }
576
484
 
@@ -607,15 +515,8 @@ pgconn_finished_p( VALUE self )
607
515
  }
608
516
 
609
517
 
610
- /*
611
- * call-seq:
612
- * conn.reset()
613
- *
614
- * Resets the backend connection. This method closes the
615
- * backend connection and tries to re-connect.
616
- */
617
518
  static VALUE
618
- pgconn_reset( VALUE self )
519
+ pgconn_sync_reset( VALUE self )
619
520
  {
620
521
  pgconn_close_socket_io( self );
621
522
  gvl_PQreset( pg_get_pgconn(self) );
@@ -654,6 +555,11 @@ pgconn_reset_poll(VALUE self)
654
555
  {
655
556
  PostgresPollingStatusType status;
656
557
  status = gvl_PQresetPoll(pg_get_pgconn(self));
558
+
559
+ if ( status == PGRES_POLLING_FAILED ) {
560
+ pgconn_close_socket_io(self);
561
+ }
562
+
657
563
  return INT2FIX((int)status);
658
564
  }
659
565
 
@@ -779,7 +685,11 @@ pgconn_conninfo( VALUE self )
779
685
  * call-seq:
780
686
  * conn.status()
781
687
  *
782
- * Returns status of connection : CONNECTION_OK or CONNECTION_BAD
688
+ * Returns the status of the connection, which is one:
689
+ * PG::Constants::CONNECTION_OK
690
+ * PG::Constants::CONNECTION_BAD
691
+ *
692
+ * ... and other constants of kind PG::Constants::CONNECTION_*
783
693
  */
784
694
  static VALUE
785
695
  pgconn_status(VALUE self)
@@ -1044,7 +954,7 @@ pgconn_connection_used_password(VALUE self)
1044
954
  /* :TODO: get_ssl */
1045
955
 
1046
956
 
1047
- static VALUE pgconn_exec_params( int, VALUE *, VALUE );
957
+ static VALUE pgconn_sync_exec_params( int, VALUE *, VALUE );
1048
958
 
1049
959
  /*
1050
960
  * call-seq:
@@ -1058,11 +968,11 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
1058
968
  * However #async_exec has two advantages:
1059
969
  *
1060
970
  * 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
1061
- * 2. Ruby VM gets notified about IO blocked operations.
1062
- * It can therefore schedule things like garbage collection, while queries are running like in this proposal: https://bugs.ruby-lang.org/issues/14723
971
+ * 2. Ruby VM gets notified about IO blocked operations and can pass them through <tt>Fiber.scheduler</tt>.
972
+ * So only <tt>async_*</tt> methods are compatible to event based schedulers like the async gem.
1063
973
  */
1064
974
  static VALUE
1065
- pgconn_exec(int argc, VALUE *argv, VALUE self)
975
+ pgconn_sync_exec(int argc, VALUE *argv, VALUE self)
1066
976
  {
1067
977
  t_pg_connection *this = pg_get_connection_safe( self );
1068
978
  PGresult *result = NULL;
@@ -1083,7 +993,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
1083
993
  pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));
1084
994
 
1085
995
  /* Otherwise, just call #exec_params instead for backward-compatibility */
1086
- return pgconn_exec_params( argc, argv, self );
996
+ return pgconn_sync_exec_params( argc, argv, self );
1087
997
 
1088
998
  }
1089
999
 
@@ -1365,7 +1275,7 @@ pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
1365
1275
  * It's not recommended to use explicit sync or async variants but #exec_params instead, unless you have a good reason to do so.
1366
1276
  */
1367
1277
  static VALUE
1368
- pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1278
+ pgconn_sync_exec_params( int argc, VALUE *argv, VALUE self )
1369
1279
  {
1370
1280
  t_pg_connection *this = pg_get_connection_safe( self );
1371
1281
  PGresult *result = NULL;
@@ -1385,7 +1295,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1385
1295
  */
1386
1296
  if ( NIL_P(paramsData.params) ) {
1387
1297
  pg_deprecated(1, ("forwarding exec_params to exec is deprecated"));
1388
- return pgconn_exec( 1, argv, self );
1298
+ return pgconn_sync_exec( 1, argv, self );
1389
1299
  }
1390
1300
  pgconn_query_assign_typemap( self, &paramsData );
1391
1301
 
@@ -1416,7 +1326,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1416
1326
  * It's not recommended to use explicit sync or async variants but #prepare instead, unless you have a good reason to do so.
1417
1327
  */
1418
1328
  static VALUE
1419
- pgconn_prepare(int argc, VALUE *argv, VALUE self)
1329
+ pgconn_sync_prepare(int argc, VALUE *argv, VALUE self)
1420
1330
  {
1421
1331
  t_pg_connection *this = pg_get_connection_safe( self );
1422
1332
  PGresult *result = NULL;
@@ -1465,7 +1375,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1465
1375
  * It's not recommended to use explicit sync or async variants but #exec_prepared instead, unless you have a good reason to do so.
1466
1376
  */
1467
1377
  static VALUE
1468
- pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1378
+ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
1469
1379
  {
1470
1380
  t_pg_connection *this = pg_get_connection_safe( self );
1471
1381
  PGresult *result = NULL;
@@ -1510,7 +1420,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1510
1420
  * It's not recommended to use explicit sync or async variants but #describe_prepared instead, unless you have a good reason to do so.
1511
1421
  */
1512
1422
  static VALUE
1513
- pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1423
+ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1514
1424
  {
1515
1425
  PGresult *result;
1516
1426
  VALUE rb_pgresult;
@@ -1538,7 +1448,7 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1538
1448
  * It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
1539
1449
  */
1540
1450
  static VALUE
1541
- pgconn_describe_portal(self, stmt_name)
1451
+ pgconn_sync_describe_portal(self, stmt_name)
1542
1452
  VALUE self, stmt_name;
1543
1453
  {
1544
1454
  PGresult *result;
@@ -2133,24 +2043,8 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
2133
2043
  }
2134
2044
 
2135
2045
 
2136
- /*
2137
- * call-seq:
2138
- * conn.get_result() -> PG::Result
2139
- * conn.get_result() {|pg_result| block }
2140
- *
2141
- * Blocks waiting for the next result from a call to
2142
- * #send_query (or another asynchronous command), and returns
2143
- * it. Returns +nil+ if no more results are available.
2144
- *
2145
- * Note: call this function repeatedly until it returns +nil+, or else
2146
- * you will not be able to issue further commands.
2147
- *
2148
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
2149
- * and the PG::Result object will automatically be cleared when the block terminates.
2150
- * In this instance, <code>conn.exec</code> returns the value of the block.
2151
- */
2152
2046
  static VALUE
2153
- pgconn_get_result(VALUE self)
2047
+ pgconn_sync_get_result(VALUE self)
2154
2048
  {
2155
2049
  PGconn *conn = pg_get_pgconn(self);
2156
2050
  PGresult *result;
@@ -2183,6 +2077,7 @@ pgconn_consume_input(self)
2183
2077
  PGconn *conn = pg_get_pgconn(self);
2184
2078
  /* returns 0 on error */
2185
2079
  if(PQconsumeInput(conn) == 0) {
2080
+ pgconn_close_socket_io(self);
2186
2081
  error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(conn));
2187
2082
  rb_iv_set(error, "@connection", self);
2188
2083
  rb_exc_raise(error);
@@ -2195,7 +2090,7 @@ pgconn_consume_input(self)
2195
2090
  * conn.is_busy() -> Boolean
2196
2091
  *
2197
2092
  * Returns +true+ if a command is busy, that is, if
2198
- * PQgetResult would block. Otherwise returns +false+.
2093
+ * #get_result would block. Otherwise returns +false+.
2199
2094
  */
2200
2095
  static VALUE
2201
2096
  pgconn_is_busy(self)
@@ -2204,24 +2099,8 @@ pgconn_is_busy(self)
2204
2099
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2205
2100
  }
2206
2101
 
2207
- /*
2208
- * call-seq:
2209
- * conn.setnonblocking(Boolean) -> nil
2210
- *
2211
- * Sets the nonblocking status of the connection.
2212
- * In the blocking state, calls to #send_query
2213
- * will block until the message is sent to the server,
2214
- * but will not wait for the query results.
2215
- * In the nonblocking state, calls to #send_query
2216
- * will return an error if the socket is not ready for
2217
- * writing.
2218
- * Note: This function does not affect #exec, because
2219
- * that function doesn't return until the server has
2220
- * processed the query and returned the results.
2221
- * Returns +nil+.
2222
- */
2223
2102
  static VALUE
2224
- pgconn_setnonblocking(self, state)
2103
+ pgconn_sync_setnonblocking(self, state)
2225
2104
  VALUE self, state;
2226
2105
  {
2227
2106
  int arg;
@@ -2243,30 +2122,13 @@ pgconn_setnonblocking(self, state)
2243
2122
  }
2244
2123
 
2245
2124
 
2246
- /*
2247
- * call-seq:
2248
- * conn.isnonblocking() -> Boolean
2249
- *
2250
- * Returns +true+ if a command is busy, that is, if
2251
- * PQgetResult would block. Otherwise returns +false+.
2252
- */
2253
2125
  static VALUE
2254
- pgconn_isnonblocking(self)
2126
+ pgconn_sync_isnonblocking(self)
2255
2127
  VALUE self;
2256
2128
  {
2257
2129
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2258
2130
  }
2259
2131
 
2260
- /*
2261
- * call-seq:
2262
- * conn.flush() -> Boolean
2263
- *
2264
- * Attempts to flush any queued output data to the server.
2265
- * Returns +true+ if data is successfully flushed, +false+
2266
- * if not (can only return +false+ if connection is
2267
- * nonblocking.
2268
- * Raises PG::Error if some other failure occurred.
2269
- */
2270
2132
  static VALUE
2271
2133
  pgconn_sync_flush(VALUE self)
2272
2134
  {
@@ -2282,18 +2144,8 @@ pgconn_sync_flush(VALUE self)
2282
2144
  return (ret) ? Qfalse : Qtrue;
2283
2145
  }
2284
2146
 
2285
- /*
2286
- * call-seq:
2287
- * conn.cancel() -> String
2288
- *
2289
- * Requests cancellation of the command currently being
2290
- * processed.
2291
- *
2292
- * Returns +nil+ on success, or a string containing the
2293
- * error message if a failure occurs.
2294
- */
2295
2147
  static VALUE
2296
- pgconn_cancel(VALUE self)
2148
+ pgconn_sync_cancel(VALUE self)
2297
2149
  {
2298
2150
  char errbuf[256];
2299
2151
  PGcancel *cancel;
@@ -2355,18 +2207,128 @@ pgconn_notifies(VALUE self)
2355
2207
  return hash;
2356
2208
  }
2357
2209
 
2210
+ #if defined(_WIN32)
2211
+
2212
+ /* We use a specialized implementation of rb_io_wait() on Windows.
2213
+ * This is because rb_io_wait() and rb_wait_for_single_fd() are very slow on Windows.
2214
+ */
2215
+
2216
+ #if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
2217
+ #include <ruby/fiber/scheduler.h>
2218
+ #endif
2219
+
2220
+ typedef enum {
2221
+ PG_RUBY_IO_READABLE = RB_WAITFD_IN,
2222
+ PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
2223
+ PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
2224
+ } pg_rb_io_event_t;
2225
+
2226
+ int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2227
+
2228
+ static VALUE
2229
+ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
2230
+ rb_io_t *fptr;
2231
+ struct timeval ptimeout;
2232
+
2233
+ struct timeval aborttime={0,0}, currtime, waittime;
2234
+ DWORD timeout_milisec = INFINITE;
2235
+ HANDLE hEvent = WSACreateEvent();
2236
+
2237
+ long rb_events = NUM2UINT(events);
2238
+ long w32_events = 0;
2239
+ DWORD wait_ret;
2240
+
2241
+ GetOpenFile((io), fptr);
2242
+ if( !NIL_P(timeout) ){
2243
+ ptimeout.tv_sec = (time_t)(NUM2DBL(timeout));
2244
+ ptimeout.tv_usec = (time_t)(NUM2DBL(timeout) - (double)ptimeout.tv_sec);
2245
+
2246
+ gettimeofday(&currtime, NULL);
2247
+ timeradd(&currtime, &ptimeout, &aborttime);
2248
+ }
2249
+
2250
+ if(rb_events & PG_RUBY_IO_READABLE) {
2251
+ w32_events |= FD_READ | FD_ACCEPT | FD_CLOSE;
2252
+ } else if(rb_events & PG_RUBY_IO_WRITABLE) {
2253
+ w32_events |= FD_WRITE | FD_CONNECT;
2254
+ } else if(rb_events & PG_RUBY_IO_PRIORITY) {
2255
+ w32_events |= FD_OOB;
2256
+ }
2257
+
2258
+ for(;;) {
2259
+ if ( WSAEventSelect(_get_osfhandle(fptr->fd), hEvent, w32_events) == SOCKET_ERROR ) {
2260
+ WSACloseEvent( hEvent );
2261
+ rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
2262
+ }
2263
+
2264
+ if ( !NIL_P(timeout) ) {
2265
+ gettimeofday(&currtime, NULL);
2266
+ timersub(&aborttime, &currtime, &waittime);
2267
+ timeout_milisec = (DWORD)( waittime.tv_sec * 1e3 + waittime.tv_usec / 1e3 );
2268
+ }
2269
+
2270
+ if( NIL_P(timeout) || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2271
+ /* Wait for the socket to become readable before checking again */
2272
+ wait_ret = rb_w32_wait_events( &hEvent, 1, timeout_milisec );
2273
+ } else {
2274
+ wait_ret = WAIT_TIMEOUT;
2275
+ }
2276
+
2277
+ if ( wait_ret == WAIT_TIMEOUT ) {
2278
+ WSACloseEvent( hEvent );
2279
+ return UINT2NUM(0);
2280
+ } else if ( wait_ret == WAIT_OBJECT_0 ) {
2281
+ WSACloseEvent( hEvent );
2282
+ /* The event we were waiting for. */
2283
+ return UINT2NUM(rb_events);
2284
+ } else if ( wait_ret == WAIT_OBJECT_0 + 1) {
2285
+ /* This indicates interruption from timer thread, GC, exception
2286
+ * from other threads etc... */
2287
+ rb_thread_check_ints();
2288
+ } else if ( wait_ret == WAIT_FAILED ) {
2289
+ WSACloseEvent( hEvent );
2290
+ rb_raise( rb_eConnectionBad, "Wait on socket error (WaitForMultipleObjects): %lu", GetLastError() );
2291
+ } else {
2292
+ WSACloseEvent( hEvent );
2293
+ rb_raise( rb_eConnectionBad, "Wait on socket abandoned (WaitForMultipleObjects)" );
2294
+ }
2295
+ }
2296
+ }
2297
+
2298
+ static VALUE
2299
+ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2300
+ #if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
2301
+ /* We don't support Fiber.scheduler on Windows ruby-3.0 because there is no fast way to check whether a scheduler is active.
2302
+ * Fortunatelly ruby-3.1 offers a C-API for it.
2303
+ */
2304
+ VALUE scheduler = rb_fiber_scheduler_current();
2305
+
2306
+ if (!NIL_P(scheduler)) {
2307
+ return rb_io_wait(io, events, timeout);
2308
+ }
2309
+ #endif
2310
+ return pg_rb_thread_io_wait(io, events, timeout);
2311
+ }
2312
+
2313
+ #elif defined(HAVE_RB_IO_WAIT)
2358
2314
 
2359
- #if !defined(HAVE_RB_IO_WAIT)
2315
+ /* Use our own function and constants names, to avoid conflicts with truffleruby-head on its road to ruby-3.0 compatibility. */
2316
+ #define pg_rb_io_wait rb_io_wait
2317
+ #define PG_RUBY_IO_READABLE RUBY_IO_READABLE
2318
+ #define PG_RUBY_IO_WRITABLE RUBY_IO_WRITABLE
2319
+ #define PG_RUBY_IO_PRIORITY RUBY_IO_PRIORITY
2320
+
2321
+ #else
2360
2322
  /* For compat with ruby < 3.0 */
2361
2323
 
2362
2324
  typedef enum {
2363
- RUBY_IO_READABLE = RB_WAITFD_IN,
2364
- RUBY_IO_WRITABLE = RB_WAITFD_OUT,
2365
- RUBY_IO_PRIORITY = RB_WAITFD_PRI,
2366
- } rb_io_event_t;
2325
+ PG_RUBY_IO_READABLE = RB_WAITFD_IN,
2326
+ PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
2327
+ PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
2328
+ } pg_rb_io_event_t;
2367
2329
 
2368
2330
  static VALUE
2369
- rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2331
+ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2370
2332
  rb_io_t *fptr;
2371
2333
  struct timeval waittime;
2372
2334
  int res;
@@ -2395,8 +2357,10 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2395
2357
  socket_io = pgconn_socket_io(self);
2396
2358
 
2397
2359
  /* Check for connection errors (PQisBusy is true on connection errors) */
2398
- if ( PQconsumeInput(conn) == 0 )
2360
+ if ( PQconsumeInput(conn) == 0 ) {
2361
+ pgconn_close_socket_io(self);
2399
2362
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2363
+ }
2400
2364
 
2401
2365
  if ( ptimeout ) {
2402
2366
  gettimeofday(&currtime, NULL);
@@ -2413,7 +2377,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2413
2377
  /* Is the given timeout valid? */
2414
2378
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2415
2379
  /* Wait for the socket to become readable before checking again */
2416
- ret = rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), wait_timeout);
2380
+ ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2417
2381
  } else {
2418
2382
  ret = Qfalse;
2419
2383
  }
@@ -2425,6 +2389,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2425
2389
 
2426
2390
  /* Check for connection errors (PQisBusy is true on connection errors) */
2427
2391
  if ( PQconsumeInput(conn) == 0 ){
2392
+ pgconn_close_socket_io(self);
2428
2393
  rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2429
2394
  }
2430
2395
  }
@@ -2432,6 +2397,16 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2432
2397
  return retval;
2433
2398
  }
2434
2399
 
2400
+ /*
2401
+ * call-seq:
2402
+ * conn.flush() -> Boolean
2403
+ *
2404
+ * Attempts to flush any queued output data to the server.
2405
+ * Returns +true+ if data is successfully flushed, +false+
2406
+ * if not (can only return +false+ if connection is
2407
+ * nonblocking.
2408
+ * Raises PG::Error if some other failure occurred.
2409
+ */
2435
2410
  static VALUE
2436
2411
  pgconn_async_flush(VALUE self)
2437
2412
  {
@@ -2439,9 +2414,9 @@ pgconn_async_flush(VALUE self)
2439
2414
  /* wait for the socket to become read- or write-ready */
2440
2415
  int events;
2441
2416
  VALUE socket_io = pgconn_socket_io(self);
2442
- events = RB_NUM2INT(rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE | RUBY_IO_WRITABLE), Qnil));
2417
+ events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE | PG_RUBY_IO_WRITABLE), Qnil));
2443
2418
 
2444
- if (events & RUBY_IO_READABLE)
2419
+ if (events & PG_RUBY_IO_READABLE)
2445
2420
  pgconn_consume_input(self);
2446
2421
  }
2447
2422
  return Qtrue;
@@ -2520,28 +2495,8 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2520
2495
  }
2521
2496
 
2522
2497
 
2523
- /*
2524
- * call-seq:
2525
- * conn.put_copy_data( buffer [, encoder] ) -> Boolean
2526
- *
2527
- * Transmits _buffer_ as copy data to the server.
2528
- * Returns true if the data was sent, false if it was
2529
- * not sent (false is only possible if the connection
2530
- * is in nonblocking mode, and this command would block).
2531
- *
2532
- * _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
2533
- * This encodes the data fields given as _buffer_ from an Array of Strings to
2534
- * PostgreSQL's COPY text format inclusive proper escaping. Optionally
2535
- * the encoder can type cast the fields from various Ruby types in one step,
2536
- * if PG::TextEncoder::CopyRow#type_map is set accordingly.
2537
- *
2538
- * Raises an exception if an error occurs.
2539
- *
2540
- * See also #copy_data.
2541
- *
2542
- */
2543
2498
  static VALUE
2544
- pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2499
+ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2545
2500
  {
2546
2501
  int ret;
2547
2502
  int len;
@@ -2596,22 +2551,8 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2596
2551
  return (ret) ? Qtrue : Qfalse;
2597
2552
  }
2598
2553
 
2599
- /*
2600
- * call-seq:
2601
- * conn.put_copy_end( [ error_message ] ) -> Boolean
2602
- *
2603
- * Sends end-of-data indication to the server.
2604
- *
2605
- * _error_message_ is an optional parameter, and if set,
2606
- * forces the COPY command to fail with the string
2607
- * _error_message_.
2608
- *
2609
- * Returns true if the end-of-data was sent, *false* if it was
2610
- * not sent (*false* is only possible if the connection
2611
- * is in nonblocking mode, and this command would block).
2612
- */
2613
2554
  static VALUE
2614
- pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2555
+ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2615
2556
  {
2616
2557
  VALUE str;
2617
2558
  VALUE error;
@@ -2633,27 +2574,8 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2633
2574
  return (ret) ? Qtrue : Qfalse;
2634
2575
  }
2635
2576
 
2636
- /*
2637
- * call-seq:
2638
- * conn.get_copy_data( [ nonblock = false [, decoder = nil ]] ) -> Object
2639
- *
2640
- * Return one row of data, +nil+
2641
- * if the copy is done, or +false+ if the call would
2642
- * block (only possible if _nonblock_ is true).
2643
- *
2644
- * If _decoder_ is not set or +nil+, data is returned as binary string.
2645
- *
2646
- * If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
2647
- * PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
2648
- * COPY text format to an Array of Strings.
2649
- * Optionally the decoder can type cast the single fields to various Ruby types in one step,
2650
- * if PG::TextDecoder::CopyRow#type_map is set accordingly.
2651
- *
2652
- * See also #copy_data.
2653
- *
2654
- */
2655
2577
  static VALUE
2656
- pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2578
+ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2657
2579
  {
2658
2580
  VALUE async_in;
2659
2581
  VALUE error;
@@ -2978,7 +2900,7 @@ pgconn_get_client_encoding(VALUE self)
2978
2900
  * It's not recommended to use explicit sync or async variants but #set_client_encoding instead, unless you have a good reason to do so.
2979
2901
  */
2980
2902
  static VALUE
2981
- pgconn_set_client_encoding(VALUE self, VALUE str)
2903
+ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2982
2904
  {
2983
2905
  PGconn *conn = pg_get_pgconn( self );
2984
2906
 
@@ -3099,7 +3021,7 @@ pgconn_block( int argc, VALUE *argv, VALUE self ) {
3099
3021
  * It's not recommended to use explicit sync or async variants but #get_last_result instead, unless you have a good reason to do so.
3100
3022
  */
3101
3023
  static VALUE
3102
- pgconn_get_last_result(VALUE self)
3024
+ pgconn_sync_get_last_result(VALUE self)
3103
3025
  {
3104
3026
  PGconn *conn = pg_get_pgconn(self);
3105
3027
  VALUE rb_pgresult = Qnil;
@@ -3201,12 +3123,14 @@ pgconn_discard_results(VALUE self)
3201
3123
  int status;
3202
3124
 
3203
3125
  /* pgconn_block() raises an exception in case of errors.
3204
- * To avoid this call rb_io_wait() and PQconsumeInput() without rb_raise().
3126
+ * To avoid this call pg_rb_io_wait() and PQconsumeInput() without rb_raise().
3205
3127
  */
3206
3128
  while( gvl_PQisBusy(conn) ){
3207
- rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
3208
- if ( PQconsumeInput(conn) == 0 )
3129
+ pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
3130
+ if ( PQconsumeInput(conn) == 0 ) {
3131
+ pgconn_close_socket_io(self);
3209
3132
  return Qfalse;
3133
+ }
3210
3134
  }
3211
3135
 
3212
3136
  cur = gvl_PQgetResult(conn);
@@ -3223,9 +3147,11 @@ pgconn_discard_results(VALUE self)
3223
3147
  int st = gvl_PQgetCopyData(conn, &buffer, 1);
3224
3148
  if( st == 0 ) {
3225
3149
  /* would block -> wait for readable data */
3226
- rb_io_wait(socket_io, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
3227
- if ( PQconsumeInput(conn) == 0 )
3150
+ pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
3151
+ if ( PQconsumeInput(conn) == 0 ) {
3152
+ pgconn_close_socket_io(self);
3228
3153
  return Qfalse;
3154
+ }
3229
3155
  } else if( st > 0 ) {
3230
3156
  /* some data retrieved -> discard it */
3231
3157
  PQfreemem(buffer);
@@ -3260,6 +3186,7 @@ pgconn_discard_results(VALUE self)
3260
3186
  * #exec is an alias for #async_exec which is almost identical to #sync_exec .
3261
3187
  * #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
3262
3188
  * #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
3189
+ * Only #async_exec is compatible to <tt>Fiber.scheduler</tt> based asynchronous IO processing introduced in ruby-3.0.
3263
3190
  * Both methods ensure that other threads can process while waiting for the server to
3264
3191
  * complete the request, but #sync_exec blocks all signals to be processed until the query is finished.
3265
3192
  * This is most notably visible by a delayed reaction to Control+C.
@@ -4037,11 +3964,11 @@ static VALUE
4037
3964
  pgconn_internal_encoding_set(VALUE self, VALUE enc)
4038
3965
  {
4039
3966
  if (NIL_P(enc)) {
4040
- pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
3967
+ pgconn_sync_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") );
4041
3968
  return enc;
4042
3969
  }
4043
3970
  else if ( TYPE(enc) == T_STRING && strcasecmp("JOHAB", StringValueCStr(enc)) == 0 ) {
4044
- pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
3971
+ pgconn_sync_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
4045
3972
  return enc;
4046
3973
  }
4047
3974
  else {
@@ -4405,10 +4332,6 @@ init_pg_connection()
4405
4332
  /****** PG::Connection CLASS METHODS ******/
4406
4333
  rb_define_alloc_func( rb_cPGconn, pgconn_s_allocate );
4407
4334
 
4408
- SINGLETON_ALIAS(rb_cPGconn, "connect", "new");
4409
- SINGLETON_ALIAS(rb_cPGconn, "open", "new");
4410
- SINGLETON_ALIAS(rb_cPGconn, "setdb", "new");
4411
- SINGLETON_ALIAS(rb_cPGconn, "setdblogin", "new");
4412
4335
  rb_define_singleton_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
4413
4336
  SINGLETON_ALIAS(rb_cPGconn, "escape", "escape_string");
4414
4337
  rb_define_singleton_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
@@ -4417,14 +4340,14 @@ init_pg_connection()
4417
4340
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4418
4341
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4419
4342
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4420
- rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
4343
+ rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4344
+ rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4421
4345
 
4422
4346
  /****** PG::Connection INSTANCE METHODS: Connection Control ******/
4423
- rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
4424
4347
  rb_define_method(rb_cPGconn, "connect_poll", pgconn_connect_poll, 0);
4425
4348
  rb_define_method(rb_cPGconn, "finish", pgconn_finish, 0);
4426
4349
  rb_define_method(rb_cPGconn, "finished?", pgconn_finished_p, 0);
4427
- rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0);
4350
+ rb_define_method(rb_cPGconn, "sync_reset", pgconn_sync_reset, 0);
4428
4351
  rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0);
4429
4352
  rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0);
4430
4353
  rb_define_alias(rb_cPGconn, "close", "finish");
@@ -4453,12 +4376,12 @@ init_pg_connection()
4453
4376
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
4454
4377
 
4455
4378
  /****** PG::Connection INSTANCE METHODS: Command Execution ******/
4456
- rb_define_method(rb_cPGconn, "sync_exec", pgconn_exec, -1);
4457
- rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_exec_params, -1);
4458
- rb_define_method(rb_cPGconn, "sync_prepare", pgconn_prepare, -1);
4459
- rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_exec_prepared, -1);
4460
- rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_describe_prepared, 1);
4461
- rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_describe_portal, 1);
4379
+ rb_define_method(rb_cPGconn, "sync_exec", pgconn_sync_exec, -1);
4380
+ rb_define_method(rb_cPGconn, "sync_exec_params", pgconn_sync_exec_params, -1);
4381
+ rb_define_method(rb_cPGconn, "sync_prepare", pgconn_sync_prepare, -1);
4382
+ rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_sync_exec_prepared, -1);
4383
+ rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_sync_describe_prepared, 1);
4384
+ rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_sync_describe_portal, 1);
4462
4385
 
4463
4386
  rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
4464
4387
  rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
@@ -4491,26 +4414,26 @@ init_pg_connection()
4491
4414
  rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4492
4415
  rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
4493
4416
  rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
4494
- rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
4417
+ rb_define_method(rb_cPGconn, "sync_get_result", pgconn_sync_get_result, 0);
4495
4418
  rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
4496
4419
  rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
4497
- rb_define_method(rb_cPGconn, "setnonblocking", pgconn_setnonblocking, 1);
4498
- rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
4499
- rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
4420
+ rb_define_method(rb_cPGconn, "sync_setnonblocking", pgconn_sync_setnonblocking, 1);
4421
+ rb_define_method(rb_cPGconn, "sync_isnonblocking", pgconn_sync_isnonblocking, 0);
4500
4422
  rb_define_method(rb_cPGconn, "sync_flush", pgconn_sync_flush, 0);
4501
- rb_define_method(rb_cPGconn, "async_flush", pgconn_async_flush, 0);
4423
+ rb_define_method(rb_cPGconn, "flush", pgconn_async_flush, 0);
4424
+ rb_define_alias(rb_cPGconn, "async_flush", "flush");
4502
4425
  rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
4503
4426
 
4504
4427
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
4505
- rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
4428
+ rb_define_method(rb_cPGconn, "sync_cancel", pgconn_sync_cancel, 0);
4506
4429
 
4507
4430
  /****** PG::Connection INSTANCE METHODS: NOTIFY ******/
4508
4431
  rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
4509
4432
 
4510
4433
  /****** PG::Connection INSTANCE METHODS: COPY ******/
4511
- rb_define_method(rb_cPGconn, "put_copy_data", pgconn_put_copy_data, -1);
4512
- rb_define_method(rb_cPGconn, "put_copy_end", pgconn_put_copy_end, -1);
4513
- rb_define_method(rb_cPGconn, "get_copy_data", pgconn_get_copy_data, -1);
4434
+ rb_define_method(rb_cPGconn, "sync_put_copy_data", pgconn_sync_put_copy_data, -1);
4435
+ rb_define_method(rb_cPGconn, "sync_put_copy_end", pgconn_sync_put_copy_end, -1);
4436
+ rb_define_method(rb_cPGconn, "sync_get_copy_data", pgconn_sync_get_copy_data, -1);
4514
4437
 
4515
4438
  /****** PG::Connection INSTANCE METHODS: Control Functions ******/
4516
4439
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
@@ -4526,18 +4449,20 @@ init_pg_connection()
4526
4449
 
4527
4450
  /****** PG::Connection INSTANCE METHODS: Other ******/
4528
4451
  rb_define_method(rb_cPGconn, "get_client_encoding", pgconn_get_client_encoding, 0);
4529
- rb_define_method(rb_cPGconn, "sync_set_client_encoding", pgconn_set_client_encoding, 1);
4530
- rb_define_method(rb_cPGconn, "async_set_client_encoding", pgconn_async_set_client_encoding, 1);
4531
- rb_define_alias(rb_cPGconn, "async_client_encoding=", "async_set_client_encoding");
4452
+ rb_define_method(rb_cPGconn, "sync_set_client_encoding", pgconn_sync_set_client_encoding, 1);
4453
+ rb_define_method(rb_cPGconn, "set_client_encoding", pgconn_async_set_client_encoding, 1);
4454
+ rb_define_alias(rb_cPGconn, "async_set_client_encoding", "set_client_encoding");
4455
+ rb_define_alias(rb_cPGconn, "client_encoding=", "set_client_encoding");
4532
4456
  rb_define_method(rb_cPGconn, "block", pgconn_block, -1);
4533
4457
  rb_define_private_method(rb_cPGconn, "flush_data=", pgconn_flush_data_set, 1);
4534
4458
  rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
4535
4459
  rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
4536
4460
  rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4537
- rb_define_method(rb_cPGconn, "sync_get_last_result", pgconn_get_last_result, 0);
4538
- rb_define_method(rb_cPGconn, "async_get_last_result", pgconn_async_get_last_result, 0);
4461
+ rb_define_method(rb_cPGconn, "sync_get_last_result", pgconn_sync_get_last_result, 0);
4462
+ rb_define_method(rb_cPGconn, "get_last_result", pgconn_async_get_last_result, 0);
4463
+ rb_define_alias(rb_cPGconn, "async_get_last_result", "get_last_result");
4539
4464
  #ifdef HAVE_PQENCRYPTPASSWORDCONN
4540
- rb_define_method(rb_cPGconn, "encrypt_password", pgconn_encrypt_password, -1);
4465
+ rb_define_method(rb_cPGconn, "sync_encrypt_password", pgconn_sync_encrypt_password, -1);
4541
4466
  #endif
4542
4467
 
4543
4468
  #ifdef HAVE_PQSSLATTRIBUTE