pg 1.2.3 → 1.4.4
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 +86 -0
- data/.github/workflows/source-gem.yml +131 -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 +209 -7
- data/Manifest.txt +0 -1
- data/README.rdoc +31 -11
- data/Rakefile +27 -138
- data/Rakefile.cross +8 -5
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/ext/errorcodes.def +8 -0
- data/ext/errorcodes.rb +0 -0
- data/ext/errorcodes.txt +3 -1
- data/ext/extconf.rb +100 -25
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +59 -29
- data/ext/pg.h +20 -1
- data/ext/pg_binary_decoder.c +1 -1
- data/ext/pg_binary_encoder.c +1 -1
- data/ext/pg_coder.c +83 -29
- data/ext/pg_connection.c +856 -656
- data/ext/pg_copy_coder.c +46 -17
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +46 -16
- data/ext/pg_result.c +88 -49
- data/ext/pg_text_decoder.c +2 -2
- data/ext/pg_text_encoder.c +7 -7
- data/ext/pg_tuple.c +50 -30
- data/ext/pg_type_map.c +42 -9
- data/ext/pg_type_map_all_strings.c +16 -2
- data/ext/pg_type_map_by_class.c +50 -25
- data/ext/pg_type_map_by_column.c +68 -30
- data/ext/pg_type_map_by_mri_type.c +48 -19
- data/ext/pg_type_map_by_oid.c +53 -24
- data/ext/pg_type_map_in_ruby.c +51 -20
- data/ext/pg_util.c +2 -2
- 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 +301 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +655 -69
- data/lib/pg/exceptions.rb +7 -1
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +47 -32
- 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/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +102 -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 +81 -224
- metadata.gz.sig +0 -0
- data/ChangeLog +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 -380
- data/spec/pg/basic_type_mapping_spec.rb +0 -630
- data/spec/pg/connection_spec.rb +0 -1949
- 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_text_encoder.c
CHANGED
|
@@ -191,7 +191,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
|
|
|
191
191
|
if (neg)
|
|
192
192
|
*out++ = '-';
|
|
193
193
|
|
|
194
|
-
len = out - start;
|
|
194
|
+
len = (int)(out - start);
|
|
195
195
|
|
|
196
196
|
/* Reverse string. */
|
|
197
197
|
out--;
|
|
@@ -252,7 +252,7 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
/*
|
|
255
|
-
* The following
|
|
255
|
+
* The following computation is roughly a conversion kind of
|
|
256
256
|
* sprintf( out, "%.16E", dvalue);
|
|
257
257
|
*/
|
|
258
258
|
|
|
@@ -403,11 +403,11 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
|
403
403
|
*optr++ = hextab[c >> 4];
|
|
404
404
|
*optr++ = hextab[c & 0xf];
|
|
405
405
|
}
|
|
406
|
-
return optr - out;
|
|
406
|
+
return (int)(optr - out);
|
|
407
407
|
}else{
|
|
408
408
|
*intermediate = rb_obj_as_string(value);
|
|
409
409
|
/* The output starts with "\x" and each character is converted to hex. */
|
|
410
|
-
return 2 +
|
|
410
|
+
return 2 + RSTRING_LENINT(*intermediate) * 2;
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
|
|
@@ -610,8 +610,8 @@ quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
|
|
610
610
|
static char *
|
|
611
611
|
pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
|
|
612
612
|
{
|
|
613
|
-
|
|
614
|
-
|
|
613
|
+
long i;
|
|
614
|
+
long nr_elems;
|
|
615
615
|
|
|
616
616
|
Check_Type(value, T_ARRAY);
|
|
617
617
|
nr_elems = RARRAY_LEN(value);
|
|
@@ -775,7 +775,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
|
|
|
775
775
|
|
|
776
776
|
|
|
777
777
|
void
|
|
778
|
-
init_pg_text_encoder()
|
|
778
|
+
init_pg_text_encoder(void)
|
|
779
779
|
{
|
|
780
780
|
s_id_encode = rb_intern("encode");
|
|
781
781
|
s_id_to_i = rb_intern("to_i");
|
data/ext/pg_tuple.c
CHANGED
|
@@ -52,57 +52,83 @@ typedef struct {
|
|
|
52
52
|
VALUE values[0];
|
|
53
53
|
} t_pg_tuple;
|
|
54
54
|
|
|
55
|
-
static inline VALUE
|
|
56
|
-
|
|
55
|
+
static inline VALUE *
|
|
56
|
+
pg_tuple_get_field_names_ptr( t_pg_tuple *this )
|
|
57
57
|
{
|
|
58
58
|
if( this->num_fields != (int)RHASH_SIZE(this->field_map) ){
|
|
59
|
-
return this->values[this->num_fields];
|
|
59
|
+
return &this->values[this->num_fields];
|
|
60
60
|
} else {
|
|
61
|
-
|
|
61
|
+
static VALUE f = Qfalse;
|
|
62
|
+
return &f;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static inline VALUE
|
|
67
|
+
pg_tuple_get_field_names( t_pg_tuple *this )
|
|
68
|
+
{
|
|
69
|
+
return *pg_tuple_get_field_names_ptr(this);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static void
|
|
73
|
+
pg_tuple_gc_mark( void *_this )
|
|
74
|
+
{
|
|
75
|
+
t_pg_tuple *this = (t_pg_tuple *)_this;
|
|
76
|
+
int i;
|
|
77
|
+
|
|
78
|
+
if( !this ) return;
|
|
79
|
+
rb_gc_mark_movable( this->result );
|
|
80
|
+
rb_gc_mark_movable( this->typemap );
|
|
81
|
+
rb_gc_mark_movable( this->field_map );
|
|
82
|
+
|
|
83
|
+
for( i = 0; i < this->num_fields; i++ ){
|
|
84
|
+
rb_gc_mark_movable( this->values[i] );
|
|
62
85
|
}
|
|
86
|
+
rb_gc_mark_movable( pg_tuple_get_field_names(this) );
|
|
63
87
|
}
|
|
64
88
|
|
|
65
89
|
static void
|
|
66
|
-
|
|
90
|
+
pg_tuple_gc_compact( void *_this )
|
|
67
91
|
{
|
|
92
|
+
t_pg_tuple *this = (t_pg_tuple *)_this;
|
|
68
93
|
int i;
|
|
69
94
|
|
|
70
95
|
if( !this ) return;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
pg_gc_location( this->result );
|
|
97
|
+
pg_gc_location( this->typemap );
|
|
98
|
+
pg_gc_location( this->field_map );
|
|
74
99
|
|
|
75
100
|
for( i = 0; i < this->num_fields; i++ ){
|
|
76
|
-
|
|
101
|
+
pg_gc_location( this->values[i] );
|
|
77
102
|
}
|
|
78
|
-
|
|
103
|
+
pg_gc_location( *pg_tuple_get_field_names_ptr(this) );
|
|
79
104
|
}
|
|
80
105
|
|
|
81
106
|
static void
|
|
82
|
-
pg_tuple_gc_free(
|
|
107
|
+
pg_tuple_gc_free( void *_this )
|
|
83
108
|
{
|
|
109
|
+
t_pg_tuple *this = (t_pg_tuple *)_this;
|
|
84
110
|
if( !this ) return;
|
|
85
111
|
xfree(this);
|
|
86
112
|
}
|
|
87
113
|
|
|
88
114
|
static size_t
|
|
89
|
-
pg_tuple_memsize(
|
|
115
|
+
pg_tuple_memsize( const void *_this )
|
|
90
116
|
{
|
|
117
|
+
const t_pg_tuple *this = (const t_pg_tuple *)_this;
|
|
91
118
|
if( this==NULL ) return 0;
|
|
92
119
|
return sizeof(*this) + sizeof(*this->values) * this->num_fields;
|
|
93
120
|
}
|
|
94
121
|
|
|
95
122
|
static const rb_data_type_t pg_tuple_type = {
|
|
96
|
-
"
|
|
123
|
+
"PG::Tuple",
|
|
97
124
|
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
125
|
+
pg_tuple_gc_mark,
|
|
126
|
+
pg_tuple_gc_free,
|
|
127
|
+
pg_tuple_memsize,
|
|
128
|
+
pg_compact_callback(pg_tuple_gc_compact),
|
|
101
129
|
},
|
|
102
130
|
0, 0,
|
|
103
|
-
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
104
131
|
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
105
|
-
#endif
|
|
106
132
|
};
|
|
107
133
|
|
|
108
134
|
/*
|
|
@@ -172,7 +198,7 @@ pg_tuple_materialize_field(t_pg_tuple *this, int col)
|
|
|
172
198
|
VALUE value = this->values[col];
|
|
173
199
|
|
|
174
200
|
if( value == Qundef ){
|
|
175
|
-
t_typemap *p_typemap =
|
|
201
|
+
t_typemap *p_typemap = RTYPEDDATA_DATA( this->typemap );
|
|
176
202
|
|
|
177
203
|
pgresult_get(this->result); /* make sure we have a valid PGresult object */
|
|
178
204
|
value = p_typemap->funcs.typecast_result_value(p_typemap, this->result, this->row_num, col);
|
|
@@ -445,10 +471,7 @@ pg_tuple_dump(VALUE self)
|
|
|
445
471
|
values = rb_ary_new4(this->num_fields, &this->values[0]);
|
|
446
472
|
a = rb_ary_new3(2, field_names, values);
|
|
447
473
|
|
|
448
|
-
|
|
449
|
-
rb_copy_generic_ivar(a, self);
|
|
450
|
-
FL_SET(a, FL_EXIVAR);
|
|
451
|
-
}
|
|
474
|
+
rb_copy_generic_ivar(a, self);
|
|
452
475
|
|
|
453
476
|
return a;
|
|
454
477
|
}
|
|
@@ -479,9 +502,9 @@ pg_tuple_load(VALUE self, VALUE a)
|
|
|
479
502
|
rb_obj_freeze(field_names);
|
|
480
503
|
values = RARRAY_AREF(a, 1);
|
|
481
504
|
Check_Type(values, T_ARRAY);
|
|
482
|
-
num_fields =
|
|
505
|
+
num_fields = RARRAY_LENINT(values);
|
|
483
506
|
|
|
484
|
-
if (
|
|
507
|
+
if (RARRAY_LENINT(field_names) != num_fields)
|
|
485
508
|
rb_raise(rb_eTypeError, "different number of fields and values");
|
|
486
509
|
|
|
487
510
|
field_map = rb_hash_new();
|
|
@@ -516,16 +539,13 @@ pg_tuple_load(VALUE self, VALUE a)
|
|
|
516
539
|
|
|
517
540
|
RTYPEDDATA_DATA(self) = this;
|
|
518
541
|
|
|
519
|
-
|
|
520
|
-
rb_copy_generic_ivar(self, a);
|
|
521
|
-
FL_SET(self, FL_EXIVAR);
|
|
522
|
-
}
|
|
542
|
+
rb_copy_generic_ivar(self, a);
|
|
523
543
|
|
|
524
544
|
return self;
|
|
525
545
|
}
|
|
526
546
|
|
|
527
547
|
void
|
|
528
|
-
init_pg_tuple()
|
|
548
|
+
init_pg_tuple(void)
|
|
529
549
|
{
|
|
530
550
|
rb_cPG_Tuple = rb_define_class_under( rb_mPG, "Tuple", rb_cObject );
|
|
531
551
|
rb_define_alloc_func( rb_cPG_Tuple, pg_tuple_s_allocate );
|
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
|
}
|
|
@@ -143,7 +176,7 @@ pg_typemap_with_default_type_map(VALUE self, VALUE typemap)
|
|
|
143
176
|
}
|
|
144
177
|
|
|
145
178
|
void
|
|
146
|
-
init_pg_type_map()
|
|
179
|
+
init_pg_type_map(void)
|
|
147
180
|
{
|
|
148
181
|
s_id_fit_to_query = rb_intern("fit_to_query");
|
|
149
182
|
s_id_fit_to_result = rb_intern("fit_to_result");
|
|
@@ -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
|
|
|
@@ -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
|
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,32 +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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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 )
|
|
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. */
|
|
133
147
|
memset(&this->cache_row, 0, sizeof(this->cache_row));
|
|
134
148
|
}
|
|
135
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
|
+
|
|
136
163
|
static VALUE
|
|
137
164
|
pg_tmbk_s_allocate( VALUE klass )
|
|
138
165
|
{
|
|
139
166
|
t_tmbk *this;
|
|
140
167
|
VALUE self;
|
|
141
168
|
|
|
142
|
-
self =
|
|
169
|
+
self = TypedData_Make_Struct( klass, t_tmbk, &pg_tmbk_type, this );
|
|
143
170
|
this->typemap.funcs.fit_to_result = pg_typemap_fit_to_result;
|
|
144
171
|
this->typemap.funcs.fit_to_query = pg_tmbk_fit_to_query;
|
|
145
172
|
this->typemap.funcs.fit_to_copy_get = pg_typemap_fit_to_copy_get;
|
|
@@ -153,7 +180,7 @@ pg_tmbk_s_allocate( VALUE klass )
|
|
|
153
180
|
this->self = self;
|
|
154
181
|
this->klass_to_coder = rb_hash_new();
|
|
155
182
|
|
|
156
|
-
/* The cache is properly initialized by
|
|
183
|
+
/* The cache is properly initialized by TypedData_Make_Struct(). */
|
|
157
184
|
|
|
158
185
|
return self;
|
|
159
186
|
}
|
|
@@ -176,7 +203,7 @@ pg_tmbk_s_allocate( VALUE klass )
|
|
|
176
203
|
static VALUE
|
|
177
204
|
pg_tmbk_aset( VALUE self, VALUE klass, VALUE coder )
|
|
178
205
|
{
|
|
179
|
-
t_tmbk *this =
|
|
206
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
|
180
207
|
|
|
181
208
|
if(NIL_P(coder)){
|
|
182
209
|
rb_hash_delete( this->klass_to_coder, klass );
|
|
@@ -200,7 +227,7 @@ pg_tmbk_aset( VALUE self, VALUE klass, VALUE coder )
|
|
|
200
227
|
static VALUE
|
|
201
228
|
pg_tmbk_aref( VALUE self, VALUE klass )
|
|
202
229
|
{
|
|
203
|
-
t_tmbk *this =
|
|
230
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
|
204
231
|
|
|
205
232
|
return rb_hash_lookup(this->klass_to_coder, klass);
|
|
206
233
|
}
|
|
@@ -214,16 +241,14 @@ pg_tmbk_aref( VALUE self, VALUE klass )
|
|
|
214
241
|
static VALUE
|
|
215
242
|
pg_tmbk_coders( VALUE self )
|
|
216
243
|
{
|
|
217
|
-
t_tmbk *this =
|
|
244
|
+
t_tmbk *this = RTYPEDDATA_DATA( self );
|
|
218
245
|
|
|
219
246
|
return rb_obj_freeze(rb_hash_dup(this->klass_to_coder));
|
|
220
247
|
}
|
|
221
248
|
|
|
222
249
|
void
|
|
223
|
-
init_pg_type_map_by_class()
|
|
250
|
+
init_pg_type_map_by_class(void)
|
|
224
251
|
{
|
|
225
|
-
s_id_ancestors = rb_intern("ancestors");
|
|
226
|
-
|
|
227
252
|
/*
|
|
228
253
|
* Document-class: PG::TypeMapByClass < PG::TypeMap
|
|
229
254
|
*
|