arql 0.1.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -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