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.
@@ -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