arql 0.1.29 → 0.2.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 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