pgsql 1.4 → 1.8
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 +4 -4
- data/LICENSE +2 -8
- data/README +26 -25
- data/lib/Rakefile +2 -2
- data/lib/conn.c +106 -107
- data/lib/conn_exec.c +24 -39
- data/lib/conn_quote.c +53 -27
- data/lib/conn_quote.h +1 -2
- data/lib/mkrf_conf +7 -15
- data/lib/module.c +3 -5
- data/lib/module.h +3 -9
- data/lib/result.c +29 -36
- metadata +6 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9774f4721fba4301276843fea1a5287083234d0aadf8947559b08e2619a97e7
|
4
|
+
data.tar.gz: b6df52ab912e62f814770c339cce1de5444f41c249869a6edf3e069dd6be7132
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 908112734acf984c86746934cea2471a702e0eeb7b93a5bf39b4abbd640eae9cb962788da168396919994429fce7d6cbfe04c3b6834e8bb5bd5a845d2a248ace
|
7
|
+
data.tar.gz: c4ac1fe22fca378f9e321f6fbc33bbd3371d0e7e831321c9ad496ce673d7a7d120a8527c31f07696a66ffa0d7c35ec760540e6954ed8c013db233056d60d3197
|
data/LICENSE
CHANGED
@@ -1,12 +1,6 @@
|
|
1
|
-
|
2
|
-
_ __ __ _ ___ __ _| |
|
3
|
-
| '_ \ / _` / __|/ _` | |
|
4
|
-
| |_) | (_| \__ \ (_| | |
|
5
|
-
| .__/ \__, |___/\__, |_|
|
6
|
-
|_| |___/ |_|
|
1
|
+
= pgsql Ruby Gem
|
7
2
|
|
8
|
-
|
9
|
-
Copyright (C) 2011-2019, 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
@@ -26,12 +26,12 @@ extern VALUE pgconn_mkstring( struct pgconn_data *ptr, const char *str);
|
|
26
26
|
extern VALUE pgconn_mkstringn( struct pgconn_data *ptr, const char *str, int len);
|
27
27
|
static VALUE pgconn_alloc( VALUE cls);
|
28
28
|
static VALUE pgconn_s_connect( int argc, VALUE *argv, VALUE cls);
|
29
|
-
static VALUE pgconn_s_parse( VALUE cls, VALUE str);
|
30
29
|
static VALUE pgconn_init( int argc, VALUE *argv, VALUE self);
|
31
30
|
static int set_connect_params( st_data_t key, st_data_t val, st_data_t args);
|
32
|
-
static
|
33
|
-
static
|
34
|
-
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));
|
35
35
|
|
36
36
|
static VALUE pgconn_close( VALUE self);
|
37
37
|
static VALUE pgconn_reset( VALUE self);
|
@@ -71,6 +71,10 @@ VALUE rb_cPgConn;
|
|
71
71
|
static VALUE rb_ePgConnFailed;
|
72
72
|
static VALUE rb_ePgConnInvalid;
|
73
73
|
|
74
|
+
static VALUE sym_dbname = Qundef;
|
75
|
+
static VALUE sym_password = Qundef;
|
76
|
+
|
77
|
+
static ID id_to_s;
|
74
78
|
|
75
79
|
|
76
80
|
void
|
@@ -200,7 +204,7 @@ pgconn_alloc( VALUE cls)
|
|
200
204
|
}
|
201
205
|
|
202
206
|
/*
|
203
|
-
* Document-method: connect
|
207
|
+
* Document-method: Pg::Conn.connect
|
204
208
|
*
|
205
209
|
* call-seq:
|
206
210
|
* Pg::Conn.connect( hash) -> conn
|
@@ -221,27 +225,9 @@ pgconn_s_connect( int argc, VALUE *argv, VALUE cls)
|
|
221
225
|
rb_ensure( rb_yield, pgconn, pgconn_close, pgconn) : pgconn;
|
222
226
|
}
|
223
227
|
|
224
|
-
/*
|
225
|
-
* call-seq:
|
226
|
-
* Pg::Conn.parse( str) -> hash
|
227
|
-
*
|
228
|
-
* Parse a connection string and return a hash with keys <code>:dbname</code>,
|
229
|
-
* <code>:user</code>, <code>:host</code>, etc.
|
230
|
-
*
|
231
|
-
*/
|
232
|
-
VALUE
|
233
|
-
pgconn_s_parse( VALUE cls, VALUE str)
|
234
|
-
{
|
235
|
-
VALUE params;
|
236
|
-
|
237
|
-
params = rb_hash_new();
|
238
|
-
connstr_to_hash( params, str);
|
239
|
-
return params;
|
240
|
-
}
|
241
|
-
|
242
228
|
|
243
229
|
/*
|
244
|
-
* Document-method: new
|
230
|
+
* Document-method: Pg::Conn.new
|
245
231
|
*
|
246
232
|
* call-seq:
|
247
233
|
* Pg::Conn.new( hash) -> conn
|
@@ -252,23 +238,39 @@ pgconn_s_parse( VALUE cls, VALUE str)
|
|
252
238
|
*
|
253
239
|
* c = Pg::Conn.new :dbname => "movies", :host => "jupiter", ...
|
254
240
|
*
|
255
|
-
*
|
256
|
-
*
|
241
|
+
* If the +str+ argument is given but no further parameters,
|
242
|
+
* the PQconnectdb() (not PQconnectdbParams()) function will be called.
|
243
|
+
* If further arguments are present, the +str+ argument will be made into
|
244
|
+
* the "dbname" parameter, but without overwriting an existing one.
|
245
|
+
*
|
246
|
+
* The "dbname" parameter may be a +conninfo+ string as described in the
|
247
|
+
* PostgreSQL documentation:
|
248
|
+
*
|
249
|
+
* c = Pg::Conn.new "postgresql://user:password@host:port/dbname"
|
250
|
+
* c = Pg::Conn.new "postgres://user:password@host:port/dbname"
|
251
|
+
* c = Pg::Conn.new "dbname=... host=... user=..."
|
257
252
|
*
|
258
|
-
*
|
253
|
+
* The password may be specified as an extra parameter:
|
259
254
|
*
|
260
|
-
*
|
261
|
-
* @ sign will be read as database name.
|
255
|
+
* c = Pg::Conn.new "postgresql://user@host/dbname", password: "verysecret"
|
262
256
|
*
|
263
257
|
* If the password is the empty string, and there is either an instance method
|
264
258
|
* or a class method <code>password?</code>, that method will be asked. This
|
265
259
|
* method may ask <code>yield :user</code> or <code>yield :dbname</code> and so
|
266
260
|
* on to get the connection parameters.
|
267
261
|
*
|
262
|
+
* class Pg::Conn
|
263
|
+
* def password?
|
264
|
+
* "tercesyrev".reverse
|
265
|
+
* end
|
266
|
+
* end
|
267
|
+
* c = Pg::Conn.new "postgresql://user@host/dbname", password: ""
|
268
|
+
*
|
268
269
|
* See the PostgreSQL documentation for a full list:
|
269
270
|
* [http://www.postgresql.org/docs/current/interactive/libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS]
|
270
271
|
*
|
271
272
|
* On failure, a +Pg::Error+ exception will be raised.
|
273
|
+
*
|
272
274
|
*/
|
273
275
|
VALUE
|
274
276
|
pgconn_init( int argc, VALUE *argv, VALUE self)
|
@@ -280,32 +282,43 @@ pgconn_init( int argc, VALUE *argv, VALUE self)
|
|
280
282
|
struct pgconn_data *c;
|
281
283
|
|
282
284
|
if (rb_scan_args( argc, argv, "02", &str, ¶ms) < 2)
|
283
|
-
if (TYPE( str)
|
285
|
+
if (TYPE( str) == T_HASH) {
|
284
286
|
params = str;
|
285
287
|
str = Qnil;
|
286
288
|
}
|
287
|
-
if (NIL_P( params))
|
288
|
-
params = rb_hash_new();
|
289
|
-
else if (TYPE( params) != T_HASH)
|
290
|
-
params = rb_convert_type( params, T_HASH, "Hash", "to_hash");
|
291
|
-
else
|
292
|
-
params = rb_obj_dup( params);
|
293
|
-
if (!NIL_P( str))
|
294
|
-
connstr_to_hash( params, str);
|
295
|
-
connstr_passwd( self, params);
|
296
289
|
|
297
290
|
Data_Get_Struct( self, struct pgconn_data, c);
|
298
291
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
292
|
+
if (NIL_P( params)) {
|
293
|
+
c->conn = PQconnectdb( RSTRING_PTR( rb_funcall( str, id_to_s, 0)));
|
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
|
+
}
|
309
322
|
if (PQstatus( c->conn) == CONNECTION_BAD)
|
310
323
|
rb_exc_raise( pgconnfailederror_new( c, params));
|
311
324
|
|
@@ -331,50 +344,29 @@ set_connect_params( st_data_t key, st_data_t val, st_data_t args)
|
|
331
344
|
return ST_CONTINUE;
|
332
345
|
}
|
333
346
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
;
|
340
|
-
|
341
|
-
#define KEY_USER "user"
|
342
|
-
#define KEY_PASSWORD "password"
|
343
|
-
#define KEY_HOST "host"
|
344
|
-
#define KEY_PORT "port"
|
345
|
-
#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
|
+
}
|
346
354
|
|
347
|
-
|
348
|
-
|
349
|
-
{
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
if (RTEST( rb_reg_match( re, str))) {
|
354
|
-
match = rb_backref_get();
|
355
|
-
#define ADD_TO_RES( key, n) \
|
356
|
-
k = ID2SYM( rb_intern( key)); m = rb_reg_nth_match( n, match); \
|
357
|
-
if (NIL_P( rb_hash_aref( params, k)) && !NIL_P(m)) \
|
358
|
-
rb_hash_aset( params, k, m)
|
359
|
-
ADD_TO_RES( KEY_USER, 1);
|
360
|
-
ADD_TO_RES( KEY_PASSWORD, 2);
|
361
|
-
ADD_TO_RES( KEY_HOST, 3);
|
362
|
-
ADD_TO_RES( KEY_PORT, 4);
|
363
|
-
ADD_TO_RES( KEY_DBNAME, 5);
|
364
|
-
#undef ADD_TO_RES
|
365
|
-
} else
|
366
|
-
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;
|
367
361
|
}
|
368
362
|
|
363
|
+
|
369
364
|
void
|
370
|
-
connstr_passwd( VALUE self, VALUE params)
|
365
|
+
connstr_passwd( VALUE self, VALUE orig_params, VALUE *params)
|
371
366
|
{
|
372
|
-
static VALUE sym_password = Qundef;
|
373
367
|
VALUE pw;
|
374
368
|
|
375
|
-
|
376
|
-
sym_password = ID2SYM( rb_intern( KEY_PASSWORD));
|
377
|
-
pw = rb_hash_aref( params, sym_password);
|
369
|
+
pw = rb_hash_aref( *params, connstr_sym_password());
|
378
370
|
if (TYPE( pw) == T_STRING && RSTRING_LEN( pw) == 0) {
|
379
371
|
static ID id_password_q = 0;
|
380
372
|
VALUE pwobj;
|
@@ -386,14 +378,18 @@ connstr_passwd( VALUE self, VALUE params)
|
|
386
378
|
pwobj = self;
|
387
379
|
if (rb_respond_to( CLASS_OF( self), id_password_q))
|
388
380
|
pwobj = CLASS_OF( self);
|
389
|
-
if (pwobj != Qundef)
|
390
|
-
|
381
|
+
if (pwobj != Qundef) {
|
382
|
+
if (*params == orig_params)
|
383
|
+
*params = rb_obj_dup( *params);
|
384
|
+
rb_hash_aset( *params, sym_password,
|
391
385
|
rb_block_call( pwobj, id_password_q, 0, NULL,
|
392
|
-
&connstr_getparam, params));
|
386
|
+
&connstr_getparam, *params));
|
387
|
+
}
|
393
388
|
}
|
394
389
|
}
|
395
390
|
|
396
|
-
VALUE
|
391
|
+
VALUE
|
392
|
+
connstr_getparam( RB_BLOCK_CALL_FUNC_ARGLIST( yielded, params))
|
397
393
|
{
|
398
394
|
return rb_hash_aref( params, yielded);
|
399
395
|
}
|
@@ -775,14 +771,14 @@ pgconn_untrace( VALUE self)
|
|
775
771
|
* == Example
|
776
772
|
*
|
777
773
|
* conn.exec <<-EOT
|
778
|
-
*
|
779
|
-
*
|
780
|
-
*
|
781
|
-
*
|
782
|
-
* $$
|
774
|
+
* CREATE OR REPLACE FUNCTION noise() RETURNS VOID AS $$
|
775
|
+
* BEGIN
|
776
|
+
* RAISE NOTICE 'Hi!';
|
777
|
+
* END;
|
778
|
+
* $$ LANGUAGE plpgsql;
|
783
779
|
* EOT
|
784
780
|
* conn.on_notice { |e| puts e.inspect }
|
785
|
-
* conn.exec "
|
781
|
+
* conn.exec "SELECT noise();"
|
786
782
|
*/
|
787
783
|
VALUE
|
788
784
|
pgconn_on_notice( VALUE self)
|
@@ -814,23 +810,20 @@ notice_receiver( void *self, const PGresult *result)
|
|
814
810
|
|
815
811
|
|
816
812
|
|
817
|
-
|
818
|
-
*
|
813
|
+
/*
|
819
814
|
* Document-class: Pg::Conn::Failed
|
820
815
|
*
|
821
816
|
* Error while establishing a connection to the PostgreSQL server.
|
822
817
|
*/
|
823
818
|
|
824
|
-
|
825
|
-
*
|
819
|
+
/*
|
826
820
|
* Document-class: Pg::Conn::Invalid
|
827
821
|
*
|
828
822
|
* Invalid (closed) connection.
|
829
823
|
*/
|
830
824
|
|
831
825
|
|
832
|
-
|
833
|
-
*
|
826
|
+
/*
|
834
827
|
* Document-class: Pg::Conn
|
835
828
|
*
|
836
829
|
* The class to access a PostgreSQL database.
|
@@ -839,7 +832,7 @@ notice_receiver( void *self, const PGresult *result)
|
|
839
832
|
*
|
840
833
|
* require "pgsql"
|
841
834
|
* conn = Pg::Conn.open :dbname => "test1"
|
842
|
-
* res = conn.exec "
|
835
|
+
* res = conn.exec "SELECT * FROM mytable;"
|
843
836
|
*
|
844
837
|
* See the Pg::Result class for information on working with the results of a
|
845
838
|
* query.
|
@@ -848,9 +841,14 @@ notice_receiver( void *self, const PGresult *result)
|
|
848
841
|
void
|
849
842
|
Init_pgsql_conn( void)
|
850
843
|
{
|
851
|
-
|
852
|
-
|
853
|
-
|
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
|
+
}
|
854
852
|
|
855
853
|
rb_cPgConn = rb_define_class_under( rb_mPg, "Conn", rb_cObject);
|
856
854
|
|
@@ -863,7 +861,6 @@ Init_pgsql_conn( void)
|
|
863
861
|
rb_define_alloc_func( rb_cPgConn, pgconn_alloc);
|
864
862
|
rb_define_singleton_method( rb_cPgConn, "connect", pgconn_s_connect, -1);
|
865
863
|
rb_define_alias( rb_singleton_class( rb_cPgConn), "open", "connect");
|
866
|
-
rb_define_singleton_method( rb_cPgConn, "parse", pgconn_s_parse, 1);
|
867
864
|
rb_define_method( rb_cPgConn, "initialize", &pgconn_init, -1);
|
868
865
|
rb_define_method( rb_cPgConn, "close", &pgconn_close, 0);
|
869
866
|
rb_define_alias( rb_cPgConn, "finish", "close");
|
@@ -903,6 +900,8 @@ Init_pgsql_conn( void)
|
|
903
900
|
|
904
901
|
rb_define_method( rb_cPgConn, "on_notice", &pgconn_on_notice, 0);
|
905
902
|
|
903
|
+
id_to_s = rb_intern( "to_s");
|
904
|
+
|
906
905
|
Init_pgsql_conn_quote();
|
907
906
|
Init_pgsql_conn_exec();
|
908
907
|
}
|
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);
|
@@ -31,17 +24,17 @@ static VALUE yield_or_return_result( VALUE res);
|
|
31
24
|
static VALUE clear_resultqueue( VALUE self);
|
32
25
|
|
33
26
|
static VALUE pgconn_query( int argc, VALUE *argv, VALUE self);
|
34
|
-
static VALUE
|
27
|
+
static VALUE pgconn_select_row( int argc, VALUE *argv, VALUE self);
|
35
28
|
static VALUE pgconn_select_value( int argc, VALUE *argv, VALUE self);
|
36
29
|
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);
|
@@ -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
|
}
|
@@ -316,13 +303,13 @@ pgconn_query( int argc, VALUE *argv, VALUE self)
|
|
316
303
|
|
317
304
|
/*
|
318
305
|
* call-seq:
|
319
|
-
* conn.
|
306
|
+
* conn.select_row( query, *bind_values)
|
320
307
|
*
|
321
308
|
* Return the first row of the query results.
|
322
309
|
* Equivalent to <code>conn.query( query, *bind_values).first</code>.
|
323
310
|
*/
|
324
311
|
VALUE
|
325
|
-
|
312
|
+
pgconn_select_row( int argc, VALUE *argv, VALUE self)
|
326
313
|
{
|
327
314
|
VALUE cmd, par;
|
328
315
|
VALUE res;
|
@@ -340,7 +327,7 @@ pgconn_select_one( int argc, VALUE *argv, VALUE self)
|
|
340
327
|
* conn.select_value( query, *bind_values)
|
341
328
|
*
|
342
329
|
* Return the first value of the first row of the query results.
|
343
|
-
* Equivalent to conn.query( query, *bind_values).first
|
330
|
+
* Equivalent to conn.query( query, *bind_values).first&.first
|
344
331
|
*/
|
345
332
|
VALUE
|
346
333
|
pgconn_select_value( int argc, VALUE *argv, VALUE self)
|
@@ -361,6 +348,7 @@ pgconn_select_value( int argc, VALUE *argv, VALUE self)
|
|
361
348
|
* call-seq:
|
362
349
|
* conn.select_values( query, *bind_values)
|
363
350
|
*
|
351
|
+
* Return the all values over all rows as one array.
|
364
352
|
* Equivalent to conn.query( query, *bind_values).flatten
|
365
353
|
*/
|
366
354
|
VALUE
|
@@ -472,10 +460,10 @@ yield_transaction( VALUE self)
|
|
472
460
|
}
|
473
461
|
|
474
462
|
VALUE
|
475
|
-
rollback_transaction( VALUE self)
|
463
|
+
rollback_transaction( VALUE self, VALUE err)
|
476
464
|
{
|
477
|
-
pgresult_clear( pg_statement_exec( self, rb_str_new2( "
|
478
|
-
rb_exc_raise(
|
465
|
+
pgresult_clear( pg_statement_exec( self, rb_str_new2( "ROLLBACK;"), Qnil));
|
466
|
+
rb_exc_raise( err);
|
479
467
|
return Qnil;
|
480
468
|
}
|
481
469
|
|
@@ -486,7 +474,7 @@ commit_transaction( VALUE self)
|
|
486
474
|
|
487
475
|
Data_Get_Struct( self, struct pgconn_data, c);
|
488
476
|
if (PQtransactionStatus( c->conn) > PQTRANS_IDLE)
|
489
|
-
pgresult_clear( pg_statement_exec( self, rb_str_new2( "
|
477
|
+
pgresult_clear( pg_statement_exec( self, rb_str_new2( "COMMIT;"), Qnil));
|
490
478
|
return Qnil;
|
491
479
|
}
|
492
480
|
|
@@ -533,7 +521,7 @@ yield_subtransaction( VALUE ary)
|
|
533
521
|
}
|
534
522
|
|
535
523
|
VALUE
|
536
|
-
rollback_subtransaction( VALUE ary)
|
524
|
+
rollback_subtransaction( VALUE ary, VALUE err)
|
537
525
|
{
|
538
526
|
VALUE cmd;
|
539
527
|
|
@@ -542,7 +530,7 @@ rollback_subtransaction( VALUE ary)
|
|
542
530
|
rb_str_buf_cat2( cmd, ";");
|
543
531
|
pgresult_clear( pg_statement_exec( rb_ary_entry( ary, 0), cmd, Qnil));
|
544
532
|
rb_ary_store( ary, 1, Qnil);
|
545
|
-
rb_exc_raise(
|
533
|
+
rb_exc_raise( err);
|
546
534
|
return Qnil;
|
547
535
|
}
|
548
536
|
|
@@ -595,7 +583,7 @@ pgconn_transaction_status( VALUE self)
|
|
595
583
|
* Write lines into a +COPY+ command. See +stringize_line+ for how to build
|
596
584
|
* standard lines.
|
597
585
|
*
|
598
|
-
* conn.copy_stdin "
|
586
|
+
* conn.copy_stdin "COPY t FROM STDIN;" do
|
599
587
|
* ary = ...
|
600
588
|
* l = stringize_line ary
|
601
589
|
* conn.put l
|
@@ -625,7 +613,7 @@ put_end( VALUE self)
|
|
625
613
|
Data_Get_Struct( self, struct pgconn_data, c);
|
626
614
|
/*
|
627
615
|
* I would like to hand over something like
|
628
|
-
* RSTRING_PTR( rb_obj_as_string(
|
616
|
+
* RSTRING_PTR( rb_obj_as_string( rb_errinfo()))
|
629
617
|
* here but when execution is inside a rescue block
|
630
618
|
* the error info will be non-null even though the
|
631
619
|
* exception just has been caught.
|
@@ -700,7 +688,7 @@ pgconn_putline( VALUE self, VALUE arg)
|
|
700
688
|
* Read lines from a +COPY+ command. The form of the lines depends
|
701
689
|
* on the statement's parameters.
|
702
690
|
*
|
703
|
-
* conn.copy_stdout "
|
691
|
+
* conn.copy_stdout "COPY t TO STDOUT;" do
|
704
692
|
* l = conn.getline
|
705
693
|
* ary = l.split /\t/
|
706
694
|
* ary.map! { |x|
|
@@ -821,7 +809,7 @@ pgconn_backup( VALUE self, VALUE label)
|
|
821
809
|
{
|
822
810
|
VALUE cmd, arg;
|
823
811
|
|
824
|
-
cmd = rb_str_new2( "
|
812
|
+
cmd = rb_str_new2( "SELECT pg_start_backup($1);");
|
825
813
|
arg = rb_ary_new3( 1, label);
|
826
814
|
pgresult_clear( pg_statement_exec( self, cmd, arg));
|
827
815
|
return rb_ensure( rb_yield, Qnil, backup_end, self);
|
@@ -833,31 +821,28 @@ backup_end( VALUE self)
|
|
833
821
|
{
|
834
822
|
VALUE cmd;
|
835
823
|
|
836
|
-
cmd = rb_str_new2( "
|
824
|
+
cmd = rb_str_new2( "SELECT pg_stop_backup();");
|
837
825
|
pgresult_clear( pg_statement_exec( self, cmd, Qnil));
|
838
826
|
return Qnil;
|
839
827
|
}
|
840
828
|
|
841
829
|
|
842
830
|
|
843
|
-
|
844
|
-
*
|
831
|
+
/*
|
845
832
|
* Document-class: Pg::Conn::ExecError
|
846
833
|
*
|
847
834
|
* Error while querying from a PostgreSQL connection.
|
848
835
|
*/
|
849
836
|
|
850
837
|
|
851
|
-
|
852
|
-
*
|
838
|
+
/*
|
853
839
|
* Document-class: Pg::Conn::TransactionError
|
854
840
|
*
|
855
841
|
* Nested transaction blocks. Use savepoints.
|
856
842
|
*/
|
857
843
|
|
858
844
|
|
859
|
-
|
860
|
-
*
|
845
|
+
/*
|
861
846
|
* Document-class: Pg::Conn::CopyError
|
862
847
|
*
|
863
848
|
* Nested transaction blocks. Use savepoints.
|
@@ -881,7 +866,7 @@ Init_pgsql_conn_exec( void)
|
|
881
866
|
rb_define_method( rb_cPgConn, "fetch", &pgconn_fetch, 0);
|
882
867
|
|
883
868
|
rb_define_method( rb_cPgConn, "query", &pgconn_query, -1);
|
884
|
-
rb_define_method( rb_cPgConn, "
|
869
|
+
rb_define_method( rb_cPgConn, "select_row", &pgconn_select_row, -1);
|
885
870
|
rb_define_method( rb_cPgConn, "select_value", &pgconn_select_value, -1);
|
886
871
|
rb_define_method( rb_cPgConn, "select_values", &pgconn_select_values, -1);
|
887
872
|
rb_define_method( rb_cPgConn, "get_notify", &pgconn_get_notify, 0);
|
@@ -911,6 +896,6 @@ Init_pgsql_conn_exec( void)
|
|
911
896
|
|
912
897
|
rb_define_method( rb_cPgConn, "backup", &pgconn_backup, 1);
|
913
898
|
|
914
|
-
|
899
|
+
id_to_a = 0;
|
915
900
|
}
|
916
901
|
|
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
|
@@ -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
|
|
@@ -496,7 +524,7 @@ VALUE pgconn_quote( VALUE self, VALUE obj)
|
|
496
524
|
} else if (co == rb_cDateTime) {
|
497
525
|
res = rb_obj_as_string( obj);
|
498
526
|
type = "timestamptz";
|
499
|
-
} else if (co ==
|
527
|
+
} else if (co == pg_monetary_class() &&
|
500
528
|
rb_respond_to( obj, id_raw)) {
|
501
529
|
res = rb_funcall( obj, id_raw, 0);
|
502
530
|
StringValue( res);
|
@@ -557,12 +585,12 @@ quote_string( VALUE conn, VALUE str)
|
|
557
585
|
VALUE
|
558
586
|
quote_array( VALUE self, VALUE result, VALUE ary)
|
559
587
|
{
|
560
|
-
long i
|
588
|
+
long i;
|
561
589
|
VALUE *o;
|
562
590
|
VALUE cf, co;
|
563
591
|
|
564
592
|
cf = Qundef;
|
565
|
-
for (o = RARRAY_PTR( ary),
|
593
|
+
for (o = RARRAY_PTR( ary), i = RARRAY_LEN( ary); i; ++o, --i) {
|
566
594
|
co = CLASS_OF( *o);
|
567
595
|
if (cf == Qundef)
|
568
596
|
cf = co;
|
@@ -624,11 +652,9 @@ pgconn_quote_identifier( VALUE self, VALUE str)
|
|
624
652
|
void
|
625
653
|
Init_pgsql_conn_quote( void)
|
626
654
|
{
|
627
|
-
rb_require( "date");
|
628
|
-
rb_require( "time");
|
629
655
|
rb_cDate = rb_const_get( rb_cObject, rb_intern( "Date"));
|
630
656
|
rb_cDateTime = rb_const_get( rb_cObject, rb_intern( "DateTime"));
|
631
|
-
|
657
|
+
rb_cMoney = Qnil;
|
632
658
|
|
633
659
|
#ifdef RDOC_NEEDS_THIS
|
634
660
|
rb_cPgConn = rb_define_class_under( rb_mPg, "Conn", rb_cObject);
|
@@ -662,7 +688,7 @@ Init_pgsql_conn_quote( void)
|
|
662
688
|
id_to_postgres = rb_intern( "to_postgres");
|
663
689
|
id_gsub = rb_intern( "gsub");
|
664
690
|
|
665
|
-
|
691
|
+
lookup_monetary = 1;
|
666
692
|
|
667
693
|
pg_string_null = rb_str_new2( "NULL"); rb_global_variable( &pg_string_null); rb_str_freeze( pg_string_null);
|
668
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
@@ -8,15 +8,14 @@
|
|
8
8
|
#include "result.h"
|
9
9
|
|
10
10
|
|
11
|
-
#define PGSQL_VERSION "1.
|
11
|
+
#define PGSQL_VERSION "1.8"
|
12
12
|
|
13
13
|
|
14
14
|
VALUE rb_mPg;
|
15
15
|
VALUE rb_ePgError;
|
16
16
|
|
17
17
|
|
18
|
-
|
19
|
-
*
|
18
|
+
/*
|
20
19
|
* Document-module: Pg
|
21
20
|
*
|
22
21
|
* The module to enclose everything.
|
@@ -25,8 +24,7 @@ VALUE rb_ePgError;
|
|
25
24
|
* connection.
|
26
25
|
*/
|
27
26
|
|
28
|
-
|
29
|
-
*
|
27
|
+
/*
|
30
28
|
* Document-class: Pg::Error
|
31
29
|
*
|
32
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
|
{
|
@@ -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,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgsql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.8'
|
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-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: autorake
|
@@ -55,10 +55,8 @@ homepage: http://www.bertram-scharpf.de/software/pgsql
|
|
55
55
|
licenses:
|
56
56
|
- BSD-2-Clause
|
57
57
|
metadata: {}
|
58
|
-
post_install_message:
|
58
|
+
post_install_message:
|
59
59
|
rdoc_options:
|
60
|
-
- "--charset"
|
61
|
-
- utf-8
|
62
60
|
- "--main"
|
63
61
|
- README
|
64
62
|
require_paths:
|
@@ -75,8 +73,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
73
|
version: '0'
|
76
74
|
requirements:
|
77
75
|
- PostgreSQL
|
78
|
-
rubygems_version: 3.0.
|
79
|
-
signing_key:
|
76
|
+
rubygems_version: 3.0.8
|
77
|
+
signing_key:
|
80
78
|
specification_version: 4
|
81
79
|
summary: PostgreSQL-API for Ruby
|
82
80
|
test_files: []
|