datasource 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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