arql 0.1.30

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.
@@ -0,0 +1,23 @@
1
+ module Arql::Commands
2
+ module Reconnect
3
+ class << self
4
+ def reconnect
5
+ Arql::SSHProxy.reconnect if Arql::App.config[:ssh].present?
6
+ ActiveRecord::Base.connection.reconnect! unless ActiveRecord::Base.connection.active?
7
+ end
8
+
9
+ def reconnect!
10
+ Arql::SSHProxy.reconnect! if Arql::App.config[:ssh].present?
11
+ ActiveRecord::Base.connection.reconnect!
12
+ end
13
+ end
14
+
15
+ Pry.commands.block_command 'reconnect' do
16
+ Reconnect.reconnect
17
+ end
18
+
19
+ Pry.commands.block_command 'reconnect!' do
20
+ Reconnect.reconnect!
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ module Arql::Commands
2
+ module Redefine
3
+ class << self
4
+ def redefine
5
+ Arql::Definition.redefine
6
+ end
7
+ end
8
+
9
+ Pry.commands.block_command 'redefine' do
10
+ Redefine.redefine
11
+ end
12
+
13
+ Pry.commands.alias_command 'redef', 'redefine'
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module Arql::Commands
2
+ module ShowSql
3
+ class << self
4
+ def show
5
+ return if Arql::App.log_io.is_a?(Arql::MultiIO) && Arql::App.log_io.include?(STDOUT)
6
+ Arql::App.log_io ||= Arql::MultiIO.new
7
+ ActiveRecord::Base.logger = Logger.new(Arql::App.log_io)
8
+ Arql::App.log_io << STDOUT
9
+ end
10
+
11
+ def hide
12
+ return if !Arql::App.log_io.is_a?(Arql::MultiIO) || !Arql::App.log_io.include?(STDOUT)
13
+ Arql::App.log_io.delete(STDOUT)
14
+ end
15
+ end
16
+
17
+ Pry.commands.block_command 'show-sql' do
18
+ ShowSql.show
19
+ end
20
+
21
+ Pry.commands.block_command 'hide-sql' do
22
+ ShowSql.hide
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
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 column.name == connection.primary_key(table_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
@@ -0,0 +1,10 @@
1
+ module Arql
2
+ class Connection
3
+ class << self
4
+ def open(options)
5
+ ActiveRecord::Base.establish_connection(options)
6
+ $C = ActiveRecord::Base.connection
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,180 @@
1
+ module Arql
2
+ module Extension
3
+ extend ActiveSupport::Concern
4
+
5
+ def t
6
+ puts Terminal::Table.new { |t|
7
+ v.each { |row| t << (row || :separator) }
8
+ }
9
+ end
10
+
11
+ def v
12
+ t = []
13
+ t << ['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']
14
+ t << nil
15
+ self.class.connection.columns(self.class.table_name).each do |column|
16
+ t << [column.name, read_attribute(column.name), column.sql_type, column.comment || '']
17
+ end
18
+ t
19
+ end
20
+
21
+ def to_insert_sql
22
+ self.class.to_insert_sql([self])
23
+ end
24
+
25
+ def to_upsert_sql
26
+ self.class.to_upsert_sql([self])
27
+ end
28
+
29
+ included do
30
+ end
31
+
32
+ class_methods do
33
+ def t
34
+ table_name = Commands::Table::get_table_name(name)
35
+ puts "\nTable: #{table_name}"
36
+ puts Commands::Table::table_info_table(table_name)
37
+ end
38
+
39
+ def v
40
+ table_name = Commands::Table::get_table_name(name)
41
+ Commands::Table::table_info(table_name)
42
+ end
43
+ def to_insert_sql(records, batch_size=1)
44
+ to_sql(records, :skip, batch_size)
45
+ end
46
+
47
+ def to_upsert_sql(records, batch_size=1)
48
+ to_sql(records, :update, batch_size)
49
+ end
50
+
51
+ def to_sql(records, on_duplicate, batch_size)
52
+ records.in_groups_of(batch_size, false).map do |group|
53
+ ActiveRecord::InsertAll.new(self, group.map(&:attributes), on_duplicate: on_duplicate).send(:to_sql) + ';'
54
+ end.join("\n")
55
+ end
56
+
57
+ def to_create_sql
58
+ ActiveRecord::Base.connection.exec_query("show create table #{table_name}").rows.last.last
59
+ end
60
+ end
61
+ end
62
+
63
+ class Definition
64
+ class << self
65
+ def models
66
+ @@models ||= []
67
+ end
68
+
69
+ def redefine
70
+ options = @@options
71
+ @@models.each do |model|
72
+ Object.send :remove_const, model[:model].name.to_sym if model[:model]
73
+ Object.send :remove_const, model[:abbr].to_sym if model[:abbr]
74
+ end
75
+ @@models = []
76
+ ActiveRecord::Base.connection.tap do |conn|
77
+ conn.tables.each do |table_name|
78
+ conn.primary_key(table_name).tap do |pkey|
79
+ table_name.camelize.tap do |const_name|
80
+ const_name = 'Modul' if const_name == 'Module'
81
+ const_name = 'Clazz' if const_name == 'Class'
82
+ Class.new(ActiveRecord::Base) do
83
+ include Arql::Extension
84
+ self.primary_key = pkey
85
+ self.table_name = table_name
86
+ self.inheritance_column = nil
87
+ self.default_timezone = :local
88
+ if options[:created_at].present?
89
+ define_singleton_method :timestamp_attributes_for_create do
90
+ options[:created_at]
91
+ end
92
+ end
93
+
94
+ if options[:updated_at].present?
95
+ define_singleton_method :timestamp_attributes_for_update do
96
+ options[:updated_at]
97
+ end
98
+ end
99
+ end.tap do |clazz|
100
+ Object.const_set(const_name, clazz).tap do |const|
101
+ const_name.gsub(/[a-z]*/, '').tap do |abbr|
102
+ unless Object.const_defined?(abbr)
103
+ Object.const_set abbr, const
104
+ abbr_const = abbr
105
+ end
106
+
107
+ @@models << {
108
+ model: const,
109
+ abbr: abbr_const,
110
+ table: table_name
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ def initialize(options)
123
+ @@options = options
124
+ @@models = []
125
+ ActiveRecord::Base.connection.tap do |conn|
126
+ conn.tables.each do |table_name|
127
+ conn.primary_key(table_name).tap do |pkey|
128
+ table_name.camelize.tap do |const_name|
129
+ const_name = 'Modul' if const_name == 'Module'
130
+ const_name = 'Clazz' if const_name == 'Class'
131
+ Class.new(ActiveRecord::Base) do
132
+ include Arql::Extension
133
+ self.primary_key = pkey
134
+ self.table_name = table_name
135
+ self.inheritance_column = nil
136
+ self.default_timezone = :local
137
+ if options[:created_at].present?
138
+ define_singleton_method :timestamp_attributes_for_create do
139
+ options[:created_at]
140
+ end
141
+ end
142
+
143
+ if options[:updated_at].present?
144
+ define_singleton_method :timestamp_attributes_for_update do
145
+ options[:updated_at]
146
+ end
147
+ end
148
+ end.tap do |clazz|
149
+ Object.const_set(const_name, clazz).tap do |const|
150
+ const_name.gsub(/[a-z]*/, '').tap do |abbr|
151
+ unless Object.const_defined?(abbr)
152
+ Object.const_set abbr, const
153
+ abbr_const = abbr
154
+ end
155
+
156
+ @@models << {
157
+ model: const,
158
+ abbr: abbr_const,
159
+ table: table_name
160
+ }
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ ::ActiveRecord::Relation.class_eval do
171
+ def t
172
+ records.t
173
+ end
174
+
175
+ def v
176
+ records.v
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,5 @@
1
+ require 'arql/ext/object'
2
+ require 'arql/ext/array'
3
+ require 'arql/ext/time'
4
+ require 'arql/ext/string'
5
+ require 'arql/ext/kernel'
@@ -0,0 +1,65 @@
1
+ class Array
2
+ def to_insert_sql(batch_size=500)
3
+ raise 'All element should be an ActiveRecord instance object' unless all? { |e| e.is_a?(ActiveRecord::Base) }
4
+ group_by(&:class).map do |(klass, records)|
5
+ klass.to_insert_sql(records, batch_size)
6
+ end.join("\n")
7
+ end
8
+
9
+ def to_upsert_sql(batch_size=500)
10
+ raise 'All element should be an ActiveRecord instance object' unless all? { |e| e.is_a?(ActiveRecord::Base) }
11
+ group_by(&:class).map do |(klass, records)|
12
+ klass.to_upsert_sql(records, batch_size)
13
+ end.join("\n")
14
+ end
15
+
16
+ def t(*attrs)
17
+ if attrs.present? && present? && first.is_a?(ActiveRecord::Base)
18
+ puts Terminal::Table.new { |t|
19
+ t << attrs
20
+ t << :separator
21
+ each do |e|
22
+ t << e.attributes.values_at(*attrs.map(&:to_s))
23
+ end
24
+ }
25
+ else
26
+ table = Terminal::Table.new { |t|
27
+ v.each { |row| t << (row || :separator)}
28
+ }.to_s
29
+
30
+ terminal_width = `tput cols`.to_i
31
+ if table.lines.first.size > terminal_width
32
+ table = table.lines.map(&:chomp)
33
+ puts table[0..2].join("\n")
34
+ puts table[3..-1].join("\n#{'-' * terminal_width}\n")
35
+ else
36
+ puts table
37
+ end
38
+ end
39
+ end
40
+
41
+ def v
42
+ return self unless present?
43
+ t = []
44
+ if map(&:class).uniq.size == 1
45
+ if first.is_a?(ActiveRecord::Base)
46
+ t << first.attribute_names
47
+ t << nil
48
+ each do |e|
49
+ t << e.attributes.values_at(*first.attribute_names).map(&:as_json)
50
+ end
51
+ elsif first.is_a?(Array)
52
+ t = map { |a| a.map(&:as_json) }
53
+ elsif first.is_a?(Hash) || first.is_a?(ActiveSupport::HashWithIndifferentAccess)
54
+ t << first.keys
55
+ t << nil
56
+ each do |e|
57
+ t << e.values_at(*first.keys).map(&:as_json)
58
+ end
59
+ else
60
+ return self
61
+ end
62
+ end
63
+ t
64
+ end
65
+ end
@@ -0,0 +1,5 @@
1
+ module Kernel
2
+ def sql(sql)
3
+ ActiveRecord::Base.connection.exec_query(sql)
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ class Object
2
+
3
+ def j
4
+ to_json
5
+ end
6
+
7
+ def jj
8
+ JSON.pretty_generate(JSON.parse(to_json))
9
+ end
10
+
11
+ def jp
12
+ puts j
13
+ end
14
+
15
+ def jjp
16
+ puts jj
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def p
3
+ puts self
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/time/conversions'
2
+ require 'active_support/core_ext/object/json'
3
+
4
+ class Time
5
+ DATE_FORMATS ||= {}
6
+ DATE_FORMATS[:default] = '%Y-%m-%d %H:%M:%S'
7
+
8
+ def inspect
9
+ to_s
10
+ end
11
+
12
+ def as_json(*args)
13
+ to_s
14
+ end
15
+ end
@@ -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