postgres 0.7.9.2007.12.22 → 0.7.9.2008.01.03
Sign up to get free protection for your applications and to get access to all the features.
- data/README +31 -105
- data/compat-ruby-postgres/postgres.c +55 -111
- data/ext/compat.c +9 -0
- data/ext/compat.h +9 -0
- data/ext/extconf.rb +1 -0
- data/ext/pg.c +564 -346
- metadata +4 -4
data/README
CHANGED
@@ -21,8 +21,6 @@ Thanks to:
|
|
21
21
|
Maintainer:
|
22
22
|
Jeff Davis <ruby-pg@j-davis.com>
|
23
23
|
|
24
|
-
Portions copyright Laika, Inc.
|
25
|
-
|
26
24
|
Copying:
|
27
25
|
You may redistribute this software under the terms of the GPL,
|
28
26
|
included in the file named GPL; or under the same terms as Ruby,
|
@@ -31,13 +29,15 @@ Copying:
|
|
31
29
|
- Summary
|
32
30
|
|
33
31
|
This is the extension library to access a PostgreSQL database from Ruby.
|
34
|
-
This library works with PostgreSQL
|
35
|
-
with 6.3 or earlier with slight modification, but not tested at all.
|
32
|
+
This library works with PostgreSQL 7.4 and later.
|
36
33
|
|
37
34
|
- Requirements
|
38
35
|
|
39
|
-
Ruby 1.
|
40
|
-
PostgreSQL
|
36
|
+
Ruby 1.8 or later.
|
37
|
+
PostgreSQL 7.4 or later installed.
|
38
|
+
|
39
|
+
It may work with earlier versions as well, but those are
|
40
|
+
not regularly tested.
|
41
41
|
|
42
42
|
- How to install ?
|
43
43
|
|
@@ -51,113 +51,35 @@ Follow the instructions below to compile and install:
|
|
51
51
|
You may need to specify the directory name for the include files and the
|
52
52
|
-lpq library by using
|
53
53
|
|
54
|
-
--with-pgsql-include
|
55
|
-
--with-pgsql-lib
|
56
|
-
or
|
57
|
-
--with-pgsql-dir=<dir>
|
58
|
-
Same as --with-pgsql-include-dir=<dir>/include,
|
59
|
-
--with-pgsql-lib-dir=<dir>/lib
|
60
|
-
|
54
|
+
--with-pgsql-include=<include file directory>
|
55
|
+
--with-pgsql-lib=<library directory>
|
61
56
|
|
62
57
|
For example:
|
63
58
|
|
64
|
-
ruby extconf.rb --with-pgsql-include
|
65
|
-
--with-pgsql-lib
|
66
|
-
or
|
67
|
-
ruby extconf.rb --with-pgsql-dir=/usr/local/pgsql/
|
59
|
+
ruby extconf.rb --with-pgsql-include=/usr/local/pgsql/include \
|
60
|
+
--with-pgsql-lib=/usr/local/pgsql/lib
|
68
61
|
|
69
62
|
- How to use ?
|
70
63
|
|
71
64
|
You need to specify:
|
72
65
|
|
73
|
-
require
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
quote
|
91
|
-
escape_bytea
|
92
|
-
|
93
|
-
methods:
|
94
|
-
db
|
95
|
-
host
|
96
|
-
options
|
97
|
-
port
|
98
|
-
tty
|
99
|
-
status
|
100
|
-
error
|
101
|
-
finish
|
102
|
-
close
|
103
|
-
reset
|
104
|
-
user
|
105
|
-
trace
|
106
|
-
untrace
|
107
|
-
|
108
|
-
exec
|
109
|
-
query
|
110
|
-
async_exec
|
111
|
-
async_query
|
112
|
-
get_notify
|
113
|
-
insert_table
|
114
|
-
putline
|
115
|
-
getline
|
116
|
-
endcopy
|
117
|
-
notifies
|
118
|
-
|
119
|
-
lo_import
|
120
|
-
lo_export
|
121
|
-
lo_create
|
122
|
-
lo_open
|
123
|
-
lo_unlink
|
124
|
-
|
125
|
-
client_encoding
|
126
|
-
set_client_encoding
|
127
|
-
|
128
|
-
class PGresult:
|
129
|
-
|
130
|
-
methods:
|
131
|
-
each
|
132
|
-
[]
|
133
|
-
status
|
134
|
-
result
|
135
|
-
fields
|
136
|
-
num_tuples
|
137
|
-
num_fields
|
138
|
-
fieldname
|
139
|
-
fieldnum
|
140
|
-
type
|
141
|
-
size
|
142
|
-
getvalue
|
143
|
-
getlength
|
144
|
-
cmdstatus
|
145
|
-
print
|
146
|
-
clear
|
147
|
-
|
148
|
-
class PGlarge:
|
149
|
-
|
150
|
-
methods:
|
151
|
-
open
|
152
|
-
close
|
153
|
-
read
|
154
|
-
write
|
155
|
-
lseek
|
156
|
-
tell
|
157
|
-
unlink
|
158
|
-
oid
|
159
|
-
size
|
160
|
-
export
|
66
|
+
require 'pg' or
|
67
|
+
require 'postgres'
|
68
|
+
|
69
|
+
These are two different modules, with important differences.
|
70
|
+
|
71
|
+
The 'postgres' module is the older module, maintained for backwards
|
72
|
+
compatibility. It has known flaws that aren't reasonably fixable without
|
73
|
+
breaking backwards compatibility. Use this module if you have code that
|
74
|
+
already works, and you just want the fixes that I've committed to this
|
75
|
+
module (for instance, this module is compatible with PostgreSQL 8.3).
|
76
|
+
|
77
|
+
The 'pg' module is the newer module, that has been greatly improved, and
|
78
|
+
is almost a complete rewrite. It is not backwards compatible. Use this module
|
79
|
+
for newly written code. It should be more stable, less buggy, and has more
|
80
|
+
features.
|
81
|
+
|
82
|
+
See the RDoc documentation for detailed usage instructions.
|
161
83
|
|
162
84
|
- Acknowledgments
|
163
85
|
|
@@ -169,3 +91,7 @@ And to the people who developed PostgreSQL.
|
|
169
91
|
This library is copyrighted by its authors; Yukihiro Matsumoto, and Eiji
|
170
92
|
Matsumoto.
|
171
93
|
|
94
|
+
Portions copyright Laika, Inc.
|
95
|
+
|
96
|
+
|
97
|
+
|
@@ -14,8 +14,16 @@
|
|
14
14
|
|
15
15
|
#include "ruby.h"
|
16
16
|
#include "rubyio.h"
|
17
|
+
|
18
|
+
#if RUBY_VM == 1
|
19
|
+
/* ruby 1.9 */
|
20
|
+
#include "ruby/st.h"
|
21
|
+
#include "ruby/intern.h"
|
22
|
+
#else
|
23
|
+
/* ruby 1.8 */
|
17
24
|
#include "st.h"
|
18
25
|
#include "intern.h"
|
26
|
+
#endif
|
19
27
|
|
20
28
|
/* grep '^#define' $(pg_config --includedir)/server/catalog/pg_type.h | grep OID */
|
21
29
|
#include "type-oids.h"
|
@@ -33,6 +41,10 @@ PQserverVersion(const PGconn *conn)
|
|
33
41
|
}
|
34
42
|
#endif /* HAVE_PQSERVERVERSION */
|
35
43
|
|
44
|
+
#ifndef RHASH_SIZE
|
45
|
+
#define RHASH_SIZE(x) RHASH((x))->tbl->num_entries
|
46
|
+
#endif /* RHASH_SIZE */
|
47
|
+
|
36
48
|
#ifndef RSTRING_LEN
|
37
49
|
#define RSTRING_LEN(x) RSTRING((x))->len
|
38
50
|
#endif /* RSTRING_LEN */
|
@@ -41,6 +53,14 @@ PQserverVersion(const PGconn *conn)
|
|
41
53
|
#define RSTRING_PTR(x) RSTRING((x))->ptr
|
42
54
|
#endif /* RSTRING_PTR */
|
43
55
|
|
56
|
+
#if RUBY_VM == 1
|
57
|
+
/* ruby 1.9 */
|
58
|
+
#define RB_REG_NEW(s, len, opt) rb_reg_new(rb_str_new((s),(len)), opt)
|
59
|
+
#else
|
60
|
+
/* ruby 1.8 */
|
61
|
+
#define RB_REG_NEW(s, len, opt) rb_reg_new((s), (len), (opt))
|
62
|
+
#endif
|
63
|
+
|
44
64
|
#ifndef HAVE_PG_ENCODING_TO_CHAR
|
45
65
|
#define pg_encoding_to_char(x) "SQL_ASCII"
|
46
66
|
#endif
|
@@ -133,7 +153,7 @@ try_connectdb(arg)
|
|
133
153
|
/* do nothing */
|
134
154
|
}
|
135
155
|
else if (!NIL_P(conninfo = rb_check_hash_type(arg))) {
|
136
|
-
VALUE key_values = rb_ary_new2(
|
156
|
+
VALUE key_values = rb_ary_new2(RHASH_SIZE(conninfo));
|
137
157
|
rb_hash_foreach(conninfo, build_key_value_string_i, key_values);
|
138
158
|
conninfo = rb_ary_join(key_values, rb_str_new2(" "));
|
139
159
|
}
|
@@ -465,21 +485,19 @@ pgconn_s_escape_bytea(self, obj)
|
|
465
485
|
VALUE self;
|
466
486
|
VALUE obj;
|
467
487
|
{
|
468
|
-
char *from, *to;
|
488
|
+
unsigned char *from, *to;
|
469
489
|
size_t from_len, to_len;
|
470
490
|
VALUE ret;
|
471
491
|
|
472
492
|
Check_Type(obj, T_STRING);
|
473
|
-
from = RSTRING_PTR(obj);
|
493
|
+
from = (unsigned char*)RSTRING_PTR(obj);
|
474
494
|
from_len = RSTRING_LEN(obj);
|
475
495
|
|
476
|
-
to =
|
496
|
+
to = PQescapeBytea(from, from_len, &to_len);
|
477
497
|
|
478
|
-
ret = rb_str_new(to, to_len - 1);
|
498
|
+
ret = rb_str_new((char*)to, to_len - 1);
|
479
499
|
OBJ_INFECT(ret, obj);
|
480
|
-
|
481
500
|
PQfreemem(to);
|
482
|
-
|
483
501
|
return ret;
|
484
502
|
}
|
485
503
|
|
@@ -503,21 +521,19 @@ pgconn_escape_bytea(self, obj)
|
|
503
521
|
VALUE self;
|
504
522
|
VALUE obj;
|
505
523
|
{
|
506
|
-
char *from, *to;
|
524
|
+
unsigned char *from, *to;
|
507
525
|
size_t from_len, to_len;
|
508
526
|
VALUE ret;
|
509
527
|
|
510
528
|
Check_Type(obj, T_STRING);
|
511
|
-
from = RSTRING_PTR(obj);
|
529
|
+
from = (unsigned char*)RSTRING_PTR(obj);
|
512
530
|
from_len = RSTRING_LEN(obj);
|
513
531
|
|
514
|
-
to =
|
532
|
+
to = PQescapeByteaConn(get_pgconn(self),from, from_len, &to_len);
|
515
533
|
|
516
|
-
ret = rb_str_new(to, to_len - 1);
|
534
|
+
ret = rb_str_new((char*)to, to_len - 1);
|
517
535
|
OBJ_INFECT(ret, obj);
|
518
|
-
|
519
536
|
PQfreemem(to);
|
520
|
-
|
521
537
|
return ret;
|
522
538
|
}
|
523
539
|
|
@@ -535,16 +551,16 @@ static VALUE
|
|
535
551
|
pgconn_s_unescape_bytea(self, obj)
|
536
552
|
VALUE self, obj;
|
537
553
|
{
|
538
|
-
char *from, *to;
|
554
|
+
unsigned char *from, *to;
|
539
555
|
size_t to_len;
|
540
556
|
VALUE ret;
|
541
557
|
|
542
558
|
Check_Type(obj, T_STRING);
|
543
|
-
from = StringValuePtr(obj);
|
559
|
+
from = (unsigned char*)StringValuePtr(obj);
|
544
560
|
|
545
|
-
to =
|
561
|
+
to = PQunescapeBytea(from, &to_len);
|
546
562
|
|
547
|
-
ret = rb_str_new(to, to_len);
|
563
|
+
ret = rb_str_new((char*)to, to_len);
|
548
564
|
OBJ_INFECT(ret, obj);
|
549
565
|
PQfreemem(to);
|
550
566
|
|
@@ -1351,7 +1367,7 @@ pgconn_set_client_encoding(obj, str)
|
|
1351
1367
|
{
|
1352
1368
|
Check_Type(str, T_STRING);
|
1353
1369
|
if ((PQsetClientEncoding(get_pgconn(obj), StringValuePtr(str))) == -1){
|
1354
|
-
rb_raise(rb_ePGError, "invalid encoding name %s",str);
|
1370
|
+
rb_raise(rb_ePGError, "invalid encoding name: %s",StringValuePtr(str));
|
1355
1371
|
}
|
1356
1372
|
return Qnil;
|
1357
1373
|
}
|
@@ -1880,76 +1896,6 @@ pgresult_getisnull(obj, tup_num, field_num)
|
|
1880
1896
|
return PQgetisnull(result, i, j) ? Qtrue : Qfalse;
|
1881
1897
|
}
|
1882
1898
|
|
1883
|
-
/*
|
1884
|
-
* call-seq:
|
1885
|
-
* res.print( file, opt )
|
1886
|
-
*
|
1887
|
-
* MISSING: Documentation
|
1888
|
-
*/
|
1889
|
-
static VALUE
|
1890
|
-
pgresult_print(obj, file, opt)
|
1891
|
-
VALUE obj, file, opt;
|
1892
|
-
{
|
1893
|
-
VALUE value;
|
1894
|
-
ID mem;
|
1895
|
-
OpenFile* fp;
|
1896
|
-
PQprintOpt po;
|
1897
|
-
|
1898
|
-
Check_Type(file, T_FILE);
|
1899
|
-
Check_Type(opt, T_STRUCT);
|
1900
|
-
GetOpenFile(file, fp);
|
1901
|
-
|
1902
|
-
memset(&po, 0, sizeof(po));
|
1903
|
-
|
1904
|
-
mem = rb_intern("header");
|
1905
|
-
value = rb_struct_getmember(opt, mem);
|
1906
|
-
po.header = value == Qtrue ? 1 : 0;
|
1907
|
-
|
1908
|
-
mem = rb_intern("align");
|
1909
|
-
value = rb_struct_getmember(opt, mem);
|
1910
|
-
po.align = value == Qtrue ? 1 : 0;
|
1911
|
-
|
1912
|
-
mem = rb_intern("standard");
|
1913
|
-
value = rb_struct_getmember(opt, mem);
|
1914
|
-
po.standard = value == Qtrue ? 1 : 0;
|
1915
|
-
|
1916
|
-
mem = rb_intern("html3");
|
1917
|
-
value = rb_struct_getmember(opt, mem);
|
1918
|
-
po.html3 = value == Qtrue ? 1 : 0;
|
1919
|
-
|
1920
|
-
mem = rb_intern("expanded");
|
1921
|
-
value = rb_struct_getmember(opt, mem);
|
1922
|
-
po.expanded = value == Qtrue ? 1 : 0;
|
1923
|
-
|
1924
|
-
mem = rb_intern("pager");
|
1925
|
-
value = rb_struct_getmember(opt, mem);
|
1926
|
-
po.pager = value == Qtrue ? 1 : 0;
|
1927
|
-
|
1928
|
-
mem = rb_intern("fieldSep");
|
1929
|
-
value = rb_struct_getmember(opt, mem);
|
1930
|
-
if (!NIL_P(value)) {
|
1931
|
-
Check_Type(value, T_STRING);
|
1932
|
-
po.fieldSep = StringValuePtr(value);
|
1933
|
-
}
|
1934
|
-
|
1935
|
-
mem = rb_intern("tableOpt");
|
1936
|
-
value = rb_struct_getmember(opt, mem);
|
1937
|
-
if (!NIL_P(value)) {
|
1938
|
-
Check_Type(value, T_STRING);
|
1939
|
-
po.tableOpt = StringValuePtr(value);
|
1940
|
-
}
|
1941
|
-
|
1942
|
-
mem = rb_intern("caption");
|
1943
|
-
value = rb_struct_getmember(opt, mem);
|
1944
|
-
if (!NIL_P(value)) {
|
1945
|
-
Check_Type(value, T_STRING);
|
1946
|
-
po.caption = StringValuePtr(value);
|
1947
|
-
}
|
1948
|
-
|
1949
|
-
PQprint(fp->f2?fp->f2:fp->f, get_pgresult(obj), &po);
|
1950
|
-
return obj;
|
1951
|
-
}
|
1952
|
-
|
1953
1899
|
/*
|
1954
1900
|
* call-seq:
|
1955
1901
|
* res.cmdtuples()
|
@@ -2332,28 +2278,27 @@ pglarge_read(argc, argv, obj)
|
|
2332
2278
|
VALUE *argv;
|
2333
2279
|
VALUE obj;
|
2334
2280
|
{
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
rb_scan_args(argc, argv, "01", &length);
|
2341
|
-
if (NIL_P(length)) {
|
2342
|
-
return loread_all(obj);
|
2343
|
-
}
|
2344
|
-
|
2345
|
-
len = NUM2INT(length);
|
2346
|
-
if (len < 0){
|
2347
|
-
rb_raise(rb_ePGError,"nagative length %d given", len);
|
2348
|
-
}
|
2349
|
-
str = rb_tainted_str_new(0,len);
|
2281
|
+
int len;
|
2282
|
+
PGlarge *pglarge = get_pglarge(obj);
|
2283
|
+
VALUE length;
|
2284
|
+
char *buffer;
|
2350
2285
|
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2286
|
+
rb_scan_args(argc, argv, "01", &length);
|
2287
|
+
if (NIL_P(length)) {
|
2288
|
+
return loread_all(obj);
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
len = NUM2INT(length);
|
2292
|
+
if (len < 0){
|
2293
|
+
rb_raise(rb_ePGError,"nagative length %d given", len);
|
2294
|
+
}
|
2295
|
+
buffer = ALLOCA_N(char, len);
|
2296
|
+
|
2297
|
+
if((len = lo_read(pglarge->pgconn, pglarge->lo_fd, buffer, len)) < 0) {
|
2298
|
+
rb_raise(rb_ePGError, "error while reading");
|
2299
|
+
}
|
2300
|
+
if (len == 0) return Qnil;
|
2301
|
+
return rb_str_new(buffer,len);
|
2357
2302
|
}
|
2358
2303
|
|
2359
2304
|
/*
|
@@ -2672,7 +2617,7 @@ void
|
|
2672
2617
|
Init_postgres()
|
2673
2618
|
{
|
2674
2619
|
pg_gsub_bang_id = rb_intern("gsub!");
|
2675
|
-
pg_escape_regex =
|
2620
|
+
pg_escape_regex = RB_REG_NEW("([\\t\\n\\\\])", 10, 0);
|
2676
2621
|
rb_global_variable(&pg_escape_regex);
|
2677
2622
|
pg_escape_str = rb_str_new("\\\\\\1", 4);
|
2678
2623
|
rb_global_variable(&pg_escape_str);
|
@@ -2815,7 +2760,6 @@ Init_postgres()
|
|
2815
2760
|
rb_define_method(rb_cPGresult, "cmdtuples", pgresult_cmdtuples, 0);
|
2816
2761
|
rb_define_method(rb_cPGresult, "cmdstatus", pgresult_cmdstatus, 0);
|
2817
2762
|
rb_define_method(rb_cPGresult, "oid", pgresult_oid, 0);
|
2818
|
-
rb_define_method(rb_cPGresult, "print", pgresult_print, 2);
|
2819
2763
|
rb_define_method(rb_cPGresult, "clear", pgresult_clear, 0);
|
2820
2764
|
rb_define_alias(rb_cPGresult, "close", "clear");
|
2821
2765
|
|
data/ext/compat.c
CHANGED
@@ -128,6 +128,15 @@ PQsendDescribePortal(PGconn *conn, const char *portalName)
|
|
128
128
|
}
|
129
129
|
#endif /* HAVE_PQSENDDESCRIBEPORTAL */
|
130
130
|
|
131
|
+
#ifndef HAVE_PQSENDPREPARE
|
132
|
+
int
|
133
|
+
PQsendPrepare(PGconn *conn, const char *stmtName, const char *query,
|
134
|
+
int nParams, const Oid *paramTypes)
|
135
|
+
{
|
136
|
+
rb_raise(rb_eStandardError, "PQsendPrepare not supported by this client version.");
|
137
|
+
}
|
138
|
+
#endif /* HAVE_PQSENDPREPARE */
|
139
|
+
|
131
140
|
#ifndef HAVE_PQENCRYPTPASSWORD
|
132
141
|
char *
|
133
142
|
PQencryptPassword(const char *passwd, const char *user)
|