panko_serializer 0.2.2 → 0.3.2
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 +1 -3
- data/_config.yml +1 -0
- data/benchmarks/bm_serialization_descriptor.rb +0 -8
- data/benchmarks/type_casts/bm_panko.rb +3 -3
- data/benchmarks/type_casts/support.rb +1 -0
- data/ext/panko_serializer/association.c +81 -0
- data/ext/panko_serializer/association.h +20 -0
- data/ext/panko_serializer/attribute.c +73 -0
- data/ext/panko_serializer/attribute.h +23 -0
- data/ext/panko_serializer/attributes_iterator.c +89 -52
- data/ext/panko_serializer/attributes_iterator.h +3 -6
- data/ext/panko_serializer/panko_serializer.c +19 -34
- data/ext/panko_serializer/panko_serializer.h +3 -1
- data/ext/panko_serializer/serialization_descriptor.c +62 -58
- data/ext/panko_serializer/serialization_descriptor.h +5 -7
- data/ext/panko_serializer/type_cast.c +38 -8
- data/ext/panko_serializer/type_cast.h +5 -0
- data/lib/panko/attribute.rb +30 -0
- data/lib/panko/response.rb +8 -0
- data/lib/panko/serialization_descriptor.rb +38 -28
- data/lib/panko/serializer.rb +21 -9
- data/lib/panko/version.rb +1 -1
- data/lib/panko_serializer.rb +2 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9e1120b6231ae836d11ca59c17443518f5ccb80
|
4
|
+
data.tar.gz: 2b38dd527027204628714825d38d5f8c83b0d4a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9642ae4e418b15a0051d2bb08b352bb035afabfb3f0eb115ded715fb6edc5db91a3a17a4dbd76793607b3c6db020eb2ea08625bf11e5b85311835cb8eebb428d
|
7
|
+
data.tar.gz: 9b0225b6e43c743425b8cbb0e105541ec646aa50a7fcaf634631ddc427ecc808cf1f96ac3a3ebe96bccdff292708f9a473f16be8481e4959917b79fc9b95d985
|
data/README.md
CHANGED
@@ -32,8 +32,6 @@ Then, install it on the command line:
|
|
32
32
|
> bundle install
|
33
33
|
```
|
34
34
|
|
35
|
-
> Since the Gem name and namespace differ, you need to require "panko" explicitly. This will be fixed before official release.
|
36
|
-
|
37
35
|
|
38
36
|
|
39
37
|
## Usage
|
@@ -66,7 +64,7 @@ class UsersController < ApplicationController
|
|
66
64
|
end
|
67
65
|
```
|
68
66
|
|
69
|
-
And voila, we have endpoint which
|
67
|
+
And voila, we have endpoint which serialize users using Panko!
|
70
68
|
|
71
69
|
|
72
70
|
## Features
|
data/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-cayman
|
@@ -1,16 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative "./benchmarking_support"
|
3
3
|
require "rails"
|
4
|
-
require "active_model"
|
5
4
|
require "active_support"
|
6
|
-
require "active_support/json"
|
7
|
-
require "action_controller"
|
8
|
-
require "action_controller/railtie"
|
9
5
|
|
10
|
-
|
11
|
-
require "memory_profiler"
|
12
|
-
require "ruby-prof"
|
13
|
-
require "ruby-prof-flamegraph"
|
14
6
|
require "panko_serializer"
|
15
7
|
|
16
8
|
def generate_attributes(count)
|
@@ -44,11 +44,11 @@ def db_panko_time
|
|
44
44
|
Panko::_type_cast(converter, from)
|
45
45
|
end
|
46
46
|
end
|
47
|
-
panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', {a:1}
|
48
|
-
db_panko_time
|
49
|
-
utc_panko_time
|
50
47
|
|
51
48
|
panko_type_convert ActiveRecord::Type::String, 1, "1"
|
49
|
+
panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', {a:1}
|
50
|
+
exit
|
51
|
+
|
52
52
|
panko_type_convert ActiveRecord::Type::Text, 1, "1"
|
53
53
|
panko_type_convert ActiveRecord::Type::Integer, "1", 1
|
54
54
|
panko_type_convert ActiveRecord::Type::Float, "1.23", 1.23
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#include "association.h"
|
2
|
+
|
3
|
+
VALUE cAssociation;
|
4
|
+
|
5
|
+
static void association_free(void* ptr) {
|
6
|
+
if (!ptr) {
|
7
|
+
return;
|
8
|
+
}
|
9
|
+
|
10
|
+
Association association = (Association)ptr;
|
11
|
+
association->name_str = Qnil;
|
12
|
+
association->name_id = 0;
|
13
|
+
association->name_sym = Qnil;
|
14
|
+
association->rb_descriptor = Qnil;
|
15
|
+
|
16
|
+
if (!association->descriptor || association->descriptor != NULL) {
|
17
|
+
association->descriptor = NULL;
|
18
|
+
}
|
19
|
+
|
20
|
+
xfree(association);
|
21
|
+
}
|
22
|
+
|
23
|
+
void association_mark(Association data) {
|
24
|
+
rb_gc_mark(data->name_str);
|
25
|
+
rb_gc_mark(data->name_sym);
|
26
|
+
rb_gc_mark(data->rb_descriptor);
|
27
|
+
|
28
|
+
if (data->descriptor != NULL) {
|
29
|
+
sd_mark(data->descriptor);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
static VALUE association_new(int argc, VALUE* argv, VALUE self) {
|
34
|
+
Association association = ALLOC(struct _Association);
|
35
|
+
|
36
|
+
Check_Type(argv[0], T_SYMBOL);
|
37
|
+
Check_Type(argv[1], T_STRING);
|
38
|
+
|
39
|
+
association->name_sym = argv[0];
|
40
|
+
association->name_str = argv[1];
|
41
|
+
association->rb_descriptor = argv[2];
|
42
|
+
|
43
|
+
association->name_id = rb_intern_str(association->name_str);
|
44
|
+
association->descriptor = sd_read(association->rb_descriptor);
|
45
|
+
|
46
|
+
return Data_Wrap_Struct(cAssociation, association_mark, association_free,
|
47
|
+
association);
|
48
|
+
}
|
49
|
+
|
50
|
+
Association association_read(VALUE association) {
|
51
|
+
return (Association)DATA_PTR(association);
|
52
|
+
}
|
53
|
+
|
54
|
+
VALUE association_name_sym_ref(VALUE self) {
|
55
|
+
Association association = (Association)DATA_PTR(self);
|
56
|
+
return association->name_sym;
|
57
|
+
}
|
58
|
+
|
59
|
+
VALUE association_descriptor_ref(VALUE self) {
|
60
|
+
Association association = (Association)DATA_PTR(self);
|
61
|
+
return association->rb_descriptor;
|
62
|
+
}
|
63
|
+
|
64
|
+
VALUE association_decriptor_aset(VALUE self, VALUE descriptor) {
|
65
|
+
Association association = (Association)DATA_PTR(self);
|
66
|
+
|
67
|
+
association->rb_descriptor = descriptor;
|
68
|
+
association->descriptor = sd_read(descriptor);
|
69
|
+
|
70
|
+
return association->rb_descriptor;
|
71
|
+
}
|
72
|
+
|
73
|
+
void panko_init_association(VALUE mPanko) {
|
74
|
+
cAssociation = rb_define_class_under(mPanko, "Association", rb_cObject);
|
75
|
+
|
76
|
+
rb_define_module_function(cAssociation, "new", association_new, -1);
|
77
|
+
|
78
|
+
rb_define_method(cAssociation, "name_sym", association_name_sym_ref, 0);
|
79
|
+
rb_define_method(cAssociation, "descriptor", association_descriptor_ref, 0);
|
80
|
+
rb_define_method(cAssociation, "descriptor=", association_decriptor_aset, 1);
|
81
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#ifndef __ASSOCIATION_H__
|
4
|
+
#define __ASSOCIATION_H__
|
5
|
+
|
6
|
+
#include "serialization_descriptor.h"
|
7
|
+
|
8
|
+
typedef struct _Association {
|
9
|
+
ID name_id;
|
10
|
+
VALUE name_sym;
|
11
|
+
VALUE name_str;
|
12
|
+
|
13
|
+
VALUE rb_descriptor;
|
14
|
+
SerializationDescriptor descriptor;
|
15
|
+
} * Association;
|
16
|
+
|
17
|
+
Association association_read(VALUE association);
|
18
|
+
void panko_init_association(VALUE mPanko);
|
19
|
+
|
20
|
+
#endif
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#include "attribute.h"
|
2
|
+
|
3
|
+
VALUE cAttribute;
|
4
|
+
|
5
|
+
static void attribute_free(void* ptr) {
|
6
|
+
if (!ptr) {
|
7
|
+
return;
|
8
|
+
}
|
9
|
+
|
10
|
+
Attribute attribute = (Attribute)ptr;
|
11
|
+
attribute->name_str = Qnil;
|
12
|
+
attribute->name_id = 0;
|
13
|
+
attribute->alias_name = Qnil;
|
14
|
+
attribute->type = Qnil;
|
15
|
+
attribute->record_class = Qnil;
|
16
|
+
|
17
|
+
xfree(attribute);
|
18
|
+
}
|
19
|
+
|
20
|
+
void attribute_mark(Attribute data) {
|
21
|
+
rb_gc_mark(data->name_str);
|
22
|
+
rb_gc_mark(data->alias_name);
|
23
|
+
rb_gc_mark(data->type);
|
24
|
+
rb_gc_mark(data->record_class);
|
25
|
+
}
|
26
|
+
|
27
|
+
static VALUE attribute_new(int argc, VALUE* argv, VALUE self) {
|
28
|
+
Attribute attribute = ALLOC(struct _Attribute);
|
29
|
+
|
30
|
+
Check_Type(argv[0], T_STRING);
|
31
|
+
if (argv[1] != Qnil) {
|
32
|
+
Check_Type(argv[1], T_STRING);
|
33
|
+
}
|
34
|
+
|
35
|
+
attribute->name_str = argv[0];
|
36
|
+
attribute->name_id = rb_intern_str(attribute->name_str);
|
37
|
+
attribute->alias_name = argv[1];
|
38
|
+
attribute->type = Qnil;
|
39
|
+
attribute->record_class = Qnil;
|
40
|
+
|
41
|
+
return Data_Wrap_Struct(cAttribute, attribute_mark, attribute_free,
|
42
|
+
attribute);
|
43
|
+
}
|
44
|
+
|
45
|
+
Attribute attribute_read(VALUE attribute) {
|
46
|
+
return (Attribute)DATA_PTR(attribute);
|
47
|
+
}
|
48
|
+
|
49
|
+
void attribute_try_invalidate(Attribute attribute, VALUE new_record_class) {
|
50
|
+
if (rb_equal(attribute->record_class, new_record_class) == Qfalse) {
|
51
|
+
attribute->type = Qnil;
|
52
|
+
attribute->record_class = new_record_class;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE attribute_name_ref(VALUE self) {
|
57
|
+
Attribute attribute = (Attribute)DATA_PTR(self);
|
58
|
+
return attribute->name_str;
|
59
|
+
}
|
60
|
+
|
61
|
+
VALUE attribute_alias_name_ref(VALUE self) {
|
62
|
+
Attribute attribute = (Attribute)DATA_PTR(self);
|
63
|
+
return attribute->alias_name;
|
64
|
+
}
|
65
|
+
|
66
|
+
void panko_init_attribute(VALUE mPanko) {
|
67
|
+
cAttribute = rb_define_class_under(mPanko, "Attribute", rb_cObject);
|
68
|
+
|
69
|
+
rb_define_module_function(cAttribute, "new", attribute_new, -1);
|
70
|
+
|
71
|
+
rb_define_method(cAttribute, "name", attribute_name_ref, 0);
|
72
|
+
rb_define_method(cAttribute, "alias_name", attribute_alias_name_ref, 0);
|
73
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#ifndef __ATTRIBUTE_H__
|
4
|
+
#define __ATTRIBUTE_H__
|
5
|
+
|
6
|
+
typedef struct _Attribute {
|
7
|
+
VALUE name_str;
|
8
|
+
ID name_id;
|
9
|
+
VALUE alias_name;
|
10
|
+
|
11
|
+
/*
|
12
|
+
* We will cache the activerecord type
|
13
|
+
* by the record_class
|
14
|
+
*/
|
15
|
+
VALUE type;
|
16
|
+
VALUE record_class;
|
17
|
+
} * Attribute;
|
18
|
+
|
19
|
+
Attribute attribute_read(VALUE attribute);
|
20
|
+
void attribute_try_invalidate(Attribute attribute, VALUE record);
|
21
|
+
void panko_init_attribute(VALUE mPanko);
|
22
|
+
|
23
|
+
#endif
|
@@ -49,79 +49,116 @@ void read_attribute_from_hash(VALUE attributes_hash,
|
|
49
49
|
volatile VALUE attribute_metadata = rb_hash_aref(attributes_hash, member);
|
50
50
|
if (attribute_metadata != Qnil) {
|
51
51
|
*value = rb_ivar_get(attribute_metadata, value_before_type_cast_id);
|
52
|
-
|
52
|
+
|
53
|
+
if (*type == Qnil) {
|
54
|
+
*type = rb_ivar_get(attribute_metadata, type_id);
|
55
|
+
}
|
53
56
|
}
|
54
57
|
}
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
59
|
+
struct attributes {
|
60
|
+
VALUE attributes_hash;
|
61
|
+
|
62
|
+
VALUE types;
|
63
|
+
VALUE additional_types;
|
64
|
+
VALUE values;
|
65
|
+
|
66
|
+
// heuristicts
|
67
|
+
bool shouldReadFromHash;
|
68
|
+
bool tryToReadFromAdditionalTypes;
|
69
|
+
};
|
70
|
+
|
71
|
+
struct attributes init_context(VALUE obj) {
|
72
|
+
struct attributes attributes_ctx;
|
73
|
+
attributes_ctx.attributes_hash = Qnil;
|
74
|
+
attributes_ctx.values = Qnil;
|
75
|
+
attributes_ctx.types = Qnil;
|
76
|
+
attributes_ctx.additional_types = Qnil;
|
77
|
+
|
78
|
+
attributes_ctx.shouldReadFromHash = false;
|
79
|
+
attributes_ctx.tryToReadFromAdditionalTypes = false;
|
80
|
+
|
81
|
+
volatile VALUE lazy_attribute_hash = panko_read_lazy_attributes_hash(obj);
|
82
|
+
|
68
83
|
if (lazy_attribute_hash == Qnil) {
|
69
|
-
|
84
|
+
// TODO: handle
|
70
85
|
}
|
71
86
|
|
72
|
-
bool tryToReadFromDelegateHash = false;
|
73
|
-
bool tryToReadFromAdditionalTypes = false;
|
74
|
-
|
75
|
-
// If lazy_attribute_hash is not ActiveRecord::LazyAttributeHash
|
76
|
-
// and it's actually hash, read from it
|
77
87
|
if (RB_TYPE_P(lazy_attribute_hash, T_HASH)) {
|
78
|
-
|
79
|
-
|
88
|
+
attributes_ctx.attributes_hash = lazy_attribute_hash;
|
89
|
+
attributes_ctx.shouldReadFromHash = true;
|
80
90
|
} else {
|
81
|
-
delegate_hash =
|
82
|
-
|
91
|
+
volatile VALUE delegate_hash =
|
92
|
+
rb_ivar_get(lazy_attribute_hash, delegate_hash_id);
|
93
|
+
if (!panko_is_empty_hash(delegate_hash)) {
|
94
|
+
attributes_ctx.attributes_hash = delegate_hash;
|
95
|
+
attributes_ctx.shouldReadFromHash = true;
|
96
|
+
}
|
83
97
|
|
84
|
-
panko_read_types_and_value(lazy_attribute_hash, &types,
|
85
|
-
&
|
98
|
+
panko_read_types_and_value(lazy_attribute_hash, &attributes_ctx.types,
|
99
|
+
&attributes_ctx.additional_types,
|
100
|
+
&attributes_ctx.values);
|
86
101
|
|
87
|
-
tryToReadFromAdditionalTypes =
|
102
|
+
attributes_ctx.tryToReadFromAdditionalTypes =
|
103
|
+
!panko_is_empty_hash(attributes_ctx.additional_types);
|
88
104
|
}
|
89
105
|
|
90
|
-
|
91
|
-
|
92
|
-
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
93
|
-
volatile VALUE member_raw = RARRAY_AREF(attributes, i);
|
94
|
-
volatile VALUE member = rb_sym2str(member_raw);
|
106
|
+
return attributes_ctx;
|
107
|
+
}
|
95
108
|
|
96
|
-
|
97
|
-
|
109
|
+
VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute) {
|
110
|
+
VALUE member = attribute->name_str;
|
111
|
+
volatile VALUE value = Qundef;
|
98
112
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
read_attribute_from_hash(delegate_hash, member, &value, &type_metadata);
|
113
|
+
if (attributes_ctx.values != Qnil && value == Qundef) {
|
114
|
+
value = rb_hash_aref(attributes_ctx.values, member);
|
115
|
+
if (value == Qnil) {
|
116
|
+
value = Qundef;
|
104
117
|
}
|
118
|
+
}
|
119
|
+
|
120
|
+
if (value == Qundef && attributes_ctx.shouldReadFromHash) {
|
121
|
+
read_attribute_from_hash(attributes_ctx.attributes_hash, member, &value,
|
122
|
+
&attribute->type);
|
123
|
+
}
|
105
124
|
|
106
|
-
|
107
|
-
|
125
|
+
if (attribute->type == Qnil) {
|
126
|
+
if (attributes_ctx.tryToReadFromAdditionalTypes) {
|
127
|
+
attribute->type = rb_hash_aref(attributes_ctx.additional_types, member);
|
128
|
+
}
|
108
129
|
|
109
|
-
|
110
|
-
|
111
|
-
}
|
112
|
-
if (type_metadata == Qnil) {
|
113
|
-
type_metadata = rb_hash_aref(types, member);
|
114
|
-
}
|
130
|
+
if (attributes_ctx.types != Qnil && attribute->type == Qnil) {
|
131
|
+
attribute->type = rb_hash_aref(attributes_ctx.types, member);
|
115
132
|
}
|
133
|
+
}
|
134
|
+
|
135
|
+
if (attribute->type != Qnil && value != Qnil) {
|
136
|
+
return type_cast(attribute->type, value);
|
137
|
+
}
|
138
|
+
|
139
|
+
return value;
|
140
|
+
}
|
141
|
+
|
142
|
+
VALUE panko_each_attribute(VALUE obj,
|
143
|
+
VALUE attributes,
|
144
|
+
EachAttributeFunc func,
|
145
|
+
VALUE writer) {
|
146
|
+
long i;
|
147
|
+
struct attributes attributes_ctx = init_context(obj);
|
148
|
+
volatile VALUE record_class = CLASS_OF(obj);
|
149
|
+
|
150
|
+
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
151
|
+
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
152
|
+
Attribute attribute = attribute_read(raw_attribute);
|
153
|
+
attribute_try_invalidate(attribute, record_class);
|
116
154
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
member = rb_sym2str(alias_name);
|
121
|
-
}
|
155
|
+
volatile VALUE name_str = attribute->name_str;
|
156
|
+
if (attribute->alias_name != Qnil) {
|
157
|
+
name_str = attribute->alias_name;
|
122
158
|
}
|
123
159
|
|
124
|
-
|
160
|
+
volatile VALUE value = read_attribute(attributes_ctx, attribute);
|
161
|
+
func(writer, name_str, value);
|
125
162
|
}
|
126
163
|
|
127
164
|
return Qnil;
|
@@ -1,17 +1,14 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <stdbool.h>
|
3
3
|
|
4
|
+
#include "attribute.h"
|
4
5
|
#include "serialization_descriptor.h"
|
6
|
+
#include "type_cast.h"
|
5
7
|
|
6
|
-
typedef void (*EachAttributeFunc)(VALUE
|
7
|
-
VALUE name,
|
8
|
-
VALUE value,
|
9
|
-
VALUE type_metadata,
|
10
|
-
VALUE context);
|
8
|
+
typedef void (*EachAttributeFunc)(VALUE writer, VALUE name, VALUE value);
|
11
9
|
|
12
10
|
extern VALUE panko_each_attribute(VALUE object,
|
13
11
|
VALUE attributes,
|
14
|
-
VALUE aliases,
|
15
12
|
EachAttributeFunc func,
|
16
13
|
VALUE context);
|
17
14
|
|
@@ -9,14 +9,7 @@ static ID pop_id;
|
|
9
9
|
|
10
10
|
static ID to_a_id;
|
11
11
|
|
12
|
-
void write_value(VALUE str_writer,
|
13
|
-
VALUE key,
|
14
|
-
VALUE value,
|
15
|
-
VALUE type_metadata) {
|
16
|
-
if (type_metadata != Qnil && value != Qnil) {
|
17
|
-
value = type_cast(type_metadata, value);
|
18
|
-
}
|
19
|
-
|
12
|
+
void write_value(VALUE str_writer, VALUE key, VALUE value) {
|
20
13
|
rb_funcall(str_writer, push_value_id, 2, value, key);
|
21
14
|
}
|
22
15
|
|
@@ -36,28 +29,20 @@ void serialize_method_fields(VALUE subject,
|
|
36
29
|
sd_apply_serializer_config(serializer, subject, context);
|
37
30
|
|
38
31
|
for (i = 0; i < RARRAY_LEN(method_fields); i++) {
|
39
|
-
VALUE attribute_name = RARRAY_AREF(method_fields, i);
|
32
|
+
volatile VALUE attribute_name = RARRAY_AREF(method_fields, i);
|
40
33
|
volatile VALUE result =
|
41
34
|
rb_funcall(serializer, rb_sym2id(attribute_name), 0);
|
42
35
|
|
43
|
-
write_value(str_writer, rb_sym2str(attribute_name), result
|
36
|
+
write_value(str_writer, rb_sym2str(attribute_name), result);
|
44
37
|
}
|
45
38
|
}
|
46
39
|
|
47
|
-
void panko_attributes_iter(VALUE object,
|
48
|
-
VALUE name,
|
49
|
-
VALUE value,
|
50
|
-
VALUE type_metadata,
|
51
|
-
VALUE str_writer) {
|
52
|
-
write_value(str_writer, name, value, type_metadata);
|
53
|
-
}
|
54
|
-
|
55
40
|
void serialize_fields(VALUE subject,
|
56
41
|
VALUE str_writer,
|
57
42
|
SerializationDescriptor descriptor,
|
58
43
|
VALUE context) {
|
59
|
-
panko_each_attribute(subject, descriptor->
|
60
|
-
|
44
|
+
panko_each_attribute(subject, descriptor->attributes, write_value,
|
45
|
+
str_writer);
|
61
46
|
|
62
47
|
serialize_method_fields(subject, str_writer, descriptor, context);
|
63
48
|
}
|
@@ -69,17 +54,16 @@ void serialize_has_one_associations(VALUE subject,
|
|
69
54
|
VALUE associations) {
|
70
55
|
long i;
|
71
56
|
for (i = 0; i < RARRAY_LEN(associations); i++) {
|
72
|
-
volatile VALUE
|
57
|
+
volatile VALUE association_el = RARRAY_AREF(associations, i);
|
58
|
+
Association association = association_read(association_el);
|
73
59
|
|
74
|
-
volatile VALUE
|
75
|
-
volatile VALUE association_descriptor = RARRAY_AREF(association, 1);
|
76
|
-
volatile VALUE value = rb_funcall(subject, rb_sym2id(name), 0);
|
60
|
+
volatile VALUE value = rb_funcall(subject, association->name_id, 0);
|
77
61
|
|
78
62
|
if (value == Qnil) {
|
79
|
-
write_value(str_writer,
|
63
|
+
write_value(str_writer, association->name_str, value);
|
80
64
|
} else {
|
81
|
-
serialize_subject(
|
82
|
-
|
65
|
+
serialize_subject(association->name_str, value, str_writer,
|
66
|
+
association->descriptor, context);
|
83
67
|
}
|
84
68
|
}
|
85
69
|
}
|
@@ -91,17 +75,16 @@ void serialize_has_many_associations(VALUE subject,
|
|
91
75
|
VALUE associations) {
|
92
76
|
long i;
|
93
77
|
for (i = 0; i < RARRAY_LEN(associations); i++) {
|
94
|
-
volatile VALUE
|
78
|
+
volatile VALUE association_el = RARRAY_AREF(associations, i);
|
79
|
+
Association association = association_read(association_el);
|
95
80
|
|
96
|
-
volatile VALUE
|
97
|
-
volatile VALUE association_descriptor = RARRAY_AREF(association, 1);
|
98
|
-
volatile VALUE value = rb_funcall(subject, rb_sym2id(name), 0);
|
81
|
+
volatile VALUE value = rb_funcall(subject, association->name_id, 0);
|
99
82
|
|
100
83
|
if (value == Qnil) {
|
101
|
-
write_value(str_writer,
|
84
|
+
write_value(str_writer, association->name_str, value);
|
102
85
|
} else {
|
103
|
-
serialize_subjects(
|
104
|
-
|
86
|
+
serialize_subjects(association->name_str, value, str_writer,
|
87
|
+
association->descriptor, context);
|
105
88
|
}
|
106
89
|
}
|
107
90
|
}
|
@@ -190,4 +173,6 @@ void Init_panko_serializer() {
|
|
190
173
|
panko_init_serialization_descriptor(mPanko);
|
191
174
|
panko_init_attributes_iterator(mPanko);
|
192
175
|
panko_init_type_cast(mPanko);
|
176
|
+
panko_init_attribute(mPanko);
|
177
|
+
panko_init_association(mPanko);
|
193
178
|
}
|
@@ -5,46 +5,44 @@ VALUE cSerializationDescriptor;
|
|
5
5
|
static ID context_id;
|
6
6
|
static ID object_id;
|
7
7
|
|
8
|
-
static void
|
9
|
-
|
10
|
-
if (ptr == 0) {
|
8
|
+
static void sd_free(SerializationDescriptor sd) {
|
9
|
+
if (!sd) {
|
11
10
|
return;
|
12
11
|
}
|
13
12
|
|
14
|
-
sd = (SerializationDescriptor)ptr;
|
15
13
|
sd->serializer_type = Qnil;
|
16
14
|
sd->serializer = Qnil;
|
17
|
-
sd->
|
15
|
+
sd->attributes = Qnil;
|
18
16
|
sd->method_fields = Qnil;
|
19
17
|
sd->has_one_associations = Qnil;
|
20
18
|
sd->has_many_associations = Qnil;
|
21
19
|
sd->aliases = Qnil;
|
20
|
+
|
21
|
+
xfree(sd);
|
22
22
|
}
|
23
23
|
|
24
|
-
void
|
24
|
+
void sd_mark(SerializationDescriptor data) {
|
25
25
|
rb_gc_mark(data->serializer_type);
|
26
26
|
rb_gc_mark(data->serializer);
|
27
|
-
rb_gc_mark(data->
|
27
|
+
rb_gc_mark(data->attributes);
|
28
28
|
rb_gc_mark(data->method_fields);
|
29
29
|
rb_gc_mark(data->has_one_associations);
|
30
30
|
rb_gc_mark(data->has_many_associations);
|
31
31
|
rb_gc_mark(data->aliases);
|
32
32
|
}
|
33
33
|
|
34
|
-
static VALUE
|
34
|
+
static VALUE sd_new(int argc, VALUE* argv, VALUE self) {
|
35
35
|
SerializationDescriptor sd = ALLOC(struct _SerializationDescriptor);
|
36
36
|
|
37
37
|
sd->serializer = Qnil;
|
38
38
|
sd->serializer_type = Qnil;
|
39
|
-
sd->
|
39
|
+
sd->attributes = Qnil;
|
40
40
|
sd->method_fields = Qnil;
|
41
41
|
sd->has_one_associations = Qnil;
|
42
42
|
sd->has_many_associations = Qnil;
|
43
43
|
sd->aliases = Qnil;
|
44
44
|
|
45
|
-
return Data_Wrap_Struct(cSerializationDescriptor,
|
46
|
-
serialization_descriptor_mark,
|
47
|
-
serialization_descriptor_free, sd);
|
45
|
+
return Data_Wrap_Struct(cSerializationDescriptor, sd_mark, sd_free, sd);
|
48
46
|
}
|
49
47
|
|
50
48
|
SerializationDescriptor sd_read(VALUE descriptor) {
|
@@ -60,87 +58,94 @@ VALUE sd_build_serializer(SerializationDescriptor sd) {
|
|
60
58
|
return sd->serializer;
|
61
59
|
}
|
62
60
|
|
61
|
+
VALUE sd_serializer_set(VALUE self, VALUE serializer) {
|
62
|
+
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
63
|
+
|
64
|
+
sd->serializer = serializer;
|
65
|
+
return Qnil;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE sd_serializer_ref(VALUE self) {
|
69
|
+
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
70
|
+
|
71
|
+
return sd->serializer;
|
72
|
+
}
|
73
|
+
|
63
74
|
void sd_apply_serializer_config(VALUE serializer, VALUE object, VALUE context) {
|
64
75
|
rb_ivar_set(serializer, object_id, object);
|
65
|
-
if(context != Qnil && context != Qundef) {
|
76
|
+
if (context != Qnil && context != Qundef) {
|
66
77
|
rb_ivar_set(serializer, context_id, context);
|
67
78
|
}
|
68
79
|
}
|
69
|
-
|
70
|
-
VALUE serialization_descriptor_fields_set(VALUE self, VALUE fields) {
|
80
|
+
VALUE sd_attributes_set(VALUE self, VALUE attributes) {
|
71
81
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
72
82
|
|
73
|
-
sd->
|
83
|
+
sd->attributes = attributes;
|
74
84
|
return Qnil;
|
75
85
|
}
|
76
86
|
|
77
|
-
VALUE
|
87
|
+
VALUE sd_attributes_ref(VALUE self) {
|
78
88
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
79
|
-
return sd->
|
89
|
+
return sd->attributes;
|
80
90
|
}
|
81
91
|
|
82
|
-
VALUE
|
83
|
-
VALUE method_fields) {
|
92
|
+
VALUE sd_method_fields_set(VALUE self, VALUE method_fields) {
|
84
93
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
85
94
|
sd->method_fields = method_fields;
|
86
95
|
return Qnil;
|
87
96
|
}
|
88
97
|
|
89
|
-
VALUE
|
98
|
+
VALUE sd_method_fields_ref(VALUE self) {
|
90
99
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
91
100
|
return sd->method_fields;
|
92
101
|
}
|
93
102
|
|
94
|
-
VALUE
|
95
|
-
VALUE self,
|
96
|
-
VALUE has_one_associations) {
|
103
|
+
VALUE sd_has_one_associations_set(VALUE self, VALUE has_one_associations) {
|
97
104
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
98
105
|
sd->has_one_associations = has_one_associations;
|
99
106
|
return Qnil;
|
100
107
|
}
|
101
108
|
|
102
|
-
VALUE
|
109
|
+
VALUE sd_has_one_associations_ref(VALUE self) {
|
103
110
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
104
111
|
return sd->has_one_associations;
|
105
112
|
}
|
106
113
|
|
107
|
-
VALUE
|
108
|
-
VALUE self,
|
109
|
-
VALUE has_many_associations) {
|
114
|
+
VALUE sd_has_many_associations_set(VALUE self, VALUE has_many_associations) {
|
110
115
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
111
116
|
sd->has_many_associations = has_many_associations;
|
112
117
|
return Qnil;
|
113
118
|
}
|
114
119
|
|
115
|
-
VALUE
|
120
|
+
VALUE sd_has_many_associations_ref(VALUE self) {
|
116
121
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
117
122
|
return sd->has_many_associations;
|
118
123
|
}
|
119
124
|
|
120
|
-
VALUE
|
125
|
+
VALUE sd_type_set(VALUE self, VALUE type) {
|
121
126
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
122
127
|
sd->serializer_type = type;
|
123
128
|
return Qnil;
|
124
129
|
}
|
125
130
|
|
126
|
-
VALUE
|
131
|
+
VALUE sd_type_aref(VALUE self, VALUE type) {
|
127
132
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
128
133
|
return sd->serializer_type;
|
129
134
|
}
|
130
135
|
|
131
|
-
VALUE
|
136
|
+
VALUE sd_aliases_set(VALUE self, VALUE aliases) {
|
132
137
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
133
138
|
sd->aliases = aliases;
|
134
139
|
return Qnil;
|
135
140
|
}
|
136
141
|
|
137
|
-
VALUE
|
142
|
+
VALUE sd_aliases_aref(VALUE self, VALUE aliases) {
|
138
143
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
139
144
|
return sd->aliases;
|
140
145
|
}
|
141
146
|
|
142
147
|
// Exposing this for testing
|
143
|
-
VALUE
|
148
|
+
VALUE public_sd_build_serializer(VALUE self) {
|
144
149
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
145
150
|
return sd_build_serializer(sd);
|
146
151
|
}
|
@@ -152,40 +157,39 @@ void panko_init_serialization_descriptor(VALUE mPanko) {
|
|
152
157
|
cSerializationDescriptor =
|
153
158
|
rb_define_class_under(mPanko, "SerializationDescriptor", rb_cObject);
|
154
159
|
|
155
|
-
rb_define_module_function(cSerializationDescriptor, "new",
|
156
|
-
serialization_descriptor_new, -1);
|
160
|
+
rb_define_module_function(cSerializationDescriptor, "new", sd_new, -1);
|
157
161
|
|
158
|
-
rb_define_method(cSerializationDescriptor,
|
159
|
-
|
160
|
-
rb_define_method(cSerializationDescriptor, "
|
161
|
-
|
162
|
+
rb_define_method(cSerializationDescriptor, "serializer=", sd_serializer_set,
|
163
|
+
1);
|
164
|
+
rb_define_method(cSerializationDescriptor, "serializer", sd_serializer_ref,
|
165
|
+
0);
|
162
166
|
|
163
|
-
rb_define_method(cSerializationDescriptor,
|
164
|
-
"method_fields=", serialization_descriptor_method_fields_set,
|
167
|
+
rb_define_method(cSerializationDescriptor, "attributes=", sd_attributes_set,
|
165
168
|
1);
|
169
|
+
rb_define_method(cSerializationDescriptor, "attributes", sd_attributes_ref,
|
170
|
+
0);
|
171
|
+
|
172
|
+
rb_define_method(cSerializationDescriptor,
|
173
|
+
"method_fields=", sd_method_fields_set, 1);
|
166
174
|
rb_define_method(cSerializationDescriptor, "method_fields",
|
167
|
-
|
175
|
+
sd_method_fields_ref, 0);
|
168
176
|
|
169
|
-
rb_define_method(cSerializationDescriptor,
|
170
|
-
|
177
|
+
rb_define_method(cSerializationDescriptor,
|
178
|
+
"has_one_associations=", sd_has_one_associations_set, 1);
|
171
179
|
rb_define_method(cSerializationDescriptor, "has_one_associations",
|
172
|
-
|
180
|
+
sd_has_one_associations_ref, 0);
|
173
181
|
|
174
|
-
rb_define_method(cSerializationDescriptor,
|
175
|
-
|
182
|
+
rb_define_method(cSerializationDescriptor,
|
183
|
+
"has_many_associations=", sd_has_many_associations_set, 1);
|
176
184
|
rb_define_method(cSerializationDescriptor, "has_many_associations",
|
177
|
-
|
185
|
+
sd_has_many_associations_ref, 0);
|
178
186
|
|
179
|
-
rb_define_method(cSerializationDescriptor,
|
180
|
-
|
181
|
-
rb_define_method(cSerializationDescriptor, "type",
|
182
|
-
serialization_descriptor_type_aref, 0);
|
187
|
+
rb_define_method(cSerializationDescriptor, "type=", sd_type_set, 1);
|
188
|
+
rb_define_method(cSerializationDescriptor, "type", sd_type_aref, 0);
|
183
189
|
|
184
|
-
rb_define_method(cSerializationDescriptor,
|
185
|
-
|
186
|
-
rb_define_method(cSerializationDescriptor, "aliases",
|
187
|
-
serialization_descriptor_aliases_aref, 0);
|
190
|
+
rb_define_method(cSerializationDescriptor, "aliases=", sd_aliases_set, 1);
|
191
|
+
rb_define_method(cSerializationDescriptor, "aliases", sd_aliases_aref, 0);
|
188
192
|
|
189
193
|
rb_define_method(cSerializationDescriptor, "build_serializer",
|
190
|
-
|
194
|
+
public_sd_build_serializer, 0);
|
191
195
|
}
|
@@ -10,19 +10,17 @@ typedef struct _SerializationDescriptor {
|
|
10
10
|
VALUE serializer;
|
11
11
|
|
12
12
|
// Metadata
|
13
|
-
VALUE
|
14
|
-
VALUE method_fields;
|
13
|
+
VALUE attributes;
|
15
14
|
VALUE aliases;
|
15
|
+
VALUE method_fields;
|
16
16
|
VALUE has_one_associations;
|
17
17
|
VALUE has_many_associations;
|
18
18
|
} * SerializationDescriptor;
|
19
19
|
|
20
|
-
VALUE serialization_descriptor_fields_ref(VALUE descriptor);
|
21
|
-
VALUE serialization_descriptor_method_fields_ref(VALUE descriptor);
|
22
|
-
VALUE serialization_descriptor_has_one_associations_ref(VALUE descriptor);
|
23
|
-
VALUE serialization_descriptor_has_many_associations_ref(VALUE descriptor);
|
24
|
-
|
25
20
|
SerializationDescriptor sd_read(VALUE descriptor);
|
21
|
+
|
22
|
+
void sd_mark(SerializationDescriptor data);
|
23
|
+
|
26
24
|
VALUE sd_build_serializer(SerializationDescriptor descriptor);
|
27
25
|
void sd_apply_serializer_config(VALUE serializer, VALUE object, VALUE context);
|
28
26
|
|
@@ -5,6 +5,10 @@ ID deserialize_from_db_id = 0;
|
|
5
5
|
ID to_s_id = 0;
|
6
6
|
ID to_i_id = 0;
|
7
7
|
|
8
|
+
static VALUE oj_type = Qundef;
|
9
|
+
static VALUE oj_parseerror_type = Qundef;
|
10
|
+
ID load_id = 0;
|
11
|
+
|
8
12
|
// Caching ActiveRecord Types
|
9
13
|
static VALUE ar_string_type = Qundef;
|
10
14
|
static VALUE ar_text_type = Qundef;
|
@@ -41,11 +45,25 @@ VALUE cache_postgres_type_lookup(VALUE ar) {
|
|
41
45
|
return Qfalse;
|
42
46
|
}
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
if (rb_const_defined_at(ar_oid, rb_intern("Float")) == (int)Qtrue) {
|
49
|
+
ar_pg_float_type = rb_const_get_at(ar_oid, rb_intern("Float"));
|
50
|
+
}
|
51
|
+
|
52
|
+
if (rb_const_defined_at(ar_oid, rb_intern("Integer")) == (int)Qtrue) {
|
53
|
+
ar_pg_integer_type = rb_const_get_at(ar_oid, rb_intern("Integer"));
|
54
|
+
}
|
55
|
+
|
56
|
+
if (rb_const_defined_at(ar_oid, rb_intern("Uuid")) == (int)Qtrue) {
|
57
|
+
ar_pg_uuid_type = rb_const_get_at(ar_oid, rb_intern("Uuid"));
|
58
|
+
}
|
59
|
+
|
60
|
+
if (rb_const_defined_at(ar_oid, rb_intern("Json")) == (int)Qtrue) {
|
61
|
+
ar_pg_json_type = rb_const_get_at(ar_oid, rb_intern("Json"));
|
62
|
+
}
|
63
|
+
|
64
|
+
if (rb_const_defined_at(ar_oid, rb_intern("DateTime")) == (int)Qtrue) {
|
65
|
+
ar_pg_date_time_type = rb_const_get_at(ar_oid, rb_intern("DateTime"));
|
66
|
+
}
|
49
67
|
|
50
68
|
return Qtrue;
|
51
69
|
}
|
@@ -187,14 +205,22 @@ bool is_json_type(VALUE type_klass) {
|
|
187
205
|
return ar_pg_json_type != Qundef && type_klass == ar_pg_json_type;
|
188
206
|
}
|
189
207
|
|
208
|
+
VALUE rescue_func() {
|
209
|
+
return Qnil;
|
210
|
+
}
|
211
|
+
|
212
|
+
VALUE parse_json(VALUE value) {
|
213
|
+
return rb_funcall(oj_type, load_id, 1, value);
|
214
|
+
}
|
215
|
+
|
190
216
|
VALUE cast_json_type(VALUE value) {
|
191
217
|
if (!RB_TYPE_P(value, T_STRING)) {
|
192
218
|
return value;
|
193
219
|
}
|
194
220
|
|
195
|
-
|
196
|
-
|
197
|
-
return
|
221
|
+
volatile VALUE result =
|
222
|
+
rb_rescue2(parse_json, value, rescue_func, Qundef, oj_parseerror_type, 0);
|
223
|
+
return result;
|
198
224
|
}
|
199
225
|
|
200
226
|
bool is_boolean_type(VALUE type_klass) {
|
@@ -282,6 +308,10 @@ void panko_init_type_cast(VALUE mPanko) {
|
|
282
308
|
to_s_id = rb_intern_const("to_s");
|
283
309
|
to_i_id = rb_intern_const("to_i");
|
284
310
|
|
311
|
+
oj_type = rb_const_get_at(rb_cObject, rb_intern("Oj"));
|
312
|
+
oj_parseerror_type = rb_const_get_at(oj_type, rb_intern("ParseError"));
|
313
|
+
load_id = rb_intern_const("load");
|
314
|
+
|
285
315
|
rb_define_singleton_method(mPanko, "_type_cast", public_type_cast, 2);
|
286
316
|
|
287
317
|
panko_init_time(mPanko);
|
@@ -1,6 +1,9 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <stdbool.h>
|
3
3
|
|
4
|
+
#ifndef __PANKO_TYPE_CAST_H__
|
5
|
+
#define __PANKO_TYPE_CAST_H__
|
6
|
+
|
4
7
|
/*
|
5
8
|
* Type Casting
|
6
9
|
*
|
@@ -72,3 +75,5 @@ static struct _TypeCast type_casts[] = {
|
|
72
75
|
|
73
76
|
extern VALUE type_cast(VALUE type_metadata, VALUE value);
|
74
77
|
void panko_init_type_cast(VALUE mPanko);
|
78
|
+
|
79
|
+
#endif
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Panko
|
4
|
+
class Attribute
|
5
|
+
def self.create(name, alias_name: nil)
|
6
|
+
alias_name = alias_name.to_s unless alias_name.nil?
|
7
|
+
Attribute.new(name.to_s, alias_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(attr)
|
11
|
+
return name.to_sym == attr if attr.is_a? Symbol
|
12
|
+
if attr.is_a? Panko::Attribute
|
13
|
+
return name == attr.name && alias_name == attr.alias_name
|
14
|
+
end
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash
|
19
|
+
name.to_sym.hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def eql?(attr)
|
23
|
+
self.==(attr)
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
"<Panko::Attribute name=#{name.inspect} alias_name=#{alias_name.inspect}>"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/panko/response.rb
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
require "oj"
|
3
3
|
|
4
4
|
module Panko
|
5
|
+
JsonValue = Struct.new(:value) do
|
6
|
+
def self.from(value)
|
7
|
+
JsonValue.new(value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
class Response
|
6
12
|
def initialize(data)
|
7
13
|
@data = data
|
@@ -15,6 +21,8 @@ module Panko
|
|
15
21
|
@data.each do |key, value|
|
16
22
|
if value.is_a?(Panko::ArraySerializer) || value.is_a?(Panko::Serializer)
|
17
23
|
writer.push_json(value.to_json, key.to_s)
|
24
|
+
elsif value.is_a?(Panko::JsonValue)
|
25
|
+
writer.push_json(value.value, key.to_s)
|
18
26
|
else
|
19
27
|
writer.push_value(value, key.to_s)
|
20
28
|
end
|
@@ -20,13 +20,31 @@ module Panko
|
|
20
20
|
|
21
21
|
backend.type = descriptor.type
|
22
22
|
|
23
|
-
backend.
|
23
|
+
backend.attributes = descriptor.attributes.map do |attr|
|
24
|
+
Attribute.create(attr.name, alias_name: attr.alias_name)
|
25
|
+
end
|
26
|
+
|
24
27
|
backend.method_fields = descriptor.method_fields.dup
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
unless descriptor.serializer.nil?
|
30
|
+
backend.serializer = descriptor.serializer.reset
|
31
|
+
end
|
32
|
+
|
33
|
+
backend.has_many_associations = descriptor.has_many_associations.map do |assoc|
|
34
|
+
Panko::Association.new(
|
35
|
+
assoc.name_sym,
|
36
|
+
assoc.name_sym.to_s,
|
37
|
+
Panko::SerializationDescriptor.duplicate(assoc.descriptor)
|
38
|
+
)
|
39
|
+
end
|
28
40
|
|
29
|
-
backend.
|
41
|
+
backend.has_one_associations = descriptor.has_one_associations.map do |assoc|
|
42
|
+
Panko::Association.new(
|
43
|
+
assoc.name_sym,
|
44
|
+
assoc.name_sym.to_s,
|
45
|
+
Panko::SerializationDescriptor.duplicate(assoc.descriptor)
|
46
|
+
)
|
47
|
+
end
|
30
48
|
|
31
49
|
backend
|
32
50
|
end
|
@@ -40,14 +58,7 @@ module Panko
|
|
40
58
|
attributes_only_filters, associations_only_filters = resolve_filters(options, :only)
|
41
59
|
attributes_except_filters, associations_except_filters = resolve_filters(options, :except)
|
42
60
|
|
43
|
-
|
44
|
-
self.aliases,
|
45
|
-
attributes_only_filters,
|
46
|
-
attributes_except_filters
|
47
|
-
)
|
48
|
-
|
49
|
-
self.fields = apply_fields_filters(
|
50
|
-
self.fields,
|
61
|
+
apply_attribute_filters!(
|
51
62
|
attributes_only_filters,
|
52
63
|
attributes_except_filters
|
53
64
|
)
|
@@ -79,17 +90,19 @@ module Panko
|
|
79
90
|
attributes_only_filters = only_filters[:attributes] || []
|
80
91
|
unless attributes_only_filters.empty?
|
81
92
|
associations.select! do |association|
|
82
|
-
attributes_only_filters.include?(association.
|
93
|
+
attributes_only_filters.include?(association.name_sym)
|
83
94
|
end
|
84
95
|
end
|
85
96
|
|
97
|
+
|
86
98
|
attributes_except_filters = except_filters[:attributes] || []
|
87
99
|
unless attributes_except_filters.empty?
|
88
100
|
associations.reject! do |association|
|
89
|
-
attributes_except_filters.include?(association.
|
101
|
+
attributes_except_filters.include?(association.name_sym)
|
90
102
|
end
|
91
103
|
end
|
92
104
|
|
105
|
+
|
93
106
|
associations_only_filters = only_filters[:associations]
|
94
107
|
associations_except_filters = except_filters[:associations]
|
95
108
|
|
@@ -98,8 +111,8 @@ module Panko
|
|
98
111
|
end
|
99
112
|
|
100
113
|
associations.map do |association|
|
101
|
-
name = association.
|
102
|
-
descriptor = association.
|
114
|
+
name = association.name_sym
|
115
|
+
descriptor = association.descriptor
|
103
116
|
|
104
117
|
only_filter = associations_only_filters[name]
|
105
118
|
except_filter = associations_except_filters[name]
|
@@ -107,7 +120,6 @@ module Panko
|
|
107
120
|
filters = {}
|
108
121
|
filters[:only] = only_filter unless only_filter.nil?
|
109
122
|
filters[:except] = except_filter unless except_filter.nil?
|
110
|
-
|
111
123
|
descriptor.apply_filters(filters) unless filters.empty?
|
112
124
|
|
113
125
|
association
|
@@ -140,24 +152,22 @@ module Panko
|
|
140
152
|
fields
|
141
153
|
end
|
142
154
|
|
143
|
-
def
|
144
|
-
return if self.aliases.nil? || self.aliases.empty?
|
145
|
-
|
155
|
+
def apply_attribute_filters!(only, except)
|
146
156
|
unless only.empty?
|
147
|
-
|
148
|
-
|
149
|
-
|
157
|
+
self.attributes.select! do |attribute|
|
158
|
+
name_to_check = attribute.name
|
159
|
+
name_to_check = attribute.alias_name unless attribute.alias_name.nil?
|
150
160
|
|
151
|
-
|
161
|
+
only.include?(name_to_check.to_sym)
|
152
162
|
end
|
153
163
|
end
|
154
164
|
|
155
165
|
unless except.empty?
|
156
|
-
|
157
|
-
|
158
|
-
|
166
|
+
self.attributes.reject! do |attribute|
|
167
|
+
name_to_check = attribute.name
|
168
|
+
name_to_check = attribute.alias_name unless attribute.alias_name.nil?
|
159
169
|
|
160
|
-
|
170
|
+
except.include?(name_to_check.to_sym)
|
161
171
|
end
|
162
172
|
end
|
163
173
|
end
|
data/lib/panko/serializer.rb
CHANGED
@@ -9,9 +9,11 @@ module Panko
|
|
9
9
|
base._descriptor = Panko::SerializationDescriptor.new
|
10
10
|
base._descriptor.type = base
|
11
11
|
|
12
|
+
base._descriptor.attributes = []
|
12
13
|
base._descriptor.aliases = {}
|
13
|
-
|
14
|
+
|
14
15
|
base._descriptor.method_fields = []
|
16
|
+
|
15
17
|
base._descriptor.has_many_associations = []
|
16
18
|
base._descriptor.has_one_associations = []
|
17
19
|
end
|
@@ -19,36 +21,39 @@ module Panko
|
|
19
21
|
attr_accessor :_descriptor
|
20
22
|
|
21
23
|
def attributes(*attrs)
|
22
|
-
@_descriptor.
|
24
|
+
@_descriptor.attributes.push(*attrs.map { |attr| Attribute.create(attr) }).uniq!
|
23
25
|
end
|
24
26
|
|
25
27
|
def aliases(aliases = {})
|
26
|
-
|
27
|
-
|
28
|
+
aliases.each do |attr, alias_name|
|
29
|
+
@_descriptor.attributes << Attribute.create(attr, alias_name: alias_name)
|
30
|
+
end
|
28
31
|
end
|
29
32
|
|
30
33
|
def method_added(method)
|
31
34
|
return if @_descriptor.nil?
|
32
|
-
@_descriptor.
|
35
|
+
@_descriptor.attributes.delete(method)
|
33
36
|
@_descriptor.method_fields << method
|
34
37
|
end
|
35
38
|
|
36
39
|
def has_one(name, options)
|
37
40
|
serializer_const = options[:serializer]
|
38
41
|
|
39
|
-
@_descriptor.has_one_associations <<
|
42
|
+
@_descriptor.has_one_associations << Panko::Association.new(
|
40
43
|
name,
|
44
|
+
name.to_s,
|
41
45
|
Panko::SerializationDescriptor.build(serializer_const, options)
|
42
|
-
|
46
|
+
)
|
43
47
|
end
|
44
48
|
|
45
49
|
def has_many(name, options)
|
46
50
|
serializer_const = options[:serializer] || options[:each_serializer]
|
47
51
|
|
48
|
-
@_descriptor.has_many_associations <<
|
52
|
+
@_descriptor.has_many_associations << Panko::Association.new(
|
49
53
|
name,
|
54
|
+
name.to_s.freeze,
|
50
55
|
Panko::SerializationDescriptor.build(serializer_const, options)
|
51
|
-
|
56
|
+
)
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
@@ -68,5 +73,12 @@ module Panko
|
|
68
73
|
Panko::serialize_subject(object, writer, @descriptor, @context)
|
69
74
|
writer.to_s
|
70
75
|
end
|
76
|
+
|
77
|
+
def reset
|
78
|
+
@object = nil
|
79
|
+
@context = nil
|
80
|
+
|
81
|
+
self
|
82
|
+
end
|
71
83
|
end
|
72
84
|
end
|
data/lib/panko/version.rb
CHANGED
data/lib/panko_serializer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panko_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yosi Attias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- LICENSE.txt
|
98
98
|
- README.md
|
99
99
|
- Rakefile
|
100
|
+
- _config.yml
|
100
101
|
- benchmarks/BENCHMARKS.md
|
101
102
|
- benchmarks/allocs.rb
|
102
103
|
- benchmarks/app.rb
|
@@ -112,6 +113,10 @@ files:
|
|
112
113
|
- benchmarks/type_casts/bm_active_record.rb
|
113
114
|
- benchmarks/type_casts/bm_panko.rb
|
114
115
|
- benchmarks/type_casts/support.rb
|
116
|
+
- ext/panko_serializer/association.c
|
117
|
+
- ext/panko_serializer/association.h
|
118
|
+
- ext/panko_serializer/attribute.c
|
119
|
+
- ext/panko_serializer/attribute.h
|
115
120
|
- ext/panko_serializer/attributes_iterator.c
|
116
121
|
- ext/panko_serializer/attributes_iterator.h
|
117
122
|
- ext/panko_serializer/extconf.rb
|
@@ -124,6 +129,7 @@ files:
|
|
124
129
|
- ext/panko_serializer/type_cast.c
|
125
130
|
- ext/panko_serializer/type_cast.h
|
126
131
|
- lib/panko/array_serializer.rb
|
132
|
+
- lib/panko/attribute.rb
|
127
133
|
- lib/panko/response.rb
|
128
134
|
- lib/panko/serialization_descriptor.rb
|
129
135
|
- lib/panko/serializer.rb
|
@@ -150,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
156
|
version: '0'
|
151
157
|
requirements: []
|
152
158
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.6.
|
159
|
+
rubygems_version: 2.6.14
|
154
160
|
signing_key:
|
155
161
|
specification_version: 4
|
156
162
|
summary: Fast serialization for ActiveModel
|