pg 0.18.0.pre20141017160319 → 0.18.0.pre20141117110243
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/ChangeLog +213 -15
- data/History.rdoc +15 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +1 -1
- data/Rakefile +0 -17
- data/ext/extconf.rb +2 -0
- data/ext/pg.c +67 -1
- data/ext/pg.h +50 -13
- data/ext/pg_binary_decoder.c +4 -4
- data/ext/pg_binary_encoder.c +1 -1
- data/ext/pg_coder.c +6 -0
- data/ext/pg_connection.c +50 -55
- data/ext/pg_copy_coder.c +13 -29
- data/ext/pg_errors.c +6 -0
- data/ext/pg_result.c +273 -77
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +44 -1
- data/ext/pg_type_map.c +85 -14
- data/ext/pg_type_map_all_strings.c +16 -13
- data/ext/pg_type_map_by_class.c +239 -0
- data/ext/pg_type_map_by_column.c +81 -23
- data/ext/pg_type_map_by_mri_type.c +42 -24
- data/ext/pg_type_map_by_oid.c +52 -20
- data/ext/util.c +1 -1
- data/lib/pg.rb +3 -3
- data/lib/pg/basic_type_mapping.rb +13 -13
- data/lib/pg/coder.rb +9 -0
- data/sample/disk_usage_report.rb +1 -1
- data/sample/pg_statistics.rb +1 -1
- data/sample/replication_monitor.rb +1 -1
- data/spec/helpers.rb +5 -3
- data/spec/pg/basic_type_mapping_spec.rb +1 -1
- data/spec/pg/connection_spec.rb +16 -5
- data/spec/pg/result_spec.rb +77 -3
- data/spec/pg/type_map_by_class_spec.rb +138 -0
- data/spec/pg/type_map_by_column_spec.rb +87 -0
- data/spec/pg/type_map_by_mri_type_spec.rb +14 -0
- data/spec/pg/type_map_by_oid_spec.rb +21 -0
- data/spec/pg/type_spec.rb +27 -7
- data/spec/pg_spec.rb +14 -0
- metadata +24 -21
- metadata.gz.sig +0 -0
data/ext/pg.h
CHANGED
@@ -90,6 +90,15 @@
|
|
90
90
|
typedef intptr_t native_int;
|
91
91
|
#endif
|
92
92
|
|
93
|
+
#ifndef RETURN_SIZED_ENUMERATOR
|
94
|
+
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR((obj), (argc), (argv))
|
95
|
+
#endif
|
96
|
+
|
97
|
+
#ifndef HAVE_RB_HASH_DUP
|
98
|
+
/* Rubinius doesn't define rb_hash_dup() */
|
99
|
+
#define rb_hash_dup(tuple) rb_funcall((tuple), rb_intern("dup"), 0)
|
100
|
+
#endif
|
101
|
+
|
93
102
|
#ifndef timeradd
|
94
103
|
#define timeradd(a, b, result) \
|
95
104
|
do { \
|
@@ -171,6 +180,19 @@ typedef struct {
|
|
171
180
|
* 1 = PGresult is cleared internally by libpq
|
172
181
|
*/
|
173
182
|
int autoclear;
|
183
|
+
|
184
|
+
/* Number of fields in fnames[] .
|
185
|
+
* Set to -1 if fnames[] is not yet initialized.
|
186
|
+
*/
|
187
|
+
int nfields;
|
188
|
+
|
189
|
+
/* Prefilled tuple Hash with fnames[] as keys. */
|
190
|
+
VALUE tuple_hash;
|
191
|
+
|
192
|
+
/* List of field names as frozen String objects.
|
193
|
+
* Only valid if nfields != -1
|
194
|
+
*/
|
195
|
+
VALUE fnames[0];
|
174
196
|
} t_pg_result;
|
175
197
|
|
176
198
|
|
@@ -179,8 +201,8 @@ typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
|
|
179
201
|
typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
|
180
202
|
typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
|
181
203
|
typedef int (* t_pg_fit_to_copy_get)(VALUE);
|
182
|
-
typedef VALUE (* t_pg_typecast_result)(VALUE, int, int);
|
183
|
-
typedef t_pg_coder *(* t_pg_typecast_query_param)(
|
204
|
+
typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
205
|
+
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
184
206
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
185
207
|
|
186
208
|
struct pg_coder {
|
@@ -199,12 +221,15 @@ typedef struct {
|
|
199
221
|
} t_pg_composite_coder;
|
200
222
|
|
201
223
|
struct pg_typemap {
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
224
|
+
struct pg_typemap_funcs {
|
225
|
+
t_pg_fit_to_result fit_to_result;
|
226
|
+
t_pg_fit_to_query fit_to_query;
|
227
|
+
t_pg_fit_to_copy_get fit_to_copy_get;
|
228
|
+
t_pg_typecast_result typecast_result_value;
|
229
|
+
t_pg_typecast_query_param typecast_query_param;
|
230
|
+
t_pg_typecast_copy_get typecast_copy_get;
|
231
|
+
} funcs;
|
232
|
+
VALUE default_typemap;
|
208
233
|
};
|
209
234
|
|
210
235
|
typedef struct {
|
@@ -227,12 +252,16 @@ extern VALUE rb_ePGerror;
|
|
227
252
|
extern VALUE rb_eServerError;
|
228
253
|
extern VALUE rb_eUnableToSend;
|
229
254
|
extern VALUE rb_eConnectionBad;
|
255
|
+
extern VALUE rb_eInvalidResultStatus;
|
256
|
+
extern VALUE rb_eNoResultError;
|
257
|
+
extern VALUE rb_eInvalidChangeOfResultFields;
|
230
258
|
extern VALUE rb_mPGconstants;
|
231
259
|
extern VALUE rb_cPGconn;
|
232
260
|
extern VALUE rb_cPGresult;
|
233
261
|
extern VALUE rb_hErrors;
|
234
262
|
extern VALUE rb_cTypeMap;
|
235
263
|
extern VALUE rb_cTypeMapAllStrings;
|
264
|
+
extern VALUE rb_mDefaultTypeMappable;
|
236
265
|
extern VALUE rb_cPG_Coder;
|
237
266
|
extern VALUE rb_cPG_SimpleEncoder;
|
238
267
|
extern VALUE rb_cPG_SimpleDecoder;
|
@@ -245,9 +274,11 @@ extern VALUE rb_mPG_TextEncoder;
|
|
245
274
|
extern VALUE rb_mPG_TextDecoder;
|
246
275
|
extern VALUE rb_mPG_BinaryEncoder;
|
247
276
|
extern VALUE rb_mPG_BinaryDecoder;
|
248
|
-
extern
|
277
|
+
extern VALUE rb_mPG_BinaryFormatting;
|
278
|
+
extern const struct pg_typemap_funcs pg_tmbc_funcs;
|
279
|
+
extern const struct pg_typemap_funcs pg_typemap_funcs;
|
249
280
|
|
250
|
-
extern VALUE
|
281
|
+
extern VALUE pg_typemap_all_strings;
|
251
282
|
|
252
283
|
/***************************************************************************
|
253
284
|
* MACROS
|
@@ -267,6 +298,7 @@ void init_pg_result _(( void ));
|
|
267
298
|
void init_pg_errors _(( void ));
|
268
299
|
void init_pg_type_map _(( void ));
|
269
300
|
void init_pg_type_map_all_strings _(( void ));
|
301
|
+
void init_pg_type_map_by_class _(( void ));
|
270
302
|
void init_pg_type_map_by_column _(( void ));
|
271
303
|
void init_pg_type_map_by_mri_type _(( void ));
|
272
304
|
void init_pg_type_map_by_oid _(( void ));
|
@@ -308,8 +340,8 @@ char *pg_rb_str_ensure_capa _(( VALUE, long, char *,
|
|
308
340
|
VALUE pg_typemap_fit_to_result _(( VALUE, VALUE ));
|
309
341
|
VALUE pg_typemap_fit_to_query _(( VALUE, VALUE ));
|
310
342
|
int pg_typemap_fit_to_copy_get _(( VALUE ));
|
311
|
-
VALUE pg_typemap_result_value _(( VALUE, int, int ));
|
312
|
-
t_pg_coder *pg_typemap_typecast_query_param _((
|
343
|
+
VALUE pg_typemap_result_value _(( t_typemap *, VALUE, int, int ));
|
344
|
+
t_pg_coder *pg_typemap_typecast_query_param _(( t_typemap *, VALUE, int ));
|
313
345
|
VALUE pg_typemap_typecast_copy_get _(( t_typemap *, VALUE, int, int, int ));
|
314
346
|
|
315
347
|
PGconn *pg_get_pgconn _(( VALUE ));
|
@@ -327,7 +359,12 @@ VALUE pg_result_clear _(( VALUE ));
|
|
327
359
|
static inline t_pg_result *
|
328
360
|
pgresult_get_this( VALUE self )
|
329
361
|
{
|
330
|
-
|
362
|
+
t_pg_result *this = DATA_PTR(self);
|
363
|
+
|
364
|
+
if( this == NULL )
|
365
|
+
rb_raise(rb_ePGerror, "result has been cleared");
|
366
|
+
|
367
|
+
return this;
|
331
368
|
}
|
332
369
|
|
333
370
|
|
data/ext/pg_binary_decoder.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -83,9 +83,9 @@ pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int
|
|
83
83
|
/*
|
84
84
|
* Document-class: PG::BinaryDecoder::Bytea < PG::SimpleDecoder
|
85
85
|
*
|
86
|
-
* This
|
87
|
-
*
|
88
|
-
*
|
86
|
+
* This decoder class delivers the data received from the server as binary String object.
|
87
|
+
* It is therefore suitable for conversion of PostgreSQL bytea data as well as any other
|
88
|
+
* data in binary format.
|
89
89
|
*
|
90
90
|
*/
|
91
91
|
VALUE
|
data/ext/pg_binary_encoder.c
CHANGED
data/ext/pg_coder.c
CHANGED
@@ -12,6 +12,7 @@ VALUE rb_cPG_SimpleDecoder;
|
|
12
12
|
VALUE rb_cPG_CompositeCoder;
|
13
13
|
VALUE rb_cPG_CompositeEncoder;
|
14
14
|
VALUE rb_cPG_CompositeDecoder;
|
15
|
+
VALUE rb_mPG_BinaryFormatting;
|
15
16
|
static ID s_id_encode;
|
16
17
|
static ID s_id_decode;
|
17
18
|
static ID s_id_CFUNC;
|
@@ -348,6 +349,9 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
|
|
348
349
|
{
|
349
350
|
VALUE cfunc_obj = Data_Wrap_Struct( rb_cObject, NULL, NULL, func );
|
350
351
|
VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
|
352
|
+
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
|
353
|
+
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
|
354
|
+
|
351
355
|
rb_define_const( coder_klass, "CFUNC", cfunc_obj );
|
352
356
|
|
353
357
|
RB_GC_GUARD(cfunc_obj);
|
@@ -470,4 +474,6 @@ init_pg_coder()
|
|
470
474
|
/* Document-class: PG::CompositeDecoder < PG::CompositeCoder */
|
471
475
|
rb_cPG_CompositeDecoder = rb_define_class_under( rb_mPG, "CompositeDecoder", rb_cPG_CompositeCoder );
|
472
476
|
rb_define_alloc_func( rb_cPG_CompositeDecoder, pg_composite_decoder_allocate );
|
477
|
+
|
478
|
+
rb_mPG_BinaryFormatting = rb_define_module_under( rb_cPG_Coder, "BinaryFormatting");
|
473
479
|
}
|
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -66,6 +66,10 @@ pg_get_connection_safe( VALUE self )
|
|
66
66
|
|
67
67
|
/*
|
68
68
|
* Fetch the PGconn data pointer and check it for sanity.
|
69
|
+
*
|
70
|
+
* Note: This function is used externally by the sequel_pg gem,
|
71
|
+
* so do changes carefully.
|
72
|
+
*
|
69
73
|
*/
|
70
74
|
PGconn *
|
71
75
|
pg_get_pgconn( VALUE self )
|
@@ -189,8 +193,8 @@ pgconn_s_allocate( VALUE klass )
|
|
189
193
|
this->socket_io = Qnil;
|
190
194
|
this->notice_receiver = Qnil;
|
191
195
|
this->notice_processor = Qnil;
|
192
|
-
this->type_map_for_queries =
|
193
|
-
this->type_map_for_results =
|
196
|
+
this->type_map_for_queries = pg_typemap_all_strings;
|
197
|
+
this->type_map_for_results = pg_typemap_all_strings;
|
194
198
|
this->encoder_for_put_copy_data = Qnil;
|
195
199
|
this->decoder_for_get_copy_data = Qnil;
|
196
200
|
this->trace_stream = Qnil;
|
@@ -623,6 +627,22 @@ pgconn_host(VALUE self)
|
|
623
627
|
return rb_tainted_str_new2(host);
|
624
628
|
}
|
625
629
|
|
630
|
+
#ifdef HAVE_PQHOSTADDR
|
631
|
+
/*
|
632
|
+
* call-seq:
|
633
|
+
* conn.hostaddr()
|
634
|
+
*
|
635
|
+
* Returns the server numeric IP address of the connection.
|
636
|
+
*/
|
637
|
+
static VALUE
|
638
|
+
pgconn_hostaddr(VALUE self)
|
639
|
+
{
|
640
|
+
char *hostaddr = PQhostaddr(pg_get_pgconn(self));
|
641
|
+
if (!hostaddr) return Qnil;
|
642
|
+
return rb_tainted_str_new2(hostaddr);
|
643
|
+
}
|
644
|
+
#endif
|
645
|
+
|
626
646
|
/*
|
627
647
|
* call-seq:
|
628
648
|
* conn.port()
|
@@ -1049,7 +1069,7 @@ alloc_typecast_buf( VALUE *typecast_heap_chain, int len )
|
|
1049
1069
|
|
1050
1070
|
|
1051
1071
|
static int
|
1052
|
-
|
1072
|
+
alloc_query_params(struct query_params_data *paramsData)
|
1053
1073
|
{
|
1054
1074
|
VALUE param_value;
|
1055
1075
|
t_typemap *p_typemap;
|
@@ -1059,7 +1079,14 @@ alloc_query_params1(struct query_params_data *paramsData)
|
|
1059
1079
|
unsigned int required_pool_size;
|
1060
1080
|
char *memory_pool;
|
1061
1081
|
|
1062
|
-
|
1082
|
+
Check_Type(paramsData->params, T_ARRAY);
|
1083
|
+
|
1084
|
+
p_typemap = DATA_PTR( paramsData->typemap );
|
1085
|
+
p_typemap->funcs.fit_to_query( paramsData->typemap, paramsData->params );
|
1086
|
+
|
1087
|
+
paramsData->heap_pool = Qnil;
|
1088
|
+
paramsData->typecast_heap_chain = Qnil;
|
1089
|
+
paramsData->gc_array = Qnil;
|
1063
1090
|
|
1064
1091
|
nParams = (int)RARRAY_LEN(paramsData->params);
|
1065
1092
|
|
@@ -1096,7 +1123,7 @@ alloc_query_params1(struct query_params_data *paramsData)
|
|
1096
1123
|
paramsData->types[i] = 0;
|
1097
1124
|
|
1098
1125
|
/* Let the given typemap select a coder for this param */
|
1099
|
-
conv = p_typemap->typecast_query_param(
|
1126
|
+
conv = p_typemap->funcs.typecast_query_param(p_typemap, param_value, i);
|
1100
1127
|
|
1101
1128
|
/* Using a coder object for the param_value? Then set it's format code and oid. */
|
1102
1129
|
if( conv ){
|
@@ -1136,8 +1163,11 @@ alloc_query_params1(struct query_params_data *paramsData)
|
|
1136
1163
|
if( paramsData->formats[i] == 0 )
|
1137
1164
|
StringValueCStr(intermediate);
|
1138
1165
|
/* In case a new string object was generated, make sure it doesn't get freed by the GC */
|
1139
|
-
if( intermediate != param_value )
|
1166
|
+
if( intermediate != param_value ){
|
1167
|
+
if( NIL_P(paramsData->gc_array) )
|
1168
|
+
paramsData->gc_array = rb_ary_new();
|
1140
1169
|
rb_ary_push(paramsData->gc_array, intermediate);
|
1170
|
+
}
|
1141
1171
|
paramsData->values[i] = RSTRING_PTR(intermediate);
|
1142
1172
|
paramsData->lengths[i] = RSTRING_LENINT(intermediate);
|
1143
1173
|
|
@@ -1176,28 +1206,6 @@ free_query_params(struct query_params_data *paramsData)
|
|
1176
1206
|
/* currently nothing to free */
|
1177
1207
|
}
|
1178
1208
|
|
1179
|
-
static int
|
1180
|
-
alloc_query_params(struct query_params_data *paramsData)
|
1181
|
-
{
|
1182
|
-
int nParams;
|
1183
|
-
Check_Type(paramsData->params, T_ARRAY);
|
1184
|
-
|
1185
|
-
if( NIL_P(paramsData->typemap) ){
|
1186
|
-
/* We don't need to call fit_to_query for pg_default_typemap. It does nothing. */
|
1187
|
-
paramsData->typemap = pg_default_typemap;
|
1188
|
-
} else {
|
1189
|
-
t_typemap *p_typemap = DATA_PTR( paramsData->typemap );
|
1190
|
-
paramsData->typemap = p_typemap->fit_to_query( paramsData->typemap, paramsData->params );
|
1191
|
-
}
|
1192
|
-
|
1193
|
-
paramsData->heap_pool = Qnil;
|
1194
|
-
paramsData->typecast_heap_chain = Qnil;
|
1195
|
-
paramsData->gc_array = rb_ary_new();
|
1196
|
-
|
1197
|
-
nParams = alloc_query_params1(paramsData);
|
1198
|
-
return nParams;
|
1199
|
-
}
|
1200
|
-
|
1201
1209
|
void
|
1202
1210
|
pgconn_query_assign_typemap( VALUE self, struct query_params_data *paramsData )
|
1203
1211
|
{
|
@@ -3609,9 +3617,7 @@ pgconn_set_default_encoding( VALUE self )
|
|
3609
3617
|
*
|
3610
3618
|
* Set the default TypeMap that is used for type casts of query bind parameters.
|
3611
3619
|
*
|
3612
|
-
* +typemap+
|
3613
|
-
* * a kind of PG::TypeMap
|
3614
|
-
* * +nil+ - to type cast all query params by #to_str.
|
3620
|
+
* +typemap+ must be a kind of PG::TypeMap .
|
3615
3621
|
*
|
3616
3622
|
*/
|
3617
3623
|
static VALUE
|
@@ -3619,13 +3625,11 @@ pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
|
|
3619
3625
|
{
|
3620
3626
|
t_pg_connection *this = pg_get_connection( self );
|
3621
3627
|
|
3622
|
-
if( typemap
|
3623
|
-
|
3624
|
-
|
3625
|
-
rb_obj_classname( typemap ) );
|
3626
|
-
}
|
3627
|
-
Check_Type(typemap, T_DATA);
|
3628
|
+
if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
|
3629
|
+
rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
|
3630
|
+
rb_obj_classname( typemap ) );
|
3628
3631
|
}
|
3632
|
+
Check_Type(typemap, T_DATA);
|
3629
3633
|
this->type_map_for_queries = typemap;
|
3630
3634
|
|
3631
3635
|
return typemap;
|
@@ -3638,10 +3642,6 @@ pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
|
|
3638
3642
|
* Returns the default TypeMap that is currently set for type casts of query
|
3639
3643
|
* bind parameters.
|
3640
3644
|
*
|
3641
|
-
* Returns either:
|
3642
|
-
* * a kind of PG::TypeMap or
|
3643
|
-
* * +nil+ - when no type map is set.
|
3644
|
-
*
|
3645
3645
|
*/
|
3646
3646
|
static VALUE
|
3647
3647
|
pgconn_type_map_for_queries_get(VALUE self)
|
@@ -3657,9 +3657,7 @@ pgconn_type_map_for_queries_get(VALUE self)
|
|
3657
3657
|
*
|
3658
3658
|
* Set the default TypeMap that is used for type casts of result values.
|
3659
3659
|
*
|
3660
|
-
* +typemap+
|
3661
|
-
* * a kind of PG::TypeMap
|
3662
|
-
* * +nil+ - to type cast all result values to String.
|
3660
|
+
* +typemap+ must be a kind of PG::TypeMap .
|
3663
3661
|
*
|
3664
3662
|
*/
|
3665
3663
|
static VALUE
|
@@ -3667,13 +3665,11 @@ pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
|
|
3667
3665
|
{
|
3668
3666
|
t_pg_connection *this = pg_get_connection( self );
|
3669
3667
|
|
3670
|
-
if( typemap
|
3671
|
-
|
3672
|
-
|
3673
|
-
rb_obj_classname( typemap ) );
|
3674
|
-
}
|
3675
|
-
Check_Type(typemap, T_DATA);
|
3668
|
+
if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
|
3669
|
+
rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
|
3670
|
+
rb_obj_classname( typemap ) );
|
3676
3671
|
}
|
3672
|
+
Check_Type(typemap, T_DATA);
|
3677
3673
|
this->type_map_for_results = typemap;
|
3678
3674
|
|
3679
3675
|
return typemap;
|
@@ -3685,10 +3681,6 @@ pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
|
|
3685
3681
|
*
|
3686
3682
|
* Returns the default TypeMap that is currently set for type casts of result values.
|
3687
3683
|
*
|
3688
|
-
* Returns either:
|
3689
|
-
* * a kind of PG::TypeMap or
|
3690
|
-
* * +nil+ - when no type map is set.
|
3691
|
-
*
|
3692
3684
|
*/
|
3693
3685
|
static VALUE
|
3694
3686
|
pgconn_type_map_for_results_get(VALUE self)
|
@@ -3843,6 +3835,9 @@ init_pg_connection()
|
|
3843
3835
|
rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
|
3844
3836
|
rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
|
3845
3837
|
rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
|
3838
|
+
#ifdef HAVE_PQHOSTADDR
|
3839
|
+
rb_define_method(rb_cPGconn, "hostaddr", pgconn_hostaddr, 0);
|
3840
|
+
#endif
|
3846
3841
|
rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
|
3847
3842
|
rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
|
3848
3843
|
#ifdef HAVE_PQCONNINFO
|
data/ext/pg_copy_coder.c
CHANGED
@@ -33,7 +33,7 @@ pg_copycoder_encoder_allocate( VALUE klass )
|
|
33
33
|
t_pg_copycoder *this;
|
34
34
|
VALUE self = Data_Make_Struct( klass, t_pg_copycoder, pg_copycoder_mark, -1, this );
|
35
35
|
pg_coder_init_encoder( self );
|
36
|
-
this->typemap =
|
36
|
+
this->typemap = pg_typemap_all_strings;
|
37
37
|
this->delimiter = '\t';
|
38
38
|
this->null_string = rb_str_new_cstr("\\N");
|
39
39
|
return self;
|
@@ -45,7 +45,7 @@ pg_copycoder_decoder_allocate( VALUE klass )
|
|
45
45
|
t_pg_copycoder *this;
|
46
46
|
VALUE self = Data_Make_Struct( klass, t_pg_copycoder, pg_copycoder_mark, -1, this );
|
47
47
|
pg_coder_init_decoder( self );
|
48
|
-
this->typemap =
|
48
|
+
this->typemap = pg_typemap_all_strings;
|
49
49
|
this->delimiter = '\t';
|
50
50
|
this->null_string = rb_str_new_cstr("\\N");
|
51
51
|
return self;
|
@@ -112,10 +112,10 @@ pg_copycoder_null_string_get(VALUE self)
|
|
112
112
|
* call-seq:
|
113
113
|
* coder.type_map = map
|
114
114
|
*
|
115
|
-
* +map+
|
116
|
-
*
|
117
|
-
*
|
118
|
-
*
|
115
|
+
* +map+ must be a kind of PG::TypeMap .
|
116
|
+
*
|
117
|
+
* Defaults to a PG::TypeMapAllStrings , so that PG::TextEncoder::String respectively
|
118
|
+
* PG::TextDecoder::String is used for encoding/decoding of all columns.
|
119
119
|
*
|
120
120
|
*/
|
121
121
|
static VALUE
|
@@ -123,7 +123,7 @@ pg_copycoder_type_map_set(VALUE self, VALUE type_map)
|
|
123
123
|
{
|
124
124
|
t_pg_copycoder *this = DATA_PTR( self );
|
125
125
|
|
126
|
-
if ( !
|
126
|
+
if ( !rb_obj_is_kind_of(type_map, rb_cTypeMap) ){
|
127
127
|
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
|
128
128
|
rb_obj_classname( type_map ) );
|
129
129
|
}
|
@@ -136,10 +136,6 @@ pg_copycoder_type_map_set(VALUE self, VALUE type_map)
|
|
136
136
|
* call-seq:
|
137
137
|
* coder.type_map -> PG::TypeMap
|
138
138
|
*
|
139
|
-
* Returns either:
|
140
|
-
* * a kind of PG::TypeMap
|
141
|
-
* * +nil+ - use String coder only.
|
142
|
-
*
|
143
139
|
*/
|
144
140
|
static VALUE
|
145
141
|
pg_copycoder_type_map_get(VALUE self)
|
@@ -169,22 +165,14 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
169
165
|
{
|
170
166
|
t_pg_copycoder *this = (t_pg_copycoder *)conv;
|
171
167
|
t_pg_coder_enc_func enc_func;
|
172
|
-
VALUE typemap;
|
173
168
|
static t_pg_coder *p_elem_coder;
|
174
169
|
int i;
|
175
170
|
t_typemap *p_typemap;
|
176
171
|
char *current_out;
|
177
172
|
char *end_capa_ptr;
|
178
173
|
|
179
|
-
|
180
|
-
|
181
|
-
/* We don't need to call fit_to_query for pg_default_typemap. It does nothing. */
|
182
|
-
typemap = pg_default_typemap;
|
183
|
-
} else {
|
184
|
-
p_typemap = DATA_PTR( this->typemap );
|
185
|
-
typemap = p_typemap->fit_to_query( this->typemap, value );
|
186
|
-
p_typemap = DATA_PTR( typemap );
|
187
|
-
}
|
174
|
+
p_typemap = DATA_PTR( this->typemap );
|
175
|
+
p_typemap->funcs.fit_to_query( this->typemap, value );
|
188
176
|
|
189
177
|
/* Allocate a new string with embedded capacity and realloc exponential when needed. */
|
190
178
|
PG_RB_STR_NEW( *intermediate, current_out, end_capa_ptr );
|
@@ -211,7 +199,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
211
199
|
current_out += RSTRING_LEN(this->null_string);
|
212
200
|
break;
|
213
201
|
default:
|
214
|
-
p_elem_coder = p_typemap->typecast_query_param(
|
202
|
+
p_elem_coder = p_typemap->funcs.typecast_query_param(p_typemap, entry, i);
|
215
203
|
enc_func = pg_coder_enc_func(p_elem_coder);
|
216
204
|
|
217
205
|
/* 1st pass for retiving the required memory space */
|
@@ -337,12 +325,8 @@ pg_text_dec_copy_row(t_pg_coder *conv, char *input_line, int len, int _tuple, in
|
|
337
325
|
char *end_capa_ptr;
|
338
326
|
t_typemap *p_typemap;
|
339
327
|
|
340
|
-
|
341
|
-
|
342
|
-
} else {
|
343
|
-
p_typemap = DATA_PTR( this->typemap );
|
344
|
-
}
|
345
|
-
expected_fields = p_typemap->fit_to_copy_get( this->typemap );
|
328
|
+
p_typemap = DATA_PTR( this->typemap );
|
329
|
+
expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
|
346
330
|
|
347
331
|
/* The received input string will probably have this->nfields fields. */
|
348
332
|
array = rb_ary_new2(expected_fields);
|
@@ -504,7 +488,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, char *input_line, int len, int _tuple, in
|
|
504
488
|
VALUE field_value;
|
505
489
|
|
506
490
|
rb_str_set_len( field_str, output_ptr - RSTRING_PTR(field_str) );
|
507
|
-
field_value = p_typemap->typecast_copy_get( p_typemap, field_str, fieldno, 0, enc_idx );
|
491
|
+
field_value = p_typemap->funcs.typecast_copy_get( p_typemap, field_str, fieldno, 0, enc_idx );
|
508
492
|
|
509
493
|
rb_ary_push(array, field_value);
|
510
494
|
|