engine2 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/app/actions.coffee +93 -58
- data/app/app.css +12 -0
- data/app/engine2.coffee +42 -24
- data/conf/message.yaml +1 -0
- data/conf/message_pl.yaml +1 -0
- data/config.coffee +2 -2
- data/engine2.gemspec +1 -1
- data/lib/engine2/action.rb +130 -126
- data/lib/engine2/action/array.rb +4 -4
- data/lib/engine2/action/decode.rb +13 -9
- data/lib/engine2/action/infra.rb +3 -3
- data/lib/engine2/action/list.rb +17 -10
- data/lib/engine2/action_node.rb +1 -2
- data/lib/engine2/core.rb +35 -7
- data/lib/engine2/model.rb +64 -15
- data/lib/engine2/post_bootstrap.rb +1 -1
- data/lib/engine2/pre_bootstrap.rb +10 -0
- data/lib/engine2/scheme.rb +2 -2
- data/lib/engine2/templates.rb +8 -0
- data/lib/engine2/type_info.rb +37 -15
- data/lib/engine2/version.rb +1 -1
- data/package.json +8 -5
- 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_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 +4 -4
- 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_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 +1 -1
- 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 +3 -3
- data/views/fields/time.slim +5 -4
- data/views/fields/typeahead_picker.slim +5 -5
- data/views/scaffold/fields.slim +4 -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/search.slim +2 -2
- data/views/scaffold/search_collapse.slim +6 -5
- data/views/scaffold/search_tabs.slim +4 -3
- 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_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_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 +4 -4
- metadata +6 -5
data/lib/engine2/action/array.rb
CHANGED
@@ -45,7 +45,7 @@ module Engine2
|
|
45
45
|
|
46
46
|
if order_str = params[:order]
|
47
47
|
order = order_str.to_sym
|
48
|
-
handler.permit lookup(:
|
48
|
+
handler.permit lookup(:fields, order, :sort)
|
49
49
|
entries = entries.sort_by{|e|e[order].to_s}
|
50
50
|
entries = entries.reverse if params[:asc] == "true"
|
51
51
|
end
|
@@ -60,14 +60,14 @@ module Engine2
|
|
60
60
|
def list_search entries, handler, search
|
61
61
|
hash = JSON.parse(search, symbolize_names: true) rescue handler.halt_forbidden
|
62
62
|
model = assets[:model]
|
63
|
-
sfields = lookup(:
|
63
|
+
sfields = lookup(:search_field_list)
|
64
64
|
handler.permit sfields
|
65
65
|
hash.each_pair do |name, value|
|
66
66
|
handler.permit sfields.include?(name)
|
67
67
|
|
68
|
-
type_info =
|
68
|
+
type_info = model.find_type_info(name)
|
69
69
|
entries = if filter = (@filters && @filters[name]) || (dynamic? && (static.filters && static.filters[name]))
|
70
|
-
filter.(entries, hash
|
70
|
+
filter.(handler, entries, hash)
|
71
71
|
elsif filter = DefaultFilters[type_info[:otype]]
|
72
72
|
filter.(entries, name, value, type_info, hash)
|
73
73
|
else
|
@@ -19,8 +19,8 @@ module Engine2
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def post_process
|
22
|
-
if fields = @meta[:
|
23
|
-
fields = fields - static.meta[:
|
22
|
+
if fields = @meta[:field_list]
|
23
|
+
fields = fields - static.meta[:field_list] if dynamic?
|
24
24
|
# no decorate here
|
25
25
|
fields.each do |name|
|
26
26
|
type_info = assets[:model].type_info[name] # foreign keys ?
|
@@ -55,7 +55,7 @@ module Engine2
|
|
55
55
|
action_type :decode_list
|
56
56
|
|
57
57
|
def invoke handler
|
58
|
-
{entries: get_query.limit(200).
|
58
|
+
{entries: get_query.limit(200).load_all}
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -64,20 +64,24 @@ module Engine2
|
|
64
64
|
|
65
65
|
def pre_run
|
66
66
|
super
|
67
|
-
limit 10
|
67
|
+
@limit = 10
|
68
68
|
end
|
69
69
|
|
70
70
|
def limit lmt
|
71
|
-
@
|
71
|
+
@limit = lmt
|
72
|
+
end
|
73
|
+
|
74
|
+
def case_insensitive
|
75
|
+
@case_insensitive = true
|
72
76
|
end
|
73
77
|
|
74
78
|
def invoke handler
|
75
79
|
if query = handler.params[:query]
|
76
|
-
condition = @meta[:decode_fields].map{|f|f.like("%#{query}%")}.reduce{|q, f| q | f}
|
77
|
-
{entries: get_query.where(condition).limit(@
|
80
|
+
condition = @meta[:decode_fields].map{|f|f.like("%#{query}%", case_insensitive: @case_insensitive)}.reduce{|q, f| q | f}
|
81
|
+
{entries: get_query.where(condition).limit(@limit).load_all}
|
78
82
|
else
|
79
83
|
handler.permit id = handler.params[:id]
|
80
|
-
record = get_query
|
84
|
+
record = get_query.load Hash[assets[:model].primary_keys.zip(split_keys(id))]
|
81
85
|
# handler.halt_not_found(LOCS[:no_entry]) unless record
|
82
86
|
{entry: record}
|
83
87
|
end
|
@@ -92,7 +96,7 @@ module Engine2
|
|
92
96
|
end
|
93
97
|
|
94
98
|
def invoke_decode handler, ids
|
95
|
-
records = get_query.where(ids.map{|keys| Hash[assets[:model].primary_keys.zip(keys)]}.reduce{|q, c| q | c}).
|
99
|
+
records = get_query.where(ids.map{|keys| Hash[assets[:model].primary_keys.zip(keys)]}.reduce{|q, c| q | c}).load_all
|
96
100
|
# handler.halt_not_found(LOCS[:no_entry]) if records.empty?
|
97
101
|
records
|
98
102
|
end
|
data/lib/engine2/action/infra.rb
CHANGED
@@ -263,9 +263,9 @@ module Engine2
|
|
263
263
|
super
|
264
264
|
panel_class 'modal-default'
|
265
265
|
panel_title LOCS[:login_title]
|
266
|
-
|
266
|
+
fields! :name, loc: LOCS[:user_name]
|
267
267
|
menu(:panel_menu).modify_option :approve, name: :login, icon: :"log-in"
|
268
|
-
@meta[:
|
268
|
+
@meta[:field_list] = [:name, :password]
|
269
269
|
parent_action = node.parent.*
|
270
270
|
if parent_action.is_a? ActionMenuSupport
|
271
271
|
parent_action.menu(:menu).option :login_form, icon: :"log-in", disabled: "action.action_pending()"
|
@@ -281,7 +281,7 @@ module Engine2
|
|
281
281
|
include ActionApproveSupport
|
282
282
|
action_type :login
|
283
283
|
|
284
|
-
def validate_record handler, record
|
284
|
+
def validate_record handler, record, parent_id
|
285
285
|
super
|
286
286
|
record.values[:password] = nil
|
287
287
|
end
|
data/lib/engine2/action/list.rb
CHANGED
@@ -9,6 +9,9 @@ module Engine2
|
|
9
9
|
(DefaultFilters ||= {}).merge!(
|
10
10
|
string: lambda{|query, name, value, type_info, hash|
|
11
11
|
case type_info[:type]
|
12
|
+
when :list_select
|
13
|
+
raise E2Error.new("Filter unimplemented for string multi list_select, field: '#{name.to_sym}'") if type_info[:multiselect] # todo
|
14
|
+
query.where(name => value)
|
12
15
|
when :many_to_one
|
13
16
|
query.where(name => value)
|
14
17
|
else
|
@@ -39,8 +42,8 @@ module Engine2
|
|
39
42
|
else
|
40
43
|
query.where(from ? name >= from.to_i : name <= to.to_i)
|
41
44
|
end
|
42
|
-
elsif value.is_a?
|
43
|
-
query.where(name => value)
|
45
|
+
elsif value.is_a?(Integer) || value.is_a?(String)
|
46
|
+
query.where(name => value.to_i)
|
44
47
|
elsif value.is_a? Array
|
45
48
|
if !value.empty?
|
46
49
|
case type_info[:type]
|
@@ -52,7 +55,11 @@ module Engine2
|
|
52
55
|
query.where(keys.map{|k| hash[k]}.transpose.map{|vals| Hash[keys.zip(vals)]}.reduce{|q, c| q | c})
|
53
56
|
end
|
54
57
|
when :list_select
|
55
|
-
|
58
|
+
if type_info[:multiselect]
|
59
|
+
query.where(~{(name.sql_number & value.reduce(0, :|)) => 0})
|
60
|
+
else
|
61
|
+
query.where(name => value) # decode in sql query ?
|
62
|
+
end
|
56
63
|
when :integer
|
57
64
|
query
|
58
65
|
else
|
@@ -88,10 +95,10 @@ module Engine2
|
|
88
95
|
|
89
96
|
if order_str = params[:order]
|
90
97
|
order = order_str.to_sym
|
91
|
-
handler.permit lookup(:
|
98
|
+
handler.permit lookup(:fields, order, :sort)
|
92
99
|
|
93
100
|
if order_blk = (@orders && @orders[order]) || (dynamic? && (static.orders && static.orders[order]))
|
94
|
-
query = order_blk.(
|
101
|
+
query = order_blk.(handler, query)
|
95
102
|
else
|
96
103
|
order = model.table_name.q(order) if model.type_info[order]
|
97
104
|
query = query.order(order)
|
@@ -106,7 +113,7 @@ module Engine2
|
|
106
113
|
|
107
114
|
query = query.limit(per_page, page)
|
108
115
|
|
109
|
-
res = {entries: query.
|
116
|
+
res = {entries: query.load_all}
|
110
117
|
res[:count] = count if count
|
111
118
|
res
|
112
119
|
end
|
@@ -114,14 +121,14 @@ module Engine2
|
|
114
121
|
def list_search query, handler, search
|
115
122
|
hash = JSON.parse(search, symbolize_names: true) rescue handler.halt_forbidden
|
116
123
|
model = assets[:model]
|
117
|
-
sfields = lookup(:
|
124
|
+
sfields = lookup(:search_field_list)
|
118
125
|
handler.permit sfields
|
119
126
|
hash.each_pair do |name, value|
|
120
127
|
handler.permit name = sfields.find{|sf|sf.to_sym == name}
|
121
128
|
|
122
|
-
type_info =
|
129
|
+
type_info = model.find_type_info(name)
|
123
130
|
query = if filter = (@filters && @filters[name]) || (dynamic? && (static.filters && static.filters[name]))
|
124
|
-
filter.(query, hash
|
131
|
+
filter.(handler, query, hash)
|
125
132
|
elsif filter = DefaultFilters[type_info[:otype]]
|
126
133
|
name = model.type_info[name] ? model.table_name.q(name) : Sequel.expr(name)
|
127
134
|
filter.(query, name, value, type_info, hash)
|
@@ -205,7 +212,7 @@ module Engine2
|
|
205
212
|
if h.initial? && nd = node.parent.nodes[:decode_entry]
|
206
213
|
action = nd.*
|
207
214
|
rec = action.invoke_decode(h, [[h.params[:parent_id]]]).first
|
208
|
-
panel_title "#{static.panel[:title]} - #{rec}"
|
215
|
+
panel_title "#{static.panel[:title]} - #{action.meta[:decode_fields].map{|f|rec[f]}.join(action.meta[:separator])}"
|
209
216
|
end
|
210
217
|
end
|
211
218
|
end
|
data/lib/engine2/action_node.rb
CHANGED
@@ -38,7 +38,7 @@ module Engine2
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def check_access! handler
|
41
|
-
|
41
|
+
!@access_block || @access_block.(handler)
|
42
42
|
end
|
43
43
|
|
44
44
|
def run_scheme name, *args, &blk
|
@@ -162,7 +162,6 @@ module Engine2
|
|
162
162
|
each_node do |node|
|
163
163
|
if model = node.*.assets[:model]
|
164
164
|
model_name = model.name.to_sym
|
165
|
-
model.synchronize_type_info
|
166
165
|
model_nodes[model_name] = node.to_a_rec{|a| !a.*.assets[:assoc]}
|
167
166
|
node.run_scheme(model_name) if SCHEMES[model_name, false]
|
168
167
|
false
|
data/lib/engine2/core.rb
CHANGED
@@ -328,6 +328,33 @@ module E2Model
|
|
328
328
|
end
|
329
329
|
|
330
330
|
module DatasetMethods
|
331
|
+
def load *args
|
332
|
+
if entry = self[*args]
|
333
|
+
model.after_load_processors.each do |name, proc|
|
334
|
+
type_info = model.find_type_info(name)
|
335
|
+
name_sym = name.to_sym
|
336
|
+
proc.(entry, name_sym, type_info) if entry.key?(name_sym)
|
337
|
+
end if model.after_load_processors
|
338
|
+
entry
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def load_all
|
343
|
+
entries = self.all
|
344
|
+
apply_after_load_processors(model, entries) if model.after_load_processors
|
345
|
+
entries
|
346
|
+
end
|
347
|
+
|
348
|
+
def apply_after_load_processors model, entries
|
349
|
+
model.after_load_processors.each do |name, proc|
|
350
|
+
type_info = model.find_type_info(name)
|
351
|
+
name_sym = name.to_sym
|
352
|
+
entries.each do |entry|
|
353
|
+
proc.(entry, name_sym, type_info) if entry.key?(name_sym)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
331
358
|
def ensure_primary_key
|
332
359
|
pk = model.primary_keys
|
333
360
|
raise Engine2::E2Error.new("No primary key defined for model #{model}") unless pk && pk.all?
|
@@ -376,12 +403,12 @@ module E2Model
|
|
376
403
|
end
|
377
404
|
end
|
378
405
|
|
379
|
-
def
|
406
|
+
def setup_query fields
|
380
407
|
joins = {}
|
381
408
|
type_info = model.type_info
|
382
409
|
model_table_name = model.table_name
|
383
410
|
|
384
|
-
|
411
|
+
select = @opts[:select].map do |sel|
|
385
412
|
extract_select sel do |table, name, aliaz|
|
386
413
|
info = if table
|
387
414
|
if table == model_table_name
|
@@ -416,11 +443,9 @@ module E2Model
|
|
416
443
|
end
|
417
444
|
end
|
418
445
|
end
|
419
|
-
end
|
446
|
+
end.compact
|
420
447
|
|
421
|
-
|
422
|
-
|
423
|
-
joins.reduce(self) do |joined, (table, assoc)|
|
448
|
+
joins.reduce(clone(select: select)) do |joined, (table, assoc)|
|
424
449
|
m = assoc.associated_class
|
425
450
|
case assoc[:type]
|
426
451
|
when :many_to_one
|
@@ -521,7 +546,10 @@ module Engine2
|
|
521
546
|
load 'engine2/models/UserInfo.rb'
|
522
547
|
Dir["#{Engine2::SETTINGS.path_for(:model_path)}/*"].each{|m| load m}
|
523
548
|
puts "MODELS: #{Sequel::DATABASES.reduce(0){|s, d|s + d.models.size}}, Time: #{Time.now - t}"
|
524
|
-
Sequel::DATABASES.each
|
549
|
+
Sequel::DATABASES.each do |db|
|
550
|
+
db.dump_schema_cache_to_file
|
551
|
+
db.models.each{|n, m|m.synchronize_type_info}
|
552
|
+
end
|
525
553
|
|
526
554
|
send(:remove_const, :ROOT) if defined? ROOT
|
527
555
|
const_set(:ROOT, ActionNode.new(nil, :api, RootAction, {}))
|
data/lib/engine2/model.rb
CHANGED
@@ -5,7 +5,7 @@ module Engine2
|
|
5
5
|
module Model
|
6
6
|
attr_reader :dummies
|
7
7
|
attr_reader :many_to_one_associations, :one_to_many_associations, :many_to_many_associations #, :one_to_one_associations
|
8
|
-
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
|
9
9
|
attr_reader :validation_in_transaction
|
10
10
|
|
11
11
|
def self.extended cls
|
@@ -19,6 +19,7 @@ module Engine2
|
|
19
19
|
@many_to_many_associations = association_reflections.select{|n, a| a[:type] == :many_to_many}
|
20
20
|
# @one_to_one_associations = association_reflections.select{|n, a| a[:type] == :one_to_one}
|
21
21
|
@validation_in_transaction = nil
|
22
|
+
@after_load_processors = nil
|
22
23
|
@before_save_processors = nil
|
23
24
|
@after_save_processors = nil
|
24
25
|
@around_save_processors = nil
|
@@ -109,9 +110,27 @@ module Engine2
|
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
113
|
+
def find_type_info name
|
114
|
+
model = self
|
115
|
+
info = case name
|
116
|
+
when Symbol
|
117
|
+
model.type_info[name]
|
118
|
+
when Sequel::SQL::QualifiedIdentifier
|
119
|
+
assoc = model.many_to_one_associations[name.table] || model.many_to_many_associations[name.table]
|
120
|
+
raise E2Error.new("Association #{name.table} not found for model #{model}") unless assoc
|
121
|
+
assoc.associated_class.type_info[name.column]
|
122
|
+
else
|
123
|
+
raise E2Error.new("Unknown type info key: #{name} in model #{model}")
|
124
|
+
end
|
125
|
+
|
126
|
+
raise E2Error.new("Type info not found for '#{name}' in model '#{model}'") unless info
|
127
|
+
info
|
128
|
+
end
|
129
|
+
|
112
130
|
def synchronize_type_info
|
113
131
|
resolve_dependencies
|
114
132
|
verify_associations
|
133
|
+
@after_load_processors = install_processors(AfterLoadProcessors)
|
115
134
|
@before_save_processors = install_processors(BeforeSaveProcessors)
|
116
135
|
@after_save_processors = install_processors(AfterSaveProcessors)
|
117
136
|
@around_save_processors = {}
|
@@ -120,18 +139,6 @@ module Engine2
|
|
120
139
|
@type_info_synchronized = true
|
121
140
|
end
|
122
141
|
|
123
|
-
def verify_associations
|
124
|
-
one_to_many_associations.each do |name, assoc|
|
125
|
-
other = assoc.associated_class
|
126
|
-
other_type_info = other.type_info
|
127
|
-
if other_keys = assoc[:keys]
|
128
|
-
other_keys.each do |key|
|
129
|
-
raise E2Error.new("No key '#{key}' found in model '#{other}' being related from #{self}") unless other_type_info[key]
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
142
|
def resolve_dependencies
|
136
143
|
resolved = {}
|
137
144
|
@type_info.each_pair do |name, info|
|
@@ -153,6 +160,18 @@ module Engine2
|
|
153
160
|
resolved[name] = @type_info[name]
|
154
161
|
end
|
155
162
|
|
163
|
+
def verify_associations
|
164
|
+
one_to_many_associations.each do |name, assoc|
|
165
|
+
other = assoc.associated_class
|
166
|
+
other_type_info = other.type_info
|
167
|
+
if other_keys = assoc[:keys]
|
168
|
+
other_keys.each do |key|
|
169
|
+
raise E2Error.new("No key '#{key}' found in model '#{other}' being related from #{self}") unless other_type_info[key]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
156
175
|
attr_reader :scheme_name, :scheme_args
|
157
176
|
|
158
177
|
def scheme s_name = :default, opts = nil, &blk
|
@@ -272,7 +291,14 @@ module Engine2
|
|
272
291
|
},
|
273
292
|
list_select: lambda{|record, field, info|
|
274
293
|
value = record.values[field]
|
275
|
-
|
294
|
+
values = info[:values].map(&:first)
|
295
|
+
|
296
|
+
result = if info[:multiselect]
|
297
|
+
value.is_a?(Array) && (values - value).length == values.length - value.length
|
298
|
+
else
|
299
|
+
values.include?(value)
|
300
|
+
end
|
301
|
+
LOCS[:invalid_list_value] unless result
|
276
302
|
},
|
277
303
|
decimal: lambda{|record, field, info|
|
278
304
|
value = record.values[field]
|
@@ -300,6 +326,20 @@ module Engine2
|
|
300
326
|
}
|
301
327
|
)
|
302
328
|
|
329
|
+
(AfterLoadProcessors ||= {}).merge!(
|
330
|
+
list_select: lambda{|record, field, info|
|
331
|
+
value = record[field]
|
332
|
+
record[field] = case info[:otype]
|
333
|
+
when :string
|
334
|
+
value.split(info[:separator])
|
335
|
+
when :integer
|
336
|
+
arr = []
|
337
|
+
value.bit_length.times{|i| arr << (1 << i) unless value[i].zero?}
|
338
|
+
arr
|
339
|
+
end if value && info[:multiselect]
|
340
|
+
}
|
341
|
+
)
|
342
|
+
|
303
343
|
(BeforeSaveProcessors ||= {}).merge!(
|
304
344
|
blob_store: lambda{|record, field, info|
|
305
345
|
if value = record.values[field] # attachment info
|
@@ -326,6 +366,15 @@ module Engine2
|
|
326
366
|
end
|
327
367
|
File.delete("#{upload}/#{value[:rackname]}")
|
328
368
|
end
|
369
|
+
},
|
370
|
+
list_select: lambda{|record, field, info|
|
371
|
+
value = record.values[field]
|
372
|
+
record[field] = case info[:otype]
|
373
|
+
when :string
|
374
|
+
value.join(info[:separator])
|
375
|
+
when :integer
|
376
|
+
value.reduce(0, :|)
|
377
|
+
end if value && info[:multiselect]
|
329
378
|
}
|
330
379
|
)
|
331
380
|
|
@@ -359,7 +408,7 @@ module Engine2
|
|
359
408
|
# record.model.where(id).update(info[:field] => Sequel.blob(open("#{upload}/#{value[:rackname]}", "rb"){|f|f.read}))
|
360
409
|
File.delete("#{upload}/#{value[:rackname]}")
|
361
410
|
end
|
362
|
-
}
|
411
|
+
},
|
363
412
|
)
|
364
413
|
|
365
414
|
(BeforeDestroyProcessors ||= {}).merge!(
|
@@ -24,6 +24,16 @@ module Sequel
|
|
24
24
|
rs.getInt(1)
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
def valid_connection_sql
|
29
|
+
'select 1 from sysibm.sysdummy1'
|
30
|
+
end
|
31
|
+
end if defined?(JDBC::AS400)
|
32
|
+
|
33
|
+
class JDBC::AS400::Dataset
|
34
|
+
def supports_where_true?
|
35
|
+
false
|
36
|
+
end
|
27
37
|
end if defined?(JDBC::AS400)
|
28
38
|
|
29
39
|
module SchemaCaching
|
data/lib/engine2/scheme.rb
CHANGED
@@ -163,7 +163,7 @@ module Engine2
|
|
163
163
|
define_scheme :blob_store do |model, field|
|
164
164
|
define_node :"#{field}_blob_store!", BlobStoreAction do
|
165
165
|
self.*.model = model
|
166
|
-
self.*.field = field
|
166
|
+
self.*.field = field
|
167
167
|
define_node :download, DownloadBlobStoreAction
|
168
168
|
define_node :upload, UploadBlobStoreAction
|
169
169
|
end
|
@@ -175,7 +175,7 @@ module Engine2
|
|
175
175
|
define_scheme :foreign_blob_store do |model, field|
|
176
176
|
define_node :"#{field}_blob_store!", ForeignBlobStoreAction do
|
177
177
|
self.*.model = model
|
178
|
-
self.*.field = field
|
178
|
+
self.*.field = field
|
179
179
|
define_node :download, DownloadForeignBlobStoreAction
|
180
180
|
define_node :upload, UploadBlobStoreAction
|
181
181
|
end
|