pg 1.0.0 → 1.1.0.pre20180730144600
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +52 -0
- data/README.rdoc +11 -0
- data/Rakefile +1 -1
- data/Rakefile.cross +1 -1
- data/ext/errorcodes.rb +1 -1
- data/ext/extconf.rb +2 -0
- data/ext/pg.c +3 -2
- data/ext/pg.h +33 -5
- data/ext/pg_binary_decoder.c +69 -6
- data/ext/pg_binary_encoder.c +1 -1
- data/ext/pg_coder.c +52 -3
- data/ext/pg_connection.c +290 -103
- data/ext/pg_copy_coder.c +10 -5
- data/ext/pg_result.c +339 -113
- data/ext/pg_text_decoder.c +597 -37
- data/ext/pg_text_encoder.c +1 -1
- data/ext/pg_tuple.c +540 -0
- data/ext/pg_type_map.c +1 -1
- data/ext/pg_type_map_all_strings.c +1 -1
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +1 -1
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +1 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/util.c +6 -6
- data/ext/util.h +2 -2
- data/lib/pg.rb +5 -3
- data/lib/pg/basic_type_mapping.rb +40 -7
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +20 -1
- data/lib/pg/constants.rb +1 -1
- data/lib/pg/exceptions.rb +1 -1
- data/lib/pg/result.rb +1 -1
- data/lib/pg/text_decoder.rb +19 -23
- data/lib/pg/text_encoder.rb +35 -1
- data/lib/pg/type_map_by_column.rb +1 -1
- data/spec/helpers.rb +39 -7
- data/spec/pg/basic_type_mapping_spec.rb +230 -27
- data/spec/pg/connection_spec.rb +116 -77
- data/spec/pg/result_spec.rb +46 -11
- data/spec/pg/type_map_by_class_spec.rb +1 -1
- data/spec/pg/type_map_by_column_spec.rb +1 -1
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_map_by_oid_spec.rb +1 -1
- data/spec/pg/type_map_in_ruby_spec.rb +1 -1
- data/spec/pg/type_map_spec.rb +1 -1
- data/spec/pg/type_spec.rb +177 -11
- data/spec/pg_spec.rb +1 -1
- metadata +24 -28
- metadata.gz.sig +0 -0
data/History.rdoc
CHANGED
@@ -1,3 +1,54 @@
|
|
1
|
+
== v2.0.0 - far from release -
|
2
|
+
|
3
|
+
Removed:
|
4
|
+
- Removed query method variants deprecated in pg-1.1.0.
|
5
|
+
|
6
|
+
|
7
|
+
== v1.1.0 [YYYY-MM-DD] Michael Granger <ged@FaerieMUD.org>
|
8
|
+
|
9
|
+
Deprecated:
|
10
|
+
- Forwarding conn.exec to conn.exec_params is deprecated.
|
11
|
+
- Forwarding conn.exec_params to conn.exec is deprecated.
|
12
|
+
- Forwarding conn.async_exec to conn.async_exec_params.
|
13
|
+
- Forwarding conn.send_query to conn.send_query_params is deprecated.
|
14
|
+
- Forwarding conn.async_exec_params to conn.async_exec is deprecated.
|
15
|
+
|
16
|
+
PG::Connection enhancements:
|
17
|
+
- Provide PG::Connection#sync_* and PG::Connection#async_* query methods for explicit calling syncronous or asynchronous libpq API.
|
18
|
+
- Make PG::Connection#exec and siblings switchable between sync and async API per PG::Connection.async_api= and change the default to async flavors.
|
19
|
+
- Add async flavors of exec_params, prepare, exec_prepared, describe_prepared and describe_portal.
|
20
|
+
They are identical to their syncronous counterpart, but make use of PostgreSQL's async API.
|
21
|
+
- Replace `rb_thread_fd_select()` by faster `rb_wait_for_single_fd()` in `conn.block` and `conn.async_exec` .
|
22
|
+
- Add PG::Connection#discard_results .
|
23
|
+
|
24
|
+
Result retrieval enhancements:
|
25
|
+
- Add PG::Result#tuple_values to retrieve all field values of a row as array.
|
26
|
+
- Add PG::Tuple, PG::Result#tuple_values and PG::Result#stream_each_tuple .
|
27
|
+
PG::Tuple offers a way to lazy cast result values.
|
28
|
+
- Estimate PG::Result size allocated by libpq and notify the garbage collector about it when running on Ruby-2.4 or newer.
|
29
|
+
- Make the estimated PG::Result size available to ObjectSpace.memsize_of(result) .
|
30
|
+
|
31
|
+
Type cast enhancements:
|
32
|
+
- Replace Ruby code by a faster C implementation of the SimpleDecoder's timestamp decode functions. github #20
|
33
|
+
- Interpret years with up to 7 digists and BC dates by timestamp decoder.
|
34
|
+
- Add text timestamp decoders for UTC vs. local timezone variations.
|
35
|
+
- Add text timestamp encoders for UTC timezone.
|
36
|
+
- Add decoders for binary timestamps: PG::BinaryDecoder::Timestamp and variations.
|
37
|
+
- Add PG::Coder#flags accessor to allow modifications of de- respectively encoder behaviour.
|
38
|
+
- Add a flag to raise TypeError for invalid input values to PG::TextDecoder::Array .
|
39
|
+
- Add a text decoder for inet/cidr written in C.
|
40
|
+
- Add a numeric decoder written in C.
|
41
|
+
- Ensure input text is zero terminated for text format in PG::Coder#decode .
|
42
|
+
|
43
|
+
Source code enhancements:
|
44
|
+
- Fix headers and permission bits of various repository files.
|
45
|
+
|
46
|
+
Bugfixes:
|
47
|
+
- Properly decode array with prepended dimensions. #272
|
48
|
+
For now dimension decorations are ignored, but a correct Array is returned.
|
49
|
+
- Array-Decoder: Avoid leaking memory when an Exception is raised while parsing. Fixes #279
|
50
|
+
|
51
|
+
|
1
52
|
== v1.0.0 [2018-01-10] Michael Granger <ged@FaerieMUD.org>
|
2
53
|
|
3
54
|
Deprecated:
|
@@ -7,6 +58,7 @@ Deprecated:
|
|
7
58
|
Removed:
|
8
59
|
- Remove compatibility code for Ruby < 2.0 and PostgreSQL < 9.2.
|
9
60
|
- Remove partial compatibility with Rubinius.
|
61
|
+
- Remove top-level constants PGconn, PGresult, and PGError.
|
10
62
|
|
11
63
|
Enhancements:
|
12
64
|
- Update error codes to PostgreSQL-10
|
data/README.rdoc
CHANGED
@@ -44,6 +44,17 @@ It usually work with earlier versions of Ruby/PostgreSQL as well, but those are
|
|
44
44
|
not regularly tested.
|
45
45
|
|
46
46
|
|
47
|
+
== Versioning
|
48
|
+
|
49
|
+
We tag and release gems according to the {Semantic Versioning}[http://semver.org/] principle.
|
50
|
+
|
51
|
+
As a result of this policy, you can (and should) specify a dependency on this gem using the {Pessimistic Version Constraint}[http://guides.rubygems.org/patterns/#pessimistic-version-constraint] with two digits of precision.
|
52
|
+
|
53
|
+
For example:
|
54
|
+
|
55
|
+
spec.add_dependency 'pg', '~> 1.0'
|
56
|
+
|
57
|
+
|
47
58
|
== How To Install
|
48
59
|
|
49
60
|
Install via RubyGems:
|
data/Rakefile
CHANGED
data/Rakefile.cross
CHANGED
data/ext/errorcodes.rb
CHANGED
data/ext/extconf.rb
CHANGED
data/ext/pg.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg.c - Toplevel extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
* Author/s:
|
6
6
|
*
|
@@ -143,7 +143,7 @@ pg_find_or_create_johab(void)
|
|
143
143
|
|
144
144
|
enc_index = rb_define_dummy_encoding(aliases[0]);
|
145
145
|
for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
|
146
|
-
|
146
|
+
rb_enc_alias(aliases[i], aliases[0]);
|
147
147
|
}
|
148
148
|
return rb_enc_from_index(enc_index);
|
149
149
|
}
|
@@ -630,5 +630,6 @@ Init_pg_ext()
|
|
630
630
|
init_pg_binary_encoder();
|
631
631
|
init_pg_binary_decoder();
|
632
632
|
init_pg_copycoder();
|
633
|
+
init_pg_tuple();
|
633
634
|
}
|
634
635
|
|
data/ext/pg.h
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
#include "ruby/encoding.h"
|
23
23
|
|
24
24
|
/* exported by ruby-1.9.3+ but not declared */
|
25
|
-
extern int
|
25
|
+
extern int rb_enc_alias(const char *, const char *);
|
26
26
|
|
27
27
|
#define PG_ENCODING_SET_NOCHECK(obj,i) \
|
28
28
|
do { \
|
@@ -77,6 +77,10 @@ typedef long suseconds_t;
|
|
77
77
|
#define PG_MAX_COLUMNS 4000
|
78
78
|
#endif
|
79
79
|
|
80
|
+
#ifndef RARRAY_AREF
|
81
|
+
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
|
82
|
+
#endif
|
83
|
+
|
80
84
|
/* The data behind each PG::Connection object */
|
81
85
|
typedef struct {
|
82
86
|
PGconn *pgconn;
|
@@ -100,6 +104,11 @@ typedef struct {
|
|
100
104
|
/* Kind of PG::Coder object for casting COPY rows to ruby values */
|
101
105
|
VALUE decoder_for_get_copy_data;
|
102
106
|
|
107
|
+
/* The connection socket, used for rb_wait_for_single_fd() */
|
108
|
+
int socket;
|
109
|
+
|
110
|
+
/* enable/disable guessing size of PGresult's allocated memory */
|
111
|
+
int guess_result_memsize;
|
103
112
|
} t_pg_connection;
|
104
113
|
|
105
114
|
typedef struct pg_coder t_pg_coder;
|
@@ -130,9 +139,15 @@ typedef struct {
|
|
130
139
|
*/
|
131
140
|
int nfields;
|
132
141
|
|
142
|
+
/* Size of PGresult as published to ruby memory management. */
|
143
|
+
ssize_t result_size;
|
144
|
+
|
133
145
|
/* Prefilled tuple Hash with fnames[] as keys. */
|
134
146
|
VALUE tuple_hash;
|
135
147
|
|
148
|
+
/* Hash with fnames[] to field number mapping. */
|
149
|
+
VALUE field_map;
|
150
|
+
|
136
151
|
/* List of field names as frozen String objects.
|
137
152
|
* Only valid if nfields != -1
|
138
153
|
*/
|
@@ -141,7 +156,7 @@ typedef struct {
|
|
141
156
|
|
142
157
|
|
143
158
|
typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
|
144
|
-
typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
|
159
|
+
typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, const char *, int, int, int, int);
|
145
160
|
typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
|
146
161
|
typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
|
147
162
|
typedef int (* t_pg_fit_to_copy_get)(VALUE);
|
@@ -149,12 +164,23 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
|
149
164
|
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
150
165
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
151
166
|
|
167
|
+
#define PG_CODER_TIMESTAMP_DB_UTC 0x0
|
168
|
+
#define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
|
169
|
+
#define PG_CODER_TIMESTAMP_APP_UTC 0x0
|
170
|
+
#define PG_CODER_TIMESTAMP_APP_LOCAL 0x2
|
171
|
+
#define PG_CODER_FORMAT_ERROR_MASK 0xc
|
172
|
+
#define PG_CODER_FORMAT_ERROR_TO_RAISE 0x4
|
173
|
+
#define PG_CODER_FORMAT_ERROR_TO_STRING 0x8
|
174
|
+
#define PG_CODER_FORMAT_ERROR_TO_PARTIAL 0xc
|
175
|
+
|
152
176
|
struct pg_coder {
|
153
177
|
t_pg_coder_enc_func enc_func;
|
154
178
|
t_pg_coder_dec_func dec_func;
|
155
179
|
VALUE coder_obj;
|
156
180
|
Oid oid;
|
157
181
|
int format;
|
182
|
+
/* OR-ed values out of PG_CODER_* */
|
183
|
+
int flags;
|
158
184
|
};
|
159
185
|
|
160
186
|
typedef struct {
|
@@ -253,9 +279,10 @@ void init_pg_text_encoder _(( void ));
|
|
253
279
|
void init_pg_text_decoder _(( void ));
|
254
280
|
void init_pg_binary_encoder _(( void ));
|
255
281
|
void init_pg_binary_decoder _(( void ));
|
282
|
+
void init_pg_tuple _(( void ));
|
256
283
|
VALUE lookup_error_class _(( const char * ));
|
257
|
-
VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
|
258
|
-
VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
|
284
|
+
VALUE pg_bin_dec_bytea _(( t_pg_coder*, const char *, int, int, int, int ));
|
285
|
+
VALUE pg_text_dec_string _(( t_pg_coder*, const char *, int, int, int, int ));
|
259
286
|
int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
|
260
287
|
int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
|
261
288
|
t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
|
@@ -298,6 +325,7 @@ VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
|
|
298
325
|
PGresult* pgresult_get _(( VALUE ));
|
299
326
|
VALUE pg_result_check _(( VALUE ));
|
300
327
|
VALUE pg_result_clear _(( VALUE ));
|
328
|
+
VALUE pg_tuple_new _(( VALUE, int ));
|
301
329
|
|
302
330
|
/*
|
303
331
|
* Fetch the data pointer for the result object
|
@@ -305,7 +333,7 @@ VALUE pg_result_clear _(( VALUE ));
|
|
305
333
|
static inline t_pg_result *
|
306
334
|
pgresult_get_this( VALUE self )
|
307
335
|
{
|
308
|
-
t_pg_result *this =
|
336
|
+
t_pg_result *this = RTYPEDDATA_DATA(self);
|
309
337
|
|
310
338
|
if( this == NULL )
|
311
339
|
rb_raise(rb_ePGerror, "result has been cleared");
|
data/ext/pg_binary_decoder.c
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
7
|
+
#include "ruby/version.h"
|
7
8
|
#include "pg.h"
|
8
9
|
#include "util.h"
|
9
10
|
#ifdef HAVE_INTTYPES_H
|
@@ -21,7 +22,7 @@ VALUE rb_mPG_BinaryDecoder;
|
|
21
22
|
*
|
22
23
|
*/
|
23
24
|
static VALUE
|
24
|
-
pg_bin_dec_boolean(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
|
25
|
+
pg_bin_dec_boolean(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
25
26
|
{
|
26
27
|
if (len < 1) {
|
27
28
|
rb_raise( rb_eTypeError, "wrong data for binary boolean converter in tuple %d field %d", tuple, field);
|
@@ -37,7 +38,7 @@ pg_bin_dec_boolean(t_pg_coder *conv, char *val, int len, int tuple, int field, i
|
|
37
38
|
*
|
38
39
|
*/
|
39
40
|
static VALUE
|
40
|
-
pg_bin_dec_integer(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
|
41
|
+
pg_bin_dec_integer(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
41
42
|
{
|
42
43
|
switch( len ){
|
43
44
|
case 2:
|
@@ -59,7 +60,7 @@ pg_bin_dec_integer(t_pg_coder *conv, char *val, int len, int tuple, int field, i
|
|
59
60
|
*
|
60
61
|
*/
|
61
62
|
static VALUE
|
62
|
-
pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
|
63
|
+
pg_bin_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
63
64
|
{
|
64
65
|
union {
|
65
66
|
float f;
|
@@ -91,7 +92,7 @@ pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int
|
|
91
92
|
*
|
92
93
|
*/
|
93
94
|
VALUE
|
94
|
-
pg_bin_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
|
95
|
+
pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
95
96
|
{
|
96
97
|
VALUE ret;
|
97
98
|
ret = rb_tainted_str_new( val, len );
|
@@ -106,7 +107,7 @@ pg_bin_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int
|
|
106
107
|
*
|
107
108
|
*/
|
108
109
|
static VALUE
|
109
|
-
pg_bin_dec_to_base64(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
|
110
|
+
pg_bin_dec_to_base64(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
110
111
|
{
|
111
112
|
t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
|
112
113
|
t_pg_coder_dec_func dec_func = pg_coder_dec_func(this->elem, this->comp.format);
|
@@ -130,6 +131,66 @@ pg_bin_dec_to_base64(t_pg_coder *conv, char *val, int len, int tuple, int field,
|
|
130
131
|
return out_value;
|
131
132
|
}
|
132
133
|
|
134
|
+
#define PG_INT64_MIN (-0x7FFFFFFFFFFFFFFFL - 1)
|
135
|
+
#define PG_INT64_MAX 0x7FFFFFFFFFFFFFFFL
|
136
|
+
|
137
|
+
/*
|
138
|
+
* Document-class: PG::BinaryDecoder::Timestamp < PG::SimpleDecoder
|
139
|
+
*
|
140
|
+
* This is a decoder class for conversion of PostgreSQL binary timestamps
|
141
|
+
* to Ruby Time objects.
|
142
|
+
*
|
143
|
+
* The following flags can be used to specify timezone interpretation:
|
144
|
+
* * +PG::Coder::TIMESTAMP_DB_UTC+ : Interpret timestamp as UTC time (default)
|
145
|
+
* * +PG::Coder::TIMESTAMP_DB_LOCAL+ : Interpret timestamp as local time
|
146
|
+
* * +PG::Coder::TIMESTAMP_APP_UTC+ : Return timestamp as UTC time (default)
|
147
|
+
* * +PG::Coder::TIMESTAMP_APP_LOCAL+ : Return timestamp as local time
|
148
|
+
*
|
149
|
+
* Example:
|
150
|
+
* deco = PG::BinaryDecoder::Timestamp.new(flags: PG::Coder::TIMESTAMP_DB_UTC | PG::Coder::TIMESTAMP_APP_LOCAL)
|
151
|
+
* deco.decode("\0"*8) # => 2000-01-01 01:00:00 +0100
|
152
|
+
*/
|
153
|
+
static VALUE
|
154
|
+
pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
|
155
|
+
{
|
156
|
+
int64_t timestamp;
|
157
|
+
struct timespec ts;
|
158
|
+
VALUE t;
|
159
|
+
|
160
|
+
if( len != sizeof(timestamp) ){
|
161
|
+
rb_raise( rb_eTypeError, "wrong data for timestamp converter in tuple %d field %d length %d", tuple, field, len);
|
162
|
+
}
|
163
|
+
|
164
|
+
timestamp = read_nbo64(val);
|
165
|
+
|
166
|
+
switch(timestamp){
|
167
|
+
case PG_INT64_MAX:
|
168
|
+
return rb_str_new2("infinity");
|
169
|
+
case PG_INT64_MIN:
|
170
|
+
return rb_str_new2("-infinity");
|
171
|
+
default:
|
172
|
+
/* PostgreSQL's timestamp is based on year 2000 and Ruby's time is based on 1970.
|
173
|
+
* Adjust the 30 years difference. */
|
174
|
+
ts.tv_sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
|
175
|
+
ts.tv_nsec = (timestamp % 1000000) * 1000;
|
176
|
+
|
177
|
+
#if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T)
|
178
|
+
/* Fast path for time conversion */
|
179
|
+
t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
|
180
|
+
#else
|
181
|
+
t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(ts.tv_sec), LL2NUM(ts.tv_nsec / 1000));
|
182
|
+
if( !(conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL) ) {
|
183
|
+
t = rb_funcall(t, rb_intern("utc"), 0);
|
184
|
+
}
|
185
|
+
#endif
|
186
|
+
if( conv->flags & PG_CODER_TIMESTAMP_DB_LOCAL ) {
|
187
|
+
/* interpret it as local time */
|
188
|
+
t = rb_funcall(t, rb_intern("-"), 1, rb_funcall(t, rb_intern("utc_offset"), 0));
|
189
|
+
}
|
190
|
+
return t;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
133
194
|
/*
|
134
195
|
* Document-class: PG::BinaryDecoder::String < PG::SimpleDecoder
|
135
196
|
*
|
@@ -156,6 +217,8 @@ init_pg_binary_decoder()
|
|
156
217
|
pg_define_coder( "String", pg_text_dec_string, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
|
157
218
|
/* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Bytea", rb_cPG_SimpleDecoder ); */
|
158
219
|
pg_define_coder( "Bytea", pg_bin_dec_bytea, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
|
220
|
+
/* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Timestamp", rb_cPG_SimpleDecoder ); */
|
221
|
+
pg_define_coder( "Timestamp", pg_bin_dec_timestamp, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
|
159
222
|
|
160
223
|
/* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "ToBase64", rb_cPG_CompositeDecoder ); */
|
161
224
|
pg_define_coder( "ToBase64", pg_bin_dec_to_base64, rb_cPG_CompositeDecoder, rb_mPG_BinaryDecoder );
|
data/ext/pg_binary_encoder.c
CHANGED
data/ext/pg_coder.c
CHANGED
@@ -38,6 +38,7 @@ pg_coder_init_encoder( VALUE self )
|
|
38
38
|
this->coder_obj = self;
|
39
39
|
this->oid = 0;
|
40
40
|
this->format = 0;
|
41
|
+
this->flags = 0;
|
41
42
|
rb_iv_set( self, "@name", Qnil );
|
42
43
|
}
|
43
44
|
|
@@ -56,6 +57,7 @@ pg_coder_init_decoder( VALUE self )
|
|
56
57
|
this->coder_obj = self;
|
57
58
|
this->oid = 0;
|
58
59
|
this->format = 0;
|
60
|
+
this->flags = 0;
|
59
61
|
rb_iv_set( self, "@name", Qnil );
|
60
62
|
}
|
61
63
|
|
@@ -192,7 +194,11 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
|
|
192
194
|
if( NIL_P(argv[0]) )
|
193
195
|
return Qnil;
|
194
196
|
|
195
|
-
|
197
|
+
if( this->format == 0 ){
|
198
|
+
val = StringValueCStr(argv[0]);
|
199
|
+
}else{
|
200
|
+
val = StringValuePtr(argv[0]);
|
201
|
+
}
|
196
202
|
if( !this->dec_func ){
|
197
203
|
rb_raise(rb_eRuntimeError, "no decoder function defined");
|
198
204
|
}
|
@@ -265,6 +271,36 @@ pg_coder_format_get(VALUE self)
|
|
265
271
|
return INT2NUM(this->format);
|
266
272
|
}
|
267
273
|
|
274
|
+
/*
|
275
|
+
* call-seq:
|
276
|
+
* coder.flags = Integer
|
277
|
+
*
|
278
|
+
* Set coder specific bitwise OR-ed flags.
|
279
|
+
* See the particular en- or decoder description for available flags.
|
280
|
+
*
|
281
|
+
* The default is +0+.
|
282
|
+
*/
|
283
|
+
static VALUE
|
284
|
+
pg_coder_flags_set(VALUE self, VALUE flags)
|
285
|
+
{
|
286
|
+
t_pg_coder *this = DATA_PTR(self);
|
287
|
+
this->flags = NUM2INT(flags);
|
288
|
+
return flags;
|
289
|
+
}
|
290
|
+
|
291
|
+
/*
|
292
|
+
* call-seq:
|
293
|
+
* coder.flags -> Integer
|
294
|
+
*
|
295
|
+
* Get current bitwise OR-ed coder flags.
|
296
|
+
*/
|
297
|
+
static VALUE
|
298
|
+
pg_coder_flags_get(VALUE self)
|
299
|
+
{
|
300
|
+
t_pg_coder *this = DATA_PTR(self);
|
301
|
+
return INT2NUM(this->flags);
|
302
|
+
}
|
303
|
+
|
268
304
|
/*
|
269
305
|
* call-seq:
|
270
306
|
* coder.needs_quotation = Boolean
|
@@ -403,14 +439,14 @@ pg_coder_enc_func(t_pg_coder *this)
|
|
403
439
|
}
|
404
440
|
|
405
441
|
static VALUE
|
406
|
-
pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
|
442
|
+
pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
|
407
443
|
{
|
408
444
|
VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
|
409
445
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
410
446
|
}
|
411
447
|
|
412
448
|
static VALUE
|
413
|
-
pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
|
449
|
+
pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
|
414
450
|
{
|
415
451
|
VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
|
416
452
|
return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
|
@@ -457,6 +493,19 @@ init_pg_coder()
|
|
457
493
|
rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
|
458
494
|
rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
|
459
495
|
rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
|
496
|
+
rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
|
497
|
+
rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
|
498
|
+
|
499
|
+
/* define flags to be used with PG::Coder#flags= */
|
500
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
|
501
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
|
502
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
|
503
|
+
rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
|
504
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
|
505
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
|
506
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
|
507
|
+
rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
|
508
|
+
|
460
509
|
/*
|
461
510
|
* Name of the coder or the corresponding data type.
|
462
511
|
*
|