spiderfw 0.6.21 → 0.6.22
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 +33 -0
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/apps/core/admin/_init.rb +4 -0
- data/apps/core/admin/admin.rb +20 -4
- data/apps/core/admin/controllers/admin_controller.rb +63 -4
- data/apps/core/admin/controllers/app_admin_controller.rb +15 -0
- data/apps/core/admin/data/locale/it/LC_MESSAGES/admin.mo +0 -0
- data/apps/core/admin/po/admin.pot +33 -0
- data/apps/core/admin/po/it/admin.po +34 -0
- data/apps/core/admin/public/css/admin.css +13 -0
- data/apps/core/admin/public/css/login.css +51 -0
- data/apps/core/admin/public/css/sass/admin.css +198 -0
- data/apps/core/admin/public/css/sass/bootstrap/bootstrap.css +3107 -0
- data/apps/core/admin/public/img/css/header_bg.png +0 -0
- data/apps/core/admin/public/img/css/noise.png +0 -0
- data/apps/core/admin/public/img/css/side_bg.png +0 -0
- data/apps/core/admin/public/img/icons/logout.png +0 -0
- data/apps/core/admin/public/img/icons-s845a69dd9f.png +0 -0
- data/apps/core/admin/public/js/bootstrap-alerts.js +113 -0
- data/apps/core/admin/public/js/bootstrap-buttons.js +62 -0
- data/apps/core/admin/public/js/bootstrap-dropdown.js +55 -0
- data/apps/core/admin/public/js/bootstrap-modal.js +260 -0
- data/apps/core/admin/public/js/bootstrap-popover.js +90 -0
- data/apps/core/admin/public/js/bootstrap-scrollspy.js +107 -0
- data/apps/core/admin/public/js/bootstrap-tabs.js +80 -0
- data/apps/core/admin/public/js/bootstrap-twipsy.js +321 -0
- data/apps/core/admin/public/sass/admin.scss +167 -0
- data/apps/core/admin/public/sass/bootstrap/bootstrap.scss +29 -0
- data/apps/core/admin/public/sass/bootstrap/forms.scss +478 -0
- data/apps/core/admin/public/sass/bootstrap/mixins.scss +220 -0
- data/apps/core/admin/public/sass/bootstrap/patterns.scss +1062 -0
- data/apps/core/admin/public/sass/bootstrap/reset.scss +141 -0
- data/apps/core/admin/public/sass/bootstrap/scaffolding.scss +136 -0
- data/apps/core/admin/public/sass/bootstrap/tables.scss +224 -0
- data/apps/core/admin/public/sass/bootstrap/type.scss +187 -0
- data/apps/core/admin/public/sass/bootstrap/variables.scss +60 -0
- data/apps/core/admin/public/sass/grid.scss +54 -0
- data/apps/core/admin/views/_app_info.shtml +5 -0
- data/apps/core/admin/views/admin.layout.shtml +35 -0
- data/apps/core/admin/views/index.shtml +1 -1
- data/apps/core/admin/views/login.layout.shtml +13 -0
- data/apps/core/auth/controllers/mixins/auth_helper.rb +1 -1
- data/apps/core/auth/models/super_user.rb +6 -0
- data/apps/core/auth/models/user.rb +9 -0
- data/apps/core/components/assets.rb +5 -1
- data/apps/core/components/data/locale/it/LC_MESSAGES/spider_components.mo +0 -0
- data/apps/core/components/po/it/spider_components.po +23 -9
- data/apps/core/components/po/spider_components.pot +16 -8
- data/apps/core/components/public/css/admin.css +0 -12
- data/apps/core/components/public/css/crud.css +16 -19
- data/apps/core/components/public/css/table.css +11 -5
- data/apps/core/components/public/js/less-1.1.3.min.js +16 -0
- data/apps/core/components/public/widgets/table.js +1 -1
- data/apps/core/components/widgets/admin/admin.rb +10 -0
- data/apps/core/components/widgets/admin/admin.shtml +24 -4
- data/apps/core/components/widgets/confirm/confirm.rb +2 -2
- data/apps/core/components/widgets/confirm/confirm.shtml +5 -2
- data/apps/core/components/widgets/crud/crud.rb +10 -1
- data/apps/core/components/widgets/crud/crud.shtml +18 -21
- data/apps/core/components/widgets/menu/menu.shtml +1 -2
- data/apps/core/components/widgets/switcher/switcher.rb +6 -3
- data/apps/core/components/widgets/switcher/templates/default.shtml +3 -1
- data/apps/core/components/widgets/table/table.rb +3 -2
- data/apps/core/components/widgets/table/table.shtml +44 -25
- data/apps/core/forms/data/locale/it/LC_MESSAGES/spider_forms.mo +0 -0
- data/apps/core/forms/po/it/spider_forms.po +7 -2
- data/apps/core/forms/po/spider_forms.pot +5 -1
- data/apps/core/forms/public/css/form.css +3 -3
- data/apps/core/forms/public/css/html_area.css +0 -1
- data/apps/core/forms/public/date_time.js +4 -3
- data/apps/core/forms/public/select.js +5 -4
- data/apps/core/forms/tags/element_label.erb +1 -1
- data/apps/core/forms/tags/row.erb +1 -1
- data/apps/core/forms/widgets/form/form.rb +23 -1
- data/apps/core/forms/widgets/form/form.shtml +7 -8
- data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +3 -3
- data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +3 -3
- data/apps/core/forms/widgets/inputs/file_input/file_input.rb +4 -2
- data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +1 -1
- data/apps/core/forms/widgets/inputs/hidden/hidden.shtml +1 -1
- data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
- data/apps/core/forms/widgets/inputs/password/password.shtml +3 -3
- data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +2 -2
- data/apps/core/forms/widgets/inputs/select/select.shtml +16 -13
- data/apps/core/forms/widgets/inputs/text/text.shtml +3 -3
- data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +5 -2
- data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +3 -3
- data/apps/messenger/_init.rb +10 -2
- data/apps/messenger/controllers/messenger_admin_controller.rb +53 -0
- data/apps/messenger/controllers/messenger_controller.rb +2 -0
- data/apps/messenger/controllers/mixins/messenger_helper.rb +2 -2
- data/apps/messenger/models/message.rb +1 -1
- data/apps/messenger/public/app_icon.png +0 -0
- data/apps/messenger/views/admin/_admin.layout.shtml +26 -0
- data/apps/messenger/views/admin/index.shtml +13 -0
- data/apps/messenger/views/admin/queue.shtml +28 -0
- data/apps/messenger/views/index.shtml +3 -3
- data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
- data/lib/spiderfw/app.rb +10 -1
- data/lib/spiderfw/cache/template_cache.rb +21 -22
- data/lib/spiderfw/cmd/commands/app.rb +3 -3
- data/lib/spiderfw/cmd/commands/setup.rb +1 -1
- data/lib/spiderfw/config/options/spider.rb +18 -2
- data/lib/spiderfw/controller/controller.rb +9 -3
- data/lib/spiderfw/controller/dispatcher.rb +25 -12
- data/lib/spiderfw/controller/home_controller.rb +3 -3
- data/lib/spiderfw/controller/http_controller.rb +11 -0
- data/lib/spiderfw/controller/mixins/static_content.rb +3 -12
- data/lib/spiderfw/controller/mixins/visual.rb +21 -20
- data/lib/spiderfw/controller/request.rb +1 -3
- data/lib/spiderfw/http/adapters/mongrel.rb +1 -1
- data/lib/spiderfw/i18n/gettext.rb +14 -0
- data/lib/spiderfw/i18n/shtml_parser.rb +2 -2
- data/lib/spiderfw/model/base_model.rb +4 -3
- data/lib/spiderfw/model/mappers/db_mapper.rb +137 -79
- data/lib/spiderfw/model/mappers/mapper.rb +6 -2
- data/lib/spiderfw/model/migrations/drop_element.rb +1 -1
- data/lib/spiderfw/model/migrations/previous_model.rb +73 -0
- data/lib/spiderfw/model/migrations/rename_element.rb +42 -0
- data/lib/spiderfw/model/migrations.rb +14 -1
- data/lib/spiderfw/model/mixins/tree.rb +65 -19
- data/lib/spiderfw/model/model_hash.rb +9 -5
- data/lib/spiderfw/model/query.rb +8 -0
- data/lib/spiderfw/model/query_funcs.rb +23 -0
- data/lib/spiderfw/model/query_set.rb +1 -1
- data/lib/spiderfw/model/request.rb +11 -3
- data/lib/spiderfw/model/storage/db/adapters/mysql.rb +28 -1
- data/lib/spiderfw/model/storage/db/adapters/oracle.rb +10 -10
- data/lib/spiderfw/model/storage/db/db_schema.rb +20 -3
- data/lib/spiderfw/model/storage/db/db_storage.rb +39 -17
- data/lib/spiderfw/setup/app_manager.rb +69 -31
- data/lib/spiderfw/setup/setup_task.rb +76 -8
- data/lib/spiderfw/spider.rb +21 -1
- data/lib/spiderfw/templates/blocks/text.rb +4 -4
- data/lib/spiderfw/templates/blocks/text_domain.rb +25 -0
- data/lib/spiderfw/templates/blocks/widget.rb +1 -1
- data/lib/spiderfw/templates/layout.rb +160 -92
- data/lib/spiderfw/templates/resources/less.rb +10 -2
- data/lib/spiderfw/templates/resources/sass.rb +66 -9
- data/lib/spiderfw/templates/template.rb +35 -10
- data/lib/spiderfw/templates/template_blocks.rb +6 -3
- data/lib/spiderfw/utils/logger.rb +20 -0
- data/lib/spiderfw/utils/memory.rb +7 -3
- data/lib/spiderfw/widget/widget.rb +13 -7
- data/lib/spiderfw/widget/widget_attributes.rb +2 -2
- data/spider.gemspec +1 -0
- metadata +68 -11
- data/apps/core/admin/views/spider_admin.layout.shtml +0 -23
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Spider; module Migrations
|
|
2
|
+
|
|
3
|
+
module PreviousModel
|
|
4
|
+
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.extend(ClassMethods)
|
|
7
|
+
klass.with_mapper do
|
|
8
|
+
def schema_table_name
|
|
9
|
+
if @model.previous_model_of
|
|
10
|
+
model.previous_model_of.mapper.schema.table.name
|
|
11
|
+
else
|
|
12
|
+
super.gsub('previousmodels__', '')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_new_model
|
|
19
|
+
nm = self.class.previous_model_of
|
|
20
|
+
obj = nm.new
|
|
21
|
+
vals = self.to_hash
|
|
22
|
+
vals.each do |k, v|
|
|
23
|
+
obj.set(k, v) if nm.elements[k]
|
|
24
|
+
end
|
|
25
|
+
obj
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
module ClassMethods
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def previous_model_of(model=nil)
|
|
32
|
+
@replacement_model = model if model
|
|
33
|
+
@replacement_model
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def class_table_inheritance(params={})
|
|
38
|
+
unless params[:name]
|
|
39
|
+
spm = nil
|
|
40
|
+
mpm = nil
|
|
41
|
+
if @replacement_model
|
|
42
|
+
spm = @replacement_model.parent_module
|
|
43
|
+
else
|
|
44
|
+
spm = self.parent_module.parent_module
|
|
45
|
+
end
|
|
46
|
+
if superclass.respond_to?(:previous_model_of)
|
|
47
|
+
if superclass.previous_model_of
|
|
48
|
+
mpm = superclass.previous_model_of
|
|
49
|
+
else
|
|
50
|
+
mpm = superclass.parent_module.parent_module
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
mpm = superclass.parent_module
|
|
54
|
+
end
|
|
55
|
+
integrated_name = (spm == mpm) ? superclass.short_name : superclass.name
|
|
56
|
+
integrated_name = Spider::Inflector.underscore(integrated_name).gsub('/', '_')
|
|
57
|
+
params[:name] = integrated_name
|
|
58
|
+
end
|
|
59
|
+
super(params)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def element(name, type, attributes={}, &proc)
|
|
63
|
+
super
|
|
64
|
+
if @elements[name].junction?
|
|
65
|
+
@elements[name].model.send(:include, PreviousModel)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end; end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Spider; module Migrations
|
|
2
|
+
|
|
3
|
+
class RenameElement < Migration
|
|
4
|
+
|
|
5
|
+
def initialize(model, element, new_element, options={})
|
|
6
|
+
@model = model
|
|
7
|
+
@element = element
|
|
8
|
+
@new_element = new_element
|
|
9
|
+
@options = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
field = @options[:field_name]
|
|
14
|
+
schema_field = nil
|
|
15
|
+
new_schema_field = nil
|
|
16
|
+
unless field
|
|
17
|
+
schema_field = @model.mapper.schema.field(@element)
|
|
18
|
+
field = schema_field.name if schema_field
|
|
19
|
+
end
|
|
20
|
+
field ||= @model.mapper.storage.column_name(@element)
|
|
21
|
+
new_field = @options[:new_field_name]
|
|
22
|
+
unless new_field
|
|
23
|
+
new_schema_field = @model.mapper.schema.field(@new_element)
|
|
24
|
+
new_field = new_schema_field.name if new_schema_field
|
|
25
|
+
end
|
|
26
|
+
new_field ||= @model.mapper.storage.column_name(@new_element)
|
|
27
|
+
f = new_schema_field || schema_field
|
|
28
|
+
raise "Neither #{@element} nor #{@new_element} were found in schema" unless f
|
|
29
|
+
|
|
30
|
+
desc = @model.mapper.storage.describe_table(@model.mapper.schema.table)
|
|
31
|
+
if desc[:columns][field] && !desc[:columns][new_field]
|
|
32
|
+
@model.mapper.storage.change_field(@model.mapper.schema.table, field, new_field, f.type, f.attributes)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def undo
|
|
37
|
+
self.class.new(@model, @new_element, @element).run
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end; end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
require 'spiderfw/model/migrations/migration'
|
|
2
|
+
require 'spiderfw/model/migrations/previous_model'
|
|
2
3
|
require 'spiderfw/model/migrations/irreversible_migration'
|
|
3
4
|
require 'spiderfw/model/migrations/replace'
|
|
4
5
|
require 'spiderfw/model/migrations/drop_element'
|
|
5
6
|
require 'spiderfw/model/migrations/drop_table'
|
|
7
|
+
require 'spiderfw/model/migrations/rename_element'
|
|
6
8
|
|
|
7
9
|
module Spider
|
|
8
10
|
|
|
@@ -17,7 +19,18 @@ module Spider
|
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def self.drop_table!(model, options={})
|
|
20
|
-
Spider::Migrations::DropTable.new(model,
|
|
22
|
+
Spider::Migrations::DropTable.new(model, options={})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.rename_element(model, element, new_element, options={})
|
|
26
|
+
RenameElement.new(model, element, new_element, options={})
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.previous_model(model, previous=nil)
|
|
30
|
+
model.send(:include, PreviousModel)
|
|
31
|
+
if previous
|
|
32
|
+
model.previous_model_of(previous)
|
|
33
|
+
end
|
|
21
34
|
end
|
|
22
35
|
|
|
23
36
|
|
|
@@ -21,15 +21,44 @@ module Spider; module Model
|
|
|
21
21
|
res = element.model.find(q)
|
|
22
22
|
return [] unless res
|
|
23
23
|
right_stack = []
|
|
24
|
+
parents = []
|
|
25
|
+
first = nil
|
|
24
26
|
res.each do |obj|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
first ||= obj
|
|
28
|
+
if right_stack.length > 0
|
|
29
|
+
while right_stack.length > 0 && right_stack.last < obj.get(right_el)
|
|
30
|
+
right_stack.pop
|
|
31
|
+
p, sub = parents.pop
|
|
32
|
+
p.set_loaded_value(element.name, sub)
|
|
33
|
+
parents.last[1] << p if parents.last
|
|
34
|
+
end
|
|
27
35
|
obj.set(element.attributes[:tree_depth], right_stack.length)
|
|
28
36
|
end
|
|
29
37
|
right_stack << obj.get(right_el)
|
|
38
|
+
parents << [obj, QuerySet.static(self.class)]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
while pair = parents.pop
|
|
42
|
+
p, sub = pair
|
|
43
|
+
p.set_loaded_value(element.name, sub)
|
|
44
|
+
parents.last[1] << p if parents.last
|
|
30
45
|
end
|
|
46
|
+
|
|
31
47
|
return res
|
|
32
48
|
end
|
|
49
|
+
|
|
50
|
+
def before_save
|
|
51
|
+
self.class.elements_array.select{ |el| el.attributes[:association] == :tree }.each do |el|
|
|
52
|
+
if element_modified?(el)
|
|
53
|
+
cnt = 1
|
|
54
|
+
self.get(el).each do |obj|
|
|
55
|
+
obj.set(el.attributes[:tree_position], cnt)
|
|
56
|
+
cnt += 1
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
super
|
|
61
|
+
end
|
|
33
62
|
|
|
34
63
|
module ClassMethods
|
|
35
64
|
|
|
@@ -189,27 +218,30 @@ module Spider; module Model
|
|
|
189
218
|
|
|
190
219
|
def before_save(obj, mode)
|
|
191
220
|
@model.elements_array.select{ |el| el.attributes[:association] == :tree }.each do |el|
|
|
192
|
-
unless obj.element_modified?(el.attributes[:reverse]) || obj.element_modified?(el.attributes[:tree_position])
|
|
221
|
+
unless mode == :insert || obj.element_modified?(el.attributes[:reverse]) || obj.element_modified?(el.attributes[:tree_position])
|
|
193
222
|
next
|
|
194
223
|
end
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if
|
|
202
|
-
|
|
203
|
-
if
|
|
204
|
-
|
|
224
|
+
# already set by parent
|
|
225
|
+
unless obj.element_modified?(el.attributes[:tree_left])
|
|
226
|
+
if mode == :update
|
|
227
|
+
tree_remove(el, obj)
|
|
228
|
+
end
|
|
229
|
+
parent = obj.get(el.attributes[:reverse])
|
|
230
|
+
if parent
|
|
231
|
+
sub = parent.get(el.name)
|
|
232
|
+
if obj.element_modified?(el.attributes[:tree_position]) && sub.length > 0
|
|
233
|
+
pos = obj.get(el.attributes[:tree_position])
|
|
234
|
+
if pos == 1
|
|
235
|
+
tree_insert_node_first(el, obj, parent)
|
|
236
|
+
else
|
|
237
|
+
tree_insert_node_right(el, obj, sub[pos-2])
|
|
238
|
+
end
|
|
205
239
|
else
|
|
206
|
-
|
|
240
|
+
tree_insert_node_under(el, obj, parent)
|
|
207
241
|
end
|
|
208
242
|
else
|
|
209
|
-
|
|
243
|
+
tree_insert_node(el, obj)
|
|
210
244
|
end
|
|
211
|
-
else
|
|
212
|
-
tree_insert_node(el, obj)
|
|
213
245
|
end
|
|
214
246
|
end
|
|
215
247
|
super
|
|
@@ -268,7 +300,7 @@ module Spider; module Model
|
|
|
268
300
|
left_el = tree_el.attributes[:tree_left]; right_el = tree_el.attributes[:tree_right]
|
|
269
301
|
cur = left+1
|
|
270
302
|
obj.get(tree_el).each do |child|
|
|
271
|
-
cur = tree_assign_values(tree_el, child, cur)
|
|
303
|
+
cur = tree_assign_values(tree_el, child, cur) + 1
|
|
272
304
|
end
|
|
273
305
|
obj.set(left_el, left)
|
|
274
306
|
obj.set(right_el, cur)
|
|
@@ -292,7 +324,7 @@ module Spider; module Model
|
|
|
292
324
|
|
|
293
325
|
def tree_insert_node_right(tree_el, obj, sibling)
|
|
294
326
|
obj.set(tree_el.attributes[:reverse], sibling.get(tree_el.attributes[:reverse]))
|
|
295
|
-
tree_insert_node(tree_el, obj, sibling.get(tree_el.attributes[:tree_right]))
|
|
327
|
+
tree_insert_node(tree_el, obj, sibling.get(tree_el.attributes[:tree_right])+1)
|
|
296
328
|
end
|
|
297
329
|
|
|
298
330
|
def tree_remove(tree_el, obj)
|
|
@@ -337,6 +369,20 @@ module Spider; module Model
|
|
|
337
369
|
condition = Condition.new.set(left_el, '>', right)
|
|
338
370
|
bulk_update({:left_el => QueryFuncs::Expression.new(":#{left_el} - 2")}, condition)
|
|
339
371
|
end
|
|
372
|
+
|
|
373
|
+
# Ensure that in Unit of Work parents are saved before children
|
|
374
|
+
def get_dependencies(task)
|
|
375
|
+
deps = super
|
|
376
|
+
if task.action == :save
|
|
377
|
+
@model.elements_array.select{ |el| el.attributes[:association] == :tree }.each do |el|
|
|
378
|
+
if task.object.element_modified?(el.attributes[:reverse])
|
|
379
|
+
parent = task.object.get(el.attributes[:reverse])
|
|
380
|
+
deps << [task, MapperTask.new(parent, :save)] if parent
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
deps
|
|
385
|
+
end
|
|
340
386
|
|
|
341
387
|
|
|
342
388
|
|
|
@@ -32,11 +32,15 @@ module Spider; module Model
|
|
|
32
32
|
val = n
|
|
33
33
|
end
|
|
34
34
|
key = key.name if key.is_a?(Element)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
if key.is_a?(String)
|
|
36
|
+
parts = key.split('.', 2)
|
|
37
|
+
return super(key.to_sym, val) unless parts[1]
|
|
38
|
+
parts[0] = parts[0].to_sym
|
|
39
|
+
self[parts[0]] = get_deep_obj unless self[parts[0]].is_a?(self.class)
|
|
40
|
+
self[parts[0]][parts[1]] = val
|
|
41
|
+
else
|
|
42
|
+
super(key, val)
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
def [](key)
|
data/lib/spiderfw/model/query.rb
CHANGED
|
@@ -21,6 +21,7 @@ module Spider; module Model
|
|
|
21
21
|
attr_reader :request
|
|
22
22
|
attr_reader :page_rows
|
|
23
23
|
attr_reader :page
|
|
24
|
+
attr_accessor :group_by_elements
|
|
24
25
|
|
|
25
26
|
# Instantiates a new query, calling Condition#where on the condition.
|
|
26
27
|
def self.where(*params)
|
|
@@ -82,6 +83,12 @@ module Spider; module Model
|
|
|
82
83
|
end
|
|
83
84
|
return self
|
|
84
85
|
end
|
|
86
|
+
|
|
87
|
+
def group_by(*elements)
|
|
88
|
+
@group_by_elements ||= []
|
|
89
|
+
@group_by_elements += elements
|
|
90
|
+
return self
|
|
91
|
+
end
|
|
85
92
|
|
|
86
93
|
# Adds each element in the given list to the request.
|
|
87
94
|
def select(*elements)
|
|
@@ -160,6 +167,7 @@ module Spider; module Model
|
|
|
160
167
|
cl.offset = @offset
|
|
161
168
|
cl.limit = @limit
|
|
162
169
|
cl.polymorphs = @polymorphs.clone
|
|
170
|
+
cl.group_by_elements = @group_by_elements.clone if @group_by_elements
|
|
163
171
|
return cl
|
|
164
172
|
end
|
|
165
173
|
|
|
@@ -94,6 +94,29 @@ module Spider; module QueryFuncs
|
|
|
94
94
|
"#{self.func_name.to_s.upcase}(#{elements.map{ |el| el.inspect }.join(', ')})"
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
+
def as(name)
|
|
98
|
+
SelectFunction.new(self, name)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class SelectFunction
|
|
104
|
+
attr_reader :function, :as
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def initialize(function, as)
|
|
108
|
+
@function = function
|
|
109
|
+
@as = as
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def inspect
|
|
113
|
+
"#{@function.inspect} AS #{@as}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def method_missing(method, *args)
|
|
117
|
+
@function.send(method, *args)
|
|
118
|
+
end
|
|
119
|
+
|
|
97
120
|
end
|
|
98
121
|
|
|
99
122
|
class ZeroArityFunction < Function
|
|
@@ -281,7 +281,7 @@ module Spider; module Model
|
|
|
281
281
|
|
|
282
282
|
# Total number of objects that would be returned had the Query no limit.
|
|
283
283
|
def total_rows
|
|
284
|
-
return @total_rows ? @total_rows : @model.mapper.count(@query.condition)
|
|
284
|
+
return @total_rows ? @total_rows : (@total_rows = @model.mapper.count(@query.condition))
|
|
285
285
|
end
|
|
286
286
|
|
|
287
287
|
# Current number of objects fetched.
|
|
@@ -24,15 +24,23 @@ module Spider; module Model
|
|
|
24
24
|
@polymorphs = {}
|
|
25
25
|
@expandable = true
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
def self.strict(val=nil, params={})
|
|
29
|
+
r = self.new(val, params)
|
|
30
|
+
r.expandable = false
|
|
31
|
+
r
|
|
32
|
+
end
|
|
27
33
|
|
|
28
34
|
# TODO: fix/remove?
|
|
29
35
|
def request(element) # :nodoc:
|
|
30
|
-
if
|
|
36
|
+
if element.is_a?(Element)
|
|
31
37
|
self[element.name.to_s] = true
|
|
32
|
-
|
|
33
|
-
element.
|
|
38
|
+
elsif element.is_a?(String)
|
|
39
|
+
element.split(',').each do |el|
|
|
34
40
|
self[el.strip] = true
|
|
35
41
|
end
|
|
42
|
+
else
|
|
43
|
+
self[element] = true
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
|
|
@@ -290,8 +290,19 @@ module Spider; module Model; module Storage; module Db
|
|
|
290
290
|
sql += "#{sql_keys(query)} FROM #{tables_sql} "
|
|
291
291
|
bind_vars += tables_values
|
|
292
292
|
where, vals = sql_condition(query)
|
|
293
|
-
|
|
293
|
+
|
|
294
|
+
bind_vars += vals if vals
|
|
294
295
|
sql += "WHERE #{where} " if where && !where.empty?
|
|
296
|
+
having, having_vals = sql_condition(query, true)
|
|
297
|
+
unless having.blank? && query[:group_by].blank?
|
|
298
|
+
group_fields = query[:group_by] || (
|
|
299
|
+
query[:keys].select{ |k| !k.is_a?(FieldExpression)
|
|
300
|
+
} + collect_having_fields(query[:condition])).flatten.uniq
|
|
301
|
+
group_keys = sql_keys(group_fields)
|
|
302
|
+
sql += "GROUP BY #{group_keys} "
|
|
303
|
+
sql += "HAVING #{having} " unless having.blank?
|
|
304
|
+
bind_vars += having_vals if having_vals
|
|
305
|
+
end
|
|
295
306
|
order = sql_order(query)
|
|
296
307
|
sql += "ORDER BY #{order} " if order && !order.empty?
|
|
297
308
|
limit = sql_limit(query)
|
|
@@ -304,12 +315,28 @@ module Spider; module Model; module Storage; module Db
|
|
|
304
315
|
sql += " AUTO_INCREMENT" if attributes[:autoincrement]
|
|
305
316
|
return sql
|
|
306
317
|
end
|
|
318
|
+
|
|
319
|
+
def sql_add_field(table_name, name, type, attributes)
|
|
320
|
+
sqls = super
|
|
321
|
+
sqls[0] += ", ADD PRIMARY KEY(#{name})" if attributes[:primary_key]
|
|
322
|
+
sqls
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def sql_alter_field(table_name, name, type, attributes)
|
|
326
|
+
sqls = super
|
|
327
|
+
sqls[0] += ", ADD PRIMARY KEY(#{name})" if attributes[:primary_key]
|
|
328
|
+
sqls
|
|
329
|
+
end
|
|
307
330
|
|
|
308
331
|
def sql_create_table(create)
|
|
309
332
|
sqls = super
|
|
310
333
|
sqls[0] += " ENGINE=#{@configuration['default_engine']}" if @configuration['default_engine']
|
|
311
334
|
sqls
|
|
312
335
|
end
|
|
336
|
+
|
|
337
|
+
def sql_create_primary_key(table_name, fields)
|
|
338
|
+
nil # done in add field or alter field
|
|
339
|
+
end
|
|
313
340
|
|
|
314
341
|
def function(func)
|
|
315
342
|
return super unless func.func_name == :concat
|
|
@@ -118,24 +118,24 @@ module Spider; module Model; module Storage; module Db
|
|
|
118
118
|
query[:order] << [query[:keys][0], 'desc'] if query[:order].length < 1
|
|
119
119
|
query[:order].each do |o|
|
|
120
120
|
field, direction = o
|
|
121
|
-
|
|
122
|
-
# unless i
|
|
123
|
-
# query[:keys].push(field)
|
|
124
|
-
# i = query[:keys].length < 1
|
|
125
|
-
# end
|
|
126
|
-
transformed = "O#{replace_cnt += 1}"
|
|
127
|
-
query[:order_replacements][field.to_s] = transformed
|
|
121
|
+
|
|
128
122
|
if field.is_a?(Spider::Model::Storage::Db::Field) && !query[:tables].include?(field.table)
|
|
129
123
|
query[:order_on_different_table] = true
|
|
130
124
|
end
|
|
131
125
|
if field.is_a?(FieldFunction)
|
|
132
126
|
query[:order_on_different_table] = true if field.joins.length > 0
|
|
133
127
|
end
|
|
134
|
-
if
|
|
128
|
+
if field.is_a?(Spider::Model::Storage::Db::Field) && field.type == 'CLOB'
|
|
135
129
|
field = "CAST(#{field} as varchar2(100))"
|
|
136
130
|
end
|
|
131
|
+
field_expr = field.is_a?(FieldExpression) ? field.expression : field.to_s
|
|
137
132
|
|
|
138
|
-
query[:keys]
|
|
133
|
+
unless query[:keys].include?(field) || field.is_a?(FieldExpression)
|
|
134
|
+
transformed = "O#{replace_cnt += 1}"
|
|
135
|
+
query[:order_replacements][field.to_s] = transformed
|
|
136
|
+
|
|
137
|
+
query[:keys] << Db::FieldExpression.new(field.table, transformed, field.type, :expression => field_expr)
|
|
138
|
+
end
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
keys = sql_keys(query)
|
|
@@ -145,7 +145,7 @@ module Spider; module Model; module Storage; module Db
|
|
|
145
145
|
bind_vars += tables_values
|
|
146
146
|
|
|
147
147
|
where, vals = sql_condition(query)
|
|
148
|
-
bind_vars += vals
|
|
148
|
+
bind_vars += vals if vals
|
|
149
149
|
sql += "WHERE #{where} " if where && !where.empty?
|
|
150
150
|
|
|
151
151
|
having, having_vals = sql_condition(query, true)
|
|
@@ -110,9 +110,14 @@ module Spider; module Model; module Storage; module Db
|
|
|
110
110
|
if field.is_a?(Hash)
|
|
111
111
|
field[:attributes] ||= {}
|
|
112
112
|
field[:attributes][:expression] ||= field[:expression]
|
|
113
|
-
|
|
113
|
+
field[:attributes][:fixed] ||= field[:fixed]
|
|
114
|
+
if field[:attributes][:expression] || field[:attributes][:fixed]
|
|
114
115
|
field[:name] = "#{@table}_#{element_name}_#{element_key}".upcase
|
|
115
|
-
|
|
116
|
+
if field[:attributes][:fixed]
|
|
117
|
+
field = FixedExpression.new(@table, field[:name], field[:type], field[:attributes][:fixed], field[:attributes])
|
|
118
|
+
else
|
|
119
|
+
field = FieldExpression.new(@table, field[:name], field[:type], field[:attributes] || {})
|
|
120
|
+
end
|
|
116
121
|
else
|
|
117
122
|
field = Field.new(@table, field[:name], field[:type], field[:attributes] || {})
|
|
118
123
|
end
|
|
@@ -280,9 +285,17 @@ module Spider; module Model; module Storage; module Db
|
|
|
280
285
|
end
|
|
281
286
|
|
|
282
287
|
end
|
|
288
|
+
|
|
289
|
+
class FixedExpression < FieldExpression
|
|
290
|
+
def initialize(table, name, type, fixed_value, attributes={})
|
|
291
|
+
attributes[:expression] = fixed_value
|
|
292
|
+
super(table, name, type, attributes)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
283
295
|
|
|
284
296
|
class FieldFunction
|
|
285
297
|
attr_reader :expression, :table, :joins
|
|
298
|
+
attr_accessor :as
|
|
286
299
|
def initialize(expression, table, joins)
|
|
287
300
|
@expression = expression
|
|
288
301
|
@table = table
|
|
@@ -298,7 +311,11 @@ module Spider; module Model; module Storage; module Db
|
|
|
298
311
|
end
|
|
299
312
|
|
|
300
313
|
def to_s
|
|
301
|
-
@
|
|
314
|
+
if @as
|
|
315
|
+
"#{@expression} AS #{@as}"
|
|
316
|
+
else
|
|
317
|
+
@expression
|
|
318
|
+
end
|
|
302
319
|
end
|
|
303
320
|
end
|
|
304
321
|
|