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.
- data.tar.gz.sig +0 -0
- data/ChangeLog +298 -193
- data/README +2 -2
- data/Rakefile +51 -29
- data/Rakefile.local +229 -160
- data/ext/compat.c +2 -2
- data/ext/extconf.rb +94 -73
- data/ext/pg.c +163 -106
- data/lib/pg.rb +3 -0
- data/rake/documentation.rb +123 -0
- data/rake/helpers.rb +375 -308
- data/rake/hg.rb +17 -3
- data/rake/manual.rb +11 -6
- data/rake/packaging.rb +7 -1
- data/rake/publishing.rb +158 -91
- data/rake/testing.rb +52 -88
- data/spec/lib/helpers.rb +30 -10
- data/spec/m17n_spec.rb +36 -24
- data/spec/pgconn_spec.rb +165 -19
- data/spec/pgresult_spec.rb +3 -6
- metadata +61 -20
- metadata.gz.sig +0 -0
- data/rake/rdoc.rb +0 -30
data/ext/compat.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/10/31 23:29:59 $
|
13
13
|
************************************************/
|
14
14
|
|
15
15
|
#include <ctype.h>
|
data/ext/extconf.rb
CHANGED
@@ -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::
|
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
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
102
|
+
Then try building again.
|
72
103
|
|
73
|
-
|
74
|
-
|
75
|
-
|
104
|
+
===================================
|
105
|
+
}.gsub( /^\t+/, ' ' )
|
106
|
+
end
|
76
107
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
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"
|
101
|
-
abort "Can't find the 'libpq/libpq-fs.h header"
|
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.
|
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
|
57
|
-
static VALUE pgconn_finish(VALUE
|
58
|
-
static VALUE pgresult_clear(VALUE
|
59
|
-
static VALUE pgresult_aref(VALUE
|
60
|
-
static VALUE make_column_result_array( VALUE
|
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*
|
65
|
-
static
|
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
|
-
|
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
|
-
*
|
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
|
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 *
|
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
|
-
|
2072
|
-
if (
|
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(
|
2078
|
-
be_pid = INT2NUM(
|
2079
|
-
extra = rb_tainted_str_new2(PGNOTIFY_EXTRA(
|
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(
|
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
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
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
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
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
|
-
|
2137
|
-
|
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
|
-
|
2170
|
+
relname = rb_tainted_str_new2( notification->relname );
|
2171
|
+
be_pid = INT2NUM( notification->be_pid );
|
2172
|
+
PQfreemem( notification );
|
2147
2173
|
|
2148
|
-
|
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"
|
3651
|
-
{"KOI8", "KOI8-
|
3652
|
-
{"
|
3653
|
-
{"
|
3654
|
-
{"
|
3655
|
-
{"
|
3656
|
-
{"
|
3657
|
-
{"
|
3658
|
-
{"
|
3659
|
-
{"
|
3660
|
-
{"
|
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
|
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) */
|