postgres 0.7.9.2007.12.12 → 0.7.9.2007.12.22
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/compat-ruby-postgres/extconf.rb +2 -2
- data/compat-ruby-postgres/libpq-compat.c +253 -0
- data/compat-ruby-postgres/postgres.c +54 -33
- data/ext/compat.c +15 -0
- data/ext/compat.h +16 -1
- data/ext/extconf.rb +2 -0
- data/ext/pg.c +515 -447
- data/ext/pg.h +0 -1
- metadata +6 -5
@@ -20,13 +20,13 @@ end
|
|
20
20
|
dir_config('pgsql', config_value('include'), config_value('lib'))
|
21
21
|
|
22
22
|
required_libraries = []
|
23
|
-
desired_functions = %w(PQsetClientEncoding pg_encoding_to_char PQfreemem)
|
23
|
+
desired_functions = %w(PQsetClientEncoding pg_encoding_to_char PQfreemem PQserverVersion)
|
24
24
|
compat_functions = %w(PQescapeString PQexecParams)
|
25
25
|
|
26
26
|
if have_build_env
|
27
27
|
required_libraries.each(&method(:have_library))
|
28
28
|
desired_functions.each(&method(:have_func))
|
29
|
-
$objs = ['postgres.o'] if compat_functions.all?(&method(:have_func))
|
29
|
+
$objs = ['postgres.o','libpq-compat.o'] if compat_functions.all?(&method(:have_func))
|
30
30
|
$CFLAGS << ' -Wall '
|
31
31
|
create_makefile("postgres")
|
32
32
|
else
|
@@ -0,0 +1,253 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
|
3
|
+
#ifndef HAVE_PQESCAPESTRING
|
4
|
+
/*
|
5
|
+
* Escaping arbitrary strings to get valid SQL literal strings.
|
6
|
+
*
|
7
|
+
* Replaces "\\" with "\\\\" and "'" with "''".
|
8
|
+
*
|
9
|
+
* length is the length of the source string. (Note: if a terminating NUL
|
10
|
+
* is encountered sooner, PQescapeString stops short of "length"; the behavior
|
11
|
+
* is thus rather like strncpy.)
|
12
|
+
*
|
13
|
+
* For safety the buffer at "to" must be at least 2*length + 1 bytes long.
|
14
|
+
* A terminating NUL character is added to the output string, whether the
|
15
|
+
* input is NUL-terminated or not.
|
16
|
+
*
|
17
|
+
* Returns the actual length of the output (not counting the terminating NUL).
|
18
|
+
*/
|
19
|
+
size_t
|
20
|
+
PQescapeString(char *to, const char *from, size_t length)
|
21
|
+
{
|
22
|
+
const char *source = from;
|
23
|
+
char *target = to;
|
24
|
+
size_t remaining = length;
|
25
|
+
|
26
|
+
while (remaining > 0 && *source != '\0')
|
27
|
+
{
|
28
|
+
switch (*source)
|
29
|
+
{
|
30
|
+
case '\\':
|
31
|
+
*target++ = '\\';
|
32
|
+
*target++ = '\\';
|
33
|
+
break;
|
34
|
+
|
35
|
+
case '\'':
|
36
|
+
*target++ = '\'';
|
37
|
+
*target++ = '\'';
|
38
|
+
break;
|
39
|
+
|
40
|
+
default:
|
41
|
+
*target++ = *source;
|
42
|
+
break;
|
43
|
+
}
|
44
|
+
source++;
|
45
|
+
remaining--;
|
46
|
+
}
|
47
|
+
|
48
|
+
/* Write the terminating NUL character. */
|
49
|
+
*target = '\0';
|
50
|
+
|
51
|
+
return target - to;
|
52
|
+
}
|
53
|
+
|
54
|
+
/*
|
55
|
+
* PQescapeBytea - converts from binary string to the
|
56
|
+
* minimal encoding necessary to include the string in an SQL
|
57
|
+
* INSERT statement with a bytea type column as the target.
|
58
|
+
*
|
59
|
+
* The following transformations are applied
|
60
|
+
* '\0' == ASCII 0 == \\000
|
61
|
+
* '\'' == ASCII 39 == \'
|
62
|
+
* '\\' == ASCII 92 == \\\\
|
63
|
+
* anything < 0x20, or > 0x7e ---> \\ooo
|
64
|
+
* (where ooo is an octal expression)
|
65
|
+
*/
|
66
|
+
unsigned char *
|
67
|
+
PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
|
68
|
+
{
|
69
|
+
const unsigned char *vp;
|
70
|
+
unsigned char *rp;
|
71
|
+
unsigned char *result;
|
72
|
+
size_t i;
|
73
|
+
size_t len;
|
74
|
+
|
75
|
+
/*
|
76
|
+
* empty string has 1 char ('\0')
|
77
|
+
*/
|
78
|
+
len = 1;
|
79
|
+
|
80
|
+
vp = bintext;
|
81
|
+
for (i = binlen; i > 0; i--, vp++)
|
82
|
+
{
|
83
|
+
if (*vp < 0x20 || *vp > 0x7e)
|
84
|
+
len += 5; /* '5' is for '\\ooo' */
|
85
|
+
else if (*vp == '\'')
|
86
|
+
len += 2;
|
87
|
+
else if (*vp == '\\')
|
88
|
+
len += 4;
|
89
|
+
else
|
90
|
+
len++;
|
91
|
+
}
|
92
|
+
|
93
|
+
rp = result = (unsigned char *) malloc(len);
|
94
|
+
if (rp == NULL)
|
95
|
+
return NULL;
|
96
|
+
|
97
|
+
vp = bintext;
|
98
|
+
*bytealen = len;
|
99
|
+
|
100
|
+
for (i = binlen; i > 0; i--, vp++)
|
101
|
+
{
|
102
|
+
if (*vp < 0x20 || *vp > 0x7e)
|
103
|
+
{
|
104
|
+
(void) sprintf(rp, "\\\\%03o", *vp);
|
105
|
+
rp += 5;
|
106
|
+
}
|
107
|
+
else if (*vp == '\'')
|
108
|
+
{
|
109
|
+
rp[0] = '\\';
|
110
|
+
rp[1] = '\'';
|
111
|
+
rp += 2;
|
112
|
+
}
|
113
|
+
else if (*vp == '\\')
|
114
|
+
{
|
115
|
+
rp[0] = '\\';
|
116
|
+
rp[1] = '\\';
|
117
|
+
rp[2] = '\\';
|
118
|
+
rp[3] = '\\';
|
119
|
+
rp += 4;
|
120
|
+
}
|
121
|
+
else
|
122
|
+
*rp++ = *vp;
|
123
|
+
}
|
124
|
+
*rp = '\0';
|
125
|
+
|
126
|
+
return result;
|
127
|
+
}
|
128
|
+
|
129
|
+
#define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')
|
130
|
+
#define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')
|
131
|
+
#define OCTVAL(CH) ((CH) - '0')
|
132
|
+
|
133
|
+
/*
|
134
|
+
* PQunescapeBytea - converts the null terminated string representation
|
135
|
+
* of a bytea, strtext, into binary, filling a buffer. It returns a
|
136
|
+
* pointer to the buffer (or NULL on error), and the size of the
|
137
|
+
* buffer in retbuflen. The pointer may subsequently be used as an
|
138
|
+
* argument to the function free(3). It is the reverse of PQescapeBytea.
|
139
|
+
*
|
140
|
+
* The following transformations are made:
|
141
|
+
* \\ == ASCII 92 == \
|
142
|
+
* \ooo == a byte whose value = ooo (ooo is an octal number)
|
143
|
+
* \x == x (x is any character not matched by the above transformations)
|
144
|
+
*/
|
145
|
+
unsigned char *
|
146
|
+
PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
|
147
|
+
{
|
148
|
+
size_t strtextlen,
|
149
|
+
buflen;
|
150
|
+
unsigned char *buffer,
|
151
|
+
*tmpbuf;
|
152
|
+
size_t i,
|
153
|
+
j;
|
154
|
+
|
155
|
+
if (strtext == NULL)
|
156
|
+
return NULL;
|
157
|
+
|
158
|
+
strtextlen = strlen(strtext);
|
159
|
+
|
160
|
+
/*
|
161
|
+
* Length of input is max length of output, but add one to avoid
|
162
|
+
* unportable malloc(0) if input is zero-length.
|
163
|
+
*/
|
164
|
+
buffer = (unsigned char *) malloc(strtextlen + 1);
|
165
|
+
if (buffer == NULL)
|
166
|
+
return NULL;
|
167
|
+
|
168
|
+
for (i = j = 0; i < strtextlen;)
|
169
|
+
{
|
170
|
+
switch (strtext[i])
|
171
|
+
{
|
172
|
+
case '\\':
|
173
|
+
i++;
|
174
|
+
if (strtext[i] == '\\')
|
175
|
+
buffer[j++] = strtext[i++];
|
176
|
+
else
|
177
|
+
{
|
178
|
+
if ((ISFIRSTOCTDIGIT(strtext[i])) &&
|
179
|
+
(ISOCTDIGIT(strtext[i + 1])) &&
|
180
|
+
(ISOCTDIGIT(strtext[i + 2])))
|
181
|
+
{
|
182
|
+
int byte;
|
183
|
+
|
184
|
+
byte = OCTVAL(strtext[i++]);
|
185
|
+
byte = (byte << 3) + OCTVAL(strtext[i++]);
|
186
|
+
byte = (byte << 3) + OCTVAL(strtext[i++]);
|
187
|
+
buffer[j++] = byte;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
/*
|
192
|
+
* Note: if we see '\' followed by something that isn't a
|
193
|
+
* recognized escape sequence, we loop around having done
|
194
|
+
* nothing except advance i. Therefore the something will
|
195
|
+
* be emitted as ordinary data on the next cycle. Corner
|
196
|
+
* case: '\' at end of string will just be discarded.
|
197
|
+
*/
|
198
|
+
break;
|
199
|
+
|
200
|
+
default:
|
201
|
+
buffer[j++] = strtext[i++];
|
202
|
+
break;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
buflen = j; /* buflen is the length of the dequoted
|
206
|
+
* data */
|
207
|
+
|
208
|
+
/* Shrink the buffer to be no larger than necessary */
|
209
|
+
/* +1 avoids unportable behavior when buflen==0 */
|
210
|
+
tmpbuf = realloc(buffer, buflen + 1);
|
211
|
+
|
212
|
+
/* It would only be a very brain-dead realloc that could fail, but... */
|
213
|
+
if (!tmpbuf)
|
214
|
+
{
|
215
|
+
free(buffer);
|
216
|
+
return NULL;
|
217
|
+
}
|
218
|
+
|
219
|
+
*retbuflen = buflen;
|
220
|
+
return tmpbuf;
|
221
|
+
}
|
222
|
+
#endif
|
223
|
+
|
224
|
+
#ifndef HAVE_PQEXECPARAMS
|
225
|
+
#include <ruby.h>
|
226
|
+
#include <re.h>
|
227
|
+
#include <libpq-fe.h>
|
228
|
+
|
229
|
+
#define BIND_PARAM_PATTERN "\\$(\\d+)"
|
230
|
+
#define BindParamNumber(match) (FIX2INT(rb_str_to_inum(rb_reg_nth_match(1, match), 10, 0))-1)
|
231
|
+
|
232
|
+
PGresult *PQexecParams_compat(PGconn *conn, VALUE command, VALUE values)
|
233
|
+
{
|
234
|
+
VALUE bind_param_re = rb_reg_new(BIND_PARAM_PATTERN, 7, 0);
|
235
|
+
VALUE result = rb_str_buf_new(RSTRING(command)->len);
|
236
|
+
char* ptr = RSTRING(command)->ptr;
|
237
|
+
int scan = 0;
|
238
|
+
while ((scan = rb_reg_search(bind_param_re, command, scan, 0)) > 0) {
|
239
|
+
VALUE match = rb_backref_get();
|
240
|
+
int pos = BindParamNumber(match);
|
241
|
+
if (pos < RARRAY(values)->len) {
|
242
|
+
rb_str_buf_cat(result, ptr, scan - (ptr - RSTRING(command)->ptr));
|
243
|
+
ptr = RSTRING(command)->ptr + scan;
|
244
|
+
rb_str_buf_append(result, RARRAY(values)->ptr[pos]);
|
245
|
+
}
|
246
|
+
scan += RSTRING(rb_reg_nth_match(0, match))->len;
|
247
|
+
ptr += RSTRING(rb_reg_nth_match(0, match))->len;
|
248
|
+
}
|
249
|
+
rb_str_buf_cat(result, ptr, RSTRING(command)->len - (ptr - RSTRING(command)->ptr));
|
250
|
+
|
251
|
+
return PQexec(conn, StringValuePtr(result));
|
252
|
+
}
|
253
|
+
#endif
|
@@ -25,6 +25,22 @@
|
|
25
25
|
#include <stdlib.h>
|
26
26
|
#include <sys/types.h>
|
27
27
|
|
28
|
+
#ifndef HAVE_PQSERVERVERSION
|
29
|
+
static int
|
30
|
+
PQserverVersion(const PGconn *conn)
|
31
|
+
{
|
32
|
+
rb_raise(rb_eArgError,"this version of libpq doesn't support PQserverVersion");
|
33
|
+
}
|
34
|
+
#endif /* HAVE_PQSERVERVERSION */
|
35
|
+
|
36
|
+
#ifndef RSTRING_LEN
|
37
|
+
#define RSTRING_LEN(x) RSTRING((x))->len
|
38
|
+
#endif /* RSTRING_LEN */
|
39
|
+
|
40
|
+
#ifndef RSTRING_PTR
|
41
|
+
#define RSTRING_PTR(x) RSTRING((x))->ptr
|
42
|
+
#endif /* RSTRING_PTR */
|
43
|
+
|
28
44
|
#ifndef HAVE_PG_ENCODING_TO_CHAR
|
29
45
|
#define pg_encoding_to_char(x) "SQL_ASCII"
|
30
46
|
#endif
|
@@ -175,9 +191,11 @@ pgconn_connect(argc, argv, self)
|
|
175
191
|
rb_raise(rb_ePGError, StringValuePtr(message));
|
176
192
|
}
|
177
193
|
|
194
|
+
#ifdef HAVE_PQSERVERVERSION
|
178
195
|
if (PQserverVersion(conn) >= 80100) {
|
179
196
|
rb_define_singleton_method(self, "lastval", pgconn_lastval, 0);
|
180
197
|
}
|
198
|
+
#endif /* HAVE_PQSERVERVERSION */
|
181
199
|
|
182
200
|
Data_Set_Struct(self, conn);
|
183
201
|
return self;
|
@@ -259,8 +277,8 @@ pgconn_s_quote(self, obj)
|
|
259
277
|
if (TYPE(obj) == T_STRING) {
|
260
278
|
/* length * 2 because every char could require escaping */
|
261
279
|
/* + 2 for the quotes, + 1 for the null terminator */
|
262
|
-
quoted = ALLOCA_N(char,
|
263
|
-
size = PQescapeString(quoted + 1,
|
280
|
+
quoted = ALLOCA_N(char, RSTRING_LEN(obj) * 2 + 2 + 1);
|
281
|
+
size = PQescapeString(quoted + 1, RSTRING_PTR(obj), RSTRING_LEN(obj));
|
264
282
|
*quoted = *(quoted + size + 1) = SINGLE_QUOTE;
|
265
283
|
result = rb_str_new(quoted, size + 2);
|
266
284
|
OBJ_INFECT(result, obj);
|
@@ -299,8 +317,9 @@ pgconn_quote(self, obj)
|
|
299
317
|
if (TYPE(obj) == T_STRING) {
|
300
318
|
/* length * 2 because every char could require escaping */
|
301
319
|
/* + 2 for the quotes, + 1 for the null terminator */
|
302
|
-
quoted = ALLOCA_N(char,
|
303
|
-
size = PQescapeStringConn(get_pgconn(self),quoted + 1,
|
320
|
+
quoted = ALLOCA_N(char, RSTRING_LEN(obj) * 2 + 2 + 1);
|
321
|
+
size = PQescapeStringConn(get_pgconn(self),quoted + 1,
|
322
|
+
RSTRING_PTR(obj), RSTRING_LEN(obj), &error);
|
304
323
|
*quoted = *(quoted + size + 1) = SINGLE_QUOTE;
|
305
324
|
result = rb_str_new(quoted, size + 2);
|
306
325
|
OBJ_INFECT(result, obj);
|
@@ -321,8 +340,8 @@ pgconn_s_quote_connstr(string)
|
|
321
340
|
|
322
341
|
Check_Type(string, T_STRING);
|
323
342
|
|
324
|
-
ptr =
|
325
|
-
len =
|
343
|
+
ptr = RSTRING_PTR(string);
|
344
|
+
len = RSTRING_LEN(string);
|
326
345
|
str = ALLOCA_N(char, len * 2 + 2 + 1);
|
327
346
|
str[j++] = '\'';
|
328
347
|
for(i = 0; i < len; i++) {
|
@@ -366,8 +385,8 @@ pgconn_s_quote_ident(self, string)
|
|
366
385
|
|
367
386
|
Check_Type(string, T_STRING);
|
368
387
|
|
369
|
-
ptr =
|
370
|
-
len =
|
388
|
+
ptr = RSTRING_PTR(string);
|
389
|
+
len = RSTRING_LEN(string);
|
371
390
|
str = ALLOCA_N(char, len * 2 + 2 + 1);
|
372
391
|
str[j++] = '"';
|
373
392
|
for(i = 0; i < len; i++) {
|
@@ -397,8 +416,8 @@ pgconn_s_escape(self, string)
|
|
397
416
|
|
398
417
|
Check_Type(string, T_STRING);
|
399
418
|
|
400
|
-
escaped = ALLOCA_N(char,
|
401
|
-
size = PQescapeString(escaped,
|
419
|
+
escaped = ALLOCA_N(char, RSTRING_LEN(string) * 2 + 1);
|
420
|
+
size = PQescapeString(escaped, RSTRING_PTR(string), RSTRING_LEN(string));
|
402
421
|
result = rb_str_new(escaped, size);
|
403
422
|
OBJ_INFECT(result, string);
|
404
423
|
return result;
|
@@ -418,8 +437,9 @@ pgconn_escape(self, string)
|
|
418
437
|
|
419
438
|
Check_Type(string, T_STRING);
|
420
439
|
|
421
|
-
escaped = ALLOCA_N(char,
|
422
|
-
size = PQescapeStringConn(get_pgconn(self),escaped,
|
440
|
+
escaped = ALLOCA_N(char, RSTRING_LEN(string) * 2 + 1);
|
441
|
+
size = PQescapeStringConn(get_pgconn(self),escaped, RSTRING_PTR(string),
|
442
|
+
RSTRING_LEN(string), &error);
|
423
443
|
result = rb_str_new(escaped, size);
|
424
444
|
OBJ_INFECT(result, string);
|
425
445
|
return result;
|
@@ -450,8 +470,8 @@ pgconn_s_escape_bytea(self, obj)
|
|
450
470
|
VALUE ret;
|
451
471
|
|
452
472
|
Check_Type(obj, T_STRING);
|
453
|
-
from =
|
454
|
-
from_len =
|
473
|
+
from = RSTRING_PTR(obj);
|
474
|
+
from_len = RSTRING_LEN(obj);
|
455
475
|
|
456
476
|
to = (char *)PQescapeBytea(from, from_len, &to_len);
|
457
477
|
|
@@ -488,8 +508,8 @@ pgconn_escape_bytea(self, obj)
|
|
488
508
|
VALUE ret;
|
489
509
|
|
490
510
|
Check_Type(obj, T_STRING);
|
491
|
-
from =
|
492
|
-
from_len =
|
511
|
+
from = RSTRING_PTR(obj);
|
512
|
+
from_len = RSTRING_LEN(obj);
|
493
513
|
|
494
514
|
to = (char *)PQescapeByteaConn(get_pgconn(self),from, from_len, &to_len);
|
495
515
|
|
@@ -653,13 +673,13 @@ translate_to_pg(VALUE value, char const** result, int* length, int* format)
|
|
653
673
|
return;
|
654
674
|
case T_STRING:
|
655
675
|
*result = StringValuePtr(value);
|
656
|
-
*length =
|
676
|
+
*length = RSTRING_LEN(value);
|
657
677
|
*format = BINARY_FORMAT;
|
658
678
|
return;
|
659
679
|
default: {
|
660
680
|
VALUE formatted = pgconn_s_format(rb_cPGconn, value);
|
661
681
|
*result = StringValuePtr(formatted);
|
662
|
-
*length =
|
682
|
+
*length = RSTRING_LEN(formatted);
|
663
683
|
*format = TEXT_FORMAT;
|
664
684
|
}
|
665
685
|
}
|
@@ -735,7 +755,7 @@ pgconn_exec(argc, argv, obj)
|
|
735
755
|
case PGRES_BAD_RESPONSE:
|
736
756
|
case PGRES_FATAL_ERROR:
|
737
757
|
case PGRES_NONFATAL_ERROR:
|
738
|
-
msg =
|
758
|
+
msg = RSTRING_PTR(rb_str_new2(PQresultErrorMessage(result)));
|
739
759
|
break;
|
740
760
|
default:
|
741
761
|
msg = "internal error : unknown result status.";
|
@@ -771,7 +791,7 @@ pgconn_async_exec(obj, str)
|
|
771
791
|
PQclear(result);
|
772
792
|
}
|
773
793
|
|
774
|
-
if (!PQsendQuery(conn,
|
794
|
+
if (!PQsendQuery(conn, RSTRING_PTR(str))) {
|
775
795
|
rb_raise(rb_ePGError, PQerrorMessage(conn));
|
776
796
|
}
|
777
797
|
|
@@ -814,7 +834,7 @@ pgconn_async_exec(obj, str)
|
|
814
834
|
case PGRES_BAD_RESPONSE:
|
815
835
|
case PGRES_FATAL_ERROR:
|
816
836
|
case PGRES_NONFATAL_ERROR:
|
817
|
-
msg =
|
837
|
+
msg = RSTRING_PTR(rb_str_new2(PQresultErrorMessage(result)));
|
818
838
|
break;
|
819
839
|
default:
|
820
840
|
msg = "internal error : unknown result status.";
|
@@ -925,9 +945,9 @@ pgconn_insert_table(obj, table, values)
|
|
925
945
|
}
|
926
946
|
}
|
927
947
|
|
928
|
-
buffer = rb_str_new(0,
|
948
|
+
buffer = rb_str_new(0, RSTRING_LEN(table) + 17 + 1);
|
929
949
|
/* starts query */
|
930
|
-
snprintf(
|
950
|
+
snprintf(RSTRING_PTR(buffer), RSTRING_LEN(buffer), "copy %s from stdin ", StringValuePtr(table));
|
931
951
|
|
932
952
|
result = PQexec(conn, StringValuePtr(buffer));
|
933
953
|
if (!result){
|
@@ -945,7 +965,7 @@ pgconn_insert_table(obj, table, values)
|
|
945
965
|
} else {
|
946
966
|
s = rb_obj_as_string(row->ptr[j]);
|
947
967
|
rb_funcall(s,pg_gsub_bang_id,2,pg_escape_regex,pg_escape_str);
|
948
|
-
rb_str_cat(buffer, StringValuePtr(s),
|
968
|
+
rb_str_cat(buffer, StringValuePtr(s), RSTRING_LEN(s));
|
949
969
|
}
|
950
970
|
}
|
951
971
|
rb_str_cat(buffer, "\n\0", 2);
|
@@ -996,7 +1016,7 @@ pgconn_getline(obj)
|
|
996
1016
|
str = rb_tainted_str_new(0, size);
|
997
1017
|
|
998
1018
|
for (;;) {
|
999
|
-
ret = PQgetline(conn,
|
1019
|
+
ret = PQgetline(conn, RSTRING_PTR(str) + bytes, size - bytes);
|
1000
1020
|
switch (ret) {
|
1001
1021
|
case EOF:
|
1002
1022
|
return Qnil;
|
@@ -1182,7 +1202,7 @@ pgconn_error(obj)
|
|
1182
1202
|
return rb_tainted_str_new2(error);
|
1183
1203
|
}
|
1184
1204
|
|
1185
|
-
/*
|
1205
|
+
/*TODO broken for ruby 1.9
|
1186
1206
|
* call-seq:
|
1187
1207
|
* conn.trace( port )
|
1188
1208
|
*
|
@@ -1194,12 +1214,12 @@ static VALUE
|
|
1194
1214
|
pgconn_trace(obj, port)
|
1195
1215
|
VALUE obj, port;
|
1196
1216
|
{
|
1197
|
-
OpenFile* fp;
|
1217
|
+
//OpenFile* fp;
|
1198
1218
|
|
1199
1219
|
Check_Type(port, T_FILE);
|
1200
|
-
GetOpenFile(port, fp);
|
1220
|
+
//GetOpenFile(port, fp);
|
1201
1221
|
|
1202
|
-
PQtrace(get_pgconn(obj), fp->f2?fp->f2:fp->f);
|
1222
|
+
//PQtrace(get_pgconn(obj), fp->f2?fp->f2:fp->f);
|
1203
1223
|
|
1204
1224
|
return obj;
|
1205
1225
|
}
|
@@ -2287,7 +2307,7 @@ loread_all(obj)
|
|
2287
2307
|
|
2288
2308
|
str = rb_tainted_str_new(0,siz);
|
2289
2309
|
for (;;) {
|
2290
|
-
n = lo_read(pglarge->pgconn, pglarge->lo_fd,
|
2310
|
+
n = lo_read(pglarge->pgconn, pglarge->lo_fd, RSTRING_PTR(str) + bytes,siz - bytes);
|
2291
2311
|
if (n == 0 && bytes == 0) return Qnil;
|
2292
2312
|
bytes += n;
|
2293
2313
|
if (bytes < siz ) break;
|
@@ -2332,7 +2352,7 @@ pglarge_read(argc, argv, obj)
|
|
2332
2352
|
rb_raise(rb_ePGError, "error while reading");
|
2333
2353
|
}
|
2334
2354
|
if (len == 0) return Qnil;
|
2335
|
-
|
2355
|
+
RSTRING_LEN(str) = len;
|
2336
2356
|
return str;
|
2337
2357
|
}
|
2338
2358
|
|
@@ -2352,10 +2372,11 @@ pglarge_write(obj, buffer)
|
|
2352
2372
|
|
2353
2373
|
Check_Type(buffer, T_STRING);
|
2354
2374
|
|
2355
|
-
if(
|
2375
|
+
if( RSTRING_LEN(buffer) < 0) {
|
2356
2376
|
rb_raise(rb_ePGError, "write buffer zero string");
|
2357
2377
|
}
|
2358
|
-
if((n = lo_write(pglarge->pgconn, pglarge->lo_fd, StringValuePtr(buffer),
|
2378
|
+
if((n = lo_write(pglarge->pgconn, pglarge->lo_fd, StringValuePtr(buffer),
|
2379
|
+
RSTRING_LEN(buffer))) == -1) {
|
2359
2380
|
rb_raise(rb_ePGError, "buffer truncated during write");
|
2360
2381
|
}
|
2361
2382
|
|