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
|
@@ -30,9 +30,9 @@ module Spider
|
|
|
30
30
|
@app_routes ||= []
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def self.print_app_routes
|
|
34
|
-
max_length =
|
|
35
|
-
|
|
33
|
+
def self.print_app_routes(routes=app_routes)
|
|
34
|
+
max_length = routes.inject(0){ |m, r| m > r[0].length ? m : r[0].length }
|
|
35
|
+
routes.map{ |r| "#{r[0].ljust(max_length+3)} -> #{r[1]}"}.sort.join("\n")
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
end
|
|
@@ -99,6 +99,16 @@ module Spider
|
|
|
99
99
|
@request.format = $2.to_sym
|
|
100
100
|
end
|
|
101
101
|
# Spider.reload_sources if Spider.conf.get('webserver.reload_sources')
|
|
102
|
+
static_level = Spider.conf.get('log.static_extensions')
|
|
103
|
+
if @request.format && @request.get? && static_level != true
|
|
104
|
+
allowed = Spider.conf.get('log.non_static_extensions_list')
|
|
105
|
+
unless allowed.include?(@request.format.to_s)
|
|
106
|
+
Spider.logger.info("GET #{@request.path}")
|
|
107
|
+
@logger_static_prev = Spider.logger.set_thread_level(static_level)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
Spider::Logger.debug("REQUEST:")
|
|
111
|
+
Spider::Logger.debug(@request.env)
|
|
102
112
|
Spider.logger.info("Request: #{@request.http_method} #{@request.http_host} #{@request.path}")
|
|
103
113
|
super(action, *arguments)
|
|
104
114
|
end
|
|
@@ -116,6 +126,7 @@ module Spider
|
|
|
116
126
|
action = $1 if (action =~ /(.+)\.(\w+)$/) # strip extension, set format
|
|
117
127
|
@request.session.persist if @request.session && @request.session.respond_to?(:persist)
|
|
118
128
|
super(action, *arguments)
|
|
129
|
+
@Spider.logger.set_thread_level(@logger_static_prev) if @logger_static_prev
|
|
119
130
|
end
|
|
120
131
|
|
|
121
132
|
def ensure(action='', *arguments)
|
|
@@ -10,8 +10,8 @@ module Spider; module ControllerMixins
|
|
|
10
10
|
|
|
11
11
|
def self.included(klass)
|
|
12
12
|
super
|
|
13
|
-
|
|
14
|
-
klass.route(
|
|
13
|
+
@static_content_route ||= 'public/'
|
|
14
|
+
klass.route(@static_content_route, :serve_static, :do => lambda{ @serving_static = true })
|
|
15
15
|
if (klass < Visual)
|
|
16
16
|
klass.no_layout('public')
|
|
17
17
|
klass.no_layout('serve_static')
|
|
@@ -61,14 +61,6 @@ module Spider; module ControllerMixins
|
|
|
61
61
|
output_static(full_path)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
def serve_widget_static(path)
|
|
65
|
-
path = sanitize_path(path)
|
|
66
|
-
parts = path.split('/public/', 2)
|
|
67
|
-
raise Spider::Controller::NotFound.new(path) unless parts[1]
|
|
68
|
-
full_path = self.class.app.widgets_path+'/'+parts[0]+'/public/'+parts[1]
|
|
69
|
-
output_static(full_path)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
64
|
def output_static(full_path, file_name=nil)
|
|
73
65
|
file_name ||= File.basename(full_path)
|
|
74
66
|
@request.misc[:is_static] = true
|
|
@@ -89,11 +81,10 @@ module Spider; module ControllerMixins
|
|
|
89
81
|
begin
|
|
90
82
|
if_modified = Time.httpdate(@request.env['HTTP_IF_MODIFIED_SINCE'])
|
|
91
83
|
rescue ArgumentError # Passenger with IE6 has this header wrong
|
|
92
|
-
if_modified = 0
|
|
93
84
|
end
|
|
94
85
|
max_age = nil
|
|
95
86
|
fresh = true
|
|
96
|
-
if fresh && mtime <= if_modified
|
|
87
|
+
if fresh && if_modified && mtime <= if_modified
|
|
97
88
|
debug("Not modified since #{if_modified}: #{full_path}")
|
|
98
89
|
#@response.status = Spider::HTTP::NOT_MODIFIED
|
|
99
90
|
@response.headers.delete("Content-Type")
|
|
@@ -43,6 +43,16 @@ module Spider; module ControllerMixins
|
|
|
43
43
|
if Spider.runmode != 'devel' && File.exists?(File.join(Spider.paths[:tmp], 'maintenance.txt'))
|
|
44
44
|
raise Spider::Controller::Maintenance
|
|
45
45
|
end
|
|
46
|
+
n_route = dispatch_next(action)
|
|
47
|
+
obj = n_route.obj if n_route
|
|
48
|
+
if obj.is_a?(Visual) && !(obj.respond_to?(:serving_static?) && obj.serving_static?(n_route.path))
|
|
49
|
+
set_layout = @layout || @dispatcher_layout
|
|
50
|
+
if set_layout
|
|
51
|
+
set_layout = [set_layout] unless set_layout.is_a?(Array)
|
|
52
|
+
set_layout.map{ |l| self.class.load_layout(l) }
|
|
53
|
+
obj.dispatcher_layout = set_layout
|
|
54
|
+
end
|
|
55
|
+
end
|
|
46
56
|
super
|
|
47
57
|
end
|
|
48
58
|
|
|
@@ -210,13 +220,12 @@ module Spider; module ControllerMixins
|
|
|
210
220
|
end
|
|
211
221
|
init_widgets(template, layout)
|
|
212
222
|
return template if done?
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
223
|
+
|
|
224
|
+
if layout
|
|
225
|
+
layout.render(scene)
|
|
226
|
+
else
|
|
227
|
+
template.render(scene)
|
|
228
|
+
end
|
|
220
229
|
return template
|
|
221
230
|
end
|
|
222
231
|
|
|
@@ -236,21 +245,12 @@ module Spider; module ControllerMixins
|
|
|
236
245
|
|
|
237
246
|
|
|
238
247
|
|
|
239
|
-
def dispatched_object(route)
|
|
240
|
-
obj = super
|
|
241
|
-
if (obj.is_a?(Visual))
|
|
242
|
-
set_layout = @layout || @dispatcher_layout
|
|
243
|
-
if set_layout
|
|
244
|
-
set_layout = [set_layout] unless set_layout.is_a?(Array)
|
|
245
|
-
set_layout.map{ |l| self.class.load_layout(l) }
|
|
246
|
-
obj.dispatcher_layout = set_layout
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
return obj
|
|
250
|
-
end
|
|
251
248
|
|
|
252
249
|
def try_rescue(exc)
|
|
253
|
-
|
|
250
|
+
if exc.respond_to?(:uuid=)
|
|
251
|
+
return super if exc.uuid # Error page already outputted
|
|
252
|
+
exc.uuid = UUIDTools::UUID.random_create.to_s
|
|
253
|
+
end
|
|
254
254
|
format = self.class.output_format(:error) || :html
|
|
255
255
|
unless exc.is_a?(Spider::Controller::Maintenance) || exc.is_a?(Spider::Controller::NotFound)
|
|
256
256
|
return super unless @executed_format == :html
|
|
@@ -555,6 +555,7 @@ module Spider; module ControllerMixins
|
|
|
555
555
|
path = Spider::Layout.named_layouts[path]
|
|
556
556
|
end
|
|
557
557
|
resource = Spider::Template.find_resource(path+'.layout', layout_path, self)
|
|
558
|
+
raise "Layout #{path} not found" unless resource && resource.path
|
|
558
559
|
layout = Spider::Layout.new(resource.path)
|
|
559
560
|
layout.definer_class = resource.definer
|
|
560
561
|
layout.asset_set = params[:assets] if params[:assets]
|
|
@@ -12,6 +12,7 @@ module Spider
|
|
|
12
12
|
|
|
13
13
|
module GetText
|
|
14
14
|
|
|
15
|
+
# Executes a block of code in the given text_domain
|
|
15
16
|
def self.in_domain(domain, &block)
|
|
16
17
|
prev_text_domain = FastGettext.text_domain
|
|
17
18
|
FastGettext.text_domain = domain if FastGettext.translation_repositories.key?(domain)
|
|
@@ -19,6 +20,19 @@ module Spider
|
|
|
19
20
|
FastGettext.text_domain = prev_text_domain
|
|
20
21
|
v
|
|
21
22
|
end
|
|
23
|
+
|
|
24
|
+
# Sets the current text_domain; return the previous domain
|
|
25
|
+
def self.set_domain(domain)
|
|
26
|
+
prev_text_domain = FastGettext.text_domain
|
|
27
|
+
FastGettext.text_domain = domain if FastGettext.translation_repositories.key?(domain)
|
|
28
|
+
prev_text_domain
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Sets the current text_domain; assumes the domain was already set before, so skips any
|
|
32
|
+
# check for domain validity
|
|
33
|
+
def self.restore_domain(domain)
|
|
34
|
+
FastGettext.text_domain = domain
|
|
35
|
+
end
|
|
22
36
|
|
|
23
37
|
end
|
|
24
38
|
|
|
@@ -21,13 +21,13 @@ module Spider; module I18n
|
|
|
21
21
|
str =~ Spider::TemplateBlocks::GettextRegexp
|
|
22
22
|
found = false
|
|
23
23
|
ary.each do |msg|
|
|
24
|
-
if (msg[0] == $
|
|
24
|
+
if (msg[0] == $2)
|
|
25
25
|
msg << "#{file}:#{cnt}"
|
|
26
26
|
found = true
|
|
27
27
|
break
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
-
ary << [$
|
|
30
|
+
ary << [$2, "#{file}:#{cnt}"] unless found
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
f.close
|
|
@@ -1174,8 +1174,8 @@ module Spider; module Model
|
|
|
1174
1174
|
qs.autoload = true
|
|
1175
1175
|
qs.where(&proc)
|
|
1176
1176
|
else
|
|
1177
|
-
condition = Condition.and(params[0])
|
|
1178
|
-
request = Request.new(params[1])
|
|
1177
|
+
condition = params[0].is_a?(Condition) ? params[0] : Condition.and(params[0])
|
|
1178
|
+
request = params[1].is_a?(Request) ? params[1] : Request.new(params[1])
|
|
1179
1179
|
query = Query.new(condition, request)
|
|
1180
1180
|
qs = QuerySet.new(self, query)
|
|
1181
1181
|
end
|
|
@@ -1852,6 +1852,7 @@ module Spider; module Model
|
|
|
1852
1852
|
@_modified_elements[key] = true
|
|
1853
1853
|
el = self.class.elements[key.to_sym]
|
|
1854
1854
|
next unless el
|
|
1855
|
+
next if el.attributes[:unmapped]
|
|
1855
1856
|
if el.integrated? && sub = self.get(el.integrated_from)
|
|
1856
1857
|
sub.set_modified(el.integrated_from_element)
|
|
1857
1858
|
end
|
|
@@ -1872,7 +1873,7 @@ module Spider; module Model
|
|
|
1872
1873
|
val.modified = false if val.is_a?(QuerySet)
|
|
1873
1874
|
end
|
|
1874
1875
|
self.class.elements_array.select{ |el| el.attributes[:integrated_model] && self.element_has_value?(el) }.each do |el|
|
|
1875
|
-
self.get(el).reset_modified_elements(elements)
|
|
1876
|
+
self.get(el).reset_modified_elements(*elements)
|
|
1876
1877
|
end
|
|
1877
1878
|
|
|
1878
1879
|
nil
|
|
@@ -90,43 +90,46 @@ module Spider; module Model; module Mappers
|
|
|
90
90
|
@model.each_element do |element|
|
|
91
91
|
next if !mapped?(element) || element.integrated?
|
|
92
92
|
next if save_mode == :update && !obj.element_modified?(element)
|
|
93
|
-
if
|
|
93
|
+
if save_mode == :insert
|
|
94
94
|
if element.attributes[:autoincrement] && !schema.attributes(element.name)[:autoincrement]
|
|
95
95
|
obj.set(element.name, @storage.sequence_next(schema.sequence(element.name)))
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
|
-
if
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
element_val = nil if element.model? && element_val.is_a?(BaseModel) && !element_val.primary_keys_set?
|
|
105
|
-
if (element.model?)
|
|
106
|
-
element.model.primary_keys.each do |key|
|
|
107
|
-
# FIXME! only works with one primary key
|
|
108
|
-
if (key.model?)
|
|
109
|
-
key_type = key.model.primary_keys[0].type
|
|
110
|
-
key_value = element_val ? element_val.get(key.name).get(key.model.primary_keys[0]) : nil
|
|
111
|
-
else
|
|
112
|
-
key_type = key.model? ? key.model.primary_keys[0].type : key.type
|
|
113
|
-
key_value = element_val ? element_val.get(key.name) : nil
|
|
114
|
-
end
|
|
115
|
-
store_key = schema.foreign_key_field(element.name, key.name)
|
|
116
|
-
next if store_key.is_a?(FieldExpression)
|
|
117
|
-
values[store_key] = map_save_value(key_type, key_value, save_mode)
|
|
118
|
-
end
|
|
119
|
-
else
|
|
120
|
-
store_key = schema.field(element.name)
|
|
121
|
-
values[store_key] = map_save_value(element.type, element_val, save_mode)
|
|
122
|
-
end
|
|
123
|
-
end
|
|
98
|
+
next if element.multiple?
|
|
99
|
+
next if save_mode == :update && element.primary_key?
|
|
100
|
+
next if element.model? && !schema.has_foreign_fields?(element.name)
|
|
101
|
+
|
|
102
|
+
element_val = obj.get(element)
|
|
103
|
+
prepare_save_value(element, element_val, save_mode, values)
|
|
124
104
|
end
|
|
125
105
|
end
|
|
126
106
|
return {
|
|
127
107
|
:values => values
|
|
128
108
|
}
|
|
129
109
|
end
|
|
110
|
+
|
|
111
|
+
def prepare_save_value(element, element_val, save_mode, values={})
|
|
112
|
+
element_val = nil if element.model? && element_val.is_a?(BaseModel) && !element_val.primary_keys_set?
|
|
113
|
+
if element.model?
|
|
114
|
+
element.model.primary_keys.each do |key|
|
|
115
|
+
# FIXME! only works with one primary key
|
|
116
|
+
if (key.model?)
|
|
117
|
+
key_type = key.model.primary_keys[0].type
|
|
118
|
+
key_value = element_val ? element_val.get(key.name).get(key.model.primary_keys[0]) : nil
|
|
119
|
+
else
|
|
120
|
+
key_type = key.model? ? key.model.primary_keys[0].type : key.type
|
|
121
|
+
key_value = element_val ? element_val.get(key.name) : nil
|
|
122
|
+
end
|
|
123
|
+
store_key = schema.foreign_key_field(element.name, key.name)
|
|
124
|
+
next if store_key.is_a?(FieldExpression)
|
|
125
|
+
values[store_key] = map_save_value(key_type, key_value, save_mode)
|
|
126
|
+
end
|
|
127
|
+
else
|
|
128
|
+
store_key = schema.field(element.name)
|
|
129
|
+
values[store_key] = map_save_value(element.type, element_val, save_mode)
|
|
130
|
+
end
|
|
131
|
+
values
|
|
132
|
+
end
|
|
130
133
|
|
|
131
134
|
# Insert preprocessing
|
|
132
135
|
def prepare_insert(obj) #:nodoc:
|
|
@@ -152,27 +155,29 @@ module Spider; module Model; module Mappers
|
|
|
152
155
|
end
|
|
153
156
|
|
|
154
157
|
# Updates according to a condition, storing the values, which must passed as a Hash.
|
|
158
|
+
# Condition may be nil.
|
|
155
159
|
def bulk_update(values, condition)
|
|
156
160
|
db_values = {}
|
|
157
161
|
joins = []
|
|
158
162
|
integrated = {}
|
|
159
|
-
condition = preprocess_condition(condition)
|
|
163
|
+
condition = preprocess_condition(condition) if condition
|
|
160
164
|
values.each do |key, val|
|
|
161
165
|
element = @model.elements[key]
|
|
162
|
-
if
|
|
166
|
+
if element.integrated?
|
|
163
167
|
integrated[element.integrated_from] ||= {}
|
|
164
168
|
integrated[element.integrated_from][key] = val
|
|
165
169
|
next
|
|
166
170
|
end
|
|
167
171
|
next if !mapped?(element)
|
|
168
|
-
next if element.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (val.is_a?(Spider::QueryFuncs::Expression))
|
|
172
|
+
next if element.multiple?
|
|
173
|
+
next if element.model? && !schema.has_foreign_fields?(element.name)
|
|
174
|
+
if val.is_a?(Spider::QueryFuncs::Expression)
|
|
172
175
|
joins += prepare_expression(val)
|
|
176
|
+
store_key = schema.field(element.name)
|
|
177
|
+
next unless store_key
|
|
173
178
|
db_values[store_key] = val
|
|
174
179
|
else
|
|
175
|
-
|
|
180
|
+
prepare_save_value(element, val, :update, db_values)
|
|
176
181
|
end
|
|
177
182
|
end
|
|
178
183
|
integrated.each do |i_el, i_values|
|
|
@@ -181,11 +186,13 @@ module Spider; module Model; module Mappers
|
|
|
181
186
|
end
|
|
182
187
|
return if db_values.empty?
|
|
183
188
|
save = {:table => schema.table, :values => db_values}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
if condition
|
|
190
|
+
condition, c_joins = prepare_condition(condition)
|
|
191
|
+
joins += c_joins
|
|
192
|
+
save[:condition] = condition
|
|
193
|
+
end
|
|
187
194
|
save[:joins] = prepare_joins(joins)
|
|
188
|
-
sql, bind_vars = @storage.sql_update(save)
|
|
195
|
+
sql, bind_vars = @storage.sql_update(save, true)
|
|
189
196
|
return @storage.execute(sql, *bind_vars)
|
|
190
197
|
end
|
|
191
198
|
|
|
@@ -252,7 +259,11 @@ module Spider; module Model; module Mappers
|
|
|
252
259
|
end
|
|
253
260
|
model = obj_or_model.is_a?(Class) ? obj_or_model : obj_or_model.model
|
|
254
261
|
data = {}
|
|
262
|
+
extra_data = {}
|
|
255
263
|
request.keys.each do |element_name|
|
|
264
|
+
if element_name.is_a?(QueryFuncs::SelectFunction)
|
|
265
|
+
extra_data[element_name.as] = result[element_name.as.to_s]
|
|
266
|
+
end
|
|
256
267
|
element = @model.elements[element_name]
|
|
257
268
|
result_value = nil
|
|
258
269
|
next if !element || element.integrated? || !have_references?(element)
|
|
@@ -282,6 +293,9 @@ module Spider; module Model; module Mappers
|
|
|
282
293
|
return nil
|
|
283
294
|
end
|
|
284
295
|
data.keys.each{ |el| obj.element_loaded(el) }
|
|
296
|
+
extra_data.each do |k, v|
|
|
297
|
+
obj[k] = v
|
|
298
|
+
end
|
|
285
299
|
if (request.polymorphs)
|
|
286
300
|
request.polymorphs.each do |model, polym_request|
|
|
287
301
|
polym_result = {}
|
|
@@ -315,7 +329,9 @@ module Spider; module Model; module Mappers
|
|
|
315
329
|
# Generates a select hash description based on the query.
|
|
316
330
|
def prepare_select(query) #:nodoc:
|
|
317
331
|
condition, joins = prepare_condition(query.condition)
|
|
318
|
-
elements = query.request.keys.select{ |k| mapped?(k) }
|
|
332
|
+
elements = query.request.keys.select{ |k| !k.is_a?(QueryFuncs::SelectFunction) && mapped?(k) }
|
|
333
|
+
select_functions = query.request.keys.select{ |k| k.is_a?(QueryFuncs::SelectFunction) }
|
|
334
|
+
|
|
319
335
|
keys = []
|
|
320
336
|
primary_keys = []
|
|
321
337
|
types = {}
|
|
@@ -331,6 +347,8 @@ module Spider; module Model; module Mappers
|
|
|
331
347
|
oj[:as] ||= "ORD#{cnt+=1}" if joins.select{ |j| j[:to] == oj[:to] }.length > 0
|
|
332
348
|
end
|
|
333
349
|
joins += order_joins if order_joins
|
|
350
|
+
group_by, group_by_joins = prepare_group_by(query)
|
|
351
|
+
joins += group_by_joins if group_by_joins
|
|
334
352
|
seen_fields = {}
|
|
335
353
|
model_pks = []
|
|
336
354
|
@model.primary_keys.each do |pk|
|
|
@@ -363,15 +381,11 @@ module Spider; module Model; module Mappers
|
|
|
363
381
|
end
|
|
364
382
|
end
|
|
365
383
|
sub_request = query.request[element.name]
|
|
366
|
-
# if (can_join?(element) && sub_request.is_a?(Request) &&
|
|
367
|
-
# sub_request.select{|k, v| !element.model.elements[k].primary_key?}.length > 0)
|
|
368
|
-
# sub_request = element.mapper.prepare_query_request(sub_request).reject{ |name, req| element.reverse == name }
|
|
369
|
-
# sub_select = element.mapper.prepare_select(Query.new(nil, sub_request))
|
|
370
|
-
# keys += sub_select[:keys]
|
|
371
|
-
# joins << get_join(element)
|
|
372
|
-
# end
|
|
373
384
|
end
|
|
374
385
|
end
|
|
386
|
+
select_functions.each do |f|
|
|
387
|
+
keys << prepare_queryfunc(f)
|
|
388
|
+
end
|
|
375
389
|
if (query.request.polymorphs? || !query.condition.polymorphs.empty?)
|
|
376
390
|
only_conditions = {:conj => 'or', :values => []} if (query.request.only_polymorphs?)
|
|
377
391
|
polymorphs = (query.request.polymorphs.keys + query.condition.polymorphs).uniq
|
|
@@ -427,6 +441,7 @@ module Spider; module Model; module Mappers
|
|
|
427
441
|
:condition => condition,
|
|
428
442
|
:joins => joins,
|
|
429
443
|
:order => order,
|
|
444
|
+
:group_by => group_by,
|
|
430
445
|
:offset => query.offset,
|
|
431
446
|
:limit => query.limit
|
|
432
447
|
}
|
|
@@ -580,9 +595,10 @@ module Spider; module Model; module Mappers
|
|
|
580
595
|
cond[:values] << [field, comp, v]
|
|
581
596
|
joins += field.joins
|
|
582
597
|
if is_having
|
|
583
|
-
|
|
584
|
-
owner_func.
|
|
585
|
-
|
|
598
|
+
k.inner_elements.each do |el_name, owner_func|
|
|
599
|
+
next if owner_func.is_a?(QueryFuncs::AggregateFunction)
|
|
600
|
+
cond[:group_by_fields] <<= owner_func.mapper_fields[el_name.to_s]
|
|
601
|
+
end
|
|
586
602
|
end
|
|
587
603
|
next
|
|
588
604
|
end
|
|
@@ -600,6 +616,7 @@ module Spider; module Model; module Mappers
|
|
|
600
616
|
element_cond = {:conj => 'AND', :values => [], :is_having => is_having}
|
|
601
617
|
v.each_with_comparison do |el_k, el_v, el_comp|
|
|
602
618
|
field = model_schema.foreign_key_field(element.name, el_k)
|
|
619
|
+
next if field.is_a?(FixedExpression)
|
|
603
620
|
el_comp ||= '='
|
|
604
621
|
op = el_comp
|
|
605
622
|
field_cond = [field, op, map_condition_value(element.model.elements[el_k.to_sym].type, el_v)]
|
|
@@ -609,50 +626,56 @@ module Spider; module Model; module Mappers
|
|
|
609
626
|
cond[:values] << element_cond
|
|
610
627
|
else
|
|
611
628
|
if element.storage == model.mapper.storage
|
|
612
|
-
join_type = join_info[element.name.to_s] ? :inner : :left
|
|
613
|
-
sub_join = model.mapper.get_join(element, join_type)
|
|
614
|
-
# FIXME! cleanup, and apply the check to joins acquired in other places, too (maybe pass the current joins to get_join)
|
|
615
|
-
existent = joins.select{ |j| j[:to] == sub_join[:to] }
|
|
616
|
-
j_cnt = nil
|
|
617
|
-
had_join = false
|
|
618
|
-
existent.each do |j|
|
|
619
|
-
if sub_join[:to] == j[:to] && sub_join[:keys] == j[:keys] && sub_join[:conditions] == j[:conditions]
|
|
620
|
-
# if any condition allows a left join, then a left join should be used here as well
|
|
621
|
-
j[:type] = :left if sub_join[:type] == :left
|
|
622
|
-
sub_join = j
|
|
623
|
-
had_join = true
|
|
624
|
-
break
|
|
625
|
-
else
|
|
626
|
-
j_cnt ||= 0; j_cnt += 1
|
|
627
|
-
end
|
|
628
|
-
end
|
|
629
|
-
sub_join[:as] = "#{sub_join[:to]}#{j_cnt}" if j_cnt
|
|
630
|
-
joins << sub_join unless had_join
|
|
631
629
|
|
|
630
|
+
needs_join = true
|
|
632
631
|
if v.nil? && comp == '='
|
|
633
632
|
el_model_schema = model_schema
|
|
634
633
|
element_cond = {:conj => 'AND', :values => [], :is_having => is_having}
|
|
635
634
|
if model.mapper.have_references?(element.name)
|
|
636
635
|
el_name = element.name
|
|
637
636
|
el_model = element.model
|
|
637
|
+
needs_join = false
|
|
638
638
|
elsif element.junction?
|
|
639
639
|
el_model = element.type
|
|
640
640
|
el_model_schema = element.model.mapper.schema
|
|
641
641
|
el_name = element.attributes[:junction_their_element]
|
|
642
642
|
else
|
|
643
|
-
el_model =
|
|
644
|
-
el_model_schema =
|
|
643
|
+
el_model = @model
|
|
644
|
+
el_model_schema = element.type.mapper.schema
|
|
645
645
|
el_name = element.reverse
|
|
646
646
|
end
|
|
647
647
|
el_model.primary_keys.each do |k|
|
|
648
648
|
field = el_model_schema.foreign_key_field(el_name, k.name)
|
|
649
|
-
|
|
649
|
+
next if field.is_a?(FixedExpression)
|
|
650
|
+
field_cond = [field, comp, map_condition_value(el_model.elements[k.name].type, nil)]
|
|
650
651
|
element_cond[:values] << field_cond
|
|
651
652
|
element_cond[:is_having] = is_having
|
|
652
653
|
cond[:group_by_fields] << field if is_having
|
|
653
654
|
end
|
|
654
655
|
cond[:values] << element_cond
|
|
655
|
-
|
|
656
|
+
end
|
|
657
|
+
if needs_join
|
|
658
|
+
join_type = join_info[element.name.to_s] ? :inner : :left
|
|
659
|
+
sub_join = model.mapper.get_join(element, join_type)
|
|
660
|
+
# FIXME! cleanup, and apply the check to joins acquired in other places, too (maybe pass the current joins to get_join)
|
|
661
|
+
existent = joins.select{ |j| j[:to] == sub_join[:to] }
|
|
662
|
+
j_cnt = nil
|
|
663
|
+
had_join = false
|
|
664
|
+
existent.each do |j|
|
|
665
|
+
if sub_join[:to] == j[:to] && sub_join[:keys] == j[:keys] && sub_join[:conditions] == j[:conditions]
|
|
666
|
+
# if any condition allows a left join, then a left join should be used here as well
|
|
667
|
+
j[:type] = :left if sub_join[:type] == :left
|
|
668
|
+
sub_join = j
|
|
669
|
+
had_join = true
|
|
670
|
+
break
|
|
671
|
+
else
|
|
672
|
+
j_cnt ||= 0; j_cnt += 1
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
sub_join[:as] = "#{sub_join[:to]}#{j_cnt}" if j_cnt
|
|
676
|
+
joins << sub_join unless had_join
|
|
677
|
+
end
|
|
678
|
+
if v
|
|
656
679
|
sub_condition, sub_joins = element.mapper.prepare_condition(v, :table => sub_join[:as],
|
|
657
680
|
:joins => joins, :join_info => el_join_info, :is_having => is_having || nil)
|
|
658
681
|
sub_condition[:table] = sub_join[:as] if sub_join[:as]
|
|
@@ -667,7 +690,7 @@ module Spider; module Model; module Mappers
|
|
|
667
690
|
end
|
|
668
691
|
elsif(model_schema.field(element.name))
|
|
669
692
|
field = model_schema.field(element.name)
|
|
670
|
-
field = FieldInAliasedTable(field, options[:table]) if options[:table]
|
|
693
|
+
field = FieldInAliasedTable.new(field, options[:table]) if options[:table]
|
|
671
694
|
op = comp ? comp : '='
|
|
672
695
|
if (v.is_a?(Spider::QueryFuncs::Expression))
|
|
673
696
|
v_joins = prepare_expression(v)
|
|
@@ -815,6 +838,7 @@ module Spider; module Model; module Mappers
|
|
|
815
838
|
owner_func.mapper_fields[el_name.to_s] = el_model.mapper.schema.field(el.name)
|
|
816
839
|
end
|
|
817
840
|
f = FieldFunction.new(storage.function(func), schema.table, joins)
|
|
841
|
+
f.as = func.as if func.is_a?(QueryFuncs::SelectFunction)
|
|
818
842
|
f.aggregate = true if func.has_aggregates?
|
|
819
843
|
return f
|
|
820
844
|
end
|
|
@@ -850,7 +874,9 @@ module Spider; module Model; module Mappers
|
|
|
850
874
|
if el.model?
|
|
851
875
|
if el_model.mapper.have_references?(el) || el.model.storage != storage
|
|
852
876
|
el.model.primary_keys.each do |pk|
|
|
853
|
-
|
|
877
|
+
field = el_model.mapper.schema.foreign_key_field(el.name, pk.name)
|
|
878
|
+
next if field.is_a?(FixedExpression)
|
|
879
|
+
fields << [field, direction]
|
|
854
880
|
end
|
|
855
881
|
else
|
|
856
882
|
el.model.primary_keys.each do |pk|
|
|
@@ -868,6 +894,34 @@ module Spider; module Model; module Mappers
|
|
|
868
894
|
return [fields, joins]
|
|
869
895
|
end
|
|
870
896
|
|
|
897
|
+
def prepare_group_by(query)
|
|
898
|
+
return nil if !query.group_by_elements
|
|
899
|
+
joins = []
|
|
900
|
+
fields = []
|
|
901
|
+
query.group_by_elements.each do |gb|
|
|
902
|
+
el_model = @model
|
|
903
|
+
el_joins, el_model, el = get_deep_join(gb)
|
|
904
|
+
# FIXME: this is almost identical to prepare_order
|
|
905
|
+
if el.model?
|
|
906
|
+
if el_model.mapper.have_references?(el) || el.model.storage != storage
|
|
907
|
+
el.model.primary_keys.each do |pk|
|
|
908
|
+
fields << el_model.mapper.schema.foreign_key_field(el.name, pk.name)
|
|
909
|
+
end
|
|
910
|
+
else
|
|
911
|
+
el.model.primary_keys.each do |pk|
|
|
912
|
+
fields << el.model.mapper.schema.field(pk.name)
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
else
|
|
916
|
+
raise "Order on unmapped element #{el_model.name}.#{el.name}" unless el_model.mapper.mapped?(el)
|
|
917
|
+
field = el_model.mapper.schema.field(el.name)
|
|
918
|
+
fields << field
|
|
919
|
+
end
|
|
920
|
+
joins += el_joins
|
|
921
|
+
end
|
|
922
|
+
return [fields, joins]
|
|
923
|
+
end
|
|
924
|
+
|
|
871
925
|
# Returns a type accepted by the storage for type.
|
|
872
926
|
def map_type(type)
|
|
873
927
|
st = type
|
|
@@ -1060,16 +1114,20 @@ module Spider; module Model; module Mappers
|
|
|
1060
1114
|
end
|
|
1061
1115
|
end
|
|
1062
1116
|
|
|
1063
|
-
|
|
1064
|
-
def generate_schema(schema=nil)
|
|
1065
|
-
had_schema = schema ? true : false
|
|
1066
|
-
schema ||= DbSchema.new
|
|
1117
|
+
def schema_table_name
|
|
1067
1118
|
n = @model.name.sub('::Models', '')
|
|
1068
1119
|
app = @model.app
|
|
1069
1120
|
app_name = app.name if app
|
|
1070
1121
|
short_prefix = app.short_prefix if app
|
|
1071
1122
|
n.sub!(app_name, short_prefix) if short_prefix
|
|
1072
|
-
|
|
1123
|
+
@storage.table_name(n)
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1126
|
+
# Autogenerates schema. Returns a DbSchema.
|
|
1127
|
+
def generate_schema(schema=nil)
|
|
1128
|
+
had_schema = schema ? true : false
|
|
1129
|
+
schema ||= DbSchema.new
|
|
1130
|
+
schema.table ||= @model.attributes[:db_table] || schema_table_name
|
|
1073
1131
|
integrated_pks = []
|
|
1074
1132
|
@model.each_element do |element|
|
|
1075
1133
|
if element.integrated?
|
|
@@ -604,7 +604,8 @@ module Spider; module Model
|
|
|
604
604
|
merged[merged_obj.object_id] = true
|
|
605
605
|
end
|
|
606
606
|
query.request.keys.each do |k, v|
|
|
607
|
-
|
|
607
|
+
# k may be a SelectFunction
|
|
608
|
+
set.element_loaded(k) if !k.is_a?(QueryFuncs::SelectFunction) && have_references?(k)
|
|
608
609
|
end
|
|
609
610
|
set.each_current do |obj|
|
|
610
611
|
next if merged[obj.object_id]
|
|
@@ -1054,7 +1055,10 @@ module Spider; module Model
|
|
|
1054
1055
|
obj.class.elements_array.each do |el|
|
|
1055
1056
|
next unless obj.element_has_value?(el)
|
|
1056
1057
|
next unless el.model?
|
|
1057
|
-
|
|
1058
|
+
next unless obj.element_modified?(el)
|
|
1059
|
+
val = obj.get(el)
|
|
1060
|
+
next unless val.modified?
|
|
1061
|
+
children << val
|
|
1058
1062
|
end
|
|
1059
1063
|
children
|
|
1060
1064
|
end
|
|
@@ -12,7 +12,7 @@ module Spider; module Migrations
|
|
|
12
12
|
field = @options[:field_name]
|
|
13
13
|
if !field
|
|
14
14
|
schema_field = @model.mapper.schema.field(@element)
|
|
15
|
-
field = schema_field.name
|
|
15
|
+
field = schema_field.name if schema_field
|
|
16
16
|
end
|
|
17
17
|
field ||= @model.mapper.storage.column_name(@element)
|
|
18
18
|
desc = @model.mapper.storage.describe_table(@model.mapper.schema.table)
|