pgsql 1.3 → 1.7
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.
- checksums.yaml +5 -13
- data/LICENSE +2 -8
- data/README +26 -25
- data/lib/Rakefile +2 -2
- data/lib/conn.c +111 -108
- data/lib/conn_exec.c +20 -36
- data/lib/conn_quote.c +57 -29
- data/lib/conn_quote.h +1 -2
- data/lib/mkrf_conf +7 -15
- data/lib/module.c +4 -5
- data/lib/module.h +3 -9
- data/lib/result.c +32 -39
- metadata +28 -34
checksums.yaml
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
data.tar.gz: !binary |-
|
|
6
|
-
YWVlZTViMjA4YmYwYzg2MjVlYWYwNjdjNTA1N2ExMmRlMDU5MTY3MA==
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: dc7ec22892e0bd75f3a0c63832471264c74e5bf758844f3fc87b9b5e2fb73b59
|
|
4
|
+
data.tar.gz: c1d31689274d2ccd7a97b4381b635f390886e419cbef1c44b7017839b8b520a9
|
|
7
5
|
SHA512:
|
|
8
|
-
metadata.gz:
|
|
9
|
-
|
|
10
|
-
MDg2YzdlMmVkZDAzZjZiY2RmOWFkNTgyZTFjNzQxMTM1ZjRhN2ExNmU4OWEx
|
|
11
|
-
MmQzZTAwOGI4NGNkZmNhNDQyMGNhM2Y3Yjg0ODNlNDQxODFmNTg=
|
|
12
|
-
data.tar.gz: !binary |-
|
|
13
|
-
YTc3ZWJkMDg0MWUwYjdhZDdkMGViMDM5MzE5YmU2MGVmZTBkYTNlMGIwNWZh
|
|
14
|
-
YzQwN2Y4ZjQ0ZjE2Yjk4OWI1OTFmMzY4NGVjNmY5NDk2MjIzYTIyMzc5MWI0
|
|
15
|
-
ODFiNTRjMjBkN2YxNDljN2FlYWJmOWUzMDQwMDE1ODAyYWQyZGY=
|
|
6
|
+
metadata.gz: 2c94ab8fc0eb95ed34e1ffb84d0f90dd34d7ac4858b693217d94e36e913d5b02f9a7653459864f002d9d84cf02219b07191ee64757a5a42899cae6b8f31aa512
|
|
7
|
+
data.tar.gz: 4a893e13d60d470e8bde739c7f33f3d6260cd20670c746d115ebd93aa74531af69059c32a9dd59419fc68dd6ddd7d7630b12b892c615c1beeb4600aa336d9c31
|
data/LICENSE
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
_ __ __ _ ___ __ _| |
|
|
3
|
-
| '_ \ / _` / __|/ _` | |
|
|
4
|
-
| |_) | (_| \__ \ (_| | |
|
|
5
|
-
| .__/ \__, |___/\__, |_|
|
|
6
|
-
|_| |___/ |_|
|
|
1
|
+
= pgsql Ruby Gem
|
|
7
2
|
|
|
8
|
-
|
|
9
|
-
Copyright (c) 2011-2013, Bertram Scharpf <software@bertram-scharpf.de>.
|
|
3
|
+
Copyright (C) 2011-2020, Bertram Scharpf <software@bertram-scharpf.de>.
|
|
10
4
|
All rights reserved.
|
|
11
5
|
|
|
12
6
|
Redistribution and use in source and binary forms, with or without
|
data/README
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
_ __ __ _ ___ __ _| |
|
|
3
|
-
| '_ \ / _` / __|/ _` | |
|
|
4
|
-
| |_) | (_| \__ \ (_| | |
|
|
5
|
-
| .__/ \__, |___/\__, |_|
|
|
6
|
-
|_| |___/ |_|
|
|
7
|
-
|
|
8
|
-
== Description
|
|
1
|
+
= pgsql Ruby Gem
|
|
9
2
|
|
|
10
3
|
A PostgreSQL library that was carefully designed.
|
|
11
4
|
|
|
5
|
+
|
|
6
|
+
== Author
|
|
7
|
+
|
|
8
|
+
Bertram Scharpf <software@bertram-scharpf.de>
|
|
9
|
+
|
|
10
|
+
|
|
12
11
|
== Features
|
|
13
12
|
|
|
14
13
|
* Connection parameters from hash
|
|
@@ -18,28 +17,30 @@ A PostgreSQL library that was carefully designed.
|
|
|
18
17
|
* Full PostgreSQL quoting support
|
|
19
18
|
* Built-in transactions and savepoints by Ruby blocks
|
|
20
19
|
|
|
20
|
+
|
|
21
21
|
== Example
|
|
22
22
|
|
|
23
23
|
Write something like this:
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
require "pgsql"
|
|
26
|
+
|
|
27
|
+
Pg::Conn.open :dbname => "test1", :user => "jdoe" do |conn|
|
|
28
|
+
conn.exec "SELECT * FROM mytable;" do |result|
|
|
29
|
+
result.each { |row|
|
|
30
|
+
l = row.join ", "
|
|
31
|
+
...
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
cmd = <<-ENDSQL
|
|
35
|
+
SELECT * FROM mytable WHERE num=$1::INTEGER;
|
|
36
|
+
ENDSQL
|
|
37
|
+
conn.query cmd, 42 do |row|
|
|
38
|
+
l = row.join ", "
|
|
39
|
+
...
|
|
40
|
+
end
|
|
41
|
+
...
|
|
33
42
|
end
|
|
34
|
-
|
|
35
|
-
select * from mytable where num=$1::integer;
|
|
36
|
-
ENDSQL
|
|
37
|
-
conn.query cmd, 42 do |row|
|
|
38
|
-
l = row.join ", "
|
|
39
|
-
...
|
|
40
|
-
end
|
|
41
|
-
...
|
|
42
|
-
end
|
|
43
|
+
|
|
43
44
|
|
|
44
45
|
== Thanks
|
|
45
46
|
|
data/lib/Rakefile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
require "autorake"
|
|
6
6
|
|
|
7
|
-
c = compiler "-O2", "-fPIC"
|
|
7
|
+
c = compiler "-O2", "-fPIC", "-Wall"
|
|
8
8
|
l = linker "-shared"
|
|
9
9
|
|
|
10
10
|
rule ".o" => ".c" do |t|
|
|
@@ -17,7 +17,7 @@ DLs = {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
DLs.each { |k,v|
|
|
20
|
-
|
|
20
|
+
file k => v do |t|
|
|
21
21
|
l.cc t.name, t.prerequisites
|
|
22
22
|
end
|
|
23
23
|
}
|
data/lib/conn.c
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
#include "conn.h"
|
|
7
7
|
|
|
8
|
+
#include "conn_quote.h"
|
|
9
|
+
#include "conn_exec.h"
|
|
8
10
|
|
|
9
11
|
#if defined( HAVE_HEADER_ST_H)
|
|
10
12
|
#include <st.h>
|
|
@@ -24,12 +26,12 @@ extern VALUE pgconn_mkstring( struct pgconn_data *ptr, const char *str);
|
|
|
24
26
|
extern VALUE pgconn_mkstringn( struct pgconn_data *ptr, const char *str, int len);
|
|
25
27
|
static VALUE pgconn_alloc( VALUE cls);
|
|
26
28
|
static VALUE pgconn_s_connect( int argc, VALUE *argv, VALUE cls);
|
|
27
|
-
static VALUE pgconn_s_parse( VALUE cls, VALUE str);
|
|
28
29
|
static VALUE pgconn_init( int argc, VALUE *argv, VALUE self);
|
|
29
30
|
static int set_connect_params( st_data_t key, st_data_t val, st_data_t args);
|
|
30
|
-
static
|
|
31
|
-
static
|
|
32
|
-
static VALUE
|
|
31
|
+
static VALUE connstr_sym_dbname( void);
|
|
32
|
+
static VALUE connstr_sym_password( void);
|
|
33
|
+
static void connstr_passwd( VALUE self, VALUE orig_params, VALUE *params);
|
|
34
|
+
static VALUE connstr_getparam( RB_BLOCK_CALL_FUNC_ARGLIST( yielded, params));
|
|
33
35
|
|
|
34
36
|
static VALUE pgconn_close( VALUE self);
|
|
35
37
|
static VALUE pgconn_reset( VALUE self);
|
|
@@ -69,6 +71,9 @@ VALUE rb_cPgConn;
|
|
|
69
71
|
static VALUE rb_ePgConnFailed;
|
|
70
72
|
static VALUE rb_ePgConnInvalid;
|
|
71
73
|
|
|
74
|
+
static VALUE sym_dbname = Qundef;
|
|
75
|
+
static VALUE sym_password = Qundef;
|
|
76
|
+
|
|
72
77
|
|
|
73
78
|
|
|
74
79
|
void
|
|
@@ -198,7 +203,7 @@ pgconn_alloc( VALUE cls)
|
|
|
198
203
|
}
|
|
199
204
|
|
|
200
205
|
/*
|
|
201
|
-
* Document-method: connect
|
|
206
|
+
* Document-method: Pg::Conn.connect
|
|
202
207
|
*
|
|
203
208
|
* call-seq:
|
|
204
209
|
* Pg::Conn.connect( hash) -> conn
|
|
@@ -219,27 +224,9 @@ pgconn_s_connect( int argc, VALUE *argv, VALUE cls)
|
|
|
219
224
|
rb_ensure( rb_yield, pgconn, pgconn_close, pgconn) : pgconn;
|
|
220
225
|
}
|
|
221
226
|
|
|
222
|
-
/*
|
|
223
|
-
* call-seq:
|
|
224
|
-
* Pg::Conn.parse( str) -> hash
|
|
225
|
-
*
|
|
226
|
-
* Parse a connection string and return a hash with keys <code>:dbname</code>,
|
|
227
|
-
* <code>:user</code>, <code>:host</code>, etc.
|
|
228
|
-
*
|
|
229
|
-
*/
|
|
230
|
-
VALUE
|
|
231
|
-
pgconn_s_parse( VALUE cls, VALUE str)
|
|
232
|
-
{
|
|
233
|
-
VALUE params;
|
|
234
|
-
|
|
235
|
-
params = rb_hash_new();
|
|
236
|
-
connstr_to_hash( params, str);
|
|
237
|
-
return params;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
227
|
|
|
241
228
|
/*
|
|
242
|
-
* Document-method: new
|
|
229
|
+
* Document-method: Pg::Conn.new
|
|
243
230
|
*
|
|
244
231
|
* call-seq:
|
|
245
232
|
* Pg::Conn.new( hash) -> conn
|
|
@@ -250,23 +237,39 @@ pgconn_s_parse( VALUE cls, VALUE str)
|
|
|
250
237
|
*
|
|
251
238
|
* c = Pg::Conn.new :dbname => "movies", :host => "jupiter", ...
|
|
252
239
|
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
240
|
+
* If the +str+ argument is given but no further parameters,
|
|
241
|
+
* the PQconnectdb() (not PQconnectdbParams()) function will be called.
|
|
242
|
+
* If further arguments are present, the +str+ argument will be made into
|
|
243
|
+
* the "dbname" parameter, but without overwriting an existing one.
|
|
255
244
|
*
|
|
256
|
-
*
|
|
245
|
+
* The "dbname" parameter may be a +conninfo+ string as described in the
|
|
246
|
+
* PostgreSQL documentation:
|
|
257
247
|
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
248
|
+
* c = Pg::Conn.new "postgresql://user:password@host:port/dbname"
|
|
249
|
+
* c = Pg::Conn.new "postgres://user:password@host:port/dbname"
|
|
250
|
+
* c = Pg::Conn.new "dbname=... host=... user=..."
|
|
251
|
+
*
|
|
252
|
+
* The password may be specified as an extra parameter:
|
|
253
|
+
*
|
|
254
|
+
* c = Pg::Conn.new "postgresql://user@host/dbname", password: "verysecret"
|
|
260
255
|
*
|
|
261
256
|
* If the password is the empty string, and there is either an instance method
|
|
262
257
|
* or a class method <code>password?</code>, that method will be asked. This
|
|
263
258
|
* method may ask <code>yield :user</code> or <code>yield :dbname</code> and so
|
|
264
259
|
* on to get the connection parameters.
|
|
265
260
|
*
|
|
261
|
+
* class Pg::Conn
|
|
262
|
+
* def password?
|
|
263
|
+
* "tercesyrev".reverse
|
|
264
|
+
* end
|
|
265
|
+
* end
|
|
266
|
+
* c = Pg::Conn.new "postgresql://user@host/dbname", password: ""
|
|
267
|
+
*
|
|
266
268
|
* See the PostgreSQL documentation for a full list:
|
|
267
269
|
* [http://www.postgresql.org/docs/current/interactive/libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS]
|
|
268
270
|
*
|
|
269
271
|
* On failure, a +Pg::Error+ exception will be raised.
|
|
272
|
+
*
|
|
270
273
|
*/
|
|
271
274
|
VALUE
|
|
272
275
|
pgconn_init( int argc, VALUE *argv, VALUE self)
|
|
@@ -278,32 +281,44 @@ pgconn_init( int argc, VALUE *argv, VALUE self)
|
|
|
278
281
|
struct pgconn_data *c;
|
|
279
282
|
|
|
280
283
|
if (rb_scan_args( argc, argv, "02", &str, ¶ms) < 2)
|
|
281
|
-
if (TYPE( str)
|
|
284
|
+
if (TYPE( str) == T_HASH) {
|
|
282
285
|
params = str;
|
|
283
286
|
str = Qnil;
|
|
284
287
|
}
|
|
285
|
-
if (NIL_P( params))
|
|
286
|
-
params = rb_hash_new();
|
|
287
|
-
else if (TYPE( params) != T_HASH)
|
|
288
|
-
params = rb_convert_type( params, T_HASH, "Hash", "to_hash");
|
|
289
|
-
else
|
|
290
|
-
params = rb_obj_dup( params);
|
|
291
|
-
if (!NIL_P( str))
|
|
292
|
-
connstr_to_hash( params, str);
|
|
293
|
-
connstr_passwd( self, params);
|
|
294
288
|
|
|
295
289
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
296
290
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
291
|
+
if (NIL_P( params)) {
|
|
292
|
+
StringValue( str);
|
|
293
|
+
c->conn = PQconnectdb( RSTRING_PTR( str));
|
|
294
|
+
} else {
|
|
295
|
+
int expand_dbname;
|
|
296
|
+
VALUE orig_params = params;
|
|
297
|
+
|
|
298
|
+
if (TYPE( params) != T_HASH)
|
|
299
|
+
params = rb_convert_type( params, T_HASH, "Hash", "to_hash");
|
|
300
|
+
|
|
301
|
+
if (!NIL_P( str) && NIL_P( rb_hash_aref( params, connstr_sym_dbname()))) {
|
|
302
|
+
if (params == orig_params)
|
|
303
|
+
params = rb_obj_dup( params);
|
|
304
|
+
rb_hash_aset( params, sym_dbname, str);
|
|
305
|
+
expand_dbname = 1;
|
|
306
|
+
} else
|
|
307
|
+
expand_dbname = 0;
|
|
308
|
+
|
|
309
|
+
connstr_passwd( self, orig_params, ¶ms);
|
|
310
|
+
|
|
311
|
+
l = RHASH_SIZE( params) + 1;
|
|
312
|
+
keywords = (const char **) ALLOCA_N( char *, l);
|
|
313
|
+
values = (const char **) ALLOCA_N( char *, l);
|
|
314
|
+
ptrs[ 0] = keywords;
|
|
315
|
+
ptrs[ 1] = values;
|
|
316
|
+
ptrs[ 2] = (const char **) c;
|
|
317
|
+
st_foreach( RHASH_TBL( params), &set_connect_params, (st_data_t) ptrs);
|
|
318
|
+
*(ptrs[ 0]) = *(ptrs[ 1]) = NULL;
|
|
319
|
+
|
|
320
|
+
c->conn = PQconnectdbParams( keywords, values, expand_dbname);
|
|
321
|
+
}
|
|
307
322
|
if (PQstatus( c->conn) == CONNECTION_BAD)
|
|
308
323
|
rb_exc_raise( pgconnfailederror_new( c, params));
|
|
309
324
|
|
|
@@ -329,50 +344,29 @@ set_connect_params( st_data_t key, st_data_t val, st_data_t args)
|
|
|
329
344
|
return ST_CONTINUE;
|
|
330
345
|
}
|
|
331
346
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
;
|
|
338
|
-
|
|
339
|
-
#define KEY_USER "user"
|
|
340
|
-
#define KEY_PASSWORD "password"
|
|
341
|
-
#define KEY_HOST "host"
|
|
342
|
-
#define KEY_PORT "port"
|
|
343
|
-
#define KEY_DBNAME "dbname"
|
|
347
|
+
VALUE
|
|
348
|
+
connstr_sym_dbname( void)
|
|
349
|
+
{
|
|
350
|
+
if (sym_dbname == Qundef)
|
|
351
|
+
sym_dbname = ID2SYM( rb_intern( "dbname"));
|
|
352
|
+
return sym_dbname;
|
|
353
|
+
}
|
|
344
354
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
{
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (RTEST( rb_reg_match( re, str))) {
|
|
352
|
-
match = rb_backref_get();
|
|
353
|
-
#define ADD_TO_RES( key, n) \
|
|
354
|
-
k = ID2SYM( rb_intern( key)); m = rb_reg_nth_match( n, match); \
|
|
355
|
-
if (NIL_P( rb_hash_aref( params, k)) && !NIL_P(m)) \
|
|
356
|
-
rb_hash_aset( params, k, m)
|
|
357
|
-
ADD_TO_RES( KEY_USER, 1);
|
|
358
|
-
ADD_TO_RES( KEY_PASSWORD, 2);
|
|
359
|
-
ADD_TO_RES( KEY_HOST, 3);
|
|
360
|
-
ADD_TO_RES( KEY_PORT, 4);
|
|
361
|
-
ADD_TO_RES( KEY_DBNAME, 5);
|
|
362
|
-
#undef ADD_TO_RES
|
|
363
|
-
} else
|
|
364
|
-
rb_raise( rb_eArgError, "Invalid connection: %s", RSTRING_PTR( str));
|
|
355
|
+
VALUE
|
|
356
|
+
connstr_sym_password( void)
|
|
357
|
+
{
|
|
358
|
+
if (sym_password == Qundef)
|
|
359
|
+
sym_password = ID2SYM( rb_intern( "password"));
|
|
360
|
+
return sym_password;
|
|
365
361
|
}
|
|
366
362
|
|
|
363
|
+
|
|
367
364
|
void
|
|
368
|
-
connstr_passwd( VALUE self, VALUE params)
|
|
365
|
+
connstr_passwd( VALUE self, VALUE orig_params, VALUE *params)
|
|
369
366
|
{
|
|
370
|
-
static VALUE sym_password = Qundef;
|
|
371
367
|
VALUE pw;
|
|
372
368
|
|
|
373
|
-
|
|
374
|
-
sym_password = ID2SYM( rb_intern( KEY_PASSWORD));
|
|
375
|
-
pw = rb_hash_aref( params, sym_password);
|
|
369
|
+
pw = rb_hash_aref( *params, connstr_sym_password());
|
|
376
370
|
if (TYPE( pw) == T_STRING && RSTRING_LEN( pw) == 0) {
|
|
377
371
|
static ID id_password_q = 0;
|
|
378
372
|
VALUE pwobj;
|
|
@@ -384,14 +378,18 @@ connstr_passwd( VALUE self, VALUE params)
|
|
|
384
378
|
pwobj = self;
|
|
385
379
|
if (rb_respond_to( CLASS_OF( self), id_password_q))
|
|
386
380
|
pwobj = CLASS_OF( self);
|
|
387
|
-
if (pwobj != Qundef)
|
|
388
|
-
|
|
381
|
+
if (pwobj != Qundef) {
|
|
382
|
+
if (*params == orig_params)
|
|
383
|
+
*params = rb_obj_dup( *params);
|
|
384
|
+
rb_hash_aset( *params, sym_password,
|
|
389
385
|
rb_block_call( pwobj, id_password_q, 0, NULL,
|
|
390
|
-
&connstr_getparam, params));
|
|
386
|
+
&connstr_getparam, *params));
|
|
387
|
+
}
|
|
391
388
|
}
|
|
392
389
|
}
|
|
393
390
|
|
|
394
|
-
VALUE
|
|
391
|
+
VALUE
|
|
392
|
+
connstr_getparam( RB_BLOCK_CALL_FUNC_ARGLIST( yielded, params))
|
|
395
393
|
{
|
|
396
394
|
return rb_hash_aref( params, yielded);
|
|
397
395
|
}
|
|
@@ -454,7 +452,7 @@ pgconn_set_client_encoding( VALUE self, VALUE str)
|
|
|
454
452
|
{
|
|
455
453
|
StringValue( str);
|
|
456
454
|
if ((PQsetClientEncoding( get_pgconn( self)->conn, RSTRING_PTR( str))) == -1)
|
|
457
|
-
rb_raise( rb_ePgError, "Invalid encoding name %s", str);
|
|
455
|
+
rb_raise( rb_ePgError, "Invalid encoding name %s", RSTRING_PTR( str));
|
|
458
456
|
return Qnil;
|
|
459
457
|
}
|
|
460
458
|
|
|
@@ -491,6 +489,8 @@ pgconn_set_externalenc( VALUE self, VALUE enc)
|
|
|
491
489
|
e = NIL_P( enc) ? rb_to_encoding( enc) : rb_default_external_encoding();
|
|
492
490
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
493
491
|
c->external = rb_enc_from_encoding( e);
|
|
492
|
+
|
|
493
|
+
return Qnil;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
/*
|
|
@@ -523,6 +523,8 @@ pgconn_set_internalenc( VALUE self, VALUE enc)
|
|
|
523
523
|
e = NIL_P( enc) ? rb_to_encoding( enc) : rb_default_internal_encoding();
|
|
524
524
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
525
525
|
c->internal = rb_enc_from_encoding( e);
|
|
526
|
+
|
|
527
|
+
return Qnil;
|
|
526
528
|
}
|
|
527
529
|
|
|
528
530
|
#endif
|
|
@@ -769,14 +771,14 @@ pgconn_untrace( VALUE self)
|
|
|
769
771
|
* == Example
|
|
770
772
|
*
|
|
771
773
|
* conn.exec <<-EOT
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
* $$
|
|
774
|
+
* CREATE OR REPLACE FUNCTION noise() RETURNS VOID AS $$
|
|
775
|
+
* BEGIN
|
|
776
|
+
* RAISE NOTICE 'Hi!';
|
|
777
|
+
* END;
|
|
778
|
+
* $$ LANGUAGE plpgsql;
|
|
777
779
|
* EOT
|
|
778
780
|
* conn.on_notice { |e| puts e.inspect }
|
|
779
|
-
* conn.exec "
|
|
781
|
+
* conn.exec "SELECT noise();"
|
|
780
782
|
*/
|
|
781
783
|
VALUE
|
|
782
784
|
pgconn_on_notice( VALUE self)
|
|
@@ -808,23 +810,20 @@ notice_receiver( void *self, const PGresult *result)
|
|
|
808
810
|
|
|
809
811
|
|
|
810
812
|
|
|
811
|
-
|
|
812
|
-
*
|
|
813
|
+
/*
|
|
813
814
|
* Document-class: Pg::Conn::Failed
|
|
814
815
|
*
|
|
815
816
|
* Error while establishing a connection to the PostgreSQL server.
|
|
816
817
|
*/
|
|
817
818
|
|
|
818
|
-
|
|
819
|
-
*
|
|
819
|
+
/*
|
|
820
820
|
* Document-class: Pg::Conn::Invalid
|
|
821
821
|
*
|
|
822
822
|
* Invalid (closed) connection.
|
|
823
823
|
*/
|
|
824
824
|
|
|
825
825
|
|
|
826
|
-
|
|
827
|
-
*
|
|
826
|
+
/*
|
|
828
827
|
* Document-class: Pg::Conn
|
|
829
828
|
*
|
|
830
829
|
* The class to access a PostgreSQL database.
|
|
@@ -833,7 +832,7 @@ notice_receiver( void *self, const PGresult *result)
|
|
|
833
832
|
*
|
|
834
833
|
* require "pgsql"
|
|
835
834
|
* conn = Pg::Conn.open :dbname => "test1"
|
|
836
|
-
* res = conn.exec "
|
|
835
|
+
* res = conn.exec "SELECT * FROM mytable;"
|
|
837
836
|
*
|
|
838
837
|
* See the Pg::Result class for information on working with the results of a
|
|
839
838
|
* query.
|
|
@@ -842,9 +841,14 @@ notice_receiver( void *self, const PGresult *result)
|
|
|
842
841
|
void
|
|
843
842
|
Init_pgsql_conn( void)
|
|
844
843
|
{
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
844
|
+
{
|
|
845
|
+
ID id_require;
|
|
846
|
+
|
|
847
|
+
id_require = rb_intern( "require");
|
|
848
|
+
rb_funcall( Qnil, id_require, 1, rb_str_new2( "date"));
|
|
849
|
+
rb_funcall( Qnil, id_require, 1, rb_str_new2( "time"));
|
|
850
|
+
rb_funcall( Qnil, id_require, 1, rb_str_new2( "bigdecimal"));
|
|
851
|
+
}
|
|
848
852
|
|
|
849
853
|
rb_cPgConn = rb_define_class_under( rb_mPg, "Conn", rb_cObject);
|
|
850
854
|
|
|
@@ -857,7 +861,6 @@ Init_pgsql_conn( void)
|
|
|
857
861
|
rb_define_alloc_func( rb_cPgConn, pgconn_alloc);
|
|
858
862
|
rb_define_singleton_method( rb_cPgConn, "connect", pgconn_s_connect, -1);
|
|
859
863
|
rb_define_alias( rb_singleton_class( rb_cPgConn), "open", "connect");
|
|
860
|
-
rb_define_singleton_method( rb_cPgConn, "parse", pgconn_s_parse, 1);
|
|
861
864
|
rb_define_method( rb_cPgConn, "initialize", &pgconn_init, -1);
|
|
862
865
|
rb_define_method( rb_cPgConn, "close", &pgconn_close, 0);
|
|
863
866
|
rb_define_alias( rb_cPgConn, "finish", "close");
|
data/lib/conn_exec.c
CHANGED
|
@@ -9,13 +9,6 @@
|
|
|
9
9
|
#include "result.h"
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
#ifdef HAVE_FUNC_RB_ERRINFO
|
|
13
|
-
#define RB_ERRINFO (rb_errinfo())
|
|
14
|
-
#else
|
|
15
|
-
#define RB_ERRINFO ruby_errinfo
|
|
16
|
-
#endif
|
|
17
|
-
|
|
18
|
-
|
|
19
12
|
static void pg_raise_connexec( struct pgconn_data *c);
|
|
20
13
|
|
|
21
14
|
static VALUE pg_statement_exec( VALUE conn, VALUE cmd, VALUE par);
|
|
@@ -37,11 +30,11 @@ static VALUE pgconn_select_values( int argc, VALUE *argv, VALUE self);
|
|
|
37
30
|
static VALUE pgconn_get_notify( VALUE self);
|
|
38
31
|
|
|
39
32
|
static VALUE pgconn_transaction( int argc, VALUE *argv, VALUE self);
|
|
40
|
-
static VALUE rollback_transaction( VALUE self);
|
|
33
|
+
static VALUE rollback_transaction( VALUE self, VALUE err);
|
|
41
34
|
static VALUE commit_transaction( VALUE self);
|
|
42
35
|
static VALUE yield_transaction( VALUE self);
|
|
43
36
|
static VALUE pgconn_subtransaction( int argc, VALUE *argv, VALUE self);
|
|
44
|
-
static VALUE rollback_subtransaction( VALUE ary);
|
|
37
|
+
static VALUE rollback_subtransaction( VALUE ary, VALUE err);
|
|
45
38
|
static VALUE release_subtransaction( VALUE ary);
|
|
46
39
|
static VALUE yield_subtransaction( VALUE ary);
|
|
47
40
|
static VALUE pgconn_transaction_status( VALUE self);
|
|
@@ -69,7 +62,7 @@ static ID id_to_a;
|
|
|
69
62
|
void
|
|
70
63
|
pg_raise_connexec( struct pgconn_data *c)
|
|
71
64
|
{
|
|
72
|
-
rb_raise( rb_ePgConnExec, PQerrorMessage( c->conn));
|
|
65
|
+
rb_raise( rb_ePgConnExec, "%s", PQerrorMessage( c->conn));
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
|
|
@@ -144,7 +137,7 @@ params_to_strings( VALUE conn, VALUE params, int *len)
|
|
|
144
137
|
|
|
145
138
|
q = pgconn_destring( c, pgconn_stringize( conn, *ptr), &n);
|
|
146
139
|
a = ALLOC_N( char, n + 1);
|
|
147
|
-
for (p = a; *p = n ? *q : '\0'; ++p, ++q, --n)
|
|
140
|
+
for (p = a; (*p = n ? *q : '\0'); ++p, ++q, --n)
|
|
148
141
|
;
|
|
149
142
|
*v = a;
|
|
150
143
|
}
|
|
@@ -166,8 +159,6 @@ free_strings( char **strs, int len)
|
|
|
166
159
|
void
|
|
167
160
|
pg_parse_parameters( int argc, VALUE *argv, VALUE *cmd, VALUE *par)
|
|
168
161
|
{
|
|
169
|
-
int len;
|
|
170
|
-
|
|
171
162
|
rb_scan_args( argc, argv, "1*", cmd, par);
|
|
172
163
|
StringValue( *cmd);
|
|
173
164
|
if (RARRAY_LEN( *par) <= 0)
|
|
@@ -207,7 +198,7 @@ pgconn_exec( int argc, VALUE *argv, VALUE self)
|
|
|
207
198
|
* Use Pg::Conn#fetch to fetch the results after you waited for data.
|
|
208
199
|
*
|
|
209
200
|
* Pg::Conn.connect do |conn|
|
|
210
|
-
* conn.send "
|
|
201
|
+
* conn.send "SELECT pg_sleep(3), * FROM t;" do
|
|
211
202
|
* ins = [ conn.socket]
|
|
212
203
|
* loop do
|
|
213
204
|
* r = IO.select ins, nil, nil, 0.5
|
|
@@ -244,7 +235,6 @@ pgconn_fetch( VALUE self)
|
|
|
244
235
|
{
|
|
245
236
|
struct pgconn_data *c;
|
|
246
237
|
PGresult *result;
|
|
247
|
-
VALUE res;
|
|
248
238
|
|
|
249
239
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
250
240
|
pg_check_conninvalid( c);
|
|
@@ -260,9 +250,6 @@ pgconn_fetch( VALUE self)
|
|
|
260
250
|
VALUE
|
|
261
251
|
yield_or_return_result( VALUE result)
|
|
262
252
|
{
|
|
263
|
-
struct pgresult_data *r;
|
|
264
|
-
|
|
265
|
-
Data_Get_Struct( result, struct pgresult_data, r);
|
|
266
253
|
return rb_block_given_p() ?
|
|
267
254
|
rb_ensure( rb_yield, result, pgresult_clear, result) : result;
|
|
268
255
|
}
|
|
@@ -472,10 +459,10 @@ yield_transaction( VALUE self)
|
|
|
472
459
|
}
|
|
473
460
|
|
|
474
461
|
VALUE
|
|
475
|
-
rollback_transaction( VALUE self)
|
|
462
|
+
rollback_transaction( VALUE self, VALUE err)
|
|
476
463
|
{
|
|
477
|
-
pgresult_clear( pg_statement_exec( self, rb_str_new2( "
|
|
478
|
-
rb_exc_raise(
|
|
464
|
+
pgresult_clear( pg_statement_exec( self, rb_str_new2( "ROLLBACK;"), Qnil));
|
|
465
|
+
rb_exc_raise( err);
|
|
479
466
|
return Qnil;
|
|
480
467
|
}
|
|
481
468
|
|
|
@@ -486,7 +473,7 @@ commit_transaction( VALUE self)
|
|
|
486
473
|
|
|
487
474
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
488
475
|
if (PQtransactionStatus( c->conn) > PQTRANS_IDLE)
|
|
489
|
-
pgresult_clear( pg_statement_exec( self, rb_str_new2( "
|
|
476
|
+
pgresult_clear( pg_statement_exec( self, rb_str_new2( "COMMIT;"), Qnil));
|
|
490
477
|
return Qnil;
|
|
491
478
|
}
|
|
492
479
|
|
|
@@ -533,7 +520,7 @@ yield_subtransaction( VALUE ary)
|
|
|
533
520
|
}
|
|
534
521
|
|
|
535
522
|
VALUE
|
|
536
|
-
rollback_subtransaction( VALUE ary)
|
|
523
|
+
rollback_subtransaction( VALUE ary, VALUE err)
|
|
537
524
|
{
|
|
538
525
|
VALUE cmd;
|
|
539
526
|
|
|
@@ -542,7 +529,7 @@ rollback_subtransaction( VALUE ary)
|
|
|
542
529
|
rb_str_buf_cat2( cmd, ";");
|
|
543
530
|
pgresult_clear( pg_statement_exec( rb_ary_entry( ary, 0), cmd, Qnil));
|
|
544
531
|
rb_ary_store( ary, 1, Qnil);
|
|
545
|
-
rb_exc_raise(
|
|
532
|
+
rb_exc_raise( err);
|
|
546
533
|
return Qnil;
|
|
547
534
|
}
|
|
548
535
|
|
|
@@ -595,7 +582,7 @@ pgconn_transaction_status( VALUE self)
|
|
|
595
582
|
* Write lines into a +COPY+ command. See +stringize_line+ for how to build
|
|
596
583
|
* standard lines.
|
|
597
584
|
*
|
|
598
|
-
* conn.copy_stdin "
|
|
585
|
+
* conn.copy_stdin "COPY t FROM STDIN;" do
|
|
599
586
|
* ary = ...
|
|
600
587
|
* l = stringize_line ary
|
|
601
588
|
* conn.put l
|
|
@@ -625,7 +612,7 @@ put_end( VALUE self)
|
|
|
625
612
|
Data_Get_Struct( self, struct pgconn_data, c);
|
|
626
613
|
/*
|
|
627
614
|
* I would like to hand over something like
|
|
628
|
-
* RSTRING_PTR( rb_obj_as_string(
|
|
615
|
+
* RSTRING_PTR( rb_obj_as_string( rb_errinfo()))
|
|
629
616
|
* here but when execution is inside a rescue block
|
|
630
617
|
* the error info will be non-null even though the
|
|
631
618
|
* exception just has been caught.
|
|
@@ -700,7 +687,7 @@ pgconn_putline( VALUE self, VALUE arg)
|
|
|
700
687
|
* Read lines from a +COPY+ command. The form of the lines depends
|
|
701
688
|
* on the statement's parameters.
|
|
702
689
|
*
|
|
703
|
-
* conn.copy_stdout "
|
|
690
|
+
* conn.copy_stdout "COPY t TO STDOUT;" do
|
|
704
691
|
* l = conn.getline
|
|
705
692
|
* ary = l.split /\t/
|
|
706
693
|
* ary.map! { |x|
|
|
@@ -821,7 +808,7 @@ pgconn_backup( VALUE self, VALUE label)
|
|
|
821
808
|
{
|
|
822
809
|
VALUE cmd, arg;
|
|
823
810
|
|
|
824
|
-
cmd = rb_str_new2( "
|
|
811
|
+
cmd = rb_str_new2( "SELECT pg_start_backup($1);");
|
|
825
812
|
arg = rb_ary_new3( 1, label);
|
|
826
813
|
pgresult_clear( pg_statement_exec( self, cmd, arg));
|
|
827
814
|
return rb_ensure( rb_yield, Qnil, backup_end, self);
|
|
@@ -833,31 +820,28 @@ backup_end( VALUE self)
|
|
|
833
820
|
{
|
|
834
821
|
VALUE cmd;
|
|
835
822
|
|
|
836
|
-
cmd = rb_str_new2( "
|
|
823
|
+
cmd = rb_str_new2( "SELECT pg_stop_backup();");
|
|
837
824
|
pgresult_clear( pg_statement_exec( self, cmd, Qnil));
|
|
838
825
|
return Qnil;
|
|
839
826
|
}
|
|
840
827
|
|
|
841
828
|
|
|
842
829
|
|
|
843
|
-
|
|
844
|
-
*
|
|
830
|
+
/*
|
|
845
831
|
* Document-class: Pg::Conn::ExecError
|
|
846
832
|
*
|
|
847
833
|
* Error while querying from a PostgreSQL connection.
|
|
848
834
|
*/
|
|
849
835
|
|
|
850
836
|
|
|
851
|
-
|
|
852
|
-
*
|
|
837
|
+
/*
|
|
853
838
|
* Document-class: Pg::Conn::TransactionError
|
|
854
839
|
*
|
|
855
840
|
* Nested transaction blocks. Use savepoints.
|
|
856
841
|
*/
|
|
857
842
|
|
|
858
843
|
|
|
859
|
-
|
|
860
|
-
*
|
|
844
|
+
/*
|
|
861
845
|
* Document-class: Pg::Conn::CopyError
|
|
862
846
|
*
|
|
863
847
|
* Nested transaction blocks. Use savepoints.
|
|
@@ -911,6 +895,6 @@ Init_pgsql_conn_exec( void)
|
|
|
911
895
|
|
|
912
896
|
rb_define_method( rb_cPgConn, "backup", &pgconn_backup, 1);
|
|
913
897
|
|
|
914
|
-
|
|
898
|
+
id_to_a = 0;
|
|
915
899
|
}
|
|
916
900
|
|
data/lib/conn_quote.c
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
#include "conn_quote.h"
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
extern VALUE
|
|
9
|
+
extern VALUE pg_monetary_class( void);
|
|
10
10
|
|
|
11
11
|
static VALUE pgconn_format( VALUE self, VALUE obj);
|
|
12
12
|
|
|
@@ -23,7 +23,8 @@ extern VALUE pgconn_for_copy( VALUE self, VALUE str);
|
|
|
23
23
|
static int needs_dquote_string( VALUE str);
|
|
24
24
|
static VALUE dquote_string( VALUE str);
|
|
25
25
|
static VALUE stringize_array( VALUE self, VALUE result, VALUE ary);
|
|
26
|
-
static VALUE gsub_escape_i(
|
|
26
|
+
static VALUE gsub_escape_i( RB_BLOCK_CALL_FUNC_ARGLIST( c, arg));
|
|
27
|
+
|
|
27
28
|
|
|
28
29
|
static VALUE pgconn_quote( VALUE self, VALUE obj);
|
|
29
30
|
static VALUE pgconn_quote_all( int argc, VALUE *argv, VALUE self);
|
|
@@ -34,33 +35,60 @@ static void quote_all( VALUE self, VALUE ary, VALUE res);
|
|
|
34
35
|
static VALUE pgconn_quote_identifier( VALUE self, VALUE value);
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
|
|
38
38
|
VALUE rb_cDate;
|
|
39
39
|
VALUE rb_cDateTime;
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
static VALUE rb_cMoney;
|
|
41
42
|
|
|
42
43
|
static ID id_format;
|
|
43
44
|
static ID id_iso8601;
|
|
44
45
|
static ID id_raw;
|
|
45
46
|
static ID id_to_postgres;
|
|
46
47
|
static ID id_gsub;
|
|
47
|
-
|
|
48
|
+
|
|
49
|
+
static int lookup_monetary;
|
|
48
50
|
|
|
49
51
|
static VALUE pg_string_null;
|
|
50
52
|
static VALUE pg_string_bsl_N;
|
|
51
53
|
static VALUE pg_escape_regex;
|
|
52
54
|
|
|
53
55
|
|
|
56
|
+
static const char *monetary[] = { "Money", "Monetary", "Amount", "Currency"};
|
|
54
57
|
|
|
58
|
+
/*
|
|
59
|
+
* Document-class: Pg::Money
|
|
60
|
+
*
|
|
61
|
+
* The class the PostgreSQL-builtin type +MONEY+ wil be mapped to.
|
|
62
|
+
* If not set, some global classes will be searched
|
|
63
|
+
* (+Money+, +Monetary+, +Amount+, +Currency+) and the constant will be
|
|
64
|
+
* set to that.
|
|
65
|
+
*
|
|
66
|
+
* Set this constant to your own class before you do the first query,
|
|
67
|
+
* or set it to +nil+ to inhibit the auto-detect.
|
|
68
|
+
*
|
|
69
|
+
* The resulting class must have a method +parse+ to build a new object
|
|
70
|
+
* from a string. It may respond to +raw+ which overwrites +to_s+.
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
55
73
|
VALUE
|
|
56
|
-
|
|
74
|
+
pg_monetary_class( void)
|
|
57
75
|
{
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
if (lookup_monetary) {
|
|
77
|
+
ID id_MONEY = rb_intern( "Money");
|
|
78
|
+
if (rb_const_defined( rb_mPg, id_MONEY))
|
|
79
|
+
rb_cMoney = rb_const_get( rb_mPg, id_MONEY);
|
|
80
|
+
else {
|
|
81
|
+
int i;
|
|
82
|
+
for (i = 0; i < (sizeof monetary) / sizeof (char *) && NIL_P( rb_cMoney); i++) {
|
|
83
|
+
ID id = rb_intern( monetary[ i]);
|
|
84
|
+
if (rb_const_defined( rb_cObject, id))
|
|
85
|
+
rb_cMoney = rb_const_get( rb_cObject, id);
|
|
86
|
+
}
|
|
87
|
+
rb_const_set( rb_mPg, id_MONEY, rb_cMoney);
|
|
88
|
+
}
|
|
89
|
+
lookup_monetary = 0;
|
|
62
90
|
}
|
|
63
|
-
return
|
|
91
|
+
return rb_cMoney;
|
|
64
92
|
}
|
|
65
93
|
|
|
66
94
|
|
|
@@ -80,8 +108,8 @@ pg_currency_class( void)
|
|
|
80
108
|
* class MyConn < Pg::Conn
|
|
81
109
|
* def format obj
|
|
82
110
|
* case obj
|
|
83
|
-
* when
|
|
84
|
-
* else
|
|
111
|
+
* when Money then obj.to_s_by_locale
|
|
112
|
+
* else obj
|
|
85
113
|
* end
|
|
86
114
|
* end
|
|
87
115
|
* end
|
|
@@ -121,7 +149,7 @@ VALUE
|
|
|
121
149
|
pgconn_escape_bytea( VALUE self, VALUE str)
|
|
122
150
|
{
|
|
123
151
|
unsigned char *s;
|
|
124
|
-
|
|
152
|
+
size_t l;
|
|
125
153
|
VALUE ret;
|
|
126
154
|
|
|
127
155
|
if (NIL_P( str))
|
|
@@ -172,11 +200,11 @@ pgconn_unescape_bytea( VALUE self, VALUE obj)
|
|
|
172
200
|
size_t l;
|
|
173
201
|
VALUE ret;
|
|
174
202
|
|
|
175
|
-
if (NIL_P( obj))
|
|
176
|
-
return Qnil;
|
|
177
203
|
#ifdef RUBY_ENCODING
|
|
178
204
|
rb_scan_args( argc, argv, "11", &obj, &enc);
|
|
179
205
|
#endif
|
|
206
|
+
if (NIL_P( obj))
|
|
207
|
+
return Qnil;
|
|
180
208
|
StringValue( obj);
|
|
181
209
|
|
|
182
210
|
s = PQunescapeBytea( (unsigned char *) RSTRING_PTR( obj), &l);
|
|
@@ -264,7 +292,7 @@ pgconn_stringize( VALUE self, VALUE obj)
|
|
|
264
292
|
result = rb_obj_as_string( obj);
|
|
265
293
|
else if (co == rb_cDateTime)
|
|
266
294
|
result = rb_obj_as_string( obj);
|
|
267
|
-
else if (co ==
|
|
295
|
+
else if (co == pg_monetary_class() &&
|
|
268
296
|
rb_respond_to( obj, id_raw))
|
|
269
297
|
result = rb_funcall( obj, id_raw, 0);
|
|
270
298
|
else if (rb_respond_to( obj, id_to_postgres)) {
|
|
@@ -292,7 +320,7 @@ pgconn_stringize_line( VALUE self, VALUE ary)
|
|
|
292
320
|
VALUE a;
|
|
293
321
|
VALUE *p;
|
|
294
322
|
int l;
|
|
295
|
-
VALUE ret
|
|
323
|
+
VALUE ret;
|
|
296
324
|
|
|
297
325
|
a = rb_check_convert_type( ary, T_ARRAY, "Array", "to_ary");
|
|
298
326
|
if (NIL_P(a))
|
|
@@ -384,13 +412,13 @@ dquote_string( VALUE str)
|
|
|
384
412
|
VALUE
|
|
385
413
|
stringize_array( VALUE self, VALUE result, VALUE ary)
|
|
386
414
|
{
|
|
387
|
-
long i
|
|
415
|
+
long i;
|
|
388
416
|
VALUE *o;
|
|
389
417
|
VALUE cf, co;
|
|
390
418
|
VALUE r;
|
|
391
419
|
|
|
392
420
|
cf = Qundef;
|
|
393
|
-
for (o = RARRAY_PTR( ary),
|
|
421
|
+
for (o = RARRAY_PTR( ary), i = RARRAY_LEN( ary); i; ++o, --i) {
|
|
394
422
|
co = CLASS_OF( *o);
|
|
395
423
|
if (cf == Qundef)
|
|
396
424
|
cf = co;
|
|
@@ -411,7 +439,7 @@ stringize_array( VALUE self, VALUE result, VALUE ary)
|
|
|
411
439
|
|
|
412
440
|
|
|
413
441
|
VALUE
|
|
414
|
-
gsub_escape_i(
|
|
442
|
+
gsub_escape_i( RB_BLOCK_CALL_FUNC_ARGLIST( c, arg))
|
|
415
443
|
{
|
|
416
444
|
const char *r;
|
|
417
445
|
|
|
@@ -453,7 +481,9 @@ gsub_escape_i( VALUE c, VALUE arg)
|
|
|
453
481
|
* Call Pg::Conn#escape_bytea first if you want to tell your string is a byte
|
|
454
482
|
* array and the quote that result.
|
|
455
483
|
*/
|
|
456
|
-
VALUE pgconn_quote( VALUE self, VALUE obj)
|
|
484
|
+
VALUE pgconn_quote( VALUE self, VALUE obj)
|
|
485
|
+
{
|
|
486
|
+
VALUE o, res;
|
|
457
487
|
|
|
458
488
|
o = rb_funcall( self, id_format, 1, obj);
|
|
459
489
|
if (!NIL_P( o))
|
|
@@ -494,7 +524,7 @@ VALUE pgconn_quote( VALUE self, VALUE obj) { VALUE o, res;
|
|
|
494
524
|
} else if (co == rb_cDateTime) {
|
|
495
525
|
res = rb_obj_as_string( obj);
|
|
496
526
|
type = "timestamptz";
|
|
497
|
-
} else if (co ==
|
|
527
|
+
} else if (co == pg_monetary_class() &&
|
|
498
528
|
rb_respond_to( obj, id_raw)) {
|
|
499
529
|
res = rb_funcall( obj, id_raw, 0);
|
|
500
530
|
StringValue( res);
|
|
@@ -555,12 +585,12 @@ quote_string( VALUE conn, VALUE str)
|
|
|
555
585
|
VALUE
|
|
556
586
|
quote_array( VALUE self, VALUE result, VALUE ary)
|
|
557
587
|
{
|
|
558
|
-
long i
|
|
588
|
+
long i;
|
|
559
589
|
VALUE *o;
|
|
560
590
|
VALUE cf, co;
|
|
561
591
|
|
|
562
592
|
cf = Qundef;
|
|
563
|
-
for (o = RARRAY_PTR( ary),
|
|
593
|
+
for (o = RARRAY_PTR( ary), i = RARRAY_LEN( ary); i; ++o, --i) {
|
|
564
594
|
co = CLASS_OF( *o);
|
|
565
595
|
if (cf == Qundef)
|
|
566
596
|
cf = co;
|
|
@@ -622,11 +652,9 @@ pgconn_quote_identifier( VALUE self, VALUE str)
|
|
|
622
652
|
void
|
|
623
653
|
Init_pgsql_conn_quote( void)
|
|
624
654
|
{
|
|
625
|
-
rb_require( "date");
|
|
626
|
-
rb_require( "time");
|
|
627
655
|
rb_cDate = rb_const_get( rb_cObject, rb_intern( "Date"));
|
|
628
656
|
rb_cDateTime = rb_const_get( rb_cObject, rb_intern( "DateTime"));
|
|
629
|
-
|
|
657
|
+
rb_cMoney = Qnil;
|
|
630
658
|
|
|
631
659
|
#ifdef RDOC_NEEDS_THIS
|
|
632
660
|
rb_cPgConn = rb_define_class_under( rb_mPg, "Conn", rb_cObject);
|
|
@@ -660,7 +688,7 @@ Init_pgsql_conn_quote( void)
|
|
|
660
688
|
id_to_postgres = rb_intern( "to_postgres");
|
|
661
689
|
id_gsub = rb_intern( "gsub");
|
|
662
690
|
|
|
663
|
-
|
|
691
|
+
lookup_monetary = 1;
|
|
664
692
|
|
|
665
693
|
pg_string_null = rb_str_new2( "NULL"); rb_global_variable( &pg_string_null); rb_str_freeze( pg_string_null);
|
|
666
694
|
pg_string_bsl_N = rb_str_new2( "\\N"); rb_global_variable( &pg_string_bsl_N); rb_str_freeze( pg_string_bsl_N);
|
data/lib/conn_quote.h
CHANGED
data/lib/mkrf_conf
CHANGED
|
@@ -10,27 +10,19 @@ Autorake.configure {
|
|
|
10
10
|
|
|
11
11
|
extending_ruby
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
have_header "st.h"
|
|
17
|
-
else
|
|
18
|
-
have_header "ruby/ruby.h"
|
|
19
|
-
have_header "ruby/io.h"
|
|
20
|
-
end
|
|
13
|
+
need_header "ruby/ruby.h"
|
|
14
|
+
need_header "ruby/io.h"
|
|
15
|
+
|
|
21
16
|
|
|
22
17
|
incdir :postgres, `pg_config --pkgincludedir`
|
|
23
18
|
incdir :postgres_server, `pg_config --includedir-server`
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
have_library "ssl"
|
|
27
|
-
have_library "pq"
|
|
20
|
+
need_library "pq"
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
need_header "postgres.h"
|
|
23
|
+
need_header "libpq-fe.h"
|
|
24
|
+
need_header "catalog/pg_type.h"
|
|
32
25
|
|
|
33
|
-
have_func "rb_errinfo"
|
|
34
26
|
have_func "rb_io_stdio_file"
|
|
35
27
|
have_func "rb_locale_encoding"
|
|
36
28
|
|
data/lib/module.c
CHANGED
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
#include "module.h"
|
|
6
6
|
|
|
7
7
|
#include "conn.h"
|
|
8
|
+
#include "result.h"
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
#define PGSQL_VERSION "1.
|
|
11
|
+
#define PGSQL_VERSION "1.7"
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
VALUE rb_mPg;
|
|
14
15
|
VALUE rb_ePgError;
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
*
|
|
18
|
+
/*
|
|
19
19
|
* Document-module: Pg
|
|
20
20
|
*
|
|
21
21
|
* The module to enclose everything.
|
|
@@ -24,8 +24,7 @@ VALUE rb_ePgError;
|
|
|
24
24
|
* connection.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
*
|
|
27
|
+
/*
|
|
29
28
|
* Document-class: Pg::Error
|
|
30
29
|
*
|
|
31
30
|
* Generic PostgreSQL error.
|
data/lib/module.h
CHANGED
|
@@ -18,15 +18,9 @@
|
|
|
18
18
|
#endif
|
|
19
19
|
#include "undef.h"
|
|
20
20
|
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
#ifdef HAVE_HEADER_LIBPQ_FE_H
|
|
25
|
-
#include <libpq-fe.h>
|
|
26
|
-
#endif
|
|
27
|
-
#ifdef HAVE_HEADER_CATALOG_PG_TYPE_H
|
|
28
|
-
#include <catalog/pg_type.h>
|
|
29
|
-
#endif
|
|
21
|
+
#include <postgres.h>
|
|
22
|
+
#include <libpq-fe.h>
|
|
23
|
+
#include <catalog/pg_type.h>
|
|
30
24
|
#include "undef.h"
|
|
31
25
|
|
|
32
26
|
|
data/lib/result.c
CHANGED
|
@@ -11,9 +11,6 @@
|
|
|
11
11
|
static void pgresult_init( struct pgresult_data *r, PGresult *result, struct pgconn_data *conn);
|
|
12
12
|
static VALUE pgreserror_new( VALUE result, VALUE cmd, VALUE par);
|
|
13
13
|
|
|
14
|
-
static VALUE pgreserror_command( VALUE self);
|
|
15
|
-
static VALUE pgreserror_params( VALUE self);
|
|
16
|
-
|
|
17
14
|
static struct pgresult_data *pgreserror_result( VALUE self);
|
|
18
15
|
static VALUE pgreserror_status( VALUE self);
|
|
19
16
|
static VALUE pgreserror_sqlst( VALUE self);
|
|
@@ -25,7 +22,6 @@ static VALUE pgreserror_diag( VALUE self, VALUE field);
|
|
|
25
22
|
|
|
26
23
|
static VALUE pgresult_s_translate_results_set( VALUE cls, VALUE fact);
|
|
27
24
|
|
|
28
|
-
static void pgresult_mark( struct pgresult_data *ptr);
|
|
29
25
|
static void pgresult_free( struct pgresult_data *ptr);
|
|
30
26
|
extern VALUE pgresult_new( PGresult *result, struct pgconn_data *conn, VALUE cmd, VALUE par);
|
|
31
27
|
|
|
@@ -57,8 +53,6 @@ static VALUE pgresult_cmdstatus( VALUE self);
|
|
|
57
53
|
static VALUE pgresult_oid( VALUE self);
|
|
58
54
|
|
|
59
55
|
|
|
60
|
-
static VALUE rb_cBigDecimal;
|
|
61
|
-
|
|
62
56
|
static VALUE rb_cPgResult;
|
|
63
57
|
static VALUE rb_ePgResError;
|
|
64
58
|
|
|
@@ -216,13 +210,6 @@ pgresult_s_translate_results_set( VALUE cls, VALUE fact)
|
|
|
216
210
|
|
|
217
211
|
|
|
218
212
|
|
|
219
|
-
void
|
|
220
|
-
pgresult_mark( struct pgresult_data *ptr)
|
|
221
|
-
{
|
|
222
|
-
rb_gc_mark( ptr->fields);
|
|
223
|
-
rb_gc_mark( ptr->indices);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
213
|
void
|
|
227
214
|
pgresult_free( struct pgresult_data *ptr)
|
|
228
215
|
{
|
|
@@ -280,8 +267,8 @@ pgresult_clear( VALUE self)
|
|
|
280
267
|
|
|
281
268
|
Data_Get_Struct( self, struct pgresult_data, r);
|
|
282
269
|
if (r->res != NULL) {
|
|
283
|
-
|
|
284
|
-
|
|
270
|
+
PQclear( r->res);
|
|
271
|
+
r->res = NULL;
|
|
285
272
|
}
|
|
286
273
|
return Qnil;
|
|
287
274
|
}
|
|
@@ -513,7 +500,7 @@ pg_fetchrow( struct pgresult_data *r, int num)
|
|
|
513
500
|
n = PQnfields( r->res);
|
|
514
501
|
if (num < PQntuples( r->res)) {
|
|
515
502
|
row = rb_ary_new2( n);
|
|
516
|
-
for (i = 0
|
|
503
|
+
for (i = 0; n; ++i, --n)
|
|
517
504
|
rb_ary_store( row, i, pg_fetchresult( r, num, i));
|
|
518
505
|
} else
|
|
519
506
|
row = Qnil;
|
|
@@ -525,7 +512,7 @@ pg_fetchresult( struct pgresult_data *r, int row, int col)
|
|
|
525
512
|
{
|
|
526
513
|
char *string;
|
|
527
514
|
Oid typ;
|
|
528
|
-
VALUE ret;
|
|
515
|
+
VALUE cls, ret;
|
|
529
516
|
|
|
530
517
|
if (PQgetisnull( r->res, row, col))
|
|
531
518
|
return Qnil;
|
|
@@ -538,50 +525,59 @@ pg_fetchresult( struct pgresult_data *r, int row, int col)
|
|
|
538
525
|
return pgconn_mkstring( r->conn, string);
|
|
539
526
|
|
|
540
527
|
typ = PQftype( r->res, col);
|
|
528
|
+
cls = Qnil;
|
|
529
|
+
ret = Qnil;
|
|
541
530
|
switch (typ) {
|
|
542
531
|
case NUMERICOID:
|
|
543
532
|
{
|
|
544
533
|
int typmod;
|
|
545
534
|
|
|
546
535
|
typmod = PQfmod( r->res, col);
|
|
547
|
-
if (typmod == -1 || (typmod - VARHDRSZ) & 0xffff)
|
|
536
|
+
if (typmod == -1 || (typmod - VARHDRSZ) & 0xffff) {
|
|
537
|
+
ret = rb_funcall( Qnil, rb_intern( "BigDecimal"), 1, rb_str_new2( string));
|
|
548
538
|
break;
|
|
539
|
+
}
|
|
549
540
|
}
|
|
550
|
-
/* if scale == 0
|
|
541
|
+
/* fall through if scale == 0 */
|
|
551
542
|
case INT8OID:
|
|
552
543
|
case INT4OID:
|
|
553
544
|
case INT2OID:
|
|
554
545
|
case OIDOID:
|
|
555
|
-
|
|
546
|
+
ret = rb_cstr_to_inum( string, 10, 0);
|
|
547
|
+
break;
|
|
556
548
|
case FLOAT8OID:
|
|
557
549
|
case FLOAT4OID:
|
|
558
|
-
|
|
550
|
+
ret = rb_float_new( rb_cstr_to_dbl( string, Qfalse));
|
|
551
|
+
break;
|
|
559
552
|
case BOOLOID:
|
|
560
|
-
|
|
561
|
-
|
|
553
|
+
ret = strchr( "tTyY", *string) != NULL ? Qtrue : Qfalse;
|
|
554
|
+
break;
|
|
562
555
|
case BYTEAOID:
|
|
563
|
-
|
|
564
|
-
default:
|
|
556
|
+
ret = rb_str_new2( string);
|
|
565
557
|
break;
|
|
566
|
-
}
|
|
567
|
-
ret = pgconn_mkstring( r->conn, string);
|
|
568
|
-
switch (typ) {
|
|
569
|
-
case NUMERICOID:
|
|
570
|
-
return rb_funcall( rb_cBigDecimal, id_new, 1, ret);
|
|
571
558
|
case DATEOID:
|
|
572
|
-
|
|
559
|
+
cls = rb_cDate;
|
|
560
|
+
break;
|
|
573
561
|
case TIMEOID:
|
|
574
562
|
case TIMETZOID:
|
|
575
|
-
|
|
563
|
+
cls = rb_cTime;
|
|
564
|
+
break;
|
|
576
565
|
case TIMESTAMPOID:
|
|
577
566
|
case TIMESTAMPTZOID:
|
|
578
|
-
|
|
567
|
+
cls = rb_cDateTime;
|
|
568
|
+
break;
|
|
579
569
|
case CASHOID:
|
|
580
|
-
|
|
581
|
-
|
|
570
|
+
cls = pg_monetary_class();
|
|
571
|
+
break;
|
|
582
572
|
default:
|
|
583
|
-
|
|
573
|
+
break;
|
|
584
574
|
}
|
|
575
|
+
if (NIL_P( ret)) {
|
|
576
|
+
ret = pgconn_mkstring( r->conn, string);
|
|
577
|
+
if (RTEST( cls))
|
|
578
|
+
ret = rb_funcall( cls, id_parse, 1, ret);
|
|
579
|
+
}
|
|
580
|
+
return ret;
|
|
585
581
|
}
|
|
586
582
|
|
|
587
583
|
/*
|
|
@@ -803,9 +799,6 @@ pgresult_oid( VALUE self)
|
|
|
803
799
|
void
|
|
804
800
|
Init_pgsql_result( void)
|
|
805
801
|
{
|
|
806
|
-
rb_require( "bigdecimal");
|
|
807
|
-
rb_cBigDecimal = rb_const_get( rb_cObject, rb_intern( "BigDecimal"));
|
|
808
|
-
|
|
809
802
|
rb_cPgResult = rb_define_class_under( rb_mPg, "Result", rb_cObject);
|
|
810
803
|
|
|
811
804
|
|
metadata
CHANGED
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgsql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.7'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bertram Scharpf
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-03-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: autorake
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '2.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.0'
|
|
27
|
-
description:
|
|
28
|
-
by Guy
|
|
29
|
-
|
|
30
|
-
Decoux. As the project wasn''t maintained a long time after Guy''s decease, I
|
|
31
|
-
|
|
27
|
+
description: |
|
|
28
|
+
This is not the official PostgreSQL library that was originally written by Guy
|
|
29
|
+
Decoux. As the project wasn't maintained a long time after Guy's decease, I
|
|
32
30
|
decided to fork my own project.
|
|
33
|
-
|
|
34
|
-
'
|
|
35
|
-
email: <software@bertram-scharpf.de>
|
|
31
|
+
email: "<software@bertram-scharpf.de>"
|
|
36
32
|
executables: []
|
|
37
33
|
extensions:
|
|
38
34
|
- lib/mkrf_conf
|
|
@@ -40,47 +36,45 @@ extra_rdoc_files:
|
|
|
40
36
|
- README
|
|
41
37
|
- LICENSE
|
|
42
38
|
files:
|
|
39
|
+
- LICENSE
|
|
40
|
+
- README
|
|
43
41
|
- lib/Rakefile
|
|
44
|
-
- lib/mkrf_conf
|
|
45
|
-
- lib/undef.h
|
|
46
|
-
- lib/module.h
|
|
47
|
-
- lib/module.c
|
|
48
|
-
- lib/conn.h
|
|
49
42
|
- lib/conn.c
|
|
50
|
-
- lib/
|
|
51
|
-
- lib/conn_quote.c
|
|
52
|
-
- lib/conn_exec.h
|
|
43
|
+
- lib/conn.h
|
|
53
44
|
- lib/conn_exec.c
|
|
54
|
-
- lib/
|
|
45
|
+
- lib/conn_exec.h
|
|
46
|
+
- lib/conn_quote.c
|
|
47
|
+
- lib/conn_quote.h
|
|
48
|
+
- lib/mkrf_conf
|
|
49
|
+
- lib/module.c
|
|
50
|
+
- lib/module.h
|
|
55
51
|
- lib/result.c
|
|
56
|
-
-
|
|
57
|
-
-
|
|
52
|
+
- lib/result.h
|
|
53
|
+
- lib/undef.h
|
|
58
54
|
homepage: http://www.bertram-scharpf.de/software/pgsql
|
|
59
|
-
licenses:
|
|
55
|
+
licenses:
|
|
56
|
+
- BSD-2-Clause
|
|
60
57
|
metadata: {}
|
|
61
|
-
post_install_message:
|
|
58
|
+
post_install_message:
|
|
62
59
|
rdoc_options:
|
|
63
|
-
- --
|
|
64
|
-
- utf-8
|
|
65
|
-
- --main
|
|
60
|
+
- "--main"
|
|
66
61
|
- README
|
|
67
62
|
require_paths:
|
|
68
63
|
- lib
|
|
69
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
65
|
requirements:
|
|
71
|
-
- -
|
|
66
|
+
- - ">="
|
|
72
67
|
- !ruby/object:Gem::Version
|
|
73
68
|
version: '0'
|
|
74
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
70
|
requirements:
|
|
76
|
-
- -
|
|
71
|
+
- - ">="
|
|
77
72
|
- !ruby/object:Gem::Version
|
|
78
73
|
version: '0'
|
|
79
74
|
requirements:
|
|
80
75
|
- PostgreSQL
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
signing_key:
|
|
76
|
+
rubygems_version: 3.0.8
|
|
77
|
+
signing_key:
|
|
84
78
|
specification_version: 4
|
|
85
79
|
summary: PostgreSQL-API for Ruby
|
|
86
80
|
test_files: []
|