engine2 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -0
- data/Rakefile +1 -1
- data/app/{engine2actions.coffee → actions.coffee} +192 -142
- data/app/app.coffee +0 -0
- data/app/app.css +4 -0
- data/app/engine2.coffee +87 -175
- data/app/modal.coffee +133 -0
- data/bower.json +2 -1
- data/conf/message.yaml +0 -0
- data/conf/message_pl.yaml +0 -0
- data/config.coffee +11 -2
- data/engine2.gemspec +2 -2
- data/lib/engine2.rb +12 -10
- data/lib/engine2/action.rb +1290 -134
- data/lib/engine2/{meta/array_meta.rb → action/array.rb} +4 -3
- data/lib/engine2/{meta/decode_meta.rb → action/decode.rb} +16 -15
- data/lib/engine2/action/delete.rb +65 -0
- data/lib/engine2/action/form.rb +16 -0
- data/lib/engine2/{meta/infra_meta.rb → action/infra.rb} +118 -85
- data/lib/engine2/action/link.rb +117 -0
- data/lib/engine2/{meta/list_meta.rb → action/list.rb} +61 -62
- data/lib/engine2/action/save.rb +30 -0
- data/lib/engine2/action/view.rb +8 -0
- data/lib/engine2/action_node.rb +221 -0
- data/lib/engine2/core.rb +120 -77
- data/lib/engine2/handler.rb +9 -10
- data/lib/engine2/model.rb +4 -20
- data/lib/engine2/models/Files.rb +2 -1
- data/lib/engine2/models/UserInfo.rb +6 -3
- data/lib/engine2/post_bootstrap.rb +3 -2
- data/lib/engine2/pre_bootstrap.rb +1 -0
- data/lib/engine2/scheme.rb +98 -47
- data/lib/engine2/templates.rb +1 -0
- data/lib/engine2/type_info.rb +6 -4
- data/lib/engine2/version.rb +2 -1
- data/package.json +12 -10
- 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 +0 -0
- data/views/fields/bs_select.slim +0 -0
- data/views/fields/bsselect_picker.slim +0 -0
- data/views/fields/bsselect_picker_opt.slim +0 -0
- data/views/fields/checkbox.slim +0 -0
- data/views/fields/checkbox_buttons.slim +0 -0
- data/views/fields/checkbox_buttons_opt.slim +0 -0
- data/views/fields/currency.slim +0 -0
- data/views/fields/date.slim +0 -0
- data/views/fields/date_range.slim +0 -0
- data/views/fields/date_time.slim +0 -0
- data/views/fields/datetime.slim +0 -0
- data/views/fields/decimal.slim +0 -0
- data/views/fields/decimal_date.slim +0 -0
- data/views/fields/decimal_time.slim +0 -0
- data/views/fields/email.slim +0 -0
- data/views/fields/file_store.slim +7 -7
- data/views/fields/input_text.slim +0 -0
- data/views/fields/integer.slim +0 -0
- data/views/fields/list_bsselect.slim +0 -0
- data/views/fields/list_bsselect_opt.slim +0 -0
- data/views/fields/list_buttons.slim +0 -0
- data/views/fields/list_buttons_opt.slim +0 -0
- data/views/fields/list_select.slim +0 -0
- data/views/fields/list_select_opt.slim +0 -0
- data/views/fields/password.slim +0 -0
- data/views/fields/radio_checkbox.slim +0 -0
- data/views/fields/scaffold.slim +0 -0
- data/views/fields/scaffold_picker.slim +0 -0
- data/views/fields/select_picker.slim +0 -0
- data/views/fields/select_picker_opt.slim +0 -0
- data/views/fields/text_area.slim +1 -0
- data/views/fields/time.slim +0 -0
- data/views/fields/typeahead_picker.slim +0 -0
- data/views/index.slim +3 -3
- data/views/infra/index.slim +0 -0
- data/views/infra/inspect.slim +20 -0
- 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 +0 -0
- data/views/scaffold/form.slim +0 -0
- data/views/scaffold/form_collapse.slim +0 -0
- data/views/scaffold/form_tabs.slim +0 -0
- data/views/scaffold/list.slim +0 -0
- data/views/scaffold/message.slim +0 -0
- data/views/scaffold/search.slim +0 -0
- data/views/scaffold/search_collapse.slim +0 -0
- data/views/scaffold/search_tabs.slim +0 -0
- data/views/scaffold/view.slim +0 -0
- data/views/scaffold/view_collapse.slim +0 -0
- data/views/scaffold/view_tabs.slim +0 -0
- data/views/search_fields/bsmselect_picker.slim +0 -0
- data/views/search_fields/bsselect_picker.slim +0 -0
- data/views/search_fields/checkbox.slim +0 -0
- data/views/search_fields/checkbox2.slim +0 -0
- data/views/search_fields/checkbox_buttons.slim +0 -0
- data/views/search_fields/date_range.slim +0 -0
- data/views/search_fields/decimal_date_range.slim +0 -0
- data/views/search_fields/input_text.slim +0 -0
- data/views/search_fields/integer.slim +0 -0
- data/views/search_fields/integer_range.slim +0 -0
- data/views/search_fields/list_bsmselect.slim +0 -0
- data/views/search_fields/list_bsselect.slim +0 -0
- data/views/search_fields/list_buttons.slim +0 -0
- data/views/search_fields/list_select.slim +0 -0
- data/views/search_fields/scaffold_picker.slim +0 -0
- data/views/search_fields/select_picker.slim +0 -0
- data/views/search_fields/typeahead_picker.slim +0 -0
- metadata +41 -42
- data/lib/engine2/meta.rb +0 -1216
- 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/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/core.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#coding: utf-8
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module PrettyJSON
|
4
5
|
def to_json_pretty
|
@@ -13,9 +14,19 @@ class BigDecimal
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
17
|
+
class Sequel::SQL::QualifiedIdentifier
|
18
|
+
def to_json(*)
|
19
|
+
"\"#{table}__#{column}\""
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_sym
|
23
|
+
:"#{table}__#{column}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
16
27
|
class Object
|
17
28
|
def instance_variables_hash
|
18
|
-
instance_variables.
|
29
|
+
instance_variables.reduce({}) do |h, i|
|
19
30
|
h[i] = instance_variable_get(i)
|
20
31
|
h
|
21
32
|
end
|
@@ -25,16 +36,24 @@ end
|
|
25
36
|
class Proc
|
26
37
|
def to_json(*)
|
27
38
|
loc = source_location
|
28
|
-
"\"#<Proc:#{loc.first[/\w+.rb/]}:#{loc.last}>\""
|
39
|
+
loc ? "\"#<Proc:#{loc.first[/\w+.rb/]}:#{loc.last}>\"" : '"source unknown"'
|
29
40
|
end
|
30
41
|
|
31
42
|
def chain &blk
|
32
|
-
|
43
|
+
prc = self
|
33
44
|
lambda do |obj|
|
34
|
-
obj.instance_eval(&
|
45
|
+
obj.instance_eval(&prc)
|
35
46
|
obj.instance_eval(&blk)
|
36
47
|
end
|
37
48
|
end
|
49
|
+
|
50
|
+
def chain_args &blk
|
51
|
+
prc = self
|
52
|
+
lambda do |*args|
|
53
|
+
instance_exec(*args, &prc)
|
54
|
+
instance_exec(*args, &blk)
|
55
|
+
end
|
56
|
+
end
|
38
57
|
end
|
39
58
|
|
40
59
|
class Hash
|
@@ -111,11 +130,27 @@ end
|
|
111
130
|
|
112
131
|
class Symbol
|
113
132
|
def icon
|
114
|
-
|
133
|
+
s = self
|
134
|
+
if s[0, 3] == 'fa_'
|
135
|
+
"<i class='fa fa-#{s[3 .. -1]}'></i>"
|
136
|
+
else
|
137
|
+
"<span class='glyphicon glyphicon-#{s}'></span>"
|
138
|
+
end
|
115
139
|
end
|
116
140
|
|
117
|
-
def
|
118
|
-
|
141
|
+
def q col
|
142
|
+
col.qualify self
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
module Faye
|
147
|
+
class WebSocket
|
148
|
+
module API
|
149
|
+
def send! msg
|
150
|
+
msg = msg.to_json if msg.is_a? Hash
|
151
|
+
send msg
|
152
|
+
end
|
153
|
+
end
|
119
154
|
end
|
120
155
|
end
|
121
156
|
|
@@ -125,13 +160,17 @@ class << Sequel
|
|
125
160
|
def split_keys id
|
126
161
|
id.split(Engine2::SETTINGS[:key_separator])
|
127
162
|
end
|
163
|
+
|
164
|
+
def join_keys keys
|
165
|
+
keys.join(Engine2::SETTINGS[:key_separator])
|
166
|
+
end
|
128
167
|
end
|
129
168
|
|
130
169
|
class Sequel::Database
|
131
170
|
attr_accessor :models, :default_schema
|
132
171
|
|
133
172
|
def cache_file
|
134
|
-
"#{Engine2::
|
173
|
+
"#{Engine2::SETTINGS.path_for(:db_path)}/#{opts[:orig_opts][:name]}.dump"
|
135
174
|
end
|
136
175
|
|
137
176
|
def load_schema_cache_from_file
|
@@ -144,7 +183,6 @@ class Sequel::Database
|
|
144
183
|
end
|
145
184
|
end
|
146
185
|
|
147
|
-
Sequel.quote_identifiers = false
|
148
186
|
Sequel.extension :core_extensions
|
149
187
|
Sequel::Inflections.clear
|
150
188
|
Sequel.alias_columns_in_joins = true
|
@@ -277,7 +315,7 @@ module E2Model
|
|
277
315
|
|
278
316
|
def primary_keys_qualified
|
279
317
|
# cache it ?
|
280
|
-
primary_keys.map{|k|
|
318
|
+
primary_keys.map{|k|table_name.q(k)}
|
281
319
|
end
|
282
320
|
|
283
321
|
def primary_keys_hash id
|
@@ -290,9 +328,8 @@ module E2Model
|
|
290
328
|
end
|
291
329
|
|
292
330
|
module DatasetMethods
|
293
|
-
|
294
331
|
def ensure_primary_key
|
295
|
-
pk =
|
332
|
+
pk = model.primary_keys
|
296
333
|
raise Engine2::E2Error.new("No primary key defined for model #{model}") unless pk && pk.all?
|
297
334
|
|
298
335
|
if opts_select = @opts[:select]
|
@@ -300,7 +337,7 @@ module E2Model
|
|
300
337
|
opts_select.each do |sel|
|
301
338
|
name = case sel
|
302
339
|
when Symbol
|
303
|
-
sel
|
340
|
+
sel
|
304
341
|
when Sequel::SQL::QualifiedIdentifier
|
305
342
|
sel.column
|
306
343
|
when Sequel::SQL::AliasedExpression
|
@@ -314,94 +351,85 @@ module E2Model
|
|
314
351
|
if pk.length == sel_pk.length
|
315
352
|
self
|
316
353
|
else
|
317
|
-
sels = (pk - sel_pk).map{|k|
|
354
|
+
sels = (pk - sel_pk).map{|k| model.table_name.q(k)}
|
318
355
|
select_more(*sels)
|
319
356
|
end
|
320
357
|
else
|
321
|
-
select(*pk.map{|k|
|
358
|
+
select(*pk.map{|k| model.table_name.q(k)})
|
322
359
|
end
|
323
360
|
|
324
361
|
end
|
325
362
|
|
363
|
+
def extract_select sel, al = nil, &blk
|
364
|
+
case sel
|
365
|
+
when Symbol
|
366
|
+
yield nil, sel, nil
|
367
|
+
when Sequel::SQL::QualifiedIdentifier
|
368
|
+
yield sel.table, sel.column, al
|
369
|
+
when Sequel::SQL::AliasedExpression, Sequel::SQL::Function
|
370
|
+
sel
|
371
|
+
# extract_select sel.expression, sel.aliaz, &blk
|
372
|
+
# expr = sel.expression
|
373
|
+
# yield expr.table, expr.column
|
374
|
+
else
|
375
|
+
raise Engine2::E2Error.new("Unknown selection #{sel}")
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
326
379
|
def setup! fields
|
327
380
|
joins = {}
|
328
381
|
type_info = model.type_info
|
329
382
|
model_table_name = model.table_name
|
330
383
|
|
331
|
-
@opts[:select].map
|
384
|
+
@opts[:select] = @opts[:select].map do |sel|
|
332
385
|
extract_select sel do |table, name, aliaz|
|
333
|
-
if table
|
386
|
+
info = if table
|
334
387
|
if table == model_table_name
|
335
|
-
|
388
|
+
model
|
336
389
|
else
|
337
|
-
|
338
|
-
raise Engine2::E2Error.new("Association #{table} not found for model #{model}") unless
|
339
|
-
|
340
|
-
end
|
341
|
-
# raise Engine2::E2Error.new("Model not found for table #{table} in model #{model}") unless m
|
342
|
-
info = m.type_info
|
390
|
+
assoc = model.many_to_one_associations[table] || model.many_to_many_associations[table]
|
391
|
+
raise Engine2::E2Error.new("Association #{table} not found for model #{model}") unless assoc
|
392
|
+
assoc.associated_class
|
393
|
+
end.type_info
|
343
394
|
else
|
344
|
-
|
395
|
+
type_info
|
345
396
|
end
|
346
397
|
|
347
|
-
f_info = info[name]
|
348
|
-
raise Engine2::E2Error.new("Column #{name} not found for table #{table || model_table_name}") unless f_info
|
349
|
-
|
350
398
|
table ||= model_table_name
|
351
|
-
|
352
399
|
if table == model_table_name
|
353
400
|
fields << name
|
354
401
|
else
|
355
|
-
fields <<
|
356
|
-
joins[table]
|
402
|
+
fields << table.q(name)
|
403
|
+
joins[table] ||= model.many_to_one_associations[table] || model.many_to_many_associations[table]
|
357
404
|
end
|
358
405
|
|
406
|
+
f_info = info[name]
|
407
|
+
raise Engine2::E2Error.new("Column #{name} not found for table #{table || model_table_name}") unless f_info
|
359
408
|
if f_info[:dummy]
|
360
409
|
nil
|
361
|
-
# elsif f_info[:type] == :blob_store
|
362
|
-
# # (~{name => nil}).as :name
|
363
|
-
# # Sequel.char_length(name).as name
|
364
|
-
# nil
|
365
410
|
else
|
411
|
+
qname = table.q(name)
|
366
412
|
if table != model_table_name
|
367
|
-
|
368
|
-
name.qualify(table).as(:"#{table}__#{name}")
|
369
|
-
else
|
370
|
-
name.qualify(table)
|
371
|
-
end
|
413
|
+
Sequel.alias_columns_in_joins ? qname.as(:"#{table}__#{name}") : qname
|
372
414
|
else
|
373
|
-
|
415
|
+
qname
|
374
416
|
end
|
375
417
|
end
|
376
418
|
end
|
377
419
|
end
|
378
420
|
|
379
|
-
@opts[:select].compact
|
421
|
+
@opts[:select].compact!.freeze
|
380
422
|
|
381
423
|
joins.reduce(self) do |joined, (table, assoc)|
|
382
424
|
m = assoc.associated_class
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
when Symbol
|
391
|
-
if sel.to_s =~ /^(\w+)__(\w+?)(?:___(\w+))?$/
|
392
|
-
yield $1.to_sym, $2.to_sym, $3 ? $3.to_sym : nil
|
393
|
-
else
|
394
|
-
yield nil, sel, al
|
425
|
+
case assoc[:type]
|
426
|
+
when :many_to_one
|
427
|
+
keys = assoc[:qualified_key]
|
428
|
+
joined.left_join(table, m.primary_keys.zip(keys.is_a?(Array) ? keys : [keys]))
|
429
|
+
when :many_to_many
|
430
|
+
joined.left_join(assoc[:join_table], assoc[:left_keys].zip(model.primary_keys)).left_join(m.table_name, m.primary_keys.zip(assoc[:right_keys]))
|
431
|
+
else unsupported_association
|
395
432
|
end
|
396
|
-
when Sequel::SQL::QualifiedIdentifier
|
397
|
-
yield sel.table, sel.column, al
|
398
|
-
when Sequel::SQL::AliasedExpression, Sequel::SQL::Function
|
399
|
-
sel
|
400
|
-
# extract_select sel.expression, sel.aliaz, &blk
|
401
|
-
# expr = sel.expression
|
402
|
-
# yield expr.table, expr.column
|
403
|
-
else
|
404
|
-
raise Engine2::E2Error.new("Unknown selection #{sel}")
|
405
433
|
end
|
406
434
|
end
|
407
435
|
|
@@ -433,10 +461,21 @@ end
|
|
433
461
|
module Engine2
|
434
462
|
LOCS ||= Hash.new{|h, k| ":#{k}:"}
|
435
463
|
PATH ||= File.expand_path('../..', File.dirname(__FILE__))
|
436
|
-
SETTINGS ||= {
|
464
|
+
SETTINGS ||= {
|
465
|
+
key_separator: '|',
|
466
|
+
app_path: 'app',
|
467
|
+
db_path: 'db',
|
468
|
+
model_path: 'models',
|
469
|
+
view_path: 'views',
|
470
|
+
asset_path: 'assets',
|
471
|
+
conf_path: 'conf'
|
472
|
+
}
|
473
|
+
|
474
|
+
def SETTINGS.path_for path
|
475
|
+
"#{self[:app_path]}/#{self[path]}"
|
476
|
+
end unless SETTINGS.frozen?
|
437
477
|
|
438
478
|
class << self
|
439
|
-
attr_reader :app
|
440
479
|
attr_reader :core_loaded
|
441
480
|
|
442
481
|
def database name
|
@@ -457,8 +496,9 @@ module Engine2
|
|
457
496
|
end
|
458
497
|
|
459
498
|
def bootstrap_e2db
|
460
|
-
|
461
|
-
|
499
|
+
e2_db_path = "#{Engine2::SETTINGS.path_for(:db_path)}/engine2.db"
|
500
|
+
e2_db_url = (defined? JRUBY_VERSION) ? "jdbc:sqlite:#{e2_db_path}" : "sqlite://#{e2_db_path}"
|
501
|
+
const_set :E2DB, connect(e2_db_url, loggers: [Logger.new($stdout)], convert_types: false, name: :engine2)
|
462
502
|
const_set :DUMMYDB, Sequel::Database.new(uri: 'dummy')
|
463
503
|
def DUMMYDB.synchronize *args;end
|
464
504
|
end
|
@@ -466,35 +506,38 @@ module Engine2
|
|
466
506
|
def reload
|
467
507
|
@core_loaded = true
|
468
508
|
t = Time.now
|
469
|
-
|
509
|
+
ActionNode.count = 0
|
470
510
|
SCHEMES.user.clear
|
471
511
|
|
472
512
|
Sequel::DATABASES.each do |db|
|
473
513
|
db.models.each{|n, m| Object.send(:remove_const, n) if Object.const_defined?(n)} unless db == E2DB || db == DUMMYDB
|
474
514
|
end
|
475
515
|
|
476
|
-
load "#{
|
516
|
+
load "#{Engine2::SETTINGS[:app_path]}/boot.rb"
|
477
517
|
|
478
518
|
Sequel::DATABASES.each &:load_schema_cache_from_file
|
479
519
|
@model_boot_blk.() if @model_boot_blk
|
480
520
|
load 'engine2/models/Files.rb'
|
481
521
|
load 'engine2/models/UserInfo.rb'
|
482
|
-
Dir["#{
|
522
|
+
Dir["#{Engine2::SETTINGS.path_for(:model_path)}/*"].each{|m| load m}
|
483
523
|
puts "MODELS: #{Sequel::DATABASES.reduce(0){|s, d|s + d.models.size}}, Time: #{Time.now - t}"
|
484
524
|
Sequel::DATABASES.each &:dump_schema_cache_to_file
|
485
525
|
|
486
526
|
send(:remove_const, :ROOT) if defined? ROOT
|
487
|
-
const_set(:ROOT,
|
527
|
+
const_set(:ROOT, ActionNode.new(nil, :api, RootAction, {}))
|
488
528
|
|
489
529
|
@boot_blk.(ROOT)
|
490
|
-
ROOT.
|
491
|
-
puts "BOOTSTRAP #{
|
530
|
+
ROOT.setup_node_tree
|
531
|
+
puts "BOOTSTRAP #{Engine2::SETTINGS[:name]}, Time: #{Time.new - t}"
|
492
532
|
end
|
493
533
|
|
494
|
-
def bootstrap
|
495
|
-
@app = app
|
534
|
+
def bootstrap path, settings = {}
|
496
535
|
SETTINGS.merge! settings
|
497
|
-
SETTINGS[:
|
536
|
+
SETTINGS[:path] = path
|
537
|
+
SETTINGS[:name] ||= File::basename(path)
|
538
|
+
SETTINGS.freeze
|
539
|
+
Handler.set :public_folder, "public"
|
540
|
+
Handler.set :views, [SETTINGS.path_for(:view_path), "#{Engine2::PATH}/views"]
|
498
541
|
bootstrap_e2db
|
499
542
|
|
500
543
|
require 'engine2/pre_bootstrap'
|
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
|
@@ -119,8 +120,6 @@ module Engine2
|
|
119
120
|
end
|
120
121
|
|
121
122
|
set :slim, pretty: true, sort_attrs: false
|
122
|
-
set :views, ["views", "#{PATH}/views"]
|
123
|
-
set :public_folder, "#{PATH}/public"
|
124
123
|
set :sessions, expire_after: 3600 # , :httponly => true, :secure => production?
|
125
124
|
|
126
125
|
helpers do
|
data/lib/engine2/model.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Engine2
|
4
5
|
module Model
|
@@ -74,6 +75,8 @@ module Engine2
|
|
74
75
|
decimal_field name, size, scale
|
75
76
|
when :blob
|
76
77
|
blob_field name, 100000
|
78
|
+
when :boolean
|
79
|
+
boolean_field name
|
77
80
|
when nil
|
78
81
|
# ignore nil type
|
79
82
|
else
|
@@ -284,7 +287,7 @@ module Engine2
|
|
284
287
|
with_errors = with.map{|w|record.errors[w]}
|
285
288
|
if with_errors.compact.empty?
|
286
289
|
all_fields = [field] + with
|
287
|
-
query = record.model.dataset
|
290
|
+
query = all_fields.reduce(record.model.dataset){|ds, f|ds.where f => record[f]}
|
288
291
|
query = query.exclude(record.model.primary_keys_hash(record.primary_key_values)) unless record.new?
|
289
292
|
unless query.empty?
|
290
293
|
msg = LOCS[:required_unique_value]
|
@@ -327,25 +330,6 @@ module Engine2
|
|
327
330
|
)
|
328
331
|
|
329
332
|
(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
333
|
file_store: lambda{|m, v, info|
|
350
334
|
value = m.values[v]
|
351
335
|
files = E2Files.db[:files]
|
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
|
@@ -28,7 +29,7 @@ module Engine2
|
|
28
29
|
search_live
|
29
30
|
|
30
31
|
on_change :model do |req, value|
|
31
|
-
#
|
32
|
+
# node.parent.*.assets[:model].select(:field).where(model: value).all.map{|rec|f = rec.values[:field]; [f, f]}
|
32
33
|
# render :field, list: {a: 1, b: 2}.to_a
|
33
34
|
end
|
34
35
|
|