pg 1.2.0-x64-mingw32 → 1.3.0.rc1-x64-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/.appveyor.yml +36 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +80 -0
- data/.github/workflows/source-gem.yml +129 -0
- data/.gitignore +13 -0
- data/.hgsigs +34 -0
- data/.hgtags +41 -0
- data/.irbrc +23 -0
- data/.pryrc +23 -0
- data/.tm_properties +21 -0
- data/.travis.yml +49 -0
- data/Gemfile +14 -0
- data/History.rdoc +98 -7
- data/Manifest.txt +0 -1
- data/README.rdoc +9 -8
- data/Rakefile +31 -140
- data/Rakefile.cross +54 -56
- data/certs/ged.pem +24 -0
- data/ext/errorcodes.def +8 -0
- data/ext/errorcodes.txt +3 -1
- data/ext/extconf.rb +90 -19
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +35 -1
- data/ext/pg.h +18 -0
- data/ext/pg_coder.c +90 -24
- data/ext/pg_connection.c +538 -279
- data/ext/pg_copy_coder.c +45 -15
- data/ext/pg_record_coder.c +38 -9
- data/ext/pg_result.c +70 -34
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +6 -6
- data/ext/pg_tuple.c +47 -21
- data/ext/pg_type_map.c +41 -8
- data/ext/pg_type_map_all_strings.c +14 -1
- data/ext/pg_type_map_by_class.c +50 -21
- data/ext/pg_type_map_by_column.c +64 -28
- data/ext/pg_type_map_by_mri_type.c +47 -18
- data/ext/pg_type_map_by_oid.c +52 -23
- data/ext/pg_type_map_in_ruby.c +50 -19
- data/ext/pg_util.c +2 -2
- data/lib/2.5/pg_ext.so +0 -0
- data/lib/2.6/pg_ext.so +0 -0
- data/lib/2.7/pg_ext.so +0 -0
- data/lib/3.0/pg_ext.so +0 -0
- data/lib/pg/basic_type_map_based_on_result.rb +47 -0
- data/lib/pg/basic_type_map_for_queries.rb +193 -0
- data/lib/pg/basic_type_map_for_results.rb +81 -0
- data/lib/pg/basic_type_registry.rb +296 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +369 -56
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +38 -24
- data/lib/x64-mingw32/libpq.dll +0 -0
- data/misc/openssl-pg-segfault.rb +31 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +21 -0
- data/misc/postgres/lib/postgres.rb +16 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +21 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
- data/pg.gemspec +32 -0
- data/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +106 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/async_mixed.rb +56 -0
- data/sample/check_conn.rb +21 -0
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/disk_usage_report.rb +177 -0
- data/sample/issue-119.rb +94 -0
- data/sample/losample.rb +69 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/notify_wait.rb +72 -0
- data/sample/pg_statistics.rb +285 -0
- data/sample/replication_monitor.rb +222 -0
- data/sample/test_binary_values.rb +33 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +311 -0
- data.tar.gz.sig +0 -0
- metadata +83 -232
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -0
- data/lib/2.2/pg_ext.so +0 -0
- data/lib/2.3/pg_ext.so +0 -0
- data/lib/2.4/pg_ext.so +0 -0
- data/lib/libpq.dll +0 -0
- data/lib/pg/basic_type_mapping.rb +0 -522
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -382
- data/spec/pg/basic_type_mapping_spec.rb +0 -645
- data/spec/pg/connection_spec.rb +0 -1911
- data/spec/pg/connection_sync_spec.rb +0 -41
- data/spec/pg/result_spec.rb +0 -681
- data/spec/pg/tuple_spec.rb +0 -333
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -226
- data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
- data/spec/pg/type_map_by_oid_spec.rb +0 -149
- data/spec/pg/type_map_in_ruby_spec.rb +0 -164
- data/spec/pg/type_map_spec.rb +0 -22
- data/spec/pg/type_spec.rb +0 -1123
- data/spec/pg_spec.rb +0 -50
data/ext/pg_type_map.c
CHANGED
@@ -6,6 +6,40 @@
|
|
6
6
|
|
7
7
|
#include "pg.h"
|
8
8
|
|
9
|
+
void
|
10
|
+
pg_typemap_mark( void *_this )
|
11
|
+
{
|
12
|
+
t_typemap *this = (t_typemap *)_this;
|
13
|
+
rb_gc_mark_movable(this->default_typemap);
|
14
|
+
}
|
15
|
+
|
16
|
+
size_t
|
17
|
+
pg_typemap_memsize( const void *_this )
|
18
|
+
{
|
19
|
+
t_typemap *this = (t_typemap *)_this;
|
20
|
+
return sizeof(*this);
|
21
|
+
}
|
22
|
+
|
23
|
+
void
|
24
|
+
pg_typemap_compact( void *_this )
|
25
|
+
{
|
26
|
+
t_typemap *this = (t_typemap *)_this;
|
27
|
+
pg_gc_location(this->default_typemap);
|
28
|
+
}
|
29
|
+
|
30
|
+
const rb_data_type_t pg_typemap_type = {
|
31
|
+
"PG::TypeMap",
|
32
|
+
{
|
33
|
+
pg_typemap_mark,
|
34
|
+
RUBY_TYPED_DEFAULT_FREE,
|
35
|
+
pg_typemap_memsize,
|
36
|
+
pg_compact_callback(pg_typemap_compact),
|
37
|
+
},
|
38
|
+
0,
|
39
|
+
0,
|
40
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
41
|
+
};
|
42
|
+
|
9
43
|
VALUE rb_cTypeMap;
|
10
44
|
VALUE rb_mDefaultTypeMappable;
|
11
45
|
static ID s_id_fit_to_query;
|
@@ -75,7 +109,7 @@ pg_typemap_s_allocate( VALUE klass )
|
|
75
109
|
VALUE self;
|
76
110
|
t_typemap *this;
|
77
111
|
|
78
|
-
self =
|
112
|
+
self = TypedData_Make_Struct( klass, t_typemap, &pg_typemap_type, this );
|
79
113
|
this->funcs = pg_typemap_funcs;
|
80
114
|
|
81
115
|
return self;
|
@@ -94,13 +128,12 @@ pg_typemap_s_allocate( VALUE klass )
|
|
94
128
|
static VALUE
|
95
129
|
pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
|
96
130
|
{
|
97
|
-
t_typemap *this =
|
131
|
+
t_typemap *this = RTYPEDDATA_DATA( self );
|
132
|
+
t_typemap *tm;
|
133
|
+
UNUSED(tm);
|
98
134
|
|
99
|
-
|
100
|
-
|
101
|
-
rb_obj_classname( typemap ) );
|
102
|
-
}
|
103
|
-
Check_Type(typemap, T_DATA);
|
135
|
+
/* Check type of method param */
|
136
|
+
TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, tm);
|
104
137
|
this->default_typemap = typemap;
|
105
138
|
|
106
139
|
return typemap;
|
@@ -119,7 +152,7 @@ pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
|
|
119
152
|
static VALUE
|
120
153
|
pg_typemap_default_type_map_get(VALUE self)
|
121
154
|
{
|
122
|
-
t_typemap *this =
|
155
|
+
t_typemap *this = RTYPEDDATA_DATA( self );
|
123
156
|
|
124
157
|
return this->default_typemap;
|
125
158
|
}
|
@@ -8,6 +8,19 @@
|
|
8
8
|
|
9
9
|
#include "pg.h"
|
10
10
|
|
11
|
+
static const rb_data_type_t pg_tmas_type = {
|
12
|
+
"PG::TypeMapAllStrings",
|
13
|
+
{
|
14
|
+
pg_typemap_mark,
|
15
|
+
RUBY_TYPED_DEFAULT_FREE,
|
16
|
+
pg_typemap_memsize,
|
17
|
+
pg_compact_callback(pg_typemap_compact),
|
18
|
+
},
|
19
|
+
&pg_typemap_type,
|
20
|
+
0,
|
21
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
22
|
+
};
|
23
|
+
|
11
24
|
VALUE rb_cTypeMapAllStrings;
|
12
25
|
VALUE pg_typemap_all_strings;
|
13
26
|
|
@@ -77,7 +90,7 @@ pg_tmas_s_allocate( VALUE klass )
|
|
77
90
|
t_typemap *this;
|
78
91
|
VALUE self;
|
79
92
|
|
80
|
-
self =
|
93
|
+
self = TypedData_Make_Struct( klass, t_typemap, &pg_tmas_type, this );
|
81
94
|
|
82
95
|
this->funcs.fit_to_result = pg_tmas_fit_to_result;
|
83
96
|
this->funcs.fit_to_query = pg_tmas_fit_to_query;
|
data/ext/pg_type_map_by_class.c
CHANGED
@@ -10,7 +10,6 @@
|
|
10
10
|
#include "pg.h"
|
11
11
|
|
12
12
|
static VALUE rb_cTypeMapByClass;
|
13
|
-
static ID s_id_ancestors;
|
14
13
|
|
15
14
|
typedef struct {
|
16
15
|
t_typemap typemap;
|
@@ -48,7 +47,7 @@ pg_tmbk_lookup_klass(t_tmbk *this, VALUE klass, VALUE param_value)
|
|
48
47
|
|
49
48
|
if( NIL_P(obj) ){
|
50
49
|
int i;
|
51
|
-
VALUE ancestors =
|
50
|
+
VALUE ancestors = rb_mod_ancestors( klass );
|
52
51
|
|
53
52
|
Check_Type( ancestors, T_ARRAY );
|
54
53
|
/* Don't look at the first element, it's expected to equal klass. */
|
@@ -63,7 +62,7 @@ pg_tmbk_lookup_klass(t_tmbk *this, VALUE klass, VALUE param_value)
|
|
63
62
|
if(NIL_P(obj)){
|
64
63
|
p_coder = NULL;
|
65
64
|
}else if(rb_obj_is_kind_of(obj, rb_cPG_Coder)){
|
66
|
-
|
65
|
+
TypedData_Get_Struct(obj, t_pg_coder, &pg_coder_type, p_coder);
|
67
66
|
}else{
|
68
67
|
if( RB_TYPE_P(obj, T_SYMBOL) ){
|
69
68
|
/* A Symbol: Call the method with this name. */
|
@@ -75,11 +74,9 @@ pg_tmbk_lookup_klass(t_tmbk *this, VALUE klass, VALUE param_value)
|
|
75
74
|
|
76
75
|
if( NIL_P(obj) ){
|
77
76
|
p_coder = NULL;
|
78
|
-
}else if( rb_obj_is_kind_of(obj, rb_cPG_Coder) ){
|
79
|
-
Data_Get_Struct(obj, t_pg_coder, p_coder);
|
80
77
|
}else{
|
81
|
-
|
82
|
-
|
78
|
+
/* Check retrieved coder type */
|
79
|
+
TypedData_Get_Struct(obj, t_pg_coder, &pg_coder_type, p_coder);
|
83
80
|
}
|
84
81
|
|
85
82
|
/* We can not cache coders retrieved by ruby code, because we can not anticipate
|
@@ -104,7 +101,7 @@ pg_tmbk_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field
|
|
104
101
|
p_coder = pg_tmbk_lookup_klass( this, rb_obj_class(param_value), param_value );
|
105
102
|
|
106
103
|
if( !p_coder ){
|
107
|
-
t_typemap *default_tm =
|
104
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
108
105
|
return default_tm->funcs.typecast_query_param( default_tm, param_value, field );
|
109
106
|
}
|
110
107
|
|
@@ -114,28 +111,62 @@ pg_tmbk_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field
|
|
114
111
|
static VALUE
|
115
112
|
pg_tmbk_fit_to_query( VALUE self, VALUE params )
|
116
113
|
{
|
117
|
-
t_tmbk *this = (t_tmbk *)
|
114
|
+
t_tmbk *this = (t_tmbk *)RTYPEDDATA_DATA(self);
|
118
115
|
/* Nothing to check at this typemap, but ensure that the default type map fits. */
|
119
|
-
t_typemap *default_tm =
|
116
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
120
117
|
default_tm->funcs.fit_to_query( this->typemap.default_typemap, params );
|
121
118
|
return self;
|
122
119
|
}
|
123
120
|
|
124
121
|
static void
|
125
|
-
pg_tmbk_mark(
|
122
|
+
pg_tmbk_mark( void *_this )
|
126
123
|
{
|
127
|
-
|
128
|
-
|
129
|
-
|
124
|
+
t_tmbk *this = (t_tmbk *)_this;
|
125
|
+
pg_typemap_mark(&this->typemap);
|
126
|
+
rb_gc_mark_movable(this->klass_to_coder);
|
127
|
+
rb_gc_mark_movable(this->self);
|
130
128
|
}
|
131
129
|
|
130
|
+
static size_t
|
131
|
+
pg_tmbk_memsize( const void *_this )
|
132
|
+
{
|
133
|
+
const t_tmbk *this = (const t_tmbk *)_this;
|
134
|
+
return sizeof(*this);
|
135
|
+
}
|
136
|
+
|
137
|
+
static void
|
138
|
+
pg_tmbk_compact(void *ptr)
|
139
|
+
{
|
140
|
+
t_tmbk *this = (t_tmbk *)ptr;
|
141
|
+
|
142
|
+
pg_typemap_compact(&this->typemap);
|
143
|
+
pg_gc_location(this->klass_to_coder);
|
144
|
+
pg_gc_location(this->self);
|
145
|
+
|
146
|
+
/* Clear the cache, to be safe from changes of klass VALUE by GC.compact. */
|
147
|
+
memset(&this->cache_row, 0, sizeof(this->cache_row));
|
148
|
+
}
|
149
|
+
|
150
|
+
static const rb_data_type_t pg_tmbk_type = {
|
151
|
+
"PG::TypeMapByClass",
|
152
|
+
{
|
153
|
+
pg_tmbk_mark,
|
154
|
+
RUBY_TYPED_DEFAULT_FREE,
|
155
|
+
pg_tmbk_memsize,
|
156
|
+
pg_compact_callback(pg_tmbk_compact),
|
157
|
+
},
|
158
|
+
&pg_typemap_type,
|
159
|
+
0,
|
160
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
161
|
+
};
|
162
|
+
|
132
163
|
static VALUE
|
133
164
|
pg_tmbk_s_allocate( VALUE klass )
|
134
165
|
{
|
135
166
|
t_tmbk *this;
|
136
167
|
VALUE self;
|
137
168
|
|
138
|
-
self =
|
169
|
+
self = TypedData_Make_Struct( klass, t_tmbk, &pg_tmbk_type, this );
|
139
170
|
this->typemap.funcs.fit_to_result = pg_typemap_fit_to_result;
|
140
171
|
this->typemap.funcs.fit_to_query = pg_tmbk_fit_to_query;
|
141
172
|
this->typemap.funcs.fit_to_copy_get = pg_typemap_fit_to_copy_get;
|
@@ -149,7 +180,7 @@ pg_tmbk_s_allocate( VALUE klass )
|
|
149
180
|
this->self = self;
|
150
181
|
this->klass_to_coder = rb_hash_new();
|
151
182
|
|
152
|
-
/* The cache is properly initialized by
|
183
|
+
/* The cache is properly initialized by TypedData_Make_Struct(). */
|
153
184
|
|
154
185
|
return self;
|
155
186
|
}
|
@@ -172,7 +203,7 @@ pg_tmbk_s_allocate( VALUE klass )
|
|
172
203
|
static VALUE
|
173
204
|
pg_tmbk_aset( VALUE self, VALUE klass, VALUE coder )
|
174
205
|
{
|
175
|
-
t_tmbk *this =
|
206
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
176
207
|
|
177
208
|
if(NIL_P(coder)){
|
178
209
|
rb_hash_delete( this->klass_to_coder, klass );
|
@@ -196,7 +227,7 @@ pg_tmbk_aset( VALUE self, VALUE klass, VALUE coder )
|
|
196
227
|
static VALUE
|
197
228
|
pg_tmbk_aref( VALUE self, VALUE klass )
|
198
229
|
{
|
199
|
-
t_tmbk *this =
|
230
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
200
231
|
|
201
232
|
return rb_hash_lookup(this->klass_to_coder, klass);
|
202
233
|
}
|
@@ -210,7 +241,7 @@ pg_tmbk_aref( VALUE self, VALUE klass )
|
|
210
241
|
static VALUE
|
211
242
|
pg_tmbk_coders( VALUE self )
|
212
243
|
{
|
213
|
-
t_tmbk *this =
|
244
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
214
245
|
|
215
246
|
return rb_obj_freeze(rb_hash_dup(this->klass_to_coder));
|
216
247
|
}
|
@@ -218,8 +249,6 @@ pg_tmbk_coders( VALUE self )
|
|
218
249
|
void
|
219
250
|
init_pg_type_map_by_class()
|
220
251
|
{
|
221
|
-
s_id_ancestors = rb_intern("ancestors");
|
222
|
-
|
223
252
|
/*
|
224
253
|
* Document-class: PG::TypeMapByClass < PG::TypeMap
|
225
254
|
*
|
data/ext/pg_type_map_by_column.c
CHANGED
@@ -16,7 +16,7 @@ static VALUE
|
|
16
16
|
pg_tmbc_fit_to_result( VALUE self, VALUE result )
|
17
17
|
{
|
18
18
|
int nfields;
|
19
|
-
t_tmbc *this =
|
19
|
+
t_tmbc *this = RTYPEDDATA_DATA( self );
|
20
20
|
t_typemap *default_tm;
|
21
21
|
VALUE sub_typemap;
|
22
22
|
|
@@ -26,8 +26,8 @@ pg_tmbc_fit_to_result( VALUE self, VALUE result )
|
|
26
26
|
nfields, this->nfields );
|
27
27
|
}
|
28
28
|
|
29
|
-
/* Ensure that the default type map fits
|
30
|
-
default_tm =
|
29
|
+
/* Ensure that the default type map fits equally. */
|
30
|
+
default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
31
31
|
sub_typemap = default_tm->funcs.fit_to_result( this->typemap.default_typemap, result );
|
32
32
|
|
33
33
|
/* Did the default type return the same object ? */
|
@@ -42,7 +42,7 @@ pg_tmbc_fit_to_result( VALUE self, VALUE result )
|
|
42
42
|
|
43
43
|
memcpy( p_new_typemap, this, struct_size );
|
44
44
|
p_new_typemap->typemap.default_typemap = sub_typemap;
|
45
|
-
|
45
|
+
RTYPEDDATA_DATA(new_typemap) = p_new_typemap;
|
46
46
|
return new_typemap;
|
47
47
|
}
|
48
48
|
}
|
@@ -51,7 +51,7 @@ static VALUE
|
|
51
51
|
pg_tmbc_fit_to_query( VALUE self, VALUE params )
|
52
52
|
{
|
53
53
|
int nfields;
|
54
|
-
t_tmbc *this =
|
54
|
+
t_tmbc *this = RTYPEDDATA_DATA( self );
|
55
55
|
t_typemap *default_tm;
|
56
56
|
|
57
57
|
nfields = (int)RARRAY_LEN( params );
|
@@ -60,8 +60,8 @@ pg_tmbc_fit_to_query( VALUE self, VALUE params )
|
|
60
60
|
nfields, this->nfields );
|
61
61
|
}
|
62
62
|
|
63
|
-
/* Ensure that the default type map fits
|
64
|
-
default_tm =
|
63
|
+
/* Ensure that the default type map fits equally. */
|
64
|
+
default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
65
65
|
default_tm->funcs.fit_to_query( this->typemap.default_typemap, params );
|
66
66
|
|
67
67
|
return self;
|
@@ -70,10 +70,10 @@ pg_tmbc_fit_to_query( VALUE self, VALUE params )
|
|
70
70
|
static int
|
71
71
|
pg_tmbc_fit_to_copy_get( VALUE self )
|
72
72
|
{
|
73
|
-
t_tmbc *this =
|
73
|
+
t_tmbc *this = RTYPEDDATA_DATA( self );
|
74
74
|
|
75
|
-
/* Ensure that the default type map fits
|
76
|
-
t_typemap *default_tm =
|
75
|
+
/* Ensure that the default type map fits equally. */
|
76
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
77
77
|
default_tm->funcs.fit_to_copy_get( this->typemap.default_typemap );
|
78
78
|
|
79
79
|
return this->nfields;
|
@@ -107,7 +107,7 @@ pg_tmbc_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
|
110
|
-
default_tm =
|
110
|
+
default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
111
111
|
return default_tm->funcs.typecast_result_value( default_tm, result, tuple, field );
|
112
112
|
}
|
113
113
|
|
@@ -120,7 +120,7 @@ pg_tmbc_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field
|
|
120
120
|
t_pg_coder *p_coder = this->convs[field].cconv;
|
121
121
|
|
122
122
|
if( !p_coder ){
|
123
|
-
t_typemap *default_tm =
|
123
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
124
124
|
return default_tm->funcs.typecast_query_param( default_tm, param_value, field );
|
125
125
|
}
|
126
126
|
|
@@ -142,7 +142,7 @@ pg_tmbc_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, i
|
|
142
142
|
p_coder = this->convs[fieldno].cconv;
|
143
143
|
|
144
144
|
if( !p_coder ){
|
145
|
-
t_typemap *default_tm =
|
145
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
146
146
|
return default_tm->funcs.typecast_copy_get( default_tm, field_str, fieldno, format, enc_idx );
|
147
147
|
}
|
148
148
|
|
@@ -158,7 +158,7 @@ pg_tmbc_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, i
|
|
158
158
|
return field_str;
|
159
159
|
}
|
160
160
|
|
161
|
-
return dec_func( p_coder, RSTRING_PTR(field_str),
|
161
|
+
return dec_func( p_coder, RSTRING_PTR(field_str), RSTRING_LENINT(field_str), 0, fieldno, enc_idx );
|
162
162
|
}
|
163
163
|
|
164
164
|
const struct pg_typemap_funcs pg_tmbc_funcs = {
|
@@ -171,34 +171,73 @@ const struct pg_typemap_funcs pg_tmbc_funcs = {
|
|
171
171
|
};
|
172
172
|
|
173
173
|
static void
|
174
|
-
pg_tmbc_mark(
|
174
|
+
pg_tmbc_mark( void *_this )
|
175
175
|
{
|
176
|
+
t_tmbc *this = (t_tmbc *)_this;
|
176
177
|
int i;
|
177
178
|
|
178
179
|
/* allocated but not initialized ? */
|
179
180
|
if( this == (t_tmbc *)&pg_typemap_funcs ) return;
|
180
181
|
|
181
|
-
|
182
|
+
pg_typemap_mark(&this->typemap);
|
182
183
|
for( i=0; i<this->nfields; i++){
|
183
184
|
t_pg_coder *p_coder = this->convs[i].cconv;
|
184
185
|
if( p_coder )
|
185
|
-
|
186
|
+
rb_gc_mark_movable(p_coder->coder_obj);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
static size_t
|
191
|
+
pg_tmbc_memsize( const void *_this )
|
192
|
+
{
|
193
|
+
const t_tmbc *this = (const t_tmbc *)_this;
|
194
|
+
return sizeof(t_tmbc) + sizeof(struct pg_tmbc_converter) * this->nfields;
|
195
|
+
}
|
196
|
+
|
197
|
+
static void
|
198
|
+
pg_tmbc_compact( void *_this )
|
199
|
+
{
|
200
|
+
t_tmbc *this = (t_tmbc *)_this;
|
201
|
+
int i;
|
202
|
+
|
203
|
+
/* allocated but not initialized ? */
|
204
|
+
if( this == (t_tmbc *)&pg_typemap_funcs ) return;
|
205
|
+
|
206
|
+
pg_typemap_compact(&this->typemap);
|
207
|
+
for( i=0; i<this->nfields; i++){
|
208
|
+
t_pg_coder *p_coder = this->convs[i].cconv;
|
209
|
+
if( p_coder )
|
210
|
+
pg_gc_location(p_coder->coder_obj);
|
186
211
|
}
|
187
212
|
}
|
188
213
|
|
189
214
|
static void
|
190
|
-
pg_tmbc_free(
|
215
|
+
pg_tmbc_free( void *_this )
|
191
216
|
{
|
217
|
+
t_tmbc *this = (t_tmbc *)_this;
|
192
218
|
/* allocated but not initialized ? */
|
193
219
|
if( this == (t_tmbc *)&pg_typemap_funcs ) return;
|
194
220
|
xfree( this );
|
195
221
|
}
|
196
222
|
|
223
|
+
static const rb_data_type_t pg_tmbc_type = {
|
224
|
+
"PG::TypeMapByColumn",
|
225
|
+
{
|
226
|
+
pg_tmbc_mark,
|
227
|
+
pg_tmbc_free,
|
228
|
+
pg_tmbc_memsize,
|
229
|
+
pg_compact_callback(pg_tmbc_compact),
|
230
|
+
},
|
231
|
+
&pg_typemap_type,
|
232
|
+
0,
|
233
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
234
|
+
};
|
235
|
+
|
197
236
|
static VALUE
|
198
237
|
pg_tmbc_s_allocate( VALUE klass )
|
199
238
|
{
|
200
239
|
/* Use pg_typemap_funcs as interim struct until #initialize is called. */
|
201
|
-
return
|
240
|
+
return TypedData_Wrap_Struct( klass, &pg_tmbc_type, (t_tmbc *)&pg_typemap_funcs );
|
202
241
|
}
|
203
242
|
|
204
243
|
VALUE
|
@@ -221,19 +260,18 @@ pg_tmbc_allocate()
|
|
221
260
|
static VALUE
|
222
261
|
pg_tmbc_init(VALUE self, VALUE conv_ary)
|
223
262
|
{
|
224
|
-
|
263
|
+
long i;
|
225
264
|
t_tmbc *this;
|
226
265
|
int conv_ary_len;
|
227
266
|
|
228
|
-
Check_Type(self, T_DATA);
|
229
267
|
Check_Type(conv_ary, T_ARRAY);
|
230
|
-
conv_ary_len =
|
268
|
+
conv_ary_len = RARRAY_LENINT(conv_ary);
|
231
269
|
this = xmalloc(sizeof(t_tmbc) + sizeof(struct pg_tmbc_converter) * conv_ary_len);
|
232
270
|
/* Set nfields to 0 at first, so that GC mark function doesn't access uninitialized memory. */
|
233
271
|
this->nfields = 0;
|
234
272
|
this->typemap.funcs = pg_tmbc_funcs;
|
235
273
|
this->typemap.default_typemap = pg_typemap_all_strings;
|
236
|
-
|
274
|
+
RTYPEDDATA_DATA(self) = this;
|
237
275
|
|
238
276
|
for(i=0; i<conv_ary_len; i++)
|
239
277
|
{
|
@@ -242,11 +280,9 @@ pg_tmbc_init(VALUE self, VALUE conv_ary)
|
|
242
280
|
if( obj == Qnil ){
|
243
281
|
/* no type cast */
|
244
282
|
this->convs[i].cconv = NULL;
|
245
|
-
} else if( rb_obj_is_kind_of(obj, rb_cPG_Coder) ){
|
246
|
-
Data_Get_Struct(obj, t_pg_coder, this->convs[i].cconv);
|
247
283
|
} else {
|
248
|
-
|
249
|
-
|
284
|
+
/* Check argument type and store the coder pointer */
|
285
|
+
TypedData_Get_Struct(obj, t_pg_coder, &pg_coder_type, this->convs[i].cconv);
|
250
286
|
}
|
251
287
|
}
|
252
288
|
|
@@ -266,7 +302,7 @@ static VALUE
|
|
266
302
|
pg_tmbc_coders(VALUE self)
|
267
303
|
{
|
268
304
|
int i;
|
269
|
-
t_tmbc *this =
|
305
|
+
t_tmbc *this = RTYPEDDATA_DATA( self );
|
270
306
|
VALUE ary_coders = rb_ary_new();
|
271
307
|
|
272
308
|
for( i=0; i<this->nfields; i++){
|
@@ -71,16 +71,12 @@ pg_tmbmt_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int fiel
|
|
71
71
|
|
72
72
|
obj = rb_funcall(ask_for_coder, rb_intern("call"), 1, param_value);
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
}else{
|
77
|
-
rb_raise(rb_eTypeError, "argument %d has invalid type %s (should be nil or some kind of PG::Coder)",
|
78
|
-
field+1, rb_obj_classname( obj ));
|
79
|
-
}
|
74
|
+
/* Check argument type and store the coder pointer */
|
75
|
+
TypedData_Get_Struct(obj, t_pg_coder, &pg_coder_type, p_coder);
|
80
76
|
}
|
81
77
|
|
82
78
|
if( !p_coder ){
|
83
|
-
t_typemap *default_tm =
|
79
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
84
80
|
return default_tm->funcs.typecast_query_param( default_tm, param_value, field );
|
85
81
|
}
|
86
82
|
|
@@ -90,24 +86,57 @@ pg_tmbmt_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int fiel
|
|
90
86
|
static VALUE
|
91
87
|
pg_tmbmt_fit_to_query( VALUE self, VALUE params )
|
92
88
|
{
|
93
|
-
t_tmbmt *this = (t_tmbmt *)
|
89
|
+
t_tmbmt *this = (t_tmbmt *)RTYPEDDATA_DATA(self);
|
94
90
|
/* Nothing to check at this typemap, but ensure that the default type map fits. */
|
95
|
-
t_typemap *default_tm =
|
91
|
+
t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
|
96
92
|
default_tm->funcs.fit_to_query( this->typemap.default_typemap, params );
|
97
93
|
return self;
|
98
94
|
}
|
99
95
|
|
100
96
|
#define GC_MARK_AS_USED(type) \
|
101
|
-
|
102
|
-
|
97
|
+
rb_gc_mark_movable( this->coders.ask_##type ); \
|
98
|
+
rb_gc_mark_movable( this->coders.coder_obj_##type );
|
103
99
|
|
104
100
|
static void
|
105
|
-
pg_tmbmt_mark(
|
101
|
+
pg_tmbmt_mark( void *_this )
|
106
102
|
{
|
107
|
-
|
103
|
+
t_tmbmt *this = (t_tmbmt *)_this;
|
104
|
+
pg_typemap_mark(&this->typemap);
|
108
105
|
FOR_EACH_MRI_TYPE( GC_MARK_AS_USED );
|
109
106
|
}
|
110
107
|
|
108
|
+
static size_t
|
109
|
+
pg_tmbmt_memsize( const void *_this )
|
110
|
+
{
|
111
|
+
const t_tmbmt *this = (const t_tmbmt *)_this;
|
112
|
+
return sizeof(*this);
|
113
|
+
}
|
114
|
+
|
115
|
+
#define GC_COMPACT(type) \
|
116
|
+
pg_gc_location( this->coders.ask_##type ); \
|
117
|
+
pg_gc_location( this->coders.coder_obj_##type );
|
118
|
+
|
119
|
+
static void
|
120
|
+
pg_tmbmt_compact( void *_this )
|
121
|
+
{
|
122
|
+
t_tmbmt *this = (t_tmbmt *)_this;
|
123
|
+
pg_typemap_compact(&this->typemap);
|
124
|
+
FOR_EACH_MRI_TYPE( GC_COMPACT );
|
125
|
+
}
|
126
|
+
|
127
|
+
static const rb_data_type_t pg_tmbmt_type = {
|
128
|
+
"PG::TypeMapByMriType",
|
129
|
+
{
|
130
|
+
pg_tmbmt_mark,
|
131
|
+
RUBY_TYPED_DEFAULT_FREE,
|
132
|
+
pg_tmbmt_memsize,
|
133
|
+
pg_compact_callback(pg_tmbmt_compact),
|
134
|
+
},
|
135
|
+
&pg_typemap_type,
|
136
|
+
0,
|
137
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
138
|
+
};
|
139
|
+
|
111
140
|
#define INIT_VARIABLES(type) \
|
112
141
|
this->coders.coder_##type = NULL; \
|
113
142
|
this->coders.ask_##type = Qnil; \
|
@@ -119,7 +148,7 @@ pg_tmbmt_s_allocate( VALUE klass )
|
|
119
148
|
t_tmbmt *this;
|
120
149
|
VALUE self;
|
121
150
|
|
122
|
-
self =
|
151
|
+
self = TypedData_Make_Struct( klass, t_tmbmt, &pg_tmbmt_type, this );
|
123
152
|
this->typemap.funcs.fit_to_result = pg_typemap_fit_to_result;
|
124
153
|
this->typemap.funcs.fit_to_query = pg_tmbmt_fit_to_query;
|
125
154
|
this->typemap.funcs.fit_to_copy_get = pg_typemap_fit_to_copy_get;
|
@@ -140,7 +169,7 @@ pg_tmbmt_s_allocate( VALUE klass )
|
|
140
169
|
this->coders.coder_##type = NULL; \
|
141
170
|
this->coders.ask_##type = Qnil; \
|
142
171
|
}else if(rb_obj_is_kind_of(coder, rb_cPG_Coder)){ \
|
143
|
-
|
172
|
+
TypedData_Get_Struct(coder, t_pg_coder, &pg_coder_type, this->coders.coder_##type); \
|
144
173
|
this->coders.ask_##type = Qnil; \
|
145
174
|
}else if(RB_TYPE_P(coder, T_SYMBOL)){ \
|
146
175
|
this->coders.coder_##type = NULL; \
|
@@ -188,7 +217,7 @@ pg_tmbmt_s_allocate( VALUE klass )
|
|
188
217
|
static VALUE
|
189
218
|
pg_tmbmt_aset( VALUE self, VALUE mri_type, VALUE coder )
|
190
219
|
{
|
191
|
-
t_tmbmt *this =
|
220
|
+
t_tmbmt *this = RTYPEDDATA_DATA( self );
|
192
221
|
char *p_mri_type;
|
193
222
|
|
194
223
|
p_mri_type = StringValueCStr(mri_type);
|
@@ -220,7 +249,7 @@ static VALUE
|
|
220
249
|
pg_tmbmt_aref( VALUE self, VALUE mri_type )
|
221
250
|
{
|
222
251
|
VALUE coder;
|
223
|
-
t_tmbmt *this =
|
252
|
+
t_tmbmt *this = RTYPEDDATA_DATA( self );
|
224
253
|
char *p_mri_type;
|
225
254
|
|
226
255
|
p_mri_type = StringValueCStr(mri_type);
|
@@ -248,7 +277,7 @@ pg_tmbmt_aref( VALUE self, VALUE mri_type )
|
|
248
277
|
static VALUE
|
249
278
|
pg_tmbmt_coders( VALUE self )
|
250
279
|
{
|
251
|
-
t_tmbmt *this =
|
280
|
+
t_tmbmt *this = RTYPEDDATA_DATA( self );
|
252
281
|
VALUE hash_coders = rb_hash_new();
|
253
282
|
|
254
283
|
FOR_EACH_MRI_TYPE( ADD_TO_HASH );
|