engine2 1.0.4 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +0 -0
- data/Rakefile +4 -4
- data/app/{engine2actions.coffee → actions.coffee} +341 -215
- data/app/app.coffee +0 -0
- data/app/app.css +17 -0
- data/app/engine2.coffee +158 -208
- data/app/modal.coffee +138 -0
- data/bower.json +4 -2
- data/conf/message.yaml +5 -0
- data/conf/message_pl.yaml +7 -2
- data/config.coffee +24 -12
- data/engine2.gemspec +8 -8
- data/lib/engine2.rb +12 -10
- data/lib/engine2/action.rb +1338 -133
- data/lib/engine2/action/array.rb +189 -0
- data/lib/engine2/{meta/decode_meta.rb → action/decode.rb} +52 -21
- data/lib/engine2/action/delete.rb +64 -0
- data/lib/engine2/action/form.rb +16 -0
- data/lib/engine2/{meta/infra_meta.rb → action/infra.rb} +123 -89
- data/lib/engine2/action/link.rb +117 -0
- data/lib/engine2/action/list.rb +333 -0
- data/lib/engine2/action/save.rb +28 -0
- data/lib/engine2/action/view.rb +8 -0
- data/lib/engine2/action_node.rb +221 -0
- data/lib/engine2/core.rb +175 -87
- data/lib/engine2/handler.rb +14 -13
- data/lib/engine2/model.rb +85 -43
- data/lib/engine2/models/Files.rb +4 -1
- data/lib/engine2/models/UserInfo.rb +6 -3
- data/lib/engine2/post_bootstrap.rb +4 -3
- data/lib/engine2/pre_bootstrap.rb +10 -6
- data/lib/engine2/scheme.rb +107 -65
- data/lib/engine2/templates.rb +41 -6
- data/lib/engine2/type_info.rb +51 -23
- data/lib/engine2/version.rb +2 -1
- data/package.json +22 -16
- data/public/favicon.ico +0 -0
- data/public/img/ajax-loader-dark.gif +0 -0
- data/public/img/ajax-loader.gif +0 -0
- data/views/fields/blob.slim +1 -1
- data/views/fields/bs_select.slim +2 -2
- data/views/fields/bsselect_picker.slim +4 -4
- data/views/fields/bsselect_picker_opt.slim +5 -5
- data/views/fields/checkbox.slim +4 -4
- data/views/fields/checkbox_button.slim +6 -0
- data/views/fields/checkbox_buttons.slim +3 -3
- data/views/fields/checkbox_buttons_opt.slim +3 -3
- data/views/fields/currency.slim +2 -2
- data/views/fields/date.slim +4 -4
- data/views/fields/date_range.slim +9 -9
- data/views/fields/date_time.slim +9 -9
- data/views/fields/datetime.slim +8 -8
- data/views/fields/decimal.slim +1 -1
- data/views/fields/decimal_date.slim +3 -3
- data/views/fields/decimal_time.slim +3 -3
- data/views/fields/email.slim +3 -3
- data/views/fields/file_store.slim +11 -11
- data/views/fields/input_text.slim +4 -4
- data/views/fields/integer.slim +1 -1
- data/views/fields/list_bsmselect.slim +20 -0
- data/views/fields/list_bsselect.slim +5 -5
- data/views/fields/list_bsselect_opt.slim +6 -6
- data/views/fields/list_buttons.slim +1 -1
- data/views/fields/list_buttons_opt.slim +2 -2
- data/views/fields/list_mbuttons.slim +9 -0
- data/views/fields/list_mbuttons_opt.slim +11 -0
- data/views/fields/list_mselect.slim +12 -0
- data/views/fields/list_select.slim +4 -4
- data/views/fields/list_select_opt.slim +5 -5
- data/views/fields/password.slim +4 -4
- data/views/fields/radio_checkbox.slim +3 -3
- data/views/fields/scaffold.slim +2 -2
- data/views/fields/scaffold_picker.slim +5 -5
- data/views/fields/select_picker.slim +3 -3
- data/views/fields/select_picker_opt.slim +4 -4
- data/views/fields/text_area.slim +4 -3
- data/views/fields/time.slim +5 -4
- data/views/fields/typeahead_picker.slim +12 -9
- data/views/index.slim +3 -3
- data/views/infra/index.slim +0 -0
- data/views/infra/inspect.slim +41 -10
- data/views/modals/close_m.slim +0 -0
- data/views/modals/confirm_m.slim +0 -0
- data/views/modals/empty_m.slim +0 -0
- data/views/modals/menu_m.slim +1 -1
- data/views/modals/yes_no_m.slim +0 -0
- data/views/panels/menu_m.slim +1 -1
- data/views/scaffold/confirm.slim +0 -0
- data/views/scaffold/fields.slim +6 -4
- data/views/scaffold/form.slim +1 -1
- data/views/scaffold/form_collapse.slim +4 -3
- data/views/scaffold/form_tabs.slim +3 -2
- data/views/scaffold/list.slim +0 -0
- data/views/scaffold/message.slim +0 -0
- data/views/scaffold/search.slim +4 -4
- data/views/scaffold/search_collapse.slim +8 -7
- data/views/scaffold/search_tabs.slim +6 -5
- data/views/scaffold/view.slim +2 -2
- data/views/scaffold/view_collapse.slim +5 -4
- data/views/scaffold/view_tabs.slim +4 -3
- data/views/search_fields/bsmselect_picker.slim +4 -4
- data/views/search_fields/bsselect_picker.slim +4 -4
- data/views/search_fields/checkbox.slim +3 -3
- data/views/search_fields/checkbox2.slim +5 -5
- data/views/search_fields/checkbox_buttons.slim +3 -3
- data/views/search_fields/date.slim +20 -0
- data/views/search_fields/date_range.slim +8 -8
- data/views/search_fields/decimal_date_range.slim +5 -5
- data/views/search_fields/input_text.slim +2 -2
- data/views/search_fields/integer.slim +1 -1
- data/views/search_fields/integer_range.slim +2 -2
- data/views/search_fields/list_bsmselect.slim +4 -4
- data/views/search_fields/list_bsselect.slim +4 -4
- data/views/search_fields/list_buttons.slim +2 -2
- data/views/search_fields/list_mbuttons.slim +12 -0
- data/views/search_fields/list_select.slim +3 -3
- data/views/search_fields/scaffold_picker.slim +2 -2
- data/views/search_fields/select_picker.slim +3 -3
- data/views/search_fields/typeahead_picker.slim +8 -7
- metadata +53 -48
- data/lib/engine2/meta.rb +0 -1216
- data/lib/engine2/meta/array_meta.rb +0 -82
- data/lib/engine2/meta/delete_meta.rb +0 -60
- data/lib/engine2/meta/form_meta.rb +0 -15
- data/lib/engine2/meta/link_meta.rb +0 -134
- data/lib/engine2/meta/list_meta.rb +0 -281
- data/lib/engine2/meta/save_meta.rb +0 -50
- data/lib/engine2/meta/view_meta.rb +0 -7
- data/public/__sinatra__/404.png +0 -0
- data/public/__sinatra__/500.png +0 -0
data/lib/engine2/handler.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
class Handler < Sinatra::Base
|
@@ -66,20 +67,20 @@ module Engine2
|
|
66
67
|
def serve_api_resource verb, path
|
67
68
|
path = path.split('/') # -1 ?
|
68
69
|
is_meta = path.pop if path.last == 'meta'
|
69
|
-
|
70
|
+
node = ROOT
|
70
71
|
path.each do |pat|
|
71
|
-
|
72
|
-
halt_not_found unless
|
73
|
-
halt_unauthorized unless
|
72
|
+
node = node[pat.to_sym]
|
73
|
+
halt_not_found unless node
|
74
|
+
halt_unauthorized unless node.check_access!(self)
|
74
75
|
end
|
75
76
|
|
76
|
-
|
77
|
+
action = node.*
|
77
78
|
response = if is_meta
|
78
|
-
params[:access] ?
|
79
|
+
params[:access] ? node.access_info(self) : {meta: action.meta, actions: node.nodes_info(self)}
|
79
80
|
else
|
80
|
-
if
|
81
|
+
if action.http_method == verb && action.invokable
|
81
82
|
begin
|
82
|
-
|
83
|
+
action.invoke!(self)
|
83
84
|
rescue => error
|
84
85
|
attachment nil, nil
|
85
86
|
# content_type :json
|
@@ -118,16 +119,16 @@ module Engine2
|
|
118
119
|
slim name.to_sym
|
119
120
|
end
|
120
121
|
|
121
|
-
set :slim, pretty:
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
set :slim, pretty: !production?, sort_attrs: false
|
123
|
+
unless production? # use Engine2::SETTINGS[:reloading] ?
|
124
|
+
set :sessions, expire_after: 3600
|
125
|
+
# set :session_store, Rack::Session::Pool
|
126
|
+
end
|
125
127
|
|
126
128
|
helpers do
|
127
129
|
def find_template(views, name, engine, &block)
|
128
130
|
views.each{|v| super(v, name, engine, &block)}
|
129
131
|
end
|
130
132
|
end
|
131
|
-
|
132
133
|
end
|
133
134
|
end
|
data/lib/engine2/model.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
module Model
|
5
6
|
attr_reader :dummies
|
6
7
|
attr_reader :many_to_one_associations, :one_to_many_associations, :many_to_many_associations #, :one_to_one_associations
|
7
|
-
attr_reader :before_save_processors, :after_save_processors, :before_destroy_processors, :after_destroy_processors
|
8
|
+
attr_reader :after_load_processors, :before_save_processors, :after_save_processors, :before_destroy_processors, :after_destroy_processors
|
8
9
|
attr_reader :validation_in_transaction
|
9
10
|
|
10
11
|
def self.extended cls
|
@@ -18,12 +19,15 @@ module Engine2
|
|
18
19
|
@many_to_many_associations = association_reflections.select{|n, a| a[:type] == :many_to_many}
|
19
20
|
# @one_to_one_associations = association_reflections.select{|n, a| a[:type] == :one_to_one}
|
20
21
|
@validation_in_transaction = nil
|
22
|
+
@after_load_processors = nil
|
21
23
|
@before_save_processors = nil
|
22
24
|
@after_save_processors = nil
|
23
25
|
@around_save_processors = nil
|
24
26
|
@before_destroy_processors = nil
|
25
27
|
@after_destroy_processors = nil
|
26
28
|
@type_info_synchronized = nil
|
29
|
+
@model_icon = :"list"
|
30
|
+
@model_route = cls.name.to_sym
|
27
31
|
end
|
28
32
|
cls.setup_schema
|
29
33
|
end
|
@@ -52,12 +56,12 @@ module Engine2
|
|
52
56
|
when :integer
|
53
57
|
integer_field name
|
54
58
|
when :string
|
55
|
-
|
56
|
-
|
59
|
+
string_field name, case db_info[:db_type]
|
60
|
+
when 'text', 'character varying'
|
61
|
+
100
|
57
62
|
else
|
58
|
-
|
63
|
+
Integer(db_info[:column_size] || db_info[:db_type][/\((\d+)\)/, 1])
|
59
64
|
end
|
60
|
-
|
61
65
|
when :time
|
62
66
|
time_field name, LOCS[:default_time_format], LOCS[:default_time_model_format]
|
63
67
|
when :date
|
@@ -74,6 +78,8 @@ module Engine2
|
|
74
78
|
decimal_field name, size, scale
|
75
79
|
when :blob
|
76
80
|
blob_field name, 100000
|
81
|
+
when :boolean
|
82
|
+
boolean_field name
|
77
83
|
when nil
|
78
84
|
# ignore nil type
|
79
85
|
else
|
@@ -106,9 +112,27 @@ module Engine2
|
|
106
112
|
end
|
107
113
|
end
|
108
114
|
|
115
|
+
def find_type_info name
|
116
|
+
model = self
|
117
|
+
info = case name
|
118
|
+
when Symbol
|
119
|
+
model.type_info[name]
|
120
|
+
when Sequel::SQL::QualifiedIdentifier
|
121
|
+
assoc = model.many_to_one_associations[name.table] || model.many_to_many_associations[name.table]
|
122
|
+
raise E2Error.new("Association #{name.table} not found for model #{model}") unless assoc
|
123
|
+
assoc.associated_class.type_info[name.column]
|
124
|
+
else
|
125
|
+
raise E2Error.new("Unknown type info key: #{name} in model #{model}")
|
126
|
+
end
|
127
|
+
|
128
|
+
raise E2Error.new("Type info not found for '#{name}' in model '#{model}'") unless info
|
129
|
+
info
|
130
|
+
end
|
131
|
+
|
109
132
|
def synchronize_type_info
|
110
133
|
resolve_dependencies
|
111
134
|
verify_associations
|
135
|
+
@after_load_processors = install_processors(AfterLoadProcessors)
|
112
136
|
@before_save_processors = install_processors(BeforeSaveProcessors)
|
113
137
|
@after_save_processors = install_processors(AfterSaveProcessors)
|
114
138
|
@around_save_processors = {}
|
@@ -117,18 +141,6 @@ module Engine2
|
|
117
141
|
@type_info_synchronized = true
|
118
142
|
end
|
119
143
|
|
120
|
-
def verify_associations
|
121
|
-
one_to_many_associations.each do |name, assoc|
|
122
|
-
other = assoc.associated_class
|
123
|
-
other_type_info = other.type_info
|
124
|
-
if other_keys = assoc[:keys]
|
125
|
-
other_keys.each do |key|
|
126
|
-
raise E2Error.new("No key '#{key}' found in model '#{other}' being related from #{self}") unless other_type_info[key]
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
144
|
def resolve_dependencies
|
133
145
|
resolved = {}
|
134
146
|
@type_info.each_pair do |name, info|
|
@@ -150,14 +162,33 @@ module Engine2
|
|
150
162
|
resolved[name] = @type_info[name]
|
151
163
|
end
|
152
164
|
|
165
|
+
def verify_associations
|
166
|
+
one_to_many_associations.each do |name, assoc|
|
167
|
+
other = assoc.associated_class
|
168
|
+
other_type_info = other.type_info
|
169
|
+
if other_keys = assoc[:keys]
|
170
|
+
other_keys.each do |key|
|
171
|
+
raise E2Error.new("No key '#{key}' found in model '#{other}' being related from #{self}") unless other_type_info[key]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
153
177
|
attr_reader :scheme_name, :scheme_args
|
154
178
|
|
155
179
|
def scheme s_name = :default, opts = nil, &blk
|
156
180
|
@scheme_name = s_name
|
157
|
-
@scheme_args = [
|
158
|
-
SCHEMES::define_scheme
|
181
|
+
@scheme_args = [model_route, self, opts]
|
182
|
+
SCHEMES::define_scheme model_route, &blk
|
183
|
+
end
|
184
|
+
|
185
|
+
def model_icon icn = nil
|
186
|
+
icn ? @model_icon = icn : @model_icon
|
159
187
|
end
|
160
188
|
|
189
|
+
def model_route rt = nil
|
190
|
+
rt ? @model_route = rt : @model_route
|
191
|
+
end
|
161
192
|
end
|
162
193
|
|
163
194
|
# def define_dummy_model
|
@@ -269,7 +300,14 @@ module Engine2
|
|
269
300
|
},
|
270
301
|
list_select: lambda{|record, field, info|
|
271
302
|
value = record.values[field]
|
272
|
-
|
303
|
+
values = info[:values].map(&:first)
|
304
|
+
|
305
|
+
result = if info[:multiselect]
|
306
|
+
value.is_a?(Array) && (values - value).length == values.length - value.length
|
307
|
+
else
|
308
|
+
values.include?(value)
|
309
|
+
end
|
310
|
+
LOCS[:invalid_list_value] unless result
|
273
311
|
},
|
274
312
|
decimal: lambda{|record, field, info|
|
275
313
|
value = record.values[field]
|
@@ -284,7 +322,7 @@ module Engine2
|
|
284
322
|
with_errors = with.map{|w|record.errors[w]}
|
285
323
|
if with_errors.compact.empty?
|
286
324
|
all_fields = [field] + with
|
287
|
-
query = record.model.dataset
|
325
|
+
query = all_fields.reduce(record.model.dataset){|ds, f|ds.where f => record[f]}
|
288
326
|
query = query.exclude(record.model.primary_keys_hash(record.primary_key_values)) unless record.new?
|
289
327
|
unless query.empty?
|
290
328
|
msg = LOCS[:required_unique_value]
|
@@ -297,6 +335,20 @@ module Engine2
|
|
297
335
|
}
|
298
336
|
)
|
299
337
|
|
338
|
+
(AfterLoadProcessors ||= {}).merge!(
|
339
|
+
list_select: lambda{|record, field, info|
|
340
|
+
value = record[field]
|
341
|
+
record[field] = case info[:otype]
|
342
|
+
when :string
|
343
|
+
value.split(info[:separator])
|
344
|
+
when :integer
|
345
|
+
arr = []
|
346
|
+
value.bit_length.times{|i| arr << (1 << i) unless value[i].zero?}
|
347
|
+
arr
|
348
|
+
end if value && info[:multiselect]
|
349
|
+
}
|
350
|
+
)
|
351
|
+
|
300
352
|
(BeforeSaveProcessors ||= {}).merge!(
|
301
353
|
blob_store: lambda{|record, field, info|
|
302
354
|
if value = record.values[field] # attachment info
|
@@ -323,33 +375,23 @@ module Engine2
|
|
323
375
|
end
|
324
376
|
File.delete("#{upload}/#{value[:rackname]}")
|
325
377
|
end
|
378
|
+
},
|
379
|
+
list_select: lambda{|record, field, info|
|
380
|
+
value = record.values[field]
|
381
|
+
record[field] = case info[:otype]
|
382
|
+
when :string
|
383
|
+
value.join(info[:separator])
|
384
|
+
when :integer
|
385
|
+
value.reduce(0, :|)
|
386
|
+
end if value && info[:multiselect] && !info[:dummy]
|
326
387
|
}
|
327
388
|
)
|
328
389
|
|
329
390
|
(AfterSaveProcessors ||= {}).merge!(
|
330
|
-
star_to_many_field: lambda{|record, field, info|
|
331
|
-
value = record.values[field]
|
332
|
-
if value && value.is_a?(Hash)
|
333
|
-
assoc = record.model.association_reflections[info[:assoc_name]]
|
334
|
-
other_model = assoc.associated_class
|
335
|
-
unlinked = value[:unlinked]
|
336
|
-
linked = value[:linked]
|
337
|
-
parent_key = record.primary_key_values
|
338
|
-
case assoc[:type]
|
339
|
-
when :one_to_many
|
340
|
-
StarToManyUnlinkMetaBase.one_to_many_unlink_db(other_model, assoc, unlinked) if unlinked
|
341
|
-
StarToManyLinkMeta.one_to_many_link_db(other_model, assoc, parent_key, linked) if linked
|
342
|
-
when :many_to_many
|
343
|
-
StarToManyUnlinkMetaBase.many_to_many_unlink_db(other_model, assoc, parent_key, unlinked) if unlinked
|
344
|
-
StarToManyLinkMeta.many_to_many_link_db(other_model, assoc, parent_key, linked) if linked
|
345
|
-
else unsupported_association
|
346
|
-
end
|
347
|
-
end
|
348
|
-
},
|
349
391
|
file_store: lambda{|m, v, info|
|
350
392
|
value = m.values[v]
|
351
393
|
files = E2Files.db[:files]
|
352
|
-
owner = m.primary_key_values
|
394
|
+
owner = Sequel::join_keys(m.primary_key_values)
|
353
395
|
upload = info[:store][:upload]
|
354
396
|
files_dir = info[:store][:files]
|
355
397
|
value.each do |entry|
|
@@ -375,7 +417,7 @@ module Engine2
|
|
375
417
|
# record.model.where(id).update(info[:field] => Sequel.blob(open("#{upload}/#{value[:rackname]}", "rb"){|f|f.read}))
|
376
418
|
File.delete("#{upload}/#{value[:rackname]}")
|
377
419
|
end
|
378
|
-
}
|
420
|
+
},
|
379
421
|
)
|
380
422
|
|
381
423
|
(BeforeDestroyProcessors ||= {}).merge!(
|
@@ -393,7 +435,7 @@ module Engine2
|
|
393
435
|
file_store: lambda{|m, v, info|
|
394
436
|
files = E2Files.db[:files]
|
395
437
|
files_dir = info[:store][:files]
|
396
|
-
owner = m.primary_key_values
|
438
|
+
owner = Sequel::join_keys(m.primary_key_values)
|
397
439
|
files.select(:id, :name).where(owner: owner, model: m.model.name, field: v.to_s).all.each do |entry|
|
398
440
|
File.delete("#{files_dir}/#{entry[:name]}_#{entry[:id]}")
|
399
441
|
end
|
data/lib/engine2/models/Files.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
E2DB.create_table :files do
|
@@ -13,6 +14,8 @@ module Engine2
|
|
13
14
|
|
14
15
|
class E2Files < Sequel::Model(E2DB[:files])
|
15
16
|
extend Engine2::Model
|
17
|
+
model_icon :'file'
|
18
|
+
model_route :E2Files
|
16
19
|
|
17
20
|
type_info do
|
18
21
|
# list_select :model, Hash[@model.db.models.keys.map{|m| [m, m]}]
|
@@ -28,7 +31,7 @@ module Engine2
|
|
28
31
|
search_live
|
29
32
|
|
30
33
|
on_change :model do |req, value|
|
31
|
-
#
|
34
|
+
# node.parent.*.assets[:model].select(:field).where(model: value).all.map{|rec|f = rec.values[:field]; [f, f]}
|
32
35
|
# render :field, list: {a: 1, b: 2}.to_a
|
33
36
|
end
|
34
37
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
class UserInfo < Sequel::Model(DUMMYDB)
|
@@ -6,15 +7,17 @@ module Engine2
|
|
6
7
|
extend MemoryModel
|
7
8
|
|
8
9
|
type_info do
|
9
|
-
string_field :name,
|
10
|
+
string_field :name, 100
|
10
11
|
required :name, LOCS[:user_required]
|
11
|
-
string_field :password,
|
12
|
+
string_field :password, 100
|
12
13
|
required :password, LOCS[:password_required]
|
13
14
|
password :password
|
14
15
|
end
|
15
16
|
|
16
17
|
def to_hash
|
17
|
-
|
18
|
+
hash = @values.dup
|
19
|
+
hash.delete(:password)
|
20
|
+
hash
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Sequel
|
4
5
|
module SequelFixes
|
@@ -8,7 +9,7 @@ module Sequel
|
|
8
9
|
when Sequel::SQL::QualifiedIdentifier
|
9
10
|
sel.column
|
10
11
|
when Sequel::SQL::AliasedExpression
|
11
|
-
Sequel::SQL::Identifier.new sel.
|
12
|
+
Sequel::SQL::Identifier.new sel.alias
|
12
13
|
else
|
13
14
|
sel # symbol ?
|
14
15
|
end
|
@@ -31,10 +32,10 @@ module Sequel
|
|
31
32
|
columns = SequelFixes.fix_aliased_expression(clone(:append_sql=>'', :placeholder_literal_null=>true))
|
32
33
|
dsa1 = dataset_alias(1)
|
33
34
|
rn = row_number_column
|
34
|
-
sql = @opts[:append_sql] ||
|
35
|
+
sql = @opts[:append_sql] || String.new
|
35
36
|
subselect_sql_append(sql, unlimited.
|
36
37
|
unordered.
|
37
|
-
select_append{ROW_NUMBER
|
38
|
+
select_append{:ROW_NUMBER.sql_function.over(:order=>order).as(rn)}.
|
38
39
|
from_self(:alias=>dsa1).
|
39
40
|
select(*columns).
|
40
41
|
limit(@opts[:limit]).
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Sequel
|
4
5
|
class JDBC::Database
|
@@ -23,13 +24,16 @@ module Sequel
|
|
23
24
|
rs.getInt(1)
|
24
25
|
end
|
25
26
|
end
|
27
|
+
|
28
|
+
def valid_connection_sql
|
29
|
+
'select 1 from sysibm.sysdummy1'
|
30
|
+
end
|
26
31
|
end if defined?(JDBC::AS400)
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
33
|
+
class JDBC::AS400::Dataset
|
34
|
+
def supports_where_true?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end if defined?(JDBC::AS400)
|
34
38
|
|
35
39
|
end if defined? JRUBY_VERSION
|
data/lib/engine2/scheme.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
class Schemes
|
5
6
|
CRUD ||= {create: true, view: true, modify: true, delete: true}.freeze # bulk_delete: true
|
6
7
|
VIEW ||= {view: true}.freeze
|
7
8
|
LINK ||= {star_to_many_link: true, view: true, star_to_many_unlink: true}.freeze # star_to_many_bulk_unlink: true
|
9
|
+
STMF_CRUD ||= {star_to_many_field_create: true, star_to_many_field_view: true, star_to_many_field_modify: true, star_to_many_field_delete: true}.freeze
|
10
|
+
STMF_VIEW ||= {star_to_many_field_view: true}.freeze
|
11
|
+
STMF_LINK ||= {star_to_many_field_view: true, star_to_many_field_link: true ,star_to_many_field_unlink: true, star_to_many_field_link_list: true}.freeze
|
8
12
|
|
9
13
|
attr_reader :builtin, :user
|
10
14
|
def initialize
|
@@ -29,50 +33,52 @@ module Engine2
|
|
29
33
|
SCHEMES.builtin.clear
|
30
34
|
SCHEMES.instance_eval do
|
31
35
|
|
36
|
+
define_scheme :confirm do |name, action, options|
|
37
|
+
define_node :"confirm_#{name}", ConfirmAction do
|
38
|
+
self.*.panel_title options[:title]
|
39
|
+
self.*.message options[:message]
|
40
|
+
define_node name, action
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
32
44
|
define_scheme :view do |name = :view|
|
33
|
-
|
45
|
+
define_node name, ViewAction
|
34
46
|
end
|
35
47
|
|
36
48
|
define_scheme :create do |name = :create|
|
37
|
-
|
38
|
-
|
49
|
+
define_node name, CreateAction do
|
50
|
+
define_node :approve, InsertAction
|
39
51
|
end
|
40
52
|
end
|
41
53
|
|
42
54
|
define_scheme :modify do |name = :modify|
|
43
|
-
|
44
|
-
|
55
|
+
define_node name, ModifyAction do
|
56
|
+
define_node :approve, UpdateAction
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
48
60
|
define_scheme :delete do
|
49
|
-
|
50
|
-
|
51
|
-
self.*.panel_title LOCS[:confirm_delete_title]
|
52
|
-
define_action :delete, DeleteMeta
|
53
|
-
end
|
61
|
+
run_scheme :confirm, :delete, DeleteAction,
|
62
|
+
message: LOCS[:delete_question], title: LOCS[:confirm_delete_title]
|
54
63
|
end
|
55
64
|
|
56
65
|
define_scheme :bulk_delete do
|
57
|
-
|
58
|
-
|
59
|
-
self.*.panel_title LOCS[:confirm_bulk_delete_title]
|
60
|
-
define_action :bulk_delete, BulkDeleteMeta
|
61
|
-
end
|
66
|
+
run_scheme :confirm, :bulk_delete, BulkDeleteAction,
|
67
|
+
message: LOCS[:delete_question], title: LOCS[:confirm_bulk_delete_title]
|
62
68
|
end
|
63
69
|
|
64
70
|
define_scheme :default do |name, model, options|
|
65
71
|
options ||= Schemes::CRUD
|
66
|
-
|
72
|
+
define_node name, ListAction, model: model do
|
67
73
|
options.each{|k, v| run_scheme(k) if v}
|
68
74
|
|
69
|
-
|
70
|
-
#
|
75
|
+
define_node_bundle :form, :create, :modify if options[:create] && options[:modify]
|
76
|
+
# define_node_bundle :decode, :decode_entry, :decode_list, :typahead
|
71
77
|
|
72
78
|
# if ?
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
define_node :decode_entry, DecodeEntryAction
|
80
|
+
define_node :decode_list, DecodeListAction
|
81
|
+
define_node :typeahead, TypeAheadAction
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
@@ -80,7 +86,7 @@ module Engine2
|
|
80
86
|
# Many to One
|
81
87
|
#
|
82
88
|
define_scheme :many_to_one do
|
83
|
-
|
89
|
+
define_node :list, ManyToOneListAction do
|
84
90
|
run_scheme :view
|
85
91
|
end
|
86
92
|
end
|
@@ -89,18 +95,18 @@ module Engine2
|
|
89
95
|
assoc = model.association_reflections[assoc_name]
|
90
96
|
::Kernel::raise E2Error.new("Association '#{assoc_name}' not found for model '#{model}'") unless assoc
|
91
97
|
|
92
|
-
if self.*.assets[:model] != model && self.*.is_a?(
|
98
|
+
if self.*.assets[:model] != model && self.*.is_a?(ListAction)
|
93
99
|
# verify relations ?
|
94
100
|
mdl = assoc[:model]
|
95
101
|
info = mdl.type_info[assoc[:keys].first]
|
96
102
|
options = info[:decode][:search]
|
97
103
|
end
|
98
104
|
|
99
|
-
|
105
|
+
define_node :"#{assoc_name}!" do
|
100
106
|
# iterate over options like in :default ?
|
101
|
-
|
102
|
-
|
103
|
-
|
107
|
+
define_node :list, DecodeListAction, assoc: assoc if options[:list]
|
108
|
+
define_node :typeahead, TypeAheadAction, assoc: assoc if options[:typeahead]
|
109
|
+
define_node :decode, DecodeEntryAction, assoc: assoc do
|
104
110
|
run_scheme :many_to_one
|
105
111
|
end if options[:scaffold]
|
106
112
|
end
|
@@ -110,34 +116,28 @@ module Engine2
|
|
110
116
|
# * to Many
|
111
117
|
#
|
112
118
|
define_scheme :star_to_many_unlink do
|
113
|
-
|
114
|
-
|
115
|
-
self.*.panel_title LOCS[:confirm_unlink_title]
|
116
|
-
define_action :unlink, StarToManyUnlinkMeta
|
117
|
-
end
|
119
|
+
run_scheme :confirm, :unlink, StarToManyUnlinkAction,
|
120
|
+
message: LOCS[:unlink_question], title: LOCS[:confirm_unlink_title]
|
118
121
|
end
|
119
122
|
|
120
123
|
define_scheme :star_to_many_bulk_unlink do
|
121
|
-
|
122
|
-
|
123
|
-
self.*.panel_title LOCS[:confirm_bulk_unlink_title]
|
124
|
-
define_action :bulk_unlink, StarToManyBulkUnlinkMeta
|
125
|
-
end
|
124
|
+
run_scheme :confirm, :bulk_unlink, StarToManyBulkUnlinkAction,
|
125
|
+
message: LOCS[:unlink_question], title: LOCS[:confirm_bulk_unlink_title]
|
126
126
|
end
|
127
127
|
|
128
128
|
define_scheme :star_to_many_link do
|
129
|
-
|
129
|
+
define_node :link_list, StarToManyLinkListAction do
|
130
130
|
run_scheme :view
|
131
|
-
|
131
|
+
define_node :link, StarToManyLinkAction
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
define_scheme :star_to_many do |
|
135
|
+
define_scheme :star_to_many do |assoc_name, assoc, model|
|
136
|
+
action.menu(:item_menu).option assoc_name, icon: Kernel::const_get(assoc[:class_name]).model_icon # , click: "action.show_assoc($index, \"#{assoc_name}!\")"
|
136
137
|
options = assoc[:options] || Schemes::LINK
|
137
|
-
|
138
|
+
define_node assoc_name, StarToManyListAction, model: model, assoc: assoc do
|
138
139
|
options.each{|k, v| run_scheme(k) if v}
|
139
|
-
|
140
|
-
define_action_bundle :form, :create, :modify if options[:create] && options[:modify]
|
140
|
+
define_node_bundle :form, :create, :modify if options[:create] && options[:modify]
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
@@ -145,11 +145,11 @@ module Engine2
|
|
145
145
|
# arbitrary files per form
|
146
146
|
#
|
147
147
|
define_scheme :file_store do |model, field|
|
148
|
-
|
148
|
+
define_node :"#{field}_file_store!", FileStoreAction do
|
149
149
|
self.*.model = model
|
150
150
|
self.*.field = field
|
151
|
-
|
152
|
-
|
151
|
+
define_node :download, DownloadFileStoreAction
|
152
|
+
define_node :upload, UploadFileStoreAction
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -157,11 +157,11 @@ module Engine2
|
|
157
157
|
# blob field in source table
|
158
158
|
#
|
159
159
|
define_scheme :blob_store do |model, field|
|
160
|
-
|
160
|
+
define_node :"#{field}_blob_store!", BlobStoreAction do
|
161
161
|
self.*.model = model
|
162
|
-
self.*.field = field
|
163
|
-
|
164
|
-
|
162
|
+
self.*.field = field
|
163
|
+
define_node :download, DownloadBlobStoreAction
|
164
|
+
define_node :upload, UploadBlobStoreAction
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -169,29 +169,71 @@ module Engine2
|
|
169
169
|
# blob field in foreign (one to one) table
|
170
170
|
#
|
171
171
|
define_scheme :foreign_blob_store do |model, field|
|
172
|
-
|
172
|
+
define_node :"#{field}_blob_store!", ForeignBlobStoreAction do
|
173
173
|
self.*.model = model
|
174
|
-
self.*.field = field
|
175
|
-
|
176
|
-
|
174
|
+
self.*.field = field
|
175
|
+
define_node :download, DownloadForeignBlobStoreAction
|
176
|
+
define_node :upload, UploadBlobStoreAction
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
define_scheme :
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
180
|
+
define_scheme :star_to_many_field_view do
|
181
|
+
define_node :view, ViewAction do
|
182
|
+
action{@action_type = :star_to_many_field_view}
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
define_scheme :star_to_many_field_link do
|
187
|
+
define_node :link, StarToManyLinkAction
|
188
|
+
end
|
189
|
+
|
190
|
+
define_scheme :star_to_many_field_unlink do
|
191
|
+
define_node :confirm_unlink, ConfirmAction do
|
192
|
+
self.*.message LOCS[:unlink_question]
|
193
|
+
define_node :unlink, StarToManyUnlinkAction do
|
194
|
+
action{@action_type = :star_to_many_field_unlink}
|
189
195
|
end
|
190
196
|
end
|
191
197
|
end
|
192
198
|
|
193
|
-
define_scheme :
|
194
|
-
|
199
|
+
define_scheme :star_to_many_field_link_list do
|
200
|
+
define_node :link_list, StarToManyFieldLinkListAction do
|
201
|
+
run_scheme :view
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# *_to_many_field
|
207
|
+
#
|
208
|
+
define_scheme :star_to_many_field do |assoc, field|
|
209
|
+
schemes = assoc[:model].type_info.fetch(field)[:schemes]
|
210
|
+
define_node :"#{field}!", StarToManyFieldAction, assoc: assoc do
|
211
|
+
schemes.each{|k, v| run_scheme(k) if v}
|
212
|
+
|
213
|
+
define_node_bundle :form, :star_to_many_field_create, :star_to_many_field_modify if schemes[:star_to_many_field_create] && schemes[:star_to_many_field_modify]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
define_scheme :star_to_many_field_create do
|
218
|
+
define_node :create, CreateAction do
|
219
|
+
define_node :approve, StarToManyFieldInsertAction
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
define_scheme :star_to_many_field_modify do
|
224
|
+
define_node :modify, ModifyAction do
|
225
|
+
action{@action_type = :star_to_many_field_modify}
|
226
|
+
define_node :approve, StarToManyFieldUpdateAction
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
define_scheme :star_to_many_field_delete do
|
231
|
+
define_node :confirm_delete, ConfirmAction do
|
232
|
+
self.*.message LOCS[:delete_question]
|
233
|
+
self.*.panel_title LOCS[:confirm_delete_title]
|
234
|
+
define_node :delete, DeleteAction do
|
235
|
+
action{@action_type = :star_to_many_field_delete}
|
236
|
+
end
|
195
237
|
end
|
196
238
|
end
|
197
239
|
end
|