pokotarou 0.1.3 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +262 -100
- data/lib/pokotarou.rb +9 -0
- data/lib/pokotarou/additional_variables/additional_variables.rb +24 -0
- data/lib/pokotarou/additional_variables/def_const.rb +1 -0
- data/lib/pokotarou/arguments/arguments.rb +23 -0
- data/lib/pokotarou/arguments/def_args.rb +1 -0
- data/lib/pokotarou/data_register.rb +10 -16
- data/lib/pokotarou/data_structure.rb +90 -3
- data/lib/pokotarou/expression_parser.rb +148 -49
- data/lib/pokotarou/{loader.rb → file_loader.rb} +0 -0
- data/lib/pokotarou/pokotarou_handler.rb +1 -1
- data/lib/pokotarou/seeder.rb +1 -1
- data/lib/pokotarou/version.rb +1 -1
- metadata +8 -5
- data/lib/pokotarou/query_builder.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09fe06e78e1bb9689b0bbdd003ad3261dee699ce3f201bdf9174b10b6771f629'
|
4
|
+
data.tar.gz: 14ae8d05a09c850be66328e46172f16aa2bce32dbacc2564802fa41982473c59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0a6dccec5227439517f6b52ec1da3ca6181bdf4b04e2bee2f6afb4b439d709899fe731332d11ddce677fac9c8a2ed112ec0ac95a9ef1bc2aa5da674e4f4aae0
|
7
|
+
data.tar.gz: f50b5e74b3c0aef027785cec760372ea2ab6df81323950180726d4ebbbaa196b6b2a788eb4e7a5fa2ac3b0e9a94a9f99e3aaac4ee27ae20ac0d7e56f4571cf51
|
data/README.md
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
![s_PokotarouLogo](https://user-images.githubusercontent.com/52961642/
|
1
|
+
![s_PokotarouLogo](https://user-images.githubusercontent.com/52961642/62843884-46f6c700-bcf8-11e9-8267-b9fad8f34085.png)
|
2
|
+
|
3
|
+
|
2
4
|
[![Gem Version](https://badge.fury.io/rb/pokotarou.svg)](https://badge.fury.io/rb/pokotarou)
|
3
|
-
[![Build Status](https://travis-ci.org/
|
5
|
+
[![Build Status](https://travis-ci.org/Kashiwara0205/Pokotarou.svg?branch=master)](https://travis-ci.org/Kashiwara0205/Pokotarou)
|
4
6
|
|
5
|
-
Pokotarou is convenient seeder of 'Ruby on Rails'
|
6
|
-
|
7
|
+
Pokotarou is convenient seeder of 'Ruby on Rails'
|
8
|
+
In MySql, operation has been confirmed
|
7
9
|
|
8
10
|
## Features
|
9
11
|
|
10
12
|
### Easy to use
|
11
|
-
|
12
|
-
|
13
|
+
You don't have to write a program for seed
|
14
|
+
Can be set simply by writing a yml file!
|
13
15
|
|
14
16
|
### Fast speed
|
15
|
-
If it is the following table, 10,000 records can regist in 0.
|
17
|
+
If it is the following table, 10,000 records can regist in 0.41s on average
|
16
18
|
|
17
19
|
|Field|Type|NULL|
|
18
20
|
|:---|:---|:---|
|
@@ -42,20 +44,35 @@ $ gem install pokotarou
|
|
42
44
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
43
45
|
|
44
46
|
## Usage
|
45
|
-
Introduce how to execute and write configuration file.
|
46
|
-
If you want to know more information file settings, please refer to the test
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
Following yml file become seed data.
|
49
|
+
|
50
|
+
Please make following yml file in your favorite dir.
|
50
51
|
|
52
|
+
```yml
|
53
|
+
Default:
|
54
|
+
Pref:
|
55
|
+
loop: 3
|
51
56
|
```
|
52
|
-
|
57
|
+
|
58
|
+
and write following ruby code in seeds.rb.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
Pokotarou.execute("./config_filepath")
|
62
|
+
```
|
63
|
+
|
64
|
+
when you finished writing, then run rails db:seed
|
65
|
+
|
66
|
+
```bash
|
67
|
+
$ rails db:seed
|
53
68
|
```
|
54
|
-
### Configration file
|
55
69
|
|
56
|
-
|
70
|
+
As a result, seed data is registerd your db.
|
71
|
+
|
72
|
+
## How to set configlation file(.yml)?
|
73
|
+
explain how to write the configuration file below.
|
57
74
|
|
58
|
-
|
75
|
+
### Model used for explanation
|
59
76
|
Table name below is 'prefs' and model name is 'Pref'
|
60
77
|
|
61
78
|
|Field|Type|NULL|
|
@@ -79,76 +96,69 @@ Table name below is 'members' and model name is 'Member'
|
|
79
96
|
|updated_at|datetime|NO|
|
80
97
|
|
81
98
|
|
82
|
-
|
83
|
-
|
84
|
-
id column is basically registerd by autoincrement
|
99
|
+
### Standerd Setting
|
100
|
+
The basic setting method is written below
|
85
101
|
|
86
|
-
|
87
|
-
Default:
|
88
|
-
Pref:
|
89
|
-
loop: 3
|
90
|
-
```
|
102
|
+
#### Automatic data entry
|
91
103
|
|
104
|
+
If there is no definition about col, then automatically prepared data is registrd.
|
92
105
|
|
93
|
-
|
106
|
+
For example, in the case of below, it is registered automatically prepared data three times.
|
94
107
|
|
95
|
-
```
|
108
|
+
```yml
|
96
109
|
Default:
|
97
110
|
Pref:
|
98
111
|
loop: 3
|
99
|
-
col:
|
100
|
-
name: "Hokkaido"
|
101
112
|
```
|
102
113
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
```
|
114
|
+
also you can set seed_data by yourself.
|
115
|
+
```yml
|
107
116
|
Default:
|
108
117
|
Pref:
|
109
118
|
loop: 3
|
110
119
|
col:
|
111
|
-
name:
|
120
|
+
name: "Hokkaido"
|
112
121
|
```
|
113
122
|
|
114
|
-
####
|
115
|
-
|
123
|
+
#### Omitted loop
|
124
|
+
If you want to register the test data at once, I suggest ommited loop
|
116
125
|
|
117
|
-
```
|
126
|
+
```yml
|
118
127
|
Default:
|
119
|
-
Pref:
|
120
|
-
loop: 2
|
121
|
-
col:
|
122
|
-
name: ["Hokkaido", "Aomori"]
|
123
|
-
Member:
|
124
|
-
loop: 2
|
128
|
+
Pref:
|
125
129
|
col:
|
126
|
-
name:
|
127
|
-
pref_id: F|Pref
|
130
|
+
name: ["Hokkaido"]
|
128
131
|
```
|
129
132
|
|
133
|
+
```ruby
|
134
|
+
["Hokkaido"]
|
130
135
|
```
|
136
|
+
|
137
|
+
#### Array
|
138
|
+
You can set array_data.
|
139
|
+
|
140
|
+
Array data is registerd one by one.
|
141
|
+
|
142
|
+
```yml
|
131
143
|
Default:
|
132
144
|
Pref:
|
133
145
|
loop: 3
|
134
146
|
col:
|
135
147
|
name: ["Hokkaido", "Aomori", "Iwate"]
|
136
|
-
Member:
|
137
|
-
loop: 3
|
138
|
-
col:
|
139
|
-
name: ["Tarou", "Jirou", "Saburou"]
|
140
|
-
remarks: <maked[:Default][:Member][:name]>
|
141
|
-
pref_id: F|Pref
|
142
|
-
|
143
148
|
```
|
144
149
|
|
145
|
-
|
150
|
+
#### Maked function
|
151
|
+
'maked' is very useful function.
|
152
|
+
it is hash and accumulate data created in the past.
|
153
|
+
|
154
|
+
For example, in the case of below, reffer name of Pref in Default block by maked
|
155
|
+
|
156
|
+
```yml
|
146
157
|
Default:
|
147
|
-
Pref:
|
158
|
+
Pref:
|
148
159
|
loop: 2
|
149
160
|
col:
|
150
161
|
name: ["Hokkaido", "Aomori"]
|
151
|
-
Default2:
|
152
162
|
Member:
|
153
163
|
loop: 2
|
154
164
|
col:
|
@@ -160,10 +170,11 @@ Default2:
|
|
160
170
|
|
161
171
|
**※ If you set association(belongs_to, has_many...), Pokotarou automatically register foreign keys**
|
162
172
|
|
163
|
-
|
164
|
-
In the following source code, Foreign key of prefectures is registerd
|
173
|
+
' F| ' means foreign key. 'F|' is Model.all.pluck(:id)
|
165
174
|
|
166
|
-
|
175
|
+
For example, in the case of below, Member model record is registerd with pref_id(foregin key).
|
176
|
+
|
177
|
+
```yml
|
167
178
|
Default:
|
168
179
|
Pref:
|
169
180
|
loop: 3
|
@@ -176,10 +187,10 @@ Default:
|
|
176
187
|
```
|
177
188
|
|
178
189
|
#### Expression expansion
|
179
|
-
|
180
|
-
You can run ruby code in '< >'
|
190
|
+
'< >' means expression expansion.
|
191
|
+
You can run ruby code in '< >'.
|
181
192
|
|
182
|
-
```
|
193
|
+
```yml
|
183
194
|
Default:
|
184
195
|
Pref:
|
185
196
|
loop: 3
|
@@ -188,10 +199,10 @@ Default:
|
|
188
199
|
created_at: <Date.parse('1997/02/05')>
|
189
200
|
```
|
190
201
|
|
191
|
-
####
|
202
|
+
#### Additional method
|
192
203
|
You can add method and use it in pokotarou
|
193
204
|
|
194
|
-
```
|
205
|
+
```yml
|
195
206
|
Default:
|
196
207
|
Pref:
|
197
208
|
loop: 3
|
@@ -200,24 +211,27 @@ Default:
|
|
200
211
|
```
|
201
212
|
|
202
213
|
Prepare the following ruby file
|
203
|
-
|
214
|
+
|
215
|
+
```ruby
|
204
216
|
def pref_name
|
205
217
|
["Hokkaido", "Aomori", "Iwate"]
|
206
218
|
end
|
207
219
|
```
|
208
|
-
and execute the following source code in seeds.rb of Ruby on Rails
|
209
220
|
|
210
|
-
|
211
|
-
|
212
|
-
|
221
|
+
and run the following code in seeds.rb.
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
Pokotarou.import("./method_filepath")
|
225
|
+
Pokotarou.execute("./config_filepath")
|
213
226
|
```
|
214
227
|
|
228
|
+
As as result, pokotarou can call pref_name method, and seed data is registrd by pref_name method.
|
215
229
|
|
216
|
-
####
|
230
|
+
#### Multiple blocks
|
217
231
|
|
218
|
-
|
232
|
+
You can use multiple blocks.
|
219
233
|
|
220
|
-
```
|
234
|
+
```yml
|
221
235
|
Default:
|
222
236
|
Pref:
|
223
237
|
loop: 3
|
@@ -228,7 +242,7 @@ Default2:
|
|
228
242
|
|
229
243
|
and, You can change the name of the block
|
230
244
|
|
231
|
-
```
|
245
|
+
```yml
|
232
246
|
Hoge:
|
233
247
|
Pref:
|
234
248
|
loop: 3
|
@@ -237,11 +251,14 @@ Fuga:
|
|
237
251
|
loop: 3
|
238
252
|
```
|
239
253
|
|
254
|
+
### option
|
255
|
+
Option is useful function.
|
256
|
+
If you can master it, it may be easier to create test data.
|
240
257
|
|
241
258
|
#### Random
|
242
259
|
Shuffle seed data when regist
|
243
260
|
|
244
|
-
```
|
261
|
+
```yml
|
245
262
|
Default:
|
246
263
|
Pref:
|
247
264
|
loop: 3
|
@@ -253,14 +270,14 @@ Default:
|
|
253
270
|
|
254
271
|
The following results change from run to run
|
255
272
|
|
256
|
-
```
|
273
|
+
```ruby
|
257
274
|
["Aomori", "Iwate", "Iwate"]
|
258
275
|
```
|
259
276
|
|
260
277
|
#### Add_id
|
261
278
|
Add individual number to seed data of String type
|
262
279
|
|
263
|
-
```
|
280
|
+
```yml
|
264
281
|
Default:
|
265
282
|
Pref:
|
266
283
|
loop: 3
|
@@ -270,14 +287,14 @@ Default:
|
|
270
287
|
name: ["add_id"]
|
271
288
|
```
|
272
289
|
|
273
|
-
```
|
290
|
+
```ruby
|
274
291
|
["Hokkaido_0", "Aomori"_1, "Iwate_2"]
|
275
292
|
```
|
276
293
|
|
277
294
|
#### Combine serveral options
|
278
295
|
Combination of options is possible
|
279
296
|
|
280
|
-
```
|
297
|
+
```yml
|
281
298
|
Default:
|
282
299
|
Pref:
|
283
300
|
loop: 3
|
@@ -289,28 +306,31 @@ Default:
|
|
289
306
|
|
290
307
|
The following results change from run to run
|
291
308
|
|
292
|
-
```
|
309
|
+
```ruby
|
293
310
|
["Hokkaido_0", "Iwate_1", "Hokkaido_2"]
|
294
311
|
```
|
295
312
|
|
313
|
+
### Advanced Setting
|
314
|
+
The advanced setting method is written below
|
315
|
+
|
296
316
|
#### Validation
|
297
317
|
|
298
318
|
Run validation when regist
|
299
319
|
|
300
|
-
```
|
320
|
+
```yml
|
301
321
|
Default:
|
302
322
|
Pref:
|
303
323
|
loop: 3
|
304
324
|
validate: true
|
305
325
|
```
|
306
326
|
|
307
|
-
#### Autoincrement
|
327
|
+
#### Disable Autoincrement
|
308
328
|
|
309
329
|
You can disable the autoincrement setting
|
310
330
|
|
311
|
-
If you disable the setting, you can register id data prepared by
|
331
|
+
If you disable the setting, you can register id data prepared by yourself
|
312
332
|
|
313
|
-
```
|
333
|
+
```yml
|
314
334
|
Default:
|
315
335
|
Pref:
|
316
336
|
loop: 3
|
@@ -321,59 +341,169 @@ Default:
|
|
321
341
|
|
322
342
|
#### Pokotarou Handler
|
323
343
|
|
324
|
-
|
344
|
+
If you want to use configlation yml data in ruby code then you can use "PokotarouHandler"
|
345
|
+
|
346
|
+
When you use "PokotarouHandler", can update pokotarou's parameter
|
347
|
+
in ruby code.
|
348
|
+
|
349
|
+
|
350
|
+
<b>Change Operation</b>
|
325
351
|
|
326
352
|
In the following example, the number of loops is changed
|
327
353
|
|
328
|
-
```
|
329
|
-
handler = Pokotarou.gen_handler("
|
330
|
-
# change loop
|
354
|
+
```ruby
|
355
|
+
handler = Pokotarou.gen_handler("./config_filepath")
|
356
|
+
# change loop config
|
331
357
|
handler.change_loop(:Default, :Pref, 6)
|
332
358
|
Pokotarou.execute(handler.get_data)
|
333
359
|
```
|
334
360
|
|
335
|
-
In the following example, delete class in parameter
|
336
361
|
|
362
|
+
In the following example, seed data is changed
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
handler = Pokotarou.gen_handler("./config_filepath")
|
366
|
+
# change seed data config number
|
367
|
+
handler.change_seed(:Default, :Pref, :name, ["a", "b", "c"])
|
368
|
+
Pokotarou.execute(handler.get_data)
|
369
|
+
```
|
370
|
+
|
371
|
+
<b>Delete Operation</b>
|
372
|
+
|
373
|
+
In the following example, delete block config
|
374
|
+
|
375
|
+
```ruby
|
376
|
+
handler = Pokotarou.gen_handler("./config_filepath")
|
377
|
+
# delete model config in parameter
|
378
|
+
handler.delete_block(:Default)
|
379
|
+
Pokotarou.execute(handler.get_data)
|
337
380
|
```
|
338
|
-
|
339
|
-
|
340
|
-
|
381
|
+
|
382
|
+
In the following example, delete model config
|
383
|
+
|
384
|
+
```ruby
|
385
|
+
handler = Pokotarou.gen_handler("./config_filepath")
|
386
|
+
# delete model config in parameter
|
387
|
+
handler.delete_model(:Default, :Pref)
|
341
388
|
Pokotarou.execute(handler.get_data)
|
342
389
|
```
|
343
390
|
|
344
|
-
|
391
|
+
In the following example, delete col config
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
handler = Pokotarou.gen_handler("./config_filepath")
|
395
|
+
# delete col config in parameter
|
396
|
+
handler.delete_col(:Default, :Pref, :name)
|
397
|
+
Pokotarou.execute(handler.get_data)
|
398
|
+
```
|
345
399
|
|
346
|
-
|
400
|
+
#### Const
|
401
|
+
You can set const variables by const' key.
|
347
402
|
|
403
|
+
```yml
|
404
|
+
const':
|
405
|
+
name: "hoge"
|
406
|
+
Default:
|
407
|
+
Pref:
|
408
|
+
loop: 3
|
409
|
+
col:
|
410
|
+
name: <const[:name]>
|
348
411
|
```
|
412
|
+
|
413
|
+
#### Grouping
|
414
|
+
Grouping is very useful function.
|
415
|
+
Especially useful when setting multiple options.
|
416
|
+
|
417
|
+
|
418
|
+
```yml
|
349
419
|
Default:
|
420
|
+
Member:
|
421
|
+
grouping:
|
422
|
+
# set columns you want to group
|
423
|
+
hoge_g: ["name", "remark"]
|
424
|
+
col:
|
425
|
+
# you can use "hoge_g" at col
|
426
|
+
hoge_g: <['fugafuga!']>
|
427
|
+
option:
|
428
|
+
# also you can use "hoge_g" at option
|
429
|
+
hoge_g: ["add_id"]
|
430
|
+
|
431
|
+
```
|
432
|
+
|
433
|
+
#### Template
|
434
|
+
You can set template config by template' key.
|
435
|
+
|
436
|
+
The template can be overwritten with the one set later.
|
437
|
+
|
438
|
+
```yml
|
439
|
+
template':
|
440
|
+
pref_template:
|
441
|
+
loop: 3
|
442
|
+
col:
|
443
|
+
pref_id: F|Pref
|
444
|
+
name: ["hogeta", "fuga", "pokota"]
|
445
|
+
Pref:
|
350
446
|
Pref:
|
351
447
|
loop: 3
|
352
448
|
col:
|
353
449
|
name: ["Hokkaido", "Aomori", "Iwate"]
|
354
|
-
convert:
|
355
|
-
name: ["nil(0..2)"]
|
356
|
-
```
|
357
450
|
|
358
|
-
|
359
|
-
|
451
|
+
Member1:
|
452
|
+
Member:
|
453
|
+
template: pref_template
|
454
|
+
|
455
|
+
Member2:
|
456
|
+
Member:
|
457
|
+
template: pref_template
|
458
|
+
col:
|
459
|
+
name: ["hogeta2", "fuga2", "pokota2"]
|
360
460
|
```
|
361
461
|
|
362
|
-
|
462
|
+
#### Return
|
463
|
+
You can set return val by return' key.
|
363
464
|
|
364
|
-
```
|
465
|
+
```yml
|
365
466
|
Default:
|
366
467
|
Pref:
|
367
468
|
loop: 3
|
368
469
|
col:
|
369
470
|
name: ["Hokkaido", "Aomori", "Iwate"]
|
370
|
-
|
371
|
-
|
471
|
+
|
472
|
+
return': <maked[:Default][:Pref][:name]>
|
473
|
+
|
372
474
|
```
|
373
475
|
|
476
|
+
```ruby
|
477
|
+
return_val = Pokotarou.execute("filepath")
|
478
|
+
puts return_val
|
374
479
|
```
|
375
|
-
|
480
|
+
|
481
|
+
result
|
376
482
|
```
|
483
|
+
Hokkaido
|
484
|
+
Aomori
|
485
|
+
Iwate
|
486
|
+
```
|
487
|
+
#### Args
|
488
|
+
|
489
|
+
You can set args by hash.
|
490
|
+
|
491
|
+
```yml
|
492
|
+
Default:
|
493
|
+
Pref:
|
494
|
+
loop: 3
|
495
|
+
col:
|
496
|
+
name: <args[:name]>
|
497
|
+
```
|
498
|
+
```ruby
|
499
|
+
Pokotarou.set_args({ name: ["Hokkaido", "Aomori", "Iwate"] })
|
500
|
+
Pokotarou.execute("filepath")
|
501
|
+
```
|
502
|
+
|
503
|
+
### Convert
|
504
|
+
convert is a convenient function. Will convert the seed data.
|
505
|
+
|
506
|
+
#### convert option
|
377
507
|
|
378
508
|
|convert |description |
|
379
509
|
|:---------|------------------------------------------|
|
@@ -381,3 +511,35 @@ Default:
|
|
381
511
|
| nil | convert val to nil |
|
382
512
|
| big_text | convert val to big_text("text" * 50) |
|
383
513
|
| br_text | convert val to br_text("text\n" * 5) |
|
514
|
+
|
515
|
+
For example, following configfile register seed data while replacing with nil
|
516
|
+
|
517
|
+
```yml
|
518
|
+
Default:
|
519
|
+
Pref:
|
520
|
+
loop: 3
|
521
|
+
col:
|
522
|
+
name: ["Hokkaido", "Aomori", "Iwate"]
|
523
|
+
convert:
|
524
|
+
name: ["nil(0..2)"]
|
525
|
+
```
|
526
|
+
|
527
|
+
```ruby
|
528
|
+
[nil, nil, nil]
|
529
|
+
```
|
530
|
+
|
531
|
+
a little complex version
|
532
|
+
|
533
|
+
```yml
|
534
|
+
Default:
|
535
|
+
Pref:
|
536
|
+
loop: 3
|
537
|
+
col:
|
538
|
+
name: ["Hokkaido", "Aomori", "Iwate"]
|
539
|
+
convert:
|
540
|
+
name: ["empty(0..0)", "nil(1..2)"]
|
541
|
+
```
|
542
|
+
|
543
|
+
```ruby
|
544
|
+
["", nil, nil]
|
545
|
+
```
|
data/lib/pokotarou.rb
CHANGED
@@ -20,8 +20,13 @@ module Pokotarou
|
|
20
20
|
AdditionalMethods.import(filepath)
|
21
21
|
end
|
22
22
|
|
23
|
+
def set_args hash
|
24
|
+
Arguments.import(hash)
|
25
|
+
end
|
26
|
+
|
23
27
|
def reset
|
24
28
|
AdditionalMethods.remove()
|
29
|
+
Arguments.remove()
|
25
30
|
end
|
26
31
|
|
27
32
|
def gen_handler filepath
|
@@ -32,9 +37,13 @@ module Pokotarou
|
|
32
37
|
|
33
38
|
def gen_config filepath
|
34
39
|
contents = load_file(filepath)
|
40
|
+
set_const_val_config(contents)
|
35
41
|
DataStructure.gen(contents)
|
36
42
|
end
|
37
43
|
|
44
|
+
def set_const_val_config contents
|
45
|
+
AdditionalVariables.import(contents)
|
46
|
+
end
|
38
47
|
|
39
48
|
def load_file filepath
|
40
49
|
case File.extname(filepath)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AdditionalVariables
|
2
|
+
class << self
|
3
|
+
CONST_KEY = :"const'"
|
4
|
+
@const = nil
|
5
|
+
attr_reader :const
|
6
|
+
|
7
|
+
def import data
|
8
|
+
return unless data.has_key?(CONST_KEY)
|
9
|
+
@const = data[CONST_KEY]
|
10
|
+
|
11
|
+
# parse expression configlation
|
12
|
+
@const.each do |key, val|
|
13
|
+
@const[key] = ConstExpressionParser.parse(val)
|
14
|
+
end
|
15
|
+
|
16
|
+
data.delete(CONST_KEY)
|
17
|
+
end
|
18
|
+
|
19
|
+
def filepath
|
20
|
+
"pokotarou/additional_variables/def_const.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
def const; AdditionalVariables.const end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class MisMatchArgType < StandardError; end
|
2
|
+
module Arguments
|
3
|
+
class << self
|
4
|
+
@args = nil
|
5
|
+
attr_reader :args
|
6
|
+
|
7
|
+
def import hash_data
|
8
|
+
unless hash_data.kind_of?(Hash)
|
9
|
+
raise MisMatchArgType.new("Please use Hash for args")
|
10
|
+
end
|
11
|
+
@args = hash_data
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove
|
15
|
+
@args = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def filepath
|
19
|
+
"pokotarou/arguments/def_args.rb"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
def args; Arguments.args end
|
@@ -11,28 +11,19 @@ class DataRegister
|
|
11
11
|
ActiveRecord::Base.transaction do
|
12
12
|
begin
|
13
13
|
data.each do |sym_block, model_data|
|
14
|
+
next if is_dush?(sym_block.to_s)
|
14
15
|
regist_models(sym_block, model_data, maked, model_cache)
|
15
16
|
end
|
16
17
|
rescue => e
|
17
18
|
raise StandardError.new("#{e.message}")
|
18
19
|
end
|
19
20
|
end
|
21
|
+
|
22
|
+
ReturnExpressionParser.parse(data[:"return'"], maked)
|
20
23
|
end
|
21
24
|
|
22
25
|
private
|
23
26
|
|
24
|
-
def execute model, config_data, table_name, col_arr, seed_arr
|
25
|
-
# optimize is more faster than activerecord-import
|
26
|
-
# however, sql.conf setting is necessary to use
|
27
|
-
if config_data[:optimize]
|
28
|
-
# seed_arr.transpose: [[col1_element, col2_element], [col1_element, col2_element]...]
|
29
|
-
insert_query = QueryBuilder.insert(table_name, col_arr, seed_arr.transpose)
|
30
|
-
ActiveRecord::Base.connection.execute(insert_query)
|
31
|
-
else
|
32
|
-
model.import(col_arr, seed_arr.transpose, validate: config_data[:validate], timestamps: false)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
27
|
def regist_models sym_block, model_data, maked, model_cache
|
37
28
|
model_data.each do |e|
|
38
29
|
str_model = e.first.to_s
|
@@ -53,9 +44,7 @@ class DataRegister
|
|
53
44
|
|
54
45
|
output_log(config_data[:log])
|
55
46
|
begin
|
56
|
-
|
57
|
-
execute(model_cache[str_model][:model],
|
58
|
-
config_data, model_cache[str_model][:table_name], col_arr, seed_arr)
|
47
|
+
model_cache[str_model][:model].import(col_arr, seed_arr.transpose, validate: config_data[:validate], timestamps: false)
|
59
48
|
rescue => e
|
60
49
|
raise RegistError.new("
|
61
50
|
block: #{sym_block}
|
@@ -156,7 +145,7 @@ class DataRegister
|
|
156
145
|
def set_expand_expression config_data, key, val, maked
|
157
146
|
# if it exists type, there is no need for doing 'expand expression'
|
158
147
|
return if config_data[:type][key].present?
|
159
|
-
config_data[:col][key] =
|
148
|
+
config_data[:col][key] = SeedExpressionParser.parse(val, maked)
|
160
149
|
end
|
161
150
|
|
162
151
|
def set_loop_expand_expression config_data, maked
|
@@ -184,5 +173,10 @@ class DataRegister
|
|
184
173
|
puts log
|
185
174
|
end
|
186
175
|
|
176
|
+
DUSH_OPTION = /^.*\'$/
|
177
|
+
def is_dush? val
|
178
|
+
return false unless val.kind_of?(String)
|
179
|
+
DUSH_OPTION =~ val
|
180
|
+
end
|
187
181
|
end
|
188
182
|
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
class DataStructure
|
2
2
|
class << self
|
3
3
|
def gen data
|
4
|
+
execute_template_option_setting(data)
|
4
5
|
# return data structure bellow
|
5
6
|
# [{ block_name => { model_name => { column_configration }}}, ...]
|
6
7
|
data.reduce(Hash.new) do |acc, r|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
if is_dush?(r.first.to_s)
|
9
|
+
acc[r.first] = r.second
|
10
|
+
else
|
11
|
+
set_reshape_data_to_acc(acc, r)
|
12
|
+
end
|
10
13
|
|
11
14
|
acc
|
12
15
|
end
|
@@ -14,6 +17,75 @@ class DataStructure
|
|
14
17
|
|
15
18
|
private
|
16
19
|
|
20
|
+
def execute_template_option_setting data
|
21
|
+
return unless data.has_key?(:"template'")
|
22
|
+
templates = data[:"template'"]
|
23
|
+
data.delete(:"template'")
|
24
|
+
data.each do |_, val|
|
25
|
+
set_template_option(val, templates)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_template_option model_data, templates
|
30
|
+
model_data.each do |key, val|
|
31
|
+
next unless has_template?(val)
|
32
|
+
template_name = val[:template]
|
33
|
+
template = templates[template_name.to_sym]
|
34
|
+
copy_template = template.deep_dup
|
35
|
+
# when a new key is generated, it is added behind
|
36
|
+
# so, overwrite config_data to template first
|
37
|
+
|
38
|
+
# from val to copy_template
|
39
|
+
deep_overwrite(val, copy_template)
|
40
|
+
# update config data
|
41
|
+
model_data[key] = copy_template
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def deep_overwrite from_hash, to_hash
|
46
|
+
from_hash.each do |key, val|
|
47
|
+
if val.kind_of?(Hash)
|
48
|
+
to_hash[key] ||= Hash.new
|
49
|
+
deep_overwrite(val, to_hash[key])
|
50
|
+
else
|
51
|
+
to_hash[key] = val
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_reshape_data_to_acc acc, r
|
57
|
+
execute_grouping_option_setting(r.second)
|
58
|
+
# r.first is block_name
|
59
|
+
# r.second is model_data, like { Pref: {loop: 3}, Member: {loop: 3}... }
|
60
|
+
acc[r.first] = gen_structure(r.second)
|
61
|
+
end
|
62
|
+
|
63
|
+
def execute_grouping_option_setting model_data
|
64
|
+
model_data.each do |key, val|
|
65
|
+
set_grouping_option(val) if has_grouping?(val)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_grouping_option val
|
70
|
+
val[:grouping].each do |grouping_key, cols|
|
71
|
+
apply_grouping_col(:col, val, grouping_key, cols)
|
72
|
+
apply_grouping_col(:option, val, grouping_key, cols)
|
73
|
+
apply_grouping_col(:convert, val, grouping_key, cols)
|
74
|
+
end
|
75
|
+
|
76
|
+
val.delete(:grouping)
|
77
|
+
end
|
78
|
+
|
79
|
+
def apply_grouping_col config_name, val, grouping_key, cols
|
80
|
+
return if val[config_name].blank?
|
81
|
+
return unless val[config_name].has_key?(grouping_key)
|
82
|
+
cols.each do |e|
|
83
|
+
val[config_name][e.to_sym] = val[config_name][grouping_key]
|
84
|
+
end
|
85
|
+
|
86
|
+
val[config_name].delete(grouping_key)
|
87
|
+
end
|
88
|
+
|
17
89
|
def gen_structure model_data
|
18
90
|
model_data.reduce(Hash.new) do |acc, r|
|
19
91
|
# r.second is config_data, like {loop: 3, ...}
|
@@ -84,5 +156,20 @@ class DataStructure
|
|
84
156
|
return false unless val.kind_of?(String)
|
85
157
|
ENUM =~ val
|
86
158
|
end
|
159
|
+
|
160
|
+
DUSH_OPTION = /^.*\'$/
|
161
|
+
def is_dush? val
|
162
|
+
return false unless val.kind_of?(String)
|
163
|
+
DUSH_OPTION =~ val
|
164
|
+
end
|
165
|
+
|
166
|
+
def has_grouping? config_data
|
167
|
+
return false if config_data.blank?
|
168
|
+
config_data.has_key?(:grouping)
|
169
|
+
end
|
170
|
+
|
171
|
+
def has_template? config_data
|
172
|
+
config_data.has_key?(:template)
|
173
|
+
end
|
87
174
|
end
|
88
175
|
end
|
@@ -1,75 +1,162 @@
|
|
1
1
|
require "pokotarou/additional_methods.rb"
|
2
|
+
require "pokotarou/additional_variables/additional_variables.rb"
|
3
|
+
require "pokotarou/arguments/arguments.rb"
|
2
4
|
class ParseError < StandardError; end
|
5
|
+
FOREIGN_KEY_SYMBOL = "F|"
|
3
6
|
|
4
|
-
# for seed data
|
5
7
|
class ExpressionParser
|
6
8
|
class << self
|
7
|
-
|
8
|
-
def parse config_val, maked
|
9
|
+
def parse config_val, maked = nil
|
9
10
|
begin
|
10
|
-
require AdditionalMethods.filepath if AdditionalMethods.filepath.present?
|
11
11
|
case
|
12
|
-
|
13
|
-
|
12
|
+
# Array
|
13
|
+
when is_array?(config_val)
|
14
|
+
array_procees(config_val)
|
15
|
+
|
16
|
+
# ForeignKey
|
14
17
|
when is_foreign_key?(config_val)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
return model.pluck(:id)
|
18
|
+
foreign_key_process(config_val)
|
19
|
+
|
20
|
+
# Expression
|
19
21
|
when is_expression?(config_val)
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
expression_process(config_val, maked)
|
23
|
+
|
24
|
+
# Integer
|
25
|
+
when is_integer?(config_val)
|
26
|
+
integer_process(config_val)
|
27
|
+
|
28
|
+
# Nil
|
29
|
+
when is_nil?(config_val)
|
30
|
+
nil_process(config_val)
|
31
|
+
|
32
|
+
# Other
|
23
33
|
else
|
24
|
-
|
25
|
-
# escape \\
|
26
|
-
[config_val.tr("\\","")]
|
27
|
-
else
|
28
|
-
[config_val]
|
29
|
-
end
|
34
|
+
nothing_apply_process(config_val)
|
30
35
|
end
|
31
36
|
rescue => e
|
32
|
-
|
37
|
+
output_error(e)
|
33
38
|
end
|
34
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def array_procees val
|
43
|
+
return val
|
44
|
+
end
|
45
|
+
|
46
|
+
def foreign_key_process val
|
47
|
+
# remove 'F|'
|
48
|
+
str_model = val.sub(FOREIGN_KEY_SYMBOL, "")
|
49
|
+
model = eval(str_model)
|
50
|
+
return model.pluck(:id)
|
51
|
+
end
|
52
|
+
|
53
|
+
def expression_process val, maked
|
54
|
+
# remove '<>'
|
55
|
+
expression = val.strip[1..-2]
|
56
|
+
require AdditionalVariables.filepath if AdditionalVariables.const.present?
|
57
|
+
require AdditionalMethods.filepath if AdditionalMethods.filepath.present?
|
58
|
+
require Arguments.filepath if Arguments.filepath.present?
|
59
|
+
return self.parse(eval(expression), maked)
|
60
|
+
end
|
61
|
+
|
62
|
+
def integer_process val
|
63
|
+
nothing_apply_process(val)
|
64
|
+
end
|
65
|
+
|
66
|
+
def nil_process val
|
67
|
+
nothing_apply_process(val)
|
68
|
+
end
|
69
|
+
|
70
|
+
def nothing_apply_process val
|
71
|
+
# for escape \\
|
72
|
+
val.instance_of?(String) ? val.tr("\\","") : val
|
73
|
+
end
|
74
|
+
|
75
|
+
def output_error e
|
76
|
+
raise ParseError.new("Failed Expression parse:#{e.message}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# for seed data
|
82
|
+
class SeedExpressionParser < ExpressionParser
|
83
|
+
class << self
|
84
|
+
private
|
85
|
+
def nothing_apply_process val
|
86
|
+
# for escape \\
|
87
|
+
val.instance_of?(String) ? [val.tr("\\","")] : [val]
|
88
|
+
end
|
89
|
+
|
90
|
+
def output_error e
|
91
|
+
raise ParseError.new("Failed Seed Expression parse:#{e.message}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# for return variables
|
97
|
+
class ReturnExpressionParser < ExpressionParser
|
98
|
+
class << self
|
99
|
+
private
|
100
|
+
def output_error e
|
101
|
+
ParseError.new("Failed Const Expression parse:#{e.message}")
|
102
|
+
end
|
35
103
|
end
|
36
104
|
end
|
37
105
|
|
38
106
|
# for loop data
|
39
|
-
class LoopExpressionParser
|
107
|
+
class LoopExpressionParser < ExpressionParser
|
40
108
|
class << self
|
41
|
-
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
109
|
+
private
|
110
|
+
def array_procees val
|
111
|
+
val.size
|
112
|
+
end
|
113
|
+
|
114
|
+
def foreign_key_process val
|
115
|
+
# remove 'F|'
|
116
|
+
str_model = val.sub(FOREIGN_KEY_SYMBOL, "")
|
117
|
+
model = eval(str_model)
|
118
|
+
return model.pluck(:id).size
|
119
|
+
end
|
120
|
+
|
121
|
+
def integer_process val
|
122
|
+
val
|
123
|
+
end
|
124
|
+
|
125
|
+
def nil_process _
|
126
|
+
1
|
127
|
+
end
|
128
|
+
|
129
|
+
def output_error e
|
130
|
+
ParseError.new("Failed Loop Expression parse: #{e.message}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# for const variables
|
136
|
+
class ConstExpressionParser < ExpressionParser
|
137
|
+
class << self
|
138
|
+
private
|
139
|
+
def expression_process val, _
|
140
|
+
# remove '<>'
|
141
|
+
expression = val.strip[1..-2]
|
142
|
+
require AdditionalMethods.filepath if AdditionalMethods.filepath.present?
|
143
|
+
require Arguments.filepath if Arguments.filepath.present?
|
144
|
+
return self.parse(eval(expression))
|
145
|
+
end
|
146
|
+
|
147
|
+
def nothing_apply_process val
|
148
|
+
# for escape \\
|
149
|
+
val.instance_of?(String) ? val.tr("\\","") : val
|
150
|
+
end
|
151
|
+
|
152
|
+
def output_error
|
153
|
+
ParseError.new("Failed Const Expression parse: #{e.message}")
|
67
154
|
end
|
68
155
|
end
|
69
156
|
end
|
70
157
|
|
71
|
-
FOREIGN_KEY = /^F\|[A-Z][A-Za-z0-9]*$/
|
72
|
-
def is_foreign_key? val
|
158
|
+
FOREIGN_KEY = /^F\|[A-Z][:A-Za-z0-9]*$/
|
159
|
+
def is_foreign_key? val
|
73
160
|
return false unless val.kind_of?(String)
|
74
161
|
FOREIGN_KEY =~ val
|
75
162
|
end
|
@@ -78,4 +165,16 @@ EXPRESSION = /^\s*<.*>\s*$/
|
|
78
165
|
def is_expression? val
|
79
166
|
return false unless val.kind_of?(String)
|
80
167
|
EXPRESSION =~ val
|
168
|
+
end
|
169
|
+
|
170
|
+
def is_array? val
|
171
|
+
val.instance_of?(Array)
|
172
|
+
end
|
173
|
+
|
174
|
+
def is_integer? val
|
175
|
+
val.instance_of?(Integer)
|
176
|
+
end
|
177
|
+
|
178
|
+
def is_nil? val
|
179
|
+
val.nil?
|
81
180
|
end
|
File without changes
|
data/lib/pokotarou/seeder.rb
CHANGED
@@ -13,7 +13,7 @@ class Seeder
|
|
13
13
|
return make_array(n, ->(){ rand(0.0..1_000_000_000.0) }) if type == "decimal"
|
14
14
|
return make_array(n, ->(){ SecureRandom.hex(20) }) if type == "string"
|
15
15
|
return make_array(n, ->(){ SecureRandom.hex(300) }) if ["text", "binary"].include?(type)
|
16
|
-
return make_array(n, ->(){ [
|
16
|
+
return make_array(n, ->(){ [true, false].sample }) if type == "boolean"
|
17
17
|
return make_string_array(n, enum) if type == "string"
|
18
18
|
return make_datetime_array() if ["string", "datetime", "date", "time"].include?(type)
|
19
19
|
end
|
data/lib/pokotarou/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pokotarou
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kashiwara
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.00'
|
41
|
-
description:
|
41
|
+
description: Pokotarou is convenient seeder of 'Ruby on Rails'
|
42
42
|
email:
|
43
43
|
- tamatebako0205@gmail.com
|
44
44
|
executables: []
|
@@ -50,15 +50,18 @@ files:
|
|
50
50
|
- Rakefile
|
51
51
|
- lib/pokotarou.rb
|
52
52
|
- lib/pokotarou/additional_methods.rb
|
53
|
+
- lib/pokotarou/additional_variables/additional_variables.rb
|
54
|
+
- lib/pokotarou/additional_variables/def_const.rb
|
55
|
+
- lib/pokotarou/arguments/arguments.rb
|
56
|
+
- lib/pokotarou/arguments/def_args.rb
|
53
57
|
- lib/pokotarou/array_operation.rb
|
54
58
|
- lib/pokotarou/converter.rb
|
55
59
|
- lib/pokotarou/data_register.rb
|
56
60
|
- lib/pokotarou/data_structure.rb
|
57
61
|
- lib/pokotarou/expression_parser.rb
|
58
|
-
- lib/pokotarou/
|
62
|
+
- lib/pokotarou/file_loader.rb
|
59
63
|
- lib/pokotarou/option.rb
|
60
64
|
- lib/pokotarou/pokotarou_handler.rb
|
61
|
-
- lib/pokotarou/query_builder.rb
|
62
65
|
- lib/pokotarou/seeder.rb
|
63
66
|
- lib/pokotarou/version.rb
|
64
67
|
- lib/tasks/pokotarou_tasks.rake
|
@@ -1,43 +0,0 @@
|
|
1
|
-
class QueryBuilder
|
2
|
-
class << self
|
3
|
-
|
4
|
-
# build insert query
|
5
|
-
def insert table_name, col_arr, seed_arr
|
6
|
-
col_str = convert_col_to_sql_str(col_arr)
|
7
|
-
seed_str = convert_seed_to_sql_str(seed_arr)
|
8
|
-
|
9
|
-
"INSERT INTO #{table_name} #{col_str} VALUES#{seed_str}"
|
10
|
-
end
|
11
|
-
|
12
|
-
def convert_to_sql_str arr
|
13
|
-
arr_str =
|
14
|
-
arr.reduce("(") do |acc, r|
|
15
|
-
acc << add_double_quote(r.to_s) << ","
|
16
|
-
end
|
17
|
-
# remove ' , ' and add ' ) '
|
18
|
-
arr_str.chop << ")"
|
19
|
-
end
|
20
|
-
|
21
|
-
def convert_seed_to_sql_str seed_arr
|
22
|
-
seed_str =
|
23
|
-
seed_arr.reduce("") do |acc, r|
|
24
|
-
acc << convert_to_sql_str(r) << ","
|
25
|
-
end
|
26
|
-
# remove ' , '
|
27
|
-
seed_str.chop
|
28
|
-
end
|
29
|
-
|
30
|
-
def convert_col_to_sql_str col_arr
|
31
|
-
col_str =
|
32
|
-
col_arr.reduce("(") do |acc, r|
|
33
|
-
acc << r.to_s << ","
|
34
|
-
end
|
35
|
-
# remove ' , ' and add ' ) '
|
36
|
-
col_str.chop << ")"
|
37
|
-
end
|
38
|
-
|
39
|
-
def add_double_quote str
|
40
|
-
"\"" << str << "\""
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|