pg 0.9.0 → 0.10.0

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.
@@ -8,8 +8,8 @@
8
8
  Author: ematsu
9
9
  modified at: Wed Jan 20 16:41:51 1999
10
10
 
11
- $Author: jdavis $
12
- $Date: 2007-12-04 14:25:44 -0800 (Tue, 04 Dec 2007) $
11
+ $Author: ged $
12
+ $Date: 2010/10/31 23:29:59 $
13
13
  ************************************************/
14
14
 
15
15
  #include <ctype.h>
@@ -1,15 +1,10 @@
1
+ require 'pp'
1
2
  require 'mkmf'
2
3
 
3
4
  if pgdir = with_config( 'pg' )
4
- ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPERATOR + ENV['PATH']
5
+ ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
5
6
  end
6
7
 
7
- ### Read the output of a command using the fork+pipe syntax so execution errors
8
- ### propagate to Ruby.
9
- def read_cmd_output( *cmd )
10
- output = IO.read( '|-' ) or exec( *cmd )
11
- return output.chomp
12
- end
13
8
 
14
9
  ### Turn a version string into a Comparable binary datastructure
15
10
  def vvec( version )
@@ -22,88 +17,116 @@ if vvec(RUBY_VERSION) < vvec('1.8')
22
17
  exit 1
23
18
  end
24
19
 
25
- pgconfig = with_config( 'pg-config' ) || 'pg_config'
26
- if pgconfig = find_executable( pgconfig )
27
- $CPPFLAGS << " -I%s" % [ read_cmd_output(pgconfig, '--includedir') ]
28
- $LDFLAGS << " -L%s" % [ read_cmd_output(pgconfig, '--libdir') ]
29
- end
20
+ if ENV['CROSS_COMPILING']
30
21
 
31
- # Sort out the universal vs. single-archicture build problems on MacOS X
32
- if RUBY_PLATFORM.include?( 'darwin' )
33
- puts "MacOS X build: fixing architecture flags:"
34
-
35
- # Only keep the '-arch <a>' flags present in both the cflags reported
36
- # by pg_config and those that Ruby specifies.
37
- commonflags = nil
38
- if ENV['ARCHFLAGS']
39
- puts " using the value in ARCHFLAGS environment variable (%p)." % [ ENV['ARCHFLAGS'] ]
40
- commonflags = ENV['ARCHFLAGS']
41
- elsif pgconfig
42
- puts " finding flags common to both Ruby and PostgreSQL..."
43
- archflags = []
44
- pgcflags = read_cmd_output( pgconfig, '--cflags' )
45
- pgcflags.scan( /-arch\s+(\S+)/ ).each do |arch|
46
- puts " testing for architecture: %p" % [ arch ]
47
- archflags << "-arch #{arch}" if Config::CONFIG['CFLAGS'].index("-arch #{arch}")
22
+ $LDFLAGS << " -L#{CONFIG['libdir']}"
23
+
24
+ # Link against all required libraries for static build, if they are available
25
+ have_library( 'gdi32', 'CreateDC' ) && append_library( $libs, 'gdi32' )
26
+ have_library( 'secur32' ) && append_library( $libs, 'secur32' )
27
+ have_library( 'crypto', 'BIO_new' ) && append_library( $libs, 'crypto' )
28
+ have_library( 'ssl', 'SSL_new' ) && append_library( $libs, 'ssl' )
29
+
30
+ else
31
+ pgconfig = with_config( 'pg-config' ) || 'pg_config'
32
+ if pgconfig = find_executable( pgconfig )
33
+ $CFLAGS << " " + `#{pgconfig} --cflags`.chomp
34
+ $CPPFLAGS << " -I%s" % [ `#{pgconfig} --includedir`.chomp ]
35
+ $LDFLAGS << " -L%s" % [ `#{pgconfig} --libdir`.chomp ]
36
+ end
37
+
38
+ # Sort out the universal vs. single-archicture build problems on MacOS X
39
+ if RUBY_PLATFORM.include?( 'darwin' )
40
+ puts "MacOS X build: fixing architecture flags:"
41
+ ruby_archs = Config::CONFIG['CFLAGS'].scan( /-arch (\S+)/ ).flatten
42
+ $stderr.puts "Ruby cflags: %p" % [ Config::CONFIG['CFLAGS'] ]
43
+
44
+ # Only keep the '-arch <a>' flags present in both the cflags reported
45
+ # by pg_config and those that Ruby specifies.
46
+ commonflags = nil
47
+ if ENV['ARCHFLAGS']
48
+ puts " using the value in ARCHFLAGS environment variable (%p)." % [ ENV['ARCHFLAGS'] ]
49
+ common_archs = ENV['ARCHFLAGS'].scan( /-arch\s+(\S+)/ ).flatten
50
+
51
+ # Warn if the ARCHFLAGS doesn't have at least one architecture in
52
+ # common with the running ruby.
53
+ if ( (common_archs & ruby_archs).empty? )
54
+ $stderr.puts '',
55
+ "*** Your ARCHFLAGS setting doesn't seem to contain an architecture in common",
56
+ "with the running ruby interpreter (%p vs. %p)" % [ common_archs, ruby_archs ],
57
+ "I'll continue anyway, but if it fails, try unsetting ARCHFLAGS."
58
+ end
59
+
60
+ commonflags = ENV['ARCHFLAGS']
48
61
  end
49
62
 
50
- commonflags = archflags.join(' ')
51
- puts " common arch flags: %s" % [ commonflags ]
52
- else
53
- $stderr.puts %{
54
- =========== WARNING ===========
63
+ if pgconfig
64
+ puts " finding flags common to both Ruby and PostgreSQL..."
65
+ archflags = []
66
+ pgcflags = `#{pgconfig} --cflags`.chomp
67
+ pgarchs = pgcflags.scan( /-arch\s+(\S+)/ ).flatten
68
+ pgarchs.each do |arch|
69
+ puts " testing for architecture: %p" % [ arch ]
70
+ archflags << "-arch #{arch}" if ruby_archs.include?( arch )
71
+ end
72
+
73
+ if archflags.empty?
74
+ $stderr.puts '',
75
+ "*** Your PostgreSQL installation doesn't seem to have an architecture " +
76
+ "in common with the running ruby interpreter (%p vs. %p)" %
77
+ [ pgarchs, ruby_archs ],
78
+ "I'll continue anyway, but if it fails, try setting ARCHFLAGS."
79
+ else
80
+ commonflags = archflags.join(' ')
81
+ puts " common arch flags: %s" % [ commonflags ]
82
+ end
83
+ else
84
+ $stderr.puts %{
85
+ =========== WARNING ===========
55
86
 
56
- You are building this extension on OS X without setting the
57
- ARCHFLAGS environment variable, and pg_config wasn't found in
58
- your PATH. If you are seeing this message, that means that the
59
- build will probably fail.
87
+ You are building this extension on OS X without setting the
88
+ ARCHFLAGS environment variable, and pg_config wasn't found in
89
+ your PATH. If you are seeing this message, that means that the
90
+ build will probably fail.
60
91
 
61
- If it does, you can correct this by either including the path
62
- to 'pg_config' in your PATH or setting the environment variable
63
- ARCHFLAGS to '-arch <arch>' before building.
92
+ If it does, you can correct this by either including the path
93
+ to 'pg_config' in your PATH or setting the environment variable
94
+ ARCHFLAGS to '-arch <arch>' before building.
64
95
 
65
- For example:
66
- (in bash) $ export PATH=/opt/local/lib/postgresql84/bin:$PATH
67
- $ export ARCHFLAGS='-arch x86_64'
68
- (in tcsh) % set path = ( /opt/local/lib/postgresql84/bin $PATH )
69
- % setenv ARCHFLAGS '-arch x86_64'
96
+ For example:
97
+ (in bash) $ export PATH=/opt/local/lib/postgresql84/bin:$PATH
98
+ $ export ARCHFLAGS='-arch x86_64'
99
+ (in tcsh) % set path = ( /opt/local/lib/postgresql84/bin $PATH )
100
+ % setenv ARCHFLAGS '-arch x86_64'
70
101
 
71
- Then try building again.
102
+ Then try building again.
72
103
 
73
- ===================================
74
- }.gsub( /^\t+/, ' ' )
75
- end
104
+ ===================================
105
+ }.gsub( /^\t+/, ' ' )
106
+ end
76
107
 
77
- if commonflags
78
- $CFLAGS.gsub!( /-arch\s+\S+ /, '' )
79
- $LDFLAGS.gsub!( /-arch\s+\S+ /, '' )
80
- CONFIG['LDSHARED'].gsub!( /-arch\s+\S+ /, '' )
108
+ if commonflags
109
+ $CFLAGS.gsub!( /-arch\s+\S+ /, '' )
110
+ $LDFLAGS.gsub!( /-arch\s+\S+ /, '' )
111
+ CONFIG['LDSHARED'].gsub!( /-arch\s+\S+ /, '' )
81
112
 
82
- $CFLAGS << ' ' << commonflags
83
- $LDFLAGS << ' ' << commonflags
84
- CONFIG['LDSHARED'] << ' ' << commonflags
113
+ $CFLAGS << ' ' << commonflags
114
+ $LDFLAGS << ' ' << commonflags
115
+ CONFIG['LDSHARED'] << ' ' << commonflags
116
+ end
85
117
  end
86
118
  end
87
119
 
88
-
89
120
  dir_config 'pg'
90
121
 
91
- if enable_config("static-build")
92
- # Link against all required libraries for static build, if they are available
93
- have_library('gdi32', 'CreateDC') && append_library($libs, 'gdi32')
94
- have_library('secur32') && append_library($libs, 'secur32')
95
- have_library('crypto', 'BIO_new') && append_library($libs, 'crypto')
96
- have_library('ssl', 'SSL_new') && append_library($libs, 'ssl')
97
- end
98
-
99
122
 
100
- abort "Can't find the 'libpq-fe.h header" unless have_header( 'libpq-fe.h' )
101
- abort "Can't find the 'libpq/libpq-fs.h header" unless have_header('libpq/libpq-fs.h')
123
+ find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
124
+ find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
102
125
 
103
126
  abort "Can't find the PostgreSQL client library (libpq)" unless
104
- have_library( 'pq', 'PQconnectdb' ) ||
105
- have_library( 'libpq', 'PQconnectdb' ) ||
106
- have_library( 'ms/libpq', 'PQconnectdb' )
127
+ have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
128
+ have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
129
+ have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
107
130
 
108
131
  # optional headers/functions
109
132
  have_func 'PQconnectionUsedPassword'
@@ -119,8 +142,6 @@ have_func 'PQsetClientEncoding'
119
142
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
120
143
  have_header 'unistd.h' unless enable_config("static-build")
121
144
 
122
- $CFLAGS << ' -Wall'
123
-
124
145
  create_header()
125
146
  create_makefile( "pg_ext" )
126
147
 
data/ext/pg.c CHANGED
@@ -8,8 +8,8 @@
8
8
  Author: ematsu
9
9
  modified at: Wed Jan 20 16:41:51 1999
10
10
 
11
- $Author$
12
- $Date$
11
+ $Author: ged $
12
+ $Date: 2010/11/12 03:39:48 $
13
13
  ************************************************/
14
14
 
15
15
  #include "pg.h"
@@ -23,7 +23,7 @@ static VALUE rb_cPGconn;
23
23
  static VALUE rb_cPGresult;
24
24
  static VALUE rb_ePGError;
25
25
 
26
- static const char *VERSION = "0.9.0";
26
+ static const char *VERSION = "0.10.0";
27
27
 
28
28
 
29
29
  /* The following functions are part of libpq, but not
@@ -50,21 +50,22 @@ static const char *VERSION = "0.9.0";
50
50
  * UTILITY FUNCTIONS
51
51
  **************************************************************************/
52
52
 
53
- static void free_pgconn(PGconn *);
54
- static void pgresult_check(VALUE, VALUE);
53
+ static void free_pgconn( PGconn * );
54
+ static void pgresult_check( VALUE, VALUE );
55
55
 
56
- static PGconn *get_pgconn(VALUE self);
57
- static VALUE pgconn_finish(VALUE self);
58
- static VALUE pgresult_clear(VALUE self);
59
- static VALUE pgresult_aref(VALUE self, VALUE index);
60
- static VALUE make_column_result_array( VALUE self, int col );
56
+ static PGconn *get_pgconn( VALUE );
57
+ static VALUE pgconn_finish( VALUE );
58
+ static VALUE pgresult_clear( VALUE );
59
+ static VALUE pgresult_aref( VALUE, VALUE );
60
+ static VALUE make_column_result_array( VALUE, int );
61
61
 
62
62
  #ifdef M17N_SUPPORTED
63
- # define ASSOCIATE_INDEX(obj, index_holder) rb_enc_associate_index((obj), enc_get_index((index_holder)))
64
- static rb_encoding * pgconn_get_client_encoding_as_rb_encoding(PGconn* conn);
65
- static int enc_get_index(VALUE val);
63
+ # define ASSOCIATE_INDEX( obj, index_holder ) rb_enc_associate_index((obj), enc_get_index((index_holder)))
64
+ static rb_encoding * pgconn_get_client_encoding_as_rb_encoding( PGconn * );
65
+ static const char * pgconn_get_rb_encoding_as_pg_encname( rb_encoding * );
66
+ static int enc_get_index( VALUE );
66
67
  #else
67
- # define ASSOCIATE_INDEX(obj, index_holder) /* nothing */
68
+ # define ASSOCIATE_INDEX( obj, index_holder ) /* nothing */
68
69
  #endif
69
70
 
70
71
  static PQnoticeReceiver default_notice_receiver = NULL;
@@ -240,7 +241,7 @@ parse_connect_args(int argc, VALUE *argv, VALUE self)
240
241
  VALUE args,arg;
241
242
  VALUE conninfo_rstr = rb_str_new("",0);
242
243
  char *host, *port, *opt, *tty, *dbname, *login, *pwd;
243
- host=port=opt=tty=dbname=login=pwd=NULL;
244
+ host = port = opt = tty = dbname = login = pwd = NULL;
244
245
 
245
246
  rb_scan_args(argc, argv, "0*", &args);
246
247
  if (RARRAY_LEN(args) == 1) {
@@ -291,8 +292,9 @@ parse_connect_args(int argc, VALUE *argv, VALUE self)
291
292
  build_key_value_string(conninfo_rstr, "password", rb_ary_entry(args,6));
292
293
  }
293
294
  else {
294
- rb_raise(rb_eArgError,
295
- "Expected connection info string, hash, or 7 separate arguments.");
295
+ rb_raise( rb_eArgError,
296
+ "Expected connection info string, hash, or 7 separate arguments, got a %s.",
297
+ RSTRING_PTR(rb_obj_classname( args )) );
296
298
  }
297
299
 
298
300
  return conninfo_rstr;
@@ -388,7 +390,10 @@ pgconn_alloc(VALUE klass)
388
390
  * # As an Array
389
391
  * PGconn.connect( nil, 5432, nil, nil, 'test', nil, nil )
390
392
  *
391
- * On failure, it raises a PGError.
393
+ * If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the
394
+ * connection will have its +client_encoding+ set accordingly.
395
+ *
396
+ * @raises [PGError] if the connection fails.
392
397
  */
393
398
  static VALUE
394
399
  pgconn_init(int argc, VALUE *argv, VALUE self)
@@ -396,6 +401,10 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
396
401
  PGconn *conn = NULL;
397
402
  VALUE conninfo;
398
403
  VALUE error;
404
+ #ifdef M17N_SUPPORTED
405
+ rb_encoding *enc;
406
+ const char *encname;
407
+ #endif
399
408
 
400
409
  conninfo = parse_connect_args(argc, argv, self);
401
410
  conn = PQconnectdb(StringValuePtr(conninfo));
@@ -412,6 +421,17 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
412
421
  rb_exc_raise(error);
413
422
  }
414
423
 
424
+ #ifdef M17N_SUPPORTED
425
+ /* If Ruby has its Encoding.default_internal set, set PostgreSQL's client_encoding
426
+ * to match */
427
+ if (( enc = rb_default_internal_encoding() )) {
428
+ encname = pgconn_get_rb_encoding_as_pg_encname( enc );
429
+ if ( PQsetClientEncoding(conn, encname) != 0 )
430
+ rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
431
+ encname, PQerrorMessage(conn) );
432
+ }
433
+ #endif
434
+
415
435
  if (rb_block_given_p()) {
416
436
  return rb_ensure(rb_yield, self, pgconn_finish, self);
417
437
  }
@@ -427,6 +447,12 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
427
447
  * This is an asynchronous version of PGconn.connect().
428
448
  *
429
449
  * Use PGconn#connect_poll to poll the status of the connection.
450
+ *
451
+ * NOTE: this does *not* set the connection's +client_encoding+ for you if
452
+ * Encoding.default_internal is set. To set it after the connection is established,
453
+ * call PGconn#internal_encoding=. You can also set it automatically by setting
454
+ * ENV['PGCLIENTENCODING'], or include the 'options' connection parameter.
455
+ *
430
456
  */
431
457
  static VALUE
432
458
  pgconn_s_connect_start(int argc, VALUE *argv, VALUE self)
@@ -489,7 +515,7 @@ pgconn_s_conndefaults(VALUE self)
489
515
  VALUE ary = rb_ary_new();
490
516
  VALUE hash;
491
517
  int i = 0;
492
-
518
+
493
519
  for(i = 0; options[i].keyword != NULL; i++) {
494
520
  hash = rb_hash_new();
495
521
  if(options[i].keyword)
@@ -535,7 +561,7 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
535
561
  {
536
562
  char *encrypted = NULL;
537
563
  VALUE rval = Qnil;
538
-
564
+
539
565
  Check_Type(password, T_STRING);
540
566
  Check_Type(username, T_STRING);
541
567
 
@@ -1065,7 +1091,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
1065
1091
  else
1066
1092
  paramFormats[i] = NUM2INT(param_format);
1067
1093
  }
1068
-
1094
+
1069
1095
  result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
1070
1096
  (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
1071
1097
 
@@ -1252,7 +1278,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1252
1278
  else
1253
1279
  paramFormats[i] = NUM2INT(param_format);
1254
1280
  }
1255
-
1281
+
1256
1282
  result = PQexecPrepared(conn, StringValuePtr(name), nParams,
1257
1283
  (const char * const *)paramValues, paramLengths, paramFormats,
1258
1284
  resultFormat);
@@ -1617,7 +1643,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1617
1643
  else
1618
1644
  paramFormats[i] = NUM2INT(param_format);
1619
1645
  }
1620
-
1646
+
1621
1647
  result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
1622
1648
  (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
1623
1649
 
@@ -1802,7 +1828,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1802
1828
  else
1803
1829
  paramFormats[i] = NUM2INT(param_format);
1804
1830
  }
1805
-
1831
+
1806
1832
  result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
1807
1833
  (const char * const *)paramValues, paramLengths, paramFormats,
1808
1834
  resultFormat);
@@ -2038,7 +2064,7 @@ pgconn_cancel(VALUE self)
2038
2064
  rb_raise(rb_ePGError,"Invalid connection!");
2039
2065
 
2040
2066
  ret = PQcancel(cancel, errbuf, 256);
2041
- if(ret == 1)
2067
+ if(ret == 1)
2042
2068
  retval = Qnil;
2043
2069
  else
2044
2070
  retval = rb_str_new2(errbuf);
@@ -2052,14 +2078,14 @@ pgconn_cancel(VALUE self)
2052
2078
  * call-seq:
2053
2079
  * conn.notifies()
2054
2080
  *
2055
- * Returns a hash of the unprocessed notifiers.
2081
+ * Returns a hash of the unprocessed notifications.
2056
2082
  * If there is no unprocessed notifier, it returns +nil+.
2057
2083
  */
2058
2084
  static VALUE
2059
2085
  pgconn_notifies(VALUE self)
2060
2086
  {
2061
2087
  PGconn* conn = get_pgconn(self);
2062
- PGnotify *notify;
2088
+ PGnotify *notification;
2063
2089
  VALUE hash;
2064
2090
  VALUE sym_relname, sym_be_pid, sym_extra;
2065
2091
  VALUE relname, be_pid, extra;
@@ -2068,21 +2094,21 @@ pgconn_notifies(VALUE self)
2068
2094
  sym_be_pid = ID2SYM(rb_intern("be_pid"));
2069
2095
  sym_extra = ID2SYM(rb_intern("extra"));
2070
2096
 
2071
- notify = PQnotifies(conn);
2072
- if (notify == NULL) {
2097
+ notification = PQnotifies(conn);
2098
+ if (notification == NULL) {
2073
2099
  return Qnil;
2074
2100
  }
2075
-
2101
+
2076
2102
  hash = rb_hash_new();
2077
- relname = rb_tainted_str_new2(notify->relname);
2078
- be_pid = INT2NUM(notify->be_pid);
2079
- extra = rb_tainted_str_new2(PGNOTIFY_EXTRA(notify));
2080
-
2103
+ relname = rb_tainted_str_new2(notification->relname);
2104
+ be_pid = INT2NUM(notification->be_pid);
2105
+ extra = rb_tainted_str_new2(PGNOTIFY_EXTRA(notification));
2106
+
2081
2107
  rb_hash_aset(hash, sym_relname, relname);
2082
2108
  rb_hash_aset(hash, sym_be_pid, be_pid);
2083
2109
  rb_hash_aset(hash, sym_extra, extra);
2084
2110
 
2085
- PQfreemem(notify);
2111
+ PQfreemem(notification);
2086
2112
  return hash;
2087
2113
  }
2088
2114
 
@@ -2104,48 +2130,51 @@ pgconn_notifies(VALUE self)
2104
2130
  static VALUE
2105
2131
  pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2106
2132
  {
2107
- PGconn *conn = get_pgconn(self);
2108
- PGnotify *notify;
2109
- int sd = PQsocket(conn);
2110
- int ret;
2111
- struct timeval timeout;
2112
- struct timeval *ptimeout = NULL;
2113
- VALUE timeout_in, relname = Qnil, be_pid = Qnil;
2114
- double timeout_sec;
2115
- fd_set sd_rset;
2116
-
2117
- if (sd < 0)
2133
+ PGconn *conn = get_pgconn( self );
2134
+ PGnotify *notification;
2135
+ int sd = PQsocket( conn );
2136
+ int ret;
2137
+ struct timeval timeout;
2138
+ struct timeval *ptimeout = NULL;
2139
+ VALUE timeout_in, relname = Qnil, be_pid = Qnil;
2140
+ double timeout_sec;
2141
+ fd_set sd_rset;
2142
+
2143
+ if ( sd < 0 )
2118
2144
  rb_bug("PQsocket(conn): couldn't fetch the connection's socket!");
2119
2145
 
2120
- if (rb_scan_args(argc, argv, "01", &timeout_in) == 1) {
2121
- timeout_sec = NUM2DBL(timeout_in);
2122
- timeout.tv_sec = (long)timeout_sec;
2123
- timeout.tv_usec = (long)((timeout_sec - (long)timeout_sec) * 1e6);
2124
- ptimeout = &timeout;
2125
- }
2126
-
2127
- FD_ZERO(&sd_rset);
2128
- FD_SET(sd, &sd_rset);
2129
- ret = rb_thread_select(sd+1, &sd_rset, NULL, NULL, ptimeout);
2130
- if (ret == 0) {
2131
- return Qnil;
2132
- } else if (ret < 0) {
2133
- rb_sys_fail(0);
2146
+ if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2147
+ timeout_sec = NUM2DBL( timeout_in );
2148
+ timeout.tv_sec = (long)timeout_sec;
2149
+ timeout.tv_usec = (long)( (timeout_sec - (long)timeout_sec) * 1e6 );
2150
+ ptimeout = &timeout;
2134
2151
  }
2135
-
2136
- if ( (ret = PQconsumeInput(conn)) != 1 ) {
2137
- rb_raise(rb_ePGError, "PQconsumeInput == %d: %s", ret, PQerrorMessage(conn));
2152
+
2153
+ /* Check for notifications */
2154
+ while ( (notification = PQnotifies(conn)) == NULL ) {
2155
+ FD_ZERO( &sd_rset );
2156
+ FD_SET( sd, &sd_rset );
2157
+
2158
+ /* Wait for the socket to become readable before checking again */
2159
+ if ( (ret = rb_thread_select(sd+1, &sd_rset, NULL, NULL, ptimeout)) < 0 )
2160
+ rb_sys_fail( 0 );
2161
+
2162
+ /* Return nil if the select timed out */
2163
+ if ( ret == 0 ) return Qnil;
2164
+
2165
+ /* Read the socket */
2166
+ if ( (ret = PQconsumeInput(conn)) != 1 )
2167
+ rb_raise(rb_ePGError, "PQconsumeInput == %d: %s", ret, PQerrorMessage(conn));
2138
2168
  }
2139
-
2140
- while ((notify = PQnotifies(conn)) != NULL) {
2141
- relname = rb_tainted_str_new2(notify->relname);
2142
- be_pid = INT2NUM(notify->be_pid);
2143
- PQfreemem(notify);
2144
- }
2145
2169
 
2146
- if (rb_block_given_p()) rb_yield( rb_ary_new3(2, relname, be_pid) );
2170
+ relname = rb_tainted_str_new2( notification->relname );
2171
+ be_pid = INT2NUM( notification->be_pid );
2172
+ PQfreemem( notification );
2147
2173
 
2148
- return relname;
2174
+ if ( rb_block_given_p() )
2175
+ rb_yield_splat( rb_ary_new3(2, relname, be_pid) );
2176
+
2177
+ return relname;
2149
2178
  }
2150
2179
 
2151
2180
 
@@ -2472,7 +2501,7 @@ pgconn_transaction(VALUE self)
2472
2501
  PGresult *result;
2473
2502
  VALUE rb_pgresult;
2474
2503
  int status;
2475
-
2504
+
2476
2505
  if (rb_block_given_p()) {
2477
2506
  result = PQexec(conn, "BEGIN");
2478
2507
  rb_pgresult = new_pgresult(result, conn);
@@ -2490,7 +2519,7 @@ pgconn_transaction(VALUE self)
2490
2519
  pgresult_check(self, rb_pgresult);
2491
2520
  rb_jump_tag(status);
2492
2521
  }
2493
-
2522
+
2494
2523
  }
2495
2524
  else {
2496
2525
  /* no block supplied? */
@@ -2529,7 +2558,7 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
2529
2558
  * double-quotes. */
2530
2559
  char buffer[NAMEDATALEN*2+2];
2531
2560
  unsigned int i=0,j=0;
2532
-
2561
+
2533
2562
  if(strlen(str) >= NAMEDATALEN) {
2534
2563
  rb_raise(rb_eArgError,
2535
2564
  "Input string is longer than NAMEDATALEN-1 (%d)",
@@ -3206,7 +3235,7 @@ pgresult_ftablecol(VALUE self, VALUE column_number)
3206
3235
 
3207
3236
  if( col_number < 0 || col_number >= PQnfields(pgresult))
3208
3237
  rb_raise(rb_eArgError,"Invalid column index: %d", col_number);
3209
-
3238
+
3210
3239
  n = PQftablecol(pgresult, col_number);
3211
3240
  return INT2FIX(n);
3212
3241
  }
@@ -3502,10 +3531,12 @@ pgresult_aref(VALUE self, VALUE index)
3502
3531
  PQgetlength(result, tuple_num, field_num));
3503
3532
 
3504
3533
  /* associate client encoding for text format only */
3505
- if(0 == PQfformat(result, field_num)) {
3534
+ if(0 == PQfformat(result, field_num)) {
3535
+ fflush( stdout );
3506
3536
  ASSOCIATE_INDEX(val, self);
3507
3537
  } else {
3508
3538
  #ifdef M17N_SUPPORTED
3539
+ fflush( stdout );
3509
3540
  rb_enc_associate(val, rb_ascii8bit_encoding());
3510
3541
  #endif
3511
3542
  }
@@ -3548,7 +3579,7 @@ pgresult_field_values( VALUE self, VALUE field )
3548
3579
 
3549
3580
  if ( fnum < 0 )
3550
3581
  rb_raise( rb_eIndexError, "no such field '%s' in result", fieldname );
3551
-
3582
+
3552
3583
  return make_column_result_array( self, fnum );
3553
3584
  }
3554
3585
 
@@ -3564,7 +3595,7 @@ make_column_result_array( VALUE self, int col )
3564
3595
  int row = PQntuples( result );
3565
3596
  VALUE ary = rb_ary_new2( row );
3566
3597
  VALUE val = Qnil;
3567
-
3598
+
3568
3599
  if ( col >= PQnfields(result) )
3569
3600
  rb_raise( rb_eIndexError, "no column %d in result", col );
3570
3601
 
@@ -3583,7 +3614,7 @@ make_column_result_array( VALUE self, int col )
3583
3614
 
3584
3615
  rb_ary_store( ary, row, val );
3585
3616
  }
3586
-
3617
+
3587
3618
  return ary;
3588
3619
  }
3589
3620
 
@@ -3635,34 +3666,36 @@ pgresult_fields(VALUE self)
3635
3666
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
3636
3667
  */
3637
3668
  static const char * const (enc_pg2ruby_mapping[][2]) = {
3638
- {"BIG5", "Big5" },
3639
- {"EUC_CN", "GB2312" },
3640
- {"EUC_JP", "EUC-JP" },
3641
- {"EUC_JIS_2004", "EUC-JP" },
3642
- {"EUC_KR", "EUC-KR" },
3643
- {"EUC_TW", "EUC-TW" },
3644
- {"GB18030", "GB18030" },
3645
- {"GBK", "GBK" },
3646
- {"ISO_8859_5", "ISO-8859-5" },
3647
- {"ISO_8859_6", "ISO-8859-6" },
3648
- {"ISO_8859_7", "ISO-8859-7" },
3649
- {"ISO_8859_8", "ISO-8859-8" },
3650
- /* {"JOHAB", "JOHAB" }, dummy */
3651
- {"KOI8", "KOI8-U" },
3652
- {"LATIN1", "ISO-8859-1" },
3653
- {"LATIN2", "ISO-8859-2" },
3654
- {"LATIN3", "ISO-8859-3" },
3655
- {"LATIN4", "ISO-8859-4" },
3656
- {"LATIN5", "ISO-8859-5" },
3657
- {"LATIN6", "ISO-8859-6" },
3658
- {"LATIN7", "ISO-8859-7" },
3659
- {"LATIN8", "ISO-8859-8" },
3660
- {"LATIN9", "ISO-8859-9" },
3669
+ {"BIG5", "Big5" },
3670
+ {"EUC_CN", "GB2312" },
3671
+ {"EUC_JP", "EUC-JP" },
3672
+ {"EUC_JIS_2004", "EUC-JP" },
3673
+ {"EUC_KR", "EUC-KR" },
3674
+ {"EUC_TW", "EUC-TW" },
3675
+ {"GB18030", "GB18030" },
3676
+ {"GBK", "GBK" },
3677
+ {"ISO_8859_5", "ISO-8859-5" },
3678
+ {"ISO_8859_6", "ISO-8859-6" },
3679
+ {"ISO_8859_7", "ISO-8859-7" },
3680
+ {"ISO_8859_8", "ISO-8859-8" },
3681
+ /* {"JOHAB", "JOHAB" }, dummy */
3682
+ {"KOI8", "KOI8-R" },
3683
+ {"KOI8R", "KOI8-R" },
3684
+ {"KOI8U", "KOI8-U" },
3685
+ {"LATIN1", "ISO-8859-1" },
3686
+ {"LATIN2", "ISO-8859-2" },
3687
+ {"LATIN3", "ISO-8859-3" },
3688
+ {"LATIN4", "ISO-8859-4" },
3689
+ {"LATIN5", "ISO-8859-5" },
3690
+ {"LATIN6", "ISO-8859-6" },
3691
+ {"LATIN7", "ISO-8859-7" },
3692
+ {"LATIN8", "ISO-8859-8" },
3693
+ {"LATIN9", "ISO-8859-9" },
3661
3694
  {"LATIN10", "ISO-8859-10" },
3662
- {"MULE_INTERNAL", "Emacs-Mule" },
3695
+ {"MULE_INTERNAL", "Emacs-Mule" },
3663
3696
  {"SJIS", "Windows-31J" },
3664
3697
  {"SHIFT_JIS_2004","Windows-31J" },
3665
- /*{"SQL_ASCII", NULL }, special case*/
3698
+ /* {"SQL_ASCII", NULL }, special case*/
3666
3699
  {"UHC", "CP949" },
3667
3700
  {"UTF8", "UTF-8" },
3668
3701
  {"WIN866", "IBM866" },
@@ -3756,6 +3789,30 @@ cache:
3756
3789
  return enc;
3757
3790
  }
3758
3791
 
3792
+
3793
+ /*
3794
+ * Returns the given rb_encoding as the equivalent PostgreSQL encoding string.
3795
+ *
3796
+ */
3797
+ static const char *
3798
+ pgconn_get_rb_encoding_as_pg_encname( rb_encoding *enc )
3799
+ {
3800
+ const char *rb_encname = rb_enc_name( enc );
3801
+ const char *encname = NULL;
3802
+ int i;
3803
+
3804
+ for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
3805
+ if (strcmp(rb_encname, enc_pg2ruby_mapping[i][1]) == 0) {
3806
+ encname = enc_pg2ruby_mapping[i][0];
3807
+ }
3808
+ }
3809
+
3810
+ if ( !encname ) encname = "SQL_ASCII";
3811
+
3812
+ return encname;
3813
+ }
3814
+
3815
+
3759
3816
  /*
3760
3817
  * call-seq:
3761
3818
  * conn.internal_encoding() -> Encoding
@@ -3933,7 +3990,7 @@ Init_pg_ext()
3933
3990
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3934
3991
 
3935
3992
  /****** PGconn CLASS CONSTANTS: Connection Status ******/
3936
-
3993
+
3937
3994
  /* Connection succeeded */
3938
3995
  rb_define_const(rb_cPGconn, "CONNECTION_OK", INT2FIX(CONNECTION_OK));
3939
3996
  /* Connection failed */
@@ -3966,7 +4023,7 @@ Init_pg_ext()
3966
4023
  rb_define_const(rb_cPGconn, "PGRES_POLLING_OK", INT2FIX(PGRES_POLLING_OK));
3967
4024
 
3968
4025
  /****** PGconn CLASS CONSTANTS: Transaction Status ******/
3969
-
4026
+
3970
4027
  /* Transaction is currently idle (#transaction_status) */
3971
4028
  rb_define_const(rb_cPGconn, "PQTRANS_IDLE", INT2FIX(PQTRANS_IDLE));
3972
4029
  /* Transaction is currently active; query has been sent to the server, but not yet completed. (#transaction_status) */