pg 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b92ccb2d1b40d1641f55960ab8c290cd918d1f5caf21d8a434cfed4c32a3a2c
4
- data.tar.gz: 15ab0a988b2b70690bf074c078f44183e76e1cdfc99cabc818073366c2a07292
3
+ metadata.gz: 474c4e35a7ad4b1699e8a9cba4962442e8a66899489db5f88aeccc41f3323ab2
4
+ data.tar.gz: 645b283b84bcd7676353ca62efde6bbd2b1a3feea7fc43ef1921882cce3ee032
5
5
  SHA512:
6
- metadata.gz: 571cb50a99c5638e9e0819baae243d91cee56cb953a2037b07446e2bceb243d3b94084f803bc3bbba9acc5e5582401d19571a4f04094ad0e4ac5e71a077580e6
7
- data.tar.gz: 6b2e02994f1713004f282c74fcf2a970b8e750553cfc740805bbd47b13c53a3e41ac3de622c905c0ac920343c2672c2f9a3a2d11827c70e1944ce9c25c46377a
6
+ metadata.gz: 14595674eb04b991f007cf5e2b6a965574f9411ab352a26e3adc602eae72c0f03591d46c9d2e6bf25545cb19734877008868e95952f59a28ad5f1481ff7e0d15
7
+ data.tar.gz: 0d9c09338f69f695c751573b086d5feeafbd32781cfbd2b697ab36df898a210adf68e11e164165581fa9fdef39fea98d00b86fe7a08862b3d38709c87bfb1b0d
checksums.yaml.gz.sig CHANGED
Binary file
data/History.rdoc CHANGED
@@ -1,3 +1,19 @@
1
+ == v1.3.4 [2022-03-10] Lars Kanis <lars@greiz-reinsdorf.de>
2
+
3
+ Bugfixes:
4
+
5
+ - Don't leak IO in case of connection errors. #439
6
+ Previously it was kept open until the PG::Connection was garbage collected.
7
+ - Fix a performance regession in conn.get_result noticed in single row mode. #442
8
+ - Fix occasional error Errno::EBADF (Bad file descriptor) while connecting. #444
9
+ - Fix compatibility of res.stream_each* methods with Fiber.scheduler. #446
10
+ - Remove FL_TEST and FL_SET, which are MRI-internal. #437
11
+
12
+ Enhancements:
13
+
14
+ - Allow pgresult_stream_any to be used by sequel_pg. #443
15
+
16
+
1
17
  == v1.3.3 [2022-02-22] Lars Kanis <lars@greiz-reinsdorf.de>
2
18
 
3
19
  Bugfixes:
data/ext/errorcodes.rb CHANGED
File without changes
data/ext/extconf.rb CHANGED
File without changes
data/ext/pg.h CHANGED
@@ -344,6 +344,7 @@ void pg_typemap_compact _(( void * ));
344
344
 
345
345
  PGconn *pg_get_pgconn _(( VALUE ));
346
346
  t_pg_connection *pg_get_connection _(( VALUE ));
347
+ VALUE pgconn_block _(( int, VALUE *, VALUE ));
347
348
 
348
349
  VALUE pg_new_result _(( PGresult *, VALUE ));
349
350
  VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
data/ext/pg_connection.c CHANGED
@@ -475,9 +475,7 @@ pgconn_connect_poll(VALUE self)
475
475
  PostgresPollingStatusType status;
476
476
  status = gvl_PQconnectPoll(pg_get_pgconn(self));
477
477
 
478
- if ( status == PGRES_POLLING_FAILED ) {
479
- pgconn_close_socket_io(self);
480
- }
478
+ pgconn_close_socket_io(self);
481
479
 
482
480
  return INT2FIX((int)status);
483
481
  }
@@ -556,9 +554,7 @@ pgconn_reset_poll(VALUE self)
556
554
  PostgresPollingStatusType status;
557
555
  status = gvl_PQresetPoll(pg_get_pgconn(self));
558
556
 
559
- if ( status == PGRES_POLLING_FAILED ) {
560
- pgconn_close_socket_io(self);
561
- }
557
+ pgconn_close_socket_io(self);
562
558
 
563
559
  return INT2FIX((int)status);
564
560
  }
@@ -2343,21 +2339,12 @@ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2343
2339
  static void *
2344
2340
  wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2345
2341
  {
2346
- VALUE socket_io;
2347
2342
  VALUE ret;
2348
2343
  void *retval;
2349
2344
  struct timeval aborttime={0,0}, currtime, waittime;
2350
2345
  VALUE wait_timeout = Qnil;
2351
2346
  PGconn *conn = pg_get_pgconn(self);
2352
2347
 
2353
- socket_io = pgconn_socket_io(self);
2354
-
2355
- /* Check for connection errors (PQisBusy is true on connection errors) */
2356
- if ( PQconsumeInput(conn) == 0 ) {
2357
- pgconn_close_socket_io(self);
2358
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2359
- }
2360
-
2361
2348
  if ( ptimeout ) {
2362
2349
  gettimeofday(&currtime, NULL);
2363
2350
  timeradd(&currtime, ptimeout, &aborttime);
@@ -2372,6 +2359,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2372
2359
 
2373
2360
  /* Is the given timeout valid? */
2374
2361
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2362
+ VALUE socket_io = pgconn_socket_io(self);
2375
2363
  /* Wait for the socket to become readable before checking again */
2376
2364
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2377
2365
  } else {
@@ -2984,7 +2972,7 @@ get_result_readable(PGconn *conn)
2984
2972
  * If +true+ is returned, +conn.is_busy+ will return +false+
2985
2973
  * and +conn.get_result+ will not block.
2986
2974
  */
2987
- static VALUE
2975
+ VALUE
2988
2976
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
2989
2977
  struct timeval timeout;
2990
2978
  struct timeval *ptimeout = NULL;
@@ -3072,7 +3060,8 @@ pgconn_async_get_last_result(VALUE self)
3072
3060
  for(;;) {
3073
3061
  int status;
3074
3062
 
3075
- pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3063
+ /* wait for input (without blocking) before reading each result */
3064
+ wait_socket_readable(self, NULL, get_result_readable);
3076
3065
 
3077
3066
  cur = gvl_PQgetResult(conn);
3078
3067
  if (cur == NULL)
data/ext/pg_result.c CHANGED
@@ -1383,7 +1383,7 @@ pgresult_type_map_get(VALUE self)
1383
1383
 
1384
1384
 
1385
1385
  static void
1386
- yield_hash(VALUE self, int ntuples, int nfields)
1386
+ yield_hash(VALUE self, int ntuples, int nfields, void *data)
1387
1387
  {
1388
1388
  int tuple_num;
1389
1389
  t_pg_result *this = pgresult_get_this(self);
@@ -1397,7 +1397,7 @@ yield_hash(VALUE self, int ntuples, int nfields)
1397
1397
  }
1398
1398
 
1399
1399
  static void
1400
- yield_array(VALUE self, int ntuples, int nfields)
1400
+ yield_array(VALUE self, int ntuples, int nfields, void *data)
1401
1401
  {
1402
1402
  int row;
1403
1403
  t_pg_result *this = pgresult_get_this(self);
@@ -1417,7 +1417,7 @@ yield_array(VALUE self, int ntuples, int nfields)
1417
1417
  }
1418
1418
 
1419
1419
  static void
1420
- yield_tuple(VALUE self, int ntuples, int nfields)
1420
+ yield_tuple(VALUE self, int ntuples, int nfields, void *data)
1421
1421
  {
1422
1422
  int tuple_num;
1423
1423
  t_pg_result *this = pgresult_get_this(self);
@@ -1436,8 +1436,9 @@ yield_tuple(VALUE self, int ntuples, int nfields)
1436
1436
  }
1437
1437
  }
1438
1438
 
1439
- static VALUE
1440
- pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int))
1439
+ /* Non-static, and data pointer for use by sequel_pg */
1440
+ VALUE
1441
+ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int, void*), void* data)
1441
1442
  {
1442
1443
  t_pg_result *this;
1443
1444
  int nfields;
@@ -1465,7 +1466,12 @@ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int))
1465
1466
  pg_result_check( self );
1466
1467
  }
1467
1468
 
1468
- yielder( self, ntuples, nfields );
1469
+ yielder( self, ntuples, nfields, data );
1470
+
1471
+ if( gvl_PQisBusy(pgconn) ){
1472
+ /* wait for input (without blocking) before reading each result */
1473
+ pgconn_block( 0, NULL, this->connection );
1474
+ }
1469
1475
 
1470
1476
  pgresult = gvl_PQgetResult(pgconn);
1471
1477
  if( pgresult == NULL )
@@ -1516,7 +1522,7 @@ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int))
1516
1522
  static VALUE
1517
1523
  pgresult_stream_each(VALUE self)
1518
1524
  {
1519
- return pgresult_stream_any(self, yield_hash);
1525
+ return pgresult_stream_any(self, yield_hash, NULL);
1520
1526
  }
1521
1527
 
1522
1528
  /*
@@ -1532,7 +1538,7 @@ pgresult_stream_each(VALUE self)
1532
1538
  static VALUE
1533
1539
  pgresult_stream_each_row(VALUE self)
1534
1540
  {
1535
- return pgresult_stream_any(self, yield_array);
1541
+ return pgresult_stream_any(self, yield_array, NULL);
1536
1542
  }
1537
1543
 
1538
1544
  /*
@@ -1549,7 +1555,7 @@ pgresult_stream_each_tuple(VALUE self)
1549
1555
  /* allocate VALUEs that are shared between all streamed tuples */
1550
1556
  ensure_init_for_tuple(self);
1551
1557
 
1552
- return pgresult_stream_any(self, yield_tuple);
1558
+ return pgresult_stream_any(self, yield_tuple, NULL);
1553
1559
  }
1554
1560
 
1555
1561
  /*
data/ext/pg_tuple.c CHANGED
@@ -471,10 +471,7 @@ pg_tuple_dump(VALUE self)
471
471
  values = rb_ary_new4(this->num_fields, &this->values[0]);
472
472
  a = rb_ary_new3(2, field_names, values);
473
473
 
474
- if (FL_TEST(self, FL_EXIVAR)) {
475
- rb_copy_generic_ivar(a, self);
476
- FL_SET(a, FL_EXIVAR);
477
- }
474
+ rb_copy_generic_ivar(a, self);
478
475
 
479
476
  return a;
480
477
  }
@@ -542,10 +539,7 @@ pg_tuple_load(VALUE self, VALUE a)
542
539
 
543
540
  RTYPEDDATA_DATA(self) = this;
544
541
 
545
- if (FL_TEST(a, FL_EXIVAR)) {
546
- rb_copy_generic_ivar(self, a);
547
- FL_SET(self, FL_EXIVAR);
548
- }
542
+ rb_copy_generic_ivar(self, a);
549
543
 
550
544
  return self;
551
545
  }
data/lib/pg/connection.rb CHANGED
@@ -612,9 +612,6 @@ class PG::Connection
612
612
  alias async_cancel cancel
613
613
 
614
614
  private def async_connect_or_reset(poll_meth)
615
- # Now grab a reference to the underlying socket so we know when the connection is established
616
- socket = socket_io
617
-
618
615
  # Track the progress of the connection, waiting for the socket to become readable/writable before polling it
619
616
  poll_status = PG::PGRES_POLLING_WRITING
620
617
  until poll_status == PG::PGRES_POLLING_OK ||
@@ -623,18 +620,22 @@ class PG::Connection
623
620
  # If the socket needs to read, wait 'til it becomes readable to poll again
624
621
  case poll_status
625
622
  when PG::PGRES_POLLING_READING
626
- socket.wait_readable
623
+ socket_io.wait_readable
627
624
 
628
625
  # ...and the same for when the socket needs to write
629
626
  when PG::PGRES_POLLING_WRITING
630
- socket.wait_writable
627
+ socket_io.wait_writable
631
628
  end
632
629
 
633
630
  # Check to see if it's finished or failed yet
634
631
  poll_status = send( poll_meth )
635
632
  end
636
633
 
637
- raise(PG::ConnectionBad, error_message) unless status == PG::CONNECTION_OK
634
+ unless status == PG::CONNECTION_OK
635
+ msg = error_message
636
+ finish
637
+ raise PG::ConnectionBad, msg
638
+ end
638
639
 
639
640
  # Set connection to nonblocking to handle all blocking states in ruby.
640
641
  # That way a fiber scheduler is able to handle IO requests.
data/lib/pg/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module PG
2
2
  # Library version
3
- VERSION = '1.3.3'
3
+ VERSION = '1.3.4'
4
4
  end
File without changes
File without changes
data/sample/async_api.rb CHANGED
@@ -27,10 +27,6 @@ conn = PG::Connection.connect_start( :dbname => 'test' ) or
27
27
  abort "Connection failed: %s" % [ conn.error_message ] if
28
28
  conn.status == PG::CONNECTION_BAD
29
29
 
30
- # Now grab a reference to the underlying socket so we know when the
31
- # connection is established
32
- socket = conn.socket_io
33
-
34
30
  # Track the progress of the connection, waiting for the socket to become readable/writable
35
31
  # before polling it
36
32
  poll_status = PG::PGRES_POLLING_WRITING
@@ -41,13 +37,13 @@ until poll_status == PG::PGRES_POLLING_OK ||
41
37
  case poll_status
42
38
  when PG::PGRES_POLLING_READING
43
39
  output_progress " waiting for socket to become readable"
44
- select( [socket], nil, nil, TIMEOUT ) or
40
+ select( [conn.socket_io], nil, nil, TIMEOUT ) or
45
41
  raise "Asynchronous connection timed out!"
46
42
 
47
43
  # ...and the same for when the socket needs to write
48
44
  when PG::PGRES_POLLING_WRITING
49
45
  output_progress " waiting for socket to become writable"
50
- select( nil, [socket], nil, TIMEOUT ) or
46
+ select( nil, [conn.socket_io], nil, TIMEOUT ) or
51
47
  raise "Asynchronous connection timed out!"
52
48
  end
53
49
 
@@ -85,7 +81,7 @@ loop do
85
81
  # Buffer any incoming data on the socket until a full result is ready.
86
82
  conn.consume_input
87
83
  while conn.is_busy
88
- select( [socket], nil, nil, TIMEOUT ) or
84
+ select( [conn.socket_io], nil, nil, TIMEOUT ) or
89
85
  raise "Timeout waiting for query response."
90
86
  conn.consume_input
91
87
  end
File without changes
File without changes
data/sample/check_conn.rb CHANGED
File without changes
data/sample/copydata.rb CHANGED
File without changes
data/sample/copyfrom.rb CHANGED
File without changes
data/sample/copyto.rb CHANGED
File without changes
data/sample/cursor.rb CHANGED
File without changes
File without changes
data/sample/issue-119.rb CHANGED
File without changes
data/sample/losample.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -36,7 +36,7 @@ cert_chain:
36
36
  oL1mUdzB8KrZL4/WbG5YNX6UTtJbIOu9qEFbBAy4/jtIkJX+dlNoFwd4GXQW1YNO
37
37
  nA==
38
38
  -----END CERTIFICATE-----
39
- date: 2022-02-22 00:00:00.000000000 Z
39
+ date: 2022-03-10 00:00:00.000000000 Z
40
40
  dependencies: []
41
41
  description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
42
42
  9.3 and later.
metadata.gz.sig CHANGED
Binary file