postgres 0.7.9.2007.12.22 → 0.7.9.2008.01.03
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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)
|