lib/engine2/core.rb in engine2-1.0.1 vs lib/engine2/core.rb in engine2-1.0.2

- old
+ new

@@ -25,10 +25,18 @@ class Proc def to_json(*) loc = source_location "\"#<Proc:#{loc.first[/\w+.rb/]}:#{loc.last}>\"" end + + def chain &blk + proc = self + lambda do |obj| + obj.instance_eval(&proc) + obj.instance_eval(&blk) + end + end end class Hash include PrettyJSON @@ -121,11 +129,11 @@ class Sequel::Database attr_accessor :models, :default_schema def cache_file - "#{APP_LOCATION}/#{opts[:orig_opts][:name]}.dump" + "#{Engine2::app}/#{opts[:orig_opts][:name]}.dump" end def load_schema_cache_from_file self.models = {} load_schema_cache? cache_file if adapter_scheme @@ -234,11 +242,11 @@ errors.add(name, req[:message]) if !req[:if] || req[:if].(self) end else info[:validations].each_pair do |validation, args| validation_proc = Engine2::Validations[validation] || args[:lambda] # swap ? - raise "Validation not found for field '#{name}' of type #{validation}" unless validation_proc + raise E2Error.new("Validation not found for field '#{name}' of type #{validation}") unless validation_proc if result = validation_proc.(self, name, info) errors.add(name, result) break end end @@ -343,15 +351,11 @@ if table == model_table_name fields << name else fields << :"#{table}__#{name}" - assoc = model.many_to_one_associations[table] - unless assoc - # fail - end - joins[table] = assoc + joins[table] = model.many_to_one_associations[table] end if f_info[:dummy] nil # elsif f_info[:type] == :blob_store @@ -373,15 +377,13 @@ end @opts[:select].compact! joins.reduce(self) do |joined, (table, assoc)| - assoc = model.many_to_one_associations[table] # || model.one_to_one_associations[table] m = Object.const_get(assoc[:class_name]) keys = assoc[:qualified_key] - keys = [keys] unless keys.is_a?(Array) - joined.left_join(table, m.primary_keys.zip(keys)) + joined.left_join(table, m.primary_keys.zip(keys.is_a?(Array) ? keys : [keys])) end end def extract_select sel, al = nil, &blk case sel @@ -431,69 +433,78 @@ module Engine2 LOCS ||= Hash.new{|h, k| ":#{k}:"} PATH ||= File.expand_path('../..', File.dirname(__FILE__)) class << self - attr_accessor :core_loading - end + attr_reader :app, :reloading + attr_reader :core_loaded - self.core_loading = true + def database name + Object.const_set(name, yield) unless Object.const_defined?(name) + end - def self.database name - Object.const_set(name, yield) unless Object.const_defined?(name) - end + def connect *args + db = Sequel.connect *args + db + end - def self.connect *args - db = Sequel.connect *args - db.models = {} - db - end + def boot &blk + @boot_blk = blk + end - e2_db_file = (defined? JRUBY_VERSION) ? "jdbc:sqlite:#{APP_LOCATION}/engine2.db" : "sqlite://#{APP_LOCATION}/engine2.db" - E2DB ||= connect e2_db_file, loggers: [Logger.new($stdout)], convert_types: false, name: :engine2 - DUMMYDB ||= Sequel::Database.new uri: 'dummy' - def DUMMYDB.synchronize *args;end + def model_boot &blk + @model_boot_blk = blk + end - def self.boot &blk - @boot_blk = blk - end + def bootstrap_e2db + e2_db_file = (defined? JRUBY_VERSION) ? "jdbc:sqlite:#{@app}/engine2.db" : "sqlite://#{@app}/engine2.db" + Engine2.const_set :E2DB, connect(e2_db_file, loggers: [Logger.new($stdout)], convert_types: false, name: :engine2) + Engine2.const_set :DUMMYDB, Sequel::Database.new(uri: 'dummy') + def DUMMYDB.synchronize *args;end + end - def self.model_boot &blk - @model_boot_blk = blk - end + def reload + @core_loaded = true + t = Time.now + Action.count = 0 + SCHEMES.user.clear - def self.bootstrap app = APP_LOCATION - require 'engine2/pre_bootstrap' - t = Time.now - Action.count = 0 - SCHEMES.clear + Sequel::DATABASES.each do |db| + db.models.each{|n, m| Object.send(:remove_const, n) if Object.const_defined?(n)} unless db == E2DB || db == DUMMYDB + end - Sequel::DATABASES.each do |db| - db.models.each{|n, m| Object.send(:remove_const, n) if Object.const_defined?(n)} unless db == E2DB || db == DUMMYDB - end + load "#{app}/boot.rb" - load "#{app}/boot.rb" + Sequel::DATABASES.each &:load_schema_cache_from_file + @model_boot_blk.() if @model_boot_blk + load 'engine2/models/Files.rb' + load 'engine2/models/UserInfo.rb' + Dir["#{app}/models/*"].each{|m| load m} + puts "MODELS: #{Sequel::DATABASES.reduce(0){|s, d|s + d.models.size}}, Time: #{Time.now - t}" + Sequel::DATABASES.each &:dump_schema_cache_to_file - Sequel::DATABASES.each &:load_schema_cache_from_file - @model_boot_blk.() if @model_boot_blk - load 'engine2/models/Files.rb' - load 'engine2/models/UserInfo.rb' - Dir["#{app}/models/*"].each{|m| load m} - puts "MODELS, Time: #{Time.now - t}" - Sequel::DATABASES.each &:dump_schema_cache_to_file + Engine2.send(:remove_const, :ROOT) if defined? ROOT + Engine2.const_set(:ROOT, Action.new(nil, :api, DummyMeta, {})) - SCHEMES.merge! - Engine2.send(:remove_const, :ROOT) if defined? ROOT - Engine2.const_set(:ROOT, Action.new(nil, :api, DummyMeta, {})) + @boot_blk.(ROOT) + ROOT.setup_action_tree + puts "BOOTSTRAP #{app}, Time: #{Time.new - t}" + end - @boot_blk.(ROOT) - ROOT.setup_action_tree - puts "BOOTSTRAP #{app}, Time: #{Time.new - t}" - self.core_loading = false - require 'engine2/post_bootstrap' + def bootstrap app, opts = {} + @app = app + @reloading = opts[:reloading] + bootstrap_e2db + + require 'engine2/pre_bootstrap' + reload + require 'engine2/post_bootstrap' + end end + @core_loaded = false + class E2Error < RuntimeError def initialize msg super end end @@ -532,12 +543,12 @@ def option_at index, name, properties = {}, &blk option name, properties, index, &blk end - def option_index iname + def option_index iname, raise = true index = @entries.index{|e| (e.is_a?(MenuBuilder) ? e.name : e[:name]) == iname} - raise E2Error.new("No menu option #{iname} found") unless index + raise E2Error.new("No menu option #{iname} found") if !index && raise index end def modify_option name, properties index = option_index(name)