active_record_mysql_repl 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: accf9badcb507bbebe51faf48edd6ef5fe850e01214cc34a8be1b06400b5a8d7
4
- data.tar.gz: 225572e71a93254ccb85ee5c1b5d0878a8fe5a71ac9c44eab6d236c4f113accc
3
+ metadata.gz: 1d60c9d4baca1fb49f423f128a5015c348e17301c593895afa9083c2ee47b495
4
+ data.tar.gz: 4060d8523d63a3db240d6cd96cefcc6f1e0a0e3e4c2e35691d736005f86f90e3
5
5
  SHA512:
6
- metadata.gz: f8cd05e53b0e49770e89fdf93f9ceb9c29df31d814f7f721267304e9557df7d753673781a05b3c8282ab019b16306f5d4e4920a7a7b2ff8776f1ab6da0a0fa5e
7
- data.tar.gz: 0db40cd1589fa912dbb76c2d95195bec40d5ffc59affef92afc35eb6ec32a3c66cb7bccd73114bb9472dc5e726f855bc73f473fbe2d3f91fa82313144eeecf88
6
+ metadata.gz: 9fa3e154a372791095e0b6e4766e7a23d3a1c3f4f74fda84a0d4aeac33d2ef202080911a447c4a9ebe6b7a47eb09a9138630715e46b7bb482dbac5b1d2528fe3
7
+ data.tar.gz: e8599c8c29441696533ace9baa75163a24a271cd8b74a67e7038af2ec8e16c540ef869029438344fe75aa2f455b8012d61459efa26046ebcf86987314ef66c2d
data/.bundle/config ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_PATH: "vendor/bundle"
3
+ BUNDLE_BUILD__MYSQL2: "--with-mysql-dir=/opt/homebrew/opt/mysql-client@8.4"
data/README.md CHANGED
@@ -1,38 +1,629 @@
1
1
  # ActiveRecordMysqlRepl
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
3
+ ## Prerequisites
4
4
 
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/active_record_mysql_repl`. To experiment with that code, run `bin/console` for an interactive prompt.
5
+ ### Ruby version 3.0.0 or higher
6
6
 
7
- ## Installation
7
+ e.g) Using rbenv
8
+
9
+ ```bash
10
+ $ rbenv install 3.3.6
11
+ ```
8
12
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
13
+ ### mysql-client 8.0
10
14
 
11
- Install the gem and add to the application's Gemfile by executing:
15
+ e.g) on macOS
12
16
 
13
17
  ```bash
14
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
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
- If bundler is not being used to manage dependencies, install the gem by executing:
22
+ ## Installation
23
+
24
+ Just by installing the gem, you can use the `army` command.
18
25
 
19
26
  ```bash
20
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
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
- TODO: Write usage instructions here
58
+ ### Sample Configurations
26
59
 
27
- ## Development
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
+ ![image](https://github.com/user-attachments/assets/ddc59020-42db-4240-91db-76dae560fdf5)
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
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
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
- 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).
622
+ TODO
32
623
 
33
624
  ## Contributing
34
625
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/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/[USERNAME]/active_record_mysql_repl/blob/main/CODE_OF_CONDUCT.md).
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] || '~/.army.yml')
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]
@@ -14,7 +14,7 @@ module ActiveRecordMysqlRepl
14
14
  end
15
15
 
16
16
  def associations
17
- File.join(@army_config_dir, @associations)
17
+ File.join(@army_config_dir, @associations) if @associations.present?
18
18
  end
19
19
 
20
20
  def extensions_dir
@@ -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 = Associations.analyze(tables, association_settings[db_config_key])
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
@@ -10,6 +10,7 @@ module ActiverecordMysqlRepl
10
10
 
11
11
  def describe
12
12
  [
13
+ "# #{self.table_name}",
13
14
  exec_sql("DESCRIBE #{self.table_name}").tab(:h),
14
15
  exec_sql("SHOW INDEX FROM #{self.table_name}").tab(:h)
15
16
  ].join("\n")
@@ -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,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordMysqlRepl
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require "awesome_print"
3
5
  Pry.config.print = proc do |_output, value, pry_instance|
@@ -1,9 +1,9 @@
1
- # yaml-language-server: $schema=https://raw.githubusercontent.com/nogahighland/active_record_mysql_repl/refs/heads/main/json_schema/databases_schema.json
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: 3306
6
+ port: 33060
7
7
  user: root
8
8
  password: root
9
9
  prompt_color: cyan
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UpcaseName
4
+ def upcase_name
5
+ self.name.upcase
6
+ end
7
+ end
8
+
9
+ ::UserProfile.include UpcaseName
@@ -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: ./databases.sample.yml
4
- associations: ./associations.sample.yml
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.2
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 00:00:00.000000000 Z
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: