panko_serializer 0.8.5 → 1.0.0
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
- data/README.md +6 -4
- data/lib/panko/array_serializer.rb +55 -16
- data/lib/panko/code_gen/active_record/access_classifier.rb +65 -0
- data/lib/panko/code_gen/active_record/define_attribute_methods.rb +13 -0
- data/lib/panko/code_gen/code_builder.rb +32 -0
- data/lib/panko/code_gen/compile_cache.rb +28 -0
- data/lib/panko/code_gen/compiler.rb +56 -0
- data/lib/panko/code_gen/config.rb +79 -0
- data/lib/panko/code_gen/datetime_format.rb +38 -0
- data/lib/panko/code_gen/descriptor.rb +136 -0
- data/lib/panko/code_gen/descriptor_builder.rb +166 -0
- data/lib/panko/code_gen/dump.rb +52 -0
- data/lib/panko/code_gen/errors.rb +21 -0
- data/lib/panko/code_gen/filter.rb +29 -0
- data/lib/panko/code_gen/filter_adapter.rb +44 -0
- data/lib/panko/code_gen/filters/indexed.rb +62 -0
- data/lib/panko/code_gen/filters/none.rb +19 -0
- data/lib/panko/code_gen/generator.rb +23 -0
- data/lib/panko/code_gen/generators/banner.rb +27 -0
- data/lib/panko/code_gen/generators/class_emitter.rb +120 -0
- data/lib/panko/code_gen/generators/cycle_membership.rb +53 -0
- data/lib/panko/code_gen/generators/descriptor_walk.rb +22 -0
- data/lib/panko/code_gen/generators/fanout.rb +60 -0
- data/lib/panko/code_gen/generators/field_index.rb +31 -0
- data/lib/panko/code_gen/generators/field_walk.rb +38 -0
- data/lib/panko/code_gen/generators/generated_names.rb +73 -0
- data/lib/panko/code_gen/generators/hash_sink.rb +217 -0
- data/lib/panko/code_gen/generators/json_sink.rb +290 -0
- data/lib/panko/code_gen/generators/record_access/generic.rb +92 -0
- data/lib/panko/code_gen/generators/record_access/specialized.rb +90 -0
- data/lib/panko/code_gen/generators/release.rb +60 -0
- data/lib/panko/code_gen/generators/sink.rb +80 -0
- data/lib/panko/code_gen/instance_pool.rb +27 -0
- data/lib/panko/code_gen/runtime.rb +27 -0
- data/lib/panko/code_gen/serializer_cache.rb +242 -0
- data/lib/panko/code_gen/validators/callable_arity.rb +42 -0
- data/lib/panko/code_gen/validators/name_uniqueness.rb +44 -0
- data/lib/panko/code_gen/validators/source_resolution.rb +48 -0
- data/lib/panko/code_gen/validators/validator.rb +19 -0
- data/lib/panko/code_gen/writers_pool.rb +51 -0
- data/lib/panko/code_gen.rb +82 -0
- data/lib/panko/compile_all.rb +80 -0
- data/lib/panko/compile_all_result.rb +21 -0
- data/lib/panko/config.rb +71 -0
- data/lib/panko/descriptor.rb +93 -0
- data/lib/panko/response.rb +40 -8
- data/lib/panko/serializer.rb +175 -91
- data/lib/panko/serializer_resolver.rb +2 -8
- data/lib/panko/version.rb +1 -1
- data/lib/panko_serializer.rb +3 -5
- metadata +49 -35
- data/ext/panko_serializer/attributes_writer/active_record.c +0 -181
- data/ext/panko_serializer/attributes_writer/active_record.h +0 -17
- data/ext/panko_serializer/attributes_writer/attributes_writer.c +0 -55
- data/ext/panko_serializer/attributes_writer/attributes_writer.h +0 -35
- data/ext/panko_serializer/attributes_writer/common.c +0 -10
- data/ext/panko_serializer/attributes_writer/common.h +0 -9
- data/ext/panko_serializer/attributes_writer/hash.c +0 -13
- data/ext/panko_serializer/attributes_writer/hash.h +0 -7
- data/ext/panko_serializer/attributes_writer/plain.c +0 -13
- data/ext/panko_serializer/attributes_writer/plain.h +0 -7
- data/ext/panko_serializer/attributes_writer/type_cast/time_conversion.c +0 -156
- data/ext/panko_serializer/attributes_writer/type_cast/time_conversion.h +0 -10
- data/ext/panko_serializer/attributes_writer/type_cast/type_cast.c +0 -409
- data/ext/panko_serializer/attributes_writer/type_cast/type_cast.h +0 -81
- data/ext/panko_serializer/common.h +0 -9
- data/ext/panko_serializer/extconf.rb +0 -28
- data/ext/panko_serializer/panko_serializer.c +0 -181
- data/ext/panko_serializer/panko_serializer.h +0 -12
- data/ext/panko_serializer/serialization_descriptor/association.c +0 -90
- data/ext/panko_serializer/serialization_descriptor/association.h +0 -20
- data/ext/panko_serializer/serialization_descriptor/attribute.c +0 -96
- data/ext/panko_serializer/serialization_descriptor/attribute.h +0 -27
- data/ext/panko_serializer/serialization_descriptor/serialization_descriptor.c +0 -177
- data/ext/panko_serializer/serialization_descriptor/serialization_descriptor.h +0 -30
- data/lib/panko/association.rb +0 -17
- data/lib/panko/attribute.rb +0 -29
- data/lib/panko/object_writer.rb +0 -68
- data/lib/panko/serialization_descriptor.rb +0 -180
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: panko_serializer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yosi Attias
|
|
@@ -35,14 +35,14 @@ dependencies:
|
|
|
35
35
|
requirements:
|
|
36
36
|
- - ">="
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: '
|
|
38
|
+
version: '7.2'
|
|
39
39
|
type: :runtime
|
|
40
40
|
prerelease: false
|
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
|
42
42
|
requirements:
|
|
43
43
|
- - ">="
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: '
|
|
45
|
+
version: '7.2'
|
|
46
46
|
- !ruby/object:Gem::Dependency
|
|
47
47
|
name: appraisal
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -60,42 +60,56 @@ dependencies:
|
|
|
60
60
|
email:
|
|
61
61
|
- yosy101@gmail.com
|
|
62
62
|
executables: []
|
|
63
|
-
extensions:
|
|
64
|
-
- ext/panko_serializer/extconf.rb
|
|
63
|
+
extensions: []
|
|
65
64
|
extra_rdoc_files: []
|
|
66
65
|
files:
|
|
67
66
|
- LICENSE.txt
|
|
68
67
|
- README.md
|
|
69
|
-
- ext/panko_serializer/attributes_writer/active_record.c
|
|
70
|
-
- ext/panko_serializer/attributes_writer/active_record.h
|
|
71
|
-
- ext/panko_serializer/attributes_writer/attributes_writer.c
|
|
72
|
-
- ext/panko_serializer/attributes_writer/attributes_writer.h
|
|
73
|
-
- ext/panko_serializer/attributes_writer/common.c
|
|
74
|
-
- ext/panko_serializer/attributes_writer/common.h
|
|
75
|
-
- ext/panko_serializer/attributes_writer/hash.c
|
|
76
|
-
- ext/panko_serializer/attributes_writer/hash.h
|
|
77
|
-
- ext/panko_serializer/attributes_writer/plain.c
|
|
78
|
-
- ext/panko_serializer/attributes_writer/plain.h
|
|
79
|
-
- ext/panko_serializer/attributes_writer/type_cast/time_conversion.c
|
|
80
|
-
- ext/panko_serializer/attributes_writer/type_cast/time_conversion.h
|
|
81
|
-
- ext/panko_serializer/attributes_writer/type_cast/type_cast.c
|
|
82
|
-
- ext/panko_serializer/attributes_writer/type_cast/type_cast.h
|
|
83
|
-
- ext/panko_serializer/common.h
|
|
84
|
-
- ext/panko_serializer/extconf.rb
|
|
85
|
-
- ext/panko_serializer/panko_serializer.c
|
|
86
|
-
- ext/panko_serializer/panko_serializer.h
|
|
87
|
-
- ext/panko_serializer/serialization_descriptor/association.c
|
|
88
|
-
- ext/panko_serializer/serialization_descriptor/association.h
|
|
89
|
-
- ext/panko_serializer/serialization_descriptor/attribute.c
|
|
90
|
-
- ext/panko_serializer/serialization_descriptor/attribute.h
|
|
91
|
-
- ext/panko_serializer/serialization_descriptor/serialization_descriptor.c
|
|
92
|
-
- ext/panko_serializer/serialization_descriptor/serialization_descriptor.h
|
|
93
68
|
- lib/panko/array_serializer.rb
|
|
94
|
-
- lib/panko/
|
|
95
|
-
- lib/panko/
|
|
96
|
-
- lib/panko/
|
|
69
|
+
- lib/panko/code_gen.rb
|
|
70
|
+
- lib/panko/code_gen/active_record/access_classifier.rb
|
|
71
|
+
- lib/panko/code_gen/active_record/define_attribute_methods.rb
|
|
72
|
+
- lib/panko/code_gen/code_builder.rb
|
|
73
|
+
- lib/panko/code_gen/compile_cache.rb
|
|
74
|
+
- lib/panko/code_gen/compiler.rb
|
|
75
|
+
- lib/panko/code_gen/config.rb
|
|
76
|
+
- lib/panko/code_gen/datetime_format.rb
|
|
77
|
+
- lib/panko/code_gen/descriptor.rb
|
|
78
|
+
- lib/panko/code_gen/descriptor_builder.rb
|
|
79
|
+
- lib/panko/code_gen/dump.rb
|
|
80
|
+
- lib/panko/code_gen/errors.rb
|
|
81
|
+
- lib/panko/code_gen/filter.rb
|
|
82
|
+
- lib/panko/code_gen/filter_adapter.rb
|
|
83
|
+
- lib/panko/code_gen/filters/indexed.rb
|
|
84
|
+
- lib/panko/code_gen/filters/none.rb
|
|
85
|
+
- lib/panko/code_gen/generator.rb
|
|
86
|
+
- lib/panko/code_gen/generators/banner.rb
|
|
87
|
+
- lib/panko/code_gen/generators/class_emitter.rb
|
|
88
|
+
- lib/panko/code_gen/generators/cycle_membership.rb
|
|
89
|
+
- lib/panko/code_gen/generators/descriptor_walk.rb
|
|
90
|
+
- lib/panko/code_gen/generators/fanout.rb
|
|
91
|
+
- lib/panko/code_gen/generators/field_index.rb
|
|
92
|
+
- lib/panko/code_gen/generators/field_walk.rb
|
|
93
|
+
- lib/panko/code_gen/generators/generated_names.rb
|
|
94
|
+
- lib/panko/code_gen/generators/hash_sink.rb
|
|
95
|
+
- lib/panko/code_gen/generators/json_sink.rb
|
|
96
|
+
- lib/panko/code_gen/generators/record_access/generic.rb
|
|
97
|
+
- lib/panko/code_gen/generators/record_access/specialized.rb
|
|
98
|
+
- lib/panko/code_gen/generators/release.rb
|
|
99
|
+
- lib/panko/code_gen/generators/sink.rb
|
|
100
|
+
- lib/panko/code_gen/instance_pool.rb
|
|
101
|
+
- lib/panko/code_gen/runtime.rb
|
|
102
|
+
- lib/panko/code_gen/serializer_cache.rb
|
|
103
|
+
- lib/panko/code_gen/validators/callable_arity.rb
|
|
104
|
+
- lib/panko/code_gen/validators/name_uniqueness.rb
|
|
105
|
+
- lib/panko/code_gen/validators/source_resolution.rb
|
|
106
|
+
- lib/panko/code_gen/validators/validator.rb
|
|
107
|
+
- lib/panko/code_gen/writers_pool.rb
|
|
108
|
+
- lib/panko/compile_all.rb
|
|
109
|
+
- lib/panko/compile_all_result.rb
|
|
110
|
+
- lib/panko/config.rb
|
|
111
|
+
- lib/panko/descriptor.rb
|
|
97
112
|
- lib/panko/response.rb
|
|
98
|
-
- lib/panko/serialization_descriptor.rb
|
|
99
113
|
- lib/panko/serializer.rb
|
|
100
114
|
- lib/panko/serializer_resolver.rb
|
|
101
115
|
- lib/panko/version.rb
|
|
@@ -115,14 +129,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
115
129
|
requirements:
|
|
116
130
|
- - ">="
|
|
117
131
|
- !ruby/object:Gem::Version
|
|
118
|
-
version: 3.
|
|
132
|
+
version: '3.4'
|
|
119
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
134
|
requirements:
|
|
121
135
|
- - ">="
|
|
122
136
|
- !ruby/object:Gem::Version
|
|
123
137
|
version: '0'
|
|
124
138
|
requirements: []
|
|
125
|
-
rubygems_version:
|
|
139
|
+
rubygems_version: 4.0.20
|
|
126
140
|
specification_version: 4
|
|
127
141
|
summary: High Performance JSON Serialization for ActiveRecord & Ruby Objects
|
|
128
142
|
test_files: []
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
#include "active_record.h"
|
|
2
|
-
|
|
3
|
-
static ID attributes_id;
|
|
4
|
-
static ID types_id;
|
|
5
|
-
static ID additional_types_id;
|
|
6
|
-
static ID values_id;
|
|
7
|
-
static ID delegate_hash_id;
|
|
8
|
-
|
|
9
|
-
static ID value_before_type_cast_id;
|
|
10
|
-
static ID type_id;
|
|
11
|
-
|
|
12
|
-
static ID fetch_id;
|
|
13
|
-
|
|
14
|
-
struct attributes {
|
|
15
|
-
// Hash
|
|
16
|
-
VALUE attributes_hash;
|
|
17
|
-
size_t attributes_hash_size;
|
|
18
|
-
|
|
19
|
-
// Hash
|
|
20
|
-
VALUE types;
|
|
21
|
-
// Hash
|
|
22
|
-
VALUE additional_types;
|
|
23
|
-
// heuristics
|
|
24
|
-
bool tryToReadFromAdditionalTypes;
|
|
25
|
-
|
|
26
|
-
// Rails <8: Hash
|
|
27
|
-
// Rails >=8: ActiveRecord::Result::IndexedRow
|
|
28
|
-
VALUE values;
|
|
29
|
-
|
|
30
|
-
// Hash
|
|
31
|
-
VALUE indexed_row_column_indexes;
|
|
32
|
-
// Array or NIL
|
|
33
|
-
VALUE indexed_row_row;
|
|
34
|
-
bool is_indexed_row;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
struct attributes init_context(VALUE obj) {
|
|
38
|
-
volatile VALUE attributes_set = rb_ivar_get(obj, attributes_id);
|
|
39
|
-
volatile VALUE attributes_hash = rb_ivar_get(attributes_set, attributes_id);
|
|
40
|
-
|
|
41
|
-
struct attributes attrs = (struct attributes){
|
|
42
|
-
.attributes_hash =
|
|
43
|
-
PANKO_EMPTY_HASH(attributes_hash) ? Qnil : attributes_hash,
|
|
44
|
-
.attributes_hash_size = 0,
|
|
45
|
-
.types = rb_ivar_get(attributes_set, types_id),
|
|
46
|
-
.additional_types = rb_ivar_get(attributes_set, additional_types_id),
|
|
47
|
-
.tryToReadFromAdditionalTypes =
|
|
48
|
-
PANKO_EMPTY_HASH(rb_ivar_get(attributes_set, additional_types_id)) ==
|
|
49
|
-
false,
|
|
50
|
-
.values = rb_ivar_get(attributes_set, values_id),
|
|
51
|
-
.is_indexed_row = false,
|
|
52
|
-
.indexed_row_column_indexes = Qnil,
|
|
53
|
-
.indexed_row_row = Qnil,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
if (attrs.attributes_hash != Qnil) {
|
|
57
|
-
attrs.attributes_hash_size = RHASH_SIZE(attrs.attributes_hash);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (strcmp(rb_class2name(CLASS_OF(attrs.values)),
|
|
61
|
-
"ActiveRecord::Result::IndexedRow") == 0) {
|
|
62
|
-
volatile VALUE indexed_row_column_indexes =
|
|
63
|
-
rb_ivar_get(attrs.values, rb_intern("@column_indexes"));
|
|
64
|
-
volatile VALUE indexed_row_row =
|
|
65
|
-
rb_ivar_get(attrs.values, rb_intern("@row"));
|
|
66
|
-
|
|
67
|
-
attrs.indexed_row_column_indexes = indexed_row_column_indexes;
|
|
68
|
-
attrs.indexed_row_row = indexed_row_row;
|
|
69
|
-
attrs.is_indexed_row = true;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return attrs;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
VALUE _read_value_from_indexed_row(struct attributes attributes_ctx,
|
|
76
|
-
volatile VALUE member) {
|
|
77
|
-
volatile VALUE value = Qnil;
|
|
78
|
-
|
|
79
|
-
if (NIL_P(attributes_ctx.indexed_row_column_indexes) ||
|
|
80
|
-
NIL_P(attributes_ctx.indexed_row_row)) {
|
|
81
|
-
return value;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
volatile VALUE column_index =
|
|
85
|
-
rb_hash_aref(attributes_ctx.indexed_row_column_indexes, member);
|
|
86
|
-
|
|
87
|
-
if (NIL_P(column_index)) {
|
|
88
|
-
return value;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
volatile VALUE row = attributes_ctx.indexed_row_row;
|
|
92
|
-
if (NIL_P(row)) {
|
|
93
|
-
return value;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return RARRAY_AREF(row, NUM2INT(column_index));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute,
|
|
100
|
-
volatile VALUE* isJson) {
|
|
101
|
-
volatile VALUE member, value;
|
|
102
|
-
|
|
103
|
-
member = attribute->name_str;
|
|
104
|
-
value = Qnil;
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
// we have attributes_hash
|
|
108
|
-
!NIL_P(attributes_ctx.attributes_hash)
|
|
109
|
-
// It's not empty
|
|
110
|
-
&& (attributes_ctx.attributes_hash_size > 0)) {
|
|
111
|
-
volatile VALUE attribute_metadata =
|
|
112
|
-
rb_hash_aref(attributes_ctx.attributes_hash, member);
|
|
113
|
-
|
|
114
|
-
if (attribute_metadata != Qnil) {
|
|
115
|
-
value = rb_ivar_get(attribute_metadata, value_before_type_cast_id);
|
|
116
|
-
|
|
117
|
-
if (NIL_P(attribute->type)) {
|
|
118
|
-
attribute->type = rb_ivar_get(attribute_metadata, type_id);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (NIL_P(value) && !NIL_P(attributes_ctx.values)) {
|
|
124
|
-
if (attributes_ctx.is_indexed_row == true) {
|
|
125
|
-
value = _read_value_from_indexed_row(attributes_ctx, member);
|
|
126
|
-
} else {
|
|
127
|
-
value = rb_hash_aref(attributes_ctx.values, member);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (NIL_P(attribute->type) && !NIL_P(value)) {
|
|
132
|
-
if (attributes_ctx.tryToReadFromAdditionalTypes == true) {
|
|
133
|
-
attribute->type = rb_hash_aref(attributes_ctx.additional_types, member);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!NIL_P(attributes_ctx.types) && NIL_P(attribute->type)) {
|
|
137
|
-
attribute->type = rb_hash_aref(attributes_ctx.types, member);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (!NIL_P(attribute->type) && !NIL_P(value)) {
|
|
142
|
-
return type_cast(attribute->type, value, isJson);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return value;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
void active_record_attributes_writer(VALUE obj, VALUE attributes,
|
|
149
|
-
EachAttributeFunc write_value,
|
|
150
|
-
VALUE writer) {
|
|
151
|
-
long i;
|
|
152
|
-
struct attributes attributes_ctx = init_context(obj);
|
|
153
|
-
volatile VALUE record_class = CLASS_OF(obj);
|
|
154
|
-
|
|
155
|
-
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
|
156
|
-
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
|
157
|
-
Attribute attribute = PANKO_ATTRIBUTE_READ(raw_attribute);
|
|
158
|
-
attribute_try_invalidate(attribute, record_class);
|
|
159
|
-
|
|
160
|
-
volatile VALUE isJson = Qfalse;
|
|
161
|
-
volatile VALUE value = read_attribute(attributes_ctx, attribute, &isJson);
|
|
162
|
-
|
|
163
|
-
write_value(writer, attr_name_for_serialization(attribute), value, isJson);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
void init_active_record_attributes_writer(VALUE mPanko) {
|
|
168
|
-
attributes_id = rb_intern("@attributes");
|
|
169
|
-
delegate_hash_id = rb_intern("@delegate_hash");
|
|
170
|
-
values_id = rb_intern("@values");
|
|
171
|
-
types_id = rb_intern("@types");
|
|
172
|
-
additional_types_id = rb_intern("@additional_types");
|
|
173
|
-
type_id = rb_intern("@type");
|
|
174
|
-
value_before_type_cast_id = rb_intern("@value_before_type_cast");
|
|
175
|
-
fetch_id = rb_intern("fetch");
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
void panko_init_active_record(VALUE mPanko) {
|
|
179
|
-
init_active_record_attributes_writer(mPanko);
|
|
180
|
-
panko_init_type_cast(mPanko);
|
|
181
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <ruby.h>
|
|
4
|
-
#include <stdbool.h>
|
|
5
|
-
|
|
6
|
-
#include "../common.h"
|
|
7
|
-
#include "common.h"
|
|
8
|
-
#include "serialization_descriptor/attribute.h"
|
|
9
|
-
#include "type_cast/type_cast.h"
|
|
10
|
-
|
|
11
|
-
extern void active_record_attributes_writer(VALUE object, VALUE attributes,
|
|
12
|
-
EachAttributeFunc func,
|
|
13
|
-
VALUE writer);
|
|
14
|
-
|
|
15
|
-
void init_active_record_attributes_writer(VALUE mPanko);
|
|
16
|
-
|
|
17
|
-
void panko_init_active_record(VALUE mPanko);
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
#include "attributes_writer.h"
|
|
2
|
-
|
|
3
|
-
static bool types_initialized = false;
|
|
4
|
-
static VALUE ar_base_type = Qundef;
|
|
5
|
-
|
|
6
|
-
VALUE init_types(VALUE v) {
|
|
7
|
-
if (types_initialized == true) {
|
|
8
|
-
return Qundef;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
types_initialized = true;
|
|
12
|
-
|
|
13
|
-
volatile VALUE ar_type =
|
|
14
|
-
rb_const_get_at(rb_cObject, rb_intern("ActiveRecord"));
|
|
15
|
-
|
|
16
|
-
ar_base_type = rb_const_get_at(ar_type, rb_intern("Base"));
|
|
17
|
-
rb_global_variable(&ar_base_type);
|
|
18
|
-
|
|
19
|
-
return Qundef;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
AttributesWriter create_attributes_writer(VALUE object) {
|
|
23
|
-
// If ActiveRecord::Base can't be found it will throw error
|
|
24
|
-
int isErrored;
|
|
25
|
-
rb_protect(init_types, Qnil, &isErrored);
|
|
26
|
-
|
|
27
|
-
if (ar_base_type != Qundef &&
|
|
28
|
-
rb_obj_is_kind_of(object, ar_base_type) == Qtrue) {
|
|
29
|
-
return (AttributesWriter){
|
|
30
|
-
.object_type = ActiveRecord,
|
|
31
|
-
.write_attributes = active_record_attributes_writer};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!RB_SPECIAL_CONST_P(object) && BUILTIN_TYPE(object) == T_HASH) {
|
|
35
|
-
return (AttributesWriter){.object_type = Hash,
|
|
36
|
-
.write_attributes = hash_attributes_writer};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (AttributesWriter){.object_type = Plain,
|
|
40
|
-
.write_attributes = plain_attributes_writer};
|
|
41
|
-
|
|
42
|
-
return create_empty_attributes_writer();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
void empty_write_attributes(VALUE obj, VALUE attributes, EachAttributeFunc func,
|
|
46
|
-
VALUE writer) {}
|
|
47
|
-
|
|
48
|
-
AttributesWriter create_empty_attributes_writer() {
|
|
49
|
-
return (AttributesWriter){.object_type = UnknownObjectType,
|
|
50
|
-
.write_attributes = empty_write_attributes};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
void init_attributes_writer(VALUE mPanko) {
|
|
54
|
-
init_active_record_attributes_writer(mPanko);
|
|
55
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <ruby.h>
|
|
4
|
-
|
|
5
|
-
#include "active_record.h"
|
|
6
|
-
#include "common.h"
|
|
7
|
-
#include "hash.h"
|
|
8
|
-
#include "plain.h"
|
|
9
|
-
|
|
10
|
-
enum ObjectType {
|
|
11
|
-
UnknownObjectType = 0,
|
|
12
|
-
ActiveRecord = 1,
|
|
13
|
-
Plain = 2,
|
|
14
|
-
Hash = 3
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
typedef struct _AttributesWriter {
|
|
18
|
-
enum ObjectType object_type;
|
|
19
|
-
|
|
20
|
-
void (*write_attributes)(VALUE object, VALUE attributes,
|
|
21
|
-
EachAttributeFunc func, VALUE context);
|
|
22
|
-
} AttributesWriter;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Infers the attributes writer from the object type
|
|
26
|
-
*/
|
|
27
|
-
AttributesWriter create_attributes_writer(VALUE object);
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Creates empty writer
|
|
31
|
-
* Useful when the writer is not known, and you need init something
|
|
32
|
-
*/
|
|
33
|
-
AttributesWriter create_empty_attributes_writer();
|
|
34
|
-
|
|
35
|
-
void init_attributes_writer(VALUE mPanko);
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#include "hash.h"
|
|
2
|
-
|
|
3
|
-
void hash_attributes_writer(VALUE obj, VALUE attributes,
|
|
4
|
-
EachAttributeFunc write_value, VALUE writer) {
|
|
5
|
-
long i;
|
|
6
|
-
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
|
7
|
-
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
|
8
|
-
Attribute attribute = attribute_read(raw_attribute);
|
|
9
|
-
|
|
10
|
-
write_value(writer, attr_name_for_serialization(attribute),
|
|
11
|
-
rb_hash_aref(obj, attribute->name_str), Qfalse);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#include "plain.h"
|
|
2
|
-
|
|
3
|
-
void plain_attributes_writer(VALUE obj, VALUE attributes,
|
|
4
|
-
EachAttributeFunc write_value, VALUE writer) {
|
|
5
|
-
long i;
|
|
6
|
-
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
|
7
|
-
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
|
8
|
-
Attribute attribute = attribute_read(raw_attribute);
|
|
9
|
-
|
|
10
|
-
write_value(writer, attr_name_for_serialization(attribute),
|
|
11
|
-
rb_funcall(obj, attribute->name_id, 0), Qfalse);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
#include "time_conversion.h"
|
|
2
|
-
|
|
3
|
-
const int YEAR_REGION = 1;
|
|
4
|
-
const int MONTH_REGION = 2;
|
|
5
|
-
const int DAY_REGION = 3;
|
|
6
|
-
const int HOUR_REGION = 4;
|
|
7
|
-
const int MINUTE_REGION = 5;
|
|
8
|
-
const int SECOND_REGION = 6;
|
|
9
|
-
|
|
10
|
-
static regex_t* iso8601_time_regex;
|
|
11
|
-
static regex_t* ar_iso_datetime_regex;
|
|
12
|
-
|
|
13
|
-
VALUE is_iso8601_time_string(const char* value) {
|
|
14
|
-
const UChar *start, *range, *end;
|
|
15
|
-
OnigPosition r;
|
|
16
|
-
|
|
17
|
-
const UChar* str = (const UChar*)(value);
|
|
18
|
-
|
|
19
|
-
end = str + strlen(value);
|
|
20
|
-
start = str;
|
|
21
|
-
range = end;
|
|
22
|
-
r = onig_search(iso8601_time_regex, str, end, start, range, NULL,
|
|
23
|
-
ONIG_OPTION_NONE);
|
|
24
|
-
|
|
25
|
-
return r >= 0 ? Qtrue : Qfalse;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
void append_region_str(const char* source, char** to, int regionBegin,
|
|
29
|
-
int regionEnd) {
|
|
30
|
-
long iter = 0;
|
|
31
|
-
for (iter = regionBegin; iter < regionEnd; iter++) {
|
|
32
|
-
*(*to)++ = source[iter];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
bool is_iso_ar_iso_datetime_string_fast_case(const char* value) {
|
|
37
|
-
return (
|
|
38
|
-
// year
|
|
39
|
-
isdigit(value[0]) && isdigit(value[1]) && isdigit(value[2]) &&
|
|
40
|
-
isdigit(value[3]) && value[4] == '-' &&
|
|
41
|
-
// month
|
|
42
|
-
isdigit(value[5]) && isdigit(value[6]) && value[7] == '-' &&
|
|
43
|
-
// mday
|
|
44
|
-
isdigit(value[8]) && isdigit(value[9]) && value[10] == ' ' &&
|
|
45
|
-
|
|
46
|
-
// hour
|
|
47
|
-
isdigit(value[11]) && isdigit(value[12]) && value[13] == ':' &&
|
|
48
|
-
// minute
|
|
49
|
-
isdigit(value[14]) && isdigit(value[15]) && value[16] == ':' &&
|
|
50
|
-
// seconds
|
|
51
|
-
isdigit(value[17]) && isdigit(value[18]));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
bool is_iso_ar_iso_datetime_string_slow_case(const char* value) {
|
|
55
|
-
const UChar *start, *range, *end;
|
|
56
|
-
OnigPosition r;
|
|
57
|
-
OnigRegion* region = onig_region_new();
|
|
58
|
-
|
|
59
|
-
const UChar* str = (const UChar*)(value);
|
|
60
|
-
|
|
61
|
-
end = str + strlen(value);
|
|
62
|
-
start = str;
|
|
63
|
-
range = end;
|
|
64
|
-
r = onig_search(ar_iso_datetime_regex, str, end, start, range, region,
|
|
65
|
-
ONIG_OPTION_NONE);
|
|
66
|
-
|
|
67
|
-
onig_region_free(region, 1);
|
|
68
|
-
|
|
69
|
-
return (r >= 0);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
VALUE iso_ar_iso_datetime_string(const char* value) {
|
|
73
|
-
if (is_iso_ar_iso_datetime_string_fast_case(value) == true ||
|
|
74
|
-
is_iso_ar_iso_datetime_string_slow_case(value) == true) {
|
|
75
|
-
volatile VALUE output;
|
|
76
|
-
|
|
77
|
-
char buf[24] = "";
|
|
78
|
-
char* cur = buf;
|
|
79
|
-
|
|
80
|
-
append_region_str(value, &cur, 0, 4);
|
|
81
|
-
*cur++ = '-';
|
|
82
|
-
|
|
83
|
-
append_region_str(value, &cur, 5, 7);
|
|
84
|
-
*cur++ = '-';
|
|
85
|
-
|
|
86
|
-
append_region_str(value, &cur, 8, 10);
|
|
87
|
-
*cur++ = 'T';
|
|
88
|
-
|
|
89
|
-
append_region_str(value, &cur, 11, 13);
|
|
90
|
-
*cur++ = ':';
|
|
91
|
-
|
|
92
|
-
append_region_str(value, &cur, 14, 16);
|
|
93
|
-
*cur++ = ':';
|
|
94
|
-
|
|
95
|
-
append_region_str(value, &cur, 17, 19);
|
|
96
|
-
|
|
97
|
-
*cur++ = '.';
|
|
98
|
-
if (value[19] == '.' && isdigit(value[20])) {
|
|
99
|
-
if (isdigit(value[20])) {
|
|
100
|
-
*cur++ = value[20];
|
|
101
|
-
} else {
|
|
102
|
-
*cur++ = '0';
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (isdigit(value[21])) {
|
|
106
|
-
*cur++ = value[21];
|
|
107
|
-
} else {
|
|
108
|
-
*cur++ = '0';
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (isdigit(value[22])) {
|
|
112
|
-
*cur++ = value[22];
|
|
113
|
-
} else {
|
|
114
|
-
*cur++ = '0';
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
*cur++ = '0';
|
|
118
|
-
*cur++ = '0';
|
|
119
|
-
*cur++ = '0';
|
|
120
|
-
}
|
|
121
|
-
*cur++ = 'Z';
|
|
122
|
-
|
|
123
|
-
output = rb_str_new(buf, cur - buf);
|
|
124
|
-
return output;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return Qnil;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
void build_regex(OnigRegex* reg, const UChar* pattern) {
|
|
131
|
-
OnigErrorInfo einfo;
|
|
132
|
-
|
|
133
|
-
int r = onig_new(reg, pattern, pattern + strlen((char*)pattern),
|
|
134
|
-
ONIG_OPTION_DEFAULT, ONIG_ENCODING_ASCII,
|
|
135
|
-
ONIG_SYNTAX_DEFAULT, &einfo);
|
|
136
|
-
|
|
137
|
-
if (r != ONIG_NORMAL) {
|
|
138
|
-
char s[ONIG_MAX_ERROR_MESSAGE_LEN];
|
|
139
|
-
onig_error_code_to_str((UChar*)s, r, &einfo);
|
|
140
|
-
printf("ERROR: %s\n", s);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
void panko_init_time(VALUE mPanko) {
|
|
145
|
-
const UChar *ISO8601_PATTERN, *AR_ISO_DATETIME_PATTERN;
|
|
146
|
-
|
|
147
|
-
ISO8601_PATTERN =
|
|
148
|
-
(UChar*)"^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$";
|
|
149
|
-
|
|
150
|
-
build_regex(&iso8601_time_regex, ISO8601_PATTERN);
|
|
151
|
-
|
|
152
|
-
AR_ISO_DATETIME_PATTERN =
|
|
153
|
-
(UChar*)"\\A(?<year>\\d{4})-(?<month>\\d\\d)-(?<mday>\\d\\d) (?<hour>\\d\\d):(?<min>\\d\\d):(?<sec>\\d\\d)(\\.(?<microsec>\\d+))?\\z";
|
|
154
|
-
|
|
155
|
-
build_regex(&ar_iso_datetime_regex, AR_ISO_DATETIME_PATTERN);
|
|
156
|
-
}
|