pg 0.7.9.2008.03.18 → 0.7.9.2008.08.17
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/postgres.html +278 -0
- data/doc/postgres.jp.html +256 -0
- data/ext/extconf.rb +3 -1
- data/ext/mkrf_config.rb +131 -0
- data/ext/pg.c +664 -638
- data/sample/losample.rb +47 -0
- data/sample/psql.rb +1181 -0
- data/sample/psqlHelp.rb +158 -0
- data/sample/test1.rb +63 -0
- data/sample/test2.rb +44 -0
- data/sample/test4.rb +71 -0
- data/spec/data/expected_trace.out +26 -0
- data/spec/data/random_binary_data +0 -0
- data/spec/pgconn_spec.rb +127 -0
- data/spec/pgresult_spec.rb +108 -0
- metadata +56 -40
- data/BSD +0 -23
- data/COPYING.txt +0 -340
- data/Contributors +0 -28
- data/GPL +0 -340
- data/LICENSE +0 -58
- data/README +0 -125
data/ext/extconf.rb
CHANGED
data/ext/mkrf_config.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mkrf'
|
3
|
+
|
4
|
+
unless system("pg_config --bindir > /dev/null")
|
5
|
+
$stderr.write("ERROR: can't find pg_config.\n")
|
6
|
+
$stderr.write("HINT: Make sure pg_config is in your PATH\n")
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
$functions = %w[
|
11
|
+
lo_create
|
12
|
+
PQconnectionUsedPassword
|
13
|
+
PQisthreadsafe
|
14
|
+
PQprepare
|
15
|
+
PQexecParams
|
16
|
+
PQescapeString
|
17
|
+
PQescapeStringConn
|
18
|
+
lo_create
|
19
|
+
pg_encoding_to_char
|
20
|
+
PQsetClientEncoding
|
21
|
+
]
|
22
|
+
|
23
|
+
# OS X compatibility
|
24
|
+
if(PLATFORM =~ /darwin/) then
|
25
|
+
# test if postgresql is probably universal
|
26
|
+
bindir = escape_path(IO.popen("pg_config --bindir").readline.chomp)
|
27
|
+
Open3.popen3('file',"#{bindir}/pg_config") do |the_in, the_out, the_err|
|
28
|
+
filetype = the_out.readline.chomp
|
29
|
+
end
|
30
|
+
# if it's not universal, ARCHFLAGS should be set
|
31
|
+
if((filetype !~ /universal binary/) && ENV['ARCHFLAGS'].nil?) then
|
32
|
+
arch_tmp = (IO.popen("uname -p").readline.chomp rescue nil)
|
33
|
+
if(arch_tmp == 'powerpc')
|
34
|
+
arch = 'ppc'
|
35
|
+
else
|
36
|
+
arch = 'i386'
|
37
|
+
end
|
38
|
+
$stderr.write %{
|
39
|
+
=========== WARNING ===========
|
40
|
+
|
41
|
+
You are building this extension on OS X without setting the
|
42
|
+
ARCHFLAGS environment variable, and PostgreSQL does not appear
|
43
|
+
to have been built as a universal binary. If you are seeing this
|
44
|
+
message, that means that the build will probably fail.
|
45
|
+
|
46
|
+
Try setting the environment variable ARCHFLAGS
|
47
|
+
to '-arch #{arch}' before building.
|
48
|
+
|
49
|
+
For example:
|
50
|
+
(in bash) $ export ARCHFLAGS='-arch #{arch}'
|
51
|
+
(in tcsh) % setenv ARCHFLAGS '-arch #{arch}'
|
52
|
+
|
53
|
+
Then try building again.
|
54
|
+
|
55
|
+
===================================
|
56
|
+
}
|
57
|
+
# We don't exit here. Who knows? It might build.
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if RUBY_VERSION < '1.8'
|
62
|
+
puts 'This library is for ruby-1.8 or higher.'
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def escape_path(path)
|
67
|
+
if(PLATFORM =~ /mswin|mingw/) then
|
68
|
+
'"' + path + '"'
|
69
|
+
else
|
70
|
+
path.gsub(%r{([^a-zA-Z0-9/._-])}, "\\\\\\1")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def pg_config(type)
|
75
|
+
IO.popen("pg_config --#{type}dir").readline.chomp
|
76
|
+
end
|
77
|
+
|
78
|
+
def config_value(type)
|
79
|
+
escape_path(ENV["POSTGRES_#{type.upcase}"] || pg_config(type))
|
80
|
+
end
|
81
|
+
|
82
|
+
Mkrf::Generator.new('pg', '*.c',
|
83
|
+
{
|
84
|
+
:includes => [config_value('include'), Config::CONFIG['includedir'],
|
85
|
+
Config::CONFIG["archdir"], Config::CONFIG['sitelibdir'], "."],
|
86
|
+
:library_paths => [config_value('lib')],
|
87
|
+
# must set loaded_libs to work around a mkrf bug on some platforms
|
88
|
+
:loaded_libs => []
|
89
|
+
}
|
90
|
+
) do |g|
|
91
|
+
|
92
|
+
$stdout.write("checking for libpq-fe.h... ")
|
93
|
+
if g.include_header('libpq-fe.h') &&
|
94
|
+
g.include_header('libpq/libpq-fs.h')
|
95
|
+
then
|
96
|
+
puts 'yes'
|
97
|
+
else
|
98
|
+
puts 'no'
|
99
|
+
puts 'Could not find PostgreSQL headers: ' +
|
100
|
+
'Rakefile not created'
|
101
|
+
exit 1
|
102
|
+
end
|
103
|
+
|
104
|
+
$stdout.write("checking for libpq... ")
|
105
|
+
# we have to check a few possible names to account
|
106
|
+
# for building on windows
|
107
|
+
if g.include_library('pq') ||
|
108
|
+
g.include_library('libpq') ||
|
109
|
+
g.include_library('ms/libpq')
|
110
|
+
then
|
111
|
+
puts 'yes'
|
112
|
+
else
|
113
|
+
puts 'no'
|
114
|
+
puts 'Could not find PostgreSQL client library: ' +
|
115
|
+
'Rakefile not created'
|
116
|
+
exit 1
|
117
|
+
end
|
118
|
+
|
119
|
+
$functions.each do |func|
|
120
|
+
$stdout.write("checking for #{func}()... ")
|
121
|
+
if(g.has_function?(func)) then
|
122
|
+
g.add_define("HAVE_#{func.upcase}")
|
123
|
+
puts 'yes'
|
124
|
+
else
|
125
|
+
puts 'no'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
puts "creating Rakefile"
|
130
|
+
end
|
131
|
+
|
data/ext/pg.c
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
modified at: Wed Jan 20 16:41:51 1999
|
10
10
|
|
11
11
|
$Author: jdavis $
|
12
|
-
$Date: 2008-
|
12
|
+
$Date: 2008-08-17 13:43:21 -0700 (Sun, 17 Aug 2008) $
|
13
13
|
************************************************/
|
14
14
|
|
15
15
|
#include "pg.h"
|
@@ -60,8 +60,7 @@ static PQnoticeProcessor default_notice_processor = NULL;
|
|
60
60
|
* when building the connection string.
|
61
61
|
*/
|
62
62
|
static VALUE
|
63
|
-
pgconn_s_quote_connstr(string)
|
64
|
-
VALUE string;
|
63
|
+
pgconn_s_quote_connstr(VALUE string)
|
65
64
|
{
|
66
65
|
char *str,*ptr;
|
67
66
|
int i,j=0,len;
|
@@ -71,7 +70,7 @@ pgconn_s_quote_connstr(string)
|
|
71
70
|
|
72
71
|
ptr = RSTRING_PTR(string);
|
73
72
|
len = RSTRING_LEN(string);
|
74
|
-
str =
|
73
|
+
str = ALLOC_N(char, len * 2 + 2 + 1);
|
75
74
|
str[j++] = '\'';
|
76
75
|
for(i = 0; i < len; i++) {
|
77
76
|
if(ptr[i] == '\'' || ptr[i] == '\\')
|
@@ -80,27 +79,10 @@ pgconn_s_quote_connstr(string)
|
|
80
79
|
}
|
81
80
|
str[j++] = '\'';
|
82
81
|
result = rb_str_new(str, j);
|
82
|
+
free(str);
|
83
83
|
return result;
|
84
84
|
}
|
85
85
|
|
86
|
-
/*
|
87
|
-
* Appends key='hash[key]' to conninfo_rstr
|
88
|
-
*/
|
89
|
-
static void
|
90
|
-
build_key_value_string(hash, conninfo_rstr, key)
|
91
|
-
VALUE hash, conninfo_rstr;
|
92
|
-
char *key;
|
93
|
-
{
|
94
|
-
if(rb_funcall(hash, rb_intern("has_key?"), 1, ID2SYM(rb_intern(key)))) {
|
95
|
-
rb_str_cat2(conninfo_rstr, " ");
|
96
|
-
rb_str_cat2(conninfo_rstr, key);
|
97
|
-
rb_str_cat2(conninfo_rstr, "=");
|
98
|
-
rb_str_concat(conninfo_rstr, pgconn_s_quote_connstr(rb_obj_as_string(
|
99
|
-
rb_hash_aref(hash, ID2SYM(rb_intern(key))))));
|
100
|
-
}
|
101
|
-
return;
|
102
|
-
}
|
103
|
-
|
104
86
|
static char *
|
105
87
|
value_as_cstring(VALUE in_str)
|
106
88
|
{
|
@@ -134,16 +116,16 @@ get_pgconn(VALUE self)
|
|
134
116
|
static PGresult*
|
135
117
|
get_pgresult(VALUE self)
|
136
118
|
{
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
119
|
+
PGresult *result;
|
120
|
+
Data_Get_Struct(self, PGresult, result);
|
121
|
+
if (result == NULL) rb_raise(rb_ePGError, "result has been cleared");
|
122
|
+
return result;
|
141
123
|
}
|
142
124
|
|
143
125
|
static VALUE
|
144
126
|
new_pgresult(PGresult *result)
|
145
127
|
{
|
146
|
-
|
128
|
+
return Data_Wrap_Struct(rb_cPGresult, NULL, free_pgresult, result);
|
147
129
|
}
|
148
130
|
|
149
131
|
/*
|
@@ -182,7 +164,8 @@ pgresult_check(VALUE rb_pgconn, VALUE rb_pgresult)
|
|
182
164
|
return;
|
183
165
|
}
|
184
166
|
|
185
|
-
static VALUE
|
167
|
+
static VALUE
|
168
|
+
yield_pgresult(VALUE rb_pgresult)
|
186
169
|
{
|
187
170
|
int i;
|
188
171
|
PGresult *result = get_pgresult(rb_pgresult);
|
@@ -217,6 +200,89 @@ notice_processor_proxy(void *arg, const char *message)
|
|
217
200
|
return;
|
218
201
|
}
|
219
202
|
|
203
|
+
/*
|
204
|
+
* Appends key='val' to conninfo_rstr
|
205
|
+
*/
|
206
|
+
static void
|
207
|
+
build_key_value_string(VALUE conninfo_rstr, char *key, VALUE val)
|
208
|
+
{
|
209
|
+
if(val != Qnil) {
|
210
|
+
if(RSTRING_LEN(conninfo_rstr) > 0)
|
211
|
+
rb_str_cat2(conninfo_rstr, " ");
|
212
|
+
rb_str_cat2(conninfo_rstr, key);
|
213
|
+
rb_str_cat2(conninfo_rstr, "=");
|
214
|
+
rb_str_concat(conninfo_rstr,
|
215
|
+
pgconn_s_quote_connstr(rb_obj_as_string(val)));
|
216
|
+
}
|
217
|
+
return;
|
218
|
+
}
|
219
|
+
|
220
|
+
static VALUE
|
221
|
+
parse_connect_args(int argc, VALUE *argv, VALUE self)
|
222
|
+
{
|
223
|
+
VALUE args,arg;
|
224
|
+
PGconn *conn = NULL;
|
225
|
+
VALUE conninfo_rstr = rb_str_new("",0);
|
226
|
+
VALUE error;
|
227
|
+
char *host, *port, *opt, *tty, *dbname, *login, *pwd;
|
228
|
+
host=port=opt=tty=dbname=login=pwd=NULL;
|
229
|
+
|
230
|
+
rb_scan_args(argc, argv, "0*", &args);
|
231
|
+
if (RARRAY_LEN(args) == 1) {
|
232
|
+
arg = rb_ary_entry(args,0);
|
233
|
+
if(TYPE(arg) == T_HASH) {
|
234
|
+
build_key_value_string(conninfo_rstr, "host",
|
235
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("host"))));
|
236
|
+
build_key_value_string(conninfo_rstr, "hostaddr",
|
237
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("hostaddr"))));
|
238
|
+
build_key_value_string(conninfo_rstr, "port",
|
239
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("port"))));
|
240
|
+
build_key_value_string(conninfo_rstr, "dbname",
|
241
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("dbname"))));
|
242
|
+
build_key_value_string(conninfo_rstr, "user",
|
243
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("user"))));
|
244
|
+
build_key_value_string(conninfo_rstr, "password",
|
245
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("password"))));
|
246
|
+
build_key_value_string(conninfo_rstr, "connect_timeout",
|
247
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("connect_timeout"))));
|
248
|
+
build_key_value_string(conninfo_rstr, "options",
|
249
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("options"))));
|
250
|
+
build_key_value_string(conninfo_rstr, "tty",
|
251
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("tty"))));
|
252
|
+
build_key_value_string(conninfo_rstr, "sslmode",
|
253
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("sslmode"))));
|
254
|
+
build_key_value_string(conninfo_rstr, "krbsrvname",
|
255
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("krbsrvname"))));
|
256
|
+
build_key_value_string(conninfo_rstr, "gsslib",
|
257
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("gsslib"))));
|
258
|
+
build_key_value_string(conninfo_rstr, "service",
|
259
|
+
rb_hash_aref(arg, ID2SYM(rb_intern("service"))));
|
260
|
+
}
|
261
|
+
else if(TYPE(arg) == T_STRING) {
|
262
|
+
conninfo_rstr = arg;
|
263
|
+
}
|
264
|
+
else {
|
265
|
+
rb_raise(rb_eArgError,
|
266
|
+
"Expecting String or Hash as single argument");
|
267
|
+
}
|
268
|
+
}
|
269
|
+
else if (RARRAY_LEN(args) == 7) {
|
270
|
+
build_key_value_string(conninfo_rstr, "host", rb_ary_entry(args,0));
|
271
|
+
build_key_value_string(conninfo_rstr, "port", rb_ary_entry(args,1));
|
272
|
+
build_key_value_string(conninfo_rstr, "opt", rb_ary_entry(args,2));
|
273
|
+
build_key_value_string(conninfo_rstr, "tty", rb_ary_entry(args,3));
|
274
|
+
build_key_value_string(conninfo_rstr, "dbname", rb_ary_entry(args,4));
|
275
|
+
build_key_value_string(conninfo_rstr, "user", rb_ary_entry(args,5));
|
276
|
+
build_key_value_string(conninfo_rstr, "password", rb_ary_entry(args,6));
|
277
|
+
}
|
278
|
+
else {
|
279
|
+
rb_raise(rb_eArgError,
|
280
|
+
"Expected connection info string, hash, or 7 separate arguments.");
|
281
|
+
}
|
282
|
+
|
283
|
+
return conninfo_rstr;
|
284
|
+
}
|
285
|
+
|
220
286
|
/********************************************************************
|
221
287
|
*
|
222
288
|
* Document-class: PGError
|
@@ -249,21 +315,11 @@ notice_processor_proxy(void *arg, const char *message)
|
|
249
315
|
*
|
250
316
|
*/
|
251
317
|
|
252
|
-
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
|
253
318
|
static VALUE
|
254
319
|
pgconn_alloc(VALUE klass)
|
255
320
|
{
|
256
321
|
return Data_Wrap_Struct(klass, NULL, free_pgconn, NULL);
|
257
322
|
}
|
258
|
-
#else
|
259
|
-
static VALUE
|
260
|
-
pgconn_s_new(int argc, VALUE *argv, VALUE klass)
|
261
|
-
{
|
262
|
-
VALUE self = rb_obj_alloc(klass);
|
263
|
-
rb_obj_call_init(self, argc, argv);
|
264
|
-
return self;
|
265
|
-
}
|
266
|
-
#endif
|
267
323
|
|
268
324
|
/**************************************************************************
|
269
325
|
* PGconn SINGLETON METHODS
|
@@ -273,9 +329,9 @@ pgconn_s_new(int argc, VALUE *argv, VALUE klass)
|
|
273
329
|
* Document-method: new
|
274
330
|
*
|
275
331
|
* call-seq:
|
276
|
-
*
|
277
|
-
*
|
278
|
-
*
|
332
|
+
* PGconn.new(connection_hash) -> PGconn
|
333
|
+
* PGconn.new(connection_string) -> PGconn
|
334
|
+
* PGconn.new(host, port, options, tty, dbname, login, password) -> PGconn
|
279
335
|
*
|
280
336
|
* * +host+ - server hostname
|
281
337
|
* * +hostaddr+ - server address (avoids hostname lookup, overrides +host+)
|
@@ -297,89 +353,75 @@ pgconn_s_new(int argc, VALUE *argv, VALUE klass)
|
|
297
353
|
*
|
298
354
|
* On failure, it raises a PGError exception.
|
299
355
|
*/
|
300
|
-
|
301
356
|
static VALUE
|
302
|
-
pgconn_init(argc, argv, self)
|
303
|
-
int argc;
|
304
|
-
VALUE *argv;
|
305
|
-
VALUE self;
|
357
|
+
pgconn_init(int argc, VALUE *argv, VALUE self)
|
306
358
|
{
|
307
|
-
|
308
|
-
|
309
|
-
char *conninfo = NULL;
|
310
|
-
VALUE conninfo_rstr;
|
359
|
+
PGconn *conn = NULL;
|
360
|
+
VALUE conninfo;
|
311
361
|
VALUE error;
|
312
|
-
char *host, *port, *opt, *tty, *dbname, *login, *pwd;
|
313
|
-
host=port=opt=tty=dbname=login=pwd=NULL;
|
314
362
|
|
315
|
-
|
316
|
-
|
317
|
-
arg = rb_ary_entry(args,0);
|
318
|
-
if(TYPE(arg) == T_HASH) {
|
319
|
-
conninfo_rstr = rb_str_new2("");
|
320
|
-
build_key_value_string(arg, conninfo_rstr, "host");
|
321
|
-
build_key_value_string(arg, conninfo_rstr, "hostaddr");
|
322
|
-
build_key_value_string(arg, conninfo_rstr, "port");
|
323
|
-
build_key_value_string(arg, conninfo_rstr, "dbname");
|
324
|
-
build_key_value_string(arg, conninfo_rstr, "user");
|
325
|
-
build_key_value_string(arg, conninfo_rstr, "password");
|
326
|
-
build_key_value_string(arg, conninfo_rstr, "opt");
|
327
|
-
build_key_value_string(arg, conninfo_rstr, "tty");
|
328
|
-
build_key_value_string(arg, conninfo_rstr, "sslmode");
|
329
|
-
build_key_value_string(arg, conninfo_rstr, "krbsrvname");
|
330
|
-
build_key_value_string(arg, conninfo_rstr, "gsslib");
|
331
|
-
build_key_value_string(arg, conninfo_rstr, "service");
|
332
|
-
conninfo = StringValuePtr(conninfo_rstr);
|
333
|
-
}
|
334
|
-
else if(TYPE(arg) == T_STRING) {
|
335
|
-
conninfo = StringValuePtr(arg);
|
336
|
-
}
|
337
|
-
else {
|
338
|
-
rb_raise(rb_eArgError,
|
339
|
-
"Expecting String or Hash as single argument");
|
340
|
-
}
|
341
|
-
conn = PQconnectdb(conninfo);
|
342
|
-
}
|
343
|
-
else if (RARRAY_LEN(args) == 7) {
|
344
|
-
host = value_as_cstring(rb_ary_entry(args,0));
|
345
|
-
port = value_as_cstring(rb_ary_entry(args,1));
|
346
|
-
opt = value_as_cstring(rb_ary_entry(args,2));
|
347
|
-
tty = value_as_cstring(rb_ary_entry(args,3));
|
348
|
-
dbname = value_as_cstring(rb_ary_entry(args,4));
|
349
|
-
login = value_as_cstring(rb_ary_entry(args,5));
|
350
|
-
pwd = value_as_cstring(rb_ary_entry(args,6));
|
363
|
+
conninfo = parse_connect_args(argc, argv, self);
|
364
|
+
conn = PQconnectdb(StringValuePtr(conninfo));
|
351
365
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
366
|
+
if(conn == NULL)
|
367
|
+
rb_raise(rb_ePGError, "PQconnectStart() unable to allocate structure");
|
368
|
+
if (PQstatus(conn) == CONNECTION_BAD) {
|
369
|
+
error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
|
370
|
+
rb_iv_set(error, "@connection", self);
|
371
|
+
rb_exc_raise(error);
|
357
372
|
}
|
358
373
|
|
359
|
-
if (PQstatus(conn) == CONNECTION_BAD) {
|
360
|
-
error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
|
361
|
-
rb_iv_set(error, "@connection", self);
|
362
|
-
rb_exc_raise(error);
|
363
|
-
}
|
364
|
-
|
365
374
|
Check_Type(self, T_DATA);
|
366
375
|
DATA_PTR(self) = conn;
|
367
376
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
377
|
+
if (rb_block_given_p()) {
|
378
|
+
return rb_ensure(rb_yield, self, pgconn_finish, self);
|
379
|
+
}
|
380
|
+
return self;
|
372
381
|
}
|
373
382
|
|
374
|
-
/*
|
383
|
+
/*
|
375
384
|
* call-seq:
|
376
|
-
* PGconn.connect_start(
|
385
|
+
* PGconn.connect_start(connection_hash) -> PGconn
|
386
|
+
* PGconn.connect_start(connection_string) -> PGconn
|
387
|
+
* PGconn.connect_start(host, port, options, tty, dbname, login, password) -> PGconn
|
388
|
+
*
|
389
|
+
* This is an asynchronous version of PGconn.connect().
|
390
|
+
*
|
391
|
+
* Use PGconn#connect_poll to poll the status of the connection.
|
377
392
|
*/
|
378
393
|
static VALUE
|
379
394
|
pgconn_s_connect_start(int argc, VALUE *argv, VALUE self)
|
380
395
|
{
|
381
|
-
|
382
|
-
|
396
|
+
PGconn *conn = NULL;
|
397
|
+
VALUE rb_conn;
|
398
|
+
VALUE conninfo;
|
399
|
+
VALUE error;
|
400
|
+
|
401
|
+
/*
|
402
|
+
* PGconn.connect_start must act as both alloc() and initialize()
|
403
|
+
* because it is not invoked by calling new().
|
404
|
+
*/
|
405
|
+
rb_conn = pgconn_alloc(rb_cPGconn);
|
406
|
+
|
407
|
+
conninfo = parse_connect_args(argc, argv, self);
|
408
|
+
conn = PQconnectdb(StringValuePtr(conninfo));
|
409
|
+
|
410
|
+
if(conn == NULL)
|
411
|
+
rb_raise(rb_ePGError, "PQconnectStart() unable to allocate structure");
|
412
|
+
if (PQstatus(conn) == CONNECTION_BAD) {
|
413
|
+
error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
|
414
|
+
rb_iv_set(error, "@connection", self);
|
415
|
+
rb_exc_raise(error);
|
416
|
+
}
|
417
|
+
|
418
|
+
Check_Type(rb_conn, T_DATA);
|
419
|
+
DATA_PTR(rb_conn) = conn;
|
420
|
+
|
421
|
+
if (rb_block_given_p()) {
|
422
|
+
return rb_ensure(rb_yield, self, pgconn_finish, self);
|
423
|
+
}
|
424
|
+
return rb_conn;
|
383
425
|
}
|
384
426
|
|
385
427
|
/*
|
@@ -444,8 +486,7 @@ pgconn_s_conndefaults(VALUE self)
|
|
444
486
|
* Return value is the encrypted password.
|
445
487
|
*/
|
446
488
|
static VALUE
|
447
|
-
pgconn_s_encrypt_password(self, password, username)
|
448
|
-
VALUE self, password, username;
|
489
|
+
pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
449
490
|
{
|
450
491
|
char *ret;
|
451
492
|
Check_Type(password, T_STRING);
|
@@ -462,8 +503,7 @@ pgconn_s_encrypt_password(self, password, username)
|
|
462
503
|
* Returns +true+ if libpq is thread safe, +false+ otherwise.
|
463
504
|
*/
|
464
505
|
static VALUE
|
465
|
-
pgconn_s_isthreadsafe(self)
|
466
|
-
VALUE self;
|
506
|
+
pgconn_s_isthreadsafe(VALUE self)
|
467
507
|
{
|
468
508
|
return PQisthreadsafe() ? Qtrue : Qfalse;
|
469
509
|
}
|
@@ -472,11 +512,35 @@ pgconn_s_isthreadsafe(self)
|
|
472
512
|
* PGconn INSTANCE METHODS
|
473
513
|
**************************************************************************/
|
474
514
|
|
475
|
-
/*
|
515
|
+
/*
|
476
516
|
* call-seq:
|
477
517
|
* conn.connect_poll() -> Fixnum
|
478
518
|
*
|
479
|
-
*
|
519
|
+
* Returns one of:
|
520
|
+
* * +PGRES_POLLING_READING+ - wait until the socket is ready to read
|
521
|
+
* * +PGRES_POLLING_WRITING+ - wait until the socket is ready to write
|
522
|
+
* * +PGRES_POLLING_FAILED+ - the asynchronous connection has failed
|
523
|
+
* * +PGRES_POLLING_OK+ - the asynchronous connection is ready
|
524
|
+
*
|
525
|
+
* Example:
|
526
|
+
* conn = PGconn.connect_start("dbname=mydatabase")
|
527
|
+
* socket = IO.for_fd(conn.socket)
|
528
|
+
* status = conn.connect_poll
|
529
|
+
* while(status != PGconn::PGRES_POLLING_OK) do
|
530
|
+
* # do some work while waiting for the connection to complete
|
531
|
+
* if(status == PGconn::PGRES_POLLING_READING)
|
532
|
+
* if(not select([socket], [], [], 10.0))
|
533
|
+
* raise "Asynchronous connection timed out!"
|
534
|
+
* end
|
535
|
+
* elsif(status == PGconn::PGRES_POLLING_WRITING)
|
536
|
+
* if(not select([], [socket], [], 10.0))
|
537
|
+
* raise "Asynchronous connection timed out!"
|
538
|
+
* end
|
539
|
+
* end
|
540
|
+
* status = conn.connect_poll
|
541
|
+
* end
|
542
|
+
* # now conn.status == CONNECTION_OK, and connection
|
543
|
+
* # is ready.
|
480
544
|
*/
|
481
545
|
static VALUE
|
482
546
|
pgconn_connect_poll(VALUE self)
|
@@ -493,12 +557,11 @@ pgconn_connect_poll(VALUE self)
|
|
493
557
|
* Closes the backend connection.
|
494
558
|
*/
|
495
559
|
static VALUE
|
496
|
-
pgconn_finish(self)
|
497
|
-
VALUE self;
|
560
|
+
pgconn_finish(VALUE self)
|
498
561
|
{
|
499
|
-
|
500
|
-
|
501
|
-
|
562
|
+
PQfinish(get_pgconn(self));
|
563
|
+
DATA_PTR(self) = NULL;
|
564
|
+
return Qnil;
|
502
565
|
}
|
503
566
|
|
504
567
|
/*
|
@@ -509,11 +572,10 @@ pgconn_finish(self)
|
|
509
572
|
* backend connection and tries to re-connect.
|
510
573
|
*/
|
511
574
|
static VALUE
|
512
|
-
pgconn_reset(self)
|
513
|
-
VALUE self;
|
575
|
+
pgconn_reset(VALUE self)
|
514
576
|
{
|
515
|
-
|
516
|
-
|
577
|
+
PQreset(get_pgconn(self));
|
578
|
+
return self;
|
517
579
|
}
|
518
580
|
|
519
581
|
/*
|
@@ -557,12 +619,11 @@ pgconn_reset_poll(VALUE self)
|
|
557
619
|
* Returns the connected database name.
|
558
620
|
*/
|
559
621
|
static VALUE
|
560
|
-
pgconn_db(self)
|
561
|
-
VALUE self;
|
622
|
+
pgconn_db(VALUE self)
|
562
623
|
{
|
563
|
-
|
564
|
-
|
565
|
-
|
624
|
+
char *db = PQdb(get_pgconn(self));
|
625
|
+
if (!db) return Qnil;
|
626
|
+
return rb_tainted_str_new2(db);
|
566
627
|
}
|
567
628
|
|
568
629
|
/*
|
@@ -572,12 +633,11 @@ pgconn_db(self)
|
|
572
633
|
* Returns the authenticated user name.
|
573
634
|
*/
|
574
635
|
static VALUE
|
575
|
-
pgconn_user(self)
|
576
|
-
VALUE self;
|
636
|
+
pgconn_user(VALUE self)
|
577
637
|
{
|
578
|
-
|
579
|
-
|
580
|
-
|
638
|
+
char *user = PQuser(get_pgconn(self));
|
639
|
+
if (!user) return Qnil;
|
640
|
+
return rb_tainted_str_new2(user);
|
581
641
|
}
|
582
642
|
|
583
643
|
/*
|
@@ -587,12 +647,11 @@ pgconn_user(self)
|
|
587
647
|
* Returns the authenticated user name.
|
588
648
|
*/
|
589
649
|
static VALUE
|
590
|
-
pgconn_pass(self)
|
591
|
-
VALUE self;
|
650
|
+
pgconn_pass(VALUE self)
|
592
651
|
{
|
593
|
-
|
594
|
-
|
595
|
-
|
652
|
+
char *user = PQpass(get_pgconn(self));
|
653
|
+
if (!user) return Qnil;
|
654
|
+
return rb_tainted_str_new2(user);
|
596
655
|
}
|
597
656
|
|
598
657
|
/*
|
@@ -602,12 +661,11 @@ pgconn_pass(self)
|
|
602
661
|
* Returns the connected server name.
|
603
662
|
*/
|
604
663
|
static VALUE
|
605
|
-
pgconn_host(self)
|
606
|
-
VALUE self;
|
664
|
+
pgconn_host(VALUE self)
|
607
665
|
{
|
608
|
-
|
609
|
-
|
610
|
-
|
666
|
+
char *host = PQhost(get_pgconn(self));
|
667
|
+
if (!host) return Qnil;
|
668
|
+
return rb_tainted_str_new2(host);
|
611
669
|
}
|
612
670
|
|
613
671
|
/*
|
@@ -617,11 +675,10 @@ pgconn_host(self)
|
|
617
675
|
* Returns the connected server port number.
|
618
676
|
*/
|
619
677
|
static VALUE
|
620
|
-
pgconn_port(self)
|
621
|
-
VALUE self;
|
678
|
+
pgconn_port(VALUE self)
|
622
679
|
{
|
623
|
-
|
624
|
-
|
680
|
+
char* port = PQport(get_pgconn(self));
|
681
|
+
return INT2NUM(atol(port));
|
625
682
|
}
|
626
683
|
|
627
684
|
/*
|
@@ -631,12 +688,11 @@ pgconn_port(self)
|
|
631
688
|
* Returns the connected pgtty. (Obsolete)
|
632
689
|
*/
|
633
690
|
static VALUE
|
634
|
-
pgconn_tty(self)
|
635
|
-
VALUE self;
|
691
|
+
pgconn_tty(VALUE self)
|
636
692
|
{
|
637
|
-
|
638
|
-
|
639
|
-
|
693
|
+
char *tty = PQtty(get_pgconn(self));
|
694
|
+
if (!tty) return Qnil;
|
695
|
+
return rb_tainted_str_new2(tty);
|
640
696
|
}
|
641
697
|
|
642
698
|
/*
|
@@ -646,12 +702,11 @@ pgconn_tty(self)
|
|
646
702
|
* Returns backend option string.
|
647
703
|
*/
|
648
704
|
static VALUE
|
649
|
-
pgconn_options(self)
|
650
|
-
VALUE self;
|
705
|
+
pgconn_options(VALUE self)
|
651
706
|
{
|
652
|
-
|
653
|
-
|
654
|
-
|
707
|
+
char *options = PQoptions(get_pgconn(self));
|
708
|
+
if (!options) return Qnil;
|
709
|
+
return rb_tainted_str_new2(options);
|
655
710
|
}
|
656
711
|
|
657
712
|
/*
|
@@ -661,10 +716,9 @@ pgconn_options(self)
|
|
661
716
|
* Returns status of connection : CONNECTION_OK or CONNECTION_BAD
|
662
717
|
*/
|
663
718
|
static VALUE
|
664
|
-
pgconn_status(self)
|
665
|
-
VALUE self;
|
719
|
+
pgconn_status(VALUE self)
|
666
720
|
{
|
667
|
-
|
721
|
+
return INT2NUM(PQstatus(get_pgconn(self)));
|
668
722
|
}
|
669
723
|
|
670
724
|
/*
|
@@ -679,10 +733,9 @@ pgconn_status(self)
|
|
679
733
|
* PQTRANS_UNKNOWN = 4 (cannot determine status)
|
680
734
|
*/
|
681
735
|
static VALUE
|
682
|
-
pgconn_transaction_status(self)
|
683
|
-
VALUE self;
|
736
|
+
pgconn_transaction_status(VALUE self)
|
684
737
|
{
|
685
|
-
|
738
|
+
return INT2NUM(PQtransactionStatus(get_pgconn(self)));
|
686
739
|
}
|
687
740
|
|
688
741
|
/*
|
@@ -704,8 +757,7 @@ pgconn_transaction_status(self)
|
|
704
757
|
* Returns nil if the value of the parameter is not known.
|
705
758
|
*/
|
706
759
|
static VALUE
|
707
|
-
pgconn_parameter_status(self, param_name)
|
708
|
-
VALUE self, param_name;
|
760
|
+
pgconn_parameter_status(VALUE self, VALUE param_name)
|
709
761
|
{
|
710
762
|
const char *ret = PQparameterStatus(get_pgconn(self),
|
711
763
|
StringValuePtr(param_name));
|
@@ -724,10 +776,9 @@ pgconn_parameter_status(self, param_name)
|
|
724
776
|
* obsolete and not supported by libpq.)
|
725
777
|
*/
|
726
778
|
static VALUE
|
727
|
-
pgconn_protocol_version(self)
|
728
|
-
VALUE self;
|
779
|
+
pgconn_protocol_version(VALUE self)
|
729
780
|
{
|
730
|
-
|
781
|
+
return INT2NUM(PQprotocolVersion(get_pgconn(self)));
|
731
782
|
}
|
732
783
|
|
733
784
|
/*
|
@@ -737,10 +788,9 @@ pgconn_protocol_version(self)
|
|
737
788
|
* The number is formed by converting the major, minor, and revision numbers into two-decimal-digit numbers and appending them together. For example, version 7.4.2 will be returned as 70402, and version 8.1 will be returned as 80100 (leading zeroes are not shown). Zero is returned if the connection is bad.
|
738
789
|
*/
|
739
790
|
static VALUE
|
740
|
-
pgconn_server_version(self)
|
741
|
-
VALUE self;
|
791
|
+
pgconn_server_version(VALUE self)
|
742
792
|
{
|
743
|
-
|
793
|
+
return INT2NUM(PQserverVersion(get_pgconn(self)));
|
744
794
|
}
|
745
795
|
|
746
796
|
/*
|
@@ -750,12 +800,11 @@ pgconn_server_version(self)
|
|
750
800
|
* Returns the error message about connection.
|
751
801
|
*/
|
752
802
|
static VALUE
|
753
|
-
pgconn_error_message(self)
|
754
|
-
VALUE self;
|
803
|
+
pgconn_error_message(VALUE self)
|
755
804
|
{
|
756
|
-
|
757
|
-
|
758
|
-
|
805
|
+
char *error = PQerrorMessage(get_pgconn(self));
|
806
|
+
if (!error) return Qnil;
|
807
|
+
return rb_tainted_str_new2(error);
|
759
808
|
}
|
760
809
|
|
761
810
|
/*
|
@@ -783,8 +832,7 @@ pgconn_socket(VALUE self)
|
|
783
832
|
* Note that this is a PID on database server host.
|
784
833
|
*/
|
785
834
|
static VALUE
|
786
|
-
pgconn_backend_pid(self)
|
787
|
-
VALUE self;
|
835
|
+
pgconn_backend_pid(VALUE self)
|
788
836
|
{
|
789
837
|
return INT2NUM(PQbackendPID(get_pgconn(self)));
|
790
838
|
}
|
@@ -797,8 +845,7 @@ pgconn_backend_pid(self)
|
|
797
845
|
* password, but none was available. +false+ otherwise.
|
798
846
|
*/
|
799
847
|
static VALUE
|
800
|
-
pgconn_connection_needs_password(self)
|
801
|
-
VALUE self;
|
848
|
+
pgconn_connection_needs_password(VALUE self)
|
802
849
|
{
|
803
850
|
return PQconnectionNeedsPassword(get_pgconn(self)) ? Qtrue : Qfalse;
|
804
851
|
}
|
@@ -811,8 +858,7 @@ pgconn_connection_needs_password(self)
|
|
811
858
|
* a caller-supplied password, +false+ otherwise.
|
812
859
|
*/
|
813
860
|
static VALUE
|
814
|
-
pgconn_connection_used_password(self)
|
815
|
-
VALUE self;
|
861
|
+
pgconn_connection_used_password(VALUE self)
|
816
862
|
{
|
817
863
|
return PQconnectionUsedPassword(get_pgconn(self)) ? Qtrue : Qfalse;
|
818
864
|
}
|
@@ -853,10 +899,7 @@ pgconn_connection_used_password(self)
|
|
853
899
|
* for binary.
|
854
900
|
*/
|
855
901
|
static VALUE
|
856
|
-
pgconn_exec(argc, argv, self)
|
857
|
-
int argc;
|
858
|
-
VALUE *argv;
|
859
|
-
VALUE self;
|
902
|
+
pgconn_exec(int argc, VALUE *argv, VALUE self)
|
860
903
|
{
|
861
904
|
PGconn *conn = get_pgconn(self);
|
862
905
|
PGresult *result = NULL;
|
@@ -865,6 +908,7 @@ pgconn_exec(argc, argv, self)
|
|
865
908
|
VALUE param, param_type, param_value, param_format;
|
866
909
|
VALUE param_value_tmp;
|
867
910
|
VALUE sym_type, sym_value, sym_format;
|
911
|
+
VALUE gc_array;
|
868
912
|
int i=0;
|
869
913
|
int nParams;
|
870
914
|
Oid *paramTypes;
|
@@ -873,19 +917,19 @@ pgconn_exec(argc, argv, self)
|
|
873
917
|
int *paramFormats;
|
874
918
|
int resultFormat;
|
875
919
|
|
876
|
-
|
920
|
+
rb_scan_args(argc, argv, "12", &command, ¶ms, &in_res_fmt);
|
877
921
|
|
878
|
-
|
922
|
+
Check_Type(command, T_STRING);
|
879
923
|
|
880
924
|
/* If called with no parameters, use PQexec */
|
881
925
|
if(NIL_P(params)) {
|
882
926
|
result = PQexec(conn, StringValuePtr(command));
|
883
927
|
rb_pgresult = new_pgresult(result);
|
884
928
|
pgresult_check(self, rb_pgresult);
|
885
|
-
|
886
|
-
|
929
|
+
if (rb_block_given_p()) {
|
930
|
+
return rb_ensure(yield_pgresult, rb_pgresult,
|
887
931
|
pgresult_clear, rb_pgresult);
|
888
|
-
|
932
|
+
}
|
889
933
|
return rb_pgresult;
|
890
934
|
}
|
891
935
|
|
@@ -901,6 +945,8 @@ pgconn_exec(argc, argv, self)
|
|
901
945
|
resultFormat = NUM2INT(in_res_fmt);
|
902
946
|
}
|
903
947
|
|
948
|
+
gc_array = rb_ary_new();
|
949
|
+
rb_gc_register_address(&gc_array);
|
904
950
|
sym_type = ID2SYM(rb_intern("type"));
|
905
951
|
sym_value = ID2SYM(rb_intern("value"));
|
906
952
|
sym_format = ID2SYM(rb_intern("format"));
|
@@ -940,6 +986,8 @@ pgconn_exec(argc, argv, self)
|
|
940
986
|
}
|
941
987
|
else {
|
942
988
|
Check_Type(param_value, T_STRING);
|
989
|
+
/* make sure param_value doesn't get freed by the GC */
|
990
|
+
rb_ary_push(gc_array, param_value);
|
943
991
|
paramValues[i] = StringValuePtr(param_value);
|
944
992
|
paramLengths[i] = RSTRING_LEN(param_value);
|
945
993
|
}
|
@@ -953,6 +1001,8 @@ pgconn_exec(argc, argv, self)
|
|
953
1001
|
result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
|
954
1002
|
(const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
|
955
1003
|
|
1004
|
+
rb_gc_unregister_address(&gc_array);
|
1005
|
+
|
956
1006
|
free(paramTypes);
|
957
1007
|
free(paramValues);
|
958
1008
|
free(paramLengths);
|
@@ -960,10 +1010,10 @@ pgconn_exec(argc, argv, self)
|
|
960
1010
|
|
961
1011
|
rb_pgresult = new_pgresult(result);
|
962
1012
|
pgresult_check(self, rb_pgresult);
|
963
|
-
|
964
|
-
|
1013
|
+
if (rb_block_given_p()) {
|
1014
|
+
return rb_ensure(yield_pgresult, rb_pgresult,
|
965
1015
|
pgresult_clear, rb_pgresult);
|
966
|
-
|
1016
|
+
}
|
967
1017
|
return rb_pgresult;
|
968
1018
|
}
|
969
1019
|
|
@@ -988,10 +1038,7 @@ pgconn_exec(argc, argv, self)
|
|
988
1038
|
* inside the SQL query.
|
989
1039
|
*/
|
990
1040
|
static VALUE
|
991
|
-
pgconn_prepare(argc, argv, self)
|
992
|
-
int argc;
|
993
|
-
VALUE *argv;
|
994
|
-
VALUE self;
|
1041
|
+
pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
995
1042
|
{
|
996
1043
|
PGconn *conn = get_pgconn(self);
|
997
1044
|
PGresult *result = NULL;
|
@@ -1002,9 +1049,9 @@ pgconn_prepare(argc, argv, self)
|
|
1002
1049
|
int nParams = 0;
|
1003
1050
|
Oid *paramTypes = NULL;
|
1004
1051
|
|
1005
|
-
|
1052
|
+
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1006
1053
|
Check_Type(name, T_STRING);
|
1007
|
-
|
1054
|
+
Check_Type(command, T_STRING);
|
1008
1055
|
|
1009
1056
|
if(! NIL_P(in_paramtypes)) {
|
1010
1057
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1054,10 +1101,7 @@ pgconn_prepare(argc, argv, self)
|
|
1054
1101
|
* for binary.
|
1055
1102
|
*/
|
1056
1103
|
static VALUE
|
1057
|
-
pgconn_exec_prepared(argc, argv, self)
|
1058
|
-
int argc;
|
1059
|
-
VALUE *argv;
|
1060
|
-
VALUE self;
|
1104
|
+
pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
1061
1105
|
{
|
1062
1106
|
PGconn *conn = get_pgconn(self);
|
1063
1107
|
PGresult *result = NULL;
|
@@ -1066,6 +1110,7 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1066
1110
|
VALUE param, param_value, param_format;
|
1067
1111
|
VALUE param_value_tmp;
|
1068
1112
|
VALUE sym_value, sym_format;
|
1113
|
+
VALUE gc_array;
|
1069
1114
|
int i = 0;
|
1070
1115
|
int nParams;
|
1071
1116
|
char ** paramValues;
|
@@ -1074,7 +1119,7 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1074
1119
|
int resultFormat;
|
1075
1120
|
|
1076
1121
|
|
1077
|
-
|
1122
|
+
rb_scan_args(argc, argv, "12", &name, ¶ms, &in_res_fmt);
|
1078
1123
|
Check_Type(name, T_STRING);
|
1079
1124
|
|
1080
1125
|
if(NIL_P(params)) {
|
@@ -1092,6 +1137,8 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1092
1137
|
resultFormat = NUM2INT(in_res_fmt);
|
1093
1138
|
}
|
1094
1139
|
|
1140
|
+
gc_array = rb_ary_new();
|
1141
|
+
rb_gc_register_address(&gc_array);
|
1095
1142
|
sym_value = ID2SYM(rb_intern("value"));
|
1096
1143
|
sym_format = ID2SYM(rb_intern("format"));
|
1097
1144
|
nParams = RARRAY(params)->len;
|
@@ -1121,6 +1168,8 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1121
1168
|
}
|
1122
1169
|
else {
|
1123
1170
|
Check_Type(param_value, T_STRING);
|
1171
|
+
/* make sure param_value doesn't get freed by the GC */
|
1172
|
+
rb_ary_push(gc_array, param_value);
|
1124
1173
|
paramValues[i] = StringValuePtr(param_value);
|
1125
1174
|
paramLengths[i] = RSTRING_LEN(param_value);
|
1126
1175
|
}
|
@@ -1135,16 +1184,18 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1135
1184
|
(const char * const *)paramValues, paramLengths, paramFormats,
|
1136
1185
|
resultFormat);
|
1137
1186
|
|
1187
|
+
rb_gc_unregister_address(&gc_array);
|
1188
|
+
|
1138
1189
|
free(paramValues);
|
1139
1190
|
free(paramLengths);
|
1140
1191
|
free(paramFormats);
|
1141
1192
|
|
1142
1193
|
rb_pgresult = new_pgresult(result);
|
1143
1194
|
pgresult_check(self, rb_pgresult);
|
1144
|
-
|
1145
|
-
|
1195
|
+
if (rb_block_given_p()) {
|
1196
|
+
return rb_ensure(yield_pgresult, rb_pgresult,
|
1146
1197
|
pgresult_clear, rb_pgresult);
|
1147
|
-
|
1198
|
+
}
|
1148
1199
|
return rb_pgresult;
|
1149
1200
|
}
|
1150
1201
|
|
@@ -1156,8 +1207,7 @@ pgconn_exec_prepared(argc, argv, self)
|
|
1156
1207
|
* _statement_name_.
|
1157
1208
|
*/
|
1158
1209
|
static VALUE
|
1159
|
-
pgconn_describe_prepared(self, stmt_name)
|
1160
|
-
VALUE self, stmt_name;
|
1210
|
+
pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
1161
1211
|
{
|
1162
1212
|
PGresult *result;
|
1163
1213
|
VALUE rb_pgresult;
|
@@ -1250,30 +1300,29 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1250
1300
|
* inside of SQL commands.
|
1251
1301
|
*/
|
1252
1302
|
static VALUE
|
1253
|
-
pgconn_s_escape(self, string)
|
1254
|
-
VALUE self;
|
1255
|
-
VALUE string;
|
1303
|
+
pgconn_s_escape(VALUE self, VALUE string)
|
1256
1304
|
{
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1305
|
+
char *escaped;
|
1306
|
+
int size,error;
|
1307
|
+
VALUE result;
|
1260
1308
|
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1309
|
+
Check_Type(string, T_STRING);
|
1310
|
+
|
1311
|
+
escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1);
|
1312
|
+
if(CLASS_OF(self) == rb_cPGconn) {
|
1313
|
+
size = PQescapeStringConn(get_pgconn(self), escaped,
|
1266
1314
|
RSTRING_PTR(string), RSTRING_LEN(string), &error);
|
1267
1315
|
if(error) {
|
1268
1316
|
rb_raise(rb_ePGError, PQerrorMessage(get_pgconn(self)));
|
1269
1317
|
}
|
1270
|
-
|
1271
|
-
|
1318
|
+
} else {
|
1319
|
+
size = PQescapeString(escaped, RSTRING_PTR(string),
|
1272
1320
|
RSTRING_LEN(string));
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1321
|
+
}
|
1322
|
+
result = rb_str_new(escaped, size);
|
1323
|
+
free(escaped);
|
1324
|
+
OBJ_INFECT(result, string);
|
1325
|
+
return result;
|
1277
1326
|
}
|
1278
1327
|
|
1279
1328
|
/*
|
@@ -1302,28 +1351,26 @@ pgconn_s_escape(self, string)
|
|
1302
1351
|
* SQL commands.
|
1303
1352
|
*/
|
1304
1353
|
static VALUE
|
1305
|
-
pgconn_s_escape_bytea(self, str)
|
1306
|
-
VALUE self;
|
1307
|
-
VALUE str;
|
1354
|
+
pgconn_s_escape_bytea(VALUE self, VALUE str)
|
1308
1355
|
{
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1356
|
+
unsigned char *from, *to;
|
1357
|
+
size_t from_len, to_len;
|
1358
|
+
VALUE ret;
|
1359
|
+
|
1360
|
+
Check_Type(str, T_STRING);
|
1361
|
+
from = (unsigned char*)RSTRING_PTR(str);
|
1362
|
+
from_len = RSTRING_LEN(str);
|
1363
|
+
|
1364
|
+
if(CLASS_OF(self) == rb_cPGconn) {
|
1318
1365
|
to = PQescapeByteaConn(get_pgconn(self), from, from_len, &to_len);
|
1319
|
-
|
1366
|
+
} else {
|
1320
1367
|
to = PQescapeBytea( from, from_len, &to_len);
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
ret = rb_str_new((char*)to, to_len - 1);
|
1371
|
+
OBJ_INFECT(ret, str);
|
1372
|
+
PQfreemem(to);
|
1373
|
+
return ret;
|
1327
1374
|
}
|
1328
1375
|
|
1329
1376
|
|
@@ -1337,22 +1384,21 @@ pgconn_s_escape_bytea(self, str)
|
|
1337
1384
|
*
|
1338
1385
|
*/
|
1339
1386
|
static VALUE
|
1340
|
-
pgconn_s_unescape_bytea(self, str)
|
1341
|
-
VALUE self, str;
|
1387
|
+
pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
1342
1388
|
{
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1389
|
+
unsigned char *from, *to;
|
1390
|
+
size_t to_len;
|
1391
|
+
VALUE ret;
|
1346
1392
|
|
1347
|
-
|
1348
|
-
|
1393
|
+
Check_Type(str, T_STRING);
|
1394
|
+
from = (unsigned char*)StringValuePtr(str);
|
1349
1395
|
|
1350
|
-
|
1396
|
+
to = PQunescapeBytea(from, &to_len);
|
1351
1397
|
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1398
|
+
ret = rb_str_new((char*)to, to_len);
|
1399
|
+
OBJ_INFECT(ret, str);
|
1400
|
+
PQfreemem(to);
|
1401
|
+
return ret;
|
1356
1402
|
}
|
1357
1403
|
|
1358
1404
|
/*
|
@@ -1387,17 +1433,15 @@ pgconn_s_unescape_bytea(self, str)
|
|
1387
1433
|
* for binary.
|
1388
1434
|
*/
|
1389
1435
|
static VALUE
|
1390
|
-
pgconn_send_query(argc, argv, self)
|
1391
|
-
int argc;
|
1392
|
-
VALUE *argv;
|
1393
|
-
VALUE self;
|
1436
|
+
pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
1394
1437
|
{
|
1395
|
-
|
1396
|
-
|
1438
|
+
PGconn *conn = get_pgconn(self);
|
1439
|
+
int result;
|
1397
1440
|
VALUE command, params, in_res_fmt;
|
1398
1441
|
VALUE param, param_type, param_value, param_format;
|
1399
1442
|
VALUE param_value_tmp;
|
1400
1443
|
VALUE sym_type, sym_value, sym_format;
|
1444
|
+
VALUE gc_array;
|
1401
1445
|
VALUE error;
|
1402
1446
|
int i=0;
|
1403
1447
|
int nParams;
|
@@ -1407,8 +1451,8 @@ pgconn_send_query(argc, argv, self)
|
|
1407
1451
|
int *paramFormats;
|
1408
1452
|
int resultFormat;
|
1409
1453
|
|
1410
|
-
|
1411
|
-
|
1454
|
+
rb_scan_args(argc, argv, "12", &command, ¶ms, &in_res_fmt);
|
1455
|
+
Check_Type(command, T_STRING);
|
1412
1456
|
|
1413
1457
|
/* If called with no parameters, use PQsendQuery */
|
1414
1458
|
if(NIL_P(params)) {
|
@@ -1432,6 +1476,8 @@ pgconn_send_query(argc, argv, self)
|
|
1432
1476
|
resultFormat = NUM2INT(in_res_fmt);
|
1433
1477
|
}
|
1434
1478
|
|
1479
|
+
gc_array = rb_ary_new();
|
1480
|
+
rb_gc_register_address(&gc_array);
|
1435
1481
|
sym_type = ID2SYM(rb_intern("type"));
|
1436
1482
|
sym_value = ID2SYM(rb_intern("value"));
|
1437
1483
|
sym_format = ID2SYM(rb_intern("format"));
|
@@ -1471,6 +1517,8 @@ pgconn_send_query(argc, argv, self)
|
|
1471
1517
|
}
|
1472
1518
|
else {
|
1473
1519
|
Check_Type(param_value, T_STRING);
|
1520
|
+
/* make sure param_value doesn't get freed by the GC */
|
1521
|
+
rb_ary_push(gc_array, param_value);
|
1474
1522
|
paramValues[i] = StringValuePtr(param_value);
|
1475
1523
|
paramLengths[i] = RSTRING_LEN(param_value);
|
1476
1524
|
}
|
@@ -1484,6 +1532,8 @@ pgconn_send_query(argc, argv, self)
|
|
1484
1532
|
result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
|
1485
1533
|
(const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
|
1486
1534
|
|
1535
|
+
rb_gc_unregister_address(&gc_array);
|
1536
|
+
|
1487
1537
|
free(paramTypes);
|
1488
1538
|
free(paramValues);
|
1489
1539
|
free(paramLengths);
|
@@ -1518,12 +1568,9 @@ pgconn_send_query(argc, argv, self)
|
|
1518
1568
|
* inside the SQL query.
|
1519
1569
|
*/
|
1520
1570
|
static VALUE
|
1521
|
-
pgconn_send_prepare(argc, argv, self)
|
1522
|
-
int argc;
|
1523
|
-
VALUE *argv;
|
1524
|
-
VALUE self;
|
1571
|
+
pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
1525
1572
|
{
|
1526
|
-
|
1573
|
+
PGconn *conn = get_pgconn(self);
|
1527
1574
|
int result;
|
1528
1575
|
VALUE name, command, in_paramtypes;
|
1529
1576
|
VALUE param;
|
@@ -1532,9 +1579,9 @@ pgconn_send_prepare(argc, argv, self)
|
|
1532
1579
|
int nParams = 0;
|
1533
1580
|
Oid *paramTypes = NULL;
|
1534
1581
|
|
1535
|
-
|
1582
|
+
rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
|
1536
1583
|
Check_Type(name, T_STRING);
|
1537
|
-
|
1584
|
+
Check_Type(command, T_STRING);
|
1538
1585
|
|
1539
1586
|
if(! NIL_P(in_paramtypes)) {
|
1540
1587
|
Check_Type(in_paramtypes, T_ARRAY);
|
@@ -1588,17 +1635,15 @@ pgconn_send_prepare(argc, argv, self)
|
|
1588
1635
|
* for binary.
|
1589
1636
|
*/
|
1590
1637
|
static VALUE
|
1591
|
-
pgconn_send_query_prepared(argc, argv, self)
|
1592
|
-
int argc;
|
1593
|
-
VALUE *argv;
|
1594
|
-
VALUE self;
|
1638
|
+
pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
1595
1639
|
{
|
1596
|
-
|
1597
|
-
|
1640
|
+
PGconn *conn = get_pgconn(self);
|
1641
|
+
int result;
|
1598
1642
|
VALUE name, params, in_res_fmt;
|
1599
1643
|
VALUE param, param_value, param_format;
|
1600
1644
|
VALUE param_value_tmp;
|
1601
1645
|
VALUE sym_value, sym_format;
|
1646
|
+
VALUE gc_array;
|
1602
1647
|
VALUE error;
|
1603
1648
|
int i = 0;
|
1604
1649
|
int nParams;
|
@@ -1607,7 +1652,7 @@ pgconn_send_query_prepared(argc, argv, self)
|
|
1607
1652
|
int *paramFormats;
|
1608
1653
|
int resultFormat;
|
1609
1654
|
|
1610
|
-
|
1655
|
+
rb_scan_args(argc, argv, "12", &name, ¶ms, &in_res_fmt);
|
1611
1656
|
Check_Type(name, T_STRING);
|
1612
1657
|
|
1613
1658
|
if(NIL_P(params)) {
|
@@ -1625,6 +1670,8 @@ pgconn_send_query_prepared(argc, argv, self)
|
|
1625
1670
|
resultFormat = NUM2INT(in_res_fmt);
|
1626
1671
|
}
|
1627
1672
|
|
1673
|
+
gc_array = rb_ary_new();
|
1674
|
+
rb_gc_register_address(&gc_array);
|
1628
1675
|
sym_value = ID2SYM(rb_intern("value"));
|
1629
1676
|
sym_format = ID2SYM(rb_intern("format"));
|
1630
1677
|
nParams = RARRAY(params)->len;
|
@@ -1655,6 +1702,8 @@ pgconn_send_query_prepared(argc, argv, self)
|
|
1655
1702
|
}
|
1656
1703
|
else {
|
1657
1704
|
Check_Type(param_value, T_STRING);
|
1705
|
+
/* make sure param_value doesn't get freed by the GC */
|
1706
|
+
rb_ary_push(gc_array, param_value);
|
1658
1707
|
paramValues[i] = StringValuePtr(param_value);
|
1659
1708
|
paramLengths[i] = RSTRING_LEN(param_value);
|
1660
1709
|
}
|
@@ -1669,6 +1718,8 @@ pgconn_send_query_prepared(argc, argv, self)
|
|
1669
1718
|
(const char * const *)paramValues, paramLengths, paramFormats,
|
1670
1719
|
resultFormat);
|
1671
1720
|
|
1721
|
+
rb_gc_unregister_address(&gc_array);
|
1722
|
+
|
1672
1723
|
free(paramValues);
|
1673
1724
|
free(paramLengths);
|
1674
1725
|
free(paramFormats);
|
@@ -1689,8 +1740,7 @@ pgconn_send_query_prepared(argc, argv, self)
|
|
1689
1740
|
* Use in combination with +conn.get_result+.
|
1690
1741
|
*/
|
1691
1742
|
static VALUE
|
1692
|
-
pgconn_send_describe_prepared(self, stmt_name)
|
1693
|
-
VALUE self, stmt_name;
|
1743
|
+
pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
1694
1744
|
{
|
1695
1745
|
VALUE error;
|
1696
1746
|
PGconn *conn = get_pgconn(self);
|
@@ -1712,8 +1762,7 @@ pgconn_send_describe_prepared(self, stmt_name)
|
|
1712
1762
|
* Use in combination with +conn.get_result+.
|
1713
1763
|
*/
|
1714
1764
|
static VALUE
|
1715
|
-
pgconn_send_describe_portal(self, portal)
|
1716
|
-
VALUE self, portal;
|
1765
|
+
pgconn_send_describe_portal(VALUE self, VALUE portal)
|
1717
1766
|
{
|
1718
1767
|
VALUE error;
|
1719
1768
|
PGconn *conn = get_pgconn(self);
|
@@ -1740,8 +1789,7 @@ pgconn_send_describe_portal(self, portal)
|
|
1740
1789
|
* or else you will not be able to issue further commands.
|
1741
1790
|
*/
|
1742
1791
|
static VALUE
|
1743
|
-
pgconn_get_result(self)
|
1744
|
-
VALUE self;
|
1792
|
+
pgconn_get_result(VALUE self)
|
1745
1793
|
{
|
1746
1794
|
PGconn *conn = get_pgconn(self);
|
1747
1795
|
PGresult *result;
|
@@ -1752,10 +1800,10 @@ pgconn_get_result(self)
|
|
1752
1800
|
return Qnil;
|
1753
1801
|
rb_pgresult = new_pgresult(result);
|
1754
1802
|
pgresult_check(self, rb_pgresult);
|
1755
|
-
|
1756
|
-
|
1803
|
+
if (rb_block_given_p()) {
|
1804
|
+
return rb_ensure(yield_pgresult, rb_pgresult,
|
1757
1805
|
pgresult_clear, rb_pgresult);
|
1758
|
-
|
1806
|
+
}
|
1759
1807
|
return rb_pgresult;
|
1760
1808
|
}
|
1761
1809
|
|
@@ -1798,10 +1846,19 @@ pgconn_is_busy(self)
|
|
1798
1846
|
|
1799
1847
|
/*
|
1800
1848
|
* call-seq:
|
1801
|
-
* conn.setnonblocking() ->
|
1849
|
+
* conn.setnonblocking(Boolean) -> nil
|
1802
1850
|
*
|
1803
|
-
*
|
1804
|
-
*
|
1851
|
+
* Sets the nonblocking status of the connection.
|
1852
|
+
* In the blocking state, calls to PGconn#send_query
|
1853
|
+
* will block until the message is sent to the server,
|
1854
|
+
* but will not wait for the query results.
|
1855
|
+
* In the nonblocking state, calls to PGconn#send_query
|
1856
|
+
* will return an error if the socket is not ready for
|
1857
|
+
* writing.
|
1858
|
+
* Note: This function does not affect PGconn#exec, because
|
1859
|
+
* that function doesn't return until the server has
|
1860
|
+
* processed the query and returned the results.
|
1861
|
+
* Returns +nil+.
|
1805
1862
|
*/
|
1806
1863
|
static VALUE
|
1807
1864
|
pgconn_setnonblocking(self, state)
|
@@ -1866,11 +1923,37 @@ pgconn_flush(self)
|
|
1866
1923
|
return (ret) ? Qfalse : Qtrue;
|
1867
1924
|
}
|
1868
1925
|
|
1869
|
-
|
1926
|
+
/*
|
1927
|
+
* call-seq:
|
1928
|
+
* conn.cancel() -> String
|
1929
|
+
*
|
1930
|
+
* Requests cancellation of the command currently being
|
1931
|
+
* processed.
|
1932
|
+
*
|
1933
|
+
* Returns +nil+ on success, or a string containing the
|
1934
|
+
* error message if a failure occurs.
|
1935
|
+
*/
|
1936
|
+
static VALUE
|
1937
|
+
pgconn_cancel(VALUE self)
|
1938
|
+
{
|
1939
|
+
char errbuf[256];
|
1940
|
+
PGcancel *cancel;
|
1941
|
+
VALUE retval;
|
1942
|
+
int ret;
|
1870
1943
|
|
1871
|
-
|
1944
|
+
cancel = PQgetCancel(get_pgconn(self));
|
1945
|
+
if(cancel == NULL)
|
1946
|
+
rb_raise(rb_ePGError,"Invalid connection!");
|
1872
1947
|
|
1873
|
-
|
1948
|
+
ret = PQcancel(cancel, errbuf, 256);
|
1949
|
+
if(ret == 1)
|
1950
|
+
retval = Qnil;
|
1951
|
+
else
|
1952
|
+
retval = rb_str_new2(errbuf);
|
1953
|
+
|
1954
|
+
PQfreeCancel(cancel);
|
1955
|
+
return retval;
|
1956
|
+
}
|
1874
1957
|
|
1875
1958
|
/*
|
1876
1959
|
* call-seq:
|
@@ -1880,12 +1963,11 @@ pgconn_flush(self)
|
|
1880
1963
|
* If there is no unprocessed notifier, it returns +nil+.
|
1881
1964
|
*/
|
1882
1965
|
static VALUE
|
1883
|
-
pgconn_notifies(self)
|
1884
|
-
VALUE self;
|
1966
|
+
pgconn_notifies(VALUE self)
|
1885
1967
|
{
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1968
|
+
PGconn* conn = get_pgconn(self);
|
1969
|
+
PGnotify *notify;
|
1970
|
+
VALUE hash;
|
1889
1971
|
VALUE sym_relname, sym_be_pid, sym_extra;
|
1890
1972
|
VALUE relname, be_pid, extra;
|
1891
1973
|
|
@@ -1893,22 +1975,22 @@ pgconn_notifies(self)
|
|
1893
1975
|
sym_be_pid = ID2SYM(rb_intern("be_pid"));
|
1894
1976
|
sym_extra = ID2SYM(rb_intern("extra"));
|
1895
1977
|
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1978
|
+
notify = PQnotifies(conn);
|
1979
|
+
if (notify == NULL) {
|
1980
|
+
return Qnil;
|
1981
|
+
}
|
1900
1982
|
|
1901
1983
|
hash = rb_hash_new();
|
1902
1984
|
relname = rb_tainted_str_new2(notify->relname);
|
1903
1985
|
be_pid = INT2NUM(notify->be_pid);
|
1904
1986
|
extra = rb_tainted_str_new2(PGNOTIFY_EXTRA(notify));
|
1905
1987
|
|
1906
|
-
|
1988
|
+
rb_hash_aset(hash, sym_relname, relname);
|
1907
1989
|
rb_hash_aset(hash, sym_be_pid, be_pid);
|
1908
1990
|
rb_hash_aset(hash, sym_extra, extra);
|
1909
1991
|
|
1910
|
-
|
1911
|
-
|
1992
|
+
PQfreemem(notify);
|
1993
|
+
return hash;
|
1912
1994
|
}
|
1913
1995
|
|
1914
1996
|
|
@@ -1957,23 +2039,20 @@ pgconn_put_copy_data(self, buffer)
|
|
1957
2039
|
* is in nonblocking mode, and this command would block).
|
1958
2040
|
*/
|
1959
2041
|
static VALUE
|
1960
|
-
pgconn_put_copy_end(argc, argv, self)
|
1961
|
-
int argc;
|
1962
|
-
VALUE *argv;
|
1963
|
-
VALUE self;
|
2042
|
+
pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
1964
2043
|
{
|
1965
|
-
|
2044
|
+
VALUE str;
|
1966
2045
|
VALUE error;
|
1967
2046
|
int ret;
|
1968
2047
|
char *error_message = NULL;
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
2048
|
+
PGconn *conn = get_pgconn(self);
|
2049
|
+
|
2050
|
+
if (rb_scan_args(argc, argv, "01", &str) == 0)
|
2051
|
+
error_message = NULL;
|
2052
|
+
else
|
2053
|
+
error_message = StringValuePtr(str);
|
2054
|
+
|
2055
|
+
ret = PQputCopyEnd(conn, error_message);
|
1977
2056
|
if(ret == -1) {
|
1978
2057
|
error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
|
1979
2058
|
rb_iv_set(error, "@connection", self);
|
@@ -1992,25 +2071,22 @@ pgconn_put_copy_end(argc, argv, self)
|
|
1992
2071
|
*
|
1993
2072
|
*/
|
1994
2073
|
static VALUE
|
1995
|
-
pgconn_get_copy_data( argc, argv, self )
|
1996
|
-
int argc;
|
1997
|
-
VALUE *argv;
|
1998
|
-
VALUE self;
|
2074
|
+
pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
1999
2075
|
{
|
2000
|
-
|
2076
|
+
VALUE async_in;
|
2001
2077
|
VALUE error;
|
2002
2078
|
VALUE result_str;
|
2003
2079
|
int ret;
|
2004
2080
|
int async;
|
2005
2081
|
char *buffer;
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2082
|
+
PGconn *conn = get_pgconn(self);
|
2083
|
+
|
2084
|
+
if (rb_scan_args(argc, argv, "01", &async_in) == 0)
|
2085
|
+
async = 0;
|
2086
|
+
else
|
2011
2087
|
async = (async_in == Qfalse || async_in == Qnil) ? 0 : 1;
|
2012
2088
|
|
2013
|
-
|
2089
|
+
ret = PQgetCopyData(conn, &buffer, async);
|
2014
2090
|
if(ret == -2) { // error
|
2015
2091
|
error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
|
2016
2092
|
rb_iv_set(error, "@connection", self);
|
@@ -2097,8 +2173,7 @@ pgconn_trace(VALUE self, VALUE stream)
|
|
2097
2173
|
* Disables the message tracing.
|
2098
2174
|
*/
|
2099
2175
|
static VALUE
|
2100
|
-
pgconn_untrace(self)
|
2101
|
-
VALUE self;
|
2176
|
+
pgconn_untrace(VALUE self)
|
2102
2177
|
{
|
2103
2178
|
VALUE trace_stream;
|
2104
2179
|
PQuntrace(get_pgconn(self));
|
@@ -2129,8 +2204,8 @@ pgconn_untrace(self)
|
|
2129
2204
|
static VALUE
|
2130
2205
|
pgconn_set_notice_receiver(VALUE self)
|
2131
2206
|
{
|
2132
|
-
|
2133
|
-
|
2207
|
+
VALUE proc, old_proc;
|
2208
|
+
PGconn *conn = get_pgconn(self);
|
2134
2209
|
|
2135
2210
|
/* If default_notice_receiver is unset, assume that the current
|
2136
2211
|
* notice receiver is the default, and save it to a global variable.
|
@@ -2175,8 +2250,8 @@ pgconn_set_notice_receiver(VALUE self)
|
|
2175
2250
|
static VALUE
|
2176
2251
|
pgconn_set_notice_processor(VALUE self)
|
2177
2252
|
{
|
2178
|
-
|
2179
|
-
|
2253
|
+
VALUE proc, old_proc;
|
2254
|
+
PGconn *conn = get_pgconn(self);
|
2180
2255
|
|
2181
2256
|
/* If default_notice_processor is unset, assume that the current
|
2182
2257
|
* notice processor is the default, and save it to a global variable.
|
@@ -2206,11 +2281,10 @@ pgconn_set_notice_processor(VALUE self)
|
|
2206
2281
|
* Returns the client encoding as a String.
|
2207
2282
|
*/
|
2208
2283
|
static VALUE
|
2209
|
-
pgconn_get_client_encoding(self)
|
2210
|
-
VALUE self;
|
2284
|
+
pgconn_get_client_encoding(VALUE self)
|
2211
2285
|
{
|
2212
|
-
|
2213
|
-
|
2286
|
+
char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(get_pgconn(self)));
|
2287
|
+
return rb_tainted_str_new2(encoding);
|
2214
2288
|
}
|
2215
2289
|
|
2216
2290
|
/*
|
@@ -2220,14 +2294,13 @@ pgconn_get_client_encoding(self)
|
|
2220
2294
|
* Sets the client encoding to the _encoding_ String.
|
2221
2295
|
*/
|
2222
2296
|
static VALUE
|
2223
|
-
pgconn_set_client_encoding(self, str)
|
2224
|
-
VALUE self, str;
|
2297
|
+
pgconn_set_client_encoding(VALUE self, VALUE str)
|
2225
2298
|
{
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2230
|
-
|
2299
|
+
Check_Type(str, T_STRING);
|
2300
|
+
if ((PQsetClientEncoding(get_pgconn(self), StringValuePtr(str))) == -1){
|
2301
|
+
rb_raise(rb_ePGError, "invalid encoding name: %s",StringValuePtr(str));
|
2302
|
+
}
|
2303
|
+
return Qnil;
|
2231
2304
|
}
|
2232
2305
|
|
2233
2306
|
/*
|
@@ -2298,7 +2371,7 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
|
|
2298
2371
|
VALUE ret;
|
2299
2372
|
char *str = StringValuePtr(in_str);
|
2300
2373
|
/* result size at most NAMEDATALEN*2 plus surrounding
|
2301
|
-
|
2374
|
+
* double-quotes. */
|
2302
2375
|
char buffer[NAMEDATALEN*2+2];
|
2303
2376
|
unsigned int i=0,j=0;
|
2304
2377
|
|
@@ -2422,26 +2495,23 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
2422
2495
|
* On failure, it raises PGError exception.
|
2423
2496
|
*/
|
2424
2497
|
static VALUE
|
2425
|
-
pgconn_locreat(argc, argv, self)
|
2426
|
-
int argc;
|
2427
|
-
VALUE *argv;
|
2428
|
-
VALUE self;
|
2498
|
+
pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
2429
2499
|
{
|
2430
|
-
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
if (rb_scan_args(argc, argv, "01", &nmode) == 0)
|
2436
|
-
mode = INV_READ;
|
2437
|
-
else
|
2438
|
-
mode = NUM2INT(nmode);
|
2439
|
-
|
2440
|
-
lo_oid = lo_creat(conn, mode);
|
2441
|
-
if (lo_oid == 0)
|
2442
|
-
rb_raise(rb_ePGError, "lo_creat failed");
|
2500
|
+
Oid lo_oid;
|
2501
|
+
int mode;
|
2502
|
+
VALUE nmode;
|
2503
|
+
PGconn *conn = get_pgconn(self);
|
2443
2504
|
|
2444
|
-
|
2505
|
+
if (rb_scan_args(argc, argv, "01", &nmode) == 0)
|
2506
|
+
mode = INV_READ;
|
2507
|
+
else
|
2508
|
+
mode = NUM2INT(nmode);
|
2509
|
+
|
2510
|
+
lo_oid = lo_creat(conn, mode);
|
2511
|
+
if (lo_oid == 0)
|
2512
|
+
rb_raise(rb_ePGError, "lo_creat failed");
|
2513
|
+
|
2514
|
+
return INT2FIX(lo_oid);
|
2445
2515
|
}
|
2446
2516
|
|
2447
2517
|
/*
|
@@ -2452,18 +2522,17 @@ pgconn_locreat(argc, argv, self)
|
|
2452
2522
|
* On failure, it raises PGError exception.
|
2453
2523
|
*/
|
2454
2524
|
static VALUE
|
2455
|
-
pgconn_locreate(self, in_lo_oid)
|
2456
|
-
VALUE self, in_lo_oid;
|
2525
|
+
pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
2457
2526
|
{
|
2458
|
-
|
2459
|
-
|
2527
|
+
Oid ret, lo_oid;
|
2528
|
+
PGconn *conn = get_pgconn(self);
|
2460
2529
|
lo_oid = NUM2INT(in_lo_oid);
|
2461
|
-
|
2462
|
-
ret = lo_create(conn, in_lo_oid);
|
2463
|
-
if (ret == InvalidOid)
|
2464
|
-
rb_raise(rb_ePGError, "lo_create failed");
|
2465
2530
|
|
2466
|
-
|
2531
|
+
ret = lo_create(conn, in_lo_oid);
|
2532
|
+
if (ret == InvalidOid)
|
2533
|
+
rb_raise(rb_ePGError, "lo_create failed");
|
2534
|
+
|
2535
|
+
return INT2FIX(ret);
|
2467
2536
|
}
|
2468
2537
|
|
2469
2538
|
/*
|
@@ -2475,20 +2544,19 @@ pgconn_locreate(self, in_lo_oid)
|
|
2475
2544
|
* On failure, it raises a PGError exception.
|
2476
2545
|
*/
|
2477
2546
|
static VALUE
|
2478
|
-
pgconn_loimport(self, filename)
|
2479
|
-
VALUE self, filename;
|
2547
|
+
pgconn_loimport(VALUE self, VALUE filename)
|
2480
2548
|
{
|
2481
|
-
|
2549
|
+
Oid lo_oid;
|
2482
2550
|
|
2483
|
-
|
2551
|
+
PGconn *conn = get_pgconn(self);
|
2484
2552
|
|
2485
|
-
|
2553
|
+
Check_Type(filename, T_STRING);
|
2486
2554
|
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2555
|
+
lo_oid = lo_import(conn, StringValuePtr(filename));
|
2556
|
+
if (lo_oid == 0) {
|
2557
|
+
rb_raise(rb_ePGError, PQerrorMessage(conn));
|
2558
|
+
}
|
2559
|
+
return INT2FIX(lo_oid);
|
2492
2560
|
}
|
2493
2561
|
|
2494
2562
|
/*
|
@@ -2498,22 +2566,21 @@ pgconn_loimport(self, filename)
|
|
2498
2566
|
* Saves a large object of _oid_ to a _file_.
|
2499
2567
|
*/
|
2500
2568
|
static VALUE
|
2501
|
-
pgconn_loexport(self, lo_oid,filename)
|
2502
|
-
VALUE self, lo_oid, filename;
|
2569
|
+
pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
|
2503
2570
|
{
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2571
|
+
PGconn *conn = get_pgconn(self);
|
2572
|
+
int oid;
|
2573
|
+
Check_Type(filename, T_STRING);
|
2507
2574
|
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
|
2575
|
+
oid = NUM2INT(lo_oid);
|
2576
|
+
if (oid < 0) {
|
2577
|
+
rb_raise(rb_ePGError, "invalid large object oid %d",oid);
|
2578
|
+
}
|
2512
2579
|
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2580
|
+
if (lo_export(conn, oid, StringValuePtr(filename)) < 0) {
|
2581
|
+
rb_raise(rb_ePGError, PQerrorMessage(conn));
|
2582
|
+
}
|
2583
|
+
return Qnil;
|
2517
2584
|
}
|
2518
2585
|
|
2519
2586
|
/*
|
@@ -2527,27 +2594,24 @@ pgconn_loexport(self, lo_oid,filename)
|
|
2527
2594
|
* If _mode_ is omitted, the default is +INV_READ+.
|
2528
2595
|
*/
|
2529
2596
|
static VALUE
|
2530
|
-
pgconn_loopen(argc, argv, self)
|
2531
|
-
int argc;
|
2532
|
-
VALUE *argv;
|
2533
|
-
VALUE self;
|
2597
|
+
pgconn_loopen(int argc, VALUE *argv, VALUE self)
|
2534
2598
|
{
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2599
|
+
Oid lo_oid;
|
2600
|
+
int fd, mode;
|
2601
|
+
VALUE nmode, selfid;
|
2602
|
+
PGconn *conn = get_pgconn(self);
|
2539
2603
|
|
2540
|
-
|
2541
|
-
|
2604
|
+
rb_scan_args(argc, argv, "11", &selfid, &nmode);
|
2605
|
+
lo_oid = NUM2INT(selfid);
|
2542
2606
|
if(NIL_P(nmode))
|
2543
|
-
|
2544
|
-
|
2607
|
+
mode = INV_READ;
|
2608
|
+
else
|
2545
2609
|
mode = NUM2INT(nmode);
|
2546
2610
|
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2611
|
+
if((fd = lo_open(conn, lo_oid, mode)) < 0) {
|
2612
|
+
rb_raise(rb_ePGError, "can't open large object");
|
2613
|
+
}
|
2614
|
+
return INT2FIX(fd);
|
2551
2615
|
}
|
2552
2616
|
|
2553
2617
|
/*
|
@@ -2558,24 +2622,23 @@ pgconn_loopen(argc, argv, self)
|
|
2558
2622
|
* Returns the number of bytes written.
|
2559
2623
|
*/
|
2560
2624
|
static VALUE
|
2561
|
-
pgconn_lowrite(self, in_lo_desc, buffer)
|
2562
|
-
VALUE self, buffer;
|
2625
|
+
pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
|
2563
2626
|
{
|
2564
|
-
|
2565
|
-
|
2627
|
+
int n;
|
2628
|
+
PGconn *conn = get_pgconn(self);
|
2566
2629
|
int fd = NUM2INT(in_lo_desc);
|
2567
2630
|
|
2568
|
-
|
2631
|
+
Check_Type(buffer, T_STRING);
|
2569
2632
|
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2633
|
+
if( RSTRING_LEN(buffer) < 0) {
|
2634
|
+
rb_raise(rb_ePGError, "write buffer zero string");
|
2635
|
+
}
|
2636
|
+
if((n = lo_write(conn, fd, StringValuePtr(buffer),
|
2574
2637
|
RSTRING_LEN(buffer))) < 0) {
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2638
|
+
rb_raise(rb_ePGError, "lo_write failed");
|
2639
|
+
}
|
2640
|
+
|
2641
|
+
return INT2FIX(n);
|
2579
2642
|
}
|
2580
2643
|
|
2581
2644
|
/*
|
@@ -2586,12 +2649,11 @@ pgconn_lowrite(self, in_lo_desc, buffer)
|
|
2586
2649
|
* returns resulting data.
|
2587
2650
|
*/
|
2588
2651
|
static VALUE
|
2589
|
-
pgconn_loread(self, in_lo_desc, in_len)
|
2590
|
-
VALUE self, in_lo_desc, in_len;
|
2652
|
+
pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
2591
2653
|
{
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2654
|
+
int ret;
|
2655
|
+
PGconn *conn = get_pgconn(self);
|
2656
|
+
int len = NUM2INT(in_len);
|
2595
2657
|
int lo_desc = NUM2INT(in_lo_desc);
|
2596
2658
|
VALUE str;
|
2597
2659
|
char *buffer;
|
@@ -2599,13 +2661,13 @@ pgconn_loread(self, in_lo_desc, in_len)
|
|
2599
2661
|
buffer = malloc(len);
|
2600
2662
|
if(buffer == NULL)
|
2601
2663
|
rb_raise(rb_eNoMemError, "Malloc failed!");
|
2602
|
-
|
2603
|
-
if (len < 0){
|
2604
|
-
rb_raise(rb_ePGError,"nagative length %d given", len);
|
2605
|
-
}
|
2606
2664
|
|
2607
|
-
|
2608
|
-
|
2665
|
+
if (len < 0){
|
2666
|
+
rb_raise(rb_ePGError,"nagative length %d given", len);
|
2667
|
+
}
|
2668
|
+
|
2669
|
+
if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
|
2670
|
+
rb_raise(rb_ePGError, "lo_read failed");
|
2609
2671
|
|
2610
2672
|
if(ret == 0) {
|
2611
2673
|
free(buffer);
|
@@ -2615,7 +2677,7 @@ pgconn_loread(self, in_lo_desc, in_len)
|
|
2615
2677
|
str = rb_tainted_str_new(buffer, len);
|
2616
2678
|
free(buffer);
|
2617
2679
|
|
2618
|
-
|
2680
|
+
return str;
|
2619
2681
|
}
|
2620
2682
|
|
2621
2683
|
|
@@ -2628,18 +2690,17 @@ pgconn_loread(self, in_lo_desc, in_len)
|
|
2628
2690
|
* (Or 0, 1, or 2.)
|
2629
2691
|
*/
|
2630
2692
|
static VALUE
|
2631
|
-
pgconn_lolseek(self, in_lo_desc, offset, whence)
|
2632
|
-
VALUE self, in_lo_desc, offset, whence;
|
2693
|
+
pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
|
2633
2694
|
{
|
2634
|
-
|
2695
|
+
PGconn *conn = get_pgconn(self);
|
2635
2696
|
int lo_desc = NUM2INT(in_lo_desc);
|
2636
|
-
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2640
|
-
|
2697
|
+
int ret;
|
2698
|
+
|
2699
|
+
if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
|
2700
|
+
rb_raise(rb_ePGError, "lo_lseek failed");
|
2701
|
+
}
|
2641
2702
|
|
2642
|
-
|
2703
|
+
return INT2FIX(ret);
|
2643
2704
|
}
|
2644
2705
|
|
2645
2706
|
/*
|
@@ -2649,17 +2710,16 @@ pgconn_lolseek(self, in_lo_desc, offset, whence)
|
|
2649
2710
|
* Returns the current position of the large object _lo_desc_.
|
2650
2711
|
*/
|
2651
2712
|
static VALUE
|
2652
|
-
pgconn_lotell(self,in_lo_desc)
|
2653
|
-
VALUE self, in_lo_desc;
|
2713
|
+
pgconn_lotell(VALUE self, VALUE in_lo_desc)
|
2654
2714
|
{
|
2655
|
-
|
2715
|
+
int position;
|
2656
2716
|
PGconn *conn = get_pgconn(self);
|
2657
2717
|
int lo_desc = NUM2INT(in_lo_desc);
|
2658
2718
|
|
2659
2719
|
if((position = lo_tell(conn, lo_desc)) < 0)
|
2660
2720
|
rb_raise(rb_ePGError,"lo_tell failed");
|
2661
2721
|
|
2662
|
-
|
2722
|
+
return INT2FIX(position);
|
2663
2723
|
}
|
2664
2724
|
|
2665
2725
|
/*
|
@@ -2669,17 +2729,16 @@ pgconn_lotell(self,in_lo_desc)
|
|
2669
2729
|
* Truncates the large object _lo_desc_ to size _len_.
|
2670
2730
|
*/
|
2671
2731
|
static VALUE
|
2672
|
-
pgconn_lotruncate(self, in_lo_desc, in_len)
|
2673
|
-
VALUE self, in_lo_desc, in_len;
|
2732
|
+
pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
|
2674
2733
|
{
|
2675
|
-
|
2676
|
-
|
2734
|
+
PGconn *conn = get_pgconn(self);
|
2735
|
+
int lo_desc = NUM2INT(in_lo_desc);
|
2677
2736
|
size_t len = NUM2INT(in_len);
|
2678
|
-
|
2679
|
-
|
2737
|
+
|
2738
|
+
if(lo_truncate(conn,lo_desc,len) < 0)
|
2680
2739
|
rb_raise(rb_ePGError,"lo_truncate failed");
|
2681
2740
|
|
2682
|
-
|
2741
|
+
return Qnil;
|
2683
2742
|
}
|
2684
2743
|
|
2685
2744
|
/*
|
@@ -2689,16 +2748,15 @@ pgconn_lotruncate(self, in_lo_desc, in_len)
|
|
2689
2748
|
* Closes the postgres large object of _lo_desc_.
|
2690
2749
|
*/
|
2691
2750
|
static VALUE
|
2692
|
-
pgconn_loclose(self, in_lo_desc)
|
2693
|
-
VALUE self, in_lo_desc;
|
2751
|
+
pgconn_loclose(VALUE self, VALUE in_lo_desc)
|
2694
2752
|
{
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2753
|
+
PGconn *conn = get_pgconn(self);
|
2754
|
+
int lo_desc = NUM2INT(in_lo_desc);
|
2755
|
+
|
2756
|
+
if(lo_unlink(conn,lo_desc) < 0)
|
2699
2757
|
rb_raise(rb_ePGError,"lo_close failed");
|
2700
2758
|
|
2701
|
-
|
2759
|
+
return Qnil;
|
2702
2760
|
}
|
2703
2761
|
|
2704
2762
|
/*
|
@@ -2708,19 +2766,18 @@ pgconn_loclose(self, in_lo_desc)
|
|
2708
2766
|
* Unlinks (deletes) the postgres large object of _oid_.
|
2709
2767
|
*/
|
2710
2768
|
static VALUE
|
2711
|
-
pgconn_lounlink(self, in_oid)
|
2712
|
-
VALUE self, in_oid;
|
2769
|
+
pgconn_lounlink(VALUE self, VALUE in_oid)
|
2713
2770
|
{
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
if (oid < 0)
|
2718
|
-
rb_raise(rb_ePGError, "invalid oid %d",oid);
|
2771
|
+
PGconn *conn = get_pgconn(self);
|
2772
|
+
int oid = NUM2INT(in_oid);
|
2719
2773
|
|
2720
|
-
|
2774
|
+
if (oid < 0)
|
2775
|
+
rb_raise(rb_ePGError, "invalid oid %d",oid);
|
2776
|
+
|
2777
|
+
if(lo_unlink(conn,oid) < 0)
|
2721
2778
|
rb_raise(rb_ePGError,"lo_unlink failed");
|
2722
2779
|
|
2723
|
-
|
2780
|
+
return Qnil;
|
2724
2781
|
}
|
2725
2782
|
|
2726
2783
|
/********************************************************************
|
@@ -2761,10 +2818,9 @@ pgconn_lounlink(self, in_oid)
|
|
2761
2818
|
* * +PGRES_FATAL_ERROR+
|
2762
2819
|
*/
|
2763
2820
|
static VALUE
|
2764
|
-
pgresult_result_status(self)
|
2765
|
-
VALUE self;
|
2821
|
+
pgresult_result_status(VALUE self)
|
2766
2822
|
{
|
2767
|
-
|
2823
|
+
return INT2FIX(PQresultStatus(get_pgresult(self)));
|
2768
2824
|
}
|
2769
2825
|
|
2770
2826
|
/*
|
@@ -2775,10 +2831,9 @@ pgresult_result_status(self)
|
|
2775
2831
|
*
|
2776
2832
|
*/
|
2777
2833
|
static VALUE
|
2778
|
-
pgresult_res_status(self,status)
|
2779
|
-
VALUE self,status;
|
2834
|
+
pgresult_res_status(VALUE self, VALUE status)
|
2780
2835
|
{
|
2781
|
-
|
2836
|
+
return rb_tainted_str_new2(PQresStatus(NUM2INT(status)));
|
2782
2837
|
}
|
2783
2838
|
|
2784
2839
|
/*
|
@@ -2788,10 +2843,9 @@ pgresult_res_status(self,status)
|
|
2788
2843
|
* Returns the error message of the command as a string.
|
2789
2844
|
*/
|
2790
2845
|
static VALUE
|
2791
|
-
pgresult_result_error_message(self)
|
2792
|
-
VALUE self;
|
2846
|
+
pgresult_result_error_message(VALUE self)
|
2793
2847
|
{
|
2794
|
-
|
2848
|
+
return rb_tainted_str_new2(PQresultErrorMessage(get_pgresult(self)));
|
2795
2849
|
}
|
2796
2850
|
|
2797
2851
|
/*
|
@@ -2819,7 +2873,7 @@ pgresult_result_error_field(VALUE self, VALUE field)
|
|
2819
2873
|
{
|
2820
2874
|
PGresult *result = get_pgresult(self);
|
2821
2875
|
int fieldcode = NUM2INT(field);
|
2822
|
-
|
2876
|
+
return rb_tainted_str_new2(PQresultErrorField(result,fieldcode));
|
2823
2877
|
}
|
2824
2878
|
|
2825
2879
|
/*
|
@@ -2829,12 +2883,11 @@ pgresult_result_error_field(VALUE self, VALUE field)
|
|
2829
2883
|
* Clears the PGresult object as the result of the query.
|
2830
2884
|
*/
|
2831
2885
|
static VALUE
|
2832
|
-
pgresult_clear(self)
|
2833
|
-
VALUE self;
|
2886
|
+
pgresult_clear(VALUE self)
|
2834
2887
|
{
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2888
|
+
PQclear(get_pgresult(self));
|
2889
|
+
DATA_PTR(self) = NULL;
|
2890
|
+
return Qnil;
|
2838
2891
|
}
|
2839
2892
|
|
2840
2893
|
/*
|
@@ -2844,10 +2897,9 @@ pgresult_clear(self)
|
|
2844
2897
|
* Returns the number of tuples in the query result.
|
2845
2898
|
*/
|
2846
2899
|
static VALUE
|
2847
|
-
pgresult_ntuples(self)
|
2848
|
-
VALUE self;
|
2900
|
+
pgresult_ntuples(VALUE self)
|
2849
2901
|
{
|
2850
|
-
|
2902
|
+
return INT2FIX(PQntuples(get_pgresult(self)));
|
2851
2903
|
}
|
2852
2904
|
|
2853
2905
|
/*
|
@@ -2857,10 +2909,9 @@ pgresult_ntuples(self)
|
|
2857
2909
|
* Returns the number of columns in the query result.
|
2858
2910
|
*/
|
2859
2911
|
static VALUE
|
2860
|
-
pgresult_nfields(self)
|
2861
|
-
VALUE self;
|
2912
|
+
pgresult_nfields(VALUE self)
|
2862
2913
|
{
|
2863
|
-
|
2914
|
+
return INT2NUM(PQnfields(get_pgresult(self)));
|
2864
2915
|
}
|
2865
2916
|
|
2866
2917
|
/*
|
@@ -2870,17 +2921,16 @@ pgresult_nfields(self)
|
|
2870
2921
|
* Returns the name of the column corresponding to _index_.
|
2871
2922
|
*/
|
2872
2923
|
static VALUE
|
2873
|
-
pgresult_fname(self, index)
|
2874
|
-
VALUE self, index;
|
2924
|
+
pgresult_fname(VALUE self, VALUE index)
|
2875
2925
|
{
|
2876
|
-
|
2926
|
+
PGresult *result;
|
2877
2927
|
int i = NUM2INT(index);
|
2878
2928
|
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2929
|
+
result = get_pgresult(self);
|
2930
|
+
if (i < 0 || i >= PQnfields(result)) {
|
2931
|
+
rb_raise(rb_eArgError,"invalid field number %d", i);
|
2932
|
+
}
|
2933
|
+
return rb_tainted_str_new2(PQfname(result, i));
|
2884
2934
|
}
|
2885
2935
|
|
2886
2936
|
/*
|
@@ -2893,18 +2943,17 @@ pgresult_fname(self, index)
|
|
2893
2943
|
* raises a TypeError if _name_ is not a String.
|
2894
2944
|
*/
|
2895
2945
|
static VALUE
|
2896
|
-
pgresult_fnumber(self, name)
|
2897
|
-
VALUE self, name;
|
2946
|
+
pgresult_fnumber(VALUE self, VALUE name)
|
2898
2947
|
{
|
2899
|
-
|
2900
|
-
|
2901
|
-
|
2902
|
-
|
2903
|
-
|
2904
|
-
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2948
|
+
int n;
|
2949
|
+
|
2950
|
+
Check_Type(name, T_STRING);
|
2951
|
+
|
2952
|
+
n = PQfnumber(get_pgresult(self), StringValuePtr(name));
|
2953
|
+
if (n == -1) {
|
2954
|
+
rb_raise(rb_eArgError,"Unknown field: %s", StringValuePtr(name));
|
2955
|
+
}
|
2956
|
+
return INT2FIX(n);
|
2908
2957
|
}
|
2909
2958
|
|
2910
2959
|
/*
|
@@ -2918,15 +2967,14 @@ pgresult_fnumber(self, name)
|
|
2918
2967
|
* the Oid is undefined for that column.
|
2919
2968
|
*/
|
2920
2969
|
static VALUE
|
2921
|
-
pgresult_ftable(self, column_number)
|
2922
|
-
VALUE self, column_number;
|
2970
|
+
pgresult_ftable(VALUE self, VALUE column_number)
|
2923
2971
|
{
|
2924
2972
|
Oid n = PQftable(get_pgresult(self), NUM2INT(column_number));
|
2925
|
-
|
2926
|
-
|
2973
|
+
if (n == InvalidOid) {
|
2974
|
+
rb_raise(rb_eArgError,"Oid is undefined for column: %d",
|
2927
2975
|
NUM2INT(column_number));
|
2928
|
-
|
2929
|
-
|
2976
|
+
}
|
2977
|
+
return INT2FIX(n);
|
2930
2978
|
}
|
2931
2979
|
|
2932
2980
|
/*
|
@@ -2940,16 +2988,15 @@ pgresult_ftable(self, column_number)
|
|
2940
2988
|
* the column number from its table is undefined for that column.
|
2941
2989
|
*/
|
2942
2990
|
static VALUE
|
2943
|
-
pgresult_ftablecol(self, column_number)
|
2944
|
-
VALUE self, column_number;
|
2991
|
+
pgresult_ftablecol(VALUE self, VALUE column_number)
|
2945
2992
|
{
|
2946
2993
|
int n = PQftablecol(get_pgresult(self), NUM2INT(column_number));
|
2947
|
-
|
2948
|
-
|
2994
|
+
if (n == 0) {
|
2995
|
+
rb_raise(rb_eArgError,
|
2949
2996
|
"Column number from table is undefined for column: %d",
|
2950
2997
|
NUM2INT(column_number));
|
2951
|
-
|
2952
|
-
|
2998
|
+
}
|
2999
|
+
return INT2FIX(n);
|
2953
3000
|
}
|
2954
3001
|
|
2955
3002
|
/*
|
@@ -2962,15 +3009,14 @@ pgresult_ftablecol(self, column_number)
|
|
2962
3009
|
* Raises ArgumentError if _column_number_ is out of range.
|
2963
3010
|
*/
|
2964
3011
|
static VALUE
|
2965
|
-
pgresult_fformat(self, column_number)
|
2966
|
-
VALUE self, column_number;
|
3012
|
+
pgresult_fformat(VALUE self, VALUE column_number)
|
2967
3013
|
{
|
2968
3014
|
PGresult *result = get_pgresult(self);
|
2969
3015
|
int fnumber = NUM2INT(column_number);
|
2970
|
-
|
2971
|
-
|
3016
|
+
if (fnumber >= PQnfields(result)) {
|
3017
|
+
rb_raise(rb_eArgError, "Column number is out of range: %d",
|
2972
3018
|
fnumber);
|
2973
|
-
|
3019
|
+
}
|
2974
3020
|
return INT2FIX(PQfformat(result, fnumber));
|
2975
3021
|
}
|
2976
3022
|
|
@@ -2983,15 +3029,14 @@ pgresult_fformat(self, column_number)
|
|
2983
3029
|
* The integer returned is the internal +OID+ number (in PostgreSQL) of the type.
|
2984
3030
|
*/
|
2985
3031
|
static VALUE
|
2986
|
-
pgresult_ftype(self, index)
|
2987
|
-
VALUE self, index;
|
3032
|
+
pgresult_ftype(VALUE self, VALUE index)
|
2988
3033
|
{
|
2989
|
-
|
2990
|
-
|
2991
|
-
|
2992
|
-
|
2993
|
-
|
2994
|
-
|
3034
|
+
PGresult* result = get_pgresult(self);
|
3035
|
+
int i = NUM2INT(index);
|
3036
|
+
if (i < 0 || i >= PQnfields(result)) {
|
3037
|
+
rb_raise(rb_eArgError, "invalid field number %d", i);
|
3038
|
+
}
|
3039
|
+
return INT2NUM(PQftype(result, i));
|
2995
3040
|
}
|
2996
3041
|
|
2997
3042
|
/*
|
@@ -3003,16 +3048,15 @@ pgresult_ftype(self, index)
|
|
3003
3048
|
* Raises ArgumentError if _column_number_ is out of range.
|
3004
3049
|
*/
|
3005
3050
|
static VALUE
|
3006
|
-
pgresult_fmod(self, column_number)
|
3007
|
-
VALUE self, column_number;
|
3051
|
+
pgresult_fmod(VALUE self, VALUE column_number)
|
3008
3052
|
{
|
3009
3053
|
PGresult *result = get_pgresult(self);
|
3010
3054
|
int fnumber = NUM2INT(column_number);
|
3011
3055
|
int modifier;
|
3012
|
-
|
3013
|
-
|
3056
|
+
if (fnumber >= PQnfields(result)) {
|
3057
|
+
rb_raise(rb_eArgError, "Column number is out of range: %d",
|
3014
3058
|
fnumber);
|
3015
|
-
|
3059
|
+
}
|
3016
3060
|
if((modifier = PQfmod(result,fnumber)) == -1)
|
3017
3061
|
rb_raise(rb_eArgError,
|
3018
3062
|
"No modifier information available for column: %d",
|
@@ -3031,17 +3075,16 @@ pgresult_fmod(self, column_number)
|
|
3031
3075
|
* res.size(1) => -1
|
3032
3076
|
*/
|
3033
3077
|
static VALUE
|
3034
|
-
pgresult_fsize(self, index)
|
3035
|
-
VALUE self, index;
|
3078
|
+
pgresult_fsize(VALUE self, VALUE index)
|
3036
3079
|
{
|
3037
|
-
|
3038
|
-
|
3080
|
+
PGresult *result;
|
3081
|
+
int i = NUM2INT(index);
|
3039
3082
|
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3083
|
+
result = get_pgresult(self);
|
3084
|
+
if (i < 0 || i >= PQnfields(result)) {
|
3085
|
+
rb_raise(rb_eArgError,"invalid field number %d", i);
|
3086
|
+
}
|
3087
|
+
return INT2NUM(PQfsize(result, i));
|
3045
3088
|
}
|
3046
3089
|
|
3047
3090
|
/*
|
@@ -3052,20 +3095,19 @@ pgresult_fsize(self, index)
|
|
3052
3095
|
* or +nil+ if the field is +NULL+.
|
3053
3096
|
*/
|
3054
3097
|
static VALUE
|
3055
|
-
pgresult_getvalue(self, tup_num, field_num)
|
3056
|
-
VALUE self, tup_num, field_num;
|
3098
|
+
pgresult_getvalue(VALUE self, VALUE tup_num, VALUE field_num)
|
3057
3099
|
{
|
3058
|
-
|
3059
|
-
|
3060
|
-
|
3100
|
+
PGresult *result;
|
3101
|
+
int i = NUM2INT(tup_num);
|
3102
|
+
int j = NUM2INT(field_num);
|
3061
3103
|
|
3062
|
-
|
3104
|
+
result = get_pgresult(self);
|
3063
3105
|
if(i < 0 || i >= PQntuples(result)) {
|
3064
3106
|
rb_raise(rb_eArgError,"invalid tuple number %d", i);
|
3065
3107
|
}
|
3066
|
-
|
3108
|
+
if(j < 0 || j >= PQnfields(result)) {
|
3067
3109
|
rb_raise(rb_eArgError,"invalid field number %d", j);
|
3068
|
-
|
3110
|
+
}
|
3069
3111
|
if(PQgetisnull(result, i, j))
|
3070
3112
|
return Qnil;
|
3071
3113
|
return rb_tainted_str_new(PQgetvalue(result, i, j),
|
@@ -3079,21 +3121,20 @@ pgresult_getvalue(self, tup_num, field_num)
|
|
3079
3121
|
* Returns +true+ if the specified value is +nil+; +false+ otherwise.
|
3080
3122
|
*/
|
3081
3123
|
static VALUE
|
3082
|
-
pgresult_getisnull(self, tup_num, field_num)
|
3083
|
-
VALUE self, tup_num, field_num;
|
3124
|
+
pgresult_getisnull(VALUE self, VALUE tup_num, VALUE field_num)
|
3084
3125
|
{
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3126
|
+
PGresult *result;
|
3127
|
+
int i = NUM2INT(tup_num);
|
3128
|
+
int j = NUM2INT(field_num);
|
3088
3129
|
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
|
3093
|
-
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3130
|
+
result = get_pgresult(self);
|
3131
|
+
if (i < 0 || i >= PQntuples(result)) {
|
3132
|
+
rb_raise(rb_eArgError,"invalid tuple number %d", i);
|
3133
|
+
}
|
3134
|
+
if (j < 0 || j >= PQnfields(result)) {
|
3135
|
+
rb_raise(rb_eArgError,"invalid field number %d", j);
|
3136
|
+
}
|
3137
|
+
return PQgetisnull(result, i, j) ? Qtrue : Qfalse;
|
3097
3138
|
}
|
3098
3139
|
|
3099
3140
|
/*
|
@@ -3105,21 +3146,20 @@ pgresult_getisnull(self, tup_num, field_num)
|
|
3105
3146
|
* Equivalent to <tt>res.value(<i>tup_num</i>,<i>field_num</i>).length</tt>.
|
3106
3147
|
*/
|
3107
3148
|
static VALUE
|
3108
|
-
pgresult_getlength(self, tup_num, field_num)
|
3109
|
-
VALUE self, tup_num, field_num;
|
3149
|
+
pgresult_getlength(VALUE self, VALUE tup_num, VALUE field_num)
|
3110
3150
|
{
|
3111
|
-
|
3112
|
-
|
3113
|
-
|
3151
|
+
PGresult *result;
|
3152
|
+
int i = NUM2INT(tup_num);
|
3153
|
+
int j = NUM2INT(field_num);
|
3114
3154
|
|
3115
|
-
|
3116
|
-
|
3117
|
-
|
3118
|
-
|
3119
|
-
|
3120
|
-
|
3121
|
-
|
3122
|
-
|
3155
|
+
result = get_pgresult(self);
|
3156
|
+
if (i < 0 || i >= PQntuples(result)) {
|
3157
|
+
rb_raise(rb_eArgError,"invalid tuple number %d", i);
|
3158
|
+
}
|
3159
|
+
if (j < 0 || j >= PQnfields(result)) {
|
3160
|
+
rb_raise(rb_eArgError,"invalid field number %d", j);
|
3161
|
+
}
|
3162
|
+
return INT2FIX(PQgetlength(result, i, j));
|
3123
3163
|
}
|
3124
3164
|
|
3125
3165
|
/*
|
@@ -3130,13 +3170,12 @@ pgresult_getlength(self, tup_num, field_num)
|
|
3130
3170
|
* Only useful for the result returned by conn.describePrepared
|
3131
3171
|
*/
|
3132
3172
|
static VALUE
|
3133
|
-
pgresult_nparams(self)
|
3134
|
-
VALUE self;
|
3173
|
+
pgresult_nparams(VALUE self)
|
3135
3174
|
{
|
3136
|
-
|
3175
|
+
PGresult *result;
|
3137
3176
|
|
3138
|
-
|
3139
|
-
|
3177
|
+
result = get_pgresult(self);
|
3178
|
+
return INT2FIX(PQnparams(result));
|
3140
3179
|
}
|
3141
3180
|
|
3142
3181
|
/*
|
@@ -3147,13 +3186,12 @@ pgresult_nparams(self)
|
|
3147
3186
|
* Only useful for the result returned by conn.describePrepared
|
3148
3187
|
*/
|
3149
3188
|
static VALUE
|
3150
|
-
pgresult_paramtype(self, param_number)
|
3151
|
-
VALUE self, param_number;
|
3189
|
+
pgresult_paramtype(VALUE self, VALUE param_number)
|
3152
3190
|
{
|
3153
|
-
|
3191
|
+
PGresult *result;
|
3154
3192
|
|
3155
|
-
|
3156
|
-
|
3193
|
+
result = get_pgresult(self);
|
3194
|
+
return INT2FIX(PQparamtype(result,NUM2INT(param_number)));
|
3157
3195
|
}
|
3158
3196
|
|
3159
3197
|
/*
|
@@ -3163,10 +3201,9 @@ pgresult_paramtype(self, param_number)
|
|
3163
3201
|
* Returns the status string of the last query command.
|
3164
3202
|
*/
|
3165
3203
|
static VALUE
|
3166
|
-
pgresult_cmd_status(self)
|
3167
|
-
VALUE self;
|
3204
|
+
pgresult_cmd_status(VALUE self)
|
3168
3205
|
{
|
3169
|
-
|
3206
|
+
return rb_tainted_str_new2(PQcmdStatus(get_pgresult(self)));
|
3170
3207
|
}
|
3171
3208
|
|
3172
3209
|
/*
|
@@ -3184,12 +3221,11 @@ pgresult_cmd_status(self)
|
|
3184
3221
|
* or if no tuples were affected, <tt>0</tt> is returned.
|
3185
3222
|
*/
|
3186
3223
|
static VALUE
|
3187
|
-
pgresult_cmd_tuples(self)
|
3188
|
-
VALUE self;
|
3224
|
+
pgresult_cmd_tuples(VALUE self)
|
3189
3225
|
{
|
3190
|
-
|
3191
|
-
|
3192
|
-
|
3226
|
+
long n;
|
3227
|
+
n = strtol(PQcmdTuples(get_pgresult(self)),NULL, 10);
|
3228
|
+
return INT2NUM(n);
|
3193
3229
|
}
|
3194
3230
|
|
3195
3231
|
/*
|
@@ -3200,14 +3236,13 @@ pgresult_cmd_tuples(self)
|
|
3200
3236
|
* otherwise +nil+.
|
3201
3237
|
*/
|
3202
3238
|
static VALUE
|
3203
|
-
pgresult_oid_value(self)
|
3204
|
-
VALUE self;
|
3239
|
+
pgresult_oid_value(VALUE self)
|
3205
3240
|
{
|
3206
|
-
|
3207
|
-
|
3208
|
-
|
3209
|
-
|
3210
|
-
|
3241
|
+
Oid n = PQoidValue(get_pgresult(self));
|
3242
|
+
if (n == InvalidOid)
|
3243
|
+
return Qnil;
|
3244
|
+
else
|
3245
|
+
return INT2FIX(n);
|
3211
3246
|
}
|
3212
3247
|
|
3213
3248
|
/* Utility methods not in libpq */
|
@@ -3219,8 +3254,7 @@ pgresult_oid_value(self)
|
|
3219
3254
|
* Returns tuple _n_ as a hash.
|
3220
3255
|
*/
|
3221
3256
|
static VALUE
|
3222
|
-
pgresult_aref(self, index)
|
3223
|
-
VALUE self, index;
|
3257
|
+
pgresult_aref(VALUE self, VALUE index)
|
3224
3258
|
{
|
3225
3259
|
PGresult *result = get_pgresult(self);
|
3226
3260
|
int tuple_num = NUM2INT(index);
|
@@ -3252,8 +3286,7 @@ pgresult_aref(self, index)
|
|
3252
3286
|
* Invokes block for each tuple in the result set.
|
3253
3287
|
*/
|
3254
3288
|
static VALUE
|
3255
|
-
pgresult_each(self)
|
3256
|
-
VALUE self;
|
3289
|
+
pgresult_each(VALUE self)
|
3257
3290
|
{
|
3258
3291
|
PGresult *result = get_pgresult(self);
|
3259
3292
|
int tuple_num;
|
@@ -3271,20 +3304,19 @@ pgresult_each(self)
|
|
3271
3304
|
* Returns an array of Strings representing the names of the fields in the result.
|
3272
3305
|
*/
|
3273
3306
|
static VALUE
|
3274
|
-
pgresult_fields(self)
|
3275
|
-
VALUE self;
|
3307
|
+
pgresult_fields(VALUE self)
|
3276
3308
|
{
|
3277
|
-
|
3278
|
-
|
3279
|
-
|
3280
|
-
|
3281
|
-
|
3282
|
-
|
3283
|
-
|
3284
|
-
|
3285
|
-
|
3286
|
-
|
3287
|
-
|
3309
|
+
PGresult *result;
|
3310
|
+
VALUE ary;
|
3311
|
+
int n, i;
|
3312
|
+
|
3313
|
+
result = get_pgresult(self);
|
3314
|
+
n = PQnfields(result);
|
3315
|
+
ary = rb_ary_new2(n);
|
3316
|
+
for (i=0;i<n;i++) {
|
3317
|
+
rb_ary_push(ary, rb_tainted_str_new2(PQfname(result, i)));
|
3318
|
+
}
|
3319
|
+
return ary;
|
3288
3320
|
}
|
3289
3321
|
|
3290
3322
|
/**************************************************************************/
|
@@ -3309,11 +3341,7 @@ Init_pg()
|
|
3309
3341
|
*************************/
|
3310
3342
|
|
3311
3343
|
/****** PGconn CLASS METHODS ******/
|
3312
|
-
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
|
3313
3344
|
rb_define_alloc_func(rb_cPGconn, pgconn_alloc);
|
3314
|
-
#else
|
3315
|
-
rb_define_singleton_method(rb_cPGconn, "new", pgconn_s_new, -1);
|
3316
|
-
#endif
|
3317
3345
|
rb_define_singleton_alias(rb_cPGconn, "connect", "new");
|
3318
3346
|
rb_define_singleton_alias(rb_cPGconn, "open", "new");
|
3319
3347
|
rb_define_singleton_alias(rb_cPGconn, "setdb", "new");
|
@@ -3417,14 +3445,12 @@ Init_pg()
|
|
3417
3445
|
rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
|
3418
3446
|
rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
|
3419
3447
|
rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
|
3420
|
-
rb_define_method(rb_cPGconn, "setnonblocking", pgconn_setnonblocking,
|
3448
|
+
rb_define_method(rb_cPGconn, "setnonblocking", pgconn_setnonblocking, 1);
|
3421
3449
|
rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
|
3422
3450
|
rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
|
3423
3451
|
|
3424
3452
|
/****** PGconn INSTANCE METHODS: Cancelling Queries in Progress ******/
|
3425
|
-
|
3426
|
-
//rb_define_method(rb_cPGconn, "free_cancel", pgconn_get_result, 0);
|
3427
|
-
//rb_define_method(rb_cPGconn, "cancel", pgconn_get_result, 0);
|
3453
|
+
rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
|
3428
3454
|
|
3429
3455
|
/****** PGconn INSTANCE METHODS: NOTIFY ******/
|
3430
3456
|
rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
|