lib/arql/app.rb in arql-0.3.31 vs lib/arql/app.rb in arql-0.4.0
- old
+ new
@@ -1,149 +1,176 @@
module Arql
class App
+ attr_accessor :log_io, :environments, :definitions, :options, :config
class << self
- attr_accessor :log_io, :env, :prompt, :instance, :connect_options
+ attr_accessor :instance
- def config
- @@effective_config
+ def log_io
+ instance.log_io
end
+ def log_io=(io)
+ instance.log_io = io
+ end
+
+ # environment names
+ def environments
+ instance.environments
+ end
+
def prompt
- if env
- env
- else
- File.basename(@@effective_config[:database])
- end
+ instance.prompt
end
+
+ def config
+ instance.config
+ end
end
+ def prompt
+ if environments.present?
+ environments.join('+')
+ else
+ File.basename(@options.database)
+ end
+ end
+
def initialize(options)
- require "arql/connection"
require "arql/definition"
+
+ App.instance = self
+
+ # command line options
@options = options
- App.env = @options.env
- App.connect_options = connect_options
- Connection.open(App.connect_options)
+
+ # env names
+ @environments = @options.environments
+ @environments ||= ['default']
+
print "Defining models..."
- @definition = Definition.new(effective_config)
+ @definitions = config[:environments].each_with_object({}) do |(env_name, env_conf), h|
+ h[env_name] = Definition.new(env_conf)
+ end.with_indifferent_access
+
print "\u001b[2K"
puts "\rModels defined"
print "Running initializers..."
load_initializer!
print "\u001b[2K"
puts "\rInitializers loaded"
- App.instance = self
end
- def connect_options
- connect_conf = effective_config.slice(:adapter, :host, :username,
- :password, :database, :encoding,
- :pool, :port, :socket)
- if effective_config[:ssh].present?
- connect_conf.merge!(start_ssh_proxy!)
- end
-
- connect_conf
- end
-
def load_initializer!
- return unless effective_config[:initializer]
- initializer_file = File.expand_path(effective_config[:initializer])
+ return unless config[:options][:initializer]
+
+ initializer_file = File.expand_path(config[:options][:initializer])
unless File.exist?(initializer_file)
- STDERR.puts "Specified initializer file not found, #{effective_config[:initializer]}"
+ warn "Specified initializer file not found, #{config[:options][:initializer]}"
exit(1)
end
load(initializer_file)
end
- def start_ssh_proxy!
- ssh_config = effective_config[:ssh]
- local_ssh_proxy_port = Arql::SSHProxy.connect(ssh_config.slice(:host, :user, :port, :password).merge(
- forward_host: effective_config[:host],
- forward_port: effective_config[:port],
- local_port: ssh_config[:local_port]))
- {
- host: '127.0.0.1',
- port: local_ssh_proxy_port
- }
- end
-
- def config
- @config ||= YAML.load(IO.read(File.expand_path(@options.config_file)), aliases: true).with_indifferent_access
+ def config_from_file
+ @config_from_file ||= YAML.safe_load(IO.read(File.expand_path(@options.config_file)), aliases: true).with_indifferent_access
rescue ArgumentError
- @config ||= YAML.load(IO.read(File.expand_path(@options.config_file))).with_indifferent_access
+ @config_from_file ||= YAML.safe_load(IO.read(File.expand_path(@options.config_file))).with_indifferent_access
end
- def selected_config
- if @options.env.present? && !config[@options.env].present?
- STDERR.puts "Specified ENV `#{@options.env}' not exists"
+ # Returns the configuration for config file.
+ # or default configuration (built from CLI options) if no environment specified
+ def environ_config_from_file
+ if @options.enviroments.present? || @options.environments&.any? { |env_names| !config_from_file.key?(env_names) }
+ warn "Specified ENV `#{@options.env}' not exists in config file"
+ exit(1)
end
- if env = @options.env
- config[env]
+ conf = if @options.environments.present?
+ @config_from_file.slice(*@options.environments)
else
- {}
+ { default: @options.to_h }.with_indifferent_access
end
- end
-
- def effective_config
- @@effective_config ||= nil
- unless @@effective_config
- @@effective_config = selected_config.deep_merge(@options.to_h)
- if @@effective_config[:adapter].blank?
- @@effective_config[:adapter] = 'sqlite3'
+ conf.each do |env_name, env_conf|
+ unless env_conf.key?(:namespace)
+ env_conf[:namespace] = env_name.to_s.gsub(/[^a-zA-Z0-9]/, '_').camelize
end
- @@effective_config[:database] = File.expand_path(@@effective_config[:database]) if @@effective_config[:adapter] == 'sqlite3'
end
- @@effective_config
end
+ # Returns the effective configuration for the application.
+ # structure like:
+ # {
+ # options: {show_sql: true,
+ # write_sql: 'output.sql',
+ # },
+ # environments: {
+ # development: {adapter: 'mysql2',
+ # host: 'localhost',
+ # port: 3306},
+ # test: {adapter: 'mysql2',
+ # host: 'localhost',
+ # port: 3306},
+ # }
+ # }
+ def config
+ @config ||= {
+ options: @options,
+ environments: environ_config_from_file.each_with_object({}) { |(env_name, env_conf), h|
+ conf = env_conf.deep_merge(@options.to_h)
+ conf[:adapter] = 'sqlite3' if conf[:adapter].blank?
+ conf[:database] = File.expand_path(conf[:database]) if conf[:adapter] == 'sqlite3'
+ h[env_name] = conf
+ h
+ }.with_indifferent_access
+ }
+ end
+
def run!
show_sql if should_show_sql?
write_sql if should_write_sql?
append_sql if should_append_sql?
- if effective_config[:code].present?
- eval(effective_config[:code])
- elsif effective_config[:args].present?
- effective_config[:args].first.tap { |file| load(file) }
- elsif STDIN.isatty
+ if @options.code&.present?
+ eval(@options.code)
+ elsif @options.args.present?
+ @options.args.first.tap { |file| load(file) }
+ elsif $stdin.isatty
run_repl!
else
- eval(STDIN.read)
+ eval($stdin.read)
end
end
def run_repl!
Repl.new
end
def should_show_sql?
- effective_config[:show_sql]
+ @options.show_sql
end
def should_write_sql?
- effective_config[:write_sql]
+ @options.write_sql
end
def should_append_sql?
- effective_config[:append_sql]
+ @options.append_sql
end
def show_sql
App.log_io ||= MultiIO.new
ActiveRecord::Base.logger = Logger.new(App.log_io)
- App.log_io << STDOUT
+ App.log_io << $stdout
end
def write_sql
- write_sql_file = effective_config[:write_sql]
+ write_sql_file = @options.write_sql
App.log_io ||= MultiIO.new
ActiveRecord::Base.logger = Logger.new(App.log_io)
App.log_io << File.new(write_sql_file, 'w')
end
def append_sql
- write_sql_file = effective_config[:append_sql]
+ write_sql_file = @options.append_sql
App.log_io ||= MultiIO.new
ActiveRecord::Base.logger = Logger.new(App.log_io)
App.log_io << File.new(write_sql_file, 'a')
end
end