spiderfw 0.5.7 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +17 -6
- data/apps/cas_server/controllers/mixins/cas_login_mixin.rb +18 -5
- data/apps/cas_server/lib/cas.rb +1 -1
- data/apps/cms/models/content.rb +16 -0
- data/apps/cms/models/news_item.rb +7 -0
- data/apps/cms/models/translation.rb +14 -0
- data/apps/cms/views/admin/admin.shtml +16 -0
- data/apps/cms/views/admin/content.shtml +4 -0
- data/apps/core/acl/_init.rb +10 -0
- data/apps/core/acl/controllers/acl_controller.rb +14 -0
- data/apps/core/acl/models/permission.rb +11 -0
- data/apps/core/acl/views/acl.layout.shtml +8 -0
- data/apps/core/acl/views/index.shtml +3 -0
- data/apps/core/auth/controllers/mixins/auth_helper.rb +3 -3
- data/apps/core/auth/lib/authenticable.rb +4 -0
- data/apps/core/auth/models/super_user.rb +1 -0
- data/apps/core/auth/po/it/spider_auth.po +18 -10
- data/apps/core/auth/po/spider_auth.pot +13 -1
- data/apps/core/components/_init.rb +2 -1
- data/apps/core/components/po/it/spider_components.po +3 -3
- data/apps/core/components/po/spider_components.pot +3 -3
- data/apps/core/components/public/css/month_calendar.css +24 -0
- data/apps/core/components/public/js/jquery/jquery-1.4.2-min.js +154 -0
- data/apps/core/components/public/js/jquery/jquery-1.4.2.js +6240 -0
- data/apps/core/components/public/js/jquery/plugins/jquery.form.js +1 -1
- data/apps/core/components/public/js/spider.js +26 -20
- data/apps/core/components/widgets/admin/admin.rb +1 -1
- data/apps/core/components/widgets/crud/crud.rb +1 -1
- data/apps/core/components/widgets/list/list.rb +2 -2
- data/apps/core/components/widgets/month_calendar/month_calendar.rb +67 -0
- data/apps/core/components/widgets/month_calendar/month_calendar.shtml +21 -0
- data/apps/core/components/widgets/table/table.rb +4 -2
- data/apps/core/components/widgets/table/table.shtml +37 -31
- data/apps/core/forms/_init.rb +2 -1
- data/apps/core/forms/po/it/spider_forms.po +14 -2
- data/apps/core/forms/po/spider_forms.pot +13 -1
- data/apps/core/forms/public/css/file_input.css +15 -0
- data/apps/core/forms/public/{form.css → css/form.css} +8 -0
- data/apps/core/forms/public/file_input.js +37 -0
- data/apps/core/forms/tags/element_label.erb +4 -1
- data/apps/core/forms/tags/element_row.erb +7 -2
- data/apps/core/forms/tags/row.erb +10 -1
- data/apps/core/forms/widgets/form/form.rb +43 -10
- data/apps/core/forms/widgets/form/form.shtml +12 -5
- data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -0
- data/apps/core/forms/widgets/inputs/file_input/file_input.rb +43 -0
- data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +12 -0
- data/apps/core/forms/widgets/inputs/input/input.rb +23 -1
- data/apps/core/forms/widgets/inputs/password/password.rb +1 -0
- data/apps/core/forms/widgets/inputs/text/text.shtml +1 -1
- data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +2 -2
- data/apps/git_model_versioning/models/mixins/git_versioned.rb +91 -0
- data/apps/hippo/models/mixins/hippo_struct.rb +42 -26
- data/apps/master/controllers/git.rb +32 -0
- data/apps/messenger/_init.rb +1 -1
- data/apps/messenger/config/options.rb +2 -0
- data/apps/messenger/config/worker/queue.rb +3 -0
- data/apps/messenger/controllers/mixins/{messenger_controller_mixin.rb → messenger_helper.rb} +8 -6
- data/apps/messenger/messenger.rb +10 -3
- data/apps/messenger/models/message.rb +2 -2
- data/apps/messenger/po/it/spider_messenger.po +1 -1
- data/apps/messenger/po/spider_messenger.pot +1 -1
- data/apps/saml/_init.rb +13 -0
- data/apps/saml/controllers/saml2idp.rb +18 -0
- data/apps/saml/lib/bindings/http_redirect_binding.rb +14 -0
- data/apps/saml/lib/messages/authn_request.rb +52 -0
- data/apps/saml/lib/saml.rb +10 -0
- data/apps/soap/controllers/soap_controller.rb +12 -2
- data/apps/soap/lib/soap.rb +16 -1
- data/apps/soap/soap.gemspec +10 -0
- data/apps/webdav/lib/locking.rb +2 -2
- data/apps/worker/_init.rb +2 -0
- data/apps/worker/config/options.rb +1 -0
- data/apps/worker/worker.rb +17 -4
- data/blueprints/app/__APP__.appspec +4 -0
- data/blueprints/app/_init.rb +5 -8
- data/blueprints/app/controllers/__APP___controller.rb +2 -1
- data/blueprints/app/views/__APP__.layout.shtml +4 -1
- data/blueprints/install/config/config.yml +2 -4
- data/blueprints/model.rb +15 -0
- data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
- data/data/locale/it/LC_MESSAGES/spider_auth.mo +0 -0
- data/data/locale/it/LC_MESSAGES/spider_components.mo +0 -0
- data/data/locale/it/LC_MESSAGES/spider_forms.mo +0 -0
- data/data/locale/it/LC_MESSAGES/spider_messenger.mo +0 -0
- data/lib/spiderfw/app.rb +93 -31
- data/lib/spiderfw/autoload.rb +1 -0
- data/lib/spiderfw/cmd/cmd.rb +8 -1
- data/lib/spiderfw/cmd/commands/config.rb +54 -0
- data/lib/spiderfw/config/configuration.rb +30 -0
- data/lib/spiderfw/config/options/spider.rb +18 -6
- data/lib/spiderfw/controller/controller.rb +12 -11
- data/lib/spiderfw/controller/dispatcher.rb +5 -4
- data/lib/spiderfw/controller/http_controller.rb +16 -2
- data/lib/spiderfw/controller/mixins/http_mixin.rb +3 -2
- data/lib/spiderfw/controller/mixins/static_content.rb +8 -2
- data/lib/spiderfw/controller/mixins/visual.rb +72 -52
- data/lib/spiderfw/controller/request.rb +7 -3
- data/lib/spiderfw/controller/scene.rb +6 -0
- data/lib/spiderfw/controller/session.rb +12 -8
- data/lib/spiderfw/env.rb +1 -1
- data/lib/spiderfw/http/adapters/mongrel.rb +1 -1
- data/lib/spiderfw/http/http.rb +48 -19
- data/lib/spiderfw/i18n/cldr.rb +53 -3
- data/lib/spiderfw/i18n/i18n.rb +52 -2
- data/lib/spiderfw/i18n/provider.rb +24 -0
- data/lib/spiderfw/i18n/rails.rb +24 -0
- data/lib/spiderfw/model/active_record.rb +3 -3
- data/lib/spiderfw/model/base_model.rb +45 -14
- data/lib/spiderfw/model/condition.rb +11 -2
- data/lib/spiderfw/model/data_type.rb +15 -7
- data/lib/spiderfw/model/datatypes/decimal.rb +15 -3
- data/lib/spiderfw/model/datatypes/file_path.rb +50 -0
- data/lib/spiderfw/model/datatypes/serialized_object.rb +0 -4
- data/lib/spiderfw/model/datatypes/uuid.rb +3 -3
- data/lib/spiderfw/model/datatypes.rb +1 -0
- data/lib/spiderfw/model/extended_models/managed.rb +11 -2
- data/lib/spiderfw/model/mappers/db_mapper.rb +116 -52
- data/lib/spiderfw/model/mappers/mapper.rb +36 -14
- data/lib/spiderfw/model/mixins/state_machine.rb +45 -9
- data/lib/spiderfw/model/mixins/versioned.rb +1 -1
- data/lib/spiderfw/model/model.rb +2 -1
- data/lib/spiderfw/model/query_set.rb +21 -3
- data/lib/spiderfw/model/request.rb +7 -0
- data/lib/spiderfw/model/storage/db/adapters/mssql.rb +2 -1
- data/lib/spiderfw/model/storage/db/adapters/mysql.rb +4 -1
- data/lib/spiderfw/model/storage/db/adapters/oci8.rb +35 -18
- data/lib/spiderfw/model/storage/db/adapters/sqlite.rb +68 -34
- data/lib/spiderfw/model/storage/db/connectors/odbc.rb +1 -1
- data/lib/spiderfw/model/storage/db/db_schema.rb +33 -4
- data/lib/spiderfw/model/storage/db/db_storage.rb +27 -8
- data/lib/spiderfw/requires.rb +2 -0
- data/lib/spiderfw/tag/tag.rb +1 -1
- data/lib/spiderfw/templates/blocks/attr_if.rb +7 -1
- data/lib/spiderfw/templates/blocks/each.rb +8 -3
- data/lib/spiderfw/templates/blocks/html.rb +12 -22
- data/lib/spiderfw/templates/blocks/render.rb +3 -3
- data/lib/spiderfw/templates/blocks/run.rb +47 -11
- data/lib/spiderfw/templates/blocks/tag_if.rb +2 -2
- data/lib/spiderfw/templates/blocks/text.rb +2 -1
- data/lib/spiderfw/templates/blocks/widget.rb +5 -3
- data/lib/spiderfw/templates/blocks/yield.rb +1 -1
- data/lib/spiderfw/templates/template.rb +27 -24
- data/lib/spiderfw/templates/template_blocks.rb +37 -14
- data/lib/spiderfw/utils/monkey/exception.rb +1 -1
- data/lib/spiderfw/utils/monkey/nil_class.rb +7 -0
- data/lib/spiderfw/utils/monkey/numeric.rb +15 -0
- data/lib/spiderfw/version.rb +1 -1
- data/lib/spiderfw/widget/widget.rb +36 -33
- data/lib/spiderfw/widget/widget_attributes.rb +1 -1
- data/lib/spiderfw.rb +18 -5
- data/spider.gemspec +5 -5
- metadata +44 -18
- data/apps/core/components/public/js/jquery/plugins/jtree/jquery.jtree.1.0.js +0 -187
- data/apps/core/components/public/js/jquery/plugins/jtree/jquery.jtree.1.0.min.js +0 -1
- data/apps/core/components/public/js/jquery/plugins/jtree/jquery.jtree.spider.1.0.js +0 -193
- data/apps/core/forms/widgets/inputs/subform/subform.rb +0 -10
- data/apps/core/forms/widgets/inputs/subform/subform.shtml +0 -5
- data/apps/messenger/config/worker.rb +0 -3
- data/lib/spiderfw/controller/app_controller.rb +0 -14
- data/lib/spiderfw/utils/test_case.rb +0 -24
@@ -4,20 +4,22 @@ module Spider; module Model
|
|
4
4
|
|
5
5
|
def self.included(model)
|
6
6
|
model.extend(ClassMethods)
|
7
|
+
model.mapper_include(MapperMethods)
|
7
8
|
end
|
8
9
|
|
9
10
|
module ClassMethods
|
11
|
+
attr_reader :state_events
|
10
12
|
|
11
13
|
class StateEvent
|
14
|
+
attr_reader :transitions
|
12
15
|
|
13
16
|
def initialize
|
14
17
|
@transitions = []
|
15
18
|
@action = nil
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
21
|
+
def transition(params=nil)
|
19
22
|
@transitions << params if params
|
20
|
-
@transitions
|
21
23
|
end
|
22
24
|
|
23
25
|
def action(&proc)
|
@@ -25,6 +27,10 @@ module Spider; module Model
|
|
25
27
|
@action
|
26
28
|
end
|
27
29
|
|
30
|
+
def run(obj, old_state, new_state)
|
31
|
+
@action.call(obj, old_state, new_state)
|
32
|
+
end
|
33
|
+
|
28
34
|
end
|
29
35
|
|
30
36
|
def element_association?(name, ass)
|
@@ -37,45 +43,75 @@ module Spider; module Model
|
|
37
43
|
|
38
44
|
def state(name, type, attributes={}, &proc)
|
39
45
|
attributes[:association] = :state
|
46
|
+
raise "States must be models with one primary key" unless type.is_a?(Hash) || !type.is_a?(Spider::Model::BaseModel) || type.primary_keys.length == 1
|
40
47
|
element(name, type, attributes, &proc)
|
41
48
|
end
|
42
49
|
|
43
|
-
def state_event(
|
50
|
+
def state_event(element_name)
|
44
51
|
ev = StateEvent.new
|
45
52
|
yield ev
|
46
|
-
@state_events ||=
|
47
|
-
@state_events
|
53
|
+
@state_events ||= {}
|
54
|
+
@state_events[element_name] ||= []
|
55
|
+
@state_events[element_name] << ev
|
48
56
|
end
|
49
57
|
|
50
58
|
|
51
59
|
end
|
52
60
|
|
61
|
+
def _pending_state_events
|
62
|
+
@_pending_state_events ||= []
|
63
|
+
end
|
64
|
+
|
53
65
|
module MapperMethods
|
54
66
|
|
55
67
|
def before_save(obj, mode)
|
56
68
|
obj.model.elements_array.select{ |el| el.association == :state }.each do |el|
|
57
|
-
if (obj.model.state_events[el.name] && obj.
|
69
|
+
if (obj.model.state_events[el.name] && obj.element_modified?(el))
|
58
70
|
old = obj.get_new
|
59
71
|
old_state = old.get(el.name)
|
60
72
|
new_state = obj.get(el.name)
|
73
|
+
old_state = old_state.primary_keys.first if old_state && el.model?
|
74
|
+
new_state = new_state.primary_keys.first if new_state && el.model?
|
61
75
|
obj.model.state_events[el.name].each do |event|
|
62
76
|
call_ev = false
|
63
77
|
event.transitions.each do |tr|
|
64
|
-
|
78
|
+
from_ok = false
|
79
|
+
to_ok = false
|
80
|
+
if tr[:from]
|
81
|
+
tr[:from] = [tr[:from]] unless tr[:from].is_a?(Array)
|
82
|
+
from_ok = true if tr[:from].include?(old_state)
|
83
|
+
else
|
84
|
+
from_ok = true
|
85
|
+
end
|
86
|
+
if tr[:to]
|
87
|
+
tr[:to] = [tr[:to]] unless tr[:to].is_a?(Array)
|
88
|
+
to_ok = true if tr[:to].include?(new_state)
|
89
|
+
else
|
90
|
+
to_ok = true
|
91
|
+
end
|
92
|
+
if from_ok && to_ok
|
65
93
|
call_ev = true
|
66
94
|
break
|
67
95
|
end
|
68
96
|
end
|
69
97
|
if (call_ev)
|
70
|
-
event
|
98
|
+
obj._pending_state_events << [event, old_state, new_state]
|
71
99
|
end
|
72
100
|
end
|
73
101
|
end
|
74
102
|
end
|
103
|
+
super
|
104
|
+
end
|
105
|
+
|
106
|
+
def after_save(obj, mode)
|
107
|
+
super
|
108
|
+
obj._pending_state_events.each do |event, old_state, new_state|
|
109
|
+
event.run(obj.get_new, old_state, new_state)
|
110
|
+
end
|
75
111
|
end
|
76
112
|
|
77
113
|
end
|
78
114
|
|
79
115
|
end
|
80
116
|
|
81
|
-
end; end
|
117
|
+
end; end
|
@@ -63,7 +63,7 @@ module Spider; module Model
|
|
63
63
|
junction.versioning(branch)
|
64
64
|
end
|
65
65
|
elh[:attributes][:through] = junction.version_model
|
66
|
-
elh[:attributes][:
|
66
|
+
elh[:attributes][:junction_our_element] = "#{elh[:attributes][:reverse]}_versioned".to_sym
|
67
67
|
elh[:attributes][:junction_their_element] = "#{elh[:attributes][:junction_their_element]}_versioned".to_sym
|
68
68
|
vname = "#{elh[:name]}_versioned".to_sym
|
69
69
|
vmod.send(elh[:method], vname, el.type.version_model, elh[:attributes])
|
data/lib/spiderfw/model/model.rb
CHANGED
@@ -34,7 +34,8 @@ module Spider
|
|
34
34
|
map_types = {
|
35
35
|
Spider::DataTypes::Text => String,
|
36
36
|
Spider::DataTypes::Bool => FalseClass,
|
37
|
-
Spider::DataTypes::Binary => String
|
37
|
+
Spider::DataTypes::Binary => String,
|
38
|
+
Spider::DataTypes::FilePath => String
|
38
39
|
}
|
39
40
|
return map_types[klass] if map_types[klass]
|
40
41
|
return klass
|
@@ -326,6 +326,12 @@ module Spider; module Model
|
|
326
326
|
end
|
327
327
|
end
|
328
328
|
|
329
|
+
# Remove all elements from self
|
330
|
+
def clear
|
331
|
+
@objects = []
|
332
|
+
@index_lookup.each_key{ |k| @index_lookup[k] = {} }
|
333
|
+
end
|
334
|
+
|
329
335
|
# Remove when merging
|
330
336
|
alias :map_array :map
|
331
337
|
|
@@ -336,13 +342,22 @@ module Spider; module Model
|
|
336
342
|
|
337
343
|
# Iterates on objects, loading when needed.
|
338
344
|
def each
|
345
|
+
tmp = []
|
346
|
+
prev_parents = []
|
339
347
|
self.each_index do |i|
|
340
348
|
obj = @objects[i]
|
341
349
|
prev_parent = obj._parent
|
342
350
|
prev_parent_element = obj._parent_element
|
343
351
|
obj.set_parent(self, nil)
|
352
|
+
tmp << obj
|
353
|
+
prev_parents << [prev_parent, prev_parent_element]
|
354
|
+
end
|
355
|
+
tmp.each do |obj|
|
344
356
|
yield obj
|
345
|
-
|
357
|
+
end
|
358
|
+
tmp.each_index do |i|
|
359
|
+
prev_parent, prev_parent_element = prev_parents[i]
|
360
|
+
tmp[i].set_parent(prev_parent, prev_parent_element)
|
346
361
|
end
|
347
362
|
end
|
348
363
|
|
@@ -406,8 +421,7 @@ module Spider; module Model
|
|
406
421
|
# Executes the query and fetches the objects; (the next batch if a fetch_window is set).
|
407
422
|
def load
|
408
423
|
return self unless loadable?
|
409
|
-
|
410
|
-
@index_lookup.each_key{ |k| @index_lookup[k] = {} }
|
424
|
+
clear
|
411
425
|
@loaded = false
|
412
426
|
@loaded_elements = {}
|
413
427
|
return load_next if @fetch_window && !@query.offset
|
@@ -599,6 +613,10 @@ module Spider; module Model
|
|
599
613
|
h
|
600
614
|
end
|
601
615
|
end
|
616
|
+
|
617
|
+
def reject!(&proc)
|
618
|
+
@objects.reject!(&proc)
|
619
|
+
end
|
602
620
|
|
603
621
|
def to_s
|
604
622
|
self.map{ |o| o.to_s }.join(', ')
|
@@ -10,6 +10,8 @@ module Spider; module Model
|
|
10
10
|
attr_accessor :total_rows
|
11
11
|
# (array) find also the given subclasses of the queried model.
|
12
12
|
attr_reader :polymorphs
|
13
|
+
# (bool) if true, the request will be expanded with lazy groups on load
|
14
|
+
attr_accessor :expandable
|
13
15
|
|
14
16
|
def initialize(val=nil, params={})
|
15
17
|
if (val.is_a?(Array))
|
@@ -20,6 +22,7 @@ module Spider; module Model
|
|
20
22
|
end
|
21
23
|
@total_rows = params[:total_rows]
|
22
24
|
@polymorphs = {}
|
25
|
+
@expandable = true
|
23
26
|
end
|
24
27
|
|
25
28
|
# TODO: fix/remove?
|
@@ -73,6 +76,10 @@ module Spider; module Model
|
|
73
76
|
def with_superclass?
|
74
77
|
@with_superclass
|
75
78
|
end
|
79
|
+
|
80
|
+
def expandable?
|
81
|
+
@expandable
|
82
|
+
end
|
76
83
|
|
77
84
|
end
|
78
85
|
|
@@ -12,7 +12,8 @@ module Spider; module Model; module Storage; module Db
|
|
12
12
|
@capabilities = {
|
13
13
|
:autoincrement => true,
|
14
14
|
:sequences => false,
|
15
|
-
:transactions => true
|
15
|
+
:transactions => true,
|
16
|
+
:foreign_keys => true
|
16
17
|
}
|
17
18
|
@reserved_keywords = superclass.reserved_keywords
|
18
19
|
@safe_conversions = {
|
@@ -228,6 +229,8 @@ module Spider; module Model; module Storage; module Db
|
|
228
229
|
value = super(type, value)
|
229
230
|
return value unless value
|
230
231
|
case type.name
|
232
|
+
when 'String'
|
233
|
+
return value.to_s
|
231
234
|
when 'Date', 'DateTime'
|
232
235
|
return value.strftime("%Y-%m-%dT%H:%M:%S")
|
233
236
|
when 'Fixnum'
|
@@ -7,9 +7,10 @@ module Spider; module Model; module Storage; module Db
|
|
7
7
|
@capabilities = {
|
8
8
|
:autoincrement => false,
|
9
9
|
:sequences => true,
|
10
|
-
:transactions => true
|
10
|
+
:transactions => true,
|
11
|
+
:foreign_keys => true
|
11
12
|
}
|
12
|
-
@reserved_keywords = superclass.reserved_keywords + ['oci8_row_num', 'file', 'uid']
|
13
|
+
@reserved_keywords = superclass.reserved_keywords + ['oci8_row_num', 'file', 'uid', 'name', 'comment']
|
13
14
|
@safe_conversions = {
|
14
15
|
'CHAR' => ['VARCHAR', 'CLOB'],
|
15
16
|
'VARCHAR' => ['CLOB'],
|
@@ -24,6 +25,7 @@ module Spider; module Model; module Storage; module Db
|
|
24
25
|
def self.new_connection(user, pass, dbname, role)
|
25
26
|
conn ||= ::OCI8.new(user, pass, dbname, role)
|
26
27
|
conn.autocommit = true
|
28
|
+
conn.non_blocking = true
|
27
29
|
return conn
|
28
30
|
end
|
29
31
|
|
@@ -69,19 +71,23 @@ module Spider; module Model; module Storage; module Db
|
|
69
71
|
|
70
72
|
|
71
73
|
def do_start_transaction
|
74
|
+
return unless transactions_enabled?
|
72
75
|
connection.autocommit = false
|
73
76
|
end
|
74
77
|
|
75
78
|
def in_transaction?
|
79
|
+
return false unless transactions_enabled?
|
76
80
|
return curr[:conn] && !curr[:conn].autocommit?
|
77
81
|
end
|
78
82
|
|
79
83
|
def do_commit
|
84
|
+
return release unless transactions_enabled?
|
80
85
|
curr[:conn].commit if curr[:conn]
|
81
86
|
release
|
82
87
|
end
|
83
88
|
|
84
89
|
def do_rollback
|
90
|
+
return release unless transactions_enabled?
|
85
91
|
curr[:conn].rollback
|
86
92
|
release
|
87
93
|
end
|
@@ -108,7 +114,7 @@ module Spider; module Model; module Storage; module Db
|
|
108
114
|
case type.name
|
109
115
|
when 'Date', 'DateTime'
|
110
116
|
return nil unless value
|
111
|
-
return value if value.is_a?(
|
117
|
+
return value if value.is_a?(type)
|
112
118
|
return value.to_datetime if type == DateTime
|
113
119
|
return value.to_date # FIXME: check what is returned, here we espect an OCI8::Date
|
114
120
|
when 'Spider::DataTypes::Text'
|
@@ -126,15 +132,15 @@ module Spider; module Model; module Storage; module Db
|
|
126
132
|
end
|
127
133
|
curr[:last_executed] = [sql, bind_vars]
|
128
134
|
if (Spider.conf.get('storage.db.replace_debug_vars'))
|
129
|
-
|
130
|
-
|
131
|
-
v = bind_vars[
|
132
|
-
dv = debug_vars[
|
135
|
+
debug("oci8 #{connection} executing: "+sql.gsub(/:(\d+)/){
|
136
|
+
i = $1.to_i
|
137
|
+
v = bind_vars[i-1]
|
138
|
+
dv = debug_vars[i-1]
|
133
139
|
v.is_a?(String) ? "'#{dv}'" : dv
|
134
140
|
})
|
135
141
|
else
|
136
142
|
debug_vars_str = debug_vars ? debug_vars.join(', ') : ''
|
137
|
-
debug("oci8 executing:\n#{sql}\n[#{debug_vars_str}]")
|
143
|
+
debug("oci8 #{connection} executing:\n#{sql}\n[#{debug_vars_str}]")
|
138
144
|
end
|
139
145
|
cursor = connection.parse(sql)
|
140
146
|
return cursor if (!cursor || cursor.is_a?(Fixnum))
|
@@ -152,11 +158,16 @@ module Spider; module Model; module Storage; module Db
|
|
152
158
|
if (have_result)
|
153
159
|
result = []
|
154
160
|
while (h = cursor.fetch_hash)
|
161
|
+
h.each do |key, val|
|
162
|
+
if val.respond_to?(:read)
|
163
|
+
h[key] = val.read
|
164
|
+
end
|
165
|
+
end
|
155
166
|
if block_given?
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
167
|
+
yield h
|
168
|
+
else
|
169
|
+
result << h
|
170
|
+
end
|
160
171
|
end
|
161
172
|
end
|
162
173
|
if (have_result)
|
@@ -168,9 +179,14 @@ module Spider; module Model; module Storage; module Db
|
|
168
179
|
else
|
169
180
|
return res
|
170
181
|
end
|
182
|
+
cursor.close
|
183
|
+
|
171
184
|
rescue => exc
|
185
|
+
curr[:conn].break if curr[:conn]
|
186
|
+
rollback! if in_transaction?
|
187
|
+
#curr[:conn].logoff
|
172
188
|
release
|
173
|
-
raise
|
189
|
+
raise
|
174
190
|
ensure
|
175
191
|
cursor.close if cursor
|
176
192
|
release if curr[:conn] && !in_transaction?
|
@@ -234,6 +250,7 @@ module Spider; module Model; module Storage; module Db
|
|
234
250
|
# Spider::Logger.debug("SQL SELECT:")
|
235
251
|
# Spider::Logger.debug(query)
|
236
252
|
bind_vars = query[:bind_vars] || []
|
253
|
+
order_on_different_table = false
|
237
254
|
if query[:limit] # Oracle is so braindead
|
238
255
|
replaced_fields = {}
|
239
256
|
replace_cnt = 0
|
@@ -248,6 +265,7 @@ module Spider; module Model; module Storage; module Db
|
|
248
265
|
# end
|
249
266
|
transformed = "O#{replace_cnt += 1}"
|
250
267
|
replaced_fields[field.to_s] = transformed
|
268
|
+
order_on_different_table = true if field.is_a?(Spider::Model::Storage::Db::Field) && !query[:tables].include?(field.table)
|
251
269
|
if (field.is_a?(Spider::Model::Storage::Db::Field) && field.type == 'CLOB')
|
252
270
|
field = "CAST(#{field} as varchar2(100))"
|
253
271
|
end
|
@@ -262,7 +280,7 @@ module Spider; module Model; module Storage; module Db
|
|
262
280
|
where, vals = sql_condition(query)
|
263
281
|
bind_vars += vals
|
264
282
|
sql += "WHERE #{where} " if where && !where.empty?
|
265
|
-
order = sql_order(query)
|
283
|
+
order = sql_order(query, replaced_fields)
|
266
284
|
if (query[:limit])
|
267
285
|
if (query[:offset])
|
268
286
|
limit = "oci8_row_num between :#{curr[:bind_cnt]+=1} and :#{curr[:bind_cnt]+=1}"
|
@@ -272,14 +290,12 @@ module Spider; module Model; module Storage; module Db
|
|
272
290
|
limit = "oci8_row_num < :#{curr[:bind_cnt]+=1}"
|
273
291
|
bind_vars << query[:limit] + 1
|
274
292
|
end
|
275
|
-
replaced_fields.each do |f, repl|
|
276
|
-
order = order.gsub(f, repl)
|
277
|
-
end
|
278
293
|
if (!query[:joins].empty?)
|
294
|
+
data_tables_sql = order_on_different_table ? tables_sql : query[:tables].join(', ')
|
279
295
|
pk_sql = query[:primary_keys].join(', ')
|
280
296
|
distinct_sql = "SELECT DISTINCT #{pk_sql} FROM #{tables_sql}"
|
281
297
|
distinct_sql += " WHERE #{where}" if where && !where.empty?
|
282
|
-
data_sql = "SELECT #{keys} FROM #{
|
298
|
+
data_sql = "SELECT #{keys} FROM #{data_tables_sql} WHERE (#{pk_sql}) IN (#{distinct_sql}) order by #{order}"
|
283
299
|
else
|
284
300
|
data_sql = "#{sql} order by #{order}"
|
285
301
|
end
|
@@ -296,6 +312,7 @@ module Spider; module Model; module Storage; module Db
|
|
296
312
|
end
|
297
313
|
|
298
314
|
def sql_condition_value(key, comp, value, bound_vars=true)
|
315
|
+
curr[:bind_cnt] ||= 0
|
299
316
|
if (comp.to_s.downcase == 'ilike')
|
300
317
|
comp = 'like'
|
301
318
|
key = "UPPER(#{key})"
|
@@ -6,30 +6,39 @@ module Spider; module Model; module Storage; module Db
|
|
6
6
|
class SQLite < DbStorage
|
7
7
|
@reserved_keywords = superclass.reserved_keywords + []
|
8
8
|
@capabilities = {
|
9
|
-
:autoincrement =>
|
9
|
+
:autoincrement => true,
|
10
10
|
:sequences => true,
|
11
|
-
:transactions => true
|
11
|
+
:transactions => true,
|
12
|
+
:foreign_keys => false
|
12
13
|
}
|
13
14
|
|
14
15
|
class << self; attr_reader :reserved_kewords; end
|
15
16
|
|
17
|
+
def self.max_connections
|
18
|
+
1
|
19
|
+
end
|
20
|
+
|
16
21
|
def self.base_types
|
17
22
|
super << Spider::DataTypes::Binary
|
18
23
|
end
|
19
24
|
|
20
25
|
def self.new_connection(file)
|
21
|
-
|
22
|
-
|
23
|
-
return
|
26
|
+
db = SQLite3::Database.new(file)
|
27
|
+
db.results_as_hash = true
|
28
|
+
return db
|
24
29
|
end
|
25
30
|
|
26
|
-
def
|
27
|
-
|
31
|
+
def self.connection_alive?(conn)
|
32
|
+
!conn.closed?
|
28
33
|
end
|
29
34
|
|
30
35
|
def release
|
31
|
-
|
32
|
-
|
36
|
+
begin
|
37
|
+
#curr[:conn].close
|
38
|
+
super
|
39
|
+
rescue
|
40
|
+
curr[:conn] = nil
|
41
|
+
end
|
33
42
|
end
|
34
43
|
|
35
44
|
|
@@ -43,26 +52,30 @@ module Spider; module Model; module Storage; module Db
|
|
43
52
|
@connection_params = [@file]
|
44
53
|
end
|
45
54
|
|
46
|
-
def
|
55
|
+
def do_start_transaction
|
56
|
+
return unless transactions_enabled?
|
47
57
|
connection.transaction
|
48
58
|
end
|
49
59
|
|
50
60
|
def in_transaction?
|
51
|
-
|
61
|
+
return false unless transactions_enabled?
|
62
|
+
return curr[:conn] && curr[:conn].transaction_active?
|
52
63
|
end
|
53
64
|
|
54
|
-
def
|
55
|
-
|
65
|
+
def do_commit
|
66
|
+
return release unless transactions_enabled?
|
67
|
+
curr[:conn].commit if curr[:conn]
|
56
68
|
release
|
57
69
|
end
|
58
|
-
|
59
|
-
def
|
60
|
-
|
70
|
+
|
71
|
+
def do_rollback
|
72
|
+
return release unless transactions_enabled?
|
73
|
+
curr[:conn].rollback
|
61
74
|
release
|
62
75
|
end
|
63
|
-
|
76
|
+
|
64
77
|
def assigned_key(key)
|
65
|
-
|
78
|
+
curr[:last_insert_row_id]
|
66
79
|
end
|
67
80
|
|
68
81
|
def value_for_save(type, value, save_mode)
|
@@ -81,9 +94,9 @@ module Spider; module Model; module Storage; module Db
|
|
81
94
|
debug("sqlite executing:\n#{sql}\n[#{debug_vars}]")
|
82
95
|
|
83
96
|
result = connection.execute(sql, *bind_vars)
|
84
|
-
|
97
|
+
curr[:last_insert_row_id] = connection.last_insert_row_id
|
85
98
|
result.extend(StorageResult)
|
86
|
-
|
99
|
+
curr[:last_result] = result
|
87
100
|
if block_given?
|
88
101
|
result.each{ |row| yield row }
|
89
102
|
else
|
@@ -97,8 +110,7 @@ module Spider; module Model; module Storage; module Db
|
|
97
110
|
|
98
111
|
def prepare(sql)
|
99
112
|
debug("sqlite preparing: #{sql}")
|
100
|
-
|
101
|
-
return @conn.prepare(sql)
|
113
|
+
return connection.prepare(sql)
|
102
114
|
end
|
103
115
|
|
104
116
|
def execute_statement(stmt, *bind_vars)
|
@@ -106,10 +118,10 @@ module Spider; module Model; module Storage; module Db
|
|
106
118
|
end
|
107
119
|
|
108
120
|
def total_rows
|
109
|
-
return nil unless
|
110
|
-
q =
|
121
|
+
return nil unless curr[:last_query]
|
122
|
+
q = curr[:last_query]
|
111
123
|
unless (q[:offset] || q[:limit])
|
112
|
-
return
|
124
|
+
return curr[:last_result] ? curr[:last_result].length : nil
|
113
125
|
end
|
114
126
|
q[:offset] = q[:limit] = nil
|
115
127
|
q[:keys] = ["COUNT(*) AS N"]
|
@@ -117,6 +129,10 @@ module Spider; module Model; module Storage; module Db
|
|
117
129
|
return res[0]['N']
|
118
130
|
end
|
119
131
|
|
132
|
+
#############################################################
|
133
|
+
# SQL methods #
|
134
|
+
#############################################################
|
135
|
+
|
120
136
|
##############################################################
|
121
137
|
# Methods to get information from the db #
|
122
138
|
##############################################################
|
@@ -127,17 +143,35 @@ module Spider; module Model; module Storage; module Db
|
|
127
143
|
|
128
144
|
def describe_table(table)
|
129
145
|
columns = {}
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
146
|
+
primary_keys = []
|
147
|
+
res = execute("PRAGMA table_info('#{table}')")
|
148
|
+
res.each do |row|
|
149
|
+
name = row['name']
|
150
|
+
type = row['type']
|
151
|
+
length = nil
|
152
|
+
precision = nil
|
153
|
+
if type =~ /(.+)\((.+)\)/
|
154
|
+
type = $1
|
155
|
+
length = $2
|
156
|
+
end
|
157
|
+
if length && length.include?(",")
|
158
|
+
length, precision = length.split(',')
|
137
159
|
end
|
160
|
+
length = length.to_i if length
|
161
|
+
precision = precision.to_i if length
|
162
|
+
primary_keys << name if row['pk'] == "1"
|
163
|
+
columns[name] = {:type => type, :length => length, :precision => precision}
|
138
164
|
end
|
139
|
-
stmt.
|
140
|
-
|
165
|
+
# stmt.columns.each_index do |index|
|
166
|
+
# field = stmt.columns[index]
|
167
|
+
# columns[field] ||= {}
|
168
|
+
# if (stmt.types[index] =~ /([^\(]+)(?:\((\d+)\))?/)
|
169
|
+
# columns[field][:type] = $1
|
170
|
+
# columns[field][:length] = $2.to_i if $2
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
# stmt.close
|
174
|
+
return {:columns => columns, :primary_keys => primary_keys}
|
141
175
|
end
|
142
176
|
|
143
177
|
def table_exists?(table)
|
@@ -37,7 +37,7 @@ module Spider; module Model; module Storage; module Db; module Connectors
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def parse_url(url)
|
40
|
-
# adapter
|
40
|
+
# adapter://<username:password>@<dsn>
|
41
41
|
if (url =~ /(.+):\/\/(?:(.+):(.+)@)?(.+)/)
|
42
42
|
@adapter = $1
|
43
43
|
@user = $2
|