crudboy 0.1.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.
@@ -0,0 +1,17 @@
1
+ class String
2
+ def p
3
+ puts self
4
+ end
5
+
6
+ def expa
7
+ File.expand_path(self)
8
+ end
9
+
10
+ def f
11
+ expa
12
+ end
13
+
14
+ def as_path
15
+ File.join(*(split(/\W/)))
16
+ end
17
+ 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,36 @@
1
+ module Crudboy
2
+ module Helper
3
+ def lombok
4
+ <<~EOF.chomp
5
+ import lombok.AllArgsConstructor;
6
+ import lombok.Builder;
7
+ import lombok.Data;
8
+ import lombok.NoArgsConstructor;
9
+
10
+ @Data
11
+ @Builder(toBuilder = true)
12
+ @AllArgsConstructor
13
+ @NoArgsConstructor
14
+ EOF
15
+ end
16
+
17
+ def column_names_list
18
+ columns.map do |column|
19
+ format('`%s`', column.name)
20
+ end.join(', ')
21
+ end
22
+
23
+ def insert_values_list
24
+ columns.map do |column|
25
+ column.mybatis_value_expression
26
+ end.join(', ')
27
+ end
28
+
29
+ def batch_insert_values_list
30
+ columns.map do |column|
31
+ format('#{item.%s,jdbcType=%s}', column.lower_camel_name, column.jdbc_type)
32
+ end.join(', ')
33
+ end
34
+
35
+ end
36
+ end
data/lib/crudboy/id.rb ADDED
@@ -0,0 +1,59 @@
1
+ module Crudboy
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 = Crudboy::ID
@@ -0,0 +1,55 @@
1
+ module Crudboy
2
+ class Model
3
+ attr_accessor :active_record_model, :name, :table_name, :table_comment, :columns
4
+
5
+ def initialize(active_record_model, table_name, table_comment)
6
+ @active_record_model = active_record_model
7
+ @name = @active_record_model.name
8
+ @table_name = table_name
9
+ @table_comment = table_comment
10
+ @columns = active_record_model.columns.map { |c| Column.new(c, c.name == active_record_model.primary_key) }
11
+ end
12
+
13
+ def primary_column
14
+ columns.find { |c| c.name == active_record_model.primary_key }
15
+ end
16
+
17
+ def regular_columns
18
+ columns.reject { |c| c.name == active_record_model.primary_key }
19
+ end
20
+
21
+ def columns(**options)
22
+ if options.empty?
23
+ @columns
24
+ elsif options[:except]
25
+ @columns.reject do |column|
26
+ if options[:except].is_a?(Array)
27
+ options[:except].include?(column.name)
28
+ elsif options[:except].is_a?(Regexp)
29
+ column.name =~ options[:except]
30
+ else
31
+ false
32
+ end
33
+ end
34
+ elsif options[:only]
35
+ @columns.select do |column|
36
+ if options[:only].is_a?(Array)
37
+ options[:only].include?(column.name)
38
+ elsif options[:only].is_a?(Regexp)
39
+ column.name =~ options[:only]
40
+ else
41
+ true
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def method_missing(method, *args, **options, &block)
48
+ if active_record_model.respond_to?(method)
49
+ active_record_model.send(method, *args, **options, &block)
50
+ else
51
+ super
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,31 @@
1
+ require 'net/ssh/gateway'
2
+ require 'crudboy/ssh_proxy_patch'
3
+
4
+ module Crudboy
5
+ class SSHProxy
6
+ class << self
7
+
8
+ attr_accessor :config, :ssh_gateway, :local_ssh_proxy_port
9
+
10
+ def connect(config)
11
+ @config = config
12
+ @ssh_gateway = Net::SSH::Gateway.new(config[:host], config[:user], config.slice(:port, :password).symbolize_keys.merge(keepalive: true, keepalive_interval: 30, loop_wait: 1))
13
+ @local_ssh_proxy_port = @ssh_gateway.open(config[:forward_host], config[:forward_port], config[:local_port])
14
+ end
15
+
16
+ def reconnect
17
+ reconnect! unless @ssh_gateway.active?
18
+ end
19
+
20
+ def reconnect!
21
+ @ssh_gateway.shutdown!
22
+ @ssh_gateway = Net::SSH::Gateway.new(@config[:host], @config[:user], @config.slice(:port, :password).symbolize_keys)
23
+ @ssh_gateway.open(config[:forward_host], config[:forward_port], @local_ssh_proxy_port)
24
+ end
25
+
26
+ def active?
27
+ @ssh_gateway.active?
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,88 @@
1
+ require 'net/ssh/proxy/command'
2
+
3
+ module Net
4
+ module SSH
5
+ module Proxy
6
+ class Command
7
+
8
+ # Return a new socket connected to the given host and port via the
9
+ # proxy that was requested when the socket factory was instantiated.
10
+ def open(host, port, connection_options = nil)
11
+ command_line = @command_line_template.gsub(/%(.)/) {
12
+ case $1
13
+ when 'h'
14
+ host
15
+ when 'p'
16
+ port.to_s
17
+ when 'r'
18
+ remote_user = connection_options && connection_options[:remote_user]
19
+ if remote_user
20
+ remote_user
21
+ else
22
+ raise ArgumentError, "remote user name not available"
23
+ end
24
+ when '%'
25
+ '%'
26
+ else
27
+ raise ArgumentError, "unknown key: #{$1}"
28
+ end
29
+ }
30
+ command_line = '%s %s' % [CrudboySetsidWrrapper, command_line]
31
+ begin
32
+ io = IO.popen(command_line, "r+")
33
+ begin
34
+ if result = IO.select([io], nil, [io], @timeout)
35
+ if result.last.any? || io.eof?
36
+ raise "command failed"
37
+ end
38
+ else
39
+ raise "command timed out"
40
+ end
41
+ rescue StandardError
42
+ close_on_error(io)
43
+ raise
44
+ end
45
+ rescue StandardError => e
46
+ raise ConnectError, "#{e}: #{command_line}"
47
+ end
48
+ @command_line = command_line
49
+ if Gem.win_platform?
50
+ # read_nonblock and write_nonblock are not available on Windows
51
+ # pipe. Use sysread and syswrite as a replacement works.
52
+ def io.send(data, flag)
53
+ syswrite(data)
54
+ end
55
+
56
+ def io.recv(size)
57
+ sysread(size)
58
+ end
59
+ else
60
+ def io.send(data, flag)
61
+ begin
62
+ result = write_nonblock(data)
63
+ rescue IO::WaitWritable, Errno::EINTR
64
+ IO.select(nil, [self])
65
+ retry
66
+ end
67
+ result
68
+ end
69
+
70
+ def io.recv(size)
71
+ begin
72
+ result = read_nonblock(size)
73
+ rescue IO::WaitReadable, Errno::EINTR
74
+ timeout_in_seconds = 20
75
+ if IO.select([self], nil, [self], timeout_in_seconds) == nil
76
+ raise "Unexpected spurious read wakeup"
77
+ end
78
+ retry
79
+ end
80
+ result
81
+ end
82
+ end
83
+ io
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,76 @@
1
+ require 'erb'
2
+
3
+ module Crudboy
4
+ class Template
5
+ attr_accessor :path, :base_path, :type, :context
6
+
7
+ def initialize(path, base_path, context)
8
+ @path = path
9
+ @base_path = base_path.blank? ? '.' : base_path
10
+ @type = if File.directory?(@path)
11
+ :directory
12
+ elsif @path.end_with?('.erb')
13
+ :erb
14
+ else
15
+ :plain
16
+ end
17
+ @context = context
18
+ end
19
+
20
+ def make_directory!(destination)
21
+ @context.eval(@base_path).tap do |path|
22
+ File.join(destination, path).tap do |full_path|
23
+ FileUtils.mkdir_p(full_path)
24
+ puts "mkdir -p: #{full_path}"
25
+ end
26
+ end
27
+ end
28
+
29
+ def make_base_directory!(destination)
30
+ @context.eval(@base_path).tap do |path|
31
+ File.dirname(path).tap do |base_dir|
32
+ File.join(destination, base_dir).tap do |full_path|
33
+ FileUtils.mkdir_p(full_path)
34
+ puts "mkdir -p: #{full_path}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def render_file
41
+ if erb?
42
+ erb = ERB.new(IO.read(path))
43
+ erb.filename = path
44
+ erb.result(@context.binding)
45
+ else
46
+ IO.read(path)
47
+ end
48
+ end
49
+
50
+ def render!(destination)
51
+ if directory?
52
+ make_directory!(destination)
53
+ else
54
+ make_base_directory!(destination)
55
+ render_file.tap do |file_content|
56
+ File.join(destination, @context.eval(@base_path.delete_suffix('.erb'))).tap do |path|
57
+ IO.write(path, file_content)
58
+ puts "Write file: #{path}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def directory?
65
+ @type == :directory
66
+ end
67
+
68
+ def erb?
69
+ @type == :erb
70
+ end
71
+
72
+ def plain?
73
+ @type == :plain
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,35 @@
1
+ module Crudboy
2
+ class TemplateContext
3
+
4
+ include Helper
5
+
6
+ attr_accessor :model, :columns, :table_name, :model_name, :bundle_options
7
+
8
+ def initialize(definition)
9
+ @model = definition.model
10
+ @model_name = definition.model_name
11
+ @table_name = definition.table_name
12
+ @columns = @model.columns
13
+ end
14
+
15
+ def eval(string)
16
+ instance_eval(format('%%Q{%s}', string), string, 0)
17
+ end
18
+
19
+ def binding
20
+ Kernel::binding
21
+ end
22
+
23
+ def columns(**options)
24
+ model.columns(**options)
25
+ end
26
+
27
+ def method_missing(method, *args, **options, &block)
28
+ if args.empty? && options.empty? && block.nil? && bundle_options.table.keys.include?(method)
29
+ bundle_options.send(method)
30
+ else
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Crudboy
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,256 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crudboy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Liu Xiang
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-08-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mysql2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 6.0.3
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 6.2.0
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 6.0.3
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 6.2.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: composite_primary_keys
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 12.0.3
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 12.0.3
75
+ - !ruby/object:Gem::Dependency
76
+ name: activesupport
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 6.0.3
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 6.0.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: net-ssh-gateway
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 2.0.0
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 2.0.0
103
+ - !ruby/object:Gem::Dependency
104
+ name: pry
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.13.1
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.13.1
117
+ - !ruby/object:Gem::Dependency
118
+ name: pry-byebug
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 3.9.0
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 3.9.0
131
+ - !ruby/object:Gem::Dependency
132
+ name: pry-doc
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 1.1.0
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 1.1.0
145
+ - !ruby/object:Gem::Dependency
146
+ name: rainbow
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: 3.0.0
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 3.0.0
159
+ - !ruby/object:Gem::Dependency
160
+ name: terminal-table
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: 1.8.0
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: 1.8.0
173
+ - !ruby/object:Gem::Dependency
174
+ name: table_print
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: 1.5.6
180
+ type: :runtime
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: 1.5.6
187
+ description: CRUD code generator using Rails ActiveRecord
188
+ email:
189
+ - liuxiang921@gmail.com
190
+ executables:
191
+ - crudboy
192
+ - crudboy_setsid_wrapper
193
+ extensions: []
194
+ extra_rdoc_files: []
195
+ files:
196
+ - ".gitignore"
197
+ - CODE_OF_CONDUCT.md
198
+ - Gemfile
199
+ - Gemfile.lock
200
+ - LICENSE.txt
201
+ - README.md
202
+ - Rakefile
203
+ - bin/console
204
+ - bin/setup
205
+ - crudboy.gemspec
206
+ - exe/crudboy
207
+ - exe/crudboy_setsid_wrapper
208
+ - lib/crudboy.rb
209
+ - lib/crudboy/app.rb
210
+ - lib/crudboy/bundle.rb
211
+ - lib/crudboy/cli.rb
212
+ - lib/crudboy/column.rb
213
+ - lib/crudboy/concerns.rb
214
+ - lib/crudboy/concerns/global_data_definition.rb
215
+ - lib/crudboy/concerns/table_data_definition.rb
216
+ - lib/crudboy/connection.rb
217
+ - lib/crudboy/definition.rb
218
+ - lib/crudboy/ext.rb
219
+ - lib/crudboy/ext/array.rb
220
+ - lib/crudboy/ext/hash.rb
221
+ - lib/crudboy/ext/kernel.rb
222
+ - lib/crudboy/ext/object.rb
223
+ - lib/crudboy/ext/string.rb
224
+ - lib/crudboy/ext/time.rb
225
+ - lib/crudboy/helper.rb
226
+ - lib/crudboy/id.rb
227
+ - lib/crudboy/model.rb
228
+ - lib/crudboy/ssh_proxy.rb
229
+ - lib/crudboy/ssh_proxy_patch.rb
230
+ - lib/crudboy/template.rb
231
+ - lib/crudboy/template_context.rb
232
+ - lib/crudboy/version.rb
233
+ homepage: https://github.com/lululau/crudboy
234
+ licenses:
235
+ - MIT
236
+ metadata: {}
237
+ post_install_message:
238
+ rdoc_options: []
239
+ require_paths:
240
+ - lib
241
+ required_ruby_version: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ version: 2.6.0
246
+ required_rubygems_version: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ requirements: []
252
+ rubygems_version: 3.2.3
253
+ signing_key:
254
+ specification_version: 4
255
+ summary: CRUD code generator using Rails ActiveRecord
256
+ test_files: []