active_record_mysql_repl 0.1.2 → 0.1.4
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 +4 -4
- data/.bundle/config +3 -0
- data/README.md +604 -13
- data/lib/active_record_mysql_repl/cli/main.rb +6 -1
- data/lib/active_record_mysql_repl/config.rb +1 -1
- data/lib/active_record_mysql_repl/database/association.rb +1 -1
- data/lib/active_record_mysql_repl/database/loader.rb +9 -3
- data/lib/active_record_mysql_repl/extensions/active_record.rb +1 -0
- data/lib/active_record_mysql_repl/extensions/object.rb +2 -2
- data/lib/active_record_mysql_repl/version.rb +1 -1
- data/sample_config/{.pryrc.sample → .army.sample/.pryrc.sample} +2 -0
- data/sample_config/{databases.sample.yml → .army.sample/databases.sample.yml} +2 -2
- data/sample_config/.army.sample/extensions/hello.rb +9 -0
- data/sample_config/.army.sample.yml +4 -4
- metadata +7 -5
- /data/sample_config/{associations.sample.yml → .army.sample/associations.sample.yml} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d60c9d4baca1fb49f423f128a5015c348e17301c593895afa9083c2ee47b495
|
4
|
+
data.tar.gz: 4060d8523d63a3db240d6cd96cefcc6f1e0a0e3e4c2e35691d736005f86f90e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fa3e154a372791095e0b6e4766e7a23d3a1c3f4f74fda84a0d4aeac33d2ef202080911a447c4a9ebe6b7a47eb09a9138630715e46b7bb482dbac5b1d2528fe3
|
7
|
+
data.tar.gz: e8599c8c29441696533ace9baa75163a24a271cd8b74a67e7038af2ec8e16c540ef869029438344fe75aa2f455b8012d61459efa26046ebcf86987314ef66c2d
|
data/.bundle/config
ADDED
data/README.md
CHANGED
@@ -1,38 +1,629 @@
|
|
1
1
|
# ActiveRecordMysqlRepl
|
2
2
|
|
3
|
-
|
3
|
+
## Prerequisites
|
4
4
|
|
5
|
-
|
5
|
+
### Ruby version 3.0.0 or higher
|
6
6
|
|
7
|
-
|
7
|
+
e.g) Using rbenv
|
8
|
+
|
9
|
+
```bash
|
10
|
+
$ rbenv install 3.3.6
|
11
|
+
```
|
8
12
|
|
9
|
-
|
13
|
+
### mysql-client 8.0
|
10
14
|
|
11
|
-
|
15
|
+
e.g) on macOS
|
12
16
|
|
13
17
|
```bash
|
14
|
-
|
18
|
+
$ brew install mysql-client@8.0
|
19
|
+
$ gem install mysql2 -v 0.5.6 -- --with-ldflags=-L$(brew --prefix zstd)/lib --with-mysql-dir=/opt/homebrew/opt/mysql-client@8.4
|
15
20
|
```
|
16
21
|
|
17
|
-
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Just by installing the gem, you can use the `army` command.
|
18
25
|
|
19
26
|
```bash
|
20
|
-
gem install
|
27
|
+
$ gem install active_record_mysql_repl
|
28
|
+
Successfully installed active_record_mysql_repl-x.x.x
|
29
|
+
Parsing documentation for active_record_mysql_repl-x.x.x
|
30
|
+
Installing ri documentation for active_record_mysql_repl-x.x.x
|
31
|
+
Done installing documentation for active_record_mysql_repl after 0 seconds
|
32
|
+
1 gem installed
|
33
|
+
```
|
34
|
+
|
35
|
+
```
|
36
|
+
$ army
|
37
|
+
ActiveRecordMysqlRepl Version: x.x.x
|
38
|
+
```
|
39
|
+
|
40
|
+
If you want to use the zsh completion, you can add the following line to your `.zshrc` file.
|
41
|
+
|
42
|
+
```sh
|
43
|
+
$ eval "$(army --zsh-completion)"
|
44
|
+
```
|
45
|
+
|
46
|
+
Then you can use the completion feature like below.
|
47
|
+
|
48
|
+
```sh
|
49
|
+
$ army [TAB]
|
50
|
+
option
|
51
|
+
-c -- path to .armyrc file
|
52
|
+
-d -- Database name
|
53
|
+
-e -- output erd
|
21
54
|
```
|
22
55
|
|
23
56
|
## Usage
|
24
57
|
|
25
|
-
|
58
|
+
### Sample Configurations
|
26
59
|
|
27
|
-
|
60
|
+
From the following link, you can Download the sample configuration files
|
61
|
+
https://github.com/nogahighland/active_record_mysql_repl/tree/main/sample_config
|
62
|
+
|
63
|
+
Also you can try with sample database on your local MySQL server
|
64
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/main/sample_config/sample_db.sql
|
65
|
+
|
66
|
+
### Sample Database
|
67
|
+
|
68
|
+
```sql
|
69
|
+
CREATE DATABASE test;
|
70
|
+
```
|
71
|
+
|
72
|
+
The sample configuration assumes the sample database is running on
|
73
|
+
127.0.0.1:3306/test (user: root, password: root)
|
74
|
+
|
75
|
+
```
|
76
|
+
$ mysql -u root -p test < sample_db.sql
|
77
|
+
```
|
78
|
+
|
79
|
+

|
80
|
+
|
81
|
+
This ER Diagram can be generated by the following command
|
82
|
+
|
83
|
+
```sh
|
84
|
+
army -c sample_config/.army.sample.yml -d test -e erd
|
85
|
+
```
|
86
|
+
|
87
|
+
### Showcases
|
88
|
+
|
89
|
+
```sh
|
90
|
+
army -c /path/to/sample_config/.army.sample.yml -d test
|
91
|
+
Ensureing connection to test on port 127.0.0.1:33060
|
92
|
+
Loading tables
|
93
|
+
Loading custom extensions from /path/to/sample_config/./.army.sample/extensions
|
94
|
+
```
|
95
|
+
|
96
|
+
Now you can access to the table classes as `User` if the table name is `users`.
|
97
|
+
|
98
|
+
```rb
|
99
|
+
[1] test(main)> User.all
|
100
|
+
```
|
101
|
+
|
102
|
+
<details><summary>output:</summary>
|
103
|
+
|
104
|
+
```rb
|
105
|
+
D, [2024-12-12T12:57:38.581127 #2816] DEBUG -- : User Load (10.5ms) SELECT `users`.* FROM `users`
|
106
|
+
[
|
107
|
+
[0] #<User:0x0000000123188de0> {
|
108
|
+
:id => "1",
|
109
|
+
:login_id => "user1",
|
110
|
+
:profile_id => 1
|
111
|
+
}
|
112
|
+
]
|
113
|
+
```
|
114
|
+
|
115
|
+
</details>
|
116
|
+
|
117
|
+
---
|
118
|
+
|
119
|
+
`.d` method shows the schema of the table. Let's see the `Order` table schema.
|
120
|
+
|
121
|
+
```rb
|
122
|
+
[8] test(main)> Order.d
|
123
|
+
```
|
124
|
+
|
125
|
+
<details><summary>output:</summary>
|
126
|
+
|
127
|
+
```
|
128
|
+
D, [2024-12-12T12:32:20.100309 #2816] DEBUG -- : (10.6ms) DESCRIBE orders
|
129
|
+
D, [2024-12-12T12:32:20.107976 #2816] DEBUG -- : (6.9ms) SHOW INDEX FROM orders
|
130
|
+
# orders
|
131
|
+
+---------+-------------+------+-----+---------+-------+
|
132
|
+
| Field | Type | Null | Key | Default | Extra |
|
133
|
+
+---------+-------------+------+-----+---------+-------+
|
134
|
+
| id | varchar(64) | NO | PRI | | |
|
135
|
+
| user_id | varchar(64) | NO | | | |
|
136
|
+
| item_id | varchar(64) | NO | | | |
|
137
|
+
+---------+-------------+------+-----+---------+-------+
|
138
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
139
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
140
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
141
|
+
| orders | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
142
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
143
|
+
```
|
144
|
+
|
145
|
+
</details>
|
146
|
+
|
147
|
+
---
|
148
|
+
|
149
|
+
`.ddl` method shows the DDL of the table.
|
150
|
+
|
151
|
+
```rb
|
152
|
+
[9] test(main)> Order.ddl
|
153
|
+
```
|
154
|
+
|
155
|
+
<details><summary>output:</summary>
|
156
|
+
|
157
|
+
```
|
158
|
+
D, [2024-12-12T12:32:21.878444 #2816] DEBUG -- : (8.7ms) SHOW CREATE TABLE orders
|
159
|
+
CREATE TABLE `orders` (
|
160
|
+
`id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
161
|
+
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
162
|
+
`item_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
163
|
+
PRIMARY KEY (`id`)
|
164
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
|
165
|
+
```
|
166
|
+
|
167
|
+
</details>
|
168
|
+
|
169
|
+
---
|
170
|
+
|
171
|
+
`models` is globally defined to get and array of all the table classes. By `.map(&:d)` you can see the schema of all the tables.
|
172
|
+
|
173
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/main/lib/active_record_mysql_repl/extensions/global.rb#L10-L12
|
174
|
+
|
175
|
+
```rb
|
176
|
+
[6] test(main)> puts models.map(&:d)
|
177
|
+
```
|
178
|
+
|
179
|
+
<details><summary>output:</summary>
|
180
|
+
|
181
|
+
```
|
182
|
+
D, [2024-12-12T01:26:36.677988 #25446] DEBUG -- : Brand Load (2.1ms) SELECT `brands`.* FROM `brands`
|
183
|
+
D, [2024-12-12T01:26:36.681307 #25446] DEBUG -- : Category Load (2.8ms) SELECT `categories`.* FROM `categories`
|
184
|
+
D, [2024-12-12T01:26:36.683967 #25446] DEBUG -- : Item Load (2.0ms) SELECT `items`.* FROM `items`
|
185
|
+
D, [2024-12-12T01:26:36.687282 #25446] DEBUG -- : Order Load (3.0ms) SELECT `orders`.* FROM `orders`
|
186
|
+
D, [2024-12-12T01:26:36.691204 #25446] DEBUG -- : UserProfile Load (3.6ms) SELECT `user_profiles`.* FROM `user_profiles`
|
187
|
+
D, [2024-12-12T01:26:36.694081 #25446] DEBUG -- : User Load (2.2ms) SELECT `users`.* FROM `users`
|
188
|
+
# users
|
189
|
+
+------------+-------------+------+-----+---------+-------+
|
190
|
+
| Field | Type | Null | Key | Default | Extra |
|
191
|
+
+------------+-------------+------+-----+---------+-------+
|
192
|
+
| id | varchar(64) | NO | PRI | | |
|
193
|
+
| login_id | varchar(64) | NO | | | |
|
194
|
+
| profile_id | int | YES | | | |
|
195
|
+
+------------+-------------+------+-----+---------+-------+
|
196
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
197
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
198
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
199
|
+
| users | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
200
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
201
|
+
# user_profiles
|
202
|
+
+-------+-------------+------+-----+---------+-------+
|
203
|
+
| Field | Type | Null | Key | Default | Extra |
|
204
|
+
+-------+-------------+------+-----+---------+-------+
|
205
|
+
| id | varchar(64) | NO | PRI | | |
|
206
|
+
| name | varchar(64) | NO | | | |
|
207
|
+
+-------+-------------+------+-----+---------+-------+
|
208
|
+
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
209
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
210
|
+
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
211
|
+
| user_profiles | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
212
|
+
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
213
|
+
# orders
|
214
|
+
+---------+-------------+------+-----+---------+-------+
|
215
|
+
| Field | Type | Null | Key | Default | Extra |
|
216
|
+
+---------+-------------+------+-----+---------+-------+
|
217
|
+
| id | varchar(64) | NO | PRI | | |
|
218
|
+
| user_id | varchar(64) | NO | | | |
|
219
|
+
| item_id | varchar(64) | NO | | | |
|
220
|
+
+---------+-------------+------+-----+---------+-------+
|
221
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
222
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
223
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
224
|
+
| orders | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
225
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
226
|
+
# items
|
227
|
+
+-------------+-------------+------+-----+---------+-------+
|
228
|
+
| Field | Type | Null | Key | Default | Extra |
|
229
|
+
+-------------+-------------+------+-----+---------+-------+
|
230
|
+
| id | varchar(64) | NO | PRI | | |
|
231
|
+
| category_id | varchar(64) | NO | | | |
|
232
|
+
| brand_id | varchar(64) | NO | | | |
|
233
|
+
+-------------+-------------+------+-----+---------+-------+
|
234
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
235
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
236
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
237
|
+
| items | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
238
|
+
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
239
|
+
# categories
|
240
|
+
+-----------+-------------+------+-----+---------+-------+
|
241
|
+
| Field | Type | Null | Key | Default | Extra |
|
242
|
+
+-----------+-------------+------+-----+---------+-------+
|
243
|
+
| id | varchar(64) | NO | PRI | | |
|
244
|
+
| name | varchar(64) | NO | | | |
|
245
|
+
| parent_id | varchar(64) | NO | | | |
|
246
|
+
+-----------+-------------+------+-----+---------+-------+
|
247
|
+
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
248
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
249
|
+
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
250
|
+
| categories | 0 | PRIMARY | 1 | id | A | 2 | | | | BTREE | | | YES | |
|
251
|
+
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
252
|
+
# brands
|
253
|
+
+-------+-------------+------+-----+---------+-------+
|
254
|
+
| Field | Type | Null | Key | Default | Extra |
|
255
|
+
+-------+-------------+------+-----+---------+-------+
|
256
|
+
| id | varchar(64) | NO | PRI | | |
|
257
|
+
| name | varchar(64) | NO | | | |
|
258
|
+
+-------+-------------+------+-----+---------+-------+
|
259
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
260
|
+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
|
261
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
262
|
+
| brands | 0 | PRIMARY | 1 | id | A | 1 | | | | BTREE | | | YES | |
|
263
|
+
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
|
264
|
+
```
|
265
|
+
|
266
|
+
</details>
|
267
|
+
|
268
|
+
---
|
269
|
+
|
270
|
+
To get the last record of order,
|
271
|
+
|
272
|
+
```rb
|
273
|
+
[1] test(main)> Order.last
|
274
|
+
```
|
275
|
+
|
276
|
+
<details><summary>output:</summary>
|
277
|
+
|
278
|
+
```rb
|
279
|
+
D, [2024-12-11T23:45:49.743857 #96076] DEBUG -- : Order Load (5.5ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
280
|
+
#<Order:0x00000001293677c8> {
|
281
|
+
:id => "1",
|
282
|
+
:user_id => "1",
|
283
|
+
:item_id => "1"
|
284
|
+
}
|
285
|
+
```
|
286
|
+
|
287
|
+
</details>
|
288
|
+
|
289
|
+
---
|
290
|
+
|
291
|
+
You can get the last order's user because `user_id` column exists on `orders` table. For the same reason you can get the order's item and its category too.
|
292
|
+
All the associations are chainable by the native functionality of ActiveRecord.
|
293
|
+
|
294
|
+
```rb
|
295
|
+
[5] test(main)> Order.last.user
|
296
|
+
```
|
297
|
+
|
298
|
+
<details><summary>output:</summary>
|
299
|
+
|
300
|
+
```rb
|
301
|
+
D, [2024-12-11T23:46:11.154678 #96076] DEBUG -- : Order Load (6.9ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
302
|
+
D, [2024-12-11T23:46:11.176424 #96076] DEBUG -- : User Load (2.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = '1' LIMIT 1
|
303
|
+
#<User:0x000000012961fda8> {
|
304
|
+
:id => "1",
|
305
|
+
:login_id => "user1",
|
306
|
+
:profile_id => 1
|
307
|
+
}
|
308
|
+
```
|
309
|
+
|
310
|
+
</details>
|
311
|
+
|
312
|
+
```rb
|
313
|
+
[7] test(main)> Order.last.item
|
314
|
+
```
|
315
|
+
|
316
|
+
<details><summary>output:</summary>
|
317
|
+
|
318
|
+
```rb
|
319
|
+
D, [2024-12-11T23:46:17.098874 #96076] DEBUG -- : Order Load (3.5ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
320
|
+
D, [2024-12-11T23:46:17.112940 #96076] DEBUG -- : Item Load (2.2ms) SELECT `items`.* FROM `items` WHERE `items`.`id` = '1' LIMIT 1
|
321
|
+
#<Item:0x000000012a416c40> {
|
322
|
+
:id => "1",
|
323
|
+
:category_id => "2",
|
324
|
+
:brand_id => "1"
|
325
|
+
}
|
326
|
+
```
|
327
|
+
|
328
|
+
</details>
|
329
|
+
|
330
|
+
```rb
|
331
|
+
[8] test(main)> Order.last.item.category
|
332
|
+
```
|
333
|
+
|
334
|
+
<details><summary>output:</summary>
|
335
|
+
|
336
|
+
```rb
|
337
|
+
D, [2024-12-11T23:46:21.104696 #96076] DEBUG -- : Order Load (2.1ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
338
|
+
D, [2024-12-11T23:46:21.106696 #96076] DEBUG -- : Item Load (1.5ms) SELECT `items`.* FROM `items` WHERE `items`.`id` = '1' LIMIT 1
|
339
|
+
D, [2024-12-11T23:46:21.117169 #96076] DEBUG -- : Category Load (2.5ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = '2' LIMIT 1
|
340
|
+
#<Category:0x000000012a5d7b38> {
|
341
|
+
:id => "2",
|
342
|
+
:name => "category2",
|
343
|
+
:parent_id => "1"
|
344
|
+
}
|
345
|
+
```
|
346
|
+
|
347
|
+
</details>
|
348
|
+
|
349
|
+
---
|
350
|
+
|
351
|
+
A category's parent is fetched from the same table because `parent_id`'s `parent` is treated by `ActiveRecordMysqlRepl` as inplicitly pointing to the same table.
|
352
|
+
|
353
|
+
```rb
|
354
|
+
[9] test(main)> Order.last.item.category.parent
|
355
|
+
```
|
356
|
+
|
357
|
+
<details><summary>output:</summary>
|
358
|
+
|
359
|
+
```rb
|
360
|
+
D, [2024-12-11T23:46:23.553443 #96076] DEBUG -- : Order Load (2.0ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
361
|
+
D, [2024-12-11T23:46:23.555918 #96076] DEBUG -- : Item Load (2.1ms) SELECT `items`.* FROM `items` WHERE `items`.`id` = '1' LIMIT 1
|
362
|
+
D, [2024-12-11T23:46:23.560142 #96076] DEBUG -- : Category Load (3.8ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = '2' LIMIT 1
|
363
|
+
D, [2024-12-11T23:46:23.562496 #96076] DEBUG -- : Category Load (1.3ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = '1' LIMIT 1
|
364
|
+
#<Category:0x000000012a73dd60> {
|
365
|
+
:id => "1",
|
366
|
+
:name => "category1",
|
367
|
+
:parent_id => ""
|
368
|
+
}
|
369
|
+
```
|
370
|
+
|
371
|
+
</details>
|
372
|
+
|
373
|
+
---
|
28
374
|
|
29
|
-
|
375
|
+
You can get user's profile by `.profile` because the custom association is defined here
|
376
|
+
|
377
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/main/sample_config/.army.sample/associations.sample.yml#L4-L8
|
378
|
+
|
379
|
+
```rb
|
380
|
+
[6] test(main)> Order.last.user.profile
|
381
|
+
```
|
382
|
+
|
383
|
+
<details><summary>output:</summary>
|
384
|
+
|
385
|
+
```rb
|
386
|
+
|
387
|
+
D, [2024-12-12T18:23:41.382606 #2816] DEBUG -- : Order Load (8.6ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
388
|
+
D, [2024-12-12T18:23:41.389954 #2816] DEBUG -- : User Load (2.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = '1' LIMIT 1
|
389
|
+
D, [2024-12-12T18:23:41.392060 #2816] DEBUG -- : UserProfile Load (1.8ms) SELECT `user_profiles`.* FROM `user_profiles` WHERE `user_profiles`.`id` = '1' LIMIT 1
|
390
|
+
#<UserProfile:0x000000012330a010> {
|
391
|
+
:id => "1",
|
392
|
+
:name => "user1"
|
393
|
+
}
|
394
|
+
```
|
395
|
+
|
396
|
+
</details>
|
397
|
+
|
398
|
+
---
|
399
|
+
|
400
|
+
|
401
|
+
|
402
|
+
```rb
|
403
|
+
[10] test(main)> Order.last.item.brand
|
404
|
+
```
|
405
|
+
|
406
|
+
<details><summary>output:</summary>
|
407
|
+
|
408
|
+
```rb
|
409
|
+
D, [2024-12-11T23:46:28.715219 #96076] DEBUG -- : Order Load (4.1ms) SELECT `orders`.* FROM `orders` ORDER BY `orders`.`id` DESC LIMIT 1
|
410
|
+
D, [2024-12-11T23:46:28.717319 #96076] DEBUG -- : Item Load (1.7ms) SELECT `items`.* FROM `items` WHERE `items`.`id` = '1' LIMIT 1
|
411
|
+
D, [2024-12-11T23:46:28.731254 #96076] DEBUG -- : Brand Load (3.1ms) SELECT `brands`.* FROM `brands` WHERE `brands`.`id` = '1' LIMIT 1
|
412
|
+
#<Brand:0x000000012a411ab0> {
|
413
|
+
:id => "1",
|
414
|
+
:name => "brand1"
|
415
|
+
}
|
416
|
+
```
|
417
|
+
|
418
|
+
</details>
|
419
|
+
|
420
|
+
---
|
421
|
+
|
422
|
+
By `tab` (an alias to `tabulate`), the filtered records are shown in a table format. `.tab(orientation)` accepts the `:h(orizontal)` (default when <5 columns), and `:v(ertival)` (default when >=5 columns)
|
423
|
+
|
424
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/9f7c91774b176e1204ed434dad2867721982c660/lib/active_record_mysql_repl/extensions/object.rb#L11
|
425
|
+
|
426
|
+
```rb
|
427
|
+
[3] test(main)> Order.all.tab
|
428
|
+
```
|
429
|
+
|
430
|
+
<details><summary>output:</summary>
|
431
|
+
|
432
|
+
```rb
|
433
|
+
D, [2024-12-11T23:48:46.013935 #96381] DEBUG -- : Order Load (2.2ms) SELECT `orders`.* FROM `orders`
|
434
|
+
+----+---------+---------+
|
435
|
+
| id | user_id | item_id |
|
436
|
+
+----+---------+---------+
|
437
|
+
| 1 | 1 | 1 |
|
438
|
+
+----+---------+---------+
|
439
|
+
```
|
440
|
+
|
441
|
+
</details>
|
442
|
+
|
443
|
+
---
|
444
|
+
|
445
|
+
```rb
|
446
|
+
[4] test(main)> Order.all.tab(:v)
|
447
|
+
```
|
448
|
+
|
449
|
+
<details><summary>output:</summary>
|
450
|
+
|
451
|
+
```rb
|
452
|
+
D, [2024-12-11T23:48:49.461243 #96381] DEBUG -- : Order Load (3.2ms) SELECT `orders`.* FROM `orders`
|
453
|
+
+---------+-------+
|
454
|
+
| Name | Value |
|
455
|
+
+---------+-------+
|
456
|
+
| id | 1 |
|
457
|
+
| user_id | 1 |
|
458
|
+
| item_id | 1 |
|
459
|
+
+---------+-------+
|
460
|
+
```
|
461
|
+
|
462
|
+
</details>
|
463
|
+
|
464
|
+
---
|
465
|
+
|
466
|
+
`.j` is aliased to `.to_json` and `.jp` is defined to generate pretty json.
|
467
|
+
|
468
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/9f7c91774b176e1204ed434dad2867721982c660/lib/active_record_mysql_repl/extensions/object.rb#L128-L132
|
469
|
+
|
470
|
+
```rb
|
471
|
+
[5] test(main)> Order.all.j
|
472
|
+
```
|
473
|
+
|
474
|
+
<details><summary>output:</summary>
|
475
|
+
|
476
|
+
```rb
|
477
|
+
D, [2024-12-11T23:48:55.267761 #96381] DEBUG -- : Order Load (4.4ms) SELECT `orders`.* FROM `orders`
|
478
|
+
[{"id":"1","user_id":"1","item_id":"1"}]
|
479
|
+
```
|
480
|
+
|
481
|
+
</details>
|
482
|
+
|
483
|
+
```rb
|
484
|
+
[6] test(main)> Order.all.jp
|
485
|
+
```
|
486
|
+
|
487
|
+
<details><summary>output:</summary>
|
488
|
+
|
489
|
+
```rb
|
490
|
+
D, [2024-12-11T23:48:57.250492 #96381] DEBUG -- : Order Load (1.8ms) SELECT `orders`.* FROM `orders`
|
491
|
+
[
|
492
|
+
{
|
493
|
+
"id": "1",
|
494
|
+
"user_id": "1",
|
495
|
+
"item_id": "1"
|
496
|
+
}
|
497
|
+
]
|
498
|
+
```
|
499
|
+
|
500
|
+
</details>
|
501
|
+
|
502
|
+
---
|
503
|
+
|
504
|
+
`.csv(orientation)` is defined to generate csv format. The default orientation is same as `.tab`.
|
505
|
+
|
506
|
+
https://github.com/nogahighland/active_record_mysql_repl/blob/9f7c91774b176e1204ed434dad2867721982c660/lib/active_record_mysql_repl/extensions/object.rb#L71
|
507
|
+
|
508
|
+
```rb
|
509
|
+
[1] test(main)> Order.all.csv
|
510
|
+
```
|
511
|
+
|
512
|
+
<details><summary>output:</summary>
|
513
|
+
|
514
|
+
```
|
515
|
+
D, [2024-12-12T01:29:12.844339 #26252] DEBUG -- : Order Load (2.7ms) SELECT `orders`.* FROM `orders`
|
516
|
+
id,user_id,item_id
|
517
|
+
1,1,1
|
518
|
+
```
|
519
|
+
|
520
|
+
</details>
|
521
|
+
|
522
|
+
---
|
523
|
+
|
524
|
+
`.cp` is defined to copy to clipboard the receiver object's `.to_s` representation.
|
525
|
+
|
526
|
+
```rb
|
527
|
+
[7] test(main)> Order.all.jp.cp
|
528
|
+
```
|
529
|
+
|
530
|
+
<details><summary>output:</summary>
|
531
|
+
|
532
|
+
```rb
|
533
|
+
D, [2024-12-11T23:48:59.443202 #96381] DEBUG -- : Order Load (2.0ms) SELECT `orders`.* FROM `orders`
|
534
|
+
true
|
535
|
+
```
|
536
|
+
|
537
|
+
</details>
|
538
|
+
|
539
|
+
---
|
540
|
+
|
541
|
+
`.exec_sql` is defined to execute the sql query and return the result as an array of hash.
|
542
|
+
|
543
|
+
```rb
|
544
|
+
[8] test(main)> exec_sql('select 1')
|
545
|
+
```
|
546
|
+
|
547
|
+
<details><summary>output:</summary>
|
548
|
+
|
549
|
+
```rb
|
550
|
+
D, [2024-12-11T23:49:15.879841 #96381] DEBUG -- : (1.2ms) select 1
|
551
|
+
[
|
552
|
+
[0] {
|
553
|
+
"1" => 1
|
554
|
+
}
|
555
|
+
]
|
556
|
+
```
|
557
|
+
|
558
|
+
</details>
|
559
|
+
|
560
|
+
---
|
561
|
+
|
562
|
+
```rb
|
563
|
+
[9] test(main)> exec_sql('select 1').tab
|
564
|
+
```
|
565
|
+
|
566
|
+
<details><summary>output:</summary>
|
567
|
+
|
568
|
+
```rb
|
569
|
+
D, [2024-12-11T23:49:17.187358 #96381] DEBUG -- : (2.1ms) select 1
|
570
|
+
+---+
|
571
|
+
| 1 |
|
572
|
+
+---+
|
573
|
+
| 1 |
|
574
|
+
+---+
|
575
|
+
```
|
576
|
+
|
577
|
+
</details>
|
578
|
+
|
579
|
+
---
|
580
|
+
|
581
|
+
```rb
|
582
|
+
[10] test(main)> exec_sql('select 1 as num').tab
|
583
|
+
```
|
584
|
+
|
585
|
+
<details><summary>output:</summary>
|
586
|
+
|
587
|
+
```
|
588
|
+
D, [2024-12-11T23:49:22.406631 #96381] DEBUG -- : (1.3ms) select 1 as num
|
589
|
+
+-----+
|
590
|
+
| num |
|
591
|
+
+-----+
|
592
|
+
| 1 |
|
593
|
+
+-----+
|
594
|
+
```
|
595
|
+
|
596
|
+
</details>
|
597
|
+
|
598
|
+
---
|
599
|
+
|
600
|
+
You can define your own extension script. For example `.upcase_name` is defined on `UserProfile` by the sample extension which is specified in the `.army.sample.yml` file.
|
601
|
+
|
602
|
+
- https://github.com/nogahighland/active_record_mysql_repl/blob/9f7c91774b176e1204ed434dad2867721982c660/sample_config/.army.sample.yml#L5
|
603
|
+
- https://github.com/nogahighland/active_record_mysql_repl/blob/main/sample_config/.army.sample/extensions/hello.rb
|
604
|
+
|
605
|
+
```rb
|
606
|
+
[3] test(main)> UserProfile.last.upcase_name
|
607
|
+
```
|
608
|
+
|
609
|
+
<details><summary>output:</summary>
|
610
|
+
|
611
|
+
```
|
612
|
+
D, [2024-12-12T12:09:10.987656 #60808] DEBUG -- : UserProfile Load (1.7ms) SELECT `user_profiles`.* FROM `user_profiles` ORDER BY `user_profiles`.`id` DESC LIMIT 1
|
613
|
+
USER1
|
614
|
+
```
|
615
|
+
|
616
|
+
</details>
|
617
|
+
|
618
|
+
---
|
619
|
+
|
620
|
+
## Development
|
30
621
|
|
31
|
-
|
622
|
+
TODO
|
32
623
|
|
33
624
|
## Contributing
|
34
625
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
626
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nogahifhland/active_record_mysql_repl. 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/nogahighland/active_record_mysql_repl/blob/main/CODE_OF_CONDUCT.md).
|
36
627
|
|
37
628
|
## License
|
38
629
|
|
@@ -10,13 +10,18 @@ module ActiveRecordMysqlRepl
|
|
10
10
|
module CLI
|
11
11
|
module Main
|
12
12
|
def self.run(args)
|
13
|
+
if args.empty?
|
14
|
+
puts "ActiveRecordMysqlRepl Version: #{VERSION}"
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
13
18
|
if args[0] == '--zsh-completion'
|
14
19
|
puts ZshCompletion.generate
|
15
20
|
return
|
16
21
|
end
|
17
22
|
|
18
23
|
opts = CLI::Options.parse(args)
|
19
|
-
army_config = Config.load(opts[:c] || '
|
24
|
+
army_config = Config.load(opts[:c] || File.join(Dir.home, '.army.yml'))
|
20
25
|
|
21
26
|
db_configs = Database::Configs.load(army_config.database_config)
|
22
27
|
db_config_key = opts[:d]
|
@@ -27,7 +27,7 @@ module ActiveRecordMysqlRepl
|
|
27
27
|
|
28
28
|
# Analyze the relationship between tables based on the information of *_id columns
|
29
29
|
# For example, if users.company_id exists, users belongs_to companies and companies has_many users
|
30
|
-
def self.analyze(tables, association_settings)
|
30
|
+
def self.analyze(tables, association_settings = {})
|
31
31
|
analyzed_tables = tables.map { |table| [table, AnalyzedTable.new(table)] }.to_h
|
32
32
|
|
33
33
|
analyzed_tables.each do |table_name, table|
|
@@ -11,9 +11,15 @@ module ActiveRecordMysqlRepl
|
|
11
11
|
puts "Loading tables".gray
|
12
12
|
|
13
13
|
tables = ActiveRecord::Base.connection.tables
|
14
|
-
association_settings = Associations.load(army_config.associations)
|
15
|
-
|
16
|
-
analyzed_tables =
|
14
|
+
association_settings = army_config.associations.present? ? Associations.load(army_config.associations) : {}
|
15
|
+
association_setting = association_settings[db_config_key]
|
16
|
+
analyzed_tables = begin
|
17
|
+
if association_setting.present?
|
18
|
+
Associations.analyze(tables, association_setting)
|
19
|
+
else
|
20
|
+
Associations.analyze(tables)
|
21
|
+
end
|
22
|
+
end
|
17
23
|
skipped = []
|
18
24
|
analyzed_tables.each do |analyzed_table|
|
19
25
|
# defer model definition for tables with `has_many: :xxx, through: xxx` associations
|
@@ -71,14 +71,14 @@ module ActiverecordMysqlRepl
|
|
71
71
|
def csv(orientation = nil)
|
72
72
|
arr = if self.is_a?(Array)
|
73
73
|
self
|
74
|
-
elsif self.is_a?(ActiveRecord::Relation)
|
74
|
+
elsif self.is_a?(::ActiveRecord::Relation)
|
75
75
|
self.to_a
|
76
76
|
else
|
77
77
|
[self]
|
78
78
|
end
|
79
79
|
|
80
80
|
arr = arr.map do |e|
|
81
|
-
if e.is_a?(ActiveRecord::Base)
|
81
|
+
if e.is_a?(::ActiveRecord::Base)
|
82
82
|
values = e.attributes.transform_values do |v|
|
83
83
|
next JSON.pretty_generate(v) if v.is_a?(Enumerable) && v.size > 0
|
84
84
|
next 'NULL' if v.nil?
|
@@ -1,9 +1,9 @@
|
|
1
|
-
# yaml-language-server: $schema=https://raw.githubusercontent.com/nogahighland/active_record_mysql_repl/refs/heads/main/
|
1
|
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/nogahighland/active_record_mysql_repl/refs/heads/main/json_schemas/databases_schema.json
|
2
2
|
|
3
3
|
test:
|
4
4
|
remote_host: 127.0.0.1
|
5
5
|
database: test
|
6
|
-
port:
|
6
|
+
port: 33060
|
7
7
|
user: root
|
8
8
|
password: root
|
9
9
|
prompt_color: cyan
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# yaml-language-server: $schema=https://raw.githubusercontent.com/nogahighland/active_record_mysql_repl/refs/heads/main/json_schemas/army_schema.json
|
2
2
|
|
3
|
-
database_config:
|
4
|
-
associations:
|
5
|
-
extensions_dir:
|
6
|
-
pryrc: ./.pryrc.sample
|
3
|
+
database_config: ./.army.sample/databases.sample.yml
|
4
|
+
associations: ./.army.sample/associations.sample.yml
|
5
|
+
extensions_dir: ./.army.sample/extensions
|
6
|
+
pryrc: ./.army.sample/.pryrc.sample
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_mysql_repl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroki Kishi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -214,6 +214,7 @@ executables:
|
|
214
214
|
extensions: []
|
215
215
|
extra_rdoc_files: []
|
216
216
|
files:
|
217
|
+
- ".bundle/config"
|
217
218
|
- ".rspec"
|
218
219
|
- ".standard.yml"
|
219
220
|
- CHANGELOG.md
|
@@ -248,9 +249,10 @@ files:
|
|
248
249
|
- lib/active_record_mysql_repl/ssh_tunnel.rb
|
249
250
|
- lib/active_record_mysql_repl/version.rb
|
250
251
|
- sample_config/.army.sample.yml
|
251
|
-
- sample_config/.pryrc.sample
|
252
|
-
- sample_config/associations.sample.yml
|
253
|
-
- sample_config/databases.sample.yml
|
252
|
+
- sample_config/.army.sample/.pryrc.sample
|
253
|
+
- sample_config/.army.sample/associations.sample.yml
|
254
|
+
- sample_config/.army.sample/databases.sample.yml
|
255
|
+
- sample_config/.army.sample/extensions/hello.rb
|
254
256
|
- sample_config/sample_db.sql
|
255
257
|
homepage: https://github.com/nogahighland/active_record_mysql_repl
|
256
258
|
licenses:
|
File without changes
|