pg 1.3.5-x86-mingw32 → 1.4.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/pg_connection.c CHANGED
@@ -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;
@@ -537,7 +580,7 @@ pgconn_reset_start(VALUE self)
537
580
  {
538
581
  pgconn_close_socket_io( self );
539
582
  if(gvl_PQresetStart(pg_get_pgconn(self)) == 0)
540
- rb_raise(rb_eUnableToSend, "reset has failed");
583
+ pg_raise_conn_error( rb_eUnableToSend, self, "reset has failed");
541
584
  return Qnil;
542
585
  }
543
586
 
@@ -607,7 +650,18 @@ pgconn_pass(VALUE self)
607
650
  * call-seq:
608
651
  * conn.host()
609
652
  *
610
- * 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 .
611
665
  */
612
666
  static VALUE
613
667
  pgconn_host(VALUE self)
@@ -617,6 +671,26 @@ pgconn_host(VALUE self)
617
671
  return rb_str_new2(host);
618
672
  }
619
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
+
620
694
  /*
621
695
  * call-seq:
622
696
  * conn.port()
@@ -687,6 +761,9 @@ pgconn_conninfo( VALUE self )
687
761
  * PG::Constants::CONNECTION_BAD
688
762
  *
689
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
690
767
  */
691
768
  static VALUE
692
769
  pgconn_status(VALUE self)
@@ -811,7 +888,8 @@ pgconn_socket(VALUE self)
811
888
  pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
812
889
 
813
890
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
814
- 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
+
815
893
  return INT2NUM(sd);
816
894
  }
817
895
 
@@ -839,14 +917,15 @@ pgconn_socket_io(VALUE self)
839
917
  VALUE socket_io = this->socket_io;
840
918
 
841
919
  if ( !RTEST(socket_io) ) {
842
- if( (sd = PQsocket(this->pgconn)) < 0)
843
- 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
+ }
844
923
 
845
924
  #ifdef _WIN32
846
925
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
847
- if( ruby_sd == -1 ){
848
- rb_raise(rb_eConnectionBad, "Could not wrap win32 socket handle");
849
- }
926
+ if( ruby_sd == -1 )
927
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
928
+
850
929
  this->ruby_sd = ruby_sd;
851
930
  #else
852
931
  ruby_sd = sd;
@@ -911,7 +990,7 @@ pgconn_backend_key(VALUE self)
911
990
 
912
991
  cancel = (struct pg_cancel*)PQgetCancel(conn);
913
992
  if(cancel == NULL)
914
- rb_raise(rb_ePGerror,"Invalid connection!");
993
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
915
994
 
916
995
  if( cancel->be_pid != PQbackendPID(conn) )
917
996
  rb_raise(rb_ePGerror,"Unexpected binary struct layout - please file a bug report at ruby-pg!");
@@ -1540,9 +1619,9 @@ pgconn_s_escape(VALUE self, VALUE string)
1540
1619
  if( !singleton ) {
1541
1620
  size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1542
1621
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1543
- if(error) {
1544
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1545
- }
1622
+ if(error)
1623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(pg_get_pgconn(self)));
1624
+
1546
1625
  } else {
1547
1626
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1548
1627
  }
@@ -1638,7 +1717,6 @@ pgconn_escape_literal(VALUE self, VALUE string)
1638
1717
  {
1639
1718
  t_pg_connection *this = pg_get_connection_safe( self );
1640
1719
  char *escaped = NULL;
1641
- VALUE error;
1642
1720
  VALUE result = Qnil;
1643
1721
  int enc_idx = this->enc_idx;
1644
1722
 
@@ -1649,12 +1727,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1649
1727
 
1650
1728
  escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1651
1729
  if (escaped == NULL)
1652
- {
1653
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1654
- rb_iv_set(error, "@connection", self);
1655
- rb_exc_raise(error);
1656
- return Qnil;
1657
- }
1730
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1731
+
1658
1732
  result = rb_str_new2(escaped);
1659
1733
  PQfreemem(escaped);
1660
1734
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1677,7 +1751,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1677
1751
  {
1678
1752
  t_pg_connection *this = pg_get_connection_safe( self );
1679
1753
  char *escaped = NULL;
1680
- VALUE error;
1681
1754
  VALUE result = Qnil;
1682
1755
  int enc_idx = this->enc_idx;
1683
1756
 
@@ -1688,12 +1761,8 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1688
1761
 
1689
1762
  escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1690
1763
  if (escaped == NULL)
1691
- {
1692
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1693
- rb_iv_set(error, "@connection", self);
1694
- rb_exc_raise(error);
1695
- return Qnil;
1696
- }
1764
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1765
+
1697
1766
  result = rb_str_new2(escaped);
1698
1767
  PQfreemem(escaped);
1699
1768
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1741,14 +1810,9 @@ static VALUE
1741
1810
  pgconn_set_single_row_mode(VALUE self)
1742
1811
  {
1743
1812
  PGconn *conn = pg_get_pgconn(self);
1744
- VALUE error;
1745
1813
 
1746
1814
  if( PQsetSingleRowMode(conn) == 0 )
1747
- {
1748
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1749
- rb_iv_set(error, "@connection", self);
1750
- rb_exc_raise(error);
1751
- }
1815
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1752
1816
 
1753
1817
  return self;
1754
1818
  }
@@ -1772,15 +1836,12 @@ static VALUE
1772
1836
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1773
1837
  {
1774
1838
  t_pg_connection *this = pg_get_connection_safe( self );
1775
- VALUE error;
1776
1839
 
1777
1840
  /* If called with no or nil parameters, use PQexec for compatibility */
1778
1841
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1779
- if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0) {
1780
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1781
- rb_iv_set(error, "@connection", self);
1782
- rb_exc_raise(error);
1783
- }
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
+
1784
1845
  pgconn_wait_for_flush( self );
1785
1846
  return Qnil;
1786
1847
  }
@@ -1837,7 +1898,6 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1837
1898
  t_pg_connection *this = pg_get_connection_safe( self );
1838
1899
  int result;
1839
1900
  VALUE command, in_res_fmt;
1840
- VALUE error;
1841
1901
  int nParams;
1842
1902
  int resultFormat;
1843
1903
  struct query_params_data paramsData = { this->enc_idx };
@@ -1854,11 +1914,9 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1854
1914
 
1855
1915
  free_query_params( &paramsData );
1856
1916
 
1857
- if(result == 0) {
1858
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1859
- rb_iv_set(error, "@connection", self);
1860
- rb_exc_raise(error);
1861
- }
1917
+ if(result == 0)
1918
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1919
+
1862
1920
  pgconn_wait_for_flush( self );
1863
1921
  return Qnil;
1864
1922
  }
@@ -1890,7 +1948,6 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1890
1948
  int result;
1891
1949
  VALUE name, command, in_paramtypes;
1892
1950
  VALUE param;
1893
- VALUE error;
1894
1951
  int i = 0;
1895
1952
  int nParams = 0;
1896
1953
  Oid *paramTypes = NULL;
@@ -1919,9 +1976,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1919
1976
  xfree(paramTypes);
1920
1977
 
1921
1978
  if(result == 0) {
1922
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1923
- rb_iv_set(error, "@connection", self);
1924
- rb_exc_raise(error);
1979
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1925
1980
  }
1926
1981
  pgconn_wait_for_flush( self );
1927
1982
  return Qnil;
@@ -1965,7 +2020,6 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1965
2020
  t_pg_connection *this = pg_get_connection_safe( self );
1966
2021
  int result;
1967
2022
  VALUE name, in_res_fmt;
1968
- VALUE error;
1969
2023
  int nParams;
1970
2024
  int resultFormat;
1971
2025
  struct query_params_data paramsData = { this->enc_idx };
@@ -1987,11 +2041,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1987
2041
 
1988
2042
  free_query_params( &paramsData );
1989
2043
 
1990
- if(result == 0) {
1991
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1992
- rb_iv_set(error, "@connection", self);
1993
- rb_exc_raise(error);
1994
- }
2044
+ if(result == 0)
2045
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2046
+
1995
2047
  pgconn_wait_for_flush( self );
1996
2048
  return Qnil;
1997
2049
  }
@@ -2006,14 +2058,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2006
2058
  static VALUE
2007
2059
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2008
2060
  {
2009
- VALUE error;
2010
2061
  t_pg_connection *this = pg_get_connection_safe( self );
2011
2062
  /* returns 0 on failure */
2012
- if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0) {
2013
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2014
- rb_iv_set(error, "@connection", self);
2015
- rb_exc_raise(error);
2016
- }
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
+
2017
2066
  pgconn_wait_for_flush( self );
2018
2067
  return Qnil;
2019
2068
  }
@@ -2029,14 +2078,11 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2029
2078
  static VALUE
2030
2079
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2031
2080
  {
2032
- VALUE error;
2033
2081
  t_pg_connection *this = pg_get_connection_safe( self );
2034
2082
  /* returns 0 on failure */
2035
- if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
2036
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2037
- rb_iv_set(error, "@connection", self);
2038
- rb_exc_raise(error);
2039
- }
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
+
2040
2086
  pgconn_wait_for_flush( self );
2041
2087
  return Qnil;
2042
2088
  }
@@ -2069,18 +2115,15 @@ pgconn_sync_get_result(VALUE self)
2069
2115
  * or *notifies* to see if the state has changed.
2070
2116
  */
2071
2117
  static VALUE
2072
- pgconn_consume_input(self)
2073
- VALUE self;
2118
+ pgconn_consume_input(VALUE self)
2074
2119
  {
2075
- VALUE error;
2076
2120
  PGconn *conn = pg_get_pgconn(self);
2077
2121
  /* returns 0 on error */
2078
2122
  if(PQconsumeInput(conn) == 0) {
2079
2123
  pgconn_close_socket_io(self);
2080
- error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(conn));
2081
- rb_iv_set(error, "@connection", self);
2082
- rb_exc_raise(error);
2124
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(conn));
2083
2125
  }
2126
+
2084
2127
  return Qnil;
2085
2128
  }
2086
2129
 
@@ -2092,18 +2135,15 @@ pgconn_consume_input(self)
2092
2135
  * #get_result would block. Otherwise returns +false+.
2093
2136
  */
2094
2137
  static VALUE
2095
- pgconn_is_busy(self)
2096
- VALUE self;
2138
+ pgconn_is_busy(VALUE self)
2097
2139
  {
2098
2140
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2099
2141
  }
2100
2142
 
2101
2143
  static VALUE
2102
- pgconn_sync_setnonblocking(self, state)
2103
- VALUE self, state;
2144
+ pgconn_sync_setnonblocking(VALUE self, VALUE state)
2104
2145
  {
2105
2146
  int arg;
2106
- VALUE error;
2107
2147
  PGconn *conn = pg_get_pgconn(self);
2108
2148
  if(state == Qtrue)
2109
2149
  arg = 1;
@@ -2112,18 +2152,15 @@ pgconn_sync_setnonblocking(self, state)
2112
2152
  else
2113
2153
  rb_raise(rb_eArgError, "Boolean value expected");
2114
2154
 
2115
- if(PQsetnonblocking(conn, arg) == -1) {
2116
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2117
- rb_iv_set(error, "@connection", self);
2118
- rb_exc_raise(error);
2119
- }
2155
+ if(PQsetnonblocking(conn, arg) == -1)
2156
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2157
+
2120
2158
  return Qnil;
2121
2159
  }
2122
2160
 
2123
2161
 
2124
2162
  static VALUE
2125
- pgconn_sync_isnonblocking(self)
2126
- VALUE self;
2163
+ pgconn_sync_isnonblocking(VALUE self)
2127
2164
  {
2128
2165
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2129
2166
  }
@@ -2132,14 +2169,10 @@ static VALUE
2132
2169
  pgconn_sync_flush(VALUE self)
2133
2170
  {
2134
2171
  PGconn *conn = pg_get_pgconn(self);
2135
- int ret;
2136
- VALUE error;
2137
- ret = PQflush(conn);
2138
- if(ret == -1) {
2139
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2140
- rb_iv_set(error, "@connection", self);
2141
- rb_exc_raise(error);
2142
- }
2172
+ int ret = PQflush(conn);
2173
+ if(ret == -1)
2174
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2175
+
2143
2176
  return (ret) ? Qfalse : Qtrue;
2144
2177
  }
2145
2178
 
@@ -2153,7 +2186,7 @@ pgconn_sync_cancel(VALUE self)
2153
2186
 
2154
2187
  cancel = PQgetCancel(pg_get_pgconn(self));
2155
2188
  if(cancel == NULL)
2156
- rb_raise(rb_ePGerror,"Invalid connection!");
2189
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
2157
2190
 
2158
2191
  ret = gvl_PQcancel(cancel, errbuf, sizeof(errbuf));
2159
2192
  if(ret == 1)
@@ -2362,7 +2395,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2362
2395
 
2363
2396
  /* Is the given timeout valid? */
2364
2397
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2365
- VALUE socket_io = pgconn_socket_io(self);
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);
2366
2406
  /* Wait for the socket to become readable before checking again */
2367
2407
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2368
2408
  } else {
@@ -2377,7 +2417,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2377
2417
  /* Check for connection errors (PQisBusy is true on connection errors) */
2378
2418
  if ( PQconsumeInput(conn) == 0 ){
2379
2419
  pgconn_close_socket_io(self);
2380
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2420
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2381
2421
  }
2382
2422
  }
2383
2423
 
@@ -2390,8 +2430,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2390
2430
  *
2391
2431
  * Attempts to flush any queued output data to the server.
2392
2432
  * Returns +true+ if data is successfully flushed, +false+
2393
- * if not (can only return +false+ if connection is
2394
- * nonblocking.
2433
+ * if not. It can only return +false+ if connection is
2434
+ * in nonblocking mode.
2395
2435
  * Raises PG::Error if some other failure occurred.
2396
2436
  */
2397
2437
  static VALUE
@@ -2527,11 +2567,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2527
2567
  Check_Type(buffer, T_STRING);
2528
2568
 
2529
2569
  ret = gvl_PQputCopyData(this->pgconn, RSTRING_PTR(buffer), RSTRING_LENINT(buffer));
2530
- if(ret == -1) {
2531
- VALUE error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2532
- rb_iv_set(error, "@connection", self);
2533
- rb_exc_raise(error);
2534
- }
2570
+ if(ret == -1)
2571
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2572
+
2535
2573
  RB_GC_GUARD(intermediate);
2536
2574
  RB_GC_GUARD(buffer);
2537
2575
 
@@ -2542,7 +2580,6 @@ static VALUE
2542
2580
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2543
2581
  {
2544
2582
  VALUE str;
2545
- VALUE error;
2546
2583
  int ret;
2547
2584
  const char *error_message = NULL;
2548
2585
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2553,11 +2590,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2553
2590
  error_message = pg_cstr_enc(str, this->enc_idx);
2554
2591
 
2555
2592
  ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2556
- if(ret == -1) {
2557
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2558
- rb_iv_set(error, "@connection", self);
2559
- rb_exc_raise(error);
2560
- }
2593
+ if(ret == -1)
2594
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2595
+
2561
2596
  return (ret) ? Qtrue : Qfalse;
2562
2597
  }
2563
2598
 
@@ -2565,7 +2600,6 @@ static VALUE
2565
2600
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2566
2601
  {
2567
2602
  VALUE async_in;
2568
- VALUE error;
2569
2603
  VALUE result;
2570
2604
  int ret;
2571
2605
  char *buffer;
@@ -2585,10 +2619,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2585
2619
  }
2586
2620
 
2587
2621
  ret = gvl_PQgetCopyData(this->pgconn, &buffer, RTEST(async_in));
2588
- if(ret == -2) { /* error */
2589
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2590
- rb_iv_set(error, "@connection", self);
2591
- rb_exc_raise(error);
2622
+ if(ret == -2){ /* error */
2623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2592
2624
  }
2593
2625
  if(ret == -1) { /* No data left */
2594
2626
  return Qnil;
@@ -2893,9 +2925,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2893
2925
 
2894
2926
  Check_Type(str, T_STRING);
2895
2927
 
2896
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2897
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2898
- }
2928
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2929
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2930
+
2899
2931
  pgconn_set_internal_encoding_index( self );
2900
2932
 
2901
2933
  return Qnil;
@@ -3528,11 +3560,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3528
3560
  {
3529
3561
  PGconn *conn = pg_get_pgconn(self);
3530
3562
  int res = PQenterPipelineMode(conn);
3531
- if( res == 1 ) {
3532
- return Qnil;
3533
- } else {
3534
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3535
- }
3563
+ if( res != 1 )
3564
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3565
+
3566
+ return Qnil;
3536
3567
  }
3537
3568
 
3538
3569
  /*
@@ -3551,11 +3582,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3551
3582
  {
3552
3583
  PGconn *conn = pg_get_pgconn(self);
3553
3584
  int res = PQexitPipelineMode(conn);
3554
- if( res == 1 ) {
3555
- return Qnil;
3556
- } else {
3557
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3558
- }
3585
+ if( res != 1 )
3586
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3587
+
3588
+ return Qnil;
3559
3589
  }
3560
3590
 
3561
3591
 
@@ -3575,11 +3605,10 @@ pgconn_pipeline_sync(VALUE self)
3575
3605
  {
3576
3606
  PGconn *conn = pg_get_pgconn(self);
3577
3607
  int res = PQpipelineSync(conn);
3578
- if( res == 1 ) {
3579
- return Qnil;
3580
- } else {
3581
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3582
- }
3608
+ if( res != 1 )
3609
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3610
+
3611
+ return Qnil;
3583
3612
  }
3584
3613
 
3585
3614
  /*
@@ -3599,11 +3628,10 @@ pgconn_send_flush_request(VALUE self)
3599
3628
  {
3600
3629
  PGconn *conn = pg_get_pgconn(self);
3601
3630
  int res = PQsendFlushRequest(conn);
3602
- if( res == 1 ) {
3603
- return Qnil;
3604
- } else {
3605
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3606
- }
3631
+ if( res != 1 )
3632
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3633
+
3634
+ return Qnil;
3607
3635
  }
3608
3636
 
3609
3637
  #endif
@@ -3634,7 +3662,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3634
3662
 
3635
3663
  lo_oid = lo_creat(conn, mode);
3636
3664
  if (lo_oid == 0)
3637
- rb_raise(rb_ePGerror, "lo_creat failed");
3665
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3638
3666
 
3639
3667
  return UINT2NUM(lo_oid);
3640
3668
  }
@@ -3655,7 +3683,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3655
3683
 
3656
3684
  ret = lo_create(conn, lo_oid);
3657
3685
  if (ret == InvalidOid)
3658
- rb_raise(rb_ePGerror, "lo_create failed");
3686
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3659
3687
 
3660
3688
  return UINT2NUM(ret);
3661
3689
  }
@@ -3679,7 +3707,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3679
3707
 
3680
3708
  lo_oid = lo_import(conn, StringValueCStr(filename));
3681
3709
  if (lo_oid == 0) {
3682
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3710
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3683
3711
  }
3684
3712
  return UINT2NUM(lo_oid);
3685
3713
  }
@@ -3700,7 +3728,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3700
3728
  oid = NUM2UINT(lo_oid);
3701
3729
 
3702
3730
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3703
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3731
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3704
3732
  }
3705
3733
  return Qnil;
3706
3734
  }
@@ -3731,7 +3759,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3731
3759
  mode = NUM2INT(nmode);
3732
3760
 
3733
3761
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3734
- 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));
3735
3763
  }
3736
3764
  return INT2FIX(fd);
3737
3765
  }
@@ -3753,11 +3781,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3753
3781
  Check_Type(buffer, T_STRING);
3754
3782
 
3755
3783
  if( RSTRING_LEN(buffer) < 0) {
3756
- rb_raise(rb_ePGerror, "write buffer zero string");
3784
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3757
3785
  }
3758
3786
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3759
3787
  RSTRING_LEN(buffer))) < 0) {
3760
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3788
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3761
3789
  }
3762
3790
 
3763
3791
  return INT2FIX(n);
@@ -3780,16 +3808,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3780
3808
  VALUE str;
3781
3809
  char *buffer;
3782
3810
 
3783
- buffer = ALLOC_N(char, len);
3784
- if(buffer == NULL)
3785
- rb_raise(rb_eNoMemError, "ALLOC failed!");
3786
-
3787
- if (len < 0){
3788
- rb_raise(rb_ePGerror,"nagative length %d given", len);
3789
- }
3811
+ if (len < 0)
3812
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3790
3813
 
3814
+ buffer = ALLOC_N(char, len);
3791
3815
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3792
- rb_raise(rb_ePGerror, "lo_read failed");
3816
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3793
3817
 
3794
3818
  if(ret == 0) {
3795
3819
  xfree(buffer);
@@ -3819,7 +3843,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3819
3843
  int ret;
3820
3844
 
3821
3845
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3822
- rb_raise(rb_ePGerror, "lo_lseek failed");
3846
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3823
3847
  }
3824
3848
 
3825
3849
  return INT2FIX(ret);
@@ -3839,7 +3863,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3839
3863
  int lo_desc = NUM2INT(in_lo_desc);
3840
3864
 
3841
3865
  if((position = lo_tell(conn, lo_desc)) < 0)
3842
- rb_raise(rb_ePGerror,"lo_tell failed");
3866
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3843
3867
 
3844
3868
  return INT2FIX(position);
3845
3869
  }
@@ -3858,7 +3882,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3858
3882
  size_t len = NUM2INT(in_len);
3859
3883
 
3860
3884
  if(lo_truncate(conn,lo_desc,len) < 0)
3861
- rb_raise(rb_ePGerror,"lo_truncate failed");
3885
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3862
3886
 
3863
3887
  return Qnil;
3864
3888
  }
@@ -3876,7 +3900,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3876
3900
  int lo_desc = NUM2INT(in_lo_desc);
3877
3901
 
3878
3902
  if(lo_close(conn,lo_desc) < 0)
3879
- rb_raise(rb_ePGerror,"lo_close failed");
3903
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3880
3904
 
3881
3905
  return Qnil;
3882
3906
  }
@@ -3894,7 +3918,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3894
3918
  Oid oid = NUM2UINT(in_oid);
3895
3919
 
3896
3920
  if(lo_unlink(conn,oid) < 0)
3897
- rb_raise(rb_ePGerror,"lo_unlink failed");
3921
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3898
3922
 
3899
3923
  return Qnil;
3900
3924
  }
@@ -4328,6 +4352,7 @@ init_pg_connection()
4328
4352
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4329
4353
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4330
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);
4331
4356
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4332
4357
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4333
4358
 
@@ -4345,6 +4370,9 @@ init_pg_connection()
4345
4370
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4346
4371
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4347
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
4348
4376
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4349
4377
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4350
4378
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);