scorpio 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/scorpio.rb +8 -0
- data/lib/scorpio/schema.rb +4 -0
- data/lib/scorpio/schema_instance_base.rb +2 -1
- data/lib/scorpio/schema_instance_json_coder.rb +83 -0
- data/lib/scorpio/struct_json_coder.rb +30 -0
- data/lib/scorpio/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 772f6b246d831d6737118bed2f363358ac6b62dc055c3503f0a96e04d416985e
|
4
|
+
data.tar.gz: 20e4a1d856105a0c2f25d80fb252afd7b91bc35f71babc47f2d8ab3fbd46b2df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8796f5f5227d3a70c374ae94b30cb6be1d7ad4dad71fb399c37c6c74e21117442d582a44d3417c828f156e42690d8f34a692bc3de5fcae4070431583ba1e5d88
|
7
|
+
data.tar.gz: 5d1b897306c6a43e16016e13f125e81d0408e3aca0c94009a2d8804aef0835b3a5cec144441de2979b51c9436e2fff016f0a1046e65d25dcc17471f60cda5869
|
data/CHANGELOG.md
CHANGED
data/lib/scorpio.rb
CHANGED
@@ -91,4 +91,12 @@ module Scorpio
|
|
91
91
|
autoload :ResourceBase, 'scorpio/resource_base'
|
92
92
|
autoload :Schema, 'scorpio/schema'
|
93
93
|
autoload :SchemaInstanceBase, 'scorpio/schema_instance_base'
|
94
|
+
autoload :SchemaClasses, 'scorpio/schema_instance_base'
|
95
|
+
autoload :ObjectJSONCoder, 'scorpio/schema_instance_json_coder'
|
96
|
+
autoload :StructJSONCoder, 'scorpio/struct_json_coder'
|
97
|
+
autoload :SchemaInstanceJSONCoder,'scorpio/schema_instance_json_coder'
|
98
|
+
|
99
|
+
def self.class_for_schema(*a, &b)
|
100
|
+
SchemaClasses.class_for_schema(*a, &b)
|
101
|
+
end
|
94
102
|
end
|
data/lib/scorpio/schema.rb
CHANGED
@@ -87,6 +87,10 @@ module Scorpio
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def schema_class
|
91
|
+
Scorpio.class_for_schema(self)
|
92
|
+
end
|
93
|
+
|
90
94
|
def match_to_instance(instance)
|
91
95
|
# matching oneOf is good here. one schema for one instance.
|
92
96
|
# matching anyOf is okay. there could be more than one schema matched. it's often just one. if more
|
@@ -156,13 +156,14 @@ module Scorpio
|
|
156
156
|
|
157
157
|
# this module is just a namespace for schema classes.
|
158
158
|
module SchemaClasses
|
159
|
+
extend Memoize
|
159
160
|
def self.[](schema_id)
|
160
161
|
@classes_by_id[schema_id]
|
161
162
|
end
|
162
163
|
@classes_by_id = {}
|
163
164
|
end
|
164
165
|
|
165
|
-
def
|
166
|
+
def SchemaClasses.class_for_schema(schema_object)
|
166
167
|
if schema_object.is_a?(Scorpio::Schema)
|
167
168
|
schema__ = schema_object
|
168
169
|
else
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Scorpio
|
2
|
+
# this is a ActiveRecord serialization class intended to store JSON in the
|
3
|
+
# database column and expose a ruby class once loaded on a model instance.
|
4
|
+
# this allows for better ruby idioms to access to properties, and definition
|
5
|
+
# of related methods on the loaded class.
|
6
|
+
#
|
7
|
+
# the first argument, `loaded_class`, is the class which will be used to
|
8
|
+
# instantiate the column data. properties of the loaded class will correspond
|
9
|
+
# to keys of the json object in the database.
|
10
|
+
#
|
11
|
+
# the column data may be either a single instance of the loaded class
|
12
|
+
# (represented as one json object) or an array of them (represented as a json
|
13
|
+
# array of json objects), indicated by the keyword argument `array`.
|
14
|
+
#
|
15
|
+
# the column behind the attribute may be an actual JSON column (postgres json
|
16
|
+
# or jsonb - hstore should work too if you only have string attributes) or a
|
17
|
+
# serialized string, indicated by the keyword argument `string`.
|
18
|
+
class ObjectJSONCoder
|
19
|
+
class Error < StandardError
|
20
|
+
end
|
21
|
+
class LoadError < Error
|
22
|
+
end
|
23
|
+
class DumpError < Error
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(loaded_class, string: false, array: false, next_coder: nil)
|
27
|
+
@loaded_class = loaded_class
|
28
|
+
# this notes the order of the keys as they were in the json, used by dump_object to generate
|
29
|
+
# json that is equivalent to the json/jsonifiable that came in, so that AR's #changed_attributes
|
30
|
+
# can tell whether the attribute has been changed.
|
31
|
+
@loaded_class.send(:attr_accessor, :object_json_coder_keys_order)
|
32
|
+
@string = string
|
33
|
+
@array = array
|
34
|
+
@next_coder = next_coder
|
35
|
+
end
|
36
|
+
|
37
|
+
def load(column_data)
|
38
|
+
return nil if column_data.nil?
|
39
|
+
data = @string ? ::JSON.parse(column_data) : column_data
|
40
|
+
object = if @array
|
41
|
+
unless data.respond_to?(:to_ary)
|
42
|
+
raise TypeError, "expected array-like column data; got: #{data.class}: #{data.inspect}"
|
43
|
+
end
|
44
|
+
data.map { |el| load_object(el) }
|
45
|
+
else
|
46
|
+
load_object(data)
|
47
|
+
end
|
48
|
+
object = @next_coder.load(object) if @next_coder
|
49
|
+
object
|
50
|
+
end
|
51
|
+
|
52
|
+
def dump(object)
|
53
|
+
object = @next_coder.dump(object) if @next_coder
|
54
|
+
return nil if object.nil?
|
55
|
+
jsonifiable = begin
|
56
|
+
if @array
|
57
|
+
unless object.respond_to?(:to_ary)
|
58
|
+
raise DumpError, "expected array-like attribute; got: #{object.class}: #{object.inspect}"
|
59
|
+
end
|
60
|
+
object.map do |el|
|
61
|
+
dump_object(el)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
dump_object(object)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
@string ? ::JSON.generate(jsonifiable) : jsonifiable
|
68
|
+
end
|
69
|
+
end
|
70
|
+
# this is a ActiveRecord serialization class intended to store JSON in the
|
71
|
+
# database column and expose a given SchemaInstanceBase subclass once loaded
|
72
|
+
# on a model instance.
|
73
|
+
class SchemaInstanceJSONCoder < ObjectJSONCoder
|
74
|
+
private
|
75
|
+
def load_object(data)
|
76
|
+
@loaded_class.new(data)
|
77
|
+
end
|
78
|
+
|
79
|
+
def dump_object(object)
|
80
|
+
Scorpio::Typelike.as_json(object)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Scorpio
|
2
|
+
# this is a ActiveRecord serialization class intended to store JSON in the
|
3
|
+
# database column and expose a Struct subclass once loaded on a model instance.
|
4
|
+
class StructJSONCoder < ObjectJSONCoder
|
5
|
+
private
|
6
|
+
def load_object(data)
|
7
|
+
if data.is_a?(Hash)
|
8
|
+
good_keys = @loaded_class.members.map(&:to_s)
|
9
|
+
bad_keys = data.keys - good_keys
|
10
|
+
unless bad_keys.empty?
|
11
|
+
raise LoadError, "expected keys #{good_keys}; got unrecognized keys: #{bad_keys}"
|
12
|
+
end
|
13
|
+
instance = @loaded_class.new(*@loaded_class.members.map { |m| data[m.to_s] })
|
14
|
+
instance.object_json_coder_keys_order = data.keys
|
15
|
+
instance
|
16
|
+
else
|
17
|
+
raise LoadError, "expected instance(s) of #{Hash}; got: #{data.class}: #{data.inspect}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def dump_object(object)
|
22
|
+
if object.is_a?(@loaded_class)
|
23
|
+
keys = (object.object_json_coder_keys_order || []) | @loaded_class.members.map(&:to_s)
|
24
|
+
keys.map { |member| {member => object[member]} }.inject({}, &:update)
|
25
|
+
else
|
26
|
+
raise TypeError, "expected instance(s) of #{@loaded_class}; got: #{object.class}: #{object.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/scorpio/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scorpio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -264,6 +264,8 @@ files:
|
|
264
264
|
- lib/scorpio/schema.rb
|
265
265
|
- lib/scorpio/schema_instance_base.rb
|
266
266
|
- lib/scorpio/schema_instance_base/to_rb.rb
|
267
|
+
- lib/scorpio/schema_instance_json_coder.rb
|
268
|
+
- lib/scorpio/struct_json_coder.rb
|
267
269
|
- lib/scorpio/typelike_modules.rb
|
268
270
|
- lib/scorpio/util.rb
|
269
271
|
- lib/scorpio/util/faraday/response_media_type.rb
|