arql 0.3.31 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.vscode/launch.json +1 -1
- data/Gemfile.lock +1 -1
- data/README-zh_CN.org +706 -429
- data/auto-set-id-before-save-zh_CN.org +1 -1
- data/custom-configurations-zh_CN.org +40 -3
- data/define-associations-zh_CN.org +31 -17
- data/initializer-structure-zh_CN.org +22 -4
- data/lib/arql/app.rb +98 -71
- data/lib/arql/cli.rb +31 -15
- data/lib/arql/commands/info.rb +41 -28
- data/lib/arql/commands/models.rb +106 -61
- data/lib/arql/commands/reconnect.rb +8 -4
- data/lib/arql/commands/redefine.rb +3 -1
- data/lib/arql/commands/sandbox.rb +6 -4
- data/lib/arql/commands.rb +0 -2
- data/lib/arql/concerns/global_data_definition.rb +40 -6
- data/lib/arql/concerns/model_extension.rb +168 -0
- data/lib/arql/concerns/table_data_definition.rb +20 -20
- data/lib/arql/concerns.rb +1 -0
- data/lib/arql/definition.rb +169 -317
- data/lib/arql/ext/active_record/relation.rb +29 -0
- data/lib/arql/ext/active_record/result.rb +29 -0
- data/lib/arql/ext/array.rb +40 -1
- data/lib/arql/ext/kernel.rb +70 -61
- data/lib/arql/ext/object.rb +14 -0
- data/lib/arql/ext/ransack/search.rb +29 -0
- data/lib/arql/mysqldump.rb +0 -1
- data/lib/arql/ssh_proxy.rb +25 -22
- data/lib/arql/version.rb +1 -1
- data/lib/arql.rb +11 -7
- data/sql-log-zh_CN.org +8 -3
- metadata +6 -5
- data/lib/arql/commands/table.rb +0 -55
- data/lib/arql/commands/vd.rb +0 -46
- data/lib/arql/connection.rb +0 -16
data/lib/arql/ext/kernel.rb
CHANGED
@@ -5,67 +5,11 @@ module Kernel
|
|
5
5
|
include ::Arql::Concerns::GlobalDataDefinition
|
6
6
|
|
7
7
|
def q(sql)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def print_tables(format = :md)
|
12
|
-
require 'terminal-table'
|
13
|
-
|
14
|
-
tables = ActiveRecord::Base.connection.tables.map do |table_name|
|
15
|
-
{
|
16
|
-
table: table_name,
|
17
|
-
table_comment: ActiveRecord::Base.connection.table_comment(table_name) || '',
|
18
|
-
columns: ::ActiveRecord::Base.connection.columns(table_name)
|
19
|
-
}
|
20
|
-
end
|
21
|
-
|
22
|
-
outputs = tables.map do |table|
|
23
|
-
table_name = table[:table]
|
24
|
-
table_comment = table[:table_comment]
|
25
|
-
case format
|
26
|
-
when :md
|
27
|
-
"# #{table_name} #{table_comment}\n\n" +
|
28
|
-
Terminal::Table.new { |t|
|
29
|
-
t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
|
30
|
-
t.rows = table[:columns].map { |column|
|
31
|
-
pk = if [::ActiveRecord::Base.connection.primary_key(table_name)].flatten.include?(column)
|
32
|
-
'Y'
|
33
|
-
else
|
34
|
-
''
|
35
|
-
end
|
36
|
-
[pk, "`#{column.name}`", column.sql_type, column.sql_type_metadata.limit || '', column.sql_type_metadata.precision || '',
|
37
|
-
column.sql_type_metadata.scale || '', column.default || '', column.null, column.comment || '']
|
38
|
-
}
|
39
|
-
t.style = {
|
40
|
-
border_top: false,
|
41
|
-
border_bottom: false,
|
42
|
-
border_i: '|'
|
43
|
-
}
|
44
|
-
}.to_s.lines.map { |l| ' ' + l }.join
|
45
|
-
when :org
|
46
|
-
"* #{table_name} #{table_comment}\n\n" +
|
47
|
-
Terminal::Table.new { |t|
|
48
|
-
t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
|
49
|
-
t.rows = table[:columns].map { |column|
|
50
|
-
pk = if [::ActiveRecord::Base.connection.primary_key(table_name)].flatten.include?(column)
|
51
|
-
'Y'
|
52
|
-
else
|
53
|
-
''
|
54
|
-
end
|
55
|
-
[pk, "=#{column.name}=", column.sql_type, column.sql_type_metadata.limit || '', column.sql_type_metadata.precision || '',
|
56
|
-
column.sql_type_metadata.scale || '', column.default || '', column.null, column.comment || '']
|
57
|
-
}
|
58
|
-
t.style = {
|
59
|
-
border_top: false,
|
60
|
-
border_bottom: false,
|
61
|
-
}
|
62
|
-
}.to_s.lines.map { |l| ' ' + l.gsub(/^\+|\+$/, '|') }.join
|
63
|
-
when :sql
|
64
|
-
"-- Table: #{table_name}\n\n" + ActiveRecord::Base.connection.exec_query("show create table `#{table_name}`").rows.last.last + ';'
|
65
|
-
end
|
8
|
+
if Arql::App.instance.environments.size > 1
|
9
|
+
$stderr.puts "Multiple environments are defined. Please use Namespace::q() instread, where Namespace is the namespace module of one of the environments."
|
10
|
+
return
|
66
11
|
end
|
67
|
-
|
68
|
-
outputs.each { |out| puts out; puts }
|
12
|
+
Arql::App.instance.definitions.first.connection.exec_query(sql)
|
69
13
|
end
|
70
14
|
|
71
15
|
def generate_csv(filename, **options, &block)
|
@@ -113,4 +57,69 @@ module Kernel
|
|
113
57
|
JSON.parse(IO.read(File.expand_path(filename)))
|
114
58
|
end
|
115
59
|
|
116
|
-
|
60
|
+
def within_namespace(namespace_pattern, &blk)
|
61
|
+
if namespace_pattern.is_a?(Module)
|
62
|
+
namespace_pattern.module_eval(&blk)
|
63
|
+
return
|
64
|
+
end
|
65
|
+
definition = Arql::App.instance.definitions.find do |_, defi|
|
66
|
+
case namespace_pattern
|
67
|
+
when Symbol
|
68
|
+
defi.namespace.to_s == namespace_pattern.to_s
|
69
|
+
when String
|
70
|
+
defi.namespace.to_s == namespace_pattern
|
71
|
+
when Regexp
|
72
|
+
defi.namespace.to_s =~ namespace_pattern
|
73
|
+
end
|
74
|
+
end
|
75
|
+
if definition
|
76
|
+
definition.last.namespace_module.module_eval(&blk)
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
$stderr.puts "Namespace #{namespace_pattern.inspect} not found"
|
81
|
+
end
|
82
|
+
|
83
|
+
def within_env(env_name_pattern, &blk)
|
84
|
+
definition = Arql::App.instance.definitions.find do |env_name, defi|
|
85
|
+
case env_name_pattern
|
86
|
+
when Symbol
|
87
|
+
env_name == env_name_pattern.to_s
|
88
|
+
when String
|
89
|
+
env_name == env_name_pattern
|
90
|
+
when Regexp
|
91
|
+
env_name =~ env_name_pattern
|
92
|
+
end
|
93
|
+
end
|
94
|
+
if definition
|
95
|
+
definition.last.namespace_module.module_eval(&blk)
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
$stderr.puts "Environment #{env_name_pattern.inspect} not found"
|
100
|
+
end
|
101
|
+
|
102
|
+
def models
|
103
|
+
Arql::App.instance.definitions.flat_map do |_, definition|
|
104
|
+
definition.namespace_module.models
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def table_names
|
109
|
+
Arql::App.instance.definitions.flat_map do |_, definition|
|
110
|
+
definition.namespace_module.tables
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def model_names
|
115
|
+
Arql::App.instance.definitions.flat_map do |_, definition|
|
116
|
+
definition.namespace_module.model_names
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def env_config(env_regexp)
|
121
|
+
Arql::App.instance.definitions.find do |env_name, _|
|
122
|
+
env_name =~ env_regexp
|
123
|
+
end.last.options
|
124
|
+
end
|
125
|
+
end
|
data/lib/arql/ext/object.rb
CHANGED
@@ -19,4 +19,18 @@ class Object
|
|
19
19
|
def a
|
20
20
|
[self]
|
21
21
|
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def const_missing(name)
|
25
|
+
return super unless const_defined?(:Arql)
|
26
|
+
return super unless Arql.const_defined?(:App)
|
27
|
+
return super unless Arql::App.instance&.definitions&.present?
|
28
|
+
|
29
|
+
Arql::App.instance.definitions.lazy.filter do |_, definition|
|
30
|
+
definition.namespace_module.const_defined?(name)
|
31
|
+
end.map do |_, definition|
|
32
|
+
definition.namespace_module.const_get(name)
|
33
|
+
end.first || super
|
34
|
+
end
|
35
|
+
end
|
22
36
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Ransack::Search.class_eval do
|
2
|
+
def t(*attrs, **options)
|
3
|
+
result.t(*attrs, **options)
|
4
|
+
end
|
5
|
+
|
6
|
+
def vd(*attrs, **options)
|
7
|
+
result.vd(*attrs, **options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def v
|
11
|
+
result.v
|
12
|
+
end
|
13
|
+
|
14
|
+
def a
|
15
|
+
result.a
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_csv(filename, *fields, **options)
|
19
|
+
result.write_csv(filename, *fields, **options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def write_excel(filename, *fields, **options)
|
23
|
+
result.write_excel(filename, *fields, **options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def dump(filename, batch_size=500)
|
27
|
+
result.dump(filename, batch_size)
|
28
|
+
end
|
29
|
+
end
|
data/lib/arql/mysqldump.rb
CHANGED
data/lib/arql/ssh_proxy.rb
CHANGED
@@ -3,33 +3,36 @@ require 'arql/ssh_proxy_patch'
|
|
3
3
|
|
4
4
|
module Arql
|
5
5
|
class SSHProxy
|
6
|
-
|
6
|
+
attr_accessor :config, :ssh_gateway, :local_ssh_proxy_port
|
7
7
|
|
8
|
-
|
8
|
+
def initialize(config)
|
9
|
+
print "Establishing SSH connection to #{config[:host]}:#{config[:port]}"
|
10
|
+
@config = config
|
11
|
+
@ssh_gateway = Net::SSH::Gateway.new(config[:host], config[:user], config.slice(:port, :password).symbolize_keys.merge(keepalive: true, keepalive_interval: 30, loop_wait: 1))
|
12
|
+
@local_ssh_proxy_port = @ssh_gateway.open(config[:forward_host], config[:forward_port], config[:local_port])
|
13
|
+
print "\u001b[2K"
|
14
|
+
puts "\rSSH connection to #{config[:host]}:#{config[:port]} established"
|
15
|
+
end
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@ssh_gateway = Net::SSH::Gateway.new(config[:host], config[:user], config.slice(:port, :password).symbolize_keys.merge(keepalive: true, keepalive_interval: 30, loop_wait: 1))
|
14
|
-
@local_ssh_proxy_port = @ssh_gateway.open(config[:forward_host], config[:forward_port], config[:local_port])
|
15
|
-
print "\u001b[2K"
|
16
|
-
puts "\rSSH connection to #{config[:host]}:#{config[:port]} established"
|
17
|
-
@local_ssh_proxy_port
|
18
|
-
end
|
17
|
+
def reconnect
|
18
|
+
reconnect! unless @ssh_gateway.active?
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def reconnect!
|
22
|
+
@ssh_gateway.shutdown!
|
23
|
+
@ssh_gateway = Net::SSH::Gateway.new(@config[:host], @config[:user], @config.slice(:port, :password).symbolize_keys)
|
24
|
+
@ssh_gateway.open(config[:forward_host], config[:forward_port], @local_ssh_proxy_port)
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@ssh_gateway.open(config[:forward_host], config[:forward_port], @local_ssh_proxy_port)
|
28
|
-
end
|
27
|
+
def active?
|
28
|
+
@ssh_gateway.active?
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def database_host_port
|
32
|
+
{
|
33
|
+
host: '127.0.0.1',
|
34
|
+
port: @local_ssh_proxy_port
|
35
|
+
}
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
data/lib/arql/version.rb
CHANGED
data/lib/arql.rb
CHANGED
@@ -3,21 +3,25 @@ require 'roo'
|
|
3
3
|
require 'caxlsx'
|
4
4
|
require 'csv'
|
5
5
|
require 'net/ssh/gateway'
|
6
|
-
require
|
6
|
+
require 'arql/version'
|
7
7
|
require 'arql/id'
|
8
8
|
require 'arql/multi_io'
|
9
9
|
require 'arql/ext'
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
10
|
+
require 'arql/repl'
|
11
|
+
require 'arql/ssh_proxy'
|
12
|
+
require 'arql/app'
|
13
|
+
require 'arql/cli'
|
14
|
+
require 'arql/mysqldump'
|
15
|
+
require 'arql/vd'
|
16
16
|
require 'active_support/all'
|
17
17
|
require 'active_record'
|
18
18
|
require 'kaminari/activerecord'
|
19
19
|
require 'composite_primary_keys'
|
20
20
|
require 'ransack'
|
21
21
|
|
22
|
+
require 'arql/ext/active_record/relation'
|
23
|
+
require 'arql/ext/active_record/result'
|
24
|
+
require 'arql/ext/ransack/search'
|
25
|
+
|
22
26
|
module Arql
|
23
27
|
end
|
data/sql-log-zh_CN.org
CHANGED
@@ -7,13 +7,18 @@
|
|
7
7
|
创建一个文件 =~/.arql.d/sql_log.rb= ,内容如下:
|
8
8
|
|
9
9
|
#+BEGIN_SRC ruby
|
10
|
-
unless Arql::App.
|
10
|
+
unless Arql::App.instance.options.append_sql
|
11
11
|
log_root_dir = File.expand_path('~/.arql.d/logs')
|
12
|
-
|
12
|
+
if Arql::App.instance.environments.present?
|
13
|
+
log_dir = "#{log_root_dir}/%s" % Arql::App.instance.environments.join('_')
|
14
|
+
elsif File.file?(Arql::App.instance.options[:database])
|
15
|
+
log_dir = "#{log_root_dir}/%s" % File.basename(Arql::App.instance.options[:database])
|
16
|
+
end
|
17
|
+
|
13
18
|
FileUtils.mkdir_p(log_dir)
|
14
19
|
now = Time.now
|
15
20
|
log_file = "#{log_dir}/%s.%s.%s.log" % [Time.now.strftime('%Y_%m%d_%H%M%S'), `hostname -s`.chomp.downcase, Process.pid]
|
16
|
-
Arql::App.
|
21
|
+
Arql::App.instance.options.append_sql = log_file
|
17
22
|
|
18
23
|
lfile = File.new(log_file, 'a')
|
19
24
|
lfile.sync = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liu Xiang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|
@@ -334,20 +334,21 @@ files:
|
|
334
334
|
- lib/arql/commands/redefine.rb
|
335
335
|
- lib/arql/commands/sandbox.rb
|
336
336
|
- lib/arql/commands/show_sql.rb
|
337
|
-
- lib/arql/commands/table.rb
|
338
|
-
- lib/arql/commands/vd.rb
|
339
337
|
- lib/arql/concerns.rb
|
340
338
|
- lib/arql/concerns/global_data_definition.rb
|
339
|
+
- lib/arql/concerns/model_extension.rb
|
341
340
|
- lib/arql/concerns/table_data_definition.rb
|
342
|
-
- lib/arql/connection.rb
|
343
341
|
- lib/arql/definition.rb
|
344
342
|
- lib/arql/ext.rb
|
345
343
|
- lib/arql/ext/active_record/connection_adapters/abstract_mysql_adapter.rb
|
346
344
|
- lib/arql/ext/active_record/connection_adapters/postgresql/schema_statements.rb
|
345
|
+
- lib/arql/ext/active_record/relation.rb
|
346
|
+
- lib/arql/ext/active_record/result.rb
|
347
347
|
- lib/arql/ext/array.rb
|
348
348
|
- lib/arql/ext/hash.rb
|
349
349
|
- lib/arql/ext/kernel.rb
|
350
350
|
- lib/arql/ext/object.rb
|
351
|
+
- lib/arql/ext/ransack/search.rb
|
351
352
|
- lib/arql/ext/string.rb
|
352
353
|
- lib/arql/ext/time.rb
|
353
354
|
- lib/arql/id.rb
|
data/lib/arql/commands/table.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'terminal-table'
|
2
|
-
|
3
|
-
module Arql::Commands
|
4
|
-
module Table
|
5
|
-
class << self
|
6
|
-
def get_table_name(name)
|
7
|
-
name = name.to_s
|
8
|
-
return name if name =~ /^[a-z]/
|
9
|
-
if Object.const_defined?(name)
|
10
|
-
klass = Object.const_get(name)
|
11
|
-
return klass.table_name if klass < ActiveRecord::Base
|
12
|
-
end
|
13
|
-
name
|
14
|
-
end
|
15
|
-
|
16
|
-
def table_info_table(table_name)
|
17
|
-
Terminal::Table.new do |t|
|
18
|
-
table_info(table_name).each { |row| t << (row || :separator) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def table_info(table_name)
|
23
|
-
t = []
|
24
|
-
t << ['PK', 'Name', 'SQL Type', 'Ruby Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
|
25
|
-
t << nil
|
26
|
-
connection = ::ActiveRecord::Base.connection
|
27
|
-
connection.columns(table_name).each do |column|
|
28
|
-
pk = if [connection.primary_key(table_name)].flatten.include?(column.name)
|
29
|
-
'Y'
|
30
|
-
else
|
31
|
-
''
|
32
|
-
end
|
33
|
-
t << [pk, column.name, column.sql_type,
|
34
|
-
column.sql_type_metadata.type, column.sql_type_metadata.limit || '',
|
35
|
-
column.sql_type_metadata.precision || '', column.sql_type_metadata.scale || '', column.default || '',
|
36
|
-
column.null, column.comment || '']
|
37
|
-
end
|
38
|
-
t
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
Pry.commands.block_command 't' do |name|
|
43
|
-
table_name = Table::get_table_name(name)
|
44
|
-
puts
|
45
|
-
puts "Table: #{table_name}"
|
46
|
-
puts Table::table_info_table(table_name)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
module Kernel
|
52
|
-
def table(name)
|
53
|
-
Arql::Commands::Table::table_info(Arql::Commands::Table::get_table_name(name))
|
54
|
-
end
|
55
|
-
end
|
data/lib/arql/commands/vd.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'arql/vd'
|
2
|
-
|
3
|
-
module Arql::Commands
|
4
|
-
module VD
|
5
|
-
class << self
|
6
|
-
def get_table_name(name)
|
7
|
-
name = name.to_s
|
8
|
-
return name if name =~ /^[a-z]/
|
9
|
-
if Object.const_defined?(name)
|
10
|
-
klass = Object.const_get(name)
|
11
|
-
return klass.table_name if klass < ActiveRecord::Base
|
12
|
-
end
|
13
|
-
name
|
14
|
-
end
|
15
|
-
|
16
|
-
def table_info_vd(table_name)
|
17
|
-
Arql::VD.new do |vd|
|
18
|
-
table_info(table_name).each { |row| vd << row }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def table_info(table_name)
|
23
|
-
t = []
|
24
|
-
t << ['PK', 'Name', 'SQL Type', 'Ruby Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
|
25
|
-
connection = ::ActiveRecord::Base.connection
|
26
|
-
connection.columns(table_name).each do |column|
|
27
|
-
pk = if [connection.primary_key(table_name)].flatten.include?(column.name)
|
28
|
-
'Y'
|
29
|
-
else
|
30
|
-
''
|
31
|
-
end
|
32
|
-
t << [pk, column.name, column.sql_type,
|
33
|
-
column.sql_type_metadata.type, column.sql_type_metadata.limit || '',
|
34
|
-
column.sql_type_metadata.precision || '', column.sql_type_metadata.scale || '', column.default || '',
|
35
|
-
column.null, column.comment || '']
|
36
|
-
end
|
37
|
-
t
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
Pry.commands.block_command 'vd' do |name|
|
42
|
-
table_name = VD::get_table_name(name)
|
43
|
-
VD::table_info_vd(table_name)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/lib/arql/connection.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Arql
|
2
|
-
class Connection
|
3
|
-
class << self
|
4
|
-
def open(options)
|
5
|
-
print "Establishing DB connection to #{options[:host]}:#{options[:port]}"
|
6
|
-
ActiveRecord::Base.establish_connection(options)
|
7
|
-
print "\u001b[2K"
|
8
|
-
puts "\rDB connection to #{options[:host]}:#{options[:port]} established\n"
|
9
|
-
$C = ActiveRecord::Base.connection
|
10
|
-
$C.define_singleton_method(:dump) do |filename, no_create_db=false|
|
11
|
-
Arql::Mysqldump.new.dump_database(filename, no_create_db)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|