engine2 1.0.4 → 1.0.9
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.
- 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
|