pg 1.3.3-x86-mingw32 → 1.4.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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)
@@ -2343,21 +2375,12 @@ pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2343
2375
  static void *
2344
2376
  wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)(PGconn *))
2345
2377
  {
2346
- VALUE socket_io;
2347
2378
  VALUE ret;
2348
2379
  void *retval;
2349
2380
  struct timeval aborttime={0,0}, currtime, waittime;
2350
2381
  VALUE wait_timeout = Qnil;
2351
2382
  PGconn *conn = pg_get_pgconn(self);
2352
2383
 
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
2384
  if ( ptimeout ) {
2362
2385
  gettimeofday(&currtime, NULL);
2363
2386
  timeradd(&currtime, ptimeout, &aborttime);
@@ -2372,6 +2395,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2372
2395
 
2373
2396
  /* Is the given timeout valid? */
2374
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);
2375
2406
  /* Wait for the socket to become readable before checking again */
2376
2407
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2377
2408
  } else {
@@ -2386,7 +2417,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2386
2417
  /* Check for connection errors (PQisBusy is true on connection errors) */
2387
2418
  if ( PQconsumeInput(conn) == 0 ){
2388
2419
  pgconn_close_socket_io(self);
2389
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2420
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2390
2421
  }
2391
2422
  }
2392
2423
 
@@ -2399,8 +2430,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2399
2430
  *
2400
2431
  * Attempts to flush any queued output data to the server.
2401
2432
  * Returns +true+ if data is successfully flushed, +false+
2402
- * if not (can only return +false+ if connection is
2403
- * nonblocking.
2433
+ * if not. It can only return +false+ if connection is
2434
+ * in nonblocking mode.
2404
2435
  * Raises PG::Error if some other failure occurred.
2405
2436
  */
2406
2437
  static VALUE
@@ -2536,11 +2567,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2536
2567
  Check_Type(buffer, T_STRING);
2537
2568
 
2538
2569
  ret = gvl_PQputCopyData(this->pgconn, RSTRING_PTR(buffer), RSTRING_LENINT(buffer));
2539
- if(ret == -1) {
2540
- VALUE error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2541
- rb_iv_set(error, "@connection", self);
2542
- rb_exc_raise(error);
2543
- }
2570
+ if(ret == -1)
2571
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2572
+
2544
2573
  RB_GC_GUARD(intermediate);
2545
2574
  RB_GC_GUARD(buffer);
2546
2575
 
@@ -2551,7 +2580,6 @@ static VALUE
2551
2580
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2552
2581
  {
2553
2582
  VALUE str;
2554
- VALUE error;
2555
2583
  int ret;
2556
2584
  const char *error_message = NULL;
2557
2585
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2562,11 +2590,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2562
2590
  error_message = pg_cstr_enc(str, this->enc_idx);
2563
2591
 
2564
2592
  ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2565
- if(ret == -1) {
2566
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2567
- rb_iv_set(error, "@connection", self);
2568
- rb_exc_raise(error);
2569
- }
2593
+ if(ret == -1)
2594
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2595
+
2570
2596
  return (ret) ? Qtrue : Qfalse;
2571
2597
  }
2572
2598
 
@@ -2574,7 +2600,6 @@ static VALUE
2574
2600
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2575
2601
  {
2576
2602
  VALUE async_in;
2577
- VALUE error;
2578
2603
  VALUE result;
2579
2604
  int ret;
2580
2605
  char *buffer;
@@ -2594,10 +2619,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2594
2619
  }
2595
2620
 
2596
2621
  ret = gvl_PQgetCopyData(this->pgconn, &buffer, RTEST(async_in));
2597
- if(ret == -2) { /* error */
2598
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2599
- rb_iv_set(error, "@connection", self);
2600
- rb_exc_raise(error);
2622
+ if(ret == -2){ /* error */
2623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2601
2624
  }
2602
2625
  if(ret == -1) { /* No data left */
2603
2626
  return Qnil;
@@ -2902,9 +2925,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2902
2925
 
2903
2926
  Check_Type(str, T_STRING);
2904
2927
 
2905
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2906
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2907
- }
2928
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2929
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2930
+
2908
2931
  pgconn_set_internal_encoding_index( self );
2909
2932
 
2910
2933
  return Qnil;
@@ -2984,7 +3007,7 @@ get_result_readable(PGconn *conn)
2984
3007
  * If +true+ is returned, +conn.is_busy+ will return +false+
2985
3008
  * and +conn.get_result+ will not block.
2986
3009
  */
2987
- static VALUE
3010
+ VALUE
2988
3011
  pgconn_block( int argc, VALUE *argv, VALUE self ) {
2989
3012
  struct timeval timeout;
2990
3013
  struct timeval *ptimeout = NULL;
@@ -3072,7 +3095,8 @@ pgconn_async_get_last_result(VALUE self)
3072
3095
  for(;;) {
3073
3096
  int status;
3074
3097
 
3075
- 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);
3076
3100
 
3077
3101
  cur = gvl_PQgetResult(conn);
3078
3102
  if (cur == NULL)
@@ -3536,11 +3560,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3536
3560
  {
3537
3561
  PGconn *conn = pg_get_pgconn(self);
3538
3562
  int res = PQenterPipelineMode(conn);
3539
- if( res == 1 ) {
3540
- return Qnil;
3541
- } else {
3542
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3543
- }
3563
+ if( res != 1 )
3564
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3565
+
3566
+ return Qnil;
3544
3567
  }
3545
3568
 
3546
3569
  /*
@@ -3559,11 +3582,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3559
3582
  {
3560
3583
  PGconn *conn = pg_get_pgconn(self);
3561
3584
  int res = PQexitPipelineMode(conn);
3562
- if( res == 1 ) {
3563
- return Qnil;
3564
- } else {
3565
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3566
- }
3585
+ if( res != 1 )
3586
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3587
+
3588
+ return Qnil;
3567
3589
  }
3568
3590
 
3569
3591
 
@@ -3583,11 +3605,10 @@ pgconn_pipeline_sync(VALUE self)
3583
3605
  {
3584
3606
  PGconn *conn = pg_get_pgconn(self);
3585
3607
  int res = PQpipelineSync(conn);
3586
- if( res == 1 ) {
3587
- return Qnil;
3588
- } else {
3589
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3590
- }
3608
+ if( res != 1 )
3609
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3610
+
3611
+ return Qnil;
3591
3612
  }
3592
3613
 
3593
3614
  /*
@@ -3607,11 +3628,10 @@ pgconn_send_flush_request(VALUE self)
3607
3628
  {
3608
3629
  PGconn *conn = pg_get_pgconn(self);
3609
3630
  int res = PQsendFlushRequest(conn);
3610
- if( res == 1 ) {
3611
- return Qnil;
3612
- } else {
3613
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3614
- }
3631
+ if( res != 1 )
3632
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3633
+
3634
+ return Qnil;
3615
3635
  }
3616
3636
 
3617
3637
  #endif
@@ -3642,7 +3662,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3642
3662
 
3643
3663
  lo_oid = lo_creat(conn, mode);
3644
3664
  if (lo_oid == 0)
3645
- rb_raise(rb_ePGerror, "lo_creat failed");
3665
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3646
3666
 
3647
3667
  return UINT2NUM(lo_oid);
3648
3668
  }
@@ -3663,7 +3683,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3663
3683
 
3664
3684
  ret = lo_create(conn, lo_oid);
3665
3685
  if (ret == InvalidOid)
3666
- rb_raise(rb_ePGerror, "lo_create failed");
3686
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3667
3687
 
3668
3688
  return UINT2NUM(ret);
3669
3689
  }
@@ -3687,7 +3707,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3687
3707
 
3688
3708
  lo_oid = lo_import(conn, StringValueCStr(filename));
3689
3709
  if (lo_oid == 0) {
3690
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3710
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3691
3711
  }
3692
3712
  return UINT2NUM(lo_oid);
3693
3713
  }
@@ -3708,7 +3728,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3708
3728
  oid = NUM2UINT(lo_oid);
3709
3729
 
3710
3730
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3711
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3731
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3712
3732
  }
3713
3733
  return Qnil;
3714
3734
  }
@@ -3739,7 +3759,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3739
3759
  mode = NUM2INT(nmode);
3740
3760
 
3741
3761
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3742
- 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));
3743
3763
  }
3744
3764
  return INT2FIX(fd);
3745
3765
  }
@@ -3761,11 +3781,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3761
3781
  Check_Type(buffer, T_STRING);
3762
3782
 
3763
3783
  if( RSTRING_LEN(buffer) < 0) {
3764
- rb_raise(rb_ePGerror, "write buffer zero string");
3784
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3765
3785
  }
3766
3786
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3767
3787
  RSTRING_LEN(buffer))) < 0) {
3768
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3788
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3769
3789
  }
3770
3790
 
3771
3791
  return INT2FIX(n);
@@ -3788,16 +3808,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3788
3808
  VALUE str;
3789
3809
  char *buffer;
3790
3810
 
3791
- buffer = ALLOC_N(char, len);
3792
- if(buffer == NULL)
3793
- rb_raise(rb_eNoMemError, "ALLOC failed!");
3794
-
3795
- if (len < 0){
3796
- rb_raise(rb_ePGerror,"nagative length %d given", len);
3797
- }
3811
+ if (len < 0)
3812
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3798
3813
 
3814
+ buffer = ALLOC_N(char, len);
3799
3815
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3800
- rb_raise(rb_ePGerror, "lo_read failed");
3816
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3801
3817
 
3802
3818
  if(ret == 0) {
3803
3819
  xfree(buffer);
@@ -3827,7 +3843,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3827
3843
  int ret;
3828
3844
 
3829
3845
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3830
- rb_raise(rb_ePGerror, "lo_lseek failed");
3846
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3831
3847
  }
3832
3848
 
3833
3849
  return INT2FIX(ret);
@@ -3847,7 +3863,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3847
3863
  int lo_desc = NUM2INT(in_lo_desc);
3848
3864
 
3849
3865
  if((position = lo_tell(conn, lo_desc)) < 0)
3850
- rb_raise(rb_ePGerror,"lo_tell failed");
3866
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3851
3867
 
3852
3868
  return INT2FIX(position);
3853
3869
  }
@@ -3866,7 +3882,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3866
3882
  size_t len = NUM2INT(in_len);
3867
3883
 
3868
3884
  if(lo_truncate(conn,lo_desc,len) < 0)
3869
- rb_raise(rb_ePGerror,"lo_truncate failed");
3885
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3870
3886
 
3871
3887
  return Qnil;
3872
3888
  }
@@ -3884,7 +3900,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3884
3900
  int lo_desc = NUM2INT(in_lo_desc);
3885
3901
 
3886
3902
  if(lo_close(conn,lo_desc) < 0)
3887
- rb_raise(rb_ePGerror,"lo_close failed");
3903
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3888
3904
 
3889
3905
  return Qnil;
3890
3906
  }
@@ -3902,7 +3918,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3902
3918
  Oid oid = NUM2UINT(in_oid);
3903
3919
 
3904
3920
  if(lo_unlink(conn,oid) < 0)
3905
- rb_raise(rb_ePGerror,"lo_unlink failed");
3921
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3906
3922
 
3907
3923
  return Qnil;
3908
3924
  }
@@ -4336,6 +4352,7 @@ init_pg_connection()
4336
4352
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4337
4353
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4338
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);
4339
4356
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4340
4357
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4341
4358
 
@@ -4353,6 +4370,9 @@ init_pg_connection()
4353
4370
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4354
4371
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4355
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
4356
4376
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4357
4377
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4358
4378
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);