empty_eye 0.4.2 → 0.4.3
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.
- data/CHANGELOG.md +6 -1
- data/lib/empty_eye/active_record/base.rb +41 -85
- data/lib/empty_eye/associations/shard_association_scope.rb +1 -1
- data/lib/empty_eye/associations/shard_has_one_association.rb +1 -1
- data/lib/empty_eye/persistence.rb +4 -4
- data/lib/empty_eye/{primary_view_extension.rb → primary_shard.rb} +30 -43
- data/lib/empty_eye/relation.rb +2 -65
- data/lib/empty_eye/shard.rb +86 -111
- data/lib/empty_eye/shard_collection.rb +192 -0
- data/lib/empty_eye/shard_wrangler.rb +300 -0
- data/lib/empty_eye/version.rb +1 -1
- data/lib/empty_eye.rb +5 -4
- data/spec/spec_helper.rb +0 -6
- metadata +7 -7
- data/lib/empty_eye/view_extension.rb +0 -114
- data/lib/empty_eye/view_extension_collection.rb +0 -227
@@ -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
|