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.
@@ -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