rdo-postgres 0.0.6 → 0.0.7
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.md +33 -11
- data/ext/rdo_postgres/arrays.c +48 -0
- data/ext/rdo_postgres/arrays.h +9 -0
- data/ext/rdo_postgres/casts.c +68 -25
- data/ext/rdo_postgres/casts.h +3 -0
- data/ext/rdo_postgres/driver.c +4 -8
- data/ext/rdo_postgres/extconf.rb +1 -2
- data/ext/rdo_postgres/rdo_postgres.c +2 -0
- data/ext/rdo_postgres/statements.c +25 -20
- data/ext/rdo_postgres/types.h +74 -0
- data/lib/rdo/postgres.rb +12 -0
- data/lib/rdo/postgres/array.rb +84 -0
- data/lib/rdo/postgres/array/boolean.rb +21 -0
- data/lib/rdo/postgres/array/bytea.rb +22 -0
- data/lib/rdo/postgres/array/date.rb +17 -0
- data/lib/rdo/postgres/array/float.rb +30 -0
- data/lib/rdo/postgres/array/integer.rb +21 -0
- data/lib/rdo/postgres/array/numeric.rb +23 -0
- data/lib/rdo/postgres/array/text.rb +15 -0
- data/lib/rdo/postgres/array/timestamp.rb +17 -0
- data/lib/rdo/postgres/array/timestamp_tz.rb +17 -0
- data/lib/rdo/postgres/version.rb +1 -1
- data/spec/postgres/array/boolean_spec.rb +74 -0
- data/spec/postgres/array/bytea_spec.rb +82 -0
- data/spec/postgres/array/date_spec.rb +74 -0
- data/spec/postgres/array/float_spec.rb +98 -0
- data/spec/postgres/array/integer_spec.rb +74 -0
- data/spec/postgres/array/numeric_spec.rb +83 -0
- data/spec/postgres/array/timestamp_spec.rb +80 -0
- data/spec/postgres/array/timestamp_tz_spec.rb +80 -0
- data/spec/postgres/array_spec.rb +122 -0
- data/spec/postgres/bind_params_spec.rb +191 -1
- data/spec/postgres/type_cast_spec.rb +223 -0
- metadata +33 -2
data/README.md
CHANGED
@@ -8,9 +8,8 @@ This is the PostgreSQL driver for [RDO—Ruby Data Objects]
|
|
8
8
|
Refer to the RDO project [README](https://github.com/d11wtq/rdo) for usage
|
9
9
|
information.
|
10
10
|
|
11
|
-
This driver cannot be used with
|
12
|
-
|
13
|
-
features.
|
11
|
+
This driver cannot be used with PostgreSQL versions older than 7.4. Those
|
12
|
+
versions are no longer supported by PostgreSQL in any case.
|
14
13
|
|
15
14
|
## Installation
|
16
15
|
|
@@ -51,6 +50,33 @@ conn = RDO.connect(
|
|
51
50
|
)
|
52
51
|
```
|
53
52
|
|
53
|
+
### Type Support
|
54
|
+
|
55
|
+
If not listed below, the String form of the value will be returned. The
|
56
|
+
currently mapped types are:
|
57
|
+
|
58
|
+
- NULL -> nil
|
59
|
+
- BOOLEAN -> TrueClass/FalseClass
|
60
|
+
- TEXT -> String
|
61
|
+
- VARCHAR -> String
|
62
|
+
- CHAR -> String
|
63
|
+
- BYTEA -> String
|
64
|
+
- INTEGER -> Fixnum
|
65
|
+
- INT2 -> Fixnum
|
66
|
+
- INT4 -> Fixnum
|
67
|
+
- INT8 -> Fixnum
|
68
|
+
- FLOAT/REAL -> Float
|
69
|
+
- FLOAT4 -> Float
|
70
|
+
- FLOAT8 -> Float
|
71
|
+
- NUMERIC/DECIMAL -> BigDecimal
|
72
|
+
- DATE -> Date
|
73
|
+
- TIMESTAMP -> DateTime (in the system time zone)
|
74
|
+
- TIMESTAMPTZ -> DateTime (in the specified time zone)
|
75
|
+
|
76
|
+
All 1-dimensional Arrays of the above listed are also available. Support for
|
77
|
+
multi-dimensional Arrays is planned immediately. Support for custom-typed
|
78
|
+
Arrays is coming.
|
79
|
+
|
54
80
|
### Bind parameters support
|
55
81
|
|
56
82
|
PostgreSQL uses $1, $2 etc for bind parameters. RDO uses '?'. You can use
|
@@ -72,17 +98,13 @@ conn.execute("SELECT * FROM users WHERE banned = $1 AND created_at > ?", true, 1
|
|
72
98
|
|
73
99
|
## Contributing
|
74
100
|
|
75
|
-
Contributions to support older versions of PostgreSQL (< 7.4) welcomed,
|
76
|
-
though if the changes required break the native support for newer versions
|
77
|
-
pull requests will not be accepted. It is possible to write a separate
|
78
|
-
driver for older versions of PostgreSQL and register it under the driver
|
79
|
-
name 'postgresql' instead of this one if that is preferable. Alternatively,
|
80
|
-
use an explicit name that indicates legacy compatibility, such as
|
81
|
-
'postgres73'.
|
82
|
-
|
83
101
|
If you find any bugs, please send a pull request if you think you can
|
84
102
|
fix it, or file in an issue in the issue tracker.
|
85
103
|
|
104
|
+
I'm particulary interested in patches surrounding support for built-in type
|
105
|
+
arrays, multi-dimensional arrays and arrays of custom types, such as ENUMs
|
106
|
+
(in order of difficulty/preference).
|
107
|
+
|
86
108
|
When sending pull requests, please use topic branches—don't send a pull
|
87
109
|
request from the master branch of your fork, as that may change
|
88
110
|
unintentionally.
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/*
|
2
|
+
* RDO Postgres Driver.
|
3
|
+
* Copyright © 2012 Chris Corbyn.
|
4
|
+
*
|
5
|
+
* See LICENSE file for details.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "arrays.h"
|
9
|
+
#include "casts.h"
|
10
|
+
#include "macros.h"
|
11
|
+
#include <ruby.h>
|
12
|
+
#include <libpq-fe.h>
|
13
|
+
|
14
|
+
/** Parse a bytea string into a binary Ruby String */
|
15
|
+
static VALUE rdo_postgres_array_bytea_parse_value(VALUE self, VALUE s) {
|
16
|
+
s = rb_call_super(1, &s);
|
17
|
+
Check_Type(s, T_STRING);
|
18
|
+
return rdo_postgres_cast_bytea(RSTRING_PTR(s), RSTRING_LEN(s));
|
19
|
+
}
|
20
|
+
|
21
|
+
/** Format a value as a bytea */
|
22
|
+
static VALUE rdo_postgres_array_bytea_format_value(VALUE self, VALUE v) {
|
23
|
+
if (TYPE(v) != T_STRING) {
|
24
|
+
v = RDO_OBJ_TO_S(v);
|
25
|
+
}
|
26
|
+
|
27
|
+
size_t len = 0;
|
28
|
+
unsigned char * bytea = PQescapeBytea((unsigned char *) RSTRING_PTR(v),
|
29
|
+
RSTRING_LEN(v), &len);
|
30
|
+
|
31
|
+
VALUE escaped = rb_str_new((char *) bytea, len - 1);
|
32
|
+
VALUE formatted = rb_call_super(1, &escaped);
|
33
|
+
|
34
|
+
PQfreemem(bytea);
|
35
|
+
|
36
|
+
return formatted;
|
37
|
+
}
|
38
|
+
|
39
|
+
/** Initialize Array extensions */
|
40
|
+
void Init_rdo_postgres_arrays(void) {
|
41
|
+
VALUE cByteaArray = rb_path2class("RDO::Postgres::Array::Bytea");
|
42
|
+
|
43
|
+
rb_define_method(cByteaArray,
|
44
|
+
"parse_value", rdo_postgres_array_bytea_parse_value, 1);
|
45
|
+
|
46
|
+
rb_define_method(cByteaArray,
|
47
|
+
"format_value", rdo_postgres_array_bytea_format_value, 1);
|
48
|
+
}
|
data/ext/rdo_postgres/casts.c
CHANGED
@@ -7,13 +7,18 @@
|
|
7
7
|
|
8
8
|
#include "casts.h"
|
9
9
|
#include <stdlib.h>
|
10
|
-
#include <postgres.h>
|
11
|
-
#include <catalog/pg_type.h>
|
12
10
|
#include "macros.h"
|
11
|
+
#include "types.h"
|
13
12
|
|
14
13
|
/** Predicate test if the given string is formatted as \x0afe... */
|
15
14
|
#define RDO_PG_NEW_HEX_P(s, len) (len >= 2 && s[0] == '\\' && s[1] == 'x')
|
16
15
|
|
16
|
+
/** Parse a PostgreSQL array and return an Array for the given type */
|
17
|
+
#define RDO_PG_ARRAY(clsname, s, len) \
|
18
|
+
(rb_funcall((rb_funcall(rb_path2class("RDO::Postgres::Array::" clsname), \
|
19
|
+
rb_intern("parse"), 1, rb_str_new(s, len))), \
|
20
|
+
rb_intern("to_a"), 0))
|
21
|
+
|
17
22
|
/** Lookup table for fast conversion of bytea hex strings to binary data */
|
18
23
|
static char * RDOPostgres_HexLookup;
|
19
24
|
|
@@ -45,19 +50,27 @@ static VALUE rdo_postgres_cast_bytea_hex(char * hex, size_t len) {
|
|
45
50
|
|
46
51
|
/** Cast from a bytea to a String according to a regular escape format */
|
47
52
|
static VALUE rdo_postgres_cast_bytea_escape(char * escaped, size_t len) {
|
48
|
-
unsigned char * buffer = PQunescapeBytea(escaped, &len);
|
53
|
+
unsigned char * buffer = PQunescapeBytea((unsigned char *) escaped, &len);
|
49
54
|
|
50
55
|
if (buffer == NULL) {
|
51
56
|
rb_raise(rb_eRuntimeError,
|
52
57
|
"Failed to allocate memory for PQunescapeBytea() conversion");
|
53
58
|
}
|
54
59
|
|
55
|
-
VALUE str = rb_str_new(buffer, len);
|
60
|
+
VALUE str = rb_str_new((char *) buffer, len);
|
56
61
|
PQfreemem(buffer);
|
57
62
|
|
58
63
|
return str;
|
59
64
|
}
|
60
65
|
|
66
|
+
/** Cast from a bytea to a String, automatically detecting the format */
|
67
|
+
VALUE rdo_postgres_cast_bytea(char * escaped, size_t len) {
|
68
|
+
if (RDO_PG_NEW_HEX_P(escaped, len))
|
69
|
+
return rdo_postgres_cast_bytea_hex(escaped, len);
|
70
|
+
else
|
71
|
+
return rdo_postgres_cast_bytea_escape(escaped, len);
|
72
|
+
}
|
73
|
+
|
61
74
|
/** Get the value as a ruby type */
|
62
75
|
VALUE rdo_postgres_cast_value(PGresult * res, int row, int col, int enc) {
|
63
76
|
if (PQgetisnull(res, row, col)) {
|
@@ -68,42 +81,72 @@ VALUE rdo_postgres_cast_value(PGresult * res, int row, int col, int enc) {
|
|
68
81
|
int length = PQgetlength(res, row, col);
|
69
82
|
|
70
83
|
switch (PQftype(res, col)) {
|
71
|
-
case
|
72
|
-
case
|
73
|
-
case
|
84
|
+
case RDO_PG_INT2OID:
|
85
|
+
case RDO_PG_INT4OID:
|
86
|
+
case RDO_PG_INT8OID:
|
74
87
|
return RDO_FIXNUM(value);
|
75
88
|
|
76
|
-
case
|
77
|
-
case
|
89
|
+
case RDO_PG_FLOAT4OID:
|
90
|
+
case RDO_PG_FLOAT8OID:
|
78
91
|
return RDO_FLOAT(value);
|
79
92
|
|
80
|
-
case
|
93
|
+
case RDO_PG_NUMERICOID:
|
81
94
|
return RDO_DECIMAL(value);
|
82
95
|
|
83
|
-
case
|
96
|
+
case RDO_PG_BOOLOID:
|
84
97
|
return RDO_BOOL(value);
|
85
98
|
|
86
|
-
case
|
87
|
-
|
88
|
-
return rdo_postgres_cast_bytea_hex(value, length);
|
89
|
-
else
|
90
|
-
return rdo_postgres_cast_bytea_escape(value, length);
|
99
|
+
case RDO_PG_BYTEAOID:
|
100
|
+
return rdo_postgres_cast_bytea(value, length);
|
91
101
|
|
92
|
-
case
|
102
|
+
case RDO_PG_DATEOID:
|
93
103
|
return RDO_DATE(value);
|
94
104
|
|
95
|
-
case
|
105
|
+
case RDO_PG_TIMESTAMPOID:
|
96
106
|
return RDO_DATE_TIME_WITHOUT_ZONE(value);
|
97
107
|
|
98
|
-
case
|
108
|
+
case RDO_PG_TIMESTAMPTZOID:
|
99
109
|
return RDO_DATE_TIME_WITH_ZONE(value);
|
100
110
|
|
101
|
-
case
|
102
|
-
case
|
103
|
-
case
|
104
|
-
case
|
111
|
+
case RDO_PG_TEXTOID:
|
112
|
+
case RDO_PG_CHAROID:
|
113
|
+
case RDO_PG_VARCHAROID:
|
114
|
+
case RDO_PG_BPCHAROID:
|
105
115
|
return RDO_STRING(value, length, enc);
|
106
116
|
|
117
|
+
case RDO_PG_TEXTARRAYOID:
|
118
|
+
case RDO_PG_CHARARRAYOID:
|
119
|
+
case RDO_PG_BPCHARARRAYOID:
|
120
|
+
case RDO_PG_VARCHARARRAYOID:
|
121
|
+
return RDO_PG_ARRAY("Text", value, length);
|
122
|
+
|
123
|
+
case RDO_PG_INT2ARRAYOID:
|
124
|
+
case RDO_PG_INT4ARRAYOID:
|
125
|
+
case RDO_PG_INT8ARRAYOID:
|
126
|
+
return RDO_PG_ARRAY("Integer", value, length);
|
127
|
+
|
128
|
+
case RDO_PG_FLOAT4ARRAYOID:
|
129
|
+
case RDO_PG_FLOAT8ARRAYOID:
|
130
|
+
return RDO_PG_ARRAY("Float", value, length);
|
131
|
+
|
132
|
+
case RDO_PG_NUMERICARRAYOID:
|
133
|
+
return RDO_PG_ARRAY("Numeric", value, length);
|
134
|
+
|
135
|
+
case RDO_PG_BOOLARRAYOID:
|
136
|
+
return RDO_PG_ARRAY("Boolean", value, length);
|
137
|
+
|
138
|
+
case RDO_PG_BYTEAARRAYOID:
|
139
|
+
return RDO_PG_ARRAY("Bytea", value, length);
|
140
|
+
|
141
|
+
case RDO_PG_DATEARRAYOID:
|
142
|
+
return RDO_PG_ARRAY("Date", value, length);
|
143
|
+
|
144
|
+
case RDO_PG_TIMESTAMPARRAYOID:
|
145
|
+
return RDO_PG_ARRAY("Timestamp", value, length);
|
146
|
+
|
147
|
+
case RDO_PG_TIMESTAMPTZARRAYOID:
|
148
|
+
return RDO_PG_ARRAY("TimestampTZ", value, length);
|
149
|
+
|
107
150
|
default:
|
108
151
|
return RDO_BINARY_STRING(value, length);
|
109
152
|
}
|
@@ -111,11 +154,11 @@ VALUE rdo_postgres_cast_value(PGresult * res, int row, int col, int enc) {
|
|
111
154
|
|
112
155
|
/* Initialize hex decoding lookup table */
|
113
156
|
void Init_rdo_postgres_casts(void) {
|
114
|
-
RDOPostgres_HexLookup = malloc(sizeof(char) *
|
157
|
+
RDOPostgres_HexLookup = malloc(sizeof(char) * 256);
|
115
158
|
|
116
159
|
if (RDOPostgres_HexLookup == NULL) {
|
117
160
|
rb_raise(rb_eRuntimeError,
|
118
|
-
"Failed to allocate
|
161
|
+
"Failed to allocate 256 bytes for internal lookup table");
|
119
162
|
}
|
120
163
|
|
121
164
|
char c;
|
data/ext/rdo_postgres/casts.h
CHANGED
@@ -12,5 +12,8 @@
|
|
12
12
|
/** Cast the given value from the result to a ruby type */
|
13
13
|
VALUE rdo_postgres_cast_value(PGresult * res, int row, int col, int enc);
|
14
14
|
|
15
|
+
/** Special case for casting a bytea value */
|
16
|
+
VALUE rdo_postgres_cast_bytea(char * escaped, size_t len);
|
17
|
+
|
15
18
|
/** Initialize the casting framework */
|
16
19
|
void Init_rdo_postgres_casts(void);
|
data/ext/rdo_postgres/driver.c
CHANGED
@@ -49,12 +49,10 @@ static VALUE rdo_postgres_driver_open(VALUE self) {
|
|
49
49
|
RSTRING_PTR(rb_funcall(self, rb_intern("connect_db_string"), 0)));
|
50
50
|
|
51
51
|
if (driver->conn_ptr == NULL || PQstatus(driver->conn_ptr) == CONNECTION_BAD) {
|
52
|
-
|
53
|
-
"PostgreSQL connection failed: %s",
|
52
|
+
RDO_ERROR("PostgreSQL connection failed: %s",
|
54
53
|
PQerrorMessage(driver->conn_ptr));
|
55
54
|
} else if (PQprotocolVersion(driver->conn_ptr) < 3) {
|
56
|
-
|
57
|
-
"rdo-postgres requires PostgreSQL protocol version >= 3 (using %u). "
|
55
|
+
RDO_ERROR("rdo-postgres requires PostgreSQL protocol version >= 3 (using %u). "
|
58
56
|
"PostgreSQL >= 7.4 required.",
|
59
57
|
PQprotocolVersion(driver->conn_ptr));
|
60
58
|
} else {
|
@@ -98,8 +96,7 @@ static VALUE rdo_postgres_driver_prepare(VALUE self, VALUE cmd) {
|
|
98
96
|
Data_Get_Struct(self, RDOPostgresDriver, driver);
|
99
97
|
|
100
98
|
if (!(driver->is_open)) {
|
101
|
-
|
102
|
-
"Unable to prepare statement: connection is not open");
|
99
|
+
RDO_ERROR("Unable to prepare statement: connection is not open");
|
103
100
|
}
|
104
101
|
|
105
102
|
char name[32];
|
@@ -120,8 +117,7 @@ static VALUE rdo_postgres_driver_quote(VALUE self, VALUE str) {
|
|
120
117
|
Data_Get_Struct(self, RDOPostgresDriver, driver);
|
121
118
|
|
122
119
|
if (!(driver->is_open)) {
|
123
|
-
|
124
|
-
"Unable to quote string: connection is not open");
|
120
|
+
RDO_ERROR("Unable to quote string: connection is not open");
|
125
121
|
}
|
126
122
|
|
127
123
|
char * quoted = malloc(sizeof(char) * RSTRING_LEN(str) * 2 + 1);
|
data/ext/rdo_postgres/extconf.rb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#include <stdlib.h>
|
9
9
|
#include <ruby.h>
|
10
10
|
#include "driver.h"
|
11
|
+
#include "arrays.h"
|
11
12
|
|
12
13
|
/**
|
13
14
|
* Extension initializer.
|
@@ -15,4 +16,5 @@
|
|
15
16
|
void Init_rdo_postgres(void) {
|
16
17
|
rb_require("rdo");
|
17
18
|
Init_rdo_postgres_driver();
|
19
|
+
Init_rdo_postgres_arrays();
|
18
20
|
}
|
@@ -12,8 +12,7 @@
|
|
12
12
|
#include "macros.h"
|
13
13
|
#include <stdlib.h>
|
14
14
|
#include <libpq-fe.h>
|
15
|
-
#include
|
16
|
-
#include <catalog/pg_type.h>
|
15
|
+
#include "types.h"
|
17
16
|
|
18
17
|
/** I don't like magic numbers */
|
19
18
|
#define RDO_PG_NO_OIDS 0
|
@@ -21,6 +20,11 @@
|
|
21
20
|
#define RDO_PG_TEXT_INPUT NULL
|
22
21
|
#define RDO_PG_TEXT_OUTPUT 0
|
23
22
|
|
23
|
+
/** Wrap a Ruby Array with a RDO::Postgres::Array */
|
24
|
+
#define RDO_PG_WRAP_ARRAY(clsname, a) \
|
25
|
+
(rb_funcall(rb_path2class("RDO::Postgres::Array::" clsname), \
|
26
|
+
rb_intern("new"), 1, a))
|
27
|
+
|
24
28
|
/** RDO::Postgres::StatementExecutor */
|
25
29
|
static VALUE rdo_postgres_cStatementExecutor;
|
26
30
|
|
@@ -60,8 +64,7 @@ static void rdo_postgres_statement_executor_prepare(VALUE self) {
|
|
60
64
|
Data_Get_Struct(self, RDOPostgresStatementExecutor, executor);
|
61
65
|
|
62
66
|
if (!(executor->driver->is_open)) {
|
63
|
-
|
64
|
-
"Unable to prepare statement: connection is not open");
|
67
|
+
RDO_ERROR("Unable to prepare statement: connection is not open");
|
65
68
|
}
|
66
69
|
|
67
70
|
char * cmd = rdo_postgres_params_inject_markers(executor->cmd);
|
@@ -85,8 +88,7 @@ static void rdo_postgres_statement_executor_prepare(VALUE self) {
|
|
85
88
|
char msg[sizeof(char) * (strlen(PQresultErrorMessage(res)) + 1)];
|
86
89
|
strcpy(msg, PQresultErrorMessage(res));
|
87
90
|
PQclear(res);
|
88
|
-
|
89
|
-
"Failed to prepare statement: %s", msg);
|
91
|
+
RDO_ERROR("Failed to prepare statement: %s", msg);
|
90
92
|
}
|
91
93
|
|
92
94
|
res = PQdescribePrepared(executor->driver->conn_ptr, executor->stmt_name);
|
@@ -95,8 +97,7 @@ static void rdo_postgres_statement_executor_prepare(VALUE self) {
|
|
95
97
|
char msg[sizeof(char) * (strlen(PQresultErrorMessage(res)) + 1)];
|
96
98
|
strcpy(msg, PQresultErrorMessage(res));
|
97
99
|
PQclear(res);
|
98
|
-
|
99
|
-
"Failed to prepare statement: %s", msg);
|
100
|
+
RDO_ERROR("Failed to prepare statement: %s", msg);
|
100
101
|
}
|
101
102
|
|
102
103
|
executor->nparams = PQnparams(res);
|
@@ -154,12 +155,11 @@ static VALUE rdo_postgres_statement_executor_execute(int argc, VALUE * args,
|
|
154
155
|
Data_Get_Struct(self, RDOPostgresStatementExecutor, executor);
|
155
156
|
|
156
157
|
if (!(executor->driver->is_open)) {
|
157
|
-
|
158
|
-
"Unable to execute statement: connection is not open");
|
158
|
+
RDO_ERROR("Unable to execute statement: connection is not open");
|
159
159
|
}
|
160
160
|
|
161
161
|
if (argc != executor->nparams) {
|
162
|
-
rb_raise(
|
162
|
+
rb_raise(rb_eArgError,
|
163
163
|
"Bind parameter count mismatch: wanted %i, got %i",
|
164
164
|
executor->nparams, argc);
|
165
165
|
}
|
@@ -173,13 +173,21 @@ static VALUE rdo_postgres_statement_executor_execute(int argc, VALUE * args,
|
|
173
173
|
values[i] = NULL;
|
174
174
|
lengths[i] = 0;
|
175
175
|
} else {
|
176
|
+
if (TYPE(args[i]) == T_ARRAY) {
|
177
|
+
if (executor->param_types[i] == RDO_PG_BYTEAARRAYOID) {
|
178
|
+
args[i] = RDO_PG_WRAP_ARRAY("Bytea", args[i]);
|
179
|
+
} else {
|
180
|
+
args[i] = RDO_PG_WRAP_ARRAY("Text", args[i]);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
176
184
|
if (TYPE(args[i]) != T_STRING) {
|
177
185
|
args[i] = RDO_OBJ_TO_S(args[i]);
|
178
186
|
}
|
179
187
|
|
180
|
-
if (executor->param_types[i] ==
|
181
|
-
values[i] = PQescapeByteaConn(executor->driver->conn_ptr,
|
182
|
-
RSTRING_PTR(args[i]),
|
188
|
+
if (executor->param_types[i] == RDO_PG_BYTEAOID) {
|
189
|
+
values[i] = (char *) PQescapeByteaConn(executor->driver->conn_ptr,
|
190
|
+
(unsigned char *) RSTRING_PTR(args[i]),
|
183
191
|
RSTRING_LEN(args[i]),
|
184
192
|
&(lengths[i]));
|
185
193
|
} else {
|
@@ -199,7 +207,7 @@ static VALUE rdo_postgres_statement_executor_execute(int argc, VALUE * args,
|
|
199
207
|
RDO_PG_TEXT_OUTPUT);
|
200
208
|
|
201
209
|
for (i = 0; i < argc; ++i) {
|
202
|
-
if (executor->param_types[i] ==
|
210
|
+
if (executor->param_types[i] == RDO_PG_BYTEAOID) {
|
203
211
|
PQfreemem(values[i]);
|
204
212
|
}
|
205
213
|
}
|
@@ -208,13 +216,10 @@ static VALUE rdo_postgres_statement_executor_execute(int argc, VALUE * args,
|
|
208
216
|
|
209
217
|
if (status == PGRES_BAD_RESPONSE || status == PGRES_FATAL_ERROR) {
|
210
218
|
PQclear(res);
|
211
|
-
|
212
|
-
"Failed to execute statement: %s", PQresultErrorMessage(res));
|
219
|
+
RDO_ERROR("Failed to execute statement: %s", PQresultErrorMessage(res));
|
213
220
|
}
|
214
221
|
|
215
|
-
return
|
216
|
-
rb_intern("new"), 2,
|
217
|
-
rdo_postgres_tuple_list_new(res, executor->driver->encoding),
|
222
|
+
return RDO_RESULT(rdo_postgres_tuple_list_new(res, executor->driver->encoding),
|
218
223
|
rdo_postgres_result_info_new(res));
|
219
224
|
}
|
220
225
|
|