pg 0.18.0.pre20141117110243-x86-mingw32 → 0.18.0-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.
@@ -313,8 +313,8 @@ pg_text_dec_identifier(t_pg_coder *conv, char *val, int len, int tuple, int fiel
313
313
  VALUE elem;
314
314
  int word_index = 0;
315
315
  int index;
316
- /* create a buffer of the same length, as that will be the worst case */
317
- char *word = xmalloc(len + 1);
316
+ /* Use a buffer of the same length, as that will be the worst case */
317
+ char word[len + 1];
318
318
 
319
319
  /* The current character in the input string. */
320
320
  char c;
@@ -356,8 +356,6 @@ pg_text_dec_identifier(t_pg_coder *conv, char *val, int len, int tuple, int fiel
356
356
  elem = dec_func(conv, word, word_index, tuple, field, enc_idx);
357
357
  rb_ary_push(array, elem);
358
358
 
359
- free(word);
360
-
361
359
  return array;
362
360
  }
363
361
 
@@ -47,8 +47,8 @@
47
47
  VALUE rb_mPG_TextEncoder;
48
48
  static ID s_id_encode;
49
49
  static ID s_id_to_i;
50
- static VALUE hash_false_values;
51
50
 
51
+ static int pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate);
52
52
 
53
53
  VALUE
54
54
  pg_obj_to_i( VALUE value )
@@ -68,38 +68,37 @@ pg_obj_to_i( VALUE value )
68
68
  *
69
69
  * This is the encoder class for the PostgreSQL bool type.
70
70
  *
71
- * Ruby values false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off' and 'OFF'
72
- * are encoded as SQL +FALSE+ value. nil is sent as SQL +NULL+.
73
- * Any other values are encoded as SQL +TRUE+ .
71
+ * Ruby value false is encoded as SQL +FALSE+ value.
72
+ * Ruby value true is encoded as SQL +TRUE+ value.
73
+ * Any other value is sent as it's string representation.
74
74
  *
75
75
  */
76
76
  static int
77
- pg_text_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
77
+ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate)
78
78
  {
79
- if(out){
80
- switch( TYPE(value) ){
81
- case T_FALSE:
82
- *out = 'f';
83
- break;
84
- case T_FIXNUM:
85
- case T_BIGNUM:
86
- if( NUM2LONG(value) == 0 ){
87
- *out = 'f';
88
- } else {
89
- *out = 't';
90
- }
91
- break;
92
- case T_STRING:
93
- if( rb_hash_lookup(hash_false_values, value) == Qtrue ){
94
- *out = 'f';
95
- break;
96
- }
97
- /* fall through */
98
- default:
99
- *out = 't';
100
- }
79
+ switch( TYPE(value) ){
80
+ case T_FALSE:
81
+ if(out) *out = 'f';
82
+ return 1;
83
+ case T_TRUE:
84
+ if(out) *out = 't';
85
+ return 1;
86
+ case T_FIXNUM:
87
+ case T_BIGNUM:
88
+ if( NUM2LONG(value) == 0 ){
89
+ if(out) *out = '0';
90
+ return 1;
91
+ } else if( NUM2LONG(value) == 1 ){
92
+ if(out) *out = '1';
93
+ return 1;
94
+ } else {
95
+ return pg_text_enc_integer(this, value, out, intermediate);
96
+ }
97
+ default:
98
+ return pg_coder_enc_to_s(this, value, out, intermediate);
101
99
  }
102
- return 1;
100
+ /* never reached */
101
+ return 0;
103
102
  }
104
103
 
105
104
 
@@ -638,16 +637,6 @@ init_pg_text_encoder()
638
637
  s_id_encode = rb_intern("encode");
639
638
  s_id_to_i = rb_intern("to_i");
640
639
 
641
- hash_false_values = rb_hash_new();
642
- rb_gc_register_address( &hash_false_values );
643
- rb_hash_aset( hash_false_values, rb_str_new2( "0" ), Qtrue );
644
- rb_hash_aset( hash_false_values, rb_str_new2( "f" ), Qtrue );
645
- rb_hash_aset( hash_false_values, rb_str_new2( "F" ), Qtrue );
646
- rb_hash_aset( hash_false_values, rb_str_new2( "false" ), Qtrue );
647
- rb_hash_aset( hash_false_values, rb_str_new2( "FALSE" ), Qtrue );
648
- rb_hash_aset( hash_false_values, rb_str_new2( "off" ), Qtrue );
649
- rb_hash_aset( hash_false_values, rb_str_new2( "OFF" ), Qtrue );
650
-
651
640
  /* This module encapsulates all encoder classes with text output format */
652
641
  rb_mPG_TextEncoder = rb_define_module_under( rb_mPG, "TextEncoder" );
653
642
 
data/ext/pg_type_map.c CHANGED
@@ -74,29 +74,6 @@ pg_typemap_s_allocate( VALUE klass )
74
74
  return self;
75
75
  }
76
76
 
77
- static VALUE
78
- pg_typemap_fit_to_result_ext( VALUE self, VALUE result )
79
- {
80
- t_typemap *this = DATA_PTR( self );
81
-
82
- if ( !rb_obj_is_kind_of(result, rb_cPGresult) ) {
83
- rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::Result)",
84
- rb_obj_classname( result ) );
85
- }
86
-
87
- return this->funcs.fit_to_result( self, result );
88
- }
89
-
90
- static VALUE
91
- pg_typemap_fit_to_query_ext( VALUE self, VALUE params )
92
- {
93
- t_typemap *this = DATA_PTR( self );
94
-
95
- Check_Type( params, T_ARRAY);
96
-
97
- return this->funcs.fit_to_query( self, params );
98
- }
99
-
100
77
  /*
101
78
  * call-seq:
102
79
  * res.default_type_map = typemap
@@ -174,8 +151,6 @@ init_pg_type_map()
174
151
  */
175
152
  rb_cTypeMap = rb_define_class_under( rb_mPG, "TypeMap", rb_cObject );
176
153
  rb_define_alloc_func( rb_cTypeMap, pg_typemap_s_allocate );
177
- rb_define_method( rb_cTypeMap, "fit_to_result", pg_typemap_fit_to_result_ext, 1 );
178
- rb_define_method( rb_cTypeMap, "fit_to_query", pg_typemap_fit_to_query_ext, 1 );
179
154
 
180
155
  rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable");
181
156
  rb_define_method( rb_mDefaultTypeMappable, "default_type_map=", pg_typemap_default_type_map_set, 1 );
@@ -97,7 +97,7 @@ init_pg_type_map_all_strings()
97
97
  * Document-class: PG::TypeMapAllStrings < PG::TypeMap
98
98
  *
99
99
  * This type map casts all values received from the database server to Strings
100
- * and sends all values to the server after conversion to String by +#to_str+ .
100
+ * and sends all values to the server after conversion to String by +#to_s+ .
101
101
  * That means, it is hard coded to PG::TextEncoder::String for value encoding
102
102
  * and to PG::TextDecoder::String for text format respectivly PG::BinaryDecoder::Bytea
103
103
  * for binary format received from the server.
@@ -130,7 +130,7 @@ pg_tmbo_fit_to_result( VALUE self, VALUE result )
130
130
  if( PQntuples( pgresult ) <= this->max_rows_for_online_lookup ){
131
131
  /* Do a hash lookup for each result value in pg_tmbc_result_value() */
132
132
 
133
- /* Did the default type return the same object ? */
133
+ /* Did the default type return the same object ? */
134
134
  if( sub_typemap == this->typemap.default_typemap ){
135
135
  return self;
136
136
  } else {
@@ -306,41 +306,23 @@ pg_tmbo_max_rows_for_online_lookup_get( VALUE self )
306
306
 
307
307
  /*
308
308
  * call-seq:
309
- * typemap.fit_to_result( result, online_lookup = nil )
310
- *
311
- * This is an extended version of PG::TypeMap#fit_to_result that
312
- * allows explicit selection of online lookup ( online_lookup=true )
313
- * or building of a new PG::TypeMapByColumn ( online_lookup=false ).
309
+ * typemap.build_column_map( result )
314
310
  *
311
+ * This builds a PG::TypeMapByColumn that fits to the given PG::Result object
312
+ * based on it's type OIDs.
315
313
  *
316
314
  */
317
315
  static VALUE
318
- pg_tmbo_fit_to_result_ext( int argc, VALUE *argv, VALUE self )
316
+ pg_tmbo_build_column_map( VALUE self, VALUE result )
319
317
  {
320
318
  t_tmbo *this = DATA_PTR( self );
321
- VALUE result;
322
- VALUE online_lookup;
323
-
324
- rb_scan_args(argc, argv, "11", &result, &online_lookup);
325
319
 
326
320
  if ( !rb_obj_is_kind_of(result, rb_cPGresult) ) {
327
321
  rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::Result)",
328
322
  rb_obj_classname( result ) );
329
323
  }
330
324
 
331
- if( NIL_P( online_lookup ) ){
332
- /* call super */
333
- return this->typemap.funcs.fit_to_result(self, result);
334
- } else if( RB_TYPE_P( online_lookup, T_TRUE ) ){
335
- return self;
336
- } else if( RB_TYPE_P( online_lookup, T_FALSE ) ){
337
- PGresult *pgresult = pgresult_get( result );
338
-
339
- return pg_tmbo_build_type_map_for_result2( this, pgresult );
340
- } else {
341
- rb_raise( rb_eArgError, "argument online_lookup %s should be true, false or nil instead",
342
- rb_obj_classname( result ) );
343
- }
325
+ return pg_tmbo_build_type_map_for_result2( this, pgresult_get(result) );
344
326
  }
345
327
 
346
328
 
@@ -368,6 +350,6 @@ init_pg_type_map_by_oid()
368
350
  rb_define_method( rb_cTypeMapByOid, "coders", pg_tmbo_coders, 0 );
369
351
  rb_define_method( rb_cTypeMapByOid, "max_rows_for_online_lookup=", pg_tmbo_max_rows_for_online_lookup_set, 1 );
370
352
  rb_define_method( rb_cTypeMapByOid, "max_rows_for_online_lookup", pg_tmbo_max_rows_for_online_lookup_get, 0 );
371
- rb_define_method( rb_cTypeMapByOid, "fit_to_result", pg_tmbo_fit_to_result_ext, -1 );
353
+ rb_define_method( rb_cTypeMapByOid, "build_column_map", pg_tmbo_build_column_map, 1 );
372
354
  rb_include_module( rb_cTypeMapByOid, rb_mDefaultTypeMappable );
373
355
  }
@@ -0,0 +1,302 @@
1
+ /*
2
+ * pg_type_map_in_ruby.c - PG::TypeMapInRuby class extension
3
+ * $Id$
4
+ *
5
+ */
6
+
7
+ #include "pg.h"
8
+
9
+ VALUE rb_cTypeMapInRuby;
10
+ static VALUE s_id_fit_to_result;
11
+ static VALUE s_id_fit_to_query;
12
+ static VALUE s_id_fit_to_copy_get;
13
+ static VALUE s_id_typecast_result_value;
14
+ static VALUE s_id_typecast_query_param;
15
+ static VALUE s_id_typecast_copy_get;
16
+
17
+ typedef struct {
18
+ t_typemap typemap;
19
+ VALUE self;
20
+ } t_tmir;
21
+
22
+
23
+ /*
24
+ * call-seq:
25
+ * typemap.fit_to_result( result )
26
+ *
27
+ * Check that the type map fits to the result.
28
+ *
29
+ * This method is called, when a type map is assigned to a result.
30
+ * It must return a PG::TypeMap object or raise an Exception.
31
+ * This can be +self+ or some other type map that fits to the result.
32
+ *
33
+ */
34
+ static VALUE
35
+ pg_tmir_fit_to_result( VALUE self, VALUE result )
36
+ {
37
+ t_tmir *this = DATA_PTR( self );
38
+ t_typemap *default_tm;
39
+ t_typemap *p_new_typemap;
40
+ VALUE sub_typemap;
41
+ VALUE new_typemap;
42
+
43
+ if( rb_respond_to(self, s_id_fit_to_result) ){
44
+ new_typemap = rb_funcall( self, s_id_fit_to_result, 1, result );
45
+
46
+ if ( !rb_obj_is_kind_of(new_typemap, rb_cTypeMap) ) {
47
+ rb_raise( rb_eTypeError, "wrong return type from fit_to_result: %s expected kind of PG::TypeMap",
48
+ rb_obj_classname( new_typemap ) );
49
+ }
50
+ Check_Type( new_typemap, T_DATA );
51
+ } else {
52
+ new_typemap = self;
53
+ }
54
+
55
+ /* Ensure that the default type map fits equaly. */
56
+ default_tm = DATA_PTR( this->typemap.default_typemap );
57
+ sub_typemap = default_tm->funcs.fit_to_result( this->typemap.default_typemap, result );
58
+
59
+ if( sub_typemap != this->typemap.default_typemap ){
60
+ new_typemap = rb_obj_dup( new_typemap );
61
+ }
62
+
63
+ p_new_typemap = DATA_PTR(new_typemap);
64
+ p_new_typemap->default_typemap = sub_typemap;
65
+ return new_typemap;
66
+ }
67
+
68
+ static VALUE
69
+ pg_tmir_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
70
+ {
71
+ t_tmir *this = (t_tmir *) p_typemap;
72
+
73
+ return rb_funcall( this->self, s_id_typecast_result_value, 3, result, INT2NUM(tuple), INT2NUM(field) );
74
+ }
75
+
76
+ /*
77
+ * call-seq:
78
+ * typemap.typecast_result_value( result, tuple, field )
79
+ *
80
+ * Retrieve and cast a field of the given result.
81
+ *
82
+ * This method implementation uses the #default_type_map to get the
83
+ * field value. It can be derived to change this behaviour.
84
+ *
85
+ * Parameters:
86
+ * * +result+ : The PG::Result received from the database.
87
+ * * +tuple+ : The row number to retrieve.
88
+ * * +field+ : The column number to retrieve.
89
+ *
90
+ * Note: Calling any value retrieving methods of +result+ will result
91
+ * in an (endless) recursion. Instead super() can be used to retrieve
92
+ * the value using the default_typemap.
93
+ *
94
+ */
95
+ static VALUE
96
+ pg_tmir_typecast_result_value( VALUE self, VALUE result, VALUE tuple, VALUE field )
97
+ {
98
+ t_tmir *this = DATA_PTR( self );
99
+ t_typemap *default_tm = DATA_PTR( this->typemap.default_typemap );
100
+ return default_tm->funcs.typecast_result_value( default_tm, result, NUM2INT(tuple), NUM2INT(field) );
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * typemap.fit_to_query( params )
106
+ *
107
+ * Check that the type map fits to the given user values.
108
+ *
109
+ * This method is called, when a type map is used for sending a query
110
+ * and for encoding of copy data, before the value is casted.
111
+ *
112
+ */
113
+ static VALUE
114
+ pg_tmir_fit_to_query( VALUE self, VALUE params )
115
+ {
116
+ t_tmir *this = DATA_PTR( self );
117
+ t_typemap *default_tm;
118
+
119
+ if( rb_respond_to(self, s_id_fit_to_query) ){
120
+ rb_funcall( self, s_id_fit_to_query, 1, params );
121
+ }
122
+
123
+ /* Ensure that the default type map fits equaly. */
124
+ default_tm = DATA_PTR( this->typemap.default_typemap );
125
+ default_tm->funcs.fit_to_query( this->typemap.default_typemap, params );
126
+
127
+ return self;
128
+ }
129
+
130
+ static t_pg_coder *
131
+ pg_tmir_query_param( t_typemap *p_typemap, VALUE param_value, int field )
132
+ {
133
+ t_tmir *this = (t_tmir *) p_typemap;
134
+
135
+ VALUE coder = rb_funcall( this->self, s_id_typecast_query_param, 2, param_value, INT2NUM(field) );
136
+
137
+ if ( NIL_P(coder) ){
138
+ return NULL;
139
+ } else if( rb_obj_is_kind_of(coder, rb_cPG_Coder) ) {
140
+ return DATA_PTR(coder);
141
+ } else {
142
+ rb_raise( rb_eTypeError, "wrong return type from typecast_query_param: %s expected nil or kind of PG::Coder",
143
+ rb_obj_classname( coder ) );
144
+ }
145
+ }
146
+
147
+ /*
148
+ * call-seq:
149
+ * typemap.typecast_query_param( param_value, field )
150
+ *
151
+ * Cast a field string for transmission to the server.
152
+ *
153
+ * This method implementation uses the #default_type_map to cast param_value.
154
+ * It can be derived to change this behaviour.
155
+ *
156
+ * Parameters:
157
+ * * +param_value+ : The value from the user.
158
+ * * +field+ : The field number from left to right.
159
+ *
160
+ */
161
+ static VALUE
162
+ pg_tmir_typecast_query_param( VALUE self, VALUE param_value, VALUE field )
163
+ {
164
+ t_tmir *this = DATA_PTR( self );
165
+ t_typemap *default_tm = DATA_PTR( this->typemap.default_typemap );
166
+ t_pg_coder *p_coder = default_tm->funcs.typecast_query_param( default_tm, param_value, NUM2INT(field) );
167
+
168
+ return p_coder ? p_coder->coder_obj : Qnil;
169
+ }
170
+
171
+ /* This is to fool rdoc's C parser */
172
+ #if 0
173
+ /*
174
+ * call-seq:
175
+ * typemap.fit_to_copy_get()
176
+ *
177
+ * Check that the type map can be used for PG::Connection#get_copy_data.
178
+ *
179
+ * This method is called, when a type map is used for decoding copy data,
180
+ * before the value is casted.
181
+ *
182
+ */
183
+ static VALUE pg_tmir_fit_to_copy_get_dummy( VALUE self ){}
184
+ #endif
185
+
186
+ static int
187
+ pg_tmir_fit_to_copy_get( VALUE self )
188
+ {
189
+ t_tmir *this = DATA_PTR( self );
190
+ t_typemap *default_tm;
191
+ VALUE num_columns = INT2NUM(0);
192
+
193
+ if( rb_respond_to(self, s_id_fit_to_copy_get) ){
194
+ num_columns = rb_funcall( self, s_id_fit_to_copy_get, 0 );
195
+ }
196
+
197
+ if ( !rb_obj_is_kind_of(num_columns, rb_cInteger) ) {
198
+ rb_raise( rb_eTypeError, "wrong return type from fit_to_copy_get: %s expected kind of Integer",
199
+ rb_obj_classname( num_columns ) );
200
+ }
201
+ /* Ensure that the default type map fits equaly. */
202
+ default_tm = DATA_PTR( this->typemap.default_typemap );
203
+ default_tm->funcs.fit_to_copy_get( this->typemap.default_typemap );
204
+
205
+ return NUM2INT(num_columns);;
206
+ }
207
+
208
+ static VALUE
209
+ pg_tmir_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
210
+ {
211
+ t_tmir *this = (t_tmir *) p_typemap;
212
+ rb_encoding *p_encoding = rb_enc_from_index(enc_idx);
213
+ VALUE enc = rb_enc_from_encoding(p_encoding);
214
+ /* field_str is reused in-place by pg_text_dec_copy_row(), so we need to make
215
+ * a copy of the string buffer before used in ruby space.
216
+ * This requires rb_str_new() instead of rb_str_dup() for Rubinius.
217
+ */
218
+ VALUE field_str_copy = rb_str_new(RSTRING_PTR(field_str), RSTRING_LEN(field_str));
219
+ PG_ENCODING_SET_NOCHECK(field_str_copy, ENCODING_GET(field_str));
220
+ OBJ_INFECT(field_str_copy, field_str);
221
+
222
+ return rb_funcall( this->self, s_id_typecast_copy_get, 4, field_str_copy, INT2NUM(fieldno), INT2NUM(format), enc );
223
+ }
224
+
225
+ /*
226
+ * call-seq:
227
+ * typemap.typecast_copy_get( field_str, fieldno, format, encoding )
228
+ *
229
+ * Cast a field string received by PG::Connection#get_copy_data.
230
+ *
231
+ * This method implementation uses the #default_type_map to cast field_str.
232
+ * It can be derived to change this behaviour.
233
+ *
234
+ * Parameters:
235
+ * * +field_str+ : The String received from the server.
236
+ * * +fieldno+ : The field number from left to right.
237
+ * * +format+ : The format code (0 = text, 1 = binary)
238
+ * * +encoding+ : The encoding of the connection and encoding the returned
239
+ * value should get.
240
+ *
241
+ */
242
+ static VALUE
243
+ pg_tmir_typecast_copy_get( VALUE self, VALUE field_str, VALUE fieldno, VALUE format, VALUE enc )
244
+ {
245
+ t_tmir *this = DATA_PTR( self );
246
+ t_typemap *default_tm = DATA_PTR( this->typemap.default_typemap );
247
+ int enc_idx = rb_to_encoding_index( enc );
248
+
249
+ return default_tm->funcs.typecast_copy_get( default_tm, field_str, NUM2INT(fieldno), NUM2INT(format), enc_idx );
250
+ }
251
+
252
+ static VALUE
253
+ pg_tmir_s_allocate( VALUE klass )
254
+ {
255
+ t_tmir *this;
256
+ VALUE self;
257
+
258
+ self = Data_Make_Struct( klass, t_tmir, NULL, -1, this );
259
+
260
+ this->typemap.funcs.fit_to_result = pg_tmir_fit_to_result;
261
+ this->typemap.funcs.fit_to_query = pg_tmir_fit_to_query;
262
+ this->typemap.funcs.fit_to_copy_get = pg_tmir_fit_to_copy_get;
263
+ this->typemap.funcs.typecast_result_value = pg_tmir_result_value;
264
+ this->typemap.funcs.typecast_query_param = pg_tmir_query_param;
265
+ this->typemap.funcs.typecast_copy_get = pg_tmir_copy_get;
266
+ this->typemap.default_typemap = pg_typemap_all_strings;
267
+ this->self = self;
268
+
269
+ return self;
270
+ }
271
+
272
+
273
+ void
274
+ init_pg_type_map_in_ruby()
275
+ {
276
+ s_id_fit_to_result = rb_intern("fit_to_result");
277
+ s_id_fit_to_query = rb_intern("fit_to_query");
278
+ s_id_fit_to_copy_get = rb_intern("fit_to_copy_get");
279
+ s_id_typecast_result_value = rb_intern("typecast_result_value");
280
+ s_id_typecast_query_param = rb_intern("typecast_query_param");
281
+ s_id_typecast_copy_get = rb_intern("typecast_copy_get");
282
+
283
+ /*
284
+ * Document-class: PG::TypeMapInRuby < PG::TypeMap
285
+ *
286
+ * This class can be used to implement a type map in ruby, typically as a
287
+ * #default_type_map in a type map chain.
288
+ *
289
+ * This API is EXPERIMENTAL and could change in the future.
290
+ *
291
+ */
292
+ rb_cTypeMapInRuby = rb_define_class_under( rb_mPG, "TypeMapInRuby", rb_cTypeMap );
293
+ rb_define_alloc_func( rb_cTypeMapInRuby, pg_tmir_s_allocate );
294
+ /* rb_define_method( rb_cTypeMapInRuby, "fit_to_result", pg_tmir_fit_to_result, 1 ); */
295
+ /* rb_define_method( rb_cTypeMapInRuby, "fit_to_query", pg_tmir_fit_to_query, 1 ); */
296
+ /* rb_define_method( rb_cTypeMapInRuby, "fit_to_copy_get", pg_tmir_fit_to_copy_get_dummy, 0 ); */
297
+ rb_define_method( rb_cTypeMapInRuby, "typecast_result_value", pg_tmir_typecast_result_value, 3 );
298
+ rb_define_method( rb_cTypeMapInRuby, "typecast_query_param", pg_tmir_typecast_query_param, 2 );
299
+ rb_define_method( rb_cTypeMapInRuby, "typecast_copy_get", pg_tmir_typecast_copy_get, 4 );
300
+ /* rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable"); */
301
+ rb_include_module( rb_cTypeMapInRuby, rb_mDefaultTypeMappable );
302
+ }