arql 0.1.29 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 823a5527aa1dfc5e12de5284dc43d7afcba4978608a00f31bcf53e8058e4ad67
4
- data.tar.gz: ed6026bf27d00fc953400a4776081d7f17de730dc70e96143cd448b42e21d779
3
+ metadata.gz: 44dc8e634d413b6c736c6335ce19feeb4f9b927bd5f61f8697e9102e16ce79e4
4
+ data.tar.gz: 1202b099108a83827a851e594c3511e078f6af61d3b901106e193c0a7a42c6ec
5
5
  SHA512:
6
- metadata.gz: a47d663c5b8a2297e16f895b1d74add187da511b3abeec29e142d03a2ec6ae9fe577e942c8a471590f6312c8f937945912ea12db1e620fcf29973dbac5f4297f
7
- data.tar.gz: f700d21883edbddef9c82f748dbc01c99ba984cd52048a5e9e93fc29d701036ada9fe07441746020b400a8ed632343dae3a6cdd3d04848fc0a2781b2875c9006
6
+ metadata.gz: 48233713c1b9364591a0d7d782181a9484976242fd7361927e2d8d30f5f0104e4a860a1c66bb7575da6d6e46f7294324e1c8d633fa1285e37bcf1470fe716e0b
7
+ data.tar.gz: 7877f7dd188f9f4c3b99d049a0b4b64f0e1b71e5c5daece18fabf107d26df3a69f8bf8170549430f48e300582b8660c2a23ba4e59aa69b6561d762670e3d3c4b
@@ -1,15 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arql (0.1.29)
4
+ arql (0.2.0)
5
5
  activerecord (~> 6.0.3)
6
6
  activesupport (~> 6.0.3)
7
+ caxlsx (~> 3.0.2)
7
8
  mysql2 (~> 0.5.3)
8
9
  net-ssh-gateway (~> 2.0.0)
9
10
  pry (~> 0.13.1)
10
11
  pry-byebug (~> 3.9.0)
11
12
  pry-doc (~> 1.1.0)
12
13
  rainbow (~> 3.0.0)
14
+ roo (~> 2.8.3)
13
15
  sqlite3 (~> 1.4)
14
16
  table_print (~> 1.5.6)
15
17
  terminal-table (~> 1.8.0)
@@ -17,28 +19,38 @@ PATH
17
19
  GEM
18
20
  remote: https://rubygems.org/
19
21
  specs:
20
- activemodel (6.0.3.1)
21
- activesupport (= 6.0.3.1)
22
- activerecord (6.0.3.1)
23
- activemodel (= 6.0.3.1)
24
- activesupport (= 6.0.3.1)
25
- activesupport (6.0.3.1)
22
+ activemodel (6.0.3.2)
23
+ activesupport (= 6.0.3.2)
24
+ activerecord (6.0.3.2)
25
+ activemodel (= 6.0.3.2)
26
+ activesupport (= 6.0.3.2)
27
+ activesupport (6.0.3.2)
26
28
  concurrent-ruby (~> 1.0, >= 1.0.2)
27
29
  i18n (>= 0.7, < 2)
28
30
  minitest (~> 5.1)
29
31
  tzinfo (~> 1.1)
30
32
  zeitwerk (~> 2.2, >= 2.2.2)
31
33
  byebug (11.1.3)
32
- coderay (1.1.2)
33
- concurrent-ruby (1.1.6)
34
- i18n (1.8.2)
34
+ caxlsx (3.0.2)
35
+ htmlentities (~> 4.3, >= 4.3.4)
36
+ mimemagic (~> 0.3)
37
+ nokogiri (~> 1.10, >= 1.10.4)
38
+ rubyzip (>= 1.3.0, < 3)
39
+ coderay (1.1.3)
40
+ concurrent-ruby (1.1.7)
41
+ htmlentities (4.3.4)
42
+ i18n (1.8.5)
35
43
  concurrent-ruby (~> 1.0)
36
44
  method_source (1.0.0)
45
+ mimemagic (0.3.5)
46
+ mini_portile2 (2.4.0)
37
47
  minitest (5.14.1)
38
48
  mysql2 (0.5.3)
39
- net-ssh (6.0.2)
49
+ net-ssh (6.1.0)
40
50
  net-ssh-gateway (2.0.0)
41
51
  net-ssh (>= 4.0.0)
52
+ nokogiri (1.10.10)
53
+ mini_portile2 (~> 2.4.0)
42
54
  pry (0.13.1)
43
55
  coderay (~> 1.1)
44
56
  method_source (~> 1.0)
@@ -50,8 +62,12 @@ GEM
50
62
  yard (~> 0.9.11)
51
63
  rainbow (3.0.0)
52
64
  rake (12.3.3)
65
+ roo (2.8.3)
66
+ nokogiri (~> 1)
67
+ rubyzip (>= 1.3.0, < 3.0.0)
68
+ rubyzip (2.3.0)
53
69
  sqlite3 (1.4.2)
54
- table_print (1.5.6)
70
+ table_print (1.5.7)
55
71
  terminal-table (1.8.0)
56
72
  unicode-display_width (~> 1.1, >= 1.1.1)
57
73
  thread_safe (0.3.6)
@@ -59,7 +75,7 @@ GEM
59
75
  thread_safe (~> 0.1)
60
76
  unicode-display_width (1.7.0)
61
77
  yard (0.9.25)
62
- zeitwerk (2.3.0)
78
+ zeitwerk (2.4.0)
63
79
 
64
80
  PLATFORMS
65
81
  ruby
@@ -37,4 +37,6 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency 'rainbow', '~> 3.0.0'
38
38
  spec.add_dependency 'terminal-table', '~> 1.8.0'
39
39
  spec.add_dependency 'table_print', '~> 1.5.6'
40
+ spec.add_dependency 'roo', '~> 2.8.3'
41
+ spec.add_dependency 'caxlsx', '~> 3.0.2'
40
42
  end
@@ -1,4 +1,7 @@
1
1
  require 'table_print'
2
+ require 'roo'
3
+ require 'caxlsx'
4
+ require 'csv'
2
5
  require "arql/version"
3
6
  require 'arql/id'
4
7
  require 'arql/multi_io'
@@ -4,11 +4,19 @@ module Arql
4
4
  class App
5
5
 
6
6
  class << self
7
- attr_accessor :log_io, :env
7
+ attr_accessor :log_io, :env, :prompt
8
8
 
9
9
  def config
10
10
  @@effective_config
11
11
  end
12
+
13
+ def prompt
14
+ if env
15
+ env
16
+ else
17
+ File.basename(@@effective_config[:database])
18
+ end
19
+ end
12
20
  end
13
21
 
14
22
  def initialize(options)
@@ -64,13 +72,23 @@ module Arql
64
72
  if @options.env.present? && !config[@options.env].present?
65
73
  STDERR.puts "Specified ENV `#{@options.env}' not exists"
66
74
  end
67
- sc = config[@options.env]
68
- sc[:database] = File.expand_path(sc[:database]) if sc[:adapter] == 'sqlite3'
69
- sc
75
+ if env = @options.env
76
+ config[env]
77
+ else
78
+ {}
79
+ end
70
80
  end
71
81
 
72
82
  def effective_config
73
- @@effective_config ||= selected_config.deep_merge(@options.to_h)
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
74
92
  end
75
93
 
76
94
  def run!
@@ -37,7 +37,7 @@ module Arql
37
37
  end
38
38
 
39
39
  opts.on('-aDB_ADAPTER', '--db-adapter=DB_ADAPTER', 'Specify database Adapter, default is mysql2') do |db_adapter|
40
- @options.dapter = db_adapter
40
+ @options.adapter = db_adapter
41
41
  end
42
42
 
43
43
  opts.on('-hDB_HOST', '--db-host=DB_HOST', 'Specify database host') do |db_host|
@@ -26,6 +26,14 @@ module Arql
26
26
  self.class.to_upsert_sql([self])
27
27
  end
28
28
 
29
+ def write_csv(filename, *fields, **options)
30
+ [self].write_csv(filename, *fields, **options)
31
+ end
32
+
33
+ def write_excel(filename, *fields, **options)
34
+ [self].write_excel(filename, *fields, **options)
35
+ end
36
+
29
37
  included do
30
38
  end
31
39
 
@@ -175,6 +183,15 @@ module Arql
175
183
  def v
176
184
  records.v
177
185
  end
186
+
187
+ def write_csv(filename, *fields, **options)
188
+ records.write_csv(filename, *fields, **options)
189
+ end
190
+
191
+ def write_excel(filename, *fields, **options)
192
+ records.write_excel(filename, *fields, **options)
193
+ end
194
+
178
195
  end
179
196
  end
180
197
  end
@@ -62,4 +62,47 @@ class Array
62
62
  end
63
63
  t
64
64
  end
65
+
66
+ def write_csv(filename, *fields, **options)
67
+ generate_csv(filename, **options) do |csv|
68
+ if size > 0 && first.is_a?(ActiveRecord::Base)
69
+ if fields.empty?
70
+ fields = first.attributes.keys
71
+ else
72
+ fields = fields.map(&:to_s)
73
+ end
74
+ csv << fields
75
+ end
76
+ each do |row|
77
+ if row.is_a?(Array)
78
+ csv << row.map(&:to_s)
79
+ else
80
+ csv << row.slice(fields).values.map(&:to_s)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ def write_excel(filename, *fields, **options)
87
+ sheet_name = options[:sheet_name] || 'Sheet1'
88
+ generate_excel(filename) do |workbook|
89
+ workbook.add_worksheet(name: sheet_name) do |sheet|
90
+ if size > 0 && first.is_a?(ActiveRecord::Base)
91
+ if fields.empty?
92
+ fields = first.attributes.keys
93
+ else
94
+ fields = fields.map(&:to_s)
95
+ end
96
+ sheet.add_row(fields, types: [:string] * fields.size)
97
+ end
98
+ each do |row|
99
+ if row.is_a?(Array)
100
+ sheet.add_row(row.map(&:to_s), types: [:string] * row.size)
101
+ else
102
+ sheet.add_row(row.slice(fields).values.map(&:to_s), types: [:string] * fields.size)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
65
108
  end
@@ -0,0 +1,25 @@
1
+ class Hash
2
+ def write_excel(filename)
3
+ generate_excel(filename) do |workbook|
4
+ each do |sheet_name, sheet_data|
5
+ workbook.add_worksheet(name: sheet_name) do |sheet|
6
+ if sheet_data.is_a?(Hash) && sheet_data[:fields].present?
7
+ fields = sheet_data[:fields].map(&:to_s)
8
+ else
9
+ fields = sheet_data[:data].first.attributes.keys
10
+ end
11
+ sheet.add_row(fields, types: [:string] * fields.size)
12
+ sheet_data = sheet_data[:data]
13
+ end
14
+ sheet_data.each do |row|
15
+ if row.is_a?(Array)
16
+ sheet.add_row(row.map(&:to_s), types: [:string] * row.size)
17
+ else
18
+ sheet.add_row(row.slice(fields).values.map(&:to_s), types: [:string] * fields.size)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,105 @@
1
1
  module Kernel
2
+ CSV_BOM = "\xef\xbb\xbf"
3
+
2
4
  def sql(sql)
3
5
  ActiveRecord::Base.connection.exec_query(sql)
4
6
  end
7
+
8
+ def print_tables(format = :md)
9
+ require 'terminal-table'
10
+
11
+ tables = ActiveRecord::Base.connection.tables.map do |table_name|
12
+ {
13
+ table: table_name,
14
+ table_comment: ActiveRecord::Base.connection.table_comment(table_name) || '',
15
+ columns: ::ActiveRecord::Base.connection.columns(table_name)
16
+ }
17
+ end
18
+
19
+ outputs = tables.map do |table|
20
+ table_name = table[:table]
21
+ table_comment = table[:table_comment]
22
+ case format
23
+ when :md
24
+ "# #{table_name} #{table_comment}\n\n" +
25
+ Terminal::Table.new { |t|
26
+ t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
27
+ t.rows = table[:columns].map { |column|
28
+ pk = if column.name == ::ActiveRecord::Base.connection.primary_key(table_name)
29
+ 'Y'
30
+ else
31
+ ''
32
+ end
33
+ [pk, "`#{column.name}`", column.sql_type, column.sql_type_metadata.limit || '', column.sql_type_metadata.precision || '',
34
+ column.sql_type_metadata.scale || '', column.default || '', column.null, column.comment || '']
35
+ }
36
+ t.style = {
37
+ border_top: false,
38
+ border_bottom: false,
39
+ border_i: '|'
40
+ }
41
+ }.to_s.lines.map { |l| ' ' + l }.join
42
+ when :org
43
+ "* #{table_name} #{table_comment}\n\n" +
44
+ Terminal::Table.new { |t|
45
+ t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
46
+ t.rows = table[:columns].map { |column|
47
+ pk = if column.name == ::ActiveRecord::Base.connection.primary_key(table_name)
48
+ 'Y'
49
+ else
50
+ ''
51
+ end
52
+ [pk, "=#{column.name}=", column.sql_type, column.sql_type_metadata.limit || '', column.sql_type_metadata.precision || '',
53
+ column.sql_type_metadata.scale || '', column.default || '', column.null, column.comment || '']
54
+ }
55
+ t.style = {
56
+ border_top: false,
57
+ border_bottom: false,
58
+ }
59
+ }.to_s.lines.map { |l| ' ' + l.gsub(/^\+|\+$/, '|') }.join
60
+ when :sql
61
+ "-- Table: #{table_name}\n\n" + ActiveRecord::Base.connection.exec_query("show create table `#{table_name}`").rows.last.last + ';'
62
+ end
63
+ end
64
+
65
+ outputs.each { |out| puts out; puts }
66
+ end
67
+
68
+ def generate_csv(filename, **options, &block)
69
+ opts = {
70
+ col_sep: "\t",
71
+ row_sep: "\r\n"
72
+ }
73
+ opts.merge!(options.except(:encoding))
74
+ encoding = options[:encoding] || 'UTF-16LE'
75
+ File.open(File.expand_path(filename), "w:#{encoding}") do |file|
76
+ file.write(CSV_BOM)
77
+ file.write CSV.generate(**opts, &block)
78
+ end
79
+ end
80
+
81
+ def parse_csv(filename, **options)
82
+ encoding = options[:encoding] || 'UTF-16'
83
+ opts = {
84
+ headers: false,
85
+ col_sep: "\t",
86
+ row_sep: "\r\n"
87
+ }
88
+ opts.merge!(options.except(:encoding))
89
+ CSV.parse(IO.read(File.expand_path(filename), encoding: encoding, binmode: true).encode('UTF-8'), **opts).to_a
90
+ end
91
+
92
+ def generate_excel(filename)
93
+ Axlsx::Package.new do |package|
94
+ yield(package.workbook)
95
+ package.serialize(filename)
96
+ end
97
+ end
98
+
99
+ def parse_excel(filename)
100
+ xlsx = Roo::Excelx.new(File.expand_path(filename))
101
+ xlsx.sheets.each_with_object({}) do |sheet_name, result|
102
+ result[sheet_name] = xlsx.sheet(sheet_name).to_a
103
+ end
104
+ end
5
105
  end
@@ -7,7 +7,7 @@ module Arql
7
7
  class Repl
8
8
  def initialize
9
9
  Pry.config.prompt = Pry::Prompt.new("", "", prompt)
10
- main_object.pry
10
+ Pry.start
11
11
  end
12
12
 
13
13
  def main_object
@@ -29,9 +29,13 @@ module Arql
29
29
  if obj == main_object && nest_level == 0
30
30
  nest_level_prompt = ''
31
31
  else
32
- nest_level_prompt = "(#{obj}:#{nest_level})"
32
+ nest_level_prompt = if nest_level.zero?
33
+ "(#{obj})"
34
+ else
35
+ "(#{obj}:#{nest_level})"
36
+ end
33
37
  end
34
- "%s#{Rainbow('@').green}%s#{nest_level_prompt} %s " % [Rainbow('ARQL').red, Rainbow(App.env).yellow, Rainbow('❯').green]
38
+ "%s#{Rainbow('@').green}%s#{nest_level_prompt} %s " % [Rainbow('ARQL').red, Rainbow(App.prompt).yellow, Rainbow('❯').green]
35
39
  end]
36
40
  end
37
41
  end
@@ -1,3 +1,3 @@
1
1
  module Arql
2
- VERSION = "0.1.29"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.29
4
+ version: 0.2.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: 2020-07-21 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -164,6 +164,34 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 1.5.6
167
+ - !ruby/object:Gem::Dependency
168
+ name: roo
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 2.8.3
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 2.8.3
181
+ - !ruby/object:Gem::Dependency
182
+ name: caxlsx
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 3.0.2
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 3.0.2
167
195
  description: Use ActiveRecord and Pry as your favorite SQL query editor.
168
196
  email:
169
197
  - liuxiang921@gmail.com
@@ -199,6 +227,7 @@ files:
199
227
  - lib/arql/definition.rb
200
228
  - lib/arql/ext.rb
201
229
  - lib/arql/ext/array.rb
230
+ - lib/arql/ext/hash.rb
202
231
  - lib/arql/ext/kernel.rb
203
232
  - lib/arql/ext/object.rb
204
233
  - lib/arql/ext/string.rb