arql 0.3.5 → 0.3.8
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/.gitignore +1 -0
- data/Gemfile.lock +3 -3
- data/lib/arql/app.rb +6 -0
- data/lib/arql/commands/vd.rb +46 -0
- data/lib/arql/commands.rb +1 -0
- data/lib/arql/connection.rb +3 -0
- data/lib/arql/definition.rb +45 -10
- data/lib/arql/ext/active_record/connection_adapters/abstract_mysql_adapter.rb +53 -0
- data/lib/arql/ext/active_record/connection_adapters/postgresql/schema_statements.rb +8 -0
- data/lib/arql/ext/array.rb +29 -0
- data/lib/arql/ssh_proxy.rb +4 -0
- data/lib/arql/vd.rb +42 -0
- data/lib/arql/version.rb +1 -1
- data/lib/arql.rb +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49ad54c58145e93df8e50ed2008831982b5b2274d78db75d22b074f54b807a5d
|
4
|
+
data.tar.gz: 9dae3245f6a5c16338cf894ecc08a44550e69b1fcef574a70b13d70016ee3a3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 486887bee40dc5fa2f5d4f857990a43026f98e73b2ede3d4a1ad9d0a7bf2c36ef46411ae102470c1545d259e11a3f4bc495998446432255be6e591bbeb89c2f6
|
7
|
+
data.tar.gz: be23a8df1e4a7f161a2363f467c107004e52203fe85a1c29af185d519d48bcd05a05f94017b5fe77f2dd9d981e68d441e3627da35eb84ddc869bcea790013d06
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
arql (0.3.
|
4
|
+
arql (0.3.8)
|
5
5
|
activerecord (>= 6.0.3, < 6.2.0)
|
6
6
|
activesupport (~> 6.0.3)
|
7
7
|
caxlsx (~> 3.0.2)
|
@@ -53,7 +53,7 @@ GEM
|
|
53
53
|
net-ssh (6.1.0)
|
54
54
|
net-ssh-gateway (2.0.0)
|
55
55
|
net-ssh (>= 4.0.0)
|
56
|
-
nokogiri (1.13.
|
56
|
+
nokogiri (1.13.6-x86_64-darwin)
|
57
57
|
racc (~> 1.4)
|
58
58
|
pry (0.13.1)
|
59
59
|
coderay (~> 1.1)
|
@@ -82,7 +82,7 @@ GEM
|
|
82
82
|
webrick (1.7.0)
|
83
83
|
yard (0.9.27)
|
84
84
|
webrick (~> 1.7.0)
|
85
|
-
zeitwerk (2.5.
|
85
|
+
zeitwerk (2.5.4)
|
86
86
|
|
87
87
|
PLATFORMS
|
88
88
|
ruby
|
data/lib/arql/app.rb
CHANGED
@@ -29,8 +29,14 @@ module Arql
|
|
29
29
|
App.env = @options.env
|
30
30
|
App.connect_options = connect_options
|
31
31
|
Connection.open(App.connect_options)
|
32
|
+
print "Defining models..."
|
32
33
|
@definition = Definition.new(effective_config)
|
34
|
+
print "\u001b[2K"
|
35
|
+
puts "\rModels defined"
|
36
|
+
print "Running initializers..."
|
33
37
|
load_initializer!
|
38
|
+
print "\u001b[2K"
|
39
|
+
puts "\rInitializers loaded"
|
34
40
|
App.instance = self
|
35
41
|
end
|
36
42
|
|
@@ -0,0 +1,46 @@
|
|
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/commands.rb
CHANGED
data/lib/arql/connection.rb
CHANGED
@@ -2,7 +2,10 @@ module Arql
|
|
2
2
|
class Connection
|
3
3
|
class << self
|
4
4
|
def open(options)
|
5
|
+
print "Establishing DB connection to #{options[:host]}:#{options[:port]}"
|
5
6
|
ActiveRecord::Base.establish_connection(options)
|
7
|
+
print "\u001b[2K"
|
8
|
+
puts "\rDB connection to #{options[:host]}:#{options[:port]} established\n"
|
6
9
|
$C = ActiveRecord::Base.connection
|
7
10
|
$C.define_singleton_method(:dump) do |filename, no_create_db=false|
|
8
11
|
Arql::Mysqldump.new.dump_database(filename, no_create_db)
|
data/lib/arql/definition.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'arql/concerns'
|
2
|
+
require 'arql/vd'
|
3
|
+
|
2
4
|
module Arql
|
3
5
|
module Extension
|
4
6
|
extend ActiveSupport::Concern
|
@@ -9,6 +11,15 @@ module Arql
|
|
9
11
|
}
|
10
12
|
end
|
11
13
|
|
14
|
+
def vd
|
15
|
+
VD.new do |vd|
|
16
|
+
vd << ['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']
|
17
|
+
self.class.connection.columns(self.class.table_name).each do |column|
|
18
|
+
vd << [column.name, read_attribute(column.name), column.sql_type, column.comment || '']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
12
23
|
def v
|
13
24
|
t = []
|
14
25
|
t << ['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']
|
@@ -49,6 +60,12 @@ module Arql
|
|
49
60
|
puts Commands::Table::table_info_table(table_name)
|
50
61
|
end
|
51
62
|
|
63
|
+
def vd
|
64
|
+
table_name = Commands::Table::get_table_name(name)
|
65
|
+
Commands::VD::table_info_vd(table_name)
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
52
69
|
def v
|
53
70
|
table_name = Commands::Table::get_table_name(name)
|
54
71
|
Commands::Table::table_info(table_name)
|
@@ -91,18 +108,21 @@ module Arql
|
|
91
108
|
end
|
92
109
|
@@models = []
|
93
110
|
ActiveRecord::Base.connection.tap do |conn|
|
94
|
-
conn.tables
|
95
|
-
|
96
|
-
|
111
|
+
tables = conn.tables
|
112
|
+
comments = conn.table_comment_of_tables(tables)
|
113
|
+
primary_keys = conn.primary_keys_of_tables(tables)
|
114
|
+
tables.each do |table_name|
|
115
|
+
table_comment = comments[table_name]
|
116
|
+
primary_keys[table_name].tap do |pkey|
|
97
117
|
table_name.camelize.tap do |const_name|
|
98
118
|
const_name = 'Modul' if const_name == 'Module'
|
99
119
|
const_name = 'Clazz' if const_name == 'Class'
|
100
120
|
Class.new(::ArqlModel) do
|
101
121
|
include Arql::Extension
|
102
|
-
if pkey.is_a?(Array)
|
122
|
+
if pkey.is_a?(Array) && pkey.size > 1
|
103
123
|
self.primary_keys = pkey
|
104
124
|
else
|
105
|
-
self.primary_key = pkey
|
125
|
+
self.primary_key = pkey&.first
|
106
126
|
end
|
107
127
|
self.table_name = table_name
|
108
128
|
self.inheritance_column = nil
|
@@ -169,18 +189,29 @@ module Arql
|
|
169
189
|
end.t
|
170
190
|
end
|
171
191
|
end)
|
172
|
-
|
173
|
-
|
174
|
-
|
192
|
+
|
193
|
+
tables = conn.tables
|
194
|
+
if conn.adapter_name == 'Mysql2'
|
195
|
+
require 'arql/ext/active_record/connection_adapters/abstract_mysql_adapter'
|
196
|
+
comments = conn.table_comment_of_tables(tables)
|
197
|
+
primary_keys = conn.primary_keys_of_tables(tables)
|
198
|
+
else
|
199
|
+
comments = tables.map { |t| [t, conn.table_comment(t)] }.to_h
|
200
|
+
primary_keys = tables.map { |t| [t, conn.primary_keys(t)] }.to_h
|
201
|
+
end
|
202
|
+
|
203
|
+
tables.each do |table_name|
|
204
|
+
table_comment = comments[table_name]
|
205
|
+
primary_keys[table_name].tap do |pkey|
|
175
206
|
table_name.camelize.tap do |const_name|
|
176
207
|
const_name = 'Modul' if const_name == 'Module'
|
177
208
|
const_name = 'Clazz' if const_name == 'Class'
|
178
209
|
Class.new(::ArqlModel) do
|
179
210
|
include Arql::Extension
|
180
|
-
if pkey.is_a?(Array)
|
211
|
+
if pkey.is_a?(Array) && pkey.size > 1
|
181
212
|
self.primary_keys = pkey
|
182
213
|
else
|
183
|
-
self.primary_key = pkey
|
214
|
+
self.primary_key = pkey&.first
|
184
215
|
end
|
185
216
|
self.table_name = table_name
|
186
217
|
self.inheritance_column = nil
|
@@ -229,6 +260,10 @@ module Arql
|
|
229
260
|
records.t(*attrs, **options)
|
230
261
|
end
|
231
262
|
|
263
|
+
def vd(*attrs, **options)
|
264
|
+
records.vd(*attrs, **options)
|
265
|
+
end
|
266
|
+
|
232
267
|
def v
|
233
268
|
records.v
|
234
269
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
class AbstractMysqlAdapter
|
6
|
+
|
7
|
+
def extract_schema_qualified_name_of_tables(table_names)
|
8
|
+
table_names.map do |string|
|
9
|
+
schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/)
|
10
|
+
schema, name = nil, schema unless name
|
11
|
+
[schema, name]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def quoted_scope_of_tables(names = nil)
|
16
|
+
extract_schema_qualified_name_of_tables(names).map do |(schema, name)|
|
17
|
+
scope = {}
|
18
|
+
scope[:schema] = schema ? quote(schema) : "database()"
|
19
|
+
scope[:name] = quote(name) if name
|
20
|
+
scope
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def primary_keys_of_tables(table_names) # :nodoc:
|
25
|
+
raise ArgumentError unless table_names.present?
|
26
|
+
|
27
|
+
scopes = quoted_scope_of_tables(table_names)
|
28
|
+
|
29
|
+
res = query(<<~SQL, "SCHEMA")
|
30
|
+
SELECT table_name, column_name
|
31
|
+
FROM information_schema.statistics
|
32
|
+
WHERE index_name = 'PRIMARY'
|
33
|
+
AND (table_schema, table_name) in
|
34
|
+
(#{scopes.map { |scope| "(#{scope[:schema]}, #{scope[:name]})" }.join(', ')})
|
35
|
+
ORDER BY seq_in_index
|
36
|
+
SQL
|
37
|
+
|
38
|
+
res.group_by(&:first).map { |table, vlaues| [table, vlaues.map(&:last)] }.to_h
|
39
|
+
end
|
40
|
+
|
41
|
+
def table_comment_of_tables(table_names) # :nodoc:
|
42
|
+
scopes = quoted_scope_of_tables(table_names)
|
43
|
+
|
44
|
+
query(<<~SQL, "SCHEMA").presence.try(&:to_h)
|
45
|
+
SELECT table_name, table_comment
|
46
|
+
FROM information_schema.tables
|
47
|
+
WHERE (table_schema, table_name) in
|
48
|
+
(#{scopes.map { |scope| "(#{scope[:schema]}, #{scope[:name]})" }.join(', ')})
|
49
|
+
SQL
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/arql/ext/array.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'arql/vd'
|
2
|
+
|
1
3
|
class Array
|
2
4
|
def to_insert_sql(batch_size=500)
|
3
5
|
raise 'All element should be an ActiveRecord instance object' unless all? { |e| e.is_a?(ActiveRecord::Base) }
|
@@ -48,6 +50,33 @@ class Array
|
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
53
|
+
def vd(*attrs, **options)
|
54
|
+
if (attrs.present? || options.present? && options[:except]) && present? && first.is_a?(ActiveRecord::Base)
|
55
|
+
column_names = first.attribute_names.map(&:to_sym)
|
56
|
+
attrs = attrs.flat_map { |e| e.is_a?(Regexp) ? column_names.grep(e) : e }.uniq
|
57
|
+
if options.present? && options[:except]
|
58
|
+
attrs = column_names if attrs.empty?
|
59
|
+
if options[:except].is_a?(Regexp)
|
60
|
+
attrs.reject! { |e| e =~ options[:except] }
|
61
|
+
else
|
62
|
+
attrs -= [options[:except]].flatten
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Arql::VD.new do |vd|
|
67
|
+
vd << attrs
|
68
|
+
each do |e|
|
69
|
+
vd << e.attributes.values_at(*attrs.map(&:to_s))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
else
|
73
|
+
Arql::VD.new do |vd|
|
74
|
+
v.each { |row| vd << row if row }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
51
80
|
def v
|
52
81
|
return self unless present?
|
53
82
|
t = []
|
data/lib/arql/ssh_proxy.rb
CHANGED
@@ -8,9 +8,13 @@ module Arql
|
|
8
8
|
attr_accessor :config, :ssh_gateway, :local_ssh_proxy_port
|
9
9
|
|
10
10
|
def connect(config)
|
11
|
+
print "Establishing SSH connection to #{config[:host]}:#{config[:port]}"
|
11
12
|
@config = config
|
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))
|
13
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
|
14
18
|
end
|
15
19
|
|
16
20
|
def reconnect
|
data/lib/arql/vd.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Arql
|
4
|
+
class VD
|
5
|
+
COMMAND = 'vd'
|
6
|
+
|
7
|
+
attr_accessor :rows
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
return unless check_command_installation
|
11
|
+
@rows = []
|
12
|
+
yield self
|
13
|
+
command = "#{COMMAND} -f csv"
|
14
|
+
IO.popen(command, 'w+') do |io|
|
15
|
+
io.puts(csv)
|
16
|
+
io.close_write
|
17
|
+
end
|
18
|
+
print "\033[5q"
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(row)
|
22
|
+
rows << row
|
23
|
+
end
|
24
|
+
|
25
|
+
def csv
|
26
|
+
CSV.generate do |csv|
|
27
|
+
rows.each do |row|
|
28
|
+
csv << row
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_command_installation
|
34
|
+
`which #{COMMAND}`
|
35
|
+
if $?.exitstatus != 0
|
36
|
+
puts "Please install vd (visidata) command, see: https://www.visidata.org/"
|
37
|
+
else
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/arql/version.rb
CHANGED
data/lib/arql.rb
CHANGED
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.3.
|
4
|
+
version: 0.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liu Xiang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|
@@ -245,12 +245,15 @@ files:
|
|
245
245
|
- lib/arql/commands/sandbox.rb
|
246
246
|
- lib/arql/commands/show_sql.rb
|
247
247
|
- lib/arql/commands/table.rb
|
248
|
+
- lib/arql/commands/vd.rb
|
248
249
|
- lib/arql/concerns.rb
|
249
250
|
- lib/arql/concerns/global_data_definition.rb
|
250
251
|
- lib/arql/concerns/table_data_definition.rb
|
251
252
|
- lib/arql/connection.rb
|
252
253
|
- lib/arql/definition.rb
|
253
254
|
- lib/arql/ext.rb
|
255
|
+
- lib/arql/ext/active_record/connection_adapters/abstract_mysql_adapter.rb
|
256
|
+
- lib/arql/ext/active_record/connection_adapters/postgresql/schema_statements.rb
|
254
257
|
- lib/arql/ext/array.rb
|
255
258
|
- lib/arql/ext/hash.rb
|
256
259
|
- lib/arql/ext/kernel.rb
|
@@ -263,6 +266,7 @@ files:
|
|
263
266
|
- lib/arql/repl.rb
|
264
267
|
- lib/arql/ssh_proxy.rb
|
265
268
|
- lib/arql/ssh_proxy_patch.rb
|
269
|
+
- lib/arql/vd.rb
|
266
270
|
- lib/arql/version.rb
|
267
271
|
homepage: https://github.com/lululau/arql
|
268
272
|
licenses:
|