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.
@@ -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
 
@@ -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
@@ -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.
@@ -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)(VALUE, VALUE, int);
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
- t_pg_fit_to_result fit_to_result;
203
- t_pg_fit_to_query fit_to_query;
204
- t_pg_fit_to_copy_get fit_to_copy_get;
205
- t_pg_typecast_result typecast_result_value;
206
- t_pg_typecast_query_param typecast_query_param;
207
- t_pg_typecast_copy_get typecast_copy_get;
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 const t_typemap pg_tmbc_default_typemap;
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 pg_default_typemap;
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 _(( VALUE, VALUE, int ));
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
- return DATA_PTR(self);
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
 
@@ -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 is a decoder class for conversion of PostgreSQL binary data (bytea)
87
- * to binary Ruby String objects or some other Ruby object, if a #elements_type
88
- * decoder was defined.
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
@@ -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
  }
@@ -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 = Qnil;
193
- this->type_map_for_results = Qnil;
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
- alloc_query_params1(struct query_params_data *paramsData)
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
- Data_Get_Struct( paramsData->typemap, t_typemap, p_typemap);
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(paramsData->typemap, param_value, i);
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+ can be:
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 != Qnil ){
3623
- if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
3624
- rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
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+ can be:
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 != Qnil ){
3671
- if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
3672
- rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
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