arql 0.1.31

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.
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,40 @@
1
+ require_relative 'lib/arql/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "arql"
5
+ spec.version = Arql::VERSION
6
+ spec.authors = ["Liu Xiang"]
7
+ spec.email = ["liuxiang921@gmail.com"]
8
+
9
+ spec.summary = %{Rails ActiveRecord + Pry is the best SQL query editor}
10
+ spec.description = %{Use ActiveRecord and Pry as your favorite SQL query editor.}
11
+ spec.homepage = "https://github.com/lululau/arql"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency 'mysql2', '~> 0.5.3'
27
+ # spec.add_dependency 'pg', '>= 0.18', '< 2.0'
28
+ spec.add_dependency 'sqlite3', '~> 1.4'
29
+ # spec.add_dependency 'activerecord-sqlserver-adapter'
30
+ # spec.add_dependency 'activerecord-oracle_enhanced-adapter'
31
+ spec.add_dependency 'activerecord', '~> 6.0.3'
32
+ spec.add_dependency 'activesupport', '~> 6.0.3'
33
+ spec.add_dependency 'net-ssh-gateway', '~> 2.0.0'
34
+ spec.add_dependency 'pry', '~> 0.13.1'
35
+ spec.add_dependency 'pry-byebug', '~> 3.9.0'
36
+ spec.add_dependency 'pry-doc', '~> 1.1.0'
37
+ spec.add_dependency 'rainbow', '~> 3.0.0'
38
+ spec.add_dependency 'terminal-table', '~> 1.8.0'
39
+ spec.add_dependency 'table_print', '~> 1.5.6'
40
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "arql"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ArqlSetsidWrrapper = File.dirname(File.absolute_path(__FILE__)) + '/arql_setsid_wrapper'
4
+
5
+ require "arql"
6
+
7
+ Arql::Cli.start
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Process.setsid
4
+
5
+ exec(*ARGV)
@@ -0,0 +1,12 @@
1
+ require 'table_print'
2
+ require "arql/version"
3
+ require 'arql/id'
4
+ require 'arql/multi_io'
5
+ require 'arql/ext'
6
+ require "arql/repl"
7
+ require "arql/ssh_proxy"
8
+ require "arql/app"
9
+ require "arql/cli"
10
+
11
+ module Arql
12
+ end
@@ -0,0 +1,145 @@
1
+ require 'net/ssh/gateway'
2
+
3
+ module Arql
4
+ class App
5
+
6
+ class << self
7
+ attr_accessor :log_io, :env, :prompt
8
+
9
+ def config
10
+ @@effective_config
11
+ end
12
+
13
+ def prompt
14
+ if env
15
+ env
16
+ else
17
+ File.basename(@@effective_config[:database])
18
+ end
19
+ end
20
+ end
21
+
22
+ def initialize(options)
23
+ require 'active_support/all'
24
+ require 'active_record'
25
+ require "arql/connection"
26
+ require "arql/definition"
27
+ @options = options
28
+ App.env = @options.env
29
+ Connection.open(connect_options)
30
+ @definition = Definition.new(effective_config)
31
+ load_initializer!
32
+ end
33
+
34
+ def connect_options
35
+ connect_conf = effective_config.slice(:adapter, :host, :username,
36
+ :password, :database, :encoding,
37
+ :pool, :port, :socket)
38
+ if effective_config[:ssh].present?
39
+ connect_conf.merge!(start_ssh_proxy!)
40
+ end
41
+
42
+ connect_conf
43
+ end
44
+
45
+ def load_initializer!
46
+ return unless effective_config[:initializer]
47
+ initializer_file = File.expand_path(effective_config[:initializer])
48
+ unless File.exists?(initializer_file)
49
+ STDERR.puts "Specified initializer file not found, #{effective_config[:initializer]}"
50
+ exit(1)
51
+ end
52
+ load(initializer_file)
53
+ end
54
+
55
+ def start_ssh_proxy!
56
+ ssh_config = effective_config[:ssh]
57
+ local_ssh_proxy_port = Arql::SSHProxy.connect(ssh_config.slice(:host, :user, :port, :password).merge(
58
+ forward_host: effective_config[:host],
59
+ forward_port: effective_config[:port],
60
+ local_port: ssh_config[:local_port]))
61
+ {
62
+ host: '127.0.0.1',
63
+ port: local_ssh_proxy_port
64
+ }
65
+ end
66
+
67
+ def config
68
+ @config ||= YAML.load(IO.read(File.expand_path(@options.config_file))).with_indifferent_access
69
+ end
70
+
71
+ def selected_config
72
+ if @options.env.present? && !config[@options.env].present?
73
+ STDERR.puts "Specified ENV `#{@options.env}' not exists"
74
+ end
75
+ if env = @options.env
76
+ config[env]
77
+ else
78
+ {}
79
+ end
80
+ end
81
+
82
+ def effective_config
83
+ @@effective_config ||= nil
84
+ unless @@effective_config
85
+ @@effective_config = selected_config.deep_merge(@options.to_h)
86
+ if @@effective_config[:adapter].blank?
87
+ @@effective_config[:adapter] = 'sqlite3'
88
+ end
89
+ @@effective_config[:database] = File.expand_path(@@effective_config[:database]) if @@effective_config[:adapter] == 'sqlite3'
90
+ end
91
+ @@effective_config
92
+ end
93
+
94
+ def run!
95
+ show_sql if should_show_sql?
96
+ write_sql if should_write_sql?
97
+ append_sql if should_append_sql?
98
+ if effective_config[:code].present?
99
+ eval(effective_config[:code])
100
+ elsif effective_config[:args].present?
101
+ effective_config[:args].each { |rb| load(rb) }
102
+ elsif STDIN.isatty
103
+ run_repl!
104
+ else
105
+ eval(STDIN.read)
106
+ end
107
+ end
108
+
109
+ def run_repl!
110
+ Repl.new
111
+ end
112
+
113
+ def should_show_sql?
114
+ effective_config[:show_sql]
115
+ end
116
+
117
+ def should_write_sql?
118
+ effective_config[:write_sql]
119
+ end
120
+
121
+ def should_append_sql?
122
+ effective_config[:append_sql]
123
+ end
124
+
125
+ def show_sql
126
+ App.log_io ||= MultiIO.new
127
+ ActiveRecord::Base.logger = Logger.new(App.log_io)
128
+ App.log_io << STDOUT
129
+ end
130
+
131
+ def write_sql
132
+ write_sql_file = effective_config[:write_sql]
133
+ App.log_io ||= MultiIO.new
134
+ ActiveRecord::Base.logger = Logger.new(App.log_io)
135
+ App.log_io << File.new(write_sql_file, 'w')
136
+ end
137
+
138
+ def append_sql
139
+ write_sql_file = effective_config[:append_sql]
140
+ App.log_io ||= MultiIO.new
141
+ ActiveRecord::Base.logger = Logger.new(App.log_io)
142
+ App.log_io << File.new(write_sql_file, 'a')
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,141 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+
4
+ module Arql
5
+ class Cli
6
+ class << self
7
+ def start
8
+ parse_options!
9
+ App.new(@options).run!
10
+ end
11
+
12
+ def parse_options!
13
+ @options = OpenStruct.new(config_file: default_config_file,
14
+ initializer: default_initializer,
15
+ ssh: {})
16
+
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = <<~EOF
20
+ Usage: arql [options] [ruby file]
21
+
22
+ If neither [ruby file] nor -e option specified, and STDIN is not a tty, a Pry REPL will be launched,
23
+ otherwise the specified ruby file or -e option value or ruby code read from STDIN will be run, and no REPL launched
24
+
25
+ EOF
26
+
27
+ opts.on('-cCONFIG_FILE', '--conf=CONFIG_FILE', 'Specify config file, default is $HOME/.arql.yml, or $HOME/.arql.d/init.yml.') do |config_file|
28
+ @options.config_file = config_file
29
+ end
30
+
31
+ opts.on('-iINITIALIZER', '--initializer=INITIALIZER', 'Specify initializer ruby file, default is $HOME/.arql.rb, or $HOME/.arql.d/init.rb.') do |initializer|
32
+ @options.initializer = initializer
33
+ end
34
+
35
+ opts.on('-eENVIRON', '--env=ENVIRON', 'Specify config environment.') do |env|
36
+ @options.env = env
37
+ end
38
+
39
+ opts.on('-aDB_ADAPTER', '--db-adapter=DB_ADAPTER', 'Specify database Adapter, default is mysql2') do |db_adapter|
40
+ @options.dapter = db_adapter
41
+ end
42
+
43
+ opts.on('-hDB_HOST', '--db-host=DB_HOST', 'Specify database host') do |db_host|
44
+ @options.host = db_host
45
+ end
46
+
47
+ opts.on('-pDB_PORT', '--db-port=DB_PORT', 'Specify database port') do |db_port|
48
+ @options.port = db_port.to_i
49
+ end
50
+
51
+ opts.on('-dDB_NAME', '--db-name=DB_NAME', 'Specify database name') do |db_name|
52
+ @options.database = db_name
53
+ end
54
+
55
+ opts.on('-uDB_USER', '--db-user=DB_USER', 'Specify database user') do |db_user|
56
+ @options.username = db_user
57
+ end
58
+
59
+ opts.on('-PDB_PASSWORD', '--db-password=DB_PASSWORD', 'Specify database password') do |db_password|
60
+ @options.password = db_password
61
+ end
62
+
63
+ opts.on('-n', '--db-encoding=DB_ENCODING', 'Specify database encoding, default is utf8') do |db_encoding|
64
+ @options.encoding = db_encoding
65
+ end
66
+
67
+ opts.on('-o', '--db-pool=DB_POOL', 'Specify database pool size, default is 5') do |db_pool|
68
+ @options.pool = db_pool
69
+ end
70
+
71
+ opts.on('-HSSH_HOST', '--ssh-host=SSH_HOST', 'Specify SSH host') do |ssh_host|
72
+ @options.ssh[:host] = ssh_host
73
+ end
74
+
75
+ opts.on('-OSSH_PORT', '--ssh-port=SSH_PORT', 'Specify SSH port') do |ssh_port|
76
+ @options.ssh[:port] = ssh_port.to_i
77
+ end
78
+
79
+ opts.on('-USSH_USER', '--ssh-user=SSH_USER', 'Specify SSH user') do |ssh_user|
80
+ @options.ssh[:user] = ssh_user
81
+ end
82
+
83
+ opts.on('-WSSH_PASSWORD', '--ssh-password=SSH_PASSWORD', 'Specify SSH password') do |ssh_password|
84
+ @options.ssh[:password] = ssh_password
85
+ end
86
+
87
+ opts.on('-LSSH_LOCAL_PORT', '--ssh-local-port=SSH_LOCAL_PORT', 'Specify local SSH proxy port') do |local_port|
88
+ @options.ssh[:local_port] = local_port.to_i
89
+ end
90
+
91
+ opts.on('-ECODE', '--eval=CODE', 'evaluate CODE') do |code|
92
+ @options.code = code
93
+ end
94
+
95
+ opts.on('-S', '--show-sql', 'Show SQL on STDOUT') do
96
+ @options.show_sql = true
97
+ end
98
+
99
+ opts.on('-wOUTOUT', '--write-sql=OUTPUT', 'Write SQL to OUTPUT file') do |file|
100
+ @options.write_sql = file
101
+ end
102
+
103
+ opts.on('-AOUTPUT', '--append-sql=OUTPUT', 'Append SQL to OUTPUT file') do |file|
104
+ @options.append_sql = file
105
+ end
106
+
107
+ opts.on('-V', '--version', 'Prints version') do
108
+ puts "ARQL #{Arql::VERSION}"
109
+ exit
110
+ end
111
+
112
+ opts.on('', '--help', 'Prints this help') do
113
+ puts opts
114
+ exit
115
+ end
116
+
117
+ end.parse!
118
+
119
+ @options.args = ARGV
120
+ end
121
+
122
+ def default_config_file
123
+ conf = File.expand_path('~/.arql.yml')
124
+ return conf if File.file?(conf)
125
+ conf = File.expand_path('~/.arql.yaml')
126
+ return conf if File.file?(conf)
127
+ conf = File.expand_path('~/.arql.d/init.yml')
128
+ return conf if File.file?(conf)
129
+ conf = File.expand_path('~/.arql.d/init.yaml')
130
+ return conf if File.file?(conf)
131
+ end
132
+
133
+ def default_initializer
134
+ conf = File.expand_path('~/.arql.rb')
135
+ return conf if File.file?(conf)
136
+ conf = File.expand_path('~/.arql.d/init.rb')
137
+ return conf if File.file?(conf)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,9 @@
1
+ require 'arql/commands/info'
2
+ require 'arql/commands/models'
3
+ require 'arql/commands/table'
4
+ require 'arql/commands/reconnect'
5
+ require 'arql/commands/redefine'
6
+ require 'arql/commands/show_sql'
7
+
8
+ module Arql::Commands
9
+ end
@@ -0,0 +1,52 @@
1
+ require 'rainbow'
2
+
3
+ module Arql::Commands
4
+ module Info
5
+ class << self
6
+ def db_info
7
+ <<~EOF
8
+
9
+ Database Connection Information:
10
+
11
+ Active: #{color_boolean(ActiveRecord::Base.connection.active?)}
12
+ Host: #{Arql::App.config[:host]}
13
+ Port: #{Arql::App.config[:port]}
14
+ Username: #{Arql::App.config[:username]}
15
+ Password: #{(Arql::App.config[:password] || '').gsub(/./, '*')}
16
+ Database: #{Arql::App.config[:database]}
17
+ Adapter: #{Arql::App.config[:adapter]}
18
+ Encoding: #{Arql::App.config[:encoding]}
19
+ Pool Size: #{Arql::App.config[:pool]}
20
+ EOF
21
+ end
22
+
23
+ def ssh_info
24
+ <<~EOF
25
+
26
+ SSH Connection Information:
27
+
28
+ Active: #{color_boolean(Arql::SSHProxy.active?)}
29
+ Host: #{Arql::App.config[:ssh][:host]}
30
+ Port: #{Arql::App.config[:ssh][:port]}
31
+ Username: #{Arql::App.config[:ssh][:user]}
32
+ Password: #{(Arql::App.config[:ssh][:password] || '').gsub(/./, '*')}
33
+ Local Port: #{Arql::SSHProxy.local_ssh_proxy_port}
34
+ EOF
35
+ end
36
+
37
+ private
38
+ def color_boolean(bool)
39
+ if bool
40
+ Rainbow('TRUE').green
41
+ else
42
+ Rainbow('FALSE').red
43
+ end
44
+ end
45
+ end
46
+
47
+ Pry.commands.block_command 'info' do
48
+ puts Info::db_info
49
+ puts Info::ssh_info if Arql::App.config[:ssh].present?
50
+ end
51
+ end
52
+ end