pg 0.18.0.pre20141017160319-x86-mingw32 → 0.18.0.pre20141117110243-x86-mingw32
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 +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/1.9/pg_ext.so +0 -0
- data/lib/2.0/pg_ext.so +0 -0
- data/lib/2.1/pg_ext.so +0 -0
- data/lib/i386-mingw32/libpq.dll +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/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
|