pg 1.3.4-x86-mingw32 → 1.4.1-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;
@@ -450,17 +493,18 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
450
493
  * the asynchronous connection is ready
451
494
  *
452
495
  * Example:
453
- * conn = PG::Connection.connect_start("dbname=mydatabase")
454
- * socket = conn.socket_io
496
+ * require "io/wait"
497
+ *
498
+ * conn = PG::Connection.connect_start(dbname: 'mydatabase')
455
499
  * status = conn.connect_poll
456
500
  * while(status != PG::PGRES_POLLING_OK) do
457
501
  * # do some work while waiting for the connection to complete
458
502
  * if(status == PG::PGRES_POLLING_READING)
459
- * if(not select([socket], [], [], 10.0))
503
+ * unless conn.socket_io.wait_readable(10.0)
460
504
  * raise "Asynchronous connection timed out!"
461
505
  * end
462
506
  * elsif(status == PG::PGRES_POLLING_WRITING)
463
- * if(not select([], [socket], [], 10.0))
507
+ * unless conn.socket_io.wait_writable(10.0)
464
508
  * raise "Asynchronous connection timed out!"
465
509
  * end
466
510
  * end
@@ -536,7 +580,7 @@ pgconn_reset_start(VALUE self)
536
580
  {
537
581
  pgconn_close_socket_io( self );
538
582
  if(gvl_PQresetStart(pg_get_pgconn(self)) == 0)
539
- rb_raise(rb_eUnableToSend, "reset has failed");
583
+ pg_raise_conn_error( rb_eUnableToSend, self, "reset has failed");
540
584
  return Qnil;
541
585
  }
542
586
 
@@ -606,7 +650,18 @@ pgconn_pass(VALUE self)
606
650
  * call-seq:
607
651
  * conn.host()
608
652
  *
609
- * 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 .
610
665
  */
611
666
  static VALUE
612
667
  pgconn_host(VALUE self)
@@ -616,6 +671,26 @@ pgconn_host(VALUE self)
616
671
  return rb_str_new2(host);
617
672
  }
618
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
+
619
694
  /*
620
695
  * call-seq:
621
696
  * conn.port()
@@ -686,6 +761,9 @@ pgconn_conninfo( VALUE self )
686
761
  * PG::Constants::CONNECTION_BAD
687
762
  *
688
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
689
767
  */
690
768
  static VALUE
691
769
  pgconn_status(VALUE self)
@@ -810,7 +888,8 @@ pgconn_socket(VALUE self)
810
888
  pg_deprecated(4, ("conn.socket is deprecated and should be replaced by conn.socket_io"));
811
889
 
812
890
  if( (sd = PQsocket(pg_get_pgconn(self))) < 0)
813
- 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
+
814
893
  return INT2NUM(sd);
815
894
  }
816
895
 
@@ -818,13 +897,15 @@ pgconn_socket(VALUE self)
818
897
  * call-seq:
819
898
  * conn.socket_io() -> IO
820
899
  *
821
- * Fetch a memorized IO object created from the Connection's underlying socket.
822
- * This object can be used for IO.select to wait for events while running
823
- * asynchronous API calls.
900
+ * Fetch an IO object created from the Connection's underlying socket.
901
+ * This object can be used per <tt>socket_io.wait_readable</tt>, <tt>socket_io.wait_writable</tt> or for <tt>IO.select</tt> to wait for events while running asynchronous API calls.
902
+ * <tt>IO#wait_*able</tt> is is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
903
+ *
904
+ * The IO object can change while the connection is established, but is memorized afterwards.
905
+ * So be sure not to cache the IO object, but repeat calling <tt>conn.socket_io</tt> instead.
824
906
  *
825
- * Using this instead of #socket avoids the problem of the underlying connection
826
- * being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt>
827
- * goes out of scope. In contrast to #socket, it also works on Windows.
907
+ * Using this method also works on Windows in contrast to using #socket .
908
+ * It also avoids the problem of the underlying connection being closed by Ruby when an IO created using <tt>IO.for_fd(conn.socket)</tt> goes out of scope.
828
909
  */
829
910
  static VALUE
830
911
  pgconn_socket_io(VALUE self)
@@ -836,14 +917,15 @@ pgconn_socket_io(VALUE self)
836
917
  VALUE socket_io = this->socket_io;
837
918
 
838
919
  if ( !RTEST(socket_io) ) {
839
- if( (sd = PQsocket(this->pgconn)) < 0)
840
- 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
+ }
841
923
 
842
924
  #ifdef _WIN32
843
925
  ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
844
- if( ruby_sd == -1 ){
845
- rb_raise(rb_eConnectionBad, "Could not wrap win32 socket handle");
846
- }
926
+ if( ruby_sd == -1 )
927
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
928
+
847
929
  this->ruby_sd = ruby_sd;
848
930
  #else
849
931
  ruby_sd = sd;
@@ -908,7 +990,7 @@ pgconn_backend_key(VALUE self)
908
990
 
909
991
  cancel = (struct pg_cancel*)PQgetCancel(conn);
910
992
  if(cancel == NULL)
911
- rb_raise(rb_ePGerror,"Invalid connection!");
993
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
912
994
 
913
995
  if( cancel->be_pid != PQbackendPID(conn) )
914
996
  rb_raise(rb_ePGerror,"Unexpected binary struct layout - please file a bug report at ruby-pg!");
@@ -1537,9 +1619,9 @@ pgconn_s_escape(VALUE self, VALUE string)
1537
1619
  if( !singleton ) {
1538
1620
  size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1539
1621
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1540
- if(error) {
1541
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1542
- }
1622
+ if(error)
1623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(pg_get_pgconn(self)));
1624
+
1543
1625
  } else {
1544
1626
  size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1545
1627
  }
@@ -1635,7 +1717,6 @@ pgconn_escape_literal(VALUE self, VALUE string)
1635
1717
  {
1636
1718
  t_pg_connection *this = pg_get_connection_safe( self );
1637
1719
  char *escaped = NULL;
1638
- VALUE error;
1639
1720
  VALUE result = Qnil;
1640
1721
  int enc_idx = this->enc_idx;
1641
1722
 
@@ -1646,12 +1727,8 @@ pgconn_escape_literal(VALUE self, VALUE string)
1646
1727
 
1647
1728
  escaped = PQescapeLiteral(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1648
1729
  if (escaped == NULL)
1649
- {
1650
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1651
- rb_iv_set(error, "@connection", self);
1652
- rb_exc_raise(error);
1653
- return Qnil;
1654
- }
1730
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1731
+
1655
1732
  result = rb_str_new2(escaped);
1656
1733
  PQfreemem(escaped);
1657
1734
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1674,7 +1751,6 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1674
1751
  {
1675
1752
  t_pg_connection *this = pg_get_connection_safe( self );
1676
1753
  char *escaped = NULL;
1677
- VALUE error;
1678
1754
  VALUE result = Qnil;
1679
1755
  int enc_idx = this->enc_idx;
1680
1756
 
@@ -1685,12 +1761,8 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1685
1761
 
1686
1762
  escaped = PQescapeIdentifier(this->pgconn, RSTRING_PTR(string), RSTRING_LEN(string));
1687
1763
  if (escaped == NULL)
1688
- {
1689
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
1690
- rb_iv_set(error, "@connection", self);
1691
- rb_exc_raise(error);
1692
- return Qnil;
1693
- }
1764
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
1765
+
1694
1766
  result = rb_str_new2(escaped);
1695
1767
  PQfreemem(escaped);
1696
1768
  PG_ENCODING_SET_NOCHECK(result, enc_idx);
@@ -1738,14 +1810,9 @@ static VALUE
1738
1810
  pgconn_set_single_row_mode(VALUE self)
1739
1811
  {
1740
1812
  PGconn *conn = pg_get_pgconn(self);
1741
- VALUE error;
1742
1813
 
1743
1814
  if( PQsetSingleRowMode(conn) == 0 )
1744
- {
1745
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
1746
- rb_iv_set(error, "@connection", self);
1747
- rb_exc_raise(error);
1748
- }
1815
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1749
1816
 
1750
1817
  return self;
1751
1818
  }
@@ -1769,15 +1836,12 @@ static VALUE
1769
1836
  pgconn_send_query(int argc, VALUE *argv, VALUE self)
1770
1837
  {
1771
1838
  t_pg_connection *this = pg_get_connection_safe( self );
1772
- VALUE error;
1773
1839
 
1774
1840
  /* If called with no or nil parameters, use PQexec for compatibility */
1775
1841
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1776
- if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0) {
1777
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1778
- rb_iv_set(error, "@connection", self);
1779
- rb_exc_raise(error);
1780
- }
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
+
1781
1845
  pgconn_wait_for_flush( self );
1782
1846
  return Qnil;
1783
1847
  }
@@ -1834,7 +1898,6 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1834
1898
  t_pg_connection *this = pg_get_connection_safe( self );
1835
1899
  int result;
1836
1900
  VALUE command, in_res_fmt;
1837
- VALUE error;
1838
1901
  int nParams;
1839
1902
  int resultFormat;
1840
1903
  struct query_params_data paramsData = { this->enc_idx };
@@ -1851,11 +1914,9 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1851
1914
 
1852
1915
  free_query_params( &paramsData );
1853
1916
 
1854
- if(result == 0) {
1855
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1856
- rb_iv_set(error, "@connection", self);
1857
- rb_exc_raise(error);
1858
- }
1917
+ if(result == 0)
1918
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1919
+
1859
1920
  pgconn_wait_for_flush( self );
1860
1921
  return Qnil;
1861
1922
  }
@@ -1887,7 +1948,6 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1887
1948
  int result;
1888
1949
  VALUE name, command, in_paramtypes;
1889
1950
  VALUE param;
1890
- VALUE error;
1891
1951
  int i = 0;
1892
1952
  int nParams = 0;
1893
1953
  Oid *paramTypes = NULL;
@@ -1916,9 +1976,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1916
1976
  xfree(paramTypes);
1917
1977
 
1918
1978
  if(result == 0) {
1919
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1920
- rb_iv_set(error, "@connection", self);
1921
- rb_exc_raise(error);
1979
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1922
1980
  }
1923
1981
  pgconn_wait_for_flush( self );
1924
1982
  return Qnil;
@@ -1962,7 +2020,6 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1962
2020
  t_pg_connection *this = pg_get_connection_safe( self );
1963
2021
  int result;
1964
2022
  VALUE name, in_res_fmt;
1965
- VALUE error;
1966
2023
  int nParams;
1967
2024
  int resultFormat;
1968
2025
  struct query_params_data paramsData = { this->enc_idx };
@@ -1984,11 +2041,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1984
2041
 
1985
2042
  free_query_params( &paramsData );
1986
2043
 
1987
- if(result == 0) {
1988
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
1989
- rb_iv_set(error, "@connection", self);
1990
- rb_exc_raise(error);
1991
- }
2044
+ if(result == 0)
2045
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2046
+
1992
2047
  pgconn_wait_for_flush( self );
1993
2048
  return Qnil;
1994
2049
  }
@@ -2003,14 +2058,11 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2003
2058
  static VALUE
2004
2059
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2005
2060
  {
2006
- VALUE error;
2007
2061
  t_pg_connection *this = pg_get_connection_safe( self );
2008
2062
  /* returns 0 on failure */
2009
- if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0) {
2010
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2011
- rb_iv_set(error, "@connection", self);
2012
- rb_exc_raise(error);
2013
- }
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
+
2014
2066
  pgconn_wait_for_flush( self );
2015
2067
  return Qnil;
2016
2068
  }
@@ -2026,14 +2078,11 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2026
2078
  static VALUE
2027
2079
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2028
2080
  {
2029
- VALUE error;
2030
2081
  t_pg_connection *this = pg_get_connection_safe( self );
2031
2082
  /* returns 0 on failure */
2032
- if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0) {
2033
- error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(this->pgconn));
2034
- rb_iv_set(error, "@connection", self);
2035
- rb_exc_raise(error);
2036
- }
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
+
2037
2086
  pgconn_wait_for_flush( self );
2038
2087
  return Qnil;
2039
2088
  }
@@ -2066,18 +2115,15 @@ pgconn_sync_get_result(VALUE self)
2066
2115
  * or *notifies* to see if the state has changed.
2067
2116
  */
2068
2117
  static VALUE
2069
- pgconn_consume_input(self)
2070
- VALUE self;
2118
+ pgconn_consume_input(VALUE self)
2071
2119
  {
2072
- VALUE error;
2073
2120
  PGconn *conn = pg_get_pgconn(self);
2074
2121
  /* returns 0 on error */
2075
2122
  if(PQconsumeInput(conn) == 0) {
2076
2123
  pgconn_close_socket_io(self);
2077
- error = rb_exc_new2(rb_eConnectionBad, PQerrorMessage(conn));
2078
- rb_iv_set(error, "@connection", self);
2079
- rb_exc_raise(error);
2124
+ pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(conn));
2080
2125
  }
2126
+
2081
2127
  return Qnil;
2082
2128
  }
2083
2129
 
@@ -2089,18 +2135,15 @@ pgconn_consume_input(self)
2089
2135
  * #get_result would block. Otherwise returns +false+.
2090
2136
  */
2091
2137
  static VALUE
2092
- pgconn_is_busy(self)
2093
- VALUE self;
2138
+ pgconn_is_busy(VALUE self)
2094
2139
  {
2095
2140
  return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2096
2141
  }
2097
2142
 
2098
2143
  static VALUE
2099
- pgconn_sync_setnonblocking(self, state)
2100
- VALUE self, state;
2144
+ pgconn_sync_setnonblocking(VALUE self, VALUE state)
2101
2145
  {
2102
2146
  int arg;
2103
- VALUE error;
2104
2147
  PGconn *conn = pg_get_pgconn(self);
2105
2148
  if(state == Qtrue)
2106
2149
  arg = 1;
@@ -2109,18 +2152,15 @@ pgconn_sync_setnonblocking(self, state)
2109
2152
  else
2110
2153
  rb_raise(rb_eArgError, "Boolean value expected");
2111
2154
 
2112
- if(PQsetnonblocking(conn, arg) == -1) {
2113
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2114
- rb_iv_set(error, "@connection", self);
2115
- rb_exc_raise(error);
2116
- }
2155
+ if(PQsetnonblocking(conn, arg) == -1)
2156
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2157
+
2117
2158
  return Qnil;
2118
2159
  }
2119
2160
 
2120
2161
 
2121
2162
  static VALUE
2122
- pgconn_sync_isnonblocking(self)
2123
- VALUE self;
2163
+ pgconn_sync_isnonblocking(VALUE self)
2124
2164
  {
2125
2165
  return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse;
2126
2166
  }
@@ -2129,14 +2169,10 @@ static VALUE
2129
2169
  pgconn_sync_flush(VALUE self)
2130
2170
  {
2131
2171
  PGconn *conn = pg_get_pgconn(self);
2132
- int ret;
2133
- VALUE error;
2134
- ret = PQflush(conn);
2135
- if(ret == -1) {
2136
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
2137
- rb_iv_set(error, "@connection", self);
2138
- rb_exc_raise(error);
2139
- }
2172
+ int ret = PQflush(conn);
2173
+ if(ret == -1)
2174
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2175
+
2140
2176
  return (ret) ? Qfalse : Qtrue;
2141
2177
  }
2142
2178
 
@@ -2150,7 +2186,7 @@ pgconn_sync_cancel(VALUE self)
2150
2186
 
2151
2187
  cancel = PQgetCancel(pg_get_pgconn(self));
2152
2188
  if(cancel == NULL)
2153
- rb_raise(rb_ePGerror,"Invalid connection!");
2189
+ pg_raise_conn_error( rb_ePGerror, self, "Invalid connection!");
2154
2190
 
2155
2191
  ret = gvl_PQcancel(cancel, errbuf, sizeof(errbuf));
2156
2192
  if(ret == 1)
@@ -2359,7 +2395,14 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2359
2395
 
2360
2396
  /* Is the given timeout valid? */
2361
2397
  if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
2362
- 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);
2363
2406
  /* Wait for the socket to become readable before checking again */
2364
2407
  ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
2365
2408
  } else {
@@ -2374,7 +2417,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2374
2417
  /* Check for connection errors (PQisBusy is true on connection errors) */
2375
2418
  if ( PQconsumeInput(conn) == 0 ){
2376
2419
  pgconn_close_socket_io(self);
2377
- rb_raise( rb_eConnectionBad, "PQconsumeInput() %s", PQerrorMessage(conn) );
2420
+ pg_raise_conn_error(rb_eConnectionBad, self, "PQconsumeInput() %s", PQerrorMessage(conn));
2378
2421
  }
2379
2422
  }
2380
2423
 
@@ -2387,8 +2430,8 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
2387
2430
  *
2388
2431
  * Attempts to flush any queued output data to the server.
2389
2432
  * Returns +true+ if data is successfully flushed, +false+
2390
- * if not (can only return +false+ if connection is
2391
- * nonblocking.
2433
+ * if not. It can only return +false+ if connection is
2434
+ * in nonblocking mode.
2392
2435
  * Raises PG::Error if some other failure occurred.
2393
2436
  */
2394
2437
  static VALUE
@@ -2524,11 +2567,9 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2524
2567
  Check_Type(buffer, T_STRING);
2525
2568
 
2526
2569
  ret = gvl_PQputCopyData(this->pgconn, RSTRING_PTR(buffer), RSTRING_LENINT(buffer));
2527
- if(ret == -1) {
2528
- VALUE error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2529
- rb_iv_set(error, "@connection", self);
2530
- rb_exc_raise(error);
2531
- }
2570
+ if(ret == -1)
2571
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2572
+
2532
2573
  RB_GC_GUARD(intermediate);
2533
2574
  RB_GC_GUARD(buffer);
2534
2575
 
@@ -2539,7 +2580,6 @@ static VALUE
2539
2580
  pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2540
2581
  {
2541
2582
  VALUE str;
2542
- VALUE error;
2543
2583
  int ret;
2544
2584
  const char *error_message = NULL;
2545
2585
  t_pg_connection *this = pg_get_connection_safe( self );
@@ -2550,11 +2590,9 @@ pgconn_sync_put_copy_end(int argc, VALUE *argv, VALUE self)
2550
2590
  error_message = pg_cstr_enc(str, this->enc_idx);
2551
2591
 
2552
2592
  ret = gvl_PQputCopyEnd(this->pgconn, error_message);
2553
- if(ret == -1) {
2554
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2555
- rb_iv_set(error, "@connection", self);
2556
- rb_exc_raise(error);
2557
- }
2593
+ if(ret == -1)
2594
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2595
+
2558
2596
  return (ret) ? Qtrue : Qfalse;
2559
2597
  }
2560
2598
 
@@ -2562,7 +2600,6 @@ static VALUE
2562
2600
  pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2563
2601
  {
2564
2602
  VALUE async_in;
2565
- VALUE error;
2566
2603
  VALUE result;
2567
2604
  int ret;
2568
2605
  char *buffer;
@@ -2582,10 +2619,8 @@ pgconn_sync_get_copy_data(int argc, VALUE *argv, VALUE self )
2582
2619
  }
2583
2620
 
2584
2621
  ret = gvl_PQgetCopyData(this->pgconn, &buffer, RTEST(async_in));
2585
- if(ret == -2) { /* error */
2586
- error = rb_exc_new2(rb_ePGerror, PQerrorMessage(this->pgconn));
2587
- rb_iv_set(error, "@connection", self);
2588
- rb_exc_raise(error);
2622
+ if(ret == -2){ /* error */
2623
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2589
2624
  }
2590
2625
  if(ret == -1) { /* No data left */
2591
2626
  return Qnil;
@@ -2890,9 +2925,9 @@ pgconn_sync_set_client_encoding(VALUE self, VALUE str)
2890
2925
 
2891
2926
  Check_Type(str, T_STRING);
2892
2927
 
2893
- if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 ) {
2894
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
2895
- }
2928
+ if ( (gvl_PQsetClientEncoding(conn, StringValueCStr(str))) == -1 )
2929
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
2930
+
2896
2931
  pgconn_set_internal_encoding_index( self );
2897
2932
 
2898
2933
  return Qnil;
@@ -3525,11 +3560,10 @@ pgconn_enter_pipeline_mode(VALUE self)
3525
3560
  {
3526
3561
  PGconn *conn = pg_get_pgconn(self);
3527
3562
  int res = PQenterPipelineMode(conn);
3528
- if( res == 1 ) {
3529
- return Qnil;
3530
- } else {
3531
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3532
- }
3563
+ if( res != 1 )
3564
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3565
+
3566
+ return Qnil;
3533
3567
  }
3534
3568
 
3535
3569
  /*
@@ -3548,11 +3582,10 @@ pgconn_exit_pipeline_mode(VALUE self)
3548
3582
  {
3549
3583
  PGconn *conn = pg_get_pgconn(self);
3550
3584
  int res = PQexitPipelineMode(conn);
3551
- if( res == 1 ) {
3552
- return Qnil;
3553
- } else {
3554
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3555
- }
3585
+ if( res != 1 )
3586
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3587
+
3588
+ return Qnil;
3556
3589
  }
3557
3590
 
3558
3591
 
@@ -3572,11 +3605,10 @@ pgconn_pipeline_sync(VALUE self)
3572
3605
  {
3573
3606
  PGconn *conn = pg_get_pgconn(self);
3574
3607
  int res = PQpipelineSync(conn);
3575
- if( res == 1 ) {
3576
- return Qnil;
3577
- } else {
3578
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3579
- }
3608
+ if( res != 1 )
3609
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3610
+
3611
+ return Qnil;
3580
3612
  }
3581
3613
 
3582
3614
  /*
@@ -3596,11 +3628,10 @@ pgconn_send_flush_request(VALUE self)
3596
3628
  {
3597
3629
  PGconn *conn = pg_get_pgconn(self);
3598
3630
  int res = PQsendFlushRequest(conn);
3599
- if( res == 1 ) {
3600
- return Qnil;
3601
- } else {
3602
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3603
- }
3631
+ if( res != 1 )
3632
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3633
+
3634
+ return Qnil;
3604
3635
  }
3605
3636
 
3606
3637
  #endif
@@ -3631,7 +3662,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3631
3662
 
3632
3663
  lo_oid = lo_creat(conn, mode);
3633
3664
  if (lo_oid == 0)
3634
- rb_raise(rb_ePGerror, "lo_creat failed");
3665
+ pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3635
3666
 
3636
3667
  return UINT2NUM(lo_oid);
3637
3668
  }
@@ -3652,7 +3683,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
3652
3683
 
3653
3684
  ret = lo_create(conn, lo_oid);
3654
3685
  if (ret == InvalidOid)
3655
- rb_raise(rb_ePGerror, "lo_create failed");
3686
+ pg_raise_conn_error( rb_ePGerror, self, "lo_create failed");
3656
3687
 
3657
3688
  return UINT2NUM(ret);
3658
3689
  }
@@ -3676,7 +3707,7 @@ pgconn_loimport(VALUE self, VALUE filename)
3676
3707
 
3677
3708
  lo_oid = lo_import(conn, StringValueCStr(filename));
3678
3709
  if (lo_oid == 0) {
3679
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3710
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3680
3711
  }
3681
3712
  return UINT2NUM(lo_oid);
3682
3713
  }
@@ -3697,7 +3728,7 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3697
3728
  oid = NUM2UINT(lo_oid);
3698
3729
 
3699
3730
  if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3700
- rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn));
3731
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3701
3732
  }
3702
3733
  return Qnil;
3703
3734
  }
@@ -3728,7 +3759,7 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3728
3759
  mode = NUM2INT(nmode);
3729
3760
 
3730
3761
  if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3731
- 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));
3732
3763
  }
3733
3764
  return INT2FIX(fd);
3734
3765
  }
@@ -3750,11 +3781,11 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3750
3781
  Check_Type(buffer, T_STRING);
3751
3782
 
3752
3783
  if( RSTRING_LEN(buffer) < 0) {
3753
- rb_raise(rb_ePGerror, "write buffer zero string");
3784
+ pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3754
3785
  }
3755
3786
  if((n = lo_write(conn, fd, StringValuePtr(buffer),
3756
3787
  RSTRING_LEN(buffer))) < 0) {
3757
- rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn));
3788
+ pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3758
3789
  }
3759
3790
 
3760
3791
  return INT2FIX(n);
@@ -3777,16 +3808,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3777
3808
  VALUE str;
3778
3809
  char *buffer;
3779
3810
 
3780
- buffer = ALLOC_N(char, len);
3781
- if(buffer == NULL)
3782
- rb_raise(rb_eNoMemError, "ALLOC failed!");
3783
-
3784
- if (len < 0){
3785
- rb_raise(rb_ePGerror,"nagative length %d given", len);
3786
- }
3811
+ if (len < 0)
3812
+ pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3787
3813
 
3814
+ buffer = ALLOC_N(char, len);
3788
3815
  if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3789
- rb_raise(rb_ePGerror, "lo_read failed");
3816
+ pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3790
3817
 
3791
3818
  if(ret == 0) {
3792
3819
  xfree(buffer);
@@ -3816,7 +3843,7 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3816
3843
  int ret;
3817
3844
 
3818
3845
  if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3819
- rb_raise(rb_ePGerror, "lo_lseek failed");
3846
+ pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3820
3847
  }
3821
3848
 
3822
3849
  return INT2FIX(ret);
@@ -3836,7 +3863,7 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3836
3863
  int lo_desc = NUM2INT(in_lo_desc);
3837
3864
 
3838
3865
  if((position = lo_tell(conn, lo_desc)) < 0)
3839
- rb_raise(rb_ePGerror,"lo_tell failed");
3866
+ pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3840
3867
 
3841
3868
  return INT2FIX(position);
3842
3869
  }
@@ -3855,7 +3882,7 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3855
3882
  size_t len = NUM2INT(in_len);
3856
3883
 
3857
3884
  if(lo_truncate(conn,lo_desc,len) < 0)
3858
- rb_raise(rb_ePGerror,"lo_truncate failed");
3885
+ pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3859
3886
 
3860
3887
  return Qnil;
3861
3888
  }
@@ -3873,7 +3900,7 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3873
3900
  int lo_desc = NUM2INT(in_lo_desc);
3874
3901
 
3875
3902
  if(lo_close(conn,lo_desc) < 0)
3876
- rb_raise(rb_ePGerror,"lo_close failed");
3903
+ pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3877
3904
 
3878
3905
  return Qnil;
3879
3906
  }
@@ -3891,7 +3918,7 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3891
3918
  Oid oid = NUM2UINT(in_oid);
3892
3919
 
3893
3920
  if(lo_unlink(conn,oid) < 0)
3894
- rb_raise(rb_ePGerror,"lo_unlink failed");
3921
+ pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3895
3922
 
3896
3923
  return Qnil;
3897
3924
  }
@@ -4325,6 +4352,7 @@ init_pg_connection()
4325
4352
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4326
4353
  rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4327
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);
4328
4356
  rb_define_singleton_method(rb_cPGconn, "sync_ping", pgconn_s_sync_ping, -1);
4329
4357
  rb_define_singleton_method(rb_cPGconn, "sync_connect", pgconn_s_sync_connect, -1);
4330
4358
 
@@ -4342,6 +4370,9 @@ init_pg_connection()
4342
4370
  rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4343
4371
  rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4344
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
4345
4376
  rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4346
4377
  rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4347
4378
  rb_define_method(rb_cPGconn, "conninfo", pgconn_conninfo, 0);