pg 0.18.0.pre20141017160319-x64-mingw32 → 0.18.0.pre20141117110243-x64-mingw32
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/ChangeLog +317 -235
- data/History.rdoc +15 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +1 -1
- data/ext/extconf.rb +2 -0
- data/ext/pg.c +66 -0
- data/ext/pg.h +50 -13
- data/ext/pg_binary_decoder.c +3 -3
- data/ext/pg_coder.c +6 -0
- data/ext/pg_connection.c +49 -54
- data/ext/pg_copy_coder.c +13 -29
- data/ext/pg_errors.c +6 -0
- data/ext/pg_result.c +272 -76
- data/ext/pg_text_encoder.c +43 -0
- data/ext/pg_type_map.c +84 -13
- data/ext/pg_type_map_all_strings.c +15 -12
- data/ext/pg_type_map_by_class.c +239 -0
- data/ext/pg_type_map_by_column.c +80 -22
- data/ext/pg_type_map_by_mri_type.c +41 -23
- data/ext/pg_type_map_by_oid.c +51 -19
- data/lib/2.0/pg_ext.so +0 -0
- data/lib/2.1/pg_ext.so +0 -0
- data/lib/pg.rb +2 -2
- data/lib/pg/basic_type_mapping.rb +13 -13
- data/lib/pg/coder.rb +9 -0
- data/lib/x64-mingw32/libpq.dll +0 -0
- 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/History.rdoc
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
== v0.18.0 [unreleased]
|
2
2
|
|
3
|
+
Bugfixes:
|
4
|
+
- Fix OID to Integer mapping (it is unsigned now). #187
|
5
|
+
- Fix possible segfault in conjunction with notice receiver. #185
|
6
|
+
|
3
7
|
Enhancements:
|
4
8
|
|
5
9
|
- Add an extensible type cast system.
|
10
|
+
- A lot of performance improvements.
|
11
|
+
- Return frozen String objects for result field names.
|
12
|
+
- Add PG::Result#stream_each and #stream_each_row as fast helpers for
|
13
|
+
the single row mode.
|
14
|
+
- Add Enumerator variant to PG::Result#each and #each_row.
|
15
|
+
- Add PG::Connection#conninfo and #hostaddr.
|
16
|
+
- Add PG.init_openssl and PG.init_ssl methods.
|
17
|
+
- Force zero termination for all text strings that are given to libpq.
|
18
|
+
It raises an ArgumentError if the string contains a null byte.
|
19
|
+
- Update Windows cross build to PostgreSQL 9.3.
|
20
|
+
|
6
21
|
|
7
22
|
== v0.17.1 [2013-12-18] Michael Granger <ged@FaerieMUD.org>
|
8
23
|
|
data/Manifest.txt
CHANGED
@@ -30,6 +30,7 @@ ext/pg_result.c
|
|
30
30
|
ext/pg_text_decoder.c
|
31
31
|
ext/pg_text_encoder.c
|
32
32
|
ext/pg_type_map_all_strings.c
|
33
|
+
ext/pg_type_map_by_class.c
|
33
34
|
ext/pg_type_map_by_column.c
|
34
35
|
ext/pg_type_map_by_mri_type.c
|
35
36
|
ext/pg_type_map_by_oid.c
|
@@ -73,6 +74,7 @@ spec/helpers.rb
|
|
73
74
|
spec/pg/basic_type_mapping_spec.rb
|
74
75
|
spec/pg/connection_spec.rb
|
75
76
|
spec/pg/result_spec.rb
|
77
|
+
spec/pg/type_map_by_class_spec.rb
|
76
78
|
spec/pg/type_map_by_column_spec.rb
|
77
79
|
spec/pg/type_map_by_mri_type_spec.rb
|
78
80
|
spec/pg/type_map_by_oid_spec.rb
|
data/README.rdoc
CHANGED
@@ -105,7 +105,7 @@ to convert single values to/from their string representation.
|
|
105
105
|
A TypeMap defines which value will be converted by which encoder/decoder.
|
106
106
|
There are different type map strategies, implemented by several derivations
|
107
107
|
of this class. They can be chosen and configured according to the particular
|
108
|
-
needs for type casting.
|
108
|
+
needs for type casting. The default type map is PG::TypeMapAllStrings.
|
109
109
|
|
110
110
|
A type map can be assigned per connection or per query respectively per
|
111
111
|
result set. Type maps can also be used for COPY in and out data streaming.
|
data/ext/extconf.rb
CHANGED
@@ -73,6 +73,7 @@ have_func 'PQlibVersion'
|
|
73
73
|
have_func 'PQping'
|
74
74
|
have_func 'PQsetSingleRowMode'
|
75
75
|
have_func 'PQconninfo'
|
76
|
+
have_func 'PQhostaddr'
|
76
77
|
|
77
78
|
have_func 'rb_encdb_alias'
|
78
79
|
have_func 'rb_enc_alias'
|
@@ -81,6 +82,7 @@ have_func 'rb_thread_call_with_gvl'
|
|
81
82
|
have_func 'rb_thread_fd_select'
|
82
83
|
have_func 'rb_w32_wrap_io_handle'
|
83
84
|
have_func 'rb_str_modify_expand'
|
85
|
+
have_func 'rb_hash_dup'
|
84
86
|
|
85
87
|
have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
|
86
88
|
have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
|
data/ext/pg.c
CHANGED
@@ -333,6 +333,67 @@ pg_s_threadsafe_p(VALUE self)
|
|
333
333
|
return PQisthreadsafe() ? Qtrue : Qfalse;
|
334
334
|
}
|
335
335
|
|
336
|
+
static int
|
337
|
+
pg_to_bool_int(VALUE value)
|
338
|
+
{
|
339
|
+
switch( TYPE(value) ){
|
340
|
+
case T_FALSE:
|
341
|
+
return 0;
|
342
|
+
case T_TRUE:
|
343
|
+
return 1;
|
344
|
+
default:
|
345
|
+
return NUM2INT(value);
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
/*
|
350
|
+
* call-seq:
|
351
|
+
* PG.init_openssl(do_ssl, do_crypto) -> nil
|
352
|
+
*
|
353
|
+
* Allows applications to select which security libraries to initialize.
|
354
|
+
*
|
355
|
+
* If your application initializes libssl and/or libcrypto libraries and libpq is
|
356
|
+
* built with SSL support, you should call PG.init_openssl() to tell libpq that the
|
357
|
+
* libssl and/or libcrypto libraries have been initialized by your application,
|
358
|
+
* so that libpq will not also initialize those libraries. See
|
359
|
+
* http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html for details on the SSL API.
|
360
|
+
*
|
361
|
+
* When do_ssl is +true+, libpq will initialize the OpenSSL library before first
|
362
|
+
* opening a database connection. When do_crypto is +true+, the libcrypto library
|
363
|
+
* will be initialized. By default (if PG.init_openssl() is not called), both libraries
|
364
|
+
* are initialized. When SSL support is not compiled in, this function is present but does nothing.
|
365
|
+
*
|
366
|
+
* If your application uses and initializes either OpenSSL or its underlying libcrypto library,
|
367
|
+
* you must call this function with +false+ for the appropriate parameter(s) before first opening
|
368
|
+
* a database connection. Also be sure that you have done that initialization before opening a
|
369
|
+
* database connection.
|
370
|
+
*
|
371
|
+
*/
|
372
|
+
static VALUE
|
373
|
+
pg_s_init_openssl(VALUE self, VALUE do_ssl, VALUE do_crypto)
|
374
|
+
{
|
375
|
+
UNUSED( self );
|
376
|
+
PQinitOpenSSL(pg_to_bool_int(do_ssl), pg_to_bool_int(do_crypto));
|
377
|
+
return Qnil;
|
378
|
+
}
|
379
|
+
|
380
|
+
|
381
|
+
/*
|
382
|
+
* call-seq:
|
383
|
+
* PG.init_ssl(do_ssl) -> nil
|
384
|
+
*
|
385
|
+
* Allows applications to select which security libraries to initialize.
|
386
|
+
*
|
387
|
+
* This function is equivalent to <tt>PG.init_openssl(do_ssl, do_ssl)</tt> . It is sufficient for
|
388
|
+
* applications that initialize both or neither of OpenSSL and libcrypto.
|
389
|
+
*/
|
390
|
+
static VALUE
|
391
|
+
pg_s_init_ssl(VALUE self, VALUE do_ssl)
|
392
|
+
{
|
393
|
+
UNUSED( self );
|
394
|
+
PQinitSSL(pg_to_bool_int(do_ssl));
|
395
|
+
return Qnil;
|
396
|
+
}
|
336
397
|
|
337
398
|
|
338
399
|
/**************************************************************************
|
@@ -355,6 +416,10 @@ Init_pg_ext()
|
|
355
416
|
SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
|
356
417
|
SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
|
357
418
|
|
419
|
+
rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
|
420
|
+
rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
|
421
|
+
|
422
|
+
|
358
423
|
/****** PG::Connection CLASS CONSTANTS: Connection Status ******/
|
359
424
|
|
360
425
|
/* Connection succeeded */
|
@@ -586,6 +651,7 @@ Init_pg_ext()
|
|
586
651
|
init_pg_errors();
|
587
652
|
init_pg_type_map();
|
588
653
|
init_pg_type_map_all_strings();
|
654
|
+
init_pg_type_map_by_class();
|
589
655
|
init_pg_type_map_by_column();
|
590
656
|
init_pg_type_map_by_mri_type();
|
591
657
|
init_pg_type_map_by_oid();
|
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
@@ -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_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
@@ -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
|