pg 0.18.2 → 1.5.3
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.appveyor.yml +42 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +117 -0
- data/.github/workflows/source-gem.yml +137 -0
- data/.gitignore +22 -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/BSDL +2 -2
- data/Gemfile +14 -0
- data/History.md +876 -0
- data/Manifest.txt +8 -21
- data/README-Windows.rdoc +17 -28
- data/README.ja.md +276 -0
- data/README.md +286 -0
- data/Rakefile +40 -131
- data/Rakefile.cross +88 -70
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/ext/errorcodes.def +113 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +36 -2
- data/ext/extconf.rb +120 -54
- data/ext/gvl_wrappers.c +8 -0
- data/ext/gvl_wrappers.h +44 -33
- data/ext/pg.c +226 -200
- data/ext/pg.h +99 -99
- data/ext/pg_binary_decoder.c +164 -16
- data/ext/pg_binary_encoder.c +249 -22
- data/ext/pg_coder.c +189 -44
- data/ext/pg_connection.c +1866 -1173
- data/ext/pg_copy_coder.c +398 -42
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +522 -0
- data/ext/pg_result.c +727 -232
- data/ext/pg_text_decoder.c +629 -43
- data/ext/pg_text_encoder.c +269 -102
- data/ext/pg_tuple.c +572 -0
- data/ext/pg_type_map.c +64 -23
- data/ext/pg_type_map_all_strings.c +21 -7
- data/ext/pg_type_map_by_class.c +59 -27
- data/ext/pg_type_map_by_column.c +86 -43
- data/ext/pg_type_map_by_mri_type.c +49 -20
- data/ext/pg_type_map_by_oid.c +62 -29
- data/ext/pg_type_map_in_ruby.c +56 -22
- data/ext/{util.c → pg_util.c} +12 -12
- data/ext/{util.h → pg_util.h} +2 -2
- data/lib/pg/basic_type_map_based_on_result.rb +67 -0
- data/lib/pg/basic_type_map_for_queries.rb +198 -0
- data/lib/pg/basic_type_map_for_results.rb +104 -0
- data/lib/pg/basic_type_registry.rb +299 -0
- data/lib/pg/binary_decoder/date.rb +9 -0
- data/lib/pg/binary_decoder/timestamp.rb +26 -0
- data/lib/pg/binary_encoder/timestamp.rb +20 -0
- data/lib/pg/coder.rb +36 -13
- data/lib/pg/connection.rb +797 -77
- data/lib/pg/exceptions.rb +16 -2
- data/lib/pg/result.rb +24 -7
- data/lib/pg/text_decoder/date.rb +18 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +14 -0
- data/lib/pg/text_decoder/numeric.rb +9 -0
- data/lib/pg/text_decoder/timestamp.rb +30 -0
- data/lib/pg/text_encoder/date.rb +12 -0
- data/lib/pg/text_encoder/inet.rb +28 -0
- data/lib/pg/text_encoder/json.rb +14 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +3 -2
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +106 -41
- 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 +34 -0
- data/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +1 -1
- data/sample/async_api.rb +4 -8
- data/sample/async_copyto.rb +1 -1
- data/sample/async_mixed.rb +1 -1
- data/sample/check_conn.rb +1 -1
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +1 -1
- data/sample/copyto.rb +1 -1
- data/sample/cursor.rb +1 -1
- data/sample/disk_usage_report.rb +6 -15
- data/sample/issue-119.rb +2 -2
- data/sample/losample.rb +1 -1
- data/sample/minimal-testcase.rb +2 -2
- data/sample/notify_wait.rb +1 -1
- data/sample/pg_statistics.rb +6 -15
- data/sample/replication_monitor.rb +9 -18
- data/sample/test_binary_values.rb +1 -1
- data/sample/wal_shipper.rb +2 -2
- data/sample/warehouse_partitions.rb +8 -17
- data/translation/.po4a-version +7 -0
- data/translation/po/all.pot +910 -0
- data/translation/po/ja.po +1047 -0
- data/translation/po4a.cfg +12 -0
- data.tar.gz.sig +0 -0
- metadata +137 -204
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -5545
- data/History.rdoc +0 -313
- data/README.ja.rdoc +0 -14
- data/README.rdoc +0 -161
- data/lib/pg/basic_type_mapping.rb +0 -399
- data/lib/pg/constants.rb +0 -11
- data/lib/pg/text_decoder.rb +0 -42
- data/lib/pg/text_encoder.rb +0 -27
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -355
- data/spec/pg/basic_type_mapping_spec.rb +0 -251
- data/spec/pg/connection_spec.rb +0 -1535
- data/spec/pg/result_spec.rb +0 -449
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -222
- 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 -688
- data/spec/pg_spec.rb +0 -50
data/ext/pg_type_map.c
CHANGED
|
@@ -1,65 +1,106 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
|
3
|
-
* $Id
|
|
3
|
+
* $Id$
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
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 | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
|
|
41
|
+
};
|
|
42
|
+
|
|
9
43
|
VALUE rb_cTypeMap;
|
|
10
44
|
VALUE rb_mDefaultTypeMappable;
|
|
11
45
|
static ID s_id_fit_to_query;
|
|
12
46
|
static ID s_id_fit_to_result;
|
|
13
47
|
|
|
48
|
+
NORETURN( VALUE
|
|
49
|
+
pg_typemap_fit_to_result( VALUE self, VALUE result ));
|
|
50
|
+
NORETURN( VALUE
|
|
51
|
+
pg_typemap_fit_to_query( VALUE self, VALUE params ));
|
|
52
|
+
NORETURN( int
|
|
53
|
+
pg_typemap_fit_to_copy_get( VALUE self ));
|
|
54
|
+
NORETURN( VALUE
|
|
55
|
+
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field ));
|
|
56
|
+
NORETURN( t_pg_coder *
|
|
57
|
+
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field ));
|
|
58
|
+
NORETURN( VALUE
|
|
59
|
+
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx ));
|
|
60
|
+
|
|
14
61
|
VALUE
|
|
15
62
|
pg_typemap_fit_to_result( VALUE self, VALUE result )
|
|
16
63
|
{
|
|
17
64
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map result values", rb_obj_classname(self) );
|
|
18
|
-
return Qnil;
|
|
19
65
|
}
|
|
20
66
|
|
|
21
67
|
VALUE
|
|
22
68
|
pg_typemap_fit_to_query( VALUE self, VALUE params )
|
|
23
69
|
{
|
|
24
70
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map query params", rb_obj_classname(self) );
|
|
25
|
-
return Qnil;
|
|
26
71
|
}
|
|
27
72
|
|
|
28
73
|
int
|
|
29
74
|
pg_typemap_fit_to_copy_get( VALUE self )
|
|
30
75
|
{
|
|
31
76
|
rb_raise( rb_eNotImpError, "type map %s is not suitable to map get_copy_data results", rb_obj_classname(self) );
|
|
32
|
-
return Qnil;
|
|
33
77
|
}
|
|
34
78
|
|
|
35
79
|
VALUE
|
|
36
80
|
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
|
|
37
81
|
{
|
|
38
82
|
rb_raise( rb_eNotImpError, "type map is not suitable to map result values" );
|
|
39
|
-
return Qnil;
|
|
40
83
|
}
|
|
41
84
|
|
|
42
85
|
t_pg_coder *
|
|
43
86
|
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field )
|
|
44
87
|
{
|
|
45
88
|
rb_raise( rb_eNotImpError, "type map is not suitable to map query params" );
|
|
46
|
-
return NULL;
|
|
47
89
|
}
|
|
48
90
|
|
|
49
91
|
VALUE
|
|
50
92
|
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
|
|
51
93
|
{
|
|
52
94
|
rb_raise( rb_eNotImpError, "type map is not suitable to map get_copy_data results" );
|
|
53
|
-
return Qnil;
|
|
54
95
|
}
|
|
55
96
|
|
|
56
97
|
const struct pg_typemap_funcs pg_typemap_funcs = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
98
|
+
pg_typemap_fit_to_result,
|
|
99
|
+
pg_typemap_fit_to_query,
|
|
100
|
+
pg_typemap_fit_to_copy_get,
|
|
101
|
+
pg_typemap_result_value,
|
|
102
|
+
pg_typemap_typecast_query_param,
|
|
103
|
+
pg_typemap_typecast_copy_get
|
|
63
104
|
};
|
|
64
105
|
|
|
65
106
|
static VALUE
|
|
@@ -68,7 +109,7 @@ pg_typemap_s_allocate( VALUE klass )
|
|
|
68
109
|
VALUE self;
|
|
69
110
|
t_typemap *this;
|
|
70
111
|
|
|
71
|
-
self =
|
|
112
|
+
self = TypedData_Make_Struct( klass, t_typemap, &pg_typemap_type, this );
|
|
72
113
|
this->funcs = pg_typemap_funcs;
|
|
73
114
|
|
|
74
115
|
return self;
|
|
@@ -87,14 +128,14 @@ pg_typemap_s_allocate( VALUE klass )
|
|
|
87
128
|
static VALUE
|
|
88
129
|
pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
|
|
89
130
|
{
|
|
90
|
-
t_typemap *this =
|
|
131
|
+
t_typemap *this = RTYPEDDATA_DATA( self );
|
|
132
|
+
t_typemap *tm;
|
|
133
|
+
UNUSED(tm);
|
|
91
134
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
Check_Type(typemap, T_DATA);
|
|
97
|
-
this->default_typemap = typemap;
|
|
135
|
+
rb_check_frozen(self);
|
|
136
|
+
/* Check type of method param */
|
|
137
|
+
TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, tm);
|
|
138
|
+
RB_OBJ_WRITE(self, &this->default_typemap, typemap);
|
|
98
139
|
|
|
99
140
|
return typemap;
|
|
100
141
|
}
|
|
@@ -112,7 +153,7 @@ pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
|
|
|
112
153
|
static VALUE
|
|
113
154
|
pg_typemap_default_type_map_get(VALUE self)
|
|
114
155
|
{
|
|
115
|
-
t_typemap *this =
|
|
156
|
+
t_typemap *this = RTYPEDDATA_DATA( self );
|
|
116
157
|
|
|
117
158
|
return this->default_typemap;
|
|
118
159
|
}
|
|
@@ -136,7 +177,7 @@ pg_typemap_with_default_type_map(VALUE self, VALUE typemap)
|
|
|
136
177
|
}
|
|
137
178
|
|
|
138
179
|
void
|
|
139
|
-
init_pg_type_map()
|
|
180
|
+
init_pg_type_map(void)
|
|
140
181
|
{
|
|
141
182
|
s_id_fit_to_query = rb_intern("fit_to_query");
|
|
142
183
|
s_id_fit_to_result = rb_intern("fit_to_result");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
|
|
3
|
-
* $Id
|
|
3
|
+
* $Id$
|
|
4
4
|
*
|
|
5
5
|
* This is the default typemap.
|
|
6
6
|
*
|
|
@@ -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 | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
|
|
22
|
+
};
|
|
23
|
+
|
|
11
24
|
VALUE rb_cTypeMapAllStrings;
|
|
12
25
|
VALUE pg_typemap_all_strings;
|
|
13
26
|
|
|
@@ -33,9 +46,9 @@ pg_tmas_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
|
|
|
33
46
|
len = PQgetlength( p_result->pgresult, tuple, field );
|
|
34
47
|
|
|
35
48
|
if ( 0 == PQfformat(p_result->pgresult, field) ) {
|
|
36
|
-
ret = pg_text_dec_string(NULL, val, len, tuple, field,
|
|
49
|
+
ret = pg_text_dec_string(NULL, val, len, tuple, field, p_result->enc_idx);
|
|
37
50
|
} else {
|
|
38
|
-
ret = pg_bin_dec_bytea(NULL, val, len, tuple, field,
|
|
51
|
+
ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, p_result->enc_idx);
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
return ret;
|
|
@@ -63,6 +76,7 @@ pg_tmas_fit_to_copy_get( VALUE self )
|
|
|
63
76
|
static VALUE
|
|
64
77
|
pg_tmas_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
|
|
65
78
|
{
|
|
79
|
+
rb_str_modify(field_str);
|
|
66
80
|
if( format == 0 ){
|
|
67
81
|
PG_ENCODING_SET_NOCHECK( field_str, enc_idx );
|
|
68
82
|
} else {
|
|
@@ -77,7 +91,7 @@ pg_tmas_s_allocate( VALUE klass )
|
|
|
77
91
|
t_typemap *this;
|
|
78
92
|
VALUE self;
|
|
79
93
|
|
|
80
|
-
self =
|
|
94
|
+
self = TypedData_Make_Struct( klass, t_typemap, &pg_tmas_type, this );
|
|
81
95
|
|
|
82
96
|
this->funcs.fit_to_result = pg_tmas_fit_to_result;
|
|
83
97
|
this->funcs.fit_to_query = pg_tmas_fit_to_query;
|
|
@@ -91,7 +105,7 @@ pg_tmas_s_allocate( VALUE klass )
|
|
|
91
105
|
|
|
92
106
|
|
|
93
107
|
void
|
|
94
|
-
init_pg_type_map_all_strings()
|
|
108
|
+
init_pg_type_map_all_strings(void)
|
|
95
109
|
{
|
|
96
110
|
/*
|
|
97
111
|
* Document-class: PG::TypeMapAllStrings < PG::TypeMap
|
|
@@ -99,7 +113,7 @@ init_pg_type_map_all_strings()
|
|
|
99
113
|
* This type map casts all values received from the database server to Strings
|
|
100
114
|
* and sends all values to the server after conversion to String by +#to_s+ .
|
|
101
115
|
* That means, it is hard coded to PG::TextEncoder::String for value encoding
|
|
102
|
-
* and to PG::TextDecoder::String for text format
|
|
116
|
+
* and to PG::TextDecoder::String for text format respectively PG::BinaryDecoder::Bytea
|
|
103
117
|
* for binary format received from the server.
|
|
104
118
|
*
|
|
105
119
|
* It is suitable for type casting query bind parameters, result values and
|
|
@@ -111,6 +125,6 @@ init_pg_type_map_all_strings()
|
|
|
111
125
|
rb_cTypeMapAllStrings = rb_define_class_under( rb_mPG, "TypeMapAllStrings", rb_cTypeMap );
|
|
112
126
|
rb_define_alloc_func( rb_cTypeMapAllStrings, pg_tmas_s_allocate );
|
|
113
127
|
|
|
114
|
-
pg_typemap_all_strings = rb_funcall( rb_cTypeMapAllStrings, rb_intern("new"), 0 );
|
|
128
|
+
pg_typemap_all_strings = rb_obj_freeze( rb_funcall( rb_cTypeMapAllStrings, rb_intern("new"), 0 ));
|
|
115
129
|
rb_gc_register_address( &pg_typemap_all_strings );
|
|
116
130
|
}
|
data/ext/pg_type_map_by_class.c
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* pg_type_map_by_class.c - PG::TypeMapByClass class extension
|
|
3
|
-
* $Id
|
|
3
|
+
* $Id$
|
|
4
4
|
*
|
|
5
5
|
* This type map can be used to select value encoders based on the class
|
|
6
6
|
* of the given value to be send.
|
|
@@ -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;
|
|
@@ -28,7 +27,7 @@ typedef struct {
|
|
|
28
27
|
* We use 8 Bits of the klass object id as index to a 256 entry cache.
|
|
29
28
|
* This avoids full lookups in most cases.
|
|
30
29
|
*/
|
|
31
|
-
#define CACHE_LOOKUP(this, klass) ( &this->cache_row[(klass >> 8) & 0xff] )
|
|
30
|
+
#define CACHE_LOOKUP(this, klass) ( &this->cache_row[(((unsigned long)klass) >> 8) & 0xff] )
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
static t_pg_coder *
|
|
@@ -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,10 +62,10 @@ 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
|
-
/* A
|
|
68
|
+
/* A Symbol: Call the method with this name. */
|
|
70
69
|
obj = rb_funcall(this->self, SYM2ID(obj), 1, param_value);
|
|
71
70
|
}else{
|
|
72
71
|
/* A Proc object (or something that responds to #call). */
|
|
@@ -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,42 +111,76 @@ 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 )
|
|
123
|
+
{
|
|
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);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static size_t
|
|
131
|
+
pg_tmbk_memsize( const void *_this )
|
|
126
132
|
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
/* All coders are in the Hash, so no need to mark the cache. */
|
|
133
|
+
const t_tmbk *this = (const t_tmbk *)_this;
|
|
134
|
+
return sizeof(*this);
|
|
130
135
|
}
|
|
131
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 | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
|
|
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;
|
|
142
173
|
this->typemap.funcs.typecast_result_value = pg_typemap_result_value;
|
|
143
174
|
this->typemap.funcs.typecast_query_param = pg_tmbk_typecast_query_param;
|
|
144
175
|
this->typemap.funcs.typecast_copy_get = pg_typemap_typecast_copy_get;
|
|
145
|
-
this->typemap.default_typemap
|
|
176
|
+
RB_OBJ_WRITE(self, &this->typemap.default_typemap, pg_typemap_all_strings);
|
|
146
177
|
|
|
147
178
|
/* We need to store self in the this-struct, because pg_tmbk_typecast_query_param(),
|
|
148
179
|
* is called with the this-pointer only. */
|
|
149
180
|
this->self = self;
|
|
150
|
-
this->klass_to_coder
|
|
181
|
+
RB_OBJ_WRITE(self, &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,9 @@ 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 );
|
|
207
|
+
|
|
208
|
+
rb_check_frozen(self);
|
|
176
209
|
|
|
177
210
|
if(NIL_P(coder)){
|
|
178
211
|
rb_hash_delete( this->klass_to_coder, klass );
|
|
@@ -196,7 +229,7 @@ pg_tmbk_aset( VALUE self, VALUE klass, VALUE coder )
|
|
|
196
229
|
static VALUE
|
|
197
230
|
pg_tmbk_aref( VALUE self, VALUE klass )
|
|
198
231
|
{
|
|
199
|
-
t_tmbk *this =
|
|
232
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
|
200
233
|
|
|
201
234
|
return rb_hash_lookup(this->klass_to_coder, klass);
|
|
202
235
|
}
|
|
@@ -210,16 +243,14 @@ pg_tmbk_aref( VALUE self, VALUE klass )
|
|
|
210
243
|
static VALUE
|
|
211
244
|
pg_tmbk_coders( VALUE self )
|
|
212
245
|
{
|
|
213
|
-
t_tmbk *this =
|
|
246
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
|
214
247
|
|
|
215
248
|
return rb_obj_freeze(rb_hash_dup(this->klass_to_coder));
|
|
216
249
|
}
|
|
217
250
|
|
|
218
251
|
void
|
|
219
|
-
init_pg_type_map_by_class()
|
|
252
|
+
init_pg_type_map_by_class(void)
|
|
220
253
|
{
|
|
221
|
-
s_id_ancestors = rb_intern("ancestors");
|
|
222
|
-
|
|
223
254
|
/*
|
|
224
255
|
* Document-class: PG::TypeMapByClass < PG::TypeMap
|
|
225
256
|
*
|
|
@@ -235,5 +266,6 @@ init_pg_type_map_by_class()
|
|
|
235
266
|
rb_define_method( rb_cTypeMapByClass, "[]=", pg_tmbk_aset, 2 );
|
|
236
267
|
rb_define_method( rb_cTypeMapByClass, "[]", pg_tmbk_aref, 1 );
|
|
237
268
|
rb_define_method( rb_cTypeMapByClass, "coders", pg_tmbk_coders, 0 );
|
|
269
|
+
/* rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable"); */
|
|
238
270
|
rb_include_module( rb_cTypeMapByClass, rb_mDefaultTypeMappable );
|
|
239
271
|
}
|