datasource 0.1.1 → 0.2.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 +129 -102
- data/lib/datasource/adapters/active_record.rb +106 -41
- data/lib/datasource/adapters/sequel.rb +53 -30
- data/lib/datasource/attributes/loaded.rb +101 -0
- data/lib/datasource/base.rb +90 -29
- data/lib/datasource/collection_context.rb +32 -0
- data/lib/datasource/consumer_adapters/active_model_serializers.rb +66 -4
- data/lib/datasource.rb +13 -12
- metadata +9 -9
- data/lib/datasource/attributes/loader.rb +0 -86
- data/lib/datasource/serializer.rb +0 -117
@@ -1,86 +0,0 @@
|
|
1
|
-
module Datasource
|
2
|
-
module Attributes
|
3
|
-
class Loader
|
4
|
-
class << self
|
5
|
-
attr_accessor :_options
|
6
|
-
attr_accessor :_load_proc
|
7
|
-
|
8
|
-
def inherited(base)
|
9
|
-
base._options = (_options || {}).dup
|
10
|
-
end
|
11
|
-
|
12
|
-
def options(hash)
|
13
|
-
self._options.merge!(hash)
|
14
|
-
end
|
15
|
-
|
16
|
-
def default_value
|
17
|
-
self._options[:default]
|
18
|
-
end
|
19
|
-
|
20
|
-
def load(*args, &block)
|
21
|
-
args = args.slice(0, _load_proc.arity) if _load_proc.arity >= 0
|
22
|
-
results = _load_proc.call(*args, &block)
|
23
|
-
|
24
|
-
if _options[:group_by]
|
25
|
-
results = Array(results)
|
26
|
-
send_args = if results.first && results.first.kind_of?(Hash)
|
27
|
-
[:[]]
|
28
|
-
else
|
29
|
-
[]
|
30
|
-
end
|
31
|
-
|
32
|
-
if _options[:one]
|
33
|
-
results.inject({}) do |hash, r|
|
34
|
-
key = r.send(*send_args, _options[:group_by])
|
35
|
-
hash[key] = r
|
36
|
-
hash
|
37
|
-
end
|
38
|
-
else
|
39
|
-
results.inject({}) do |hash, r|
|
40
|
-
key = r.send(*send_args, _options[:group_by])
|
41
|
-
(hash[key] ||= []).push(r)
|
42
|
-
hash
|
43
|
-
end
|
44
|
-
end
|
45
|
-
elsif _options[:array_to_hash]
|
46
|
-
Array(results).inject({}) do |hash, r|
|
47
|
-
hash[r[0]] = r[1]
|
48
|
-
hash
|
49
|
-
end
|
50
|
-
else
|
51
|
-
results
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
class Datasource::Base
|
59
|
-
private
|
60
|
-
def self.loader(name, _options = {}, &block)
|
61
|
-
klass = Class.new(Attributes::Loader) do
|
62
|
-
# depends deps
|
63
|
-
options(_options)
|
64
|
-
self._load_proc = block
|
65
|
-
end
|
66
|
-
@_loaders[name.to_sym] = klass
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.loaded(name, _options = {}, &block)
|
70
|
-
loader(name, _options, &block)
|
71
|
-
renamed_existing_method = :"#{name}_without_datasource"
|
72
|
-
orm_klass.class_eval do
|
73
|
-
alias_method renamed_existing_method, name if method_defined?(name)
|
74
|
-
fail "#{name} already defined on #{to_s}, would be overridden by datasource loaded method" if method_defined?(name)
|
75
|
-
define_method name do |*args, &block|
|
76
|
-
if loaded_values || !method_defined?(renamed_existing_method)
|
77
|
-
loaded_values[name.to_sym]
|
78
|
-
else
|
79
|
-
send(renamed_existing_method, *args, &block)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
computed name, loader: name
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
module Datasource
|
2
|
-
class Serializer
|
3
|
-
TemplatePart = Struct.new(:parent, :type, :value, :select) do
|
4
|
-
def initialize(parent, type = nil, value = nil)
|
5
|
-
super(parent, type, get_default_value(type, value), [])
|
6
|
-
end
|
7
|
-
|
8
|
-
def set_default_value(value = nil)
|
9
|
-
self.value = get_default_value(type, value)
|
10
|
-
end
|
11
|
-
private
|
12
|
-
def get_default_value(type, value)
|
13
|
-
case type
|
14
|
-
when :hash then {}
|
15
|
-
when :array then []
|
16
|
-
when :datasource then value
|
17
|
-
when nil then nil
|
18
|
-
else
|
19
|
-
fail "Unknown type #{type}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class << self
|
25
|
-
attr_accessor :datasource_count, :template
|
26
|
-
|
27
|
-
def inherited(base)
|
28
|
-
base.datasource_count = 0
|
29
|
-
@cursor = base.template = nil
|
30
|
-
end
|
31
|
-
|
32
|
-
def with_new_cursor(type, value = nil, &block)
|
33
|
-
result = nil
|
34
|
-
new_cursor = TemplatePart.new(@cursor, type, value)
|
35
|
-
@cursor = @cursor.tap do
|
36
|
-
if template.nil?
|
37
|
-
self.template = @cursor = new_cursor
|
38
|
-
elsif @cursor.type == :datasource
|
39
|
-
@cursor = @cursor.parent
|
40
|
-
return with_new_cursor(type, value, &block)
|
41
|
-
elsif @cursor.type == :array
|
42
|
-
@cursor = new_cursor
|
43
|
-
@cursor.parent.push(@cursor)
|
44
|
-
elsif @cursor.type.nil?
|
45
|
-
# replace cursor
|
46
|
-
@cursor.type = type
|
47
|
-
@cursor.set_default_value(value)
|
48
|
-
else
|
49
|
-
fail "Invalid use of #{type}."
|
50
|
-
end
|
51
|
-
result = block.call
|
52
|
-
end
|
53
|
-
result
|
54
|
-
end
|
55
|
-
|
56
|
-
def hash(&block)
|
57
|
-
with_new_cursor(:hash, &block)
|
58
|
-
end
|
59
|
-
|
60
|
-
def key(name)
|
61
|
-
fail "Cannot use key outside hash." unless template && @cursor.type == :hash
|
62
|
-
@cursor = @cursor.tap do
|
63
|
-
@cursor = @cursor.value[name.to_s] = TemplatePart.new(@cursor)
|
64
|
-
yield
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def array(&block)
|
69
|
-
with_new_cursor(:array, &block)
|
70
|
-
end
|
71
|
-
|
72
|
-
def datasource(ds)
|
73
|
-
self.datasource_count += 1
|
74
|
-
@cursor = with_new_cursor(:datasource, ds) { @cursor }
|
75
|
-
end
|
76
|
-
|
77
|
-
def attributes(*attributes)
|
78
|
-
attributes.each { |name| attribute name }
|
79
|
-
end
|
80
|
-
|
81
|
-
def attribute(name)
|
82
|
-
fail "No datasource selected - use \"select_datasource Klass\" first." unless template && @cursor.type == :datasource
|
83
|
-
@cursor.select << name
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def initialize(*scopes)
|
88
|
-
@scopes = scopes
|
89
|
-
if @scopes.size != self.class.datasource_count
|
90
|
-
fail ArgumentError, "#{self.class.name} needs #{self.class.datasource_count} scopes, you provided #{@scopes.size}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def as_json
|
95
|
-
parse_template_part(self.class.template)
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
def parse_template_part(part)
|
100
|
-
return nil unless part
|
101
|
-
case part.type
|
102
|
-
when :hash
|
103
|
-
{}.tap do |result|
|
104
|
-
part.value.each_pair do |k, v|
|
105
|
-
result[k] = parse_template_part(v)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
when :array
|
109
|
-
part.value.map { |v| parse_template_part(v) }
|
110
|
-
when :datasource
|
111
|
-
part.value.new(@scopes.shift).select(*part.select).results
|
112
|
-
else
|
113
|
-
fail "Unknown type #{type}"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|