hyraft-rule 0.1.0.alpha1
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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +239 -0
- data/exe/hyr-rule +4 -0
- data/exe/hyr-rule-db +4 -0
- data/exe/hyraft-rule +6 -0
- data/exe/hyraft-rule-db +404 -0
- data/hyraft-rule.gemspec +54 -0
- data/lib/hyraft/rule/adapter_exhaust/data_gateway_command.rb +132 -0
- data/lib/hyraft/rule/adapter_request/remove_adapter_command.rb +76 -0
- data/lib/hyraft/rule/adapter_request/web_adapter_command.rb +211 -0
- data/lib/hyraft/rule/assemble_command.rb +98 -0
- data/lib/hyraft/rule/command.rb +79 -0
- data/lib/hyraft/rule/disassemble_command.rb +127 -0
- data/lib/hyraft/rule/engine/circuit_command.rb +82 -0
- data/lib/hyraft/rule/engine/port_command.rb +60 -0
- data/lib/hyraft/rule/engine/source_command.rb +70 -0
- data/lib/hyraft/rule/template_command.rb +102 -0
- data/lib/hyraft/rule/version.rb +7 -0
- data/lib/hyraft/rule.rb +40 -0
- metadata +93 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7354edfc544227b3eb8c6dfdfa552f8ccc4764a763e975028d423657a851c417
|
|
4
|
+
data.tar.gz: 02cb548060b83aa6f3516826d08cfc649663733fdf4469155b59608a31089279
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c9c71f2963cf91e915bfcde8531985e4105dee516e8ffd472f83d64956add49536a149bb14678285fc5e22e75e0d34b891668f4dfcbbd28ee612f657d8b2346e
|
|
7
|
+
data.tar.gz: 361550c41628c903ee91f16c491e6bacf106b4ebf5f001e6b1be9310e8369ce37a1a08aca4e95e8cd930f06208e5d37c75540ef5e986421c57c9c62e4336fce9
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hyraft-rule Demjhon Silver
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
# Hyraft Rule
|
|
5
|
+
|
|
6
|
+
[](https://badge.fury.io/rb/hyraft-rule)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Hyraft Rule - ( CLI ) Command system for Hyraft applications
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
A standalone command system (cli) for Hyraft applications.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Open Gemfile:
|
|
24
|
+
put:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
gem 'hyraft-rule'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Install the gem and add to the application's Gemfile by executing:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bundle install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage ( Assemble / Disassemble )
|
|
37
|
+
- hyr-rule
|
|
38
|
+
|
|
39
|
+
Package setup:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Default web-app
|
|
43
|
+
hyr-rule assemble articles
|
|
44
|
+
hyr-rule disassemble articles
|
|
45
|
+
|
|
46
|
+
# Specific app folders
|
|
47
|
+
|
|
48
|
+
hyr-rule assemble {any-folder-name}/users
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
hyr-rule assemble admin-app/users
|
|
52
|
+
hyr-rule disassemble admin-app/users
|
|
53
|
+
|
|
54
|
+
hyr-rule assemble api_app/products
|
|
55
|
+
hyr-rule disassemble api_app/products
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Usage ( Engine )
|
|
61
|
+
- hyr-rule
|
|
62
|
+
|
|
63
|
+
Generate:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
|
|
67
|
+
hyr-rule circuit articles
|
|
68
|
+
|
|
69
|
+
hyr-rule port articles
|
|
70
|
+
|
|
71
|
+
hyr-rule source article
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage ( Web Adapter )
|
|
76
|
+
- hyr-rule
|
|
77
|
+
|
|
78
|
+
Generate:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
hyr-rule web-adapter articles
|
|
82
|
+
hyr-rule web-adapter admin-app/products
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage ( data-gateway )
|
|
86
|
+
- hyr-rule
|
|
87
|
+
|
|
88
|
+
Generate:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
hyr-rule data-gateway articles
|
|
92
|
+
hyr-rule data-gateway admin-app/products
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Usage ( Templates )
|
|
99
|
+
- hyr-rule
|
|
100
|
+
|
|
101
|
+
Generate:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
|
|
105
|
+
hyr-rule template articles
|
|
106
|
+
hyraft-rule template articles
|
|
107
|
+
|
|
108
|
+
hyr-rule template admin-app/users
|
|
109
|
+
hyraft-rule template admin-app/users
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Usage ( For Help )
|
|
113
|
+
- hyr-rule
|
|
114
|
+
|
|
115
|
+
Generate:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
|
|
119
|
+
hyr-rule h
|
|
120
|
+
|
|
121
|
+
hyr-rule help
|
|
122
|
+
|
|
123
|
+
hyr-rule -h
|
|
124
|
+
|
|
125
|
+
hyraft-rule h
|
|
126
|
+
|
|
127
|
+
hyraft-rule help
|
|
128
|
+
|
|
129
|
+
hyraft-rule -h
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## Usage ( Database )
|
|
135
|
+
- hyr-rule-db
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
Schema:
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
hyr-rule-db generate create_users
|
|
143
|
+
hyr-rule-db generate add_email_to_users
|
|
144
|
+
|
|
145
|
+
- Migration Generation Schema Examples:
|
|
146
|
+
|
|
147
|
+
hyr-rule-db generate create_users
|
|
148
|
+
hyr-rule-db generate create_articles
|
|
149
|
+
hyr-rule-db generate create_products
|
|
150
|
+
hyr-rule-db generate create_categories
|
|
151
|
+
hyr-rule-db generate add_image_file_to_articles
|
|
152
|
+
hyr-rule-db generate add_price_to_products
|
|
153
|
+
hyr-rule-db generate remove_status_from_posts
|
|
154
|
+
hyr-rule-db generate drop_old_tables
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
Examples:
|
|
158
|
+
hyr-rule-db generate create_articles title content:text
|
|
159
|
+
|
|
160
|
+
hyr-rule-db generate create_products name:string price:decimal description:text user_id:int
|
|
161
|
+
hyr-rule-db generate create_users username:string age:int email:string active:bool created_at:datetime
|
|
162
|
+
|
|
163
|
+
hyr-rule-db generate create_products name:string price:decimal description:text user_id:int
|
|
164
|
+
hyr-rule-db generate create_users username age:int email active:bool
|
|
165
|
+
hyr-rule-db generate create_articles title content:text published_at:datetime views:int
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Migrations:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
Hyraft Rule Database Commands
|
|
173
|
+
|
|
174
|
+
Commands:
|
|
175
|
+
|
|
176
|
+
migrate, up - Run all pending migrations
|
|
177
|
+
rollback, down - Rollback all migrations
|
|
178
|
+
status - Show migration status
|
|
179
|
+
reset - Rollback and re-run all migrations
|
|
180
|
+
generate <name> - Create a new migration file
|
|
181
|
+
help - Show this help
|
|
182
|
+
|
|
183
|
+
Examples:
|
|
184
|
+
|
|
185
|
+
hyr-rule-db migrate
|
|
186
|
+
hyr-rule-db status
|
|
187
|
+
hyr-rule-db rollback
|
|
188
|
+
hyr-rule-db reset
|
|
189
|
+
hyr-rule-db help
|
|
190
|
+
|
|
191
|
+
Environment Usage:
|
|
192
|
+
|
|
193
|
+
hyr-rule-db migrate # Current environment (run: hyr s thin)
|
|
194
|
+
APP_ENV=test hyr-rule-db migrate # Test environment (run: APP_ENV=test hyr s thin)
|
|
195
|
+
APP_ENV=development hyr-rule-db migrate # Development environment (run: APP_ENV=development hyr s thin)
|
|
196
|
+
APP_ENV=production hyr-rule-db migrate # Production environment (run: APP_ENV=production hyr s thin)
|
|
197
|
+
|
|
198
|
+
Quick Reference:
|
|
199
|
+
|
|
200
|
+
# Generate and run migrations for a new table
|
|
201
|
+
hyr-rule-db generate create_users
|
|
202
|
+
hyr-rule-db migrate
|
|
203
|
+
|
|
204
|
+
# Add a column to existing table
|
|
205
|
+
hyr-rule-db generate add_email_to_users
|
|
206
|
+
hyr-rule-db migrate
|
|
207
|
+
|
|
208
|
+
# Check what needs to be applied
|
|
209
|
+
hyr-rule-db status
|
|
210
|
+
|
|
211
|
+
# Rollback if something went wrong
|
|
212
|
+
hyr-rule-db rollback
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
## Development
|
|
224
|
+
|
|
225
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
226
|
+
|
|
227
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
228
|
+
|
|
229
|
+
## Contributing
|
|
230
|
+
|
|
231
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/demjhonsilver/hyraft-rule. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/demjhonsilver/hyraft-rule/blob/master/CODE_OF_CONDUCT.md).
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
236
|
+
|
|
237
|
+
## Code of Conduct
|
|
238
|
+
|
|
239
|
+
Everyone interacting in the Hyraft::Rule project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/demjhonsilver/hyraft-rule/blob/master/CODE_OF_CONDUCT.md).
|
data/exe/hyr-rule
ADDED
data/exe/hyr-rule-db
ADDED
data/exe/hyraft-rule
ADDED
data/exe/hyraft-rule-db
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'sequel'
|
|
6
|
+
|
|
7
|
+
# -------------------------------
|
|
8
|
+
# Helper: find application root
|
|
9
|
+
# -------------------------------
|
|
10
|
+
def find_app_root
|
|
11
|
+
dir = Dir.pwd
|
|
12
|
+
while dir != '/'
|
|
13
|
+
boot_path = File.join(dir, 'boot.rb')
|
|
14
|
+
return dir if File.exist?(boot_path)
|
|
15
|
+
dir = File.dirname(dir)
|
|
16
|
+
end
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
APP_ROOT = find_app_root
|
|
21
|
+
|
|
22
|
+
if APP_ROOT.nil?
|
|
23
|
+
puts "❌ Error: Could not find boot.rb"
|
|
24
|
+
puts "Please run from your Hyraft application directory"
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
$LOAD_PATH.unshift(APP_ROOT) unless $LOAD_PATH.include?(APP_ROOT)
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
require File.join(APP_ROOT, 'boot')
|
|
32
|
+
require File.join(APP_ROOT, 'infra', 'database', 'sequel_connection')
|
|
33
|
+
rescue LoadError => e
|
|
34
|
+
puts "❌ Error loading dependencies: #{e.message}"
|
|
35
|
+
exit 1
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
begin
|
|
39
|
+
Sequel.extension :migration
|
|
40
|
+
DB = SequelConnection.db
|
|
41
|
+
DB.test_connection
|
|
42
|
+
rescue => e
|
|
43
|
+
puts "❌ Database connection failed: #{e.message}"
|
|
44
|
+
exit 1
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
MIGRATIONS_DIR = File.join(APP_ROOT, 'infra', 'database', 'migrations')
|
|
48
|
+
|
|
49
|
+
# -------------------------------
|
|
50
|
+
# Generate Migration Methods
|
|
51
|
+
# -------------------------------
|
|
52
|
+
def generate_migration(migration_name, *columns)
|
|
53
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
|
54
|
+
filename = "#{timestamp}_#{migration_name}.rb"
|
|
55
|
+
full_path = File.join(MIGRATIONS_DIR, filename)
|
|
56
|
+
|
|
57
|
+
FileUtils.mkdir_p(MIGRATIONS_DIR)
|
|
58
|
+
|
|
59
|
+
table_name = extract_table_name(migration_name)
|
|
60
|
+
migration_content = if migration_name.start_with?('create_') && table_name
|
|
61
|
+
create_table_template(table_name, *columns)
|
|
62
|
+
else
|
|
63
|
+
migration_template(migration_name)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
File.write(full_path, migration_content)
|
|
67
|
+
|
|
68
|
+
puts "✓ Created migration: #{full_path}"
|
|
69
|
+
puts "Table name detected: #{table_name}" if table_name
|
|
70
|
+
|
|
71
|
+
if columns.any?
|
|
72
|
+
puts "Columns added: #{columns.join(', ')}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
puts ""
|
|
76
|
+
puts "To apply this migration, run one of these:"
|
|
77
|
+
puts " hyr-rule-db migrate # Development environment (default)"
|
|
78
|
+
puts " APP_ENV=test hyr-rule-db migrate # For test environment"
|
|
79
|
+
puts " APP_ENV=development hyr-rule-db migrate # For development environment"
|
|
80
|
+
puts " APP_ENV=production hyr-rule-db migrate # For production environment"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def extract_table_name(migration_name)
|
|
84
|
+
case migration_name
|
|
85
|
+
when /^create_(.+)$/
|
|
86
|
+
$1
|
|
87
|
+
when /^add_(.+)_to_(.+)$/
|
|
88
|
+
$2
|
|
89
|
+
when /^remove_(.+)_from_(.+)$/
|
|
90
|
+
$2
|
|
91
|
+
when /^drop_(.+)$/
|
|
92
|
+
$1
|
|
93
|
+
else
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def migration_template(migration_name)
|
|
99
|
+
table_name = extract_table_name(migration_name)
|
|
100
|
+
|
|
101
|
+
if migration_name.start_with?('create_') && table_name
|
|
102
|
+
create_table_template(table_name)
|
|
103
|
+
elsif migration_name.start_with?('add_') && table_name
|
|
104
|
+
column_name = migration_name.match(/^add_(.+)_to_#{table_name}$/)[1]
|
|
105
|
+
add_column_template(table_name, column_name)
|
|
106
|
+
elsif migration_name.start_with?('remove_') && table_name
|
|
107
|
+
column_name = migration_name.match(/^remove_(.+)_from_#{table_name}$/)[1]
|
|
108
|
+
remove_column_template(table_name, column_name)
|
|
109
|
+
elsif migration_name.start_with?('drop_') && table_name
|
|
110
|
+
drop_table_template(table_name)
|
|
111
|
+
else
|
|
112
|
+
generic_template(migration_name)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def create_table_template(table_name, *columns)
|
|
118
|
+
# Parse columns with data types (format: name:string, age:int, price:decimal)
|
|
119
|
+
columns_code = if columns.any?
|
|
120
|
+
columns.map do |col|
|
|
121
|
+
if col.include?(':')
|
|
122
|
+
col_name, col_type = col.split(':', 2)
|
|
123
|
+
case col_type.downcase
|
|
124
|
+
when 'int', 'integer'
|
|
125
|
+
"Integer :#{col_name}, null: false"
|
|
126
|
+
when 'string', 'str', 'varchar', 'var'
|
|
127
|
+
"String :#{col_name}, size: 255, null: false"
|
|
128
|
+
when 'text'
|
|
129
|
+
"String :#{col_name}, text: true, null: false"
|
|
130
|
+
when 'decimal', 'float', 'numeric'
|
|
131
|
+
"Decimal :#{col_name}, size: [10, 2], null: false"
|
|
132
|
+
when 'bool', 'boolean'
|
|
133
|
+
"TrueClass :#{col_name}, null: false"
|
|
134
|
+
when 'date'
|
|
135
|
+
"Date :#{col_name}, null: false"
|
|
136
|
+
when 'datetime', 'timestamp'
|
|
137
|
+
"DateTime :#{col_name}, null: false"
|
|
138
|
+
else
|
|
139
|
+
"String :#{col_name}, size: 255, null: false" # default fallback
|
|
140
|
+
end
|
|
141
|
+
else
|
|
142
|
+
# Default to string if no type specified
|
|
143
|
+
"String :#{col}, size: 255, null: false"
|
|
144
|
+
end
|
|
145
|
+
end.map { |line| " #{line}" }.join("\n")
|
|
146
|
+
else
|
|
147
|
+
" # Add #{table_name} columns here"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
<<~RUBY
|
|
151
|
+
Sequel.migration do
|
|
152
|
+
up do
|
|
153
|
+
create_table(:#{table_name}) do
|
|
154
|
+
primary_key :id, type: :bigint
|
|
155
|
+
#{columns_code}
|
|
156
|
+
|
|
157
|
+
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
158
|
+
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
down do
|
|
163
|
+
drop_table(:#{table_name})
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
RUBY
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def add_column_template(table_name, column_name)
|
|
177
|
+
<<~RUBY
|
|
178
|
+
Sequel.migration do
|
|
179
|
+
change do
|
|
180
|
+
alter_table(:#{table_name}) do
|
|
181
|
+
add_column :#{column_name}, String
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
RUBY
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def remove_column_template(table_name, column_name)
|
|
193
|
+
<<~RUBY
|
|
194
|
+
Sequel.migration do
|
|
195
|
+
change do
|
|
196
|
+
alter_table(:#{table_name}) do
|
|
197
|
+
drop_column :#{column_name}
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
RUBY
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def drop_table_template(table_name)
|
|
205
|
+
<<~RUBY
|
|
206
|
+
Sequel.migration do
|
|
207
|
+
change do
|
|
208
|
+
drop_table(:#{table_name})
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
RUBY
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def generic_template(migration_name)
|
|
215
|
+
<<~RUBY
|
|
216
|
+
Sequel.migration do
|
|
217
|
+
change do
|
|
218
|
+
# Migration: #{migration_name}
|
|
219
|
+
# Add your custom migration code here
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
RUBY
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# -------------------------------
|
|
226
|
+
# Migration methods
|
|
227
|
+
# -------------------------------
|
|
228
|
+
|
|
229
|
+
def run_migrations
|
|
230
|
+
migration_files = Dir.glob(File.join(MIGRATIONS_DIR, "[0-9]*_*.rb")).sort
|
|
231
|
+
if migration_files.empty?
|
|
232
|
+
puts "No migration files found in #{MIGRATIONS_DIR}"
|
|
233
|
+
return
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
begin
|
|
237
|
+
# Get current applied migrations before migration
|
|
238
|
+
applied_before = if DB.table_exists?(:schema_migrations)
|
|
239
|
+
DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
|
|
240
|
+
else
|
|
241
|
+
[]
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Run migrations
|
|
245
|
+
Sequel::Migrator.run(DB, MIGRATIONS_DIR)
|
|
246
|
+
|
|
247
|
+
# Get applied migrations after migration
|
|
248
|
+
applied_after = if DB.table_exists?(:schema_migrations)
|
|
249
|
+
DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
|
|
250
|
+
else
|
|
251
|
+
[]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Find which migrations were just applied
|
|
255
|
+
newly_applied = applied_after - applied_before
|
|
256
|
+
|
|
257
|
+
if newly_applied.empty?
|
|
258
|
+
puts "✓ All files migrated successfully: no pending migrations"
|
|
259
|
+
else
|
|
260
|
+
if newly_applied.size == 1
|
|
261
|
+
puts "✓ Migration applied successfully: #{newly_applied.first}"
|
|
262
|
+
else
|
|
263
|
+
puts "✓ #{newly_applied.size} migrations applied successfully:"
|
|
264
|
+
newly_applied.each { |migration| puts " - #{migration}" }
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
rescue => e
|
|
268
|
+
puts "✗ Migration failed: #{e.message}"
|
|
269
|
+
exit 1
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def rollback_migrations
|
|
277
|
+
puts "Rolling back all migrations..."
|
|
278
|
+
begin
|
|
279
|
+
Sequel::Migrator.run(DB, MIGRATIONS_DIR, target: 0)
|
|
280
|
+
puts "✓ Rollback completed successfully"
|
|
281
|
+
rescue => e
|
|
282
|
+
puts "✗ Rollback failed: #{e.message}"
|
|
283
|
+
exit 1
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def show_status
|
|
288
|
+
puts "Migration Status:"
|
|
289
|
+
puts "Database: #{DB.opts[:database]}"
|
|
290
|
+
|
|
291
|
+
migration_files = Dir.glob(File.join(MIGRATIONS_DIR, "[0-9]*_*.rb")).sort
|
|
292
|
+
|
|
293
|
+
if DB.table_exists?(:schema_migrations)
|
|
294
|
+
applied_migrations = DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
|
|
295
|
+
latest = applied_migrations.last
|
|
296
|
+
puts "Schema migrations table: ✓ created"
|
|
297
|
+
puts "Latest applied migration: #{latest || 'none'}"
|
|
298
|
+
puts "Applied migrations: #{applied_migrations.size} of #{migration_files.size}"
|
|
299
|
+
|
|
300
|
+
# Show pending migrations
|
|
301
|
+
pending_migrations = migration_files.reject do |file|
|
|
302
|
+
filename = File.basename(file, '.rb')
|
|
303
|
+
applied_migrations.include?(filename)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
if pending_migrations.any?
|
|
307
|
+
puts "\nPending migrations:"
|
|
308
|
+
pending_migrations.each { |f| puts " - #{File.basename(f)}" }
|
|
309
|
+
puts "\nRun one of these to apply pending migrations:"
|
|
310
|
+
puts " hyr-rule-db migrate # Development environment (default)"
|
|
311
|
+
puts " APP_ENV=test hyr-rule-db migrate # For test environment"
|
|
312
|
+
puts " APP_ENV=development hyr-rule-db migrate # For development environment"
|
|
313
|
+
puts " APP_ENV=production hyr-rule-db migrate # For production environment"
|
|
314
|
+
else
|
|
315
|
+
puts "✓ All migrations are applied"
|
|
316
|
+
end
|
|
317
|
+
else
|
|
318
|
+
puts "Schema migrations table: ○ not created yet"
|
|
319
|
+
puts "Latest applied migration: none"
|
|
320
|
+
|
|
321
|
+
if migration_files.any?
|
|
322
|
+
puts "\nMigration files:"
|
|
323
|
+
migration_files.each { |f| puts " - #{File.basename(f)}" }
|
|
324
|
+
puts "\nRun one of these to apply pending migrations:"
|
|
325
|
+
puts " hyr-rule-db migrate # For development environment"
|
|
326
|
+
puts " APP_ENV=test hyr-rule-db migrate # For test environment"
|
|
327
|
+
puts " APP_ENV=development hyr-rule-db migrate # For development environment"
|
|
328
|
+
puts " APP_ENV=production hyr-rule-db migrate # For production environment"
|
|
329
|
+
else
|
|
330
|
+
puts "No migration files found in #{MIGRATIONS_DIR}"
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def show_help
|
|
337
|
+
puts <<~HELP
|
|
338
|
+
Hyraft Rule Database Commands
|
|
339
|
+
Commands:
|
|
340
|
+
migrate, up - Run all pending migrations
|
|
341
|
+
rollback, down - Rollback all migrations
|
|
342
|
+
status - Show migration status
|
|
343
|
+
reset - Rollback and re-run all migrations
|
|
344
|
+
generate <name> - Create a new migration file
|
|
345
|
+
help - Show this help
|
|
346
|
+
|
|
347
|
+
Examples:
|
|
348
|
+
hyr-rule-db migrate
|
|
349
|
+
hyr-rule-db status
|
|
350
|
+
hyr-rule-db generate create_users
|
|
351
|
+
hyr-rule-db generate create_articles title content published_at
|
|
352
|
+
hyr-rule-db generate create_products name price description user_id
|
|
353
|
+
|
|
354
|
+
Migration Generation Examples:
|
|
355
|
+
hyr-rule-db generate create_users
|
|
356
|
+
hyr-rule-db generate create_articles title content published_at
|
|
357
|
+
hyr-rule-db generate create_products name price description
|
|
358
|
+
hyr-rule-db generate create_orders user_id total_amount status
|
|
359
|
+
hyr-rule-db generate add_email_to_users
|
|
360
|
+
hyr-rule-db generate remove_status_from_posts
|
|
361
|
+
hyr-rule-db generate drop_old_tables
|
|
362
|
+
HELP
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# -------------------------------
|
|
366
|
+
# Main execution
|
|
367
|
+
# -------------------------------
|
|
368
|
+
command = ARGV[0] || "help"
|
|
369
|
+
migration_name = ARGV[1]
|
|
370
|
+
|
|
371
|
+
case command
|
|
372
|
+
when "migrate", "up"
|
|
373
|
+
run_migrations
|
|
374
|
+
when "rollback", "down"
|
|
375
|
+
rollback_migrations
|
|
376
|
+
when "status"
|
|
377
|
+
show_status
|
|
378
|
+
when "reset"
|
|
379
|
+
rollback_migrations
|
|
380
|
+
run_migrations
|
|
381
|
+
when "generate", "g"
|
|
382
|
+
if ARGV[1]
|
|
383
|
+
migration_name = ARGV[1]
|
|
384
|
+
columns = ARGV[2..-1] || [] # Get all remaining arguments as columns
|
|
385
|
+
generate_migration(migration_name, *columns)
|
|
386
|
+
else
|
|
387
|
+
puts "Error: Migration name required"
|
|
388
|
+
puts ""
|
|
389
|
+
puts "Usage: hyr-rule-db generate <migration_name> [column1 column2 ...]"
|
|
390
|
+
puts ""
|
|
391
|
+
puts "Examples:"
|
|
392
|
+
puts " hyr-rule-db generate create_users"
|
|
393
|
+
puts " hyr-rule-db generate create_products name price description"
|
|
394
|
+
puts " hyr-rule-db generate create_orders user_id total_amount status"
|
|
395
|
+
puts " hyr-rule-db generate add_email_to_users"
|
|
396
|
+
exit 1
|
|
397
|
+
end
|
|
398
|
+
when "help", "-h", "--help"
|
|
399
|
+
show_help
|
|
400
|
+
else
|
|
401
|
+
puts "Unknown command: #{command}"
|
|
402
|
+
show_help
|
|
403
|
+
exit 1
|
|
404
|
+
end
|