csv_decision 0.3.1 → 0.3.2
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/CHANGELOG.md +5 -1
- data/csv_decision.gemspec +1 -1
- data/doc/CSVDecision/CellValidationError.html +1 -1
- data/doc/CSVDecision/Columns/Dictionary.html +1 -1
- data/doc/CSVDecision/Columns.html +1 -1
- data/doc/CSVDecision/Data.html +1 -1
- data/doc/CSVDecision/Decision.html +51 -147
- data/doc/CSVDecision/Defaults.html +1 -1
- data/doc/CSVDecision/Dictionary/Entry.html +1 -1
- data/doc/CSVDecision/Dictionary.html +1 -1
- data/doc/CSVDecision/Error.html +1 -1
- data/doc/CSVDecision/FileError.html +1 -1
- data/doc/CSVDecision/Header.html +1 -1
- data/doc/CSVDecision/Index.html +1 -1
- data/doc/CSVDecision/Input.html +2 -2
- data/doc/CSVDecision/Load.html +16 -11
- data/doc/CSVDecision/Matchers/Constant.html +1 -1
- data/doc/CSVDecision/Matchers/Function.html +3 -3
- data/doc/CSVDecision/Matchers/Guard.html +1 -1
- data/doc/CSVDecision/Matchers/Matcher.html +1 -1
- data/doc/CSVDecision/Matchers/Numeric.html +1 -1
- data/doc/CSVDecision/Matchers/Pattern.html +1 -1
- data/doc/CSVDecision/Matchers/Proc.html +1 -1
- data/doc/CSVDecision/Matchers/Range.html +1 -1
- data/doc/CSVDecision/Matchers/Symbol.html +1 -1
- data/doc/CSVDecision/Matchers.html +3 -3
- data/doc/CSVDecision/Options.html +1 -1
- data/doc/CSVDecision/Parse.html +3 -3
- data/doc/CSVDecision/Result.html +9 -22
- data/doc/CSVDecision/ScanRow.html +4 -6
- data/doc/CSVDecision/Table.html +10 -2
- data/doc/CSVDecision/TableValidationError.html +1 -1
- data/doc/CSVDecision/Validate.html +1 -1
- data/doc/CSVDecision.html +18 -13
- data/doc/_index.html +1 -1
- data/doc/file.README.html +1 -1
- data/doc/index.html +1 -1
- data/doc/method_list.html +63 -63
- data/doc/top-level-namespace.html +1 -1
- data/lib/csv_decision/decision.rb +47 -45
- data/lib/csv_decision/load.rb +5 -4
- data/lib/csv_decision/parse.rb +1 -1
- data/lib/csv_decision/result.rb +3 -3
- data/lib/csv_decision/scan_row.rb +4 -5
- data/lib/csv_decision/table.rb +4 -0
- data/spec/csv_decision/table_spec.rb +1 -0
- data/spec/data/valid/index_example.csv +1 -0
- metadata +2 -2
data/doc/method_list.html
CHANGED
@@ -246,7 +246,7 @@
|
|
246
246
|
|
247
247
|
<li class="even ">
|
248
248
|
<div class="item">
|
249
|
-
<span class='object_link'><a href="CSVDecision/Result.html#
|
249
|
+
<span class='object_link'><a href="CSVDecision/Result.html#final_result-instance_method" title="CSVDecision::Result#final_result (method)">#final_result</a></span>
|
250
250
|
<small>CSVDecision::Result</small>
|
251
251
|
</div>
|
252
252
|
</li>
|
@@ -318,7 +318,7 @@
|
|
318
318
|
|
319
319
|
<li class="odd ">
|
320
320
|
<div class="item">
|
321
|
-
<span class='object_link'><a href="CSVDecision/Decision.html#
|
321
|
+
<span class='object_link'><a href="CSVDecision/Decision.html#index_scan-instance_method" title="CSVDecision::Decision#index_scan (method)">#index_scan</a></span>
|
322
322
|
<small>CSVDecision::Decision</small>
|
323
323
|
</div>
|
324
324
|
</li>
|
@@ -334,16 +334,16 @@
|
|
334
334
|
|
335
335
|
<li class="odd ">
|
336
336
|
<div class="item">
|
337
|
-
<span class='object_link'><a href="CSVDecision/
|
338
|
-
<small>CSVDecision::
|
337
|
+
<span class='object_link'><a href="CSVDecision/Columns.html#initialize-instance_method" title="CSVDecision::Columns#initialize (method)">#initialize</a></span>
|
338
|
+
<small>CSVDecision::Columns</small>
|
339
339
|
</div>
|
340
340
|
</li>
|
341
341
|
|
342
342
|
|
343
343
|
<li class="even ">
|
344
344
|
<div class="item">
|
345
|
-
<span class='object_link'><a href="CSVDecision/
|
346
|
-
<small>CSVDecision::
|
345
|
+
<span class='object_link'><a href="CSVDecision/ScanRow.html#initialize-instance_method" title="CSVDecision::ScanRow#initialize (method)">#initialize</a></span>
|
346
|
+
<small>CSVDecision::ScanRow</small>
|
347
347
|
</div>
|
348
348
|
</li>
|
349
349
|
|
@@ -358,80 +358,80 @@
|
|
358
358
|
|
359
359
|
<li class="even ">
|
360
360
|
<div class="item">
|
361
|
-
<span class='object_link'><a href="CSVDecision/
|
362
|
-
<small>CSVDecision::
|
361
|
+
<span class='object_link'><a href="CSVDecision/Decision.html#initialize-instance_method" title="CSVDecision::Decision#initialize (method)">#initialize</a></span>
|
362
|
+
<small>CSVDecision::Decision</small>
|
363
363
|
</div>
|
364
364
|
</li>
|
365
365
|
|
366
366
|
|
367
367
|
<li class="odd ">
|
368
368
|
<div class="item">
|
369
|
-
<span class='object_link'><a href="CSVDecision/
|
370
|
-
<small>CSVDecision::
|
369
|
+
<span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#initialize-instance_method" title="CSVDecision::Columns::Dictionary#initialize (method)">#initialize</a></span>
|
370
|
+
<small>CSVDecision::Columns::Dictionary</small>
|
371
371
|
</div>
|
372
372
|
</li>
|
373
373
|
|
374
374
|
|
375
375
|
<li class="even ">
|
376
376
|
<div class="item">
|
377
|
-
<span class='object_link'><a href="CSVDecision/Matchers
|
378
|
-
<small>CSVDecision::Matchers
|
377
|
+
<span class='object_link'><a href="CSVDecision/Matchers.html#initialize-instance_method" title="CSVDecision::Matchers#initialize (method)">#initialize</a></span>
|
378
|
+
<small>CSVDecision::Matchers</small>
|
379
379
|
</div>
|
380
380
|
</li>
|
381
381
|
|
382
382
|
|
383
383
|
<li class="odd ">
|
384
384
|
<div class="item">
|
385
|
-
<span class='object_link'><a href="CSVDecision/
|
386
|
-
<small>CSVDecision::
|
385
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Pattern.html#initialize-instance_method" title="CSVDecision::Matchers::Pattern#initialize (method)">#initialize</a></span>
|
386
|
+
<small>CSVDecision::Matchers::Pattern</small>
|
387
387
|
</div>
|
388
388
|
</li>
|
389
389
|
|
390
390
|
|
391
391
|
<li class="even ">
|
392
392
|
<div class="item">
|
393
|
-
<span class='object_link'><a href="CSVDecision/
|
394
|
-
<small>CSVDecision::
|
393
|
+
<span class='object_link'><a href="CSVDecision/Result.html#initialize-instance_method" title="CSVDecision::Result#initialize (method)">#initialize</a></span>
|
394
|
+
<small>CSVDecision::Result</small>
|
395
395
|
</div>
|
396
396
|
</li>
|
397
397
|
|
398
398
|
|
399
399
|
<li class="odd ">
|
400
400
|
<div class="item">
|
401
|
-
<span class='object_link'><a href="CSVDecision/
|
402
|
-
<small>CSVDecision::
|
401
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#initialize-instance_method" title="CSVDecision::Matchers::Matcher#initialize (method)">#initialize</a></span>
|
402
|
+
<small>CSVDecision::Matchers::Matcher</small>
|
403
403
|
</div>
|
404
404
|
</li>
|
405
405
|
|
406
406
|
|
407
407
|
<li class="even ">
|
408
408
|
<div class="item">
|
409
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
410
|
-
<small>CSVDecision::Matchers::
|
409
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Proc.html#initialize-instance_method" title="CSVDecision::Matchers::Proc#initialize (method)">#initialize</a></span>
|
410
|
+
<small>CSVDecision::Matchers::Proc</small>
|
411
411
|
</div>
|
412
412
|
</li>
|
413
413
|
|
414
414
|
|
415
415
|
<li class="odd ">
|
416
416
|
<div class="item">
|
417
|
-
<span class='object_link'><a href="CSVDecision/
|
418
|
-
<small>CSVDecision::
|
417
|
+
<span class='object_link'><a href="CSVDecision/Table.html#initialize-instance_method" title="CSVDecision::Table#initialize (method)">#initialize</a></span>
|
418
|
+
<small>CSVDecision::Table</small>
|
419
419
|
</div>
|
420
420
|
</li>
|
421
421
|
|
422
422
|
|
423
423
|
<li class="even ">
|
424
424
|
<div class="item">
|
425
|
-
<span class='object_link'><a href="CSVDecision/
|
426
|
-
<small>CSVDecision::
|
425
|
+
<span class='object_link'><a href="CSVDecision/Index.html#initialize-instance_method" title="CSVDecision::Index#initialize (method)">#initialize</a></span>
|
426
|
+
<small>CSVDecision::Index</small>
|
427
427
|
</div>
|
428
428
|
</li>
|
429
429
|
|
430
430
|
|
431
431
|
<li class="odd ">
|
432
432
|
<div class="item">
|
433
|
-
<span class='object_link'><a href="CSVDecision/
|
434
|
-
<small>CSVDecision::
|
433
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Function.html#initialize-instance_method" title="CSVDecision::Matchers::Function#initialize (method)">#initialize</a></span>
|
434
|
+
<small>CSVDecision::Matchers::Function</small>
|
435
435
|
</div>
|
436
436
|
</li>
|
437
437
|
|
@@ -534,16 +534,16 @@
|
|
534
534
|
|
535
535
|
<li class="even ">
|
536
536
|
<div class="item">
|
537
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
538
|
-
<small>CSVDecision::Matchers::
|
537
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Constant.html#matches%3F-class_method" title="CSVDecision::Matchers::Constant.matches? (method)">matches?</a></span>
|
538
|
+
<small>CSVDecision::Matchers::Constant</small>
|
539
539
|
</div>
|
540
540
|
</li>
|
541
541
|
|
542
542
|
|
543
543
|
<li class="odd ">
|
544
544
|
<div class="item">
|
545
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
546
|
-
<small>CSVDecision::Matchers::
|
545
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Guard.html#matches%3F-class_method" title="CSVDecision::Matchers::Guard.matches? (method)">matches?</a></span>
|
546
|
+
<small>CSVDecision::Matchers::Guard</small>
|
547
547
|
</div>
|
548
548
|
</li>
|
549
549
|
|
@@ -574,47 +574,47 @@
|
|
574
574
|
|
575
575
|
<li class="odd ">
|
576
576
|
<div class="item">
|
577
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
578
|
-
<small>CSVDecision::Matchers::
|
577
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Symbol.html#matches%3F-class_method" title="CSVDecision::Matchers::Symbol.matches? (method)">matches?</a></span>
|
578
|
+
<small>CSVDecision::Matchers::Symbol</small>
|
579
579
|
</div>
|
580
580
|
</li>
|
581
581
|
|
582
582
|
|
583
583
|
<li class="even ">
|
584
584
|
<div class="item">
|
585
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
586
|
-
<small>CSVDecision::Matchers::
|
585
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Symbol.html#matches%3F-instance_method" title="CSVDecision::Matchers::Symbol#matches? (method)">#matches?</a></span>
|
586
|
+
<small>CSVDecision::Matchers::Symbol</small>
|
587
587
|
</div>
|
588
588
|
</li>
|
589
589
|
|
590
590
|
|
591
591
|
<li class="odd ">
|
592
592
|
<div class="item">
|
593
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
594
|
-
<small>CSVDecision::Matchers::
|
593
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Numeric.html#matches%3F-class_method" title="CSVDecision::Matchers::Numeric.matches? (method)">matches?</a></span>
|
594
|
+
<small>CSVDecision::Matchers::Numeric</small>
|
595
595
|
</div>
|
596
596
|
</li>
|
597
597
|
|
598
598
|
|
599
599
|
<li class="even ">
|
600
600
|
<div class="item">
|
601
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
602
|
-
<small>CSVDecision::Matchers::
|
601
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Numeric.html#matches%3F-instance_method" title="CSVDecision::Matchers::Numeric#matches? (method)">#matches?</a></span>
|
602
|
+
<small>CSVDecision::Matchers::Numeric</small>
|
603
603
|
</div>
|
604
604
|
</li>
|
605
605
|
|
606
606
|
|
607
607
|
<li class="odd ">
|
608
608
|
<div class="item">
|
609
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
610
|
-
<small>CSVDecision::Matchers::
|
609
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Pattern.html#matches%3F-class_method" title="CSVDecision::Matchers::Pattern.matches? (method)">matches?</a></span>
|
610
|
+
<small>CSVDecision::Matchers::Pattern</small>
|
611
611
|
</div>
|
612
612
|
</li>
|
613
613
|
|
614
614
|
|
615
615
|
<li class="even ">
|
616
616
|
<div class="item">
|
617
|
-
<span class='object_link'><a href="CSVDecision/Matchers/Pattern.html#matches%3F-
|
617
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Pattern.html#matches%3F-instance_method" title="CSVDecision::Matchers::Pattern#matches? (method)">#matches?</a></span>
|
618
618
|
<small>CSVDecision::Matchers::Pattern</small>
|
619
619
|
</div>
|
620
620
|
</li>
|
@@ -622,32 +622,32 @@
|
|
622
622
|
|
623
623
|
<li class="odd ">
|
624
624
|
<div class="item">
|
625
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
626
|
-
<small>CSVDecision::Matchers::
|
625
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Constant.html#matches%3F-instance_method" title="CSVDecision::Matchers::Constant#matches? (method)">#matches?</a></span>
|
626
|
+
<small>CSVDecision::Matchers::Constant</small>
|
627
627
|
</div>
|
628
628
|
</li>
|
629
629
|
|
630
630
|
|
631
631
|
<li class="even ">
|
632
632
|
<div class="item">
|
633
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
634
|
-
<small>CSVDecision::Matchers::
|
633
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Function.html#matches%3F-class_method" title="CSVDecision::Matchers::Function.matches? (method)">matches?</a></span>
|
634
|
+
<small>CSVDecision::Matchers::Function</small>
|
635
635
|
</div>
|
636
636
|
</li>
|
637
637
|
|
638
638
|
|
639
639
|
<li class="odd ">
|
640
640
|
<div class="item">
|
641
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
642
|
-
<small>CSVDecision::Matchers::
|
641
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Function.html#matches%3F-instance_method" title="CSVDecision::Matchers::Function#matches? (method)">#matches?</a></span>
|
642
|
+
<small>CSVDecision::Matchers::Function</small>
|
643
643
|
</div>
|
644
644
|
</li>
|
645
645
|
|
646
646
|
|
647
647
|
<li class="even ">
|
648
648
|
<div class="item">
|
649
|
-
<span class='object_link'><a href="CSVDecision/Matchers/
|
650
|
-
<small>CSVDecision::Matchers::
|
649
|
+
<span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#matches%3F-instance_method" title="CSVDecision::Matchers::Matcher#matches? (method)">#matches?</a></span>
|
650
|
+
<small>CSVDecision::Matchers::Matcher</small>
|
651
651
|
</div>
|
652
652
|
</li>
|
653
653
|
|
@@ -909,14 +909,6 @@
|
|
909
909
|
|
910
910
|
|
911
911
|
<li class="odd ">
|
912
|
-
<div class="item">
|
913
|
-
<span class='object_link'><a href="CSVDecision/Decision.html#scan-instance_method" title="CSVDecision::Decision#scan (method)">#scan</a></span>
|
914
|
-
<small>CSVDecision::Decision</small>
|
915
|
-
</div>
|
916
|
-
</li>
|
917
|
-
|
918
|
-
|
919
|
-
<li class="even ">
|
920
912
|
<div class="item">
|
921
913
|
<span class='object_link'><a href="CSVDecision/ScanRow.html#scan_columns-instance_method" title="CSVDecision::ScanRow#scan_columns (method)">#scan_columns</a></span>
|
922
914
|
<small>CSVDecision::ScanRow</small>
|
@@ -924,7 +916,7 @@
|
|
924
916
|
</li>
|
925
917
|
|
926
918
|
|
927
|
-
<li class="
|
919
|
+
<li class="even ">
|
928
920
|
<div class="item">
|
929
921
|
<span class='object_link'><a href="CSVDecision/Table.html#scan_rows-instance_method" title="CSVDecision::Table#scan_rows (method)">#scan_rows</a></span>
|
930
922
|
<small>CSVDecision::Table</small>
|
@@ -932,7 +924,7 @@
|
|
932
924
|
</li>
|
933
925
|
|
934
926
|
|
935
|
-
<li class="
|
927
|
+
<li class="odd ">
|
936
928
|
<div class="item">
|
937
929
|
<span class='object_link'><a href="CSVDecision/Dictionary/Entry.html#set_if-instance_method" title="CSVDecision::Dictionary::Entry#set_if (method)">#set_if</a></span>
|
938
930
|
<small>CSVDecision::Dictionary::Entry</small>
|
@@ -940,7 +932,7 @@
|
|
940
932
|
</li>
|
941
933
|
|
942
934
|
|
943
|
-
<li class="
|
935
|
+
<li class="even ">
|
944
936
|
<div class="item">
|
945
937
|
<span class='object_link'><a href="CSVDecision/Data.html#strip_columns-class_method" title="CSVDecision::Data.strip_columns (method)">strip_columns</a></span>
|
946
938
|
<small>CSVDecision::Data</small>
|
@@ -948,7 +940,7 @@
|
|
948
940
|
</li>
|
949
941
|
|
950
942
|
|
951
|
-
<li class="
|
943
|
+
<li class="odd ">
|
952
944
|
<div class="item">
|
953
945
|
<span class='object_link'><a href="CSVDecision/Header.html#strip_empty_columns-class_method" title="CSVDecision::Header.strip_empty_columns (method)">strip_empty_columns</a></span>
|
954
946
|
<small>CSVDecision::Header</small>
|
@@ -956,7 +948,7 @@
|
|
956
948
|
</li>
|
957
949
|
|
958
950
|
|
959
|
-
<li class="
|
951
|
+
<li class="even ">
|
960
952
|
<div class="item">
|
961
953
|
<span class='object_link'><a href="CSVDecision/Matchers/Proc.html#symbols-instance_method" title="CSVDecision::Matchers::Proc#symbols (method)">#symbols</a></span>
|
962
954
|
<small>CSVDecision::Matchers::Proc</small>
|
@@ -964,7 +956,7 @@
|
|
964
956
|
</li>
|
965
957
|
|
966
958
|
|
967
|
-
<li class="
|
959
|
+
<li class="odd ">
|
968
960
|
<div class="item">
|
969
961
|
<span class='object_link'><a href="CSVDecision/Parse.html#table-class_method" title="CSVDecision::Parse.table (method)">table</a></span>
|
970
962
|
<small>CSVDecision::Parse</small>
|
@@ -972,6 +964,14 @@
|
|
972
964
|
</li>
|
973
965
|
|
974
966
|
|
967
|
+
<li class="even ">
|
968
|
+
<div class="item">
|
969
|
+
<span class='object_link'><a href="CSVDecision/Decision.html#table_scan-instance_method" title="CSVDecision::Decision#table_scan (method)">#table_scan</a></span>
|
970
|
+
<small>CSVDecision::Decision</small>
|
971
|
+
</div>
|
972
|
+
</li>
|
973
|
+
|
974
|
+
|
975
975
|
<li class="odd ">
|
976
976
|
<div class="item">
|
977
977
|
<span class='object_link'><a href="CSVDecision/Data.html#to_array-class_method" title="CSVDecision::Data.to_array (method)">to_array</a></span>
|
@@ -100,7 +100,7 @@
|
|
100
100
|
</div>
|
101
101
|
|
102
102
|
<div id="footer">
|
103
|
-
Generated on Sun Jan
|
103
|
+
Generated on Sun Jan 28 11:58:37 2018 by
|
104
104
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
105
|
0.9.12 (ruby-2.4.0).
|
106
106
|
</div>
|
@@ -12,21 +12,19 @@ module CSVDecision
|
|
12
12
|
#
|
13
13
|
# @param table [CSVDecision::Table] Decision table.
|
14
14
|
# @param input [Hash] Input hash (keys may or may not be symbolized)
|
15
|
-
# @param symbolize_keys [
|
15
|
+
# @param symbolize_keys [Boolean] Set to false if keys are symbolized and it's
|
16
16
|
# OK to mutate the input hash. Otherwise a copy of the input hash is symbolized.
|
17
|
-
# @return [Hash] Decision result.
|
17
|
+
# @return [Hash{Symbol=>Object}] Decision result.
|
18
18
|
def self.make(table:, input:, symbolize_keys:)
|
19
19
|
# Parse and transform the hash supplied as input
|
20
20
|
input = Input.parse(table: table, input: input, symbolize_keys: symbolize_keys)
|
21
21
|
|
22
22
|
# The decision object collects the results of the search and
|
23
23
|
# calculates the final result
|
24
|
-
decision = Decision.new(table: table, input: input
|
24
|
+
decision = Decision.new(table: table, input: input)
|
25
25
|
|
26
26
|
# Use the table's index if present
|
27
|
-
|
28
|
-
|
29
|
-
decision.scan(table: table, hash: input[:hash], scan_cols: input[:scan_cols])
|
27
|
+
table.index ? decision.index_scan : decision.table_scan
|
30
28
|
end
|
31
29
|
|
32
30
|
# @param table [CSVDecision::Table] Decision table being processed.
|
@@ -34,63 +32,65 @@ module CSVDecision
|
|
34
32
|
def initialize(table:, input:)
|
35
33
|
# The result object is a hash of values, and each value will be an array if this is
|
36
34
|
# a multi-row result for the +first_match: false+ option.
|
37
|
-
@result = Result.new(table: table, input: input)
|
35
|
+
@result = Result.new(table: table, input: input[:hash])
|
38
36
|
|
39
37
|
# All rows picked by the matching process. An array if +first_match: false+,
|
40
38
|
# otherwise a single row.
|
41
39
|
@rows_picked = []
|
42
40
|
|
43
41
|
@first_match = table.options[:first_match]
|
42
|
+
|
43
|
+
@table = table
|
44
|
+
@input = input
|
44
45
|
end
|
45
46
|
|
46
47
|
# Scan the decision table up against the input hash.
|
47
48
|
#
|
48
|
-
# @param table (see #initialize)
|
49
|
-
# @param hash [Hash] Input hash.
|
50
|
-
# @param scan_cols [Hash{Index=>Object}] Input column values to scan.
|
51
49
|
# @return [Hash{Symbol=>Object}] Decision result.
|
52
|
-
def
|
53
|
-
|
54
|
-
|
50
|
+
def table_scan
|
51
|
+
hash = @input[:hash]
|
52
|
+
scan_cols = @input[:scan_cols]
|
53
|
+
|
54
|
+
if @first_match
|
55
|
+
scan_first_match(hash: hash, scan_cols: scan_cols)
|
56
|
+
else
|
57
|
+
scan_accumulate(hash: hash, scan_cols: scan_cols)
|
58
|
+
end
|
55
59
|
end
|
56
60
|
|
57
61
|
# Use an index to scan the decision table up against the input hash.
|
58
62
|
#
|
59
|
-
# @
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
# @return [Hash{Symbol=>Object}] Decision result.
|
64
|
+
def index_scan
|
65
|
+
# If the index lookup fails, there's no match.
|
66
|
+
return {} unless (index_rows = Array(@table.index.hash[@input[:key]]))
|
67
|
+
|
68
|
+
hash = @input[:hash]
|
69
|
+
scan_cols = @input[:scan_cols]
|
65
70
|
|
66
71
|
if @first_match
|
67
|
-
index_scan_first_match(
|
68
|
-
scan_cols: input[:scan_cols],
|
69
|
-
hash: input[:hash],
|
70
|
-
index_rows: Array(index_rows))
|
72
|
+
index_scan_first_match(scan_cols: scan_cols, hash: hash, index_rows: index_rows)
|
71
73
|
else
|
72
|
-
index_scan_accumulate(
|
73
|
-
scan_cols: input[:scan_cols],
|
74
|
-
hash: input[:hash],
|
75
|
-
index_rows: Array(index_rows))
|
74
|
+
index_scan_accumulate(scan_cols: scan_cols, hash: hash, index_rows: index_rows)
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
78
|
private
|
80
79
|
|
81
|
-
def scan_first_match(
|
82
|
-
table.each do |row, index|
|
83
|
-
next unless table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
80
|
+
def scan_first_match(hash:, scan_cols:)
|
81
|
+
@table.each do |row, index|
|
82
|
+
next unless @table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
84
83
|
|
85
|
-
return @result.attributes if
|
84
|
+
return @result.attributes if first_match_found(row)
|
86
85
|
end
|
87
86
|
|
88
87
|
{}
|
89
88
|
end
|
90
89
|
|
91
|
-
def scan_accumulate(
|
92
|
-
table.each do |row, index|
|
93
|
-
next unless table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
90
|
+
def scan_accumulate(hash:, scan_cols:)
|
91
|
+
@table.each do |row, index|
|
92
|
+
next unless @table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
93
|
+
|
94
94
|
# Accumulate output rows
|
95
95
|
@rows_picked << row
|
96
96
|
@result.accumulate_outs(row)
|
@@ -99,22 +99,24 @@ module CSVDecision
|
|
99
99
|
@rows_picked.empty? ? {} : accumulated_result
|
100
100
|
end
|
101
101
|
|
102
|
-
def index_scan_first_match(
|
102
|
+
def index_scan_first_match(scan_cols:, hash:, index_rows:)
|
103
103
|
index_rows.each do |start_row, end_row|
|
104
|
-
table.each(start_row, end_row || start_row) do |row, index|
|
105
|
-
next unless table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
106
|
-
|
104
|
+
@table.each(start_row, end_row || start_row) do |row, index|
|
105
|
+
next unless @table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
106
|
+
|
107
|
+
return @result.attributes if first_match_found(row)
|
107
108
|
end
|
108
109
|
end
|
109
110
|
|
110
111
|
{}
|
111
112
|
end
|
112
113
|
|
113
|
-
def index_scan_accumulate(
|
114
|
+
def index_scan_accumulate(scan_cols:, hash:, index_rows:)
|
114
115
|
index_rows.each do |start_row, end_row|
|
115
|
-
table.each(start_row, end_row || start_row) do |row, index|
|
116
|
-
next unless table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
117
|
-
|
116
|
+
@table.each(start_row, end_row || start_row) do |row, index|
|
117
|
+
next unless @table.scan_rows[index].match?(row: row, hash: hash, scan_cols: scan_cols)
|
118
|
+
|
119
|
+
# Accumulate output rows.
|
118
120
|
@rows_picked << row
|
119
121
|
@result.accumulate_outs(row)
|
120
122
|
end
|
@@ -124,7 +126,7 @@ module CSVDecision
|
|
124
126
|
end
|
125
127
|
|
126
128
|
def accumulated_result
|
127
|
-
return @result.
|
129
|
+
return @result.final_result unless @result.outs_functions
|
128
130
|
return @result.eval_outs(@rows_picked.first) unless @result.multi_result
|
129
131
|
|
130
132
|
multi_row_result
|
@@ -134,7 +136,7 @@ module CSVDecision
|
|
134
136
|
# Scan each output column that contains functions
|
135
137
|
@result.outs.each_pair { |col, column| eval_procs(col: col, column: column) if column.eval }
|
136
138
|
|
137
|
-
@result.
|
139
|
+
@result.final_result
|
138
140
|
end
|
139
141
|
|
140
142
|
def eval_procs(col:, column:)
|
@@ -147,7 +149,7 @@ module CSVDecision
|
|
147
149
|
end
|
148
150
|
end
|
149
151
|
|
150
|
-
def
|
152
|
+
def first_match_found(row)
|
151
153
|
# This decision row may contain procs, which if present will need to be evaluated.
|
152
154
|
# If this row contains if: columns then this row may be filtered out, in which case
|
153
155
|
# this method call will return false.
|
data/lib/csv_decision/load.rb
CHANGED
@@ -7,10 +7,11 @@
|
|
7
7
|
module CSVDecision
|
8
8
|
# Load all the CSV files located in the designated folder path.
|
9
9
|
#
|
10
|
-
# @param path [Pathname] Directory containing CSV files.
|
11
|
-
# @param options
|
12
|
-
# @return [Hash
|
13
|
-
#
|
10
|
+
# @param path [Pathname] Directory containing CSV decision table files.
|
11
|
+
# @param options (see CSVDecision.parse)
|
12
|
+
# @return [Hash{Symbol=><CSVDecision::Table>}] Hash of decision tables keyed by the CSV
|
13
|
+
# file's symbolized base name.
|
14
|
+
# @raise [ArgumentError] Invalid path name or folder.
|
14
15
|
def self.load(path, options = {})
|
15
16
|
Load.path(path: path, options: options)
|
16
17
|
end
|
data/lib/csv_decision/parse.rb
CHANGED
@@ -28,7 +28,7 @@ module CSVDecision
|
|
28
28
|
#
|
29
29
|
# @param data [Pathname, File, Array<Array<String>>, String] input data given as
|
30
30
|
# a CSV file, array of arrays or CSV string.
|
31
|
-
# @param options [Hash] Options hash
|
31
|
+
# @param options [Hash{Symbol=>Object}] Options hash controlling how the table is parsed and interpreted.
|
32
32
|
#
|
33
33
|
# @option options [Boolean] :first_match Stop scanning after finding the first row match.
|
34
34
|
# @option options [Boolean] :regexp_implicit Make regular expressions implicit rather than
|
data/lib/csv_decision/result.rb
CHANGED
@@ -54,8 +54,8 @@ module CSVDecision
|
|
54
54
|
end
|
55
55
|
|
56
56
|
# Derive the final result.
|
57
|
-
# @return [{Symbol=>Object}]
|
58
|
-
def
|
57
|
+
# @return [Hash{Symbol=>Object}]
|
58
|
+
def final_result
|
59
59
|
# If there are no if: columns, then nothing needs to be filtered out of this result hash.
|
60
60
|
return @attributes if @if_columns.empty?
|
61
61
|
|
@@ -74,7 +74,7 @@ module CSVDecision
|
|
74
74
|
# Then evaluate the procs, left to right
|
75
75
|
eval_outs_procs(row: row)
|
76
76
|
|
77
|
-
|
77
|
+
final_result
|
78
78
|
end
|
79
79
|
|
80
80
|
# Evaluate the cell proc using the partial result calculated so far.
|
@@ -109,9 +109,8 @@ module CSVDecision
|
|
109
109
|
# Check any table row cell constants first, and maybe fail fast...
|
110
110
|
return false if @constants.any? { |col| row[col] != scan_cols[col] }
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
# These table row cells are Proc objects which need evaluating
|
112
|
+
# These table row cells are Proc objects which need evaluating and
|
113
|
+
# must all return a truthy value.
|
115
114
|
@procs.all? { |col| row[col].call(value: scan_cols[col], hash: hash) }
|
116
115
|
end
|
117
116
|
|
@@ -121,14 +120,14 @@ module CSVDecision
|
|
121
120
|
# Scan the cell against all the matchers
|
122
121
|
proc = ScanRow.scan(column: column, matchers: matchers, cell: cell)
|
123
122
|
|
124
|
-
return set(proc, col, column) if proc
|
123
|
+
return set(proc: proc, col: col, column: column) if proc
|
125
124
|
|
126
125
|
# Just a plain constant
|
127
126
|
@constants << col
|
128
127
|
cell
|
129
128
|
end
|
130
129
|
|
131
|
-
def set(proc
|
130
|
+
def set(proc:, col:, column:)
|
132
131
|
# Unbox a constant
|
133
132
|
if proc.type == :constant
|
134
133
|
@constants << col
|
data/lib/csv_decision/table.rb
CHANGED