pg 1.3.0 → 1.4.0

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
@@ -24,11 +24,32 @@ static VALUE pgconn_set_default_encoding( VALUE self );
24
24
  static VALUE pgconn_wait_for_flush( VALUE self );
25
25
  static void pgconn_set_internal_encoding_index( VALUE );
26
26
  static const rb_data_type_t pg_connection_type;
27
+ static VALUE pgconn_async_flush(VALUE self);
27
28
 
28
29
  /*
29
30
  * Global functions
30
31
  */
31
32
 
33
+ /*
34
+ * Convenience function to raise connection errors
35
+ */
36
+ #ifdef __GNUC__
37
+ __attribute__((format(printf, 3, 4)))
38
+ #endif
39
+ static void
40
+ pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...)
41
+ {
42
+ VALUE msg, error;
43
+ va_list ap;
44
+
45
+ va_start(ap, format);
46
+ msg = rb_vsprintf(format, ap);
47
+ va_end(ap);
48
+ error = rb_exc_new_str(klass, msg);
49
+ rb_iv_set(error, "@connection", self);
50
+ rb_exc_raise(error);
51
+ }
52
+
32
53
  /*
33
54
  * Fetch the PG::Connection object data pointer.
34
55
  */
@@ -52,7 +73,7 @@ pg_get_connection_safe( VALUE self )
52
73
  TypedData_Get_Struct( self, t_pg_connection, &pg_connection_type, this);
53
74
 
54
75
  if ( !this->pgconn )
55
- rb_raise( rb_eConnectionBad, "connection is closed" );
76
+ pg_raise_conn_error( rb_eConnectionBad, self, "connection is closed");
56
77
 
57
78
  return this;
58
79
  }
@@ -70,8 +91,9 @@ pg_get_pgconn( VALUE self )
70
91
  t_pg_connection *this;
71
92
  TypedData_Get_Struct( self, t_pg_connection, &pg_connection_type, this);
72
93
 
73
- if ( !this->pgconn )
74
- rb_raise( rb_eConnectionBad, "connection is closed" );
94
+ if ( !this->pgconn ){
95
+ pg_raise_conn_error( rb_eConnectionBad, self, "connection is closed");
96
+ }
75
97
 
76
98
  return this->pgconn;
77
99
  }
@@ -89,9 +111,8 @@ pgconn_close_socket_io( VALUE self )
89
111
 
90
112
  if ( RTEST(socket_io) ) {
91
113
  #if defined(_WIN32)
92
- if( rb_w32_unwrap_io_handle(this->ruby_sd) ){
93
- rb_raise(rb_eConnectionBad, "Could not unwrap win32 socket handle");
94
- }
114
+ if( rb_w32_unwrap_io_handle(this->ruby_sd) )
115
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
95
116
  #endif
96
117
  rb_funcall( socket_io, rb_intern("close"), 0 );
97
118
  }
@@ -254,7 +275,6 @@ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
254
275
  {
255
276
  t_pg_connection *this;
256
277
  VALUE conninfo;
257
- VALUE error;
258
278
  VALUE self = pgconn_s_allocate( klass );
259
279
 
260
280
  this = pg_get_connection( self );
@@ -262,13 +282,10 @@ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
262
282
  this->pgconn = gvl_PQconnectdb(StringValueCStr(conninfo));
263
283
 
264
284
  if(this->pgconn == NULL)
265
- rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate structure");
285
+ rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate PGconn structure");
266
286
 
267
- if (PQstatus(this->pgconn) == CONNECTION_BAD) {
268
- error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(this->pgconn));
269
- rb_iv_set(error, "@connection", self);
270
- rb_exc_raise(error);
271
- }
287
+ if (PQstatus(this->pgconn) == CONNECTION_BAD)
288
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(this->pgconn));
272
289
 
273
290
  pgconn_set_default_encoding( self );
274
291
 
@@ -301,7 +318,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
301
318
  {
302
319
  VALUE rb_conn;
303
320
  VALUE conninfo;
304
- VALUE error;
305
321
  t_pg_connection *this;
306
322
 
307
323
  /*
@@ -314,13 +330,10 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
314
330
  this->pgconn = gvl_PQconnectStart( StringValueCStr(conninfo) );
315
331
 
316
332
  if( this->pgconn == NULL )
317
- rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate structure");
333
+ rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate PGconn structure");
318
334
 
319
- if ( PQstatus(this->pgconn) == CONNECTION_BAD ) {
320
- error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(this->pgconn));
321
- rb_iv_set(error, "@connection", rb_conn);
322
- rb_exc_raise(error);
323
- }
335
+ if ( PQstatus(this->pgconn) == CONNECTION_BAD )
336
+ pg_raise_conn_error( rb_eConnectionBad, rb_conn, "%s", PQerrorMessage(this->pgconn));
324
337
 
325
338
  if ( rb_block_given_p() ) {
326
339
  return rb_ensure( rb_yield, rb_conn, pgconn_finish, rb_conn );
@@ -376,6 +389,36 @@ pgconn_s_conndefaults(VALUE self)
376
389
  return array;
377
390
  }
378
391
 
392
+ /*
393
+ * Document-method: PG::Connection.conninfo_parse
394
+ *
395
+ * call-seq:
396
+ * PG::Connection.conninfo_parse(conninfo_string) -> Array
397
+ *
398
+ * Returns parsed connection options from the provided connection string as an array of hashes.
399
+ * Each hash has the same keys as PG::Connection.conndefaults() .
400
+ * The values from the +conninfo_string+ are stored in the +:val+ key.
401
+ */
402
+ static VALUE
403
+ pgconn_s_conninfo_parse(VALUE self, VALUE conninfo)
404
+ {
405
+ VALUE array;
406
+ char *errmsg = NULL;
407
+ PQconninfoOption *options = PQconninfoParse(StringValueCStr(conninfo), &errmsg);
408
+ if(errmsg){
409
+ VALUE error = rb_str_new_cstr(errmsg);
410
+ PQfreemem(errmsg);
411
+ rb_raise(rb_ePGerror, "%"PRIsVALUE, error);
412
+ }
413
+ array = pgconn_make_conninfo_array( options );
414
+
415
+ PQconninfoFree(options);
416
+
417
+ UNUSED( self );
418
+
419
+ return array;
420
+ }
421
+
379
422
 
380
423
  #ifdef HAVE_PQENCRYPTPASSWORDCONN
381
424
  static VALUE
@@ -396,7 +439,7 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
396
439
  rval = rb_str_new2( encrypted );
397
440
  PQfreemem( encrypted );
398
441
  } else {
399
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
442
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
400
443
  }
401
444
 
402
445
  return rval;
@@ -450,17 +493,18 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
450
493
  * the asynchronous connection is ready
451
494
  *
452
495
  * Example:
453
- * conn = PG::Connection.connect_start("dbname=mydatabase")
454
- * socket = conn.socket_io
496
+ * require "io/wait"
497
+ *
498
+ * conn = PG::Connection.connect_start(dbname: 'mydatabase')
455
499
  * status = conn.connect_poll
456
500
  * while(status != PG::PGRES_POLLING_OK) do
457
501
  * # do some work while waiting for the connection to complete
458
502
  * if(status == PG::PGRES_POLLING_READING)
459
- * if(not select([socket], [], [], 10.0))
503
+ * unless conn.socket_io.wait_readable(10.0)
460
504
  * raise "Asynchronous connection timed out!"
461
505
  * end
462
506
  * elsif(status == PG::PGRES_POLLING_WRITING)
463
- * if(not select([], [socket], [], 10.0))
507
+ * unless conn.socket_io.wait_writable(10.0)
464
508
  * raise "Asynchronous connection timed out!"
465
509
  * end
466
510
  * end
@@ -475,9 +519,7 @@ pgconn_connect_poll(VALUE self)
475
519
  PostgresPollingStatusType status;
476
520
  status = gvl_PQconnectPoll(pg_get_pgconn(self));
477
521
 
478
- if ( status == PGRES_POLLING_FAILED ) {
479
- pgconn_close_socket_io(self);
480
- }
522
+ pgconn_close_socket_io(self);
481
523
 
482
524
  return INT2FIX((int)status);
483
525
  }
@@ -538,7 +580,7 @@ pgconn_reset_start(VALUE self)
538
580
  {
539
581
  pgconn_close_socket_io( self );
540
582
  if(gvl_PQresetStart(pg_get_pgconn(self)) == 0)
541
- rb_raise(rb_eUnableToSend, "reset has failed");
583
+ pg_raise_conn_error( rb_eUnableToSend, self, "reset has failed");
542
584
  return Qnil;
543
585
  }
544
586
 
@@ -556,9 +598,7 @@ pgconn_reset_poll(VALUE self)
556
598
  PostgresPollingStatusType status;
557
599
  status = gvl_PQresetPoll(pg_get_pgconn(self));
558
600
 
559
- if ( status == PGRES_POLLING_FAILED ) {
560
- pgconn_close_socket_io(self);
561
- }
601
+ pgconn_close_socket_io(self);
562
602
 
563
603
  return INT2FIX((int)status);
564
604
  }
@@ -610,7 +650,18 @@ pgconn_pass(VALUE self)
610
650
  * call-seq:
611
651
  * conn.host()
612
652
  *
613
- * Returns the connected server name.
653
+ * Returns the server host name of the active connection.
654
+ * This can be a host name, an IP address, or a directory path if the connection is via Unix socket.
655
+ * (The path case can be distinguished because it will always be an absolute path, beginning with +/+ .)
656
+ *
657
+ * If the connection parameters specified both host and hostaddr, then +host+ will return the host information.
658
+ * If only hostaddr was specified, then that is returned.
659
+ * If multiple hosts were specified in the connection parameters, +host+ returns the host actually connected to.
660
+ *
661
+ * If there is an error producing the host information (perhaps if the connection has not been fully established or there was an error), it returns an empty string.
662
+ *
663
+ * If multiple hosts were specified in the connection parameters, it is not possible to rely on the result of +host+ until the connection is established.
664
+ * The status of the connection can be checked using the function Connection#status .
614
665
  */
615
666
  static VALUE
616
667
  pgconn_host(VALUE self)
@@ -620,6 +671,26 @@ pgconn_host(VALUE self)
620
671
  return rb_str_new2(host);
621
672
  }
622
673
 
674
+ /* PQhostaddr() appeared in PostgreSQL-12 together with PQresultMemorySize() */
675
+ #if defined(HAVE_PQRESULTMEMORYSIZE)
676
+ /*
677
+ * call-seq:
678
+ * conn.hostaddr()
679
+ *
680
+ * Returns the server IP address of the active connection.
681
+ * This can be the address that a host name resolved to, or an IP address provided through the hostaddr parameter.
682
+ * If there is an error producing the host information (perhaps if the connection has not been fully established or there was an error), it returns an empty string.
683
+ *
684
+ */
685
+ static VALUE
686
+ pgconn_hostaddr(VALUE self)
687
+ {
688
+ char *host = PQhostaddr(pg_get_pgconn(self));
689
+ if (!host) return Qnil;
690
+ return rb_str_new2(host);
691
+ }
692
+ #endif
693
+
623
694
  /*
624
695
  * call-seq:
625
696
  * conn.port()
@@ -690,6 +761,9 @@ pgconn_conninfo( VALUE self )
690
761
  * PG::Constants::CONNECTION_BAD
691
762
  *
692
763
  * ... and other constants of kind PG::Constants::CONNECTION_*
764
+ *
765
+ * Example:
766
+ * PG.constants.grep(/CONNECTION_/).find{|c| PG.const_get(c) == conn.status} # => :CONNECTION_OK
693
767
  */
694
768
  static VALUE
695
769
  pgconn_status(VALUE self)
@@ -814,7 +888,8 @@ pgconn_socket(VALUE self)
814
888
  pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
815
889
 
816
890
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
817
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
891
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
892
+
818
893
  return INT2NUM(sd);
819
894
  }
820
895
 
@@ -822,13 +897,15 @@ pgconn_socket(VALUE self)
822
897
  * call-seq:
823
898
  * conn.socket_io() -> IO
824
899
  *
825
- * Fetch a memorized IO object created from the Connection's underlying socket.
826
- * This object can be used for IO.select to wait for events while running
827
- * asynchronous API calls.
900
+ * Fetch an IO object created from the Connection's underlying socket.
901
+ * This object can be used per <tt>socket_io.wait_readable</tt>, <tt>socket_io.wait_writable</tt> or for <tt>IO.select</tt> to wait for events while running asynchronous API calls.
902
+ * <tt>IO#wait_*able</tt> is is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
903
+ *
904
+ * The IO object can change while the connection is established, but is memorized afterwards.
905
+ * So be sure not to cache the IO object, but repeat calling <tt>conn.socket_io</tt> instead.
828
906
  *
829
- * Using this instead of #socket avoids the problem of the underlying connection
830
- * being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt>
831
- * goes out of scope. In contrast to #socket, it also works on Windows.
907
+ * Using this method also works on Windows in contrast to using #socket .
908
+ * It also avoids the problem of the underlying connection being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt> goes out of scope.
832
909
  */
833
910
  static VALUE
834
911
  pgconn_socket_io(VALUE self)
@@ -840,14 +917,15 @@ pgconn_socket_io(VALUE self)
840
917
  VALUE socket_io = this->socket_io;
841
918
 
842
919
  if ( !RTEST(socket_io) ) {
843
- if( (sd = PQsocket(this->pgconn)) < 0)
844
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
920
+ if( (sd = PQsocket(this->pgconn)) < 0){
921
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
922
+ }
845
923
 
846
924
  #ifdef _WIN32
847
925
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
848
- if( ruby_sd == -1 ){
849
- rb_raise(rb_eConnectionBad, "Could not wrap win32 socket handle");
850
- }
926
+ if( ruby_sd == -1 )
927
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
928
+
851
929
  this->ruby_sd = ruby_sd;
852
930
  #else
853
931
  ruby_sd = sd;
@@ -912,7 +990,7 @@ pgconn_backend_key(VALUE self)
912
990
 
913
991
  cancel = (struct pg_cancel*)PQgetCancel(conn);
914
992
  if(cancel == NULL)
915
- rb_raise(rb_ePGerror,"Invalid connection!");
993
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
916
994
 
917
995
  if( cancel->be_pid != PQbackendPID(conn) )
918
996
  rb_raise(rb_ePGerror,"Unexpected binary struct layout - please file a bug report at ruby-pg!");
@@ -1541,9 +1619,9 @@ pgconn_s_escape(VALUE self, VALUE string)
1541
1619
  if( !singleton ) {
1542
1620
  size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1543
1621
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1544
- if(error) {
1545
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1546
- }
1622
+ if(error)
1623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(pg_get_pgconn(self)));
1624
+
1547
1625
  } else {
1548
1626
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1549
1627
  }
@@ -1639,7 +1717,6 @@ pgconn_escape_literal(VALUE self, VALUE string)
1639
1717
  {
1640
1718
  t_pg_connection *this = pg_get_connection_safe( self );
1641
1719
  char *escaped = NULL;
1642
- VALUE error;
1643
1720
  VALUE result = Qnil;
1644
1721
  int enc_idx = this->enc_idx;
1645
1722
 
@@ -1650,12 +1727,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1650
1727
 
1651
1728
  escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1652
1729
  if (escaped == NULL)
1653
- {
1654
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1655
- rb_iv_set(error, "@connection", self);
1656
- rb_exc_raise(error);
1657
- return Qnil;
1658
- }
1730
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1731
+
1659
1732
  result = rb_str_new2(escaped);
1660
1733
  PQfreemem(escaped);
1661
1734
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1678,7 +1751,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1678
1751
  {
1679
1752
  t_pg_connection *this = pg_get_connection_safe( self );
1680
1753
  char *escaped = NULL;
1681
- VALUE error;
1682
1754
  VALUE result = Qnil;
1683
1755
  int enc_idx = this->enc_idx;
1684
1756
 
@@ -1689,12 +1761,8 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1689
1761
 
1690
1762
  escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1691
1763
  if (escaped == NULL)
1692
- {
1693
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1694
- rb_iv_set(error, "@connection", self);
1695
- rb_exc_raise(error);
1696
- return Qnil;
1697
- }
1764
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1765
+
1698
1766
  result = rb_str_new2(escaped);
1699
1767
  PQfreemem(escaped);
1700
1768
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1742,14 +1810,9 @@ static VALUE
1742
1810
  pgconn_set_single_row_mode(VALUE self)
1743
1811
  {
1744
1812
  PGconn *conn = pg_get_pgconn(self);
1745
- VALUE error;
1746
1813
 
1747
1814
  if( PQsetSingleRowMode(conn) == 0 )
1748
- {
1749
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1750
- rb_iv_set(error, "@connection", self);
1751
- rb_exc_raise(error);
1752
- }
1815
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1753
1816
 
1754
1817
  return self;
1755
1818
  }
@@ -1773,15 +1836,12 @@ static VALUE
1773
1836
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1774
1837
  {
1775
1838
  t_pg_connection *this = pg_get_connection_safe( self );
1776
- VALUE error;
1777
1839
 
1778
1840
  /* If called with no or nil parameters, use PQexec for compatibility */
1779
1841
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1780
- if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0) {
1781
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1782
- rb_iv_set(error, "@connection", self);
1783
- rb_exc_raise(error);
1784
- }
1842
+ if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0)
1843
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1844
+
1785
1845
  pgconn_wait_for_flush( self );
1786
1846
  return Qnil;
1787
1847
  }
@@ -1838,7 +1898,6 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1838
1898
  t_pg_connection *this = pg_get_connection_safe( self );
1839
1899
  int result;
1840
1900
  VALUE command, in_res_fmt;
1841
- VALUE error;
1842
1901
  int nParams;
1843
1902
  int resultFormat;
1844
1903
  struct query_params_data paramsData = { this->enc_idx };
@@ -1855,11 +1914,9 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1855
1914
 
1856
1915
  free_query_params( &paramsData );
1857
1916
 
1858
- if(result == 0) {
1859
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1860
- rb_iv_set(error, "@connection", self);
1861
- rb_exc_raise(error);
1862
- }
1917
+ if(result == 0)
1918
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1919
+
1863
1920
  pgconn_wait_for_flush( self );
1864
1921
  return Qnil;
1865
1922
  }
@@ -1891,7 +1948,6 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1891
1948
  int result;
1892
1949
  VALUE name, command, in_paramtypes;
1893
1950
  VALUE param;
1894
- VALUE error;
1895
1951
  int i = 0;
1896
1952
  int nParams = 0;
1897
1953
  Oid *paramTypes = NULL;
@@ -1920,9 +1976,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1920
1976
  xfree(paramTypes);
1921
1977
 
1922
1978
  if(result == 0) {
1923
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1924
- rb_iv_set(error, "@connection", self);
1925
- rb_exc_raise(error);
1979
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1926
1980
  }
1927
1981
  pgconn_wait_for_flush( self );
1928
1982
  return Qnil;
@@ -1966,7 +2020,6 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1966
2020
  t_pg_connection *this = pg_get_connection_safe( self );
1967
2021
  int result;
1968
2022
  VALUE name, in_res_fmt;
1969
- VALUE error;
1970
2023
  int nParams;
1971
2024
  int resultFormat;
1972
2025
  struct query_params_data paramsData = { this->enc_idx };
@@ -1988,11 +2041,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1988
2041
 
1989
2042
  free_query_params( &paramsData );
1990
2043
 
1991
- if(result == 0) {
1992
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1993
- rb_iv_set(error, "@connection", self);
1994
- rb_exc_raise(error);
1995
- }
2044
+ if(result == 0)
2045
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2046
+
1996
2047
  pgconn_wait_for_flush( self );
1997
2048
  return Qnil;
1998
2049
  }
@@ -2007,14 +2058,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2007
2058
  static VALUE
2008
2059
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2009
2060
  {
2010
- VALUE error;
2011
2061
  t_pg_connection *this = pg_get_connection_safe( self );
2012
2062
  /* returns 0 on failure */
2013
- if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0) {
2014
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2015
- rb_iv_set(error, "@connection", self);
2016
- rb_exc_raise(error);
2017
- }
2063
+ if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0)
2064
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2065
+
2018
2066
  pgconn_wait_for_flush( self );
2019
2067
  return Qnil;
2020
2068
  }
@@ -2030,14 +2078,11 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2030
2078
  static VALUE
2031
2079
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2032
2080
  {
2033
- VALUE error;
2034
2081
  t_pg_connection *this = pg_get_connection_safe( self );
2035
2082
  /* returns 0 on failure */
2036
- if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
2037
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2038
- rb_iv_set(error, "@connection", self);
2039
- rb_exc_raise(error);
2040
- }
2083
+ if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0)
2084
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2085
+
2041
2086
  pgconn_wait_for_flush( self );
2042
2087
  return Qnil;
2043
2088
  }
@@ -2070,18 +2115,15 @@ pgconn_sync_get_result(VALUE self)
2070
2115
  * or *notifies* to see if the state has changed.
2071
2116
  */
2072
2117
  static VALUE
2073
- pgconn_consume_input(self)
2074
- VALUE self;
2118
+ pgconn_consume_input(VALUE self)
2075
2119
  {
2076
- VALUE error;
2077
2120
  PGconn *conn = pg_get_pgconn(self);
2078
2121
  /* returns 0 on error */
2079
2122
  if(PQconsumeInput(conn) == 0) {
2080
2123
  pgconn_close_socket_io(self);
2081
- error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(conn));
2082
- rb_iv_set(error, "@connection", self);
2083
- rb_exc_raise(error);
2124
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(conn));
2084
2125
  }
2126
+
2085
2127
  return Qnil;
2086
2128
  }
2087
2129
 
@@ -2093,18 +2135,15 @@ pgconn_consume_input(self)
2093
2135
  * #get_result would block. Otherwise returns +false+.
2094
2136
  */
2095
2137
  static VALUE
2096
- pgconn_is_busy(self)
2097
- VALUE self;
2138
+ pgconn_is_busy(VALUE self)
2098
2139
  {
2099
2140
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2100
2141
  }
2101
2142
 
2102
2143
  static VALUE
2103
- pgconn_sync_setnonblocking(self, state)
2104
- VALUE self, state;
2144
+ pgconn_sync_setnonblocking(VALUE self, VALUE state)
2105
2145
  {
2106
2146
  int arg;
2107
- VALUE error;
2108
2147
  PGconn *conn = pg_get_pgconn(self);
2109
2148
  if(state == Qtrue)
2110
2149
  arg = 1;
@@ -2113,18 +2152,15 @@ pgconn_sync_setnonblocking(self, state)
2113
2152
  else
2114
2153
  rb_raise(rb_eArgError, "Boolean value expected");
2115
2154
 
2116
- if(PQsetnonblocking(conn, arg) == -1) {
2117
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2118
- rb_iv_set(error, "@connection", self);
2119
- rb_exc_raise(error);
2120
- }
2155
+ if(PQsetnonblocking(conn, arg) == -1)
2156
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2157
+
2121
2158
  return Qnil;
2122
2159
  }
2123
2160
 
2124
2161
 
2125
2162
  static VALUE
2126
- pgconn_sync_isnonblocking(self)
2127
- VALUE self;
2163
+ pgconn_sync_isnonblocking(VALUE self)
2128
2164
  {
2129
2165
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2130
2166
  }
@@ -2133,14 +2169,10 @@ static VALUE
2133
2169
  pgconn_sync_flush(VALUE self)
2134
2170
  {
2135
2171
  PGconn *conn = pg_get_pgconn(self);
2136
- int ret;
2137
- VALUE error;
2138
- ret = PQflush(conn);
2139
- if(ret == -1) {
2140
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2141
- rb_iv_set(error, "@connection", self);
2142
- rb_exc_raise(error);
2143
- }
2172
+ int ret = PQflush(conn);
2173
+ if(ret == -1)
2174
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2175
+
2144
2176
  return (ret) ? Qfalse : Qtrue;
2145
2177
  }
2146
2178
 
@@ -2154,7 +2186,7 @@ pgconn_sync_cancel(VALUE self)
2154
2186
 
2155
2187
  cancel = PQgetCancel(pg_get_pgconn(self));
2156
2188
  if(cancel == NULL)
2157
- rb_raise(rb_ePGerror,"Invalid connection!");
2189
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
2158
2190
 
2159
2191
  ret = gvl_PQcancel(cancel, errbuf, sizeof(errbuf));
2160
2192
  if(ret == 1)
@@ -2241,19 +2273,15 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
2241
2273
  GetOpenFile((io), fptr);
2242
2274
  if( !NIL_P(timeout) ){
2243
2275
  ptimeout.tv_sec = (time_t)(NUM2DBL(timeout));
2244
- ptimeout.tv_usec = (time_t)(NUM2DBL(timeout) - (double)ptimeout.tv_sec);
2276
+ ptimeout.tv_usec = (time_t)((NUM2DBL(timeout) - (double)ptimeout.tv_sec) * 1e6);
2245
2277
 
2246
2278
  gettimeofday(&currtime, NULL);
2247
2279
  timeradd(&currtime, &ptimeout, &aborttime);
2248
2280
  }
2249
2281
 
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
- }
2282
+ if(rb_events & PG_RUBY_IO_READABLE) w32_events |= FD_READ | FD_ACCEPT | FD_CLOSE;
2283
+ if(rb_events & PG_RUBY_IO_WRITABLE) w32_events |= FD_WRITE | FD_CONNECT;
2284
+ if(rb_events & PG_RUBY_IO_PRIORITY) w32_events |= FD_OOB;
2257
2285
 
2258
2286
  for(;;) {
2259
2287
  if ( WSAEventSelect(_get_osfhandle(fptr->fd), hEvent, w32_events) == SOCKET_ERROR ) {
@@ -2336,7 +2364,7 @@ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2336
2364
  GetOpenFile((io), fptr);
2337
2365
  if( !NIL_P(timeout) ){
2338
2366
  waittime.tv_sec = (time_t)(NUM2DBL(timeout));
2339
- waittime.tv_usec = (time_t)(NUM2DBL(timeout) - (double)waittime.tv_sec);
2367
+ waittime.tv_usec = (time_t)((NUM2DBL(timeout) - (double)waittime.tv_sec) * 1e6);
2340
2368
  }
2341
2369
  res = rb_wait_for_single_fd(fptr->fd, NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
2342
2370
 
@@ -2347,21 +2375,12 @@ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2347
2375
  static void *
2348
2376
  wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2349
2377
  {
2350
- VALUE socket_io;
2351
2378
  VALUE ret;
2352
2379
  void *retval;
2353
2380
  struct timeval aborttime={0,0}, currtime, waittime;
2354
2381
  VALUE wait_timeout = Qnil;
2355
2382
  PGconn *conn = pg_get_pgconn(self);
2356
2383
 
2357
- socket_io = pgconn_socket_io(self);
2358
-
2359
- /* Check for connection errors (PQisBusy is true on connection errors) */
2360
- if ( PQconsumeInput(conn) == 0 ) {
2361
- pgconn_close_socket_io(self);
2362
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2363
- }
2364
-
2365
2384
  if ( ptimeout ) {
2366
2385
  gettimeofday(&currtime, NULL);
2367
2386
  timeradd(&currtime, ptimeout, &aborttime);
@@ -2376,6 +2395,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2376
2395
 
2377
2396
  /* Is the given timeout valid? */
2378
2397
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2398
+ VALUE socket_io;
2399
+
2400
+ /* before we wait for data, make sure everything has been sent */
2401
+ pgconn_async_flush(self);
2402
+ if ((retval=is_readable(conn)))
2403
+ return retval;
2404
+
2405
+ socket_io = pgconn_socket_io(self);
2379
2406
  /* Wait for the socket to become readable before checking again */
2380
2407
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2381
2408
  } else {
@@ -2390,7 +2417,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2390
2417
  /* Check for connection errors (PQisBusy is true on connection errors) */
2391
2418
  if ( PQconsumeInput(conn) == 0 ){
2392
2419
  pgconn_close_socket_io(self);
2393
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2420
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2394
2421
  }
2395
2422
  }
2396
2423
 
@@ -2403,8 +2430,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2403
2430
  *
2404
2431
  * Attempts to flush any queued output data to the server.
2405
2432
  * Returns +true+ if data is successfully flushed, +false+
2406
- * if not (can only return +false+ if connection is
2407
- * nonblocking.
2433
+ * if not. It can only return +false+ if connection is
2434
+ * in nonblocking mode.
2408
2435
  * Raises PG::Error if some other failure occurred.
2409
2436
  */
2410
2437
  static VALUE
@@ -2540,11 +2567,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2540
2567
  Check_Type(buffer, T_STRING);
2541
2568
 
2542
2569
  ret = gvl_PQputCopyData(this->pgconn, RSTRING_PTR(buffer), RSTRING_LENINT(buffer));
2543
- if(ret == -1) {
2544
- VALUE error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2545
- rb_iv_set(error, "@connection", self);
2546
- rb_exc_raise(error);
2547
- }
2570
+ if(ret == -1)
2571
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2572
+
2548
2573
  RB_GC_GUARD(intermediate);
2549
2574
  RB_GC_GUARD(buffer);
2550
2575
 
@@ -2555,7 +2580,6 @@ static VALUE
2555
2580
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2556
2581
  {
2557
2582
  VALUE str;
2558
- VALUE error;
2559
2583
  int ret;
2560
2584
  const char *error_message = NULL;
2561
2585
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2566,11 +2590,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2566
2590
  error_message = pg_cstr_enc(str, this->enc_idx);
2567
2591
 
2568
2592
  ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2569
- if(ret == -1) {
2570
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2571
- rb_iv_set(error, "@connection", self);
2572
- rb_exc_raise(error);
2573
- }
2593
+ if(ret == -1)
2594
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2595
+
2574
2596
  return (ret) ? Qtrue : Qfalse;
2575
2597
  }
2576
2598
 
@@ -2578,7 +2600,6 @@ static VALUE
2578
2600
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2579
2601
  {
2580
2602
  VALUE async_in;
2581
- VALUE error;
2582
2603
  VALUE result;
2583
2604
  int ret;
2584
2605
  char *buffer;
@@ -2598,10 +2619,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2598
2619
  }
2599
2620
 
2600
2621
  ret = gvl_PQgetCopyData(this->pgconn, &buffer, RTEST(async_in));
2601
- if(ret == -2) { /* error */
2602
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2603
- rb_iv_set(error, "@connection", self);
2604
- rb_exc_raise(error);
2622
+ if(ret == -2){ /* error */
2623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2605
2624
  }
2606
2625
  if(ret == -1) { /* No data left */
2607
2626
  return Qnil;
@@ -2906,9 +2925,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2906
2925
 
2907
2926
  Check_Type(str, T_STRING);
2908
2927
 
2909
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2910
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2911
- }
2928
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2929
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2930
+
2912
2931
  pgconn_set_internal_encoding_index( self );
2913
2932
 
2914
2933
  return Qnil;
@@ -2988,7 +3007,7 @@ get_result_readable(PGconn *conn)
2988
3007
  * If +true+ is returned, +conn.is_busy+ will return +false+
2989
3008
  * and +conn.get_result+ will not block.
2990
3009
  */
2991
- static VALUE
3010
+ VALUE
2992
3011
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
2993
3012
  struct timeval timeout;
2994
3013
  struct timeval *ptimeout = NULL;
@@ -3076,7 +3095,8 @@ pgconn_async_get_last_result(VALUE self)
3076
3095
  for(;;) {
3077
3096
  int status;
3078
3097
 
3079
- pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
3098
+ /* wait for input (without blocking) before reading each result */
3099
+ wait_socket_readable(self, NULL, get_result_readable);
3080
3100
 
3081
3101
  cur = gvl_PQgetResult(conn);
3082
3102
  if (cur == NULL)
@@ -3540,11 +3560,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3540
3560
  {
3541
3561
  PGconn *conn = pg_get_pgconn(self);
3542
3562
  int res = PQenterPipelineMode(conn);
3543
- if( res == 1 ) {
3544
- return Qnil;
3545
- } else {
3546
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3547
- }
3563
+ if( res != 1 )
3564
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3565
+
3566
+ return Qnil;
3548
3567
  }
3549
3568
 
3550
3569
  /*
@@ -3563,11 +3582,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3563
3582
  {
3564
3583
  PGconn *conn = pg_get_pgconn(self);
3565
3584
  int res = PQexitPipelineMode(conn);
3566
- if( res == 1 ) {
3567
- return Qnil;
3568
- } else {
3569
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3570
- }
3585
+ if( res != 1 )
3586
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3587
+
3588
+ return Qnil;
3571
3589
  }
3572
3590
 
3573
3591
 
@@ -3587,11 +3605,10 @@ pgconn_pipeline_sync(VALUE self)
3587
3605
  {
3588
3606
  PGconn *conn = pg_get_pgconn(self);
3589
3607
  int res = PQpipelineSync(conn);
3590
- if( res == 1 ) {
3591
- return Qnil;
3592
- } else {
3593
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3594
- }
3608
+ if( res != 1 )
3609
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3610
+
3611
+ return Qnil;
3595
3612
  }
3596
3613
 
3597
3614
  /*
@@ -3611,11 +3628,10 @@ pgconn_send_flush_request(VALUE self)
3611
3628
  {
3612
3629
  PGconn *conn = pg_get_pgconn(self);
3613
3630
  int res = PQsendFlushRequest(conn);
3614
- if( res == 1 ) {
3615
- return Qnil;
3616
- } else {
3617
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3618
- }
3631
+ if( res != 1 )
3632
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3633
+
3634
+ return Qnil;
3619
3635
  }
3620
3636
 
3621
3637
  #endif
@@ -3646,7 +3662,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3646
3662
 
3647
3663
  lo_oid = lo_creat(conn, mode);
3648
3664
  if (lo_oid == 0)
3649
- rb_raise(rb_ePGerror, "lo_creat failed");
3665
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3650
3666
 
3651
3667
  return UINT2NUM(lo_oid);
3652
3668
  }
@@ -3667,7 +3683,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3667
3683
 
3668
3684
  ret = lo_create(conn, lo_oid);
3669
3685
  if (ret == InvalidOid)
3670
- rb_raise(rb_ePGerror, "lo_create failed");
3686
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3671
3687
 
3672
3688
  return UINT2NUM(ret);
3673
3689
  }
@@ -3691,7 +3707,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3691
3707
 
3692
3708
  lo_oid = lo_import(conn, StringValueCStr(filename));
3693
3709
  if (lo_oid == 0) {
3694
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3710
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3695
3711
  }
3696
3712
  return UINT2NUM(lo_oid);
3697
3713
  }
@@ -3712,7 +3728,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3712
3728
  oid = NUM2UINT(lo_oid);
3713
3729
 
3714
3730
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3715
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3731
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3716
3732
  }
3717
3733
  return Qnil;
3718
3734
  }
@@ -3743,7 +3759,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3743
3759
  mode = NUM2INT(nmode);
3744
3760
 
3745
3761
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3746
- rb_raise(rb_ePGerror, "can't open large object: %s", PQerrorMessage(conn));
3762
+ pg_raise_conn_error( rb_ePGerror, self, "can't open large object: %s", PQerrorMessage(conn));
3747
3763
  }
3748
3764
  return INT2FIX(fd);
3749
3765
  }
@@ -3765,11 +3781,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3765
3781
  Check_Type(buffer, T_STRING);
3766
3782
 
3767
3783
  if( RSTRING_LEN(buffer) < 0) {
3768
- rb_raise(rb_ePGerror, "write buffer zero string");
3784
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3769
3785
  }
3770
3786
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3771
3787
  RSTRING_LEN(buffer))) < 0) {
3772
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3788
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3773
3789
  }
3774
3790
 
3775
3791
  return INT2FIX(n);
@@ -3792,16 +3808,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3792
3808
  VALUE str;
3793
3809
  char *buffer;
3794
3810
 
3795
- buffer = ALLOC_N(char, len);
3796
- if(buffer == NULL)
3797
- rb_raise(rb_eNoMemError, "ALLOC failed!");
3798
-
3799
- if (len < 0){
3800
- rb_raise(rb_ePGerror,"nagative length %d given", len);
3801
- }
3811
+ if (len < 0)
3812
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3802
3813
 
3814
+ buffer = ALLOC_N(char, len);
3803
3815
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3804
- rb_raise(rb_ePGerror, "lo_read failed");
3816
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3805
3817
 
3806
3818
  if(ret == 0) {
3807
3819
  xfree(buffer);
@@ -3831,7 +3843,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3831
3843
  int ret;
3832
3844
 
3833
3845
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3834
- rb_raise(rb_ePGerror, "lo_lseek failed");
3846
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3835
3847
  }
3836
3848
 
3837
3849
  return INT2FIX(ret);
@@ -3851,7 +3863,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3851
3863
  int lo_desc = NUM2INT(in_lo_desc);
3852
3864
 
3853
3865
  if((position = lo_tell(conn, lo_desc)) < 0)
3854
- rb_raise(rb_ePGerror,"lo_tell failed");
3866
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3855
3867
 
3856
3868
  return INT2FIX(position);
3857
3869
  }
@@ -3870,7 +3882,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3870
3882
  size_t len = NUM2INT(in_len);
3871
3883
 
3872
3884
  if(lo_truncate(conn,lo_desc,len) < 0)
3873
- rb_raise(rb_ePGerror,"lo_truncate failed");
3885
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3874
3886
 
3875
3887
  return Qnil;
3876
3888
  }
@@ -3888,7 +3900,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3888
3900
  int lo_desc = NUM2INT(in_lo_desc);
3889
3901
 
3890
3902
  if(lo_close(conn,lo_desc) < 0)
3891
- rb_raise(rb_ePGerror,"lo_close failed");
3903
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3892
3904
 
3893
3905
  return Qnil;
3894
3906
  }
@@ -3906,7 +3918,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3906
3918
  Oid oid = NUM2UINT(in_oid);
3907
3919
 
3908
3920
  if(lo_unlink(conn,oid) < 0)
3909
- rb_raise(rb_ePGerror,"lo_unlink failed");
3921
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3910
3922
 
3911
3923
  return Qnil;
3912
3924
  }
@@ -4340,6 +4352,7 @@ init_pg_connection()
4340
4352
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4341
4353
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4342
4354
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4355
+ rb_define_singleton_method(rb_cPGconn, "conninfo_parse", pgconn_s_conninfo_parse, 1);
4343
4356
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4344
4357
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4345
4358
 
@@ -4357,6 +4370,9 @@ init_pg_connection()
4357
4370
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4358
4371
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4359
4372
  rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
4373
+ #if defined(HAVE_PQRESULTMEMORYSIZE)
4374
+ rb_define_method(rb_cPGconn, "hostaddr", pgconn_hostaddr, 0);
4375
+ #endif
4360
4376
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4361
4377
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4362
4378
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);