arql 0.1.2 → 0.1.3

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: dc86cf0d1862e52ea16793c51d8bd46e9c0d9463bbb2c096bb265e524d74edf9
4
- data.tar.gz: d66f20e0a5f969179dcf70404f3a9c4c698618793e51c3bb0ddd928c7668ef8f
3
+ metadata.gz: 61c15f55639c3eb58102f4f03c4c5549edf06433da1037efb62372aad6ce5742
4
+ data.tar.gz: 41d5e0bac8a8d5fdeedaf2d8e23db093be42fb6f8476de674dc1aece8da6c2dd
5
5
  SHA512:
6
- metadata.gz: 5b201e845a4c691a274874b31c9b3a9cd3d23212d47496becea0ad167653f79126071329ba0f1c5bcc4bbeb6552a2c0b240006aa11f8c3ae36828ca931f595e7
7
- data.tar.gz: e2d7bd2a8a3da1122e8624ef09e6854aac9f7708b4c2bd88985d43d0a5610e0fe4a5bfd85e6764492e9c8f7067209de3959fd6364e15ec4da51d0525ed722e87
6
+ metadata.gz: 13a8e6dc10a7953c02e826e7f4bdd4674e41d7a9e436001b92985fcbf280816ebd916d5cd8e4e59368243c9b94e260bf8bddd4f49139d0f1f46b641dac2125d3
7
+ data.tar.gz: 0f128278d9de51ff5f95a1c1f598159b2aaf383da947a312579b093a9fccd898fa3e4b9275531d9739455faea51329283c82ca2d266e81c78901316dabc97c40
data/Gemfile.lock CHANGED
@@ -1,13 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arql (0.1.2)
5
- activerecord (~> 6.0.0)
6
- activesupport (~> 6.0.0)
4
+ arql (0.1.3)
5
+ activerecord (~> 6.0.3)
6
+ activesupport (~> 6.0.3)
7
7
  mysql2 (~> 0.5.3)
8
8
  net-ssh-gateway (~> 2.0.0)
9
9
  pry (~> 0.13.1)
10
10
  pry-byebug (~> 3.9.0)
11
+ pry-doc (~> 1.1.0)
12
+ rainbow (~> 3.0.0)
13
+ terminal-table (~> 1.8.0)
11
14
 
12
15
  GEM
13
16
  remote: https://rubygems.org/
@@ -40,10 +43,18 @@ GEM
40
43
  pry-byebug (3.9.0)
41
44
  byebug (~> 11.0)
42
45
  pry (~> 0.13.0)
46
+ pry-doc (1.1.0)
47
+ pry (~> 0.11)
48
+ yard (~> 0.9.11)
49
+ rainbow (3.0.0)
43
50
  rake (12.3.3)
51
+ terminal-table (1.8.0)
52
+ unicode-display_width (~> 1.1, >= 1.1.1)
44
53
  thread_safe (0.3.6)
45
54
  tzinfo (1.2.7)
46
55
  thread_safe (~> 0.1)
56
+ unicode-display_width (1.7.0)
57
+ yard (0.9.25)
47
58
  zeitwerk (2.3.0)
48
59
 
49
60
  PLATFORMS
data/arql.gemspec CHANGED
@@ -24,9 +24,12 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
 
26
26
  spec.add_dependency 'mysql2', '~> 0.5.3'
27
- spec.add_dependency 'activerecord', '~> 6.0.0'
28
- spec.add_dependency 'activesupport', '~> 6.0.0'
27
+ spec.add_dependency 'activerecord', '~> 6.0.3'
28
+ spec.add_dependency 'activesupport', '~> 6.0.3'
29
29
  spec.add_dependency 'net-ssh-gateway', '~> 2.0.0'
30
30
  spec.add_dependency 'pry', '~> 0.13.1'
31
31
  spec.add_dependency 'pry-byebug', '~> 3.9.0'
32
+ spec.add_dependency 'pry-doc', '~> 1.1.0'
33
+ spec.add_dependency 'rainbow', '~> 3.0.0'
34
+ spec.add_dependency 'terminal-table', '~> 1.8.0'
32
35
  end
data/lib/arql/app.rb CHANGED
@@ -2,6 +2,17 @@ require 'net/ssh/gateway'
2
2
 
3
3
  module Arql
4
4
  class App
5
+
6
+ class << self
7
+ def config
8
+ @@effective_config
9
+ end
10
+
11
+ def local_ssh_proxy_port
12
+ @@local_ssh_proxy_port
13
+ end
14
+ end
15
+
5
16
  def initialize(options)
6
17
  @options = options
7
18
  Connection.open(connect_options)
@@ -21,11 +32,11 @@ module Arql
21
32
 
22
33
  def start_ssh_proxy!
23
34
  ssh_config = effective_config[:ssh]
24
- @ssh_gateway = Net::SSH::Gateway.new(ssh_config[:host], ssh_config[:user])
25
- @local_ssh_proxy_port = @ssh_gateway.open(effective_config[:host], effective_config[:port], ssh_config[:local_port])
35
+ @ssh_gateway = Net::SSH::Gateway.new(ssh_config[:host], ssh_config[:user], ssh_config.slice(:port, :password).symbolize_keys)
36
+ @@local_ssh_proxy_port = @ssh_gateway.open(effective_config[:host], effective_config[:port], ssh_config[:local_port])
26
37
  {
27
38
  host: '127.0.0.1',
28
- port: @local_ssh_proxy_port
39
+ port: @@local_ssh_proxy_port
29
40
  }
30
41
  end
31
42
 
@@ -38,7 +49,7 @@ module Arql
38
49
  end
39
50
 
40
51
  def effective_config
41
- @effective_config ||= selected_config.merge(@options.to_h)
52
+ @@effective_config ||= selected_config.deep_merge(@options.to_h)
42
53
  end
43
54
 
44
55
  def run!
data/lib/arql/cli.rb CHANGED
@@ -14,7 +14,8 @@ module Arql
14
14
  encoding: 'utf8',
15
15
  pool: 5,
16
16
  config_file: default_config_file,
17
- initializer: default_initializer)
17
+ initializer: default_initializer,
18
+ ssh: {})
18
19
 
19
20
 
20
21
  OptionParser.new do |opts|
@@ -34,7 +35,7 @@ module Arql
34
35
  @options.initializer = initializer
35
36
  end
36
37
 
37
- opts.on('-EENVIRON', '--env=ENVIRON', 'Specify config environment.') do |env|
38
+ opts.on('-eENVIRON', '--env=ENVIRON', 'Specify config environment.') do |env|
38
39
  @options.env = env
39
40
  end
40
41
 
@@ -42,31 +43,31 @@ module Arql
42
43
  @options.config_file = config_file
43
44
  end
44
45
 
45
- opts.on('-ADB_ADAPTER', '--db-adapter=DB_ADAPTER', 'Specify DB Adapter, default is mysql2') do |db_adapter|
46
+ opts.on('-aDB_ADAPTER', '--db-adapter=DB_ADAPTER', 'Specify database Adapter, default is mysql2') do |db_adapter|
46
47
  @options.dapter = db_adapter
47
48
  end
48
49
 
49
- opts.on('-HDB_HOST', '--db-host=DB_HOST', 'Specify DB host, if specified -E option will be ignored') do |db_host|
50
+ opts.on('-hDB_HOST', '--db-host=DB_HOST', 'Specify database host') do |db_host|
50
51
  @options.host = db_host
51
52
  end
52
53
 
53
- opts.on('-PDB_PORT', '--db-port=DB_PORT', 'Specify DB port, if specified -E option will be ignored') do |db_port|
54
+ opts.on('-pDB_PORT', '--db-port=DB_PORT', 'Specify database port') do |db_port|
54
55
  @options.port = db_port.to_i
55
56
  end
56
57
 
57
- opts.on('-DDB_NAME', '--db-name=DB_NAME', 'Specify database name, if specified -E option will be ignored') do |db_name|
58
+ opts.on('-dDB_NAME', '--db-name=DB_NAME', 'Specify database name') do |db_name|
58
59
  @options.database = db_name
59
60
  end
60
61
 
61
- opts.on('-UDB_USER', '--db-user=DB_USER', 'Specify database user, if specified -E option will be ignored') do |db_user|
62
+ opts.on('-uDB_USER', '--db-user=DB_USER', 'Specify database user') do |db_user|
62
63
  @options.username = db_user
63
64
  end
64
65
 
65
- opts.on('-pDB_PASSWORD', '--db-password=DB_PASSWORD', 'Specify database password, if specified -E option will be ignored') do |db_password|
66
+ opts.on('-PDB_PASSWORD', '--db-password=DB_PASSWORD', 'Specify database password') do |db_password|
66
67
  @options.password = db_password
67
68
  end
68
69
 
69
- opts.on('-n', '--db-encoding=DB_ENCODING', 'Specify database encoding, default is UTF-8') do |db_encoding|
70
+ opts.on('-n', '--db-encoding=DB_ENCODING', 'Specify database encoding, default is utf8') do |db_encoding|
70
71
  @options.encoding = db_encoding
71
72
  end
72
73
 
@@ -74,11 +75,31 @@ module Arql
74
75
  @options.pool = db_pool
75
76
  end
76
77
 
77
- opts.on('-eCODE', '--eval=CODE', 'evaluate CODE') do |code|
78
+ opts.on('-HSSH_HOST', '--ssh-host=SSH_HOST', 'Specify SSH host') do |ssh_host|
79
+ @options.ssh[:host] = ssh_host
80
+ end
81
+
82
+ opts.on('-OSSH_PORT', '--ssh-port=SSH_PORT', 'Specify SSH port') do |ssh_port|
83
+ @options.ssh[:port] = ssh_port.to_i
84
+ end
85
+
86
+ opts.on('-USSH_USER', '--ssh-user=SSH_USER', 'Specify SSH user') do |ssh_user|
87
+ @options.ssh[:user] = ssh_user
88
+ end
89
+
90
+ opts.on('-WSSH_PASSWORD', '--ssh-password=SSH_PASSWORD', 'Specify SSH password') do |ssh_password|
91
+ @options.ssh[:password] = ssh_password
92
+ end
93
+
94
+ opts.on('-LSSH_LOCAL_PORT', '--ssh-local-port=SSH_LOCAL_PORT', 'Specify local SSH proxy port') do |local_port|
95
+ @options.ssh[:local_port] = local_port.to_i
96
+ end
97
+
98
+ opts.on('-ECODE', '--eval=CODE', 'evaluate CODE') do |code|
78
99
  @options.code = code
79
100
  end
80
101
 
81
- opts.on('-s', '--show-sql', 'Show SQL on STDOUT') do
102
+ opts.on('-S', '--show-sql', 'Show SQL on STDOUT') do
82
103
  @options.show_sql = true
83
104
  end
84
105
 
@@ -86,11 +107,11 @@ module Arql
86
107
  @options.write_sql = file
87
108
  end
88
109
 
89
- opts.on('-aOUTPUT', '--append-sql=OUTPUT', 'Append SQL to OUTPUT file') do |file|
110
+ opts.on('-AOUTPUT', '--append-sql=OUTPUT', 'Append SQL to OUTPUT file') do |file|
90
111
  @options.append_sql = file
91
112
  end
92
113
 
93
- opts.on('-h', '--help', 'Prints this help') do
114
+ opts.on('', '--help', 'Prints this help') do
94
115
  puts opts
95
116
  exit
96
117
  end
@@ -0,0 +1,37 @@
1
+ module Arql::Commands
2
+ module Info
3
+ class << self
4
+ def db_info
5
+ <<~EOF
6
+
7
+ Database Connection Information:
8
+ Host: #{Arql::App.config[:host]}
9
+ Port: #{Arql::App.config[:port]}
10
+ Username: #{Arql::App.config[:username]}
11
+ Password: #{Arql::App.config[:password].gsub(/./, '*')}
12
+ Database: #{Arql::App.config[:database]}
13
+ Adapter: #{Arql::App.config[:adapter]}
14
+ Encoding: #{Arql::App.config[:encoding]}
15
+ Pool Size: #{Arql::App.config[:pool]}
16
+ EOF
17
+ end
18
+
19
+ def ssh_info
20
+ <<~EOF
21
+
22
+ SSH Connection Information:
23
+ Host: #{Arql::App.config[:ssh][:host]}
24
+ Port: #{Arql::App.config[:ssh][:port]}
25
+ Username: #{Arql::App.config[:ssh][:user]}
26
+ Password: #{Arql::App.config[:ssh][:password].gsub(/./, '*')}
27
+ Local Port: #{Arql::App.local_ssh_proxy_port}
28
+ EOF
29
+ end
30
+ end
31
+
32
+ Pry.commands.block_command 'info' do
33
+ puts Info::db_info
34
+ puts Info::ssh_info if Arql::App.config[:ssh].present?
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ require 'terminal-table'
2
+
3
+ module Arql::Commands
4
+ module Models
5
+ class << self
6
+ def models
7
+ Terminal::Table.new do |t|
8
+ t << ['Table Name', 'Model Class', 'Abbr']
9
+ t << :separator
10
+ Arql::Definition.models.each do |definition|
11
+ t << [definition[:table], definition[:model].name, definition[:abbr] || '']
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ Pry.commands.block_command 'models' do
19
+ puts
20
+ puts Models::models
21
+ end
22
+
23
+ Pry.commands.alias_command 'm', 'models'
24
+ Pry.commands.alias_command 'l', 'models'
25
+ Pry.commands.alias_command 'tables', 'models'
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require 'terminal-table'
2
+
3
+ module Arql::Commands
4
+ module Table
5
+ class << self
6
+ def table_info(table_name)
7
+ Terminal::Table.new do |t|
8
+ t << ['PK', 'Name', 'SQL Type', 'Ruby Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
9
+ t << :separator
10
+ connection = ::ActiveRecord::Base.connection
11
+ connection.columns(table_name).each do |column|
12
+ pk = if column.name == connection.primary_key(table_name)
13
+ 'Y'
14
+ else
15
+ ''
16
+ end
17
+ t << [pk, column.name, column.sql_type,
18
+ column.sql_type_metadata.type, column.sql_type_metadata.limit || '',
19
+ column.sql_type_metadata.precision || '', column.sql_type_metadata.scale || '', column.default || '',
20
+ column.null, column.comment || '']
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ Pry.commands.block_command 'table' do |table_name|
28
+ puts
29
+ puts Table::table_info(table_name)
30
+ end
31
+
32
+ Pry.commands.alias_command 't', 'table'
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ require 'arql/commands/info'
2
+ require 'arql/commands/models'
3
+ require 'arql/commands/table'
4
+
5
+ module Arql::Commands
6
+ end
@@ -1,6 +1,13 @@
1
1
  module Arql
2
2
  class Definition
3
+ class << self
4
+ def models
5
+ @@models ||= []
6
+ end
7
+ end
8
+
3
9
  def initialize
10
+ @@models = []
4
11
  ActiveRecord::Base.connection.tap do |conn|
5
12
  conn.tables.each do |table_name|
6
13
  conn.primary_key(table_name).tap do |pkey|
@@ -14,7 +21,16 @@ module Arql
14
21
  end.tap do |clazz|
15
22
  Object.const_set(const_name, clazz).tap do |const|
16
23
  const_name.gsub(/[a-z]*/, '').tap do |abbr|
17
- Object.const_set abbr, const unless Object.const_defined?(abbr)
24
+ unless Object.const_defined?(abbr)
25
+ Object.const_set abbr, const
26
+ abbr_const = abbr
27
+ end
28
+
29
+ @@models << {
30
+ model: const,
31
+ abbr: abbr_const,
32
+ table: table_name
33
+ }
18
34
  end
19
35
  end
20
36
  end
data/lib/arql/id.rb ADDED
@@ -0,0 +1,59 @@
1
+ module Arql
2
+ class ID
3
+ @worker_id_bits = 5
4
+ @data_center_id_bits = 5
5
+ @max_worker_id = -1 ^ (-1 << @worker_id_bits)
6
+ @max_data_center_id = -1 ^ (-1 << @data_center_id_bits)
7
+
8
+ @sequence_bits = 12
9
+ @worker_id_shift = @sequence_bits
10
+ @data_center_id_shift = @sequence_bits + @worker_id_shift
11
+ @timestamp_left_shift = @sequence_bits + @worker_id_bits + @data_center_id_bits
12
+ @sequence_mask = -1 ^ (-1 << @sequence_bits)
13
+
14
+ @id_epoch = (Time.new(2018, 1, 1, 0, 0, 0).to_f * 1000).to_i
15
+ @worker_id = 0
16
+ @data_center_id = 0
17
+ @sequence = 0
18
+
19
+ @last_timestamp = -1
20
+
21
+ class << self
22
+ def long
23
+ ts = (Time.now.to_f * 1000).to_i
24
+ if ts < @last_timestamp
25
+ raise 'Clock moved backwards.'
26
+ end
27
+
28
+ if ts == @last_timestamp
29
+ @sequence = (@sequence + 1) & @sequence_mask
30
+ if (@sequence == 0)
31
+ ts = til_next_millis(@last_timestamp)
32
+ end
33
+ else
34
+ @sequence = 0
35
+ end
36
+ @last_timestamp = ts
37
+
38
+ ((ts - @id_epoch) << @timestamp_left_shift) | (@data_center_id << @data_center_id_shift) | (@worker_id << @worker_id_shift) | @sequence
39
+ end
40
+
41
+ def uuid
42
+ require 'securerandom'
43
+ SecureRandom.uuid.gsub('-', '')
44
+ end
45
+
46
+ private
47
+
48
+ def til_next_millis(last_timestamp)
49
+ ts = (Time.now.to_f * 1000).to_i
50
+ while ts <= last_timestamp
51
+ ts = (Time.now.to_f * 1000).to_i
52
+ end
53
+ ts
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ ::ID = Arql::ID
data/lib/arql/repl.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'pry'
2
2
  require 'pry-byebug'
3
+ require 'arql/commands'
4
+ require 'rainbow'
3
5
 
4
6
  module Arql
5
7
  class Repl
@@ -29,7 +31,7 @@ module Arql
29
31
  else
30
32
  nest_level_prompt = "(#{obj}:#{nest_level})"
31
33
  end
32
- "ARQL#{nest_level_prompt} -> "
34
+ "%s#{nest_level_prompt} %s " % [Rainbow('ARQL').red, Rainbow('❯').green]
33
35
  end]
34
36
  end
35
37
  end
data/lib/arql/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Arql
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/arql.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'active_support/all'
2
2
  require 'active_record'
3
3
  require "arql/version"
4
+ require 'arql/id'
4
5
  require 'arql/multi_io'
5
6
  require "arql/connection"
6
7
  require "arql/definition"
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.2
4
+ version: 0.1.3
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-05-07 00:00:00.000000000 Z
11
+ date: 2020-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 6.0.0
33
+ version: 6.0.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 6.0.0
40
+ version: 6.0.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.0
47
+ version: 6.0.3
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 6.0.0
54
+ version: 6.0.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: net-ssh-gateway
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,48 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.9.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-doc
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.1.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rainbow
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 3.0.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.0.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: terminal-table
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.8.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.8.0
97
139
  description: Use ActiveRecord and Pry as your favorite SQL query editor.
98
140
  email:
99
141
  - liuxiang921@gmail.com
@@ -116,8 +158,13 @@ files:
116
158
  - lib/arql.rb
117
159
  - lib/arql/app.rb
118
160
  - lib/arql/cli.rb
161
+ - lib/arql/commands.rb
162
+ - lib/arql/commands/info.rb
163
+ - lib/arql/commands/models.rb
164
+ - lib/arql/commands/table.rb
119
165
  - lib/arql/connection.rb
120
166
  - lib/arql/definition.rb
167
+ - lib/arql/id.rb
121
168
  - lib/arql/multi_io.rb
122
169
  - lib/arql/repl.rb
123
170
  - lib/arql/version.rb