pg 1.3.5 → 1.4.5

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
  }
@@ -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()
@@ -627,7 +702,10 @@ static VALUE
627
702
  pgconn_port(VALUE self)
628
703
  {
629
704
  char* port = PQport(pg_get_pgconn(self));
630
- return INT2NUM(atoi(port));
705
+ if (!port || port[0] == '\0')
706
+ return INT2NUM(DEF_PGPORT);
707
+ else
708
+ return INT2NUM(atoi(port));
631
709
  }
632
710
 
633
711
  /*
@@ -687,6 +765,9 @@ pgconn_conninfo( VALUE self )
687
765
  * PG::Constants::CONNECTION_BAD
688
766
  *
689
767
  * ... and other constants of kind PG::Constants::CONNECTION_*
768
+ *
769
+ * Example:
770
+ * PG.constants.grep(/CONNECTION_/).find{|c| PG.const_get(c) == conn.status} # => :CONNECTION_OK
690
771
  */
691
772
  static VALUE
692
773
  pgconn_status(VALUE self)
@@ -811,7 +892,8 @@ pgconn_socket(VALUE self)
811
892
  pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
812
893
 
813
894
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
814
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
895
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
896
+
815
897
  return INT2NUM(sd);
816
898
  }
817
899
 
@@ -839,14 +921,15 @@ pgconn_socket_io(VALUE self)
839
921
  VALUE socket_io = this->socket_io;
840
922
 
841
923
  if ( !RTEST(socket_io) ) {
842
- if( (sd = PQsocket(this->pgconn)) < 0)
843
- rb_raise(rb_eConnectionBad, "PQsocket() can't get socket descriptor");
924
+ if( (sd = PQsocket(this->pgconn)) < 0){
925
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
926
+ }
844
927
 
845
928
  #ifdef _WIN32
846
929
  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
- }
930
+ if( ruby_sd == -1 )
931
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
932
+
850
933
  this->ruby_sd = ruby_sd;
851
934
  #else
852
935
  ruby_sd = sd;
@@ -911,7 +994,7 @@ pgconn_backend_key(VALUE self)
911
994
 
912
995
  cancel = (struct pg_cancel*)PQgetCancel(conn);
913
996
  if(cancel == NULL)
914
- rb_raise(rb_ePGerror,"Invalid connection!");
997
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
915
998
 
916
999
  if( cancel->be_pid != PQbackendPID(conn) )
917
1000
  rb_raise(rb_ePGerror,"Unexpected binary struct layout - please file a bug report at ruby-pg!");
@@ -1447,8 +1530,7 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1447
1530
  * It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
1448
1531
  */
1449
1532
  static VALUE
1450
- pgconn_sync_describe_portal(self, stmt_name)
1451
- VALUE self, stmt_name;
1533
+ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1452
1534
  {
1453
1535
  PGresult *result;
1454
1536
  VALUE rb_pgresult;
@@ -1540,9 +1622,9 @@ pgconn_s_escape(VALUE self, VALUE string)
1540
1622
  if( !singleton ) {
1541
1623
  size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1542
1624
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1543
- if(error) {
1544
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1545
- }
1625
+ if(error)
1626
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(pg_get_pgconn(self)));
1627
+
1546
1628
  } else {
1547
1629
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1548
1630
  }
@@ -1638,7 +1720,6 @@ pgconn_escape_literal(VALUE self, VALUE string)
1638
1720
  {
1639
1721
  t_pg_connection *this = pg_get_connection_safe( self );
1640
1722
  char *escaped = NULL;
1641
- VALUE error;
1642
1723
  VALUE result = Qnil;
1643
1724
  int enc_idx = this->enc_idx;
1644
1725
 
@@ -1649,12 +1730,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1649
1730
 
1650
1731
  escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1651
1732
  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
- }
1733
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1734
+
1658
1735
  result = rb_str_new2(escaped);
1659
1736
  PQfreemem(escaped);
1660
1737
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1677,7 +1754,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1677
1754
  {
1678
1755
  t_pg_connection *this = pg_get_connection_safe( self );
1679
1756
  char *escaped = NULL;
1680
- VALUE error;
1681
1757
  VALUE result = Qnil;
1682
1758
  int enc_idx = this->enc_idx;
1683
1759
 
@@ -1688,12 +1764,8 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1688
1764
 
1689
1765
  escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1690
1766
  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
- }
1767
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1768
+
1697
1769
  result = rb_str_new2(escaped);
1698
1770
  PQfreemem(escaped);
1699
1771
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1741,14 +1813,9 @@ static VALUE
1741
1813
  pgconn_set_single_row_mode(VALUE self)
1742
1814
  {
1743
1815
  PGconn *conn = pg_get_pgconn(self);
1744
- VALUE error;
1745
1816
 
1746
1817
  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
- }
1818
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1752
1819
 
1753
1820
  return self;
1754
1821
  }
@@ -1772,15 +1839,12 @@ static VALUE
1772
1839
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1773
1840
  {
1774
1841
  t_pg_connection *this = pg_get_connection_safe( self );
1775
- VALUE error;
1776
1842
 
1777
1843
  /* If called with no or nil parameters, use PQexec for compatibility */
1778
1844
  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
- }
1845
+ if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0)
1846
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1847
+
1784
1848
  pgconn_wait_for_flush( self );
1785
1849
  return Qnil;
1786
1850
  }
@@ -1837,7 +1901,6 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1837
1901
  t_pg_connection *this = pg_get_connection_safe( self );
1838
1902
  int result;
1839
1903
  VALUE command, in_res_fmt;
1840
- VALUE error;
1841
1904
  int nParams;
1842
1905
  int resultFormat;
1843
1906
  struct query_params_data paramsData = { this->enc_idx };
@@ -1854,11 +1917,9 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1854
1917
 
1855
1918
  free_query_params( &paramsData );
1856
1919
 
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
- }
1920
+ if(result == 0)
1921
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1922
+
1862
1923
  pgconn_wait_for_flush( self );
1863
1924
  return Qnil;
1864
1925
  }
@@ -1890,7 +1951,6 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1890
1951
  int result;
1891
1952
  VALUE name, command, in_paramtypes;
1892
1953
  VALUE param;
1893
- VALUE error;
1894
1954
  int i = 0;
1895
1955
  int nParams = 0;
1896
1956
  Oid *paramTypes = NULL;
@@ -1919,9 +1979,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1919
1979
  xfree(paramTypes);
1920
1980
 
1921
1981
  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);
1982
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1925
1983
  }
1926
1984
  pgconn_wait_for_flush( self );
1927
1985
  return Qnil;
@@ -1965,7 +2023,6 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1965
2023
  t_pg_connection *this = pg_get_connection_safe( self );
1966
2024
  int result;
1967
2025
  VALUE name, in_res_fmt;
1968
- VALUE error;
1969
2026
  int nParams;
1970
2027
  int resultFormat;
1971
2028
  struct query_params_data paramsData = { this->enc_idx };
@@ -1987,11 +2044,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1987
2044
 
1988
2045
  free_query_params( &paramsData );
1989
2046
 
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
- }
2047
+ if(result == 0)
2048
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2049
+
1995
2050
  pgconn_wait_for_flush( self );
1996
2051
  return Qnil;
1997
2052
  }
@@ -2006,14 +2061,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2006
2061
  static VALUE
2007
2062
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2008
2063
  {
2009
- VALUE error;
2010
2064
  t_pg_connection *this = pg_get_connection_safe( self );
2011
2065
  /* 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
- }
2066
+ if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0)
2067
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2068
+
2017
2069
  pgconn_wait_for_flush( self );
2018
2070
  return Qnil;
2019
2071
  }
@@ -2029,14 +2081,11 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2029
2081
  static VALUE
2030
2082
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2031
2083
  {
2032
- VALUE error;
2033
2084
  t_pg_connection *this = pg_get_connection_safe( self );
2034
2085
  /* 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
- }
2086
+ if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0)
2087
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2088
+
2040
2089
  pgconn_wait_for_flush( self );
2041
2090
  return Qnil;
2042
2091
  }
@@ -2069,18 +2118,15 @@ pgconn_sync_get_result(VALUE self)
2069
2118
  * or *notifies* to see if the state has changed.
2070
2119
  */
2071
2120
  static VALUE
2072
- pgconn_consume_input(self)
2073
- VALUE self;
2121
+ pgconn_consume_input(VALUE self)
2074
2122
  {
2075
- VALUE error;
2076
2123
  PGconn *conn = pg_get_pgconn(self);
2077
2124
  /* returns 0 on error */
2078
2125
  if(PQconsumeInput(conn) == 0) {
2079
2126
  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);
2127
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(conn));
2083
2128
  }
2129
+
2084
2130
  return Qnil;
2085
2131
  }
2086
2132
 
@@ -2092,18 +2138,15 @@ pgconn_consume_input(self)
2092
2138
  * #get_result would block. Otherwise returns +false+.
2093
2139
  */
2094
2140
  static VALUE
2095
- pgconn_is_busy(self)
2096
- VALUE self;
2141
+ pgconn_is_busy(VALUE self)
2097
2142
  {
2098
2143
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2099
2144
  }
2100
2145
 
2101
2146
  static VALUE
2102
- pgconn_sync_setnonblocking(self, state)
2103
- VALUE self, state;
2147
+ pgconn_sync_setnonblocking(VALUE self, VALUE state)
2104
2148
  {
2105
2149
  int arg;
2106
- VALUE error;
2107
2150
  PGconn *conn = pg_get_pgconn(self);
2108
2151
  if(state == Qtrue)
2109
2152
  arg = 1;
@@ -2112,18 +2155,15 @@ pgconn_sync_setnonblocking(self, state)
2112
2155
  else
2113
2156
  rb_raise(rb_eArgError, "Boolean value expected");
2114
2157
 
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
- }
2158
+ if(PQsetnonblocking(conn, arg) == -1)
2159
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2160
+
2120
2161
  return Qnil;
2121
2162
  }
2122
2163
 
2123
2164
 
2124
2165
  static VALUE
2125
- pgconn_sync_isnonblocking(self)
2126
- VALUE self;
2166
+ pgconn_sync_isnonblocking(VALUE self)
2127
2167
  {
2128
2168
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2129
2169
  }
@@ -2132,14 +2172,10 @@ static VALUE
2132
2172
  pgconn_sync_flush(VALUE self)
2133
2173
  {
2134
2174
  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
- }
2175
+ int ret = PQflush(conn);
2176
+ if(ret == -1)
2177
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2178
+
2143
2179
  return (ret) ? Qfalse : Qtrue;
2144
2180
  }
2145
2181
 
@@ -2153,7 +2189,7 @@ pgconn_sync_cancel(VALUE self)
2153
2189
 
2154
2190
  cancel = PQgetCancel(pg_get_pgconn(self));
2155
2191
  if(cancel == NULL)
2156
- rb_raise(rb_ePGerror,"Invalid connection!");
2192
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
2157
2193
 
2158
2194
  ret = gvl_PQcancel(cancel, errbuf, sizeof(errbuf));
2159
2195
  if(ret == 1)
@@ -2362,7 +2398,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2362
2398
 
2363
2399
  /* Is the given timeout valid? */
2364
2400
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2365
- VALUE socket_io = pgconn_socket_io(self);
2401
+ VALUE socket_io;
2402
+
2403
+ /* before we wait for data, make sure everything has been sent */
2404
+ pgconn_async_flush(self);
2405
+ if ((retval=is_readable(conn)))
2406
+ return retval;
2407
+
2408
+ socket_io = pgconn_socket_io(self);
2366
2409
  /* Wait for the socket to become readable before checking again */
2367
2410
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2368
2411
  } else {
@@ -2377,7 +2420,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2377
2420
  /* Check for connection errors (PQisBusy is true on connection errors) */
2378
2421
  if ( PQconsumeInput(conn) == 0 ){
2379
2422
  pgconn_close_socket_io(self);
2380
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2423
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2381
2424
  }
2382
2425
  }
2383
2426
 
@@ -2390,8 +2433,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2390
2433
  *
2391
2434
  * Attempts to flush any queued output data to the server.
2392
2435
  * Returns +true+ if data is successfully flushed, +false+
2393
- * if not (can only return +false+ if connection is
2394
- * nonblocking.
2436
+ * if not. It can only return +false+ if connection is
2437
+ * in nonblocking mode.
2395
2438
  * Raises PG::Error if some other failure occurred.
2396
2439
  */
2397
2440
  static VALUE
@@ -2527,11 +2570,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2527
2570
  Check_Type(buffer, T_STRING);
2528
2571
 
2529
2572
  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
- }
2573
+ if(ret == -1)
2574
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2575
+
2535
2576
  RB_GC_GUARD(intermediate);
2536
2577
  RB_GC_GUARD(buffer);
2537
2578
 
@@ -2542,7 +2583,6 @@ static VALUE
2542
2583
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2543
2584
  {
2544
2585
  VALUE str;
2545
- VALUE error;
2546
2586
  int ret;
2547
2587
  const char *error_message = NULL;
2548
2588
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2553,11 +2593,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2553
2593
  error_message = pg_cstr_enc(str, this->enc_idx);
2554
2594
 
2555
2595
  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
- }
2596
+ if(ret == -1)
2597
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2598
+
2561
2599
  return (ret) ? Qtrue : Qfalse;
2562
2600
  }
2563
2601
 
@@ -2565,7 +2603,6 @@ static VALUE
2565
2603
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2566
2604
  {
2567
2605
  VALUE async_in;
2568
- VALUE error;
2569
2606
  VALUE result;
2570
2607
  int ret;
2571
2608
  char *buffer;
@@ -2585,10 +2622,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2585
2622
  }
2586
2623
 
2587
2624
  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);
2625
+ if(ret == -2){ /* error */
2626
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2592
2627
  }
2593
2628
  if(ret == -1) { /* No data left */
2594
2629
  return Qnil;
@@ -2893,9 +2928,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2893
2928
 
2894
2929
  Check_Type(str, T_STRING);
2895
2930
 
2896
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2897
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2898
- }
2931
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2932
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2933
+
2899
2934
  pgconn_set_internal_encoding_index( self );
2900
2935
 
2901
2936
  return Qnil;
@@ -3528,11 +3563,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3528
3563
  {
3529
3564
  PGconn *conn = pg_get_pgconn(self);
3530
3565
  int res = PQenterPipelineMode(conn);
3531
- if( res == 1 ) {
3532
- return Qnil;
3533
- } else {
3534
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3535
- }
3566
+ if( res != 1 )
3567
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3568
+
3569
+ return Qnil;
3536
3570
  }
3537
3571
 
3538
3572
  /*
@@ -3551,11 +3585,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3551
3585
  {
3552
3586
  PGconn *conn = pg_get_pgconn(self);
3553
3587
  int res = PQexitPipelineMode(conn);
3554
- if( res == 1 ) {
3555
- return Qnil;
3556
- } else {
3557
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3558
- }
3588
+ if( res != 1 )
3589
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3590
+
3591
+ return Qnil;
3559
3592
  }
3560
3593
 
3561
3594
 
@@ -3575,11 +3608,10 @@ pgconn_pipeline_sync(VALUE self)
3575
3608
  {
3576
3609
  PGconn *conn = pg_get_pgconn(self);
3577
3610
  int res = PQpipelineSync(conn);
3578
- if( res == 1 ) {
3579
- return Qnil;
3580
- } else {
3581
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3582
- }
3611
+ if( res != 1 )
3612
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3613
+
3614
+ return Qnil;
3583
3615
  }
3584
3616
 
3585
3617
  /*
@@ -3599,11 +3631,10 @@ pgconn_send_flush_request(VALUE self)
3599
3631
  {
3600
3632
  PGconn *conn = pg_get_pgconn(self);
3601
3633
  int res = PQsendFlushRequest(conn);
3602
- if( res == 1 ) {
3603
- return Qnil;
3604
- } else {
3605
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3606
- }
3634
+ if( res != 1 )
3635
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3636
+
3637
+ return Qnil;
3607
3638
  }
3608
3639
 
3609
3640
  #endif
@@ -3634,7 +3665,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3634
3665
 
3635
3666
  lo_oid = lo_creat(conn, mode);
3636
3667
  if (lo_oid == 0)
3637
- rb_raise(rb_ePGerror, "lo_creat failed");
3668
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3638
3669
 
3639
3670
  return UINT2NUM(lo_oid);
3640
3671
  }
@@ -3655,7 +3686,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3655
3686
 
3656
3687
  ret = lo_create(conn, lo_oid);
3657
3688
  if (ret == InvalidOid)
3658
- rb_raise(rb_ePGerror, "lo_create failed");
3689
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3659
3690
 
3660
3691
  return UINT2NUM(ret);
3661
3692
  }
@@ -3679,7 +3710,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3679
3710
 
3680
3711
  lo_oid = lo_import(conn, StringValueCStr(filename));
3681
3712
  if (lo_oid == 0) {
3682
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3713
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3683
3714
  }
3684
3715
  return UINT2NUM(lo_oid);
3685
3716
  }
@@ -3700,7 +3731,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3700
3731
  oid = NUM2UINT(lo_oid);
3701
3732
 
3702
3733
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3703
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3734
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3704
3735
  }
3705
3736
  return Qnil;
3706
3737
  }
@@ -3731,7 +3762,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3731
3762
  mode = NUM2INT(nmode);
3732
3763
 
3733
3764
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3734
- rb_raise(rb_ePGerror, "can't open large object: %s", PQerrorMessage(conn));
3765
+ pg_raise_conn_error( rb_ePGerror, self, "can't open large object: %s", PQerrorMessage(conn));
3735
3766
  }
3736
3767
  return INT2FIX(fd);
3737
3768
  }
@@ -3753,11 +3784,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3753
3784
  Check_Type(buffer, T_STRING);
3754
3785
 
3755
3786
  if( RSTRING_LEN(buffer) < 0) {
3756
- rb_raise(rb_ePGerror, "write buffer zero string");
3787
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3757
3788
  }
3758
3789
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3759
3790
  RSTRING_LEN(buffer))) < 0) {
3760
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3791
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3761
3792
  }
3762
3793
 
3763
3794
  return INT2FIX(n);
@@ -3780,16 +3811,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3780
3811
  VALUE str;
3781
3812
  char *buffer;
3782
3813
 
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
- }
3814
+ if (len < 0)
3815
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3790
3816
 
3817
+ buffer = ALLOC_N(char, len);
3791
3818
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3792
- rb_raise(rb_ePGerror, "lo_read failed");
3819
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3793
3820
 
3794
3821
  if(ret == 0) {
3795
3822
  xfree(buffer);
@@ -3819,7 +3846,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3819
3846
  int ret;
3820
3847
 
3821
3848
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3822
- rb_raise(rb_ePGerror, "lo_lseek failed");
3849
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3823
3850
  }
3824
3851
 
3825
3852
  return INT2FIX(ret);
@@ -3839,7 +3866,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3839
3866
  int lo_desc = NUM2INT(in_lo_desc);
3840
3867
 
3841
3868
  if((position = lo_tell(conn, lo_desc)) < 0)
3842
- rb_raise(rb_ePGerror,"lo_tell failed");
3869
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3843
3870
 
3844
3871
  return INT2FIX(position);
3845
3872
  }
@@ -3858,7 +3885,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3858
3885
  size_t len = NUM2INT(in_len);
3859
3886
 
3860
3887
  if(lo_truncate(conn,lo_desc,len) < 0)
3861
- rb_raise(rb_ePGerror,"lo_truncate failed");
3888
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3862
3889
 
3863
3890
  return Qnil;
3864
3891
  }
@@ -3876,7 +3903,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3876
3903
  int lo_desc = NUM2INT(in_lo_desc);
3877
3904
 
3878
3905
  if(lo_close(conn,lo_desc) < 0)
3879
- rb_raise(rb_ePGerror,"lo_close failed");
3906
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3880
3907
 
3881
3908
  return Qnil;
3882
3909
  }
@@ -3894,7 +3921,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3894
3921
  Oid oid = NUM2UINT(in_oid);
3895
3922
 
3896
3923
  if(lo_unlink(conn,oid) < 0)
3897
- rb_raise(rb_ePGerror,"lo_unlink failed");
3924
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3898
3925
 
3899
3926
  return Qnil;
3900
3927
  }
@@ -4301,7 +4328,7 @@ pgconn_field_name_type_get(VALUE self)
4301
4328
  * Document-class: PG::Connection
4302
4329
  */
4303
4330
  void
4304
- init_pg_connection()
4331
+ init_pg_connection(void)
4305
4332
  {
4306
4333
  s_id_encode = rb_intern("encode");
4307
4334
  s_id_autoclose_set = rb_intern("autoclose=");
@@ -4328,6 +4355,7 @@ init_pg_connection()
4328
4355
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4329
4356
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4330
4357
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4358
+ rb_define_singleton_method(rb_cPGconn, "conninfo_parse", pgconn_s_conninfo_parse, 1);
4331
4359
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4332
4360
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4333
4361
 
@@ -4345,6 +4373,9 @@ init_pg_connection()
4345
4373
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4346
4374
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4347
4375
  rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
4376
+ #if defined(HAVE_PQRESULTMEMORYSIZE)
4377
+ rb_define_method(rb_cPGconn, "hostaddr", pgconn_hostaddr, 0);
4378
+ #endif
4348
4379
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4349
4380
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4350
4381
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);