empty_eye 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,227 +0,0 @@
1
- module EmptyEye
2
- class ViewExtensionCollection
3
-
4
- #a collection of all the view_extensions
5
- #these are wranglers for the shards
6
- #uses 'array' as a proxy
7
- #performs array methods by passing things off in method missing
8
-
9
- def initialize(parent)
10
- @parent = parent
11
- @array = []
12
- end
13
-
14
- #the proxy object for instances
15
- def array
16
- @array
17
- end
18
-
19
- #we want to see the proxy object not the class info
20
- def inspect
21
- array.inspect
22
- end
23
-
24
- #the class to which the instance belongs
25
- def parent
26
- @parent
27
- end
28
-
29
- def descend(klass)
30
- @parent = klass
31
- self
32
- end
33
-
34
- #add extensions based on association from parent
35
- def association(assoc)
36
- new_extension = ViewExtension.new(assoc)
37
- reject! {|extension| new_extension.name == extension.name}
38
- push(new_extension)
39
- new_extension
40
- end
41
-
42
- #add primary extension; needs a table only
43
- def primary_table(table)
44
- push(@primary = PrimaryViewExtension.new(table, parent))
45
- end
46
-
47
- #generates view sql
48
- def create_view_sql
49
- #determine what shard will handle what columns
50
- map_attribute_management
51
- #start with primary table
52
- query = primary_arel_table
53
-
54
- #build select clause with correct table handling the appropriate columns
55
- arel_columns.each do |arel_column|
56
- query = query.project(arel_column)
57
- end
58
-
59
- #build joins
60
- without_primary.each do |ext|
61
- current = ext.arel_table
62
- key = ext.foreign_key.to_sym
63
- if ext.type_column
64
- query = query.join(current).on(
65
- primary.key.eq(current[key]), ext.type_column.eq(ext.type_value)
66
- )
67
- else
68
- query = query.join(current).on(
69
- primary.key.eq(current[key])
70
- )
71
- end
72
- end
73
-
74
- #we dont need to keep this data
75
- free_arel_columns
76
-
77
- #STI condition if needed
78
- if primary.sti_also?
79
- query.where(primary.type_column.eq(primary.type_value))
80
- end
81
-
82
- #build view creation statement
83
- "CREATE VIEW #{parent.table_name} AS\n#{query.to_sql}"
84
- end
85
-
86
- #takes the name of extension and a hash of intended updates from master instance
87
- #returns a subset of hash with only values the extension handles
88
- def delegate_map(name, hash)
89
- keys = update_mapping[name] & hash.keys
90
- keys.inject({}) do |res, col|
91
- res[col] = hash[col] if hash[col]
92
- res
93
- end
94
- end
95
-
96
- #in the end this will be an array of argument arrays
97
- #[[:validates_presence_of, :name, {}]]
98
- #parent will call the method and associated args inheriting validations
99
- def validations
100
- @validations ||= []
101
- end
102
-
103
- #the primary extension
104
- def primary
105
- @primary
106
- end
107
-
108
- #array of shard classes
109
- def shards
110
- map(&:shard)
111
- end
112
-
113
- #this object responds to array methods
114
- def respond_to?(m)
115
- super || array.respond_to?(m)
116
- end
117
-
118
- #delegate to the array proxy when the method is missing
119
- def method_missing(m, *args, &block)
120
- if respond_to?(m)
121
- array.send(m, *args, &block)
122
- else
123
- super
124
- end
125
- end
126
-
127
- #we dont need to keep this data
128
- def free_validations
129
- @validations = nil
130
- end
131
-
132
- private
133
-
134
- #all of the arel columns mapped to the right arel tables
135
- def arel_columns
136
- @arel_columns ||= []
137
- end
138
-
139
- #we dont need to keep this data
140
- def free_arel_columns
141
- @arel_columns = nil
142
- end
143
-
144
- #tracks the attributes with the view extension that will handle it
145
- def update_mapping
146
- @update_mapping ||= {}
147
- end
148
-
149
- #generate a foreign_key if it is missing
150
- def default_foreign_key
151
- view_name = parent.table_name.singularize
152
- "#{view_name}_id"
153
- end
154
-
155
- #the primary arel table
156
- def primary_arel_table
157
- primary.arel_table
158
- end
159
-
160
- #all the tables
161
- def tables
162
- map(&:table)
163
- end
164
-
165
- #map the columns to the extension that will handle it
166
- def map_attribute_management
167
- #clear out what we know
168
- arel_columns.clear
169
- #use this to track and remove dupes
170
- tracker = {}
171
- each do |ext|
172
- #mimic the parent's associations through primary shard
173
- primary.have_one(ext)
174
- ext.columns.each do |col|
175
- column = col.to_sym
176
- #skip if we already have this column
177
- next if tracker[column]
178
- #set to true so we wont do again
179
- tracker[column] = true
180
- #add the column based on the extension's arel_table
181
- arel_columns << ext.arel_table[column]
182
- #later we need to know how to update thing correctly
183
- update_mapping[ext.name] = update_mapping[ext.name].to_a << col
184
- #delegate the setter for column to shard of extension through primary shard
185
- primary.delegate_to(column, ext) unless ext.primary
186
- #mti class must inherit validations
187
- add_validations(column, ext)
188
- end
189
- end
190
- end
191
-
192
- #tried a cleaner solution but it wouldnt work
193
- #here i am stealing the arguments needed from the shards
194
- #to call the same validation on the master class (parent)
195
- def add_validations(column, ext)
196
- return unless ext.shard._validators[column].present?
197
- #primary either has no validations or they have already been inherited
198
- return if ext.primary
199
- rtn = ext.shard._validators[column].each do |validator|
200
- meth = case validator.class.to_s
201
- when /presence/i then :validates_presence_of
202
- when /acceptance/i then :validates_acceptance_of
203
- when /numericality/i then :validates_numericality_of
204
- when /length/i then :validates_length_of
205
- when /inclusion/i then :validates_inclusion_of
206
- when /format/i then :validates_format_of
207
- when /exclusion/i then :validates_exclusion_of
208
- when /confirmation/i then :validates_confirmation_of
209
- when /uniqueness/i then :validates_uniqueness_of
210
- else nil
211
- end
212
- if meth
213
- args = []
214
- args << meth
215
- args << column
216
- args << validator.options
217
- validations << args
218
- end
219
- end
220
- end
221
-
222
- #return a list of extensions without primary
223
- def without_primary
224
- array.select {|ext| ext != primary}
225
- end
226
- end
227
- end