postgres 0.7.9.2007.12.12 → 0.7.9.2007.12.22
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|