pg 1.3.5 → 1.4.3

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
  }
@@ -245,6 +266,7 @@ pgconn_s_allocate( VALUE klass )
245
266
  this->encoder_for_put_copy_data = Qnil;
246
267
  this->decoder_for_get_copy_data = Qnil;
247
268
  this->trace_stream = Qnil;
269
+ rb_ivar_set(self, rb_intern("@calls_to_put_copy_data"), INT2FIX(0));
248
270
 
249
271
  return self;
250
272
  }
@@ -254,7 +276,6 @@ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
254
276
  {
255
277
  t_pg_connection *this;
256
278
  VALUE conninfo;
257
- VALUE error;
258
279
  VALUE self = pgconn_s_allocate( klass );
259
280
 
260
281
  this = pg_get_connection( self );
@@ -262,13 +283,10 @@ pgconn_s_sync_connect(int argc, VALUE *argv, VALUE klass)
262
283
  this->pgconn = gvl_PQconnectdb(StringValueCStr(conninfo));
263
284
 
264
285
  if(this->pgconn == NULL)
265
- rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate structure");
286
+ rb_raise(rb_ePGerror, "PQconnectdb() unable to allocate PGconn structure");
266
287
 
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
- }
288
+ if (PQstatus(this->pgconn) == CONNECTION_BAD)
289
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(this->pgconn));
272
290
 
273
291
  pgconn_set_default_encoding( self );
274
292
 
@@ -301,7 +319,6 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
301
319
  {
302
320
  VALUE rb_conn;
303
321
  VALUE conninfo;
304
- VALUE error;
305
322
  t_pg_connection *this;
306
323
 
307
324
  /*
@@ -314,13 +331,10 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
314
331
  this->pgconn = gvl_PQconnectStart( StringValueCStr(conninfo) );
315
332
 
316
333
  if( this->pgconn == NULL )
317
- rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate structure");
334
+ rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate PGconn structure");
318
335
 
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
- }
336
+ if ( PQstatus(this->pgconn) == CONNECTION_BAD )
337
+ pg_raise_conn_error( rb_eConnectionBad, rb_conn, "%s", PQerrorMessage(this->pgconn));
324
338
 
325
339
  if ( rb_block_given_p() ) {
326
340
  return rb_ensure( rb_yield, rb_conn, pgconn_finish, rb_conn );
@@ -376,6 +390,36 @@ pgconn_s_conndefaults(VALUE self)
376
390
  return array;
377
391
  }
378
392
 
393
+ /*
394
+ * Document-method: PG::Connection.conninfo_parse
395
+ *
396
+ * call-seq:
397
+ * PG::Connection.conninfo_parse(conninfo_string) -> Array
398
+ *
399
+ * Returns parsed connection options from the provided connection string as an array of hashes.
400
+ * Each hash has the same keys as PG::Connection.conndefaults() .
401
+ * The values from the +conninfo_string+ are stored in the +:val+ key.
402
+ */
403
+ static VALUE
404
+ pgconn_s_conninfo_parse(VALUE self, VALUE conninfo)
405
+ {
406
+ VALUE array;
407
+ char *errmsg = NULL;
408
+ PQconninfoOption *options = PQconninfoParse(StringValueCStr(conninfo), &errmsg);
409
+ if(errmsg){
410
+ VALUE error = rb_str_new_cstr(errmsg);
411
+ PQfreemem(errmsg);
412
+ rb_raise(rb_ePGerror, "%"PRIsVALUE, error);
413
+ }
414
+ array = pgconn_make_conninfo_array( options );
415
+
416
+ PQconninfoFree(options);
417
+
418
+ UNUSED( self );
419
+
420
+ return array;
421
+ }
422
+
379
423
 
380
424
  #ifdef HAVE_PQENCRYPTPASSWORDCONN
381
425
  static VALUE
@@ -396,7 +440,7 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
396
440
  rval = rb_str_new2( encrypted );
397
441
  PQfreemem( encrypted );
398
442
  } else {
399
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
443
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
400
444
  }
401
445
 
402
446
  return rval;
@@ -537,7 +581,7 @@ pgconn_reset_start(VALUE self)
537
581
  {
538
582
  pgconn_close_socket_io( self );
539
583
  if(gvl_PQresetStart(pg_get_pgconn(self)) == 0)
540
- rb_raise(rb_eUnableToSend, "reset has failed");
584
+ pg_raise_conn_error( rb_eUnableToSend, self, "reset has failed");
541
585
  return Qnil;
542
586
  }
543
587
 
@@ -607,7 +651,18 @@ pgconn_pass(VALUE self)
607
651
  * call-seq:
608
652
  * conn.host()
609
653
  *
610
- * Returns the connected server name.
654
+ * Returns the server host name of the active connection.
655
+ * This can be a host name, an IP address, or a directory path if the connection is via Unix socket.
656
+ * (The path case can be distinguished because it will always be an absolute path, beginning with +/+ .)
657
+ *
658
+ * If the connection parameters specified both host and hostaddr, then +host+ will return the host information.
659
+ * If only hostaddr was specified, then that is returned.
660
+ * If multiple hosts were specified in the connection parameters, +host+ returns the host actually connected to.
661
+ *
662
+ * 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.
663
+ *
664
+ * 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.
665
+ * The status of the connection can be checked using the function Connection#status .
611
666
  */
612
667
  static VALUE
613
668
  pgconn_host(VALUE self)
@@ -617,6 +672,26 @@ pgconn_host(VALUE self)
617
672
  return rb_str_new2(host);
618
673
  }
619
674
 
675
+ /* PQhostaddr() appeared in PostgreSQL-12 together with PQresultMemorySize() */
676
+ #if defined(HAVE_PQRESULTMEMORYSIZE)
677
+ /*
678
+ * call-seq:
679
+ * conn.hostaddr()
680
+ *
681
+ * Returns the server IP address of the active connection.
682
+ * This can be the address that a host name resolved to, or an IP address provided through the hostaddr parameter.
683
+ * 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.
684
+ *
685
+ */
686
+ static VALUE
687
+ pgconn_hostaddr(VALUE self)
688
+ {
689
+ char *host = PQhostaddr(pg_get_pgconn(self));
690
+ if (!host) return Qnil;
691
+ return rb_str_new2(host);
692
+ }
693
+ #endif
694
+
620
695
  /*
621
696
  * call-seq:
622
697
  * conn.port()
@@ -687,6 +762,9 @@ pgconn_conninfo( VALUE self )
687
762
  * PG::Constants::CONNECTION_BAD
688
763
  *
689
764
  * ... and other constants of kind PG::Constants::CONNECTION_*
765
+ *
766
+ * Example:
767
+ * PG.constants.grep(/CONNECTION_/).find{|c| PG.const_get(c) == conn.status} # => :CONNECTION_OK
690
768
  */
691
769
  static VALUE
692
770
  pgconn_status(VALUE self)
@@ -811,7 +889,8 @@ pgconn_socket(VALUE self)
811
889
  pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
812
890
 
813
891
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
814
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
892
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
893
+
815
894
  return INT2NUM(sd);
816
895
  }
817
896
 
@@ -839,14 +918,15 @@ pgconn_socket_io(VALUE self)
839
918
  VALUE socket_io = this->socket_io;
840
919
 
841
920
  if ( !RTEST(socket_io) ) {
842
- if( (sd = PQsocket(this->pgconn)) < 0)
843
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
921
+ if( (sd = PQsocket(this->pgconn)) < 0){
922
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
923
+ }
844
924
 
845
925
  #ifdef _WIN32
846
926
  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
- }
927
+ if( ruby_sd == -1 )
928
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
929
+
850
930
  this->ruby_sd = ruby_sd;
851
931
  #else
852
932
  ruby_sd = sd;
@@ -911,7 +991,7 @@ pgconn_backend_key(VALUE self)
911
991
 
912
992
  cancel = (struct pg_cancel*)PQgetCancel(conn);
913
993
  if(cancel == NULL)
914
- rb_raise(rb_ePGerror,"Invalid connection!");
994
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
915
995
 
916
996
  if( cancel->be_pid != PQbackendPID(conn) )
917
997
  rb_raise(rb_ePGerror,"Unexpected binary struct layout - please file a bug report at ruby-pg!");
@@ -1540,9 +1620,9 @@ pgconn_s_escape(VALUE self, VALUE string)
1540
1620
  if( !singleton ) {
1541
1621
  size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1542
1622
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1543
- if(error) {
1544
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1545
- }
1623
+ if(error)
1624
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(pg_get_pgconn(self)));
1625
+
1546
1626
  } else {
1547
1627
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1548
1628
  }
@@ -1638,7 +1718,6 @@ pgconn_escape_literal(VALUE self, VALUE string)
1638
1718
  {
1639
1719
  t_pg_connection *this = pg_get_connection_safe( self );
1640
1720
  char *escaped = NULL;
1641
- VALUE error;
1642
1721
  VALUE result = Qnil;
1643
1722
  int enc_idx = this->enc_idx;
1644
1723
 
@@ -1649,12 +1728,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1649
1728
 
1650
1729
  escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1651
1730
  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
- }
1731
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1732
+
1658
1733
  result = rb_str_new2(escaped);
1659
1734
  PQfreemem(escaped);
1660
1735
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1677,7 +1752,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1677
1752
  {
1678
1753
  t_pg_connection *this = pg_get_connection_safe( self );
1679
1754
  char *escaped = NULL;
1680
- VALUE error;
1681
1755
  VALUE result = Qnil;
1682
1756
  int enc_idx = this->enc_idx;
1683
1757
 
@@ -1688,12 +1762,8 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1688
1762
 
1689
1763
  escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1690
1764
  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
- }
1765
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1766
+
1697
1767
  result = rb_str_new2(escaped);
1698
1768
  PQfreemem(escaped);
1699
1769
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1741,14 +1811,9 @@ static VALUE
1741
1811
  pgconn_set_single_row_mode(VALUE self)
1742
1812
  {
1743
1813
  PGconn *conn = pg_get_pgconn(self);
1744
- VALUE error;
1745
1814
 
1746
1815
  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
- }
1816
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1752
1817
 
1753
1818
  return self;
1754
1819
  }
@@ -1772,15 +1837,12 @@ static VALUE
1772
1837
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1773
1838
  {
1774
1839
  t_pg_connection *this = pg_get_connection_safe( self );
1775
- VALUE error;
1776
1840
 
1777
1841
  /* If called with no or nil parameters, use PQexec for compatibility */
1778
1842
  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
- }
1843
+ if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0)
1844
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1845
+
1784
1846
  pgconn_wait_for_flush( self );
1785
1847
  return Qnil;
1786
1848
  }
@@ -1837,7 +1899,6 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1837
1899
  t_pg_connection *this = pg_get_connection_safe( self );
1838
1900
  int result;
1839
1901
  VALUE command, in_res_fmt;
1840
- VALUE error;
1841
1902
  int nParams;
1842
1903
  int resultFormat;
1843
1904
  struct query_params_data paramsData = { this->enc_idx };
@@ -1854,11 +1915,9 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1854
1915
 
1855
1916
  free_query_params( &paramsData );
1856
1917
 
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
- }
1918
+ if(result == 0)
1919
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1920
+
1862
1921
  pgconn_wait_for_flush( self );
1863
1922
  return Qnil;
1864
1923
  }
@@ -1890,7 +1949,6 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1890
1949
  int result;
1891
1950
  VALUE name, command, in_paramtypes;
1892
1951
  VALUE param;
1893
- VALUE error;
1894
1952
  int i = 0;
1895
1953
  int nParams = 0;
1896
1954
  Oid *paramTypes = NULL;
@@ -1919,9 +1977,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1919
1977
  xfree(paramTypes);
1920
1978
 
1921
1979
  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);
1980
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1925
1981
  }
1926
1982
  pgconn_wait_for_flush( self );
1927
1983
  return Qnil;
@@ -1965,7 +2021,6 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1965
2021
  t_pg_connection *this = pg_get_connection_safe( self );
1966
2022
  int result;
1967
2023
  VALUE name, in_res_fmt;
1968
- VALUE error;
1969
2024
  int nParams;
1970
2025
  int resultFormat;
1971
2026
  struct query_params_data paramsData = { this->enc_idx };
@@ -1987,11 +2042,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1987
2042
 
1988
2043
  free_query_params( &paramsData );
1989
2044
 
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
- }
2045
+ if(result == 0)
2046
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2047
+
1995
2048
  pgconn_wait_for_flush( self );
1996
2049
  return Qnil;
1997
2050
  }
@@ -2006,14 +2059,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2006
2059
  static VALUE
2007
2060
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2008
2061
  {
2009
- VALUE error;
2010
2062
  t_pg_connection *this = pg_get_connection_safe( self );
2011
2063
  /* 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
- }
2064
+ if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0)
2065
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2066
+
2017
2067
  pgconn_wait_for_flush( self );
2018
2068
  return Qnil;
2019
2069
  }
@@ -2029,14 +2079,11 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2029
2079
  static VALUE
2030
2080
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2031
2081
  {
2032
- VALUE error;
2033
2082
  t_pg_connection *this = pg_get_connection_safe( self );
2034
2083
  /* 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
- }
2084
+ if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0)
2085
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2086
+
2040
2087
  pgconn_wait_for_flush( self );
2041
2088
  return Qnil;
2042
2089
  }
@@ -2069,18 +2116,15 @@ pgconn_sync_get_result(VALUE self)
2069
2116
  * or *notifies* to see if the state has changed.
2070
2117
  */
2071
2118
  static VALUE
2072
- pgconn_consume_input(self)
2073
- VALUE self;
2119
+ pgconn_consume_input(VALUE self)
2074
2120
  {
2075
- VALUE error;
2076
2121
  PGconn *conn = pg_get_pgconn(self);
2077
2122
  /* returns 0 on error */
2078
2123
  if(PQconsumeInput(conn) == 0) {
2079
2124
  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);
2125
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(conn));
2083
2126
  }
2127
+
2084
2128
  return Qnil;
2085
2129
  }
2086
2130
 
@@ -2092,18 +2136,15 @@ pgconn_consume_input(self)
2092
2136
  * #get_result would block. Otherwise returns +false+.
2093
2137
  */
2094
2138
  static VALUE
2095
- pgconn_is_busy(self)
2096
- VALUE self;
2139
+ pgconn_is_busy(VALUE self)
2097
2140
  {
2098
2141
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2099
2142
  }
2100
2143
 
2101
2144
  static VALUE
2102
- pgconn_sync_setnonblocking(self, state)
2103
- VALUE self, state;
2145
+ pgconn_sync_setnonblocking(VALUE self, VALUE state)
2104
2146
  {
2105
2147
  int arg;
2106
- VALUE error;
2107
2148
  PGconn *conn = pg_get_pgconn(self);
2108
2149
  if(state == Qtrue)
2109
2150
  arg = 1;
@@ -2112,18 +2153,15 @@ pgconn_sync_setnonblocking(self, state)
2112
2153
  else
2113
2154
  rb_raise(rb_eArgError, "Boolean value expected");
2114
2155
 
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
- }
2156
+ if(PQsetnonblocking(conn, arg) == -1)
2157
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2158
+
2120
2159
  return Qnil;
2121
2160
  }
2122
2161
 
2123
2162
 
2124
2163
  static VALUE
2125
- pgconn_sync_isnonblocking(self)
2126
- VALUE self;
2164
+ pgconn_sync_isnonblocking(VALUE self)
2127
2165
  {
2128
2166
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2129
2167
  }
@@ -2132,14 +2170,10 @@ static VALUE
2132
2170
  pgconn_sync_flush(VALUE self)
2133
2171
  {
2134
2172
  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
- }
2173
+ int ret = PQflush(conn);
2174
+ if(ret == -1)
2175
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2176
+
2143
2177
  return (ret) ? Qfalse : Qtrue;
2144
2178
  }
2145
2179
 
@@ -2153,7 +2187,7 @@ pgconn_sync_cancel(VALUE self)
2153
2187
 
2154
2188
  cancel = PQgetCancel(pg_get_pgconn(self));
2155
2189
  if(cancel == NULL)
2156
- rb_raise(rb_ePGerror,"Invalid connection!");
2190
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
2157
2191
 
2158
2192
  ret = gvl_PQcancel(cancel, errbuf, sizeof(errbuf));
2159
2193
  if(ret == 1)
@@ -2362,7 +2396,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2362
2396
 
2363
2397
  /* Is the given timeout valid? */
2364
2398
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2365
- VALUE socket_io = pgconn_socket_io(self);
2399
+ VALUE socket_io;
2400
+
2401
+ /* before we wait for data, make sure everything has been sent */
2402
+ pgconn_async_flush(self);
2403
+ if ((retval=is_readable(conn)))
2404
+ return retval;
2405
+
2406
+ socket_io = pgconn_socket_io(self);
2366
2407
  /* Wait for the socket to become readable before checking again */
2367
2408
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2368
2409
  } else {
@@ -2377,7 +2418,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2377
2418
  /* Check for connection errors (PQisBusy is true on connection errors) */
2378
2419
  if ( PQconsumeInput(conn) == 0 ){
2379
2420
  pgconn_close_socket_io(self);
2380
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2421
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2381
2422
  }
2382
2423
  }
2383
2424
 
@@ -2390,8 +2431,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2390
2431
  *
2391
2432
  * Attempts to flush any queued output data to the server.
2392
2433
  * Returns +true+ if data is successfully flushed, +false+
2393
- * if not (can only return +false+ if connection is
2394
- * nonblocking.
2434
+ * if not. It can only return +false+ if connection is
2435
+ * in nonblocking mode.
2395
2436
  * Raises PG::Error if some other failure occurred.
2396
2437
  */
2397
2438
  static VALUE
@@ -2527,11 +2568,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2527
2568
  Check_Type(buffer, T_STRING);
2528
2569
 
2529
2570
  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
- }
2571
+ if(ret == -1)
2572
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2573
+
2535
2574
  RB_GC_GUARD(intermediate);
2536
2575
  RB_GC_GUARD(buffer);
2537
2576
 
@@ -2542,7 +2581,6 @@ static VALUE
2542
2581
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2543
2582
  {
2544
2583
  VALUE str;
2545
- VALUE error;
2546
2584
  int ret;
2547
2585
  const char *error_message = NULL;
2548
2586
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2553,11 +2591,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2553
2591
  error_message = pg_cstr_enc(str, this->enc_idx);
2554
2592
 
2555
2593
  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
- }
2594
+ if(ret == -1)
2595
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2596
+
2561
2597
  return (ret) ? Qtrue : Qfalse;
2562
2598
  }
2563
2599
 
@@ -2565,7 +2601,6 @@ static VALUE
2565
2601
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2566
2602
  {
2567
2603
  VALUE async_in;
2568
- VALUE error;
2569
2604
  VALUE result;
2570
2605
  int ret;
2571
2606
  char *buffer;
@@ -2585,10 +2620,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2585
2620
  }
2586
2621
 
2587
2622
  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);
2623
+ if(ret == -2){ /* error */
2624
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2592
2625
  }
2593
2626
  if(ret == -1) { /* No data left */
2594
2627
  return Qnil;
@@ -2893,9 +2926,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2893
2926
 
2894
2927
  Check_Type(str, T_STRING);
2895
2928
 
2896
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2897
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2898
- }
2929
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2930
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2931
+
2899
2932
  pgconn_set_internal_encoding_index( self );
2900
2933
 
2901
2934
  return Qnil;
@@ -3528,11 +3561,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3528
3561
  {
3529
3562
  PGconn *conn = pg_get_pgconn(self);
3530
3563
  int res = PQenterPipelineMode(conn);
3531
- if( res == 1 ) {
3532
- return Qnil;
3533
- } else {
3534
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3535
- }
3564
+ if( res != 1 )
3565
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3566
+
3567
+ return Qnil;
3536
3568
  }
3537
3569
 
3538
3570
  /*
@@ -3551,11 +3583,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3551
3583
  {
3552
3584
  PGconn *conn = pg_get_pgconn(self);
3553
3585
  int res = PQexitPipelineMode(conn);
3554
- if( res == 1 ) {
3555
- return Qnil;
3556
- } else {
3557
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3558
- }
3586
+ if( res != 1 )
3587
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3588
+
3589
+ return Qnil;
3559
3590
  }
3560
3591
 
3561
3592
 
@@ -3575,11 +3606,10 @@ pgconn_pipeline_sync(VALUE self)
3575
3606
  {
3576
3607
  PGconn *conn = pg_get_pgconn(self);
3577
3608
  int res = PQpipelineSync(conn);
3578
- if( res == 1 ) {
3579
- return Qnil;
3580
- } else {
3581
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3582
- }
3609
+ if( res != 1 )
3610
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3611
+
3612
+ return Qnil;
3583
3613
  }
3584
3614
 
3585
3615
  /*
@@ -3599,11 +3629,10 @@ pgconn_send_flush_request(VALUE self)
3599
3629
  {
3600
3630
  PGconn *conn = pg_get_pgconn(self);
3601
3631
  int res = PQsendFlushRequest(conn);
3602
- if( res == 1 ) {
3603
- return Qnil;
3604
- } else {
3605
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3606
- }
3632
+ if( res != 1 )
3633
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3634
+
3635
+ return Qnil;
3607
3636
  }
3608
3637
 
3609
3638
  #endif
@@ -3634,7 +3663,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3634
3663
 
3635
3664
  lo_oid = lo_creat(conn, mode);
3636
3665
  if (lo_oid == 0)
3637
- rb_raise(rb_ePGerror, "lo_creat failed");
3666
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3638
3667
 
3639
3668
  return UINT2NUM(lo_oid);
3640
3669
  }
@@ -3655,7 +3684,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3655
3684
 
3656
3685
  ret = lo_create(conn, lo_oid);
3657
3686
  if (ret == InvalidOid)
3658
- rb_raise(rb_ePGerror, "lo_create failed");
3687
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3659
3688
 
3660
3689
  return UINT2NUM(ret);
3661
3690
  }
@@ -3679,7 +3708,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3679
3708
 
3680
3709
  lo_oid = lo_import(conn, StringValueCStr(filename));
3681
3710
  if (lo_oid == 0) {
3682
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3711
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3683
3712
  }
3684
3713
  return UINT2NUM(lo_oid);
3685
3714
  }
@@ -3700,7 +3729,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3700
3729
  oid = NUM2UINT(lo_oid);
3701
3730
 
3702
3731
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3703
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3732
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3704
3733
  }
3705
3734
  return Qnil;
3706
3735
  }
@@ -3731,7 +3760,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3731
3760
  mode = NUM2INT(nmode);
3732
3761
 
3733
3762
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3734
- rb_raise(rb_ePGerror, "can't open large object: %s", PQerrorMessage(conn));
3763
+ pg_raise_conn_error( rb_ePGerror, self, "can't open large object: %s", PQerrorMessage(conn));
3735
3764
  }
3736
3765
  return INT2FIX(fd);
3737
3766
  }
@@ -3753,11 +3782,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3753
3782
  Check_Type(buffer, T_STRING);
3754
3783
 
3755
3784
  if( RSTRING_LEN(buffer) < 0) {
3756
- rb_raise(rb_ePGerror, "write buffer zero string");
3785
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3757
3786
  }
3758
3787
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3759
3788
  RSTRING_LEN(buffer))) < 0) {
3760
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3789
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3761
3790
  }
3762
3791
 
3763
3792
  return INT2FIX(n);
@@ -3780,16 +3809,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3780
3809
  VALUE str;
3781
3810
  char *buffer;
3782
3811
 
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
- }
3812
+ if (len < 0)
3813
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3790
3814
 
3815
+ buffer = ALLOC_N(char, len);
3791
3816
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3792
- rb_raise(rb_ePGerror, "lo_read failed");
3817
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3793
3818
 
3794
3819
  if(ret == 0) {
3795
3820
  xfree(buffer);
@@ -3819,7 +3844,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3819
3844
  int ret;
3820
3845
 
3821
3846
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3822
- rb_raise(rb_ePGerror, "lo_lseek failed");
3847
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3823
3848
  }
3824
3849
 
3825
3850
  return INT2FIX(ret);
@@ -3839,7 +3864,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3839
3864
  int lo_desc = NUM2INT(in_lo_desc);
3840
3865
 
3841
3866
  if((position = lo_tell(conn, lo_desc)) < 0)
3842
- rb_raise(rb_ePGerror,"lo_tell failed");
3867
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3843
3868
 
3844
3869
  return INT2FIX(position);
3845
3870
  }
@@ -3858,7 +3883,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3858
3883
  size_t len = NUM2INT(in_len);
3859
3884
 
3860
3885
  if(lo_truncate(conn,lo_desc,len) < 0)
3861
- rb_raise(rb_ePGerror,"lo_truncate failed");
3886
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3862
3887
 
3863
3888
  return Qnil;
3864
3889
  }
@@ -3876,7 +3901,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3876
3901
  int lo_desc = NUM2INT(in_lo_desc);
3877
3902
 
3878
3903
  if(lo_close(conn,lo_desc) < 0)
3879
- rb_raise(rb_ePGerror,"lo_close failed");
3904
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3880
3905
 
3881
3906
  return Qnil;
3882
3907
  }
@@ -3894,7 +3919,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3894
3919
  Oid oid = NUM2UINT(in_oid);
3895
3920
 
3896
3921
  if(lo_unlink(conn,oid) < 0)
3897
- rb_raise(rb_ePGerror,"lo_unlink failed");
3922
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3898
3923
 
3899
3924
  return Qnil;
3900
3925
  }
@@ -4328,6 +4353,7 @@ init_pg_connection()
4328
4353
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4329
4354
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4330
4355
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4356
+ rb_define_singleton_method(rb_cPGconn, "conninfo_parse", pgconn_s_conninfo_parse, 1);
4331
4357
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4332
4358
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4333
4359
 
@@ -4345,6 +4371,9 @@ init_pg_connection()
4345
4371
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4346
4372
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4347
4373
  rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
4374
+ #if defined(HAVE_PQRESULTMEMORYSIZE)
4375
+ rb_define_method(rb_cPGconn, "hostaddr", pgconn_hostaddr, 0);
4376
+ #endif
4348
4377
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4349
4378
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4350
4379
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);