Skip to content

Commit 13b880f

Browse files
authored
Merge pull request #237 from metafacture/addOnceBind
Add `once()` Fix bind.
2 parents 04dd7c8 + d206e91 commit 13b880f

File tree

8 files changed

+233
-0
lines changed

8 files changed

+233
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,27 @@ do list(path: "<sourceField>", "var": "<variableName>")
583583
end
584584
```
585585

586+
#### `do once`
587+
588+
Executes the statements only once (when the bind is first encountered), not repeatedly for each record.
589+
590+
```perl
591+
do once()
592+
...
593+
end
594+
```
595+
596+
In order to execute multiple blocks only once, tag them with unique identifiers:
597+
598+
```perl
599+
do once("maps setup")
600+
...
601+
end
602+
do once("vars setup")
603+
...
604+
end
605+
```
606+
586607
### Conditionals
587608

588609
Conditionals start with `if` in case of affirming the condition or `unless` rejecting the condition.

metafix/src/main/java/org/metafacture/metafix/FixBind.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818

1919
import org.metafacture.metafix.api.FixContext;
2020

21+
import java.util.HashMap;
22+
import java.util.HashSet;
2123
import java.util.List;
2224
import java.util.Map;
25+
import java.util.Set;
2326

2427
public enum FixBind implements FixContext {
2528

@@ -55,6 +58,17 @@ public void execute(final Metafix metafix, final Record record, final List<Strin
5558
}
5659
});
5760
}
61+
},
62+
63+
once {
64+
private Map<Metafix, Set<String>> executed = new HashMap<>();
65+
66+
@Override
67+
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final RecordTransformer recordTransformer) {
68+
if (executed.computeIfAbsent(metafix, k -> new HashSet<>()).add(params.isEmpty() ? null : params.get(0))) {
69+
recordTransformer.transform(record);
70+
}
71+
}
5872
}
5973

6074
}

metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,143 @@ public void shouldPerformComplexOperationWithPathWildcard() {
744744
);
745745
}
746746

747+
@Test
748+
public void shouldExecuteOnlyOnce() {
749+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
750+
"do once()",
751+
" add_field(executed, 'true')",
752+
"end",
753+
"do once()",
754+
" add_field(never_executed, 'true')",
755+
"end"
756+
),
757+
i -> {
758+
i.startRecord("1");
759+
i.endRecord();
760+
i.startRecord("2");
761+
i.endRecord();
762+
i.startRecord("3");
763+
i.endRecord();
764+
},
765+
o -> {
766+
o.get().startRecord("1");
767+
o.get().literal("executed", "true");
768+
o.get().endRecord();
769+
o.get().startRecord("2");
770+
o.get().endRecord();
771+
o.get().startRecord("3");
772+
o.get().endRecord();
773+
}
774+
);
775+
}
776+
777+
@Test
778+
public void shouldExecuteOnlyOncePerFixInstance() {
779+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
780+
"do once()",
781+
" add_field(executed, 'true')",
782+
"end",
783+
"include('src/test/resources/org/metafacture/metafix/fixes/once.fix')"
784+
),
785+
i -> {
786+
i.startRecord("1");
787+
i.endRecord();
788+
i.startRecord("2");
789+
i.endRecord();
790+
i.startRecord("3");
791+
i.endRecord();
792+
},
793+
o -> {
794+
o.get().startRecord("1");
795+
o.get().literal("executed", "true");
796+
o.get().literal("included", "true");
797+
o.get().endRecord();
798+
o.get().startRecord("2");
799+
o.get().literal("included", "true");
800+
o.get().endRecord();
801+
o.get().startRecord("3");
802+
o.get().literal("included", "true");
803+
o.get().endRecord();
804+
}
805+
);
806+
}
807+
808+
@Test
809+
public void shouldExecuteOnlyOncePerIdentifier() {
810+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
811+
"do once()",
812+
" add_field(executed, 'true')",
813+
"end",
814+
"do once()",
815+
" add_field(never_executed, 'true')",
816+
"end",
817+
"do once('setup')",
818+
" add_field(setup, 'true')",
819+
"end",
820+
"do once('setup')",
821+
" add_field(already_setup, 'true')",
822+
"end"
823+
),
824+
i -> {
825+
i.startRecord("1");
826+
i.endRecord();
827+
i.startRecord("2");
828+
i.endRecord();
829+
i.startRecord("3");
830+
i.endRecord();
831+
},
832+
o -> {
833+
o.get().startRecord("1");
834+
o.get().literal("executed", "true");
835+
o.get().literal("setup", "true");
836+
o.get().endRecord();
837+
o.get().startRecord("2");
838+
o.get().endRecord();
839+
o.get().startRecord("3");
840+
o.get().endRecord();
841+
}
842+
);
843+
}
844+
845+
@Test
846+
public void shouldExecuteOnlyOnceConditionally() {
847+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
848+
"if exists(execute)",
849+
" do once()",
850+
" add_field(executed, 'false')",
851+
" end",
852+
" do once('setup')",
853+
" add_field(setup, 'true')",
854+
" end",
855+
"else",
856+
" do once()",
857+
" add_field(already_executed, 'true')",
858+
" end",
859+
"end"
860+
),
861+
i -> {
862+
i.startRecord("1");
863+
i.endRecord();
864+
i.startRecord("2");
865+
i.literal("execute", "too late");
866+
i.endRecord();
867+
i.startRecord("3");
868+
i.endRecord();
869+
},
870+
o -> {
871+
o.get().startRecord("1");
872+
o.get().literal("already_executed", "true");
873+
o.get().endRecord();
874+
o.get().startRecord("2");
875+
o.get().literal("execute", "too late");
876+
o.get().literal("setup", "true");
877+
o.get().endRecord();
878+
o.get().startRecord("3");
879+
o.get().endRecord();
880+
}
881+
);
882+
}
883+
747884
@Test
748885
public void shouldExecuteCustomJavaContext() {
749886
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
add_field(included, "true")
2+
3+
do once()
4+
add_field(also_executed, "false")
5+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"author" : [ {
3+
"name" : "RUVIVAL Team",
4+
"type" : "Person"
5+
}, {
6+
"name" : "Samuel Duval",
7+
"type" : "Person"
8+
} ],
9+
"@type" : "test"
10+
}
11+
{
12+
"author" : [ {
13+
"name" : "Jürgen Böhner",
14+
"type" : "Person"
15+
} ]
16+
}
17+
{
18+
"author" : [ {
19+
"name" : "Peter Müller",
20+
"type" : "Person"
21+
} ]
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"author" : [ {
3+
"name" : "RUVIVAL Team",
4+
"type" : "Person"
5+
}, {
6+
"name" : "Samuel Duval",
7+
"type" : "Person"
8+
} ]
9+
}
10+
{
11+
"author" : [ {
12+
"name" : "Jürgen Böhner",
13+
"type" : "Person"
14+
} ]
15+
}
16+
{
17+
"author" : [ {
18+
"name" : "Peter Müller",
19+
"type" : "Person"
20+
} ]
21+
}
22+
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
do once()
2+
add_field("@type","test")
3+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FLUX_DIR + "input.json"
2+
|open-file
3+
|as-records
4+
|decode-json
5+
|fix(FLUX_DIR + "test.fix")
6+
|encode-json(prettyPrinting="true")
7+
|write(FLUX_DIR + "output-metafix.json")
8+
;

0 commit comments

Comments
 (0)