embulk-filter-row 0.1.0

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.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/CHANGELOG.md +3 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.md +79 -0
  6. data/build.gradle +73 -0
  7. data/classpath/embulk-filter-row-0.1.0.jar +0 -0
  8. data/example.yml +37 -0
  9. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  10. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  11. data/gradlew +164 -0
  12. data/gradlew.bat +90 -0
  13. data/lib/embulk/filter/row.rb +3 -0
  14. data/src/main/java/org/embulk/filter/RowFilterPlugin.java +231 -0
  15. data/src/main/java/org/embulk/filter/row/BooleanCondition.java +43 -0
  16. data/src/main/java/org/embulk/filter/row/Condition.java +5 -0
  17. data/src/main/java/org/embulk/filter/row/ConditionConfig.java +32 -0
  18. data/src/main/java/org/embulk/filter/row/ConditionFactory.java +164 -0
  19. data/src/main/java/org/embulk/filter/row/DoubleCondition.java +63 -0
  20. data/src/main/java/org/embulk/filter/row/LongCondition.java +63 -0
  21. data/src/main/java/org/embulk/filter/row/StringCondition.java +58 -0
  22. data/src/main/java/org/embulk/filter/row/TimestampCondition.java +64 -0
  23. data/src/test/java/org/embulk/filter/TestRowFilterPlugin.java +5 -0
  24. data/src/test/java/org/embulk/filter/row/TestBooleanCondition.java +64 -0
  25. data/src/test/java/org/embulk/filter/row/TestConditionFactory.java +250 -0
  26. data/src/test/java/org/embulk/filter/row/TestDoubleCondition.java +81 -0
  27. data/src/test/java/org/embulk/filter/row/TestLongCondition.java +81 -0
  28. data/src/test/java/org/embulk/filter/row/TestStringCondition.java +73 -0
  29. data/src/test/java/org/embulk/filter/row/TestTimestampCondition.java +83 -0
  30. metadata +100 -0
@@ -0,0 +1,231 @@
1
+ package org.embulk.filter;
2
+
3
+ import org.embulk.config.Config;
4
+ import org.embulk.config.ConfigDefault;
5
+ import org.embulk.config.ConfigDiff;
6
+ import org.embulk.config.ConfigSource;
7
+ import org.embulk.config.Task;
8
+ import org.embulk.config.TaskSource;
9
+
10
+ import java.util.List;
11
+ import java.util.ArrayList;
12
+ import java.util.HashMap;
13
+ import com.google.common.collect.ImmutableList;
14
+ import org.slf4j.Logger;
15
+
16
+ import org.embulk.spi.type.Type;
17
+ import org.embulk.spi.type.BooleanType;
18
+ import org.embulk.spi.type.LongType;
19
+ import org.embulk.spi.type.DoubleType;
20
+ import org.embulk.spi.type.StringType;
21
+ import org.embulk.spi.type.TimestampType;
22
+ import org.embulk.spi.time.Timestamp;
23
+
24
+ import org.embulk.spi.FilterPlugin;
25
+ import org.embulk.spi.Exec;
26
+ import org.embulk.spi.Page;
27
+ import org.embulk.spi.PageBuilder;
28
+ import org.embulk.spi.PageOutput;
29
+ import org.embulk.spi.PageReader;
30
+ import org.embulk.spi.Schema;
31
+ import org.embulk.spi.SchemaConfig;
32
+ import org.embulk.spi.Column;
33
+ import org.embulk.spi.ColumnVisitor;
34
+ import org.embulk.spi.time.TimestampParser;
35
+ import org.embulk.filter.row.ConditionConfig;
36
+ import org.embulk.filter.row.Condition;
37
+ import org.embulk.filter.row.BooleanCondition;
38
+ import org.embulk.filter.row.LongCondition;
39
+ import org.embulk.filter.row.DoubleCondition;
40
+ import org.embulk.filter.row.StringCondition;
41
+ import org.embulk.filter.row.TimestampCondition;
42
+ import org.embulk.filter.row.ConditionFactory;
43
+
44
+ public class RowFilterPlugin implements FilterPlugin
45
+ {
46
+ public interface PluginTask
47
+ extends Task, TimestampParser.Task
48
+ {
49
+ @Config("conditions")
50
+ public List<ConditionConfig> getConditions();
51
+ }
52
+
53
+ @Override
54
+ public void transaction(ConfigSource config, Schema inputSchema,
55
+ FilterPlugin.Control control)
56
+ {
57
+ PluginTask task = config.loadConfig(PluginTask.class);
58
+
59
+ Schema outputSchema = inputSchema;
60
+
61
+ control.run(task.dump(), outputSchema);
62
+ }
63
+
64
+ private final Logger log;
65
+
66
+ public RowFilterPlugin()
67
+ {
68
+ log = Exec.getLogger(RowFilterPlugin.class);
69
+ }
70
+
71
+ @Override
72
+ public PageOutput open(TaskSource taskSource, Schema inputSchema,
73
+ Schema outputSchema, PageOutput output)
74
+ {
75
+ PluginTask task = taskSource.loadTask(PluginTask.class);
76
+
77
+ HashMap<String, List<Condition>> conditionMap = new HashMap<String, List<Condition>>();
78
+ for (Column column : outputSchema.getColumns()) {
79
+ String columnName = column.getName();
80
+ conditionMap.put(columnName, new ArrayList<Condition>());
81
+ }
82
+
83
+ for (ConditionConfig conditionConfig : task.getConditions()) {
84
+ String columnName = conditionConfig.getColumn();
85
+ for (Column column : outputSchema.getColumns()) {
86
+ if (columnName.equals(column.getName())) {
87
+ ConditionFactory factory = new ConditionFactory(task.getJRuby(), column, conditionConfig);
88
+ Condition condition = factory.createCondition();
89
+ conditionMap.get(columnName).add(condition);
90
+ break;
91
+ }
92
+ }
93
+ }
94
+
95
+ return new PageOutput() {
96
+ private PageReader pageReader = new PageReader(inputSchema);
97
+ private PageBuilder pageBuilder = new PageBuilder(Exec.getBufferAllocator(), outputSchema, output);
98
+ private boolean shouldAddRecord = true;
99
+
100
+ @Override
101
+ public void finish() {
102
+ pageBuilder.finish();
103
+ }
104
+
105
+ @Override
106
+ public void close() {
107
+ pageBuilder.close();
108
+ }
109
+
110
+ @Override
111
+ public void add(Page page) {
112
+ pageReader.setPage(page);
113
+
114
+ ColumnVisitorImpl visitor = new ColumnVisitorImpl(pageBuilder);
115
+ while (pageReader.nextRecord()) {
116
+ shouldAddRecord = true;
117
+ inputSchema.visitColumns(visitor);
118
+ if (shouldAddRecord) pageBuilder.addRecord();
119
+ }
120
+ }
121
+
122
+ class ColumnVisitorImpl implements ColumnVisitor {
123
+ private final PageBuilder pageBuilder;
124
+
125
+ ColumnVisitorImpl(PageBuilder pageBuilder) {
126
+ this.pageBuilder = pageBuilder;
127
+ }
128
+
129
+ @Override
130
+ public void booleanColumn(Column column) {
131
+ if (!shouldAddRecord) return;
132
+ List<Condition> conditionList = conditionMap.get(column.getName());
133
+ for (Condition _condition : conditionList) {
134
+ BooleanCondition condition = (BooleanCondition)_condition;
135
+ if (pageReader.isNull(column)) {
136
+ if (!condition.compare(null)) { shouldAddRecord = false; break; }
137
+ } else {
138
+ boolean subject = pageReader.getBoolean(column);
139
+ if (!condition.compare(subject)) { shouldAddRecord = false; break; }
140
+ }
141
+ }
142
+ if (pageReader.isNull(column)) {
143
+ pageBuilder.setNull(column);
144
+ } else {
145
+ pageBuilder.setBoolean(column, pageReader.getBoolean(column));
146
+ }
147
+ }
148
+
149
+ @Override
150
+ public void longColumn(Column column) {
151
+ if (!shouldAddRecord) return;
152
+ List<Condition> conditionList = conditionMap.get(column.getName());
153
+ for (Condition _condition : conditionList) {
154
+ LongCondition condition = (LongCondition)_condition;
155
+ if (pageReader.isNull(column)) {
156
+ if (!condition.compare(null)) { shouldAddRecord = false; break; }
157
+ } else {
158
+ long subject = pageReader.getLong(column);
159
+ if (!condition.compare(subject)) { shouldAddRecord = false; break; }
160
+ }
161
+ }
162
+ if (pageReader.isNull(column)) {
163
+ pageBuilder.setNull(column);
164
+ } else {
165
+ pageBuilder.setLong(column, pageReader.getLong(column));
166
+ }
167
+ }
168
+
169
+ @Override
170
+ public void doubleColumn(Column column) {
171
+ if (!shouldAddRecord) return;
172
+ List<Condition> conditionList = conditionMap.get(column.getName());
173
+ for (Condition _condition : conditionList) {
174
+ DoubleCondition condition = (DoubleCondition)_condition;
175
+ if (pageReader.isNull(column)) {
176
+ if (!condition.compare(null)) { shouldAddRecord = false; break; }
177
+ } else {
178
+ double subject = pageReader.getDouble(column);
179
+ if (!condition.compare(subject)) { shouldAddRecord = false; break; }
180
+ }
181
+ }
182
+ if (pageReader.isNull(column)) {
183
+ pageBuilder.setNull(column);
184
+ } else {
185
+ pageBuilder.setDouble(column, pageReader.getDouble(column));
186
+ }
187
+ }
188
+
189
+ @Override
190
+ public void stringColumn(Column column) {
191
+ if (!shouldAddRecord) return;
192
+ List<Condition> conditionList = conditionMap.get(column.getName());
193
+ for (Condition _condition : conditionList) {
194
+ StringCondition condition = (StringCondition)_condition;
195
+ if (pageReader.isNull(column)) {
196
+ if (!condition.compare(null)) { shouldAddRecord = false; break; }
197
+ } else {
198
+ String subject = pageReader.getString(column);
199
+ if (!condition.compare(subject)) { shouldAddRecord = false; break; }
200
+ }
201
+ }
202
+ if (pageReader.isNull(column)) {
203
+ pageBuilder.setNull(column);
204
+ } else {
205
+ pageBuilder.setString(column, pageReader.getString(column));
206
+ }
207
+ }
208
+
209
+ @Override
210
+ public void timestampColumn(Column column) {
211
+ if (!shouldAddRecord) return;
212
+ List<Condition> conditionList = conditionMap.get(column.getName());
213
+ for (Condition _condition : conditionList) {
214
+ TimestampCondition condition = (TimestampCondition)_condition;
215
+ if (pageReader.isNull(column)) {
216
+ if (!condition.compare(null)) { shouldAddRecord = false; break; }
217
+ } else {
218
+ Timestamp subject = pageReader.getTimestamp(column);
219
+ if (!condition.compare(subject)) { shouldAddRecord = false; break; }
220
+ }
221
+ }
222
+ if (pageReader.isNull(column)) {
223
+ pageBuilder.setNull(column);
224
+ } else {
225
+ pageBuilder.setTimestamp(column, pageReader.getTimestamp(column));
226
+ }
227
+ }
228
+ }
229
+ };
230
+ }
231
+ }
@@ -0,0 +1,43 @@
1
+ package org.embulk.filter.row;
2
+
3
+ public class BooleanCondition implements Condition
4
+ {
5
+ private BooleanComparator comparator;
6
+
7
+ @FunctionalInterface
8
+ interface BooleanComparator {
9
+ boolean compare(Boolean subject);
10
+ }
11
+
12
+ public BooleanCondition(String operator, Boolean argument, boolean not) {
13
+ BooleanComparator comparator;
14
+ switch (operator.toUpperCase()) {
15
+ case "IS NULL":
16
+ comparator = (Boolean subject) -> {
17
+ return subject == null;
18
+ };
19
+ break;
20
+ case "IS NOT NULL":
21
+ comparator = (Boolean subject) -> {
22
+ return subject != null;
23
+ };
24
+ break;
25
+ case "!=":
26
+ comparator = (Boolean subject) -> {
27
+ return subject == null ? true : !subject.equals(argument);
28
+ };
29
+ break;
30
+ default: // case "==":
31
+ comparator = (Boolean subject) -> {
32
+ return subject == null ? false : subject.equals(argument);
33
+ };
34
+ break;
35
+ }
36
+ this.comparator = comparator;
37
+ if (not) this.comparator = (Boolean subject) -> { return !comparator.compare(subject); };
38
+ }
39
+
40
+ public boolean compare(Boolean subject) {
41
+ return this.comparator.compare(subject);
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ package org.embulk.filter.row;
2
+
3
+ public interface Condition
4
+ {
5
+ }
@@ -0,0 +1,32 @@
1
+ package org.embulk.filter.row;
2
+
3
+ import org.embulk.config.Config;
4
+ import org.embulk.config.ConfigDefault;
5
+ import org.embulk.config.Task;
6
+ import com.google.common.base.Optional;
7
+
8
+ public interface ConditionConfig extends Task
9
+ {
10
+ @Config("column")
11
+ public String getColumn();
12
+
13
+ @Config("operator")
14
+ @ConfigDefault("\"==\"")
15
+ public Optional<String> getOperator();
16
+
17
+ @Config("argument")
18
+ @ConfigDefault("null")
19
+ public Optional<Object> getArgument();
20
+
21
+ @Config("not")
22
+ @ConfigDefault("false")
23
+ public Optional<Boolean> getNot();
24
+
25
+ @Config("format")
26
+ @ConfigDefault("\"%Y-%m-%d %H:%M:%S.%N %z\"")
27
+ public Optional<String> getFormat();
28
+
29
+ @Config("timezone")
30
+ @ConfigDefault("\"UTC\"")
31
+ public Optional<String> getTimezone();
32
+ }
@@ -0,0 +1,164 @@
1
+ package org.embulk.filter.row;
2
+
3
+ import org.embulk.config.Task;
4
+ import org.embulk.spi.Exec;
5
+ import org.embulk.spi.Column;
6
+ import org.embulk.spi.type.Type;
7
+ import org.embulk.spi.type.BooleanType;
8
+ import org.embulk.spi.type.LongType;
9
+ import org.embulk.spi.type.DoubleType;
10
+ import org.embulk.spi.type.StringType;
11
+ import org.embulk.spi.type.TimestampType;
12
+ import org.embulk.config.ConfigException;
13
+
14
+ import org.joda.time.DateTimeZone;
15
+ import org.embulk.spi.time.Timestamp;
16
+ import org.embulk.spi.time.TimestampParser;
17
+ import org.embulk.spi.time.TimestampParseException;
18
+ import com.google.common.base.Throwables;
19
+
20
+ import org.embulk.filter.row.ConditionConfig;
21
+ import org.embulk.filter.row.Condition;
22
+ import org.embulk.filter.row.BooleanCondition;
23
+ import org.embulk.filter.row.LongCondition;
24
+ import org.embulk.filter.row.DoubleCondition;
25
+ import org.embulk.filter.row.StringCondition;
26
+ import org.embulk.filter.row.TimestampCondition;
27
+ import org.jruby.embed.ScriptingContainer;
28
+
29
+ public class ConditionFactory
30
+ {
31
+ private final ScriptingContainer jruby;
32
+ private Column column;
33
+ private String columnName;
34
+ private Type columnType;
35
+ private ConditionConfig conditionConfig;
36
+ private String operator;
37
+ private boolean not;
38
+
39
+ public ConditionFactory(ScriptingContainer jruby, Column column, ConditionConfig conditionConfig)
40
+ {
41
+ this.jruby = jruby;
42
+ this.column = column;
43
+ this.columnName = column.getName();
44
+ this.columnType = column.getType();
45
+ this.conditionConfig = conditionConfig;
46
+ this.operator = conditionConfig.getOperator().get().toUpperCase(); // default: ==
47
+ this.not = conditionConfig.getNot().get().booleanValue(); // default: false
48
+ }
49
+
50
+ public Condition createCondition()
51
+ {
52
+ if (columnType instanceof BooleanType) {
53
+ return createBooleanCondition();
54
+ }
55
+ else if (columnType instanceof LongType) {
56
+ return createLongCondition();
57
+ }
58
+ else if (columnType instanceof DoubleType) {
59
+ return createDoubleCondition();
60
+ }
61
+ else if (columnType instanceof StringType) {
62
+ return createStringCondition();
63
+ }
64
+ else if (columnType instanceof TimestampType) {
65
+ return createTimestampCondition();
66
+ }
67
+ assert(false);
68
+ return null;
69
+ }
70
+
71
+ public BooleanCondition createBooleanCondition()
72
+ {
73
+ if (operator.equals("IS NULL") || operator.equals("IS NOT NULL")) {
74
+ return new BooleanCondition(operator, null, not);
75
+ }
76
+ else if (!conditionConfig.getArgument().isPresent()) {
77
+ throw new ConfigException(String.format("RowFilterPlugin: Argument is missing on column: %s", columnName));
78
+ }
79
+ else if (conditionConfig.getArgument().get() instanceof Boolean) {
80
+ Boolean argument = (Boolean)conditionConfig.getArgument().get();
81
+ return new BooleanCondition(operator, argument, not);
82
+ }
83
+ else {
84
+ throw new ConfigException(String.format("RowFilterPlugin: Type mismatch on column: %s", columnName));
85
+ }
86
+ }
87
+
88
+ public LongCondition createLongCondition()
89
+ {
90
+ if (operator.equals("IS NULL") || operator.equals("IS NOT NULL")) {
91
+ return new LongCondition(operator, null, not);
92
+ }
93
+ else if (!conditionConfig.getArgument().isPresent()) {
94
+ throw new ConfigException(String.format("RowFilterPlugin: Argument is missing on column: %s", columnName));
95
+ }
96
+ else if (conditionConfig.getArgument().get() instanceof Number) {
97
+ Long argument = new Long(conditionConfig.getArgument().get().toString()).longValue();
98
+ return new LongCondition(operator, argument, not);
99
+ }
100
+ else {
101
+ throw new ConfigException(String.format("RowFilterPlugin: Type mismatch on column: %s", columnName));
102
+ }
103
+ }
104
+
105
+ public DoubleCondition createDoubleCondition()
106
+ {
107
+ if (operator.equals("IS NULL") || operator.equals("IS NOT NULL")) {
108
+ return new DoubleCondition(operator, null, not);
109
+ }
110
+ else if (!conditionConfig.getArgument().isPresent()) {
111
+ throw new ConfigException(String.format("RowFilterPlugin: Argument is missing on column: %s", columnName));
112
+ }
113
+ else if (conditionConfig.getArgument().get() instanceof Number) {
114
+ Double argument = new Double(conditionConfig.getArgument().get().toString());
115
+ return new DoubleCondition(operator, argument, not);
116
+ }
117
+ else {
118
+ throw new ConfigException(String.format("RowFilterPlugin: Type mismatch on column: %s", columnName));
119
+ }
120
+ }
121
+
122
+ public StringCondition createStringCondition()
123
+ {
124
+ if (operator.equals("IS NULL") || operator.equals("IS NOT NULL")) {
125
+ return new StringCondition(operator, null, not);
126
+ }
127
+ else if (!conditionConfig.getArgument().isPresent()) {
128
+ throw new ConfigException(String.format("RowFilterPlugin: Argument is missing on column: %s", columnName));
129
+ }
130
+ else if (conditionConfig.getArgument().get() instanceof String) {
131
+ String argument = (String)conditionConfig.getArgument().get();
132
+ return new StringCondition(operator, argument, not);
133
+ }
134
+ else {
135
+ throw new ConfigException(String.format("RowFilterPlugin: Type mismatch on column: %s", columnName));
136
+ }
137
+ }
138
+
139
+ public TimestampCondition createTimestampCondition()
140
+ {
141
+ if (operator.equals("IS NULL") || operator.equals("IS NOT NULL")) {
142
+ return new TimestampCondition(operator, null, not);
143
+ }
144
+ else if (!conditionConfig.getArgument().isPresent()) {
145
+ throw new ConfigException(String.format("RowFilterPlugin: Argument is missing on column: %s", columnName));
146
+ }
147
+ else if (conditionConfig.getArgument().get() instanceof String) {
148
+ String argument = (String)conditionConfig.getArgument().get();
149
+ String format = (String)conditionConfig.getFormat().get();
150
+ DateTimeZone timezone = DateTimeZone.forID((String)conditionConfig.getTimezone().get());
151
+
152
+ TimestampParser parser = new TimestampParser(jruby, format, timezone);
153
+ try {
154
+ Timestamp timestamp = parser.parse(argument);
155
+ return new TimestampCondition(operator, timestamp, not);
156
+ } catch(TimestampParseException ex) {
157
+ throw Throwables.propagate(ex);
158
+ }
159
+ }
160
+ else {
161
+ throw new ConfigException(String.format("RowFilterPlugin: Type mismatch on column: %s", columnName));
162
+ }
163
+ }
164
+ }
@@ -0,0 +1,63 @@
1
+ package org.embulk.filter.row;
2
+
3
+ public class DoubleCondition implements Condition
4
+ {
5
+ private DoubleComparator comparator;
6
+
7
+ @FunctionalInterface
8
+ interface DoubleComparator {
9
+ boolean compare(Double subject);
10
+ }
11
+
12
+ public DoubleCondition(String operator, Double argument, boolean not) {
13
+ DoubleComparator comparator;
14
+ switch (operator.toUpperCase()) {
15
+ case "IS NULL":
16
+ comparator = (Double subject) -> {
17
+ return subject == null;
18
+ };
19
+ break;
20
+ case "IS NOT NULL":
21
+ comparator = (Double subject) -> {
22
+ return subject != null;
23
+ };
24
+ break;
25
+ case ">":
26
+ comparator = (Double subject) -> {
27
+ return subject == null ? false : subject.compareTo(argument) > 0;
28
+ };
29
+ break;
30
+ case ">=":
31
+ comparator = (Double subject) -> {
32
+ return subject == null ? false : subject.compareTo(argument) >= 0;
33
+ };
34
+ break;
35
+ case "<":
36
+ comparator = (Double subject) -> {
37
+ return subject == null ? false : subject.compareTo(argument) < 0;
38
+ };
39
+ break;
40
+ case "<=":
41
+ comparator = (Double subject) -> {
42
+ return subject == null ? false : subject.compareTo(argument) <= 0;
43
+ };
44
+ break;
45
+ case "!=":
46
+ comparator = (Double subject) -> {
47
+ return subject == null ? true : !subject.equals(argument);
48
+ };
49
+ break;
50
+ default: // case "==":
51
+ comparator = (Double subject) -> {
52
+ return subject == null ? false : subject.equals(argument);
53
+ };
54
+ break;
55
+ }
56
+ this.comparator = comparator;
57
+ if (not) this.comparator = (Double subject) -> { return !comparator.compare(subject); };
58
+ }
59
+
60
+ public boolean compare(Double subject) {
61
+ return this.comparator.compare(subject);
62
+ }
63
+ }
@@ -0,0 +1,63 @@
1
+ package org.embulk.filter.row;
2
+
3
+ public class LongCondition implements Condition
4
+ {
5
+ private LongComparator comparator;
6
+
7
+ @FunctionalInterface
8
+ interface LongComparator {
9
+ boolean compare(Long subject);
10
+ }
11
+
12
+ public LongCondition(String operator, Long argument, boolean not) {
13
+ LongComparator comparator;
14
+ switch (operator.toUpperCase()) {
15
+ case "IS NULL":
16
+ comparator = (Long subject) -> {
17
+ return subject == null;
18
+ };
19
+ break;
20
+ case "IS NOT NULL":
21
+ comparator = (Long subject) -> {
22
+ return subject != null;
23
+ };
24
+ break;
25
+ case ">":
26
+ comparator = (Long subject) -> {
27
+ return subject == null ? false : subject.compareTo(argument) > 0;
28
+ };
29
+ break;
30
+ case ">=":
31
+ comparator = (Long subject) -> {
32
+ return subject == null ? false : subject.compareTo(argument) >= 0;
33
+ };
34
+ break;
35
+ case "<":
36
+ comparator = (Long subject) -> {
37
+ return subject == null ? false : subject.compareTo(argument) < 0;
38
+ };
39
+ break;
40
+ case "<=":
41
+ comparator = (Long subject) -> {
42
+ return subject == null ? false : subject.compareTo(argument) <= 0;
43
+ };
44
+ break;
45
+ case "!=":
46
+ comparator = (Long subject) -> {
47
+ return subject == null ? true : !subject.equals(argument);
48
+ };
49
+ break;
50
+ default: // case "==":
51
+ comparator = (Long subject) -> {
52
+ return subject == null ? false : subject.equals(argument);
53
+ };
54
+ break;
55
+ }
56
+ this.comparator = comparator;
57
+ if (not) this.comparator = (Long subject) -> { return !comparator.compare(subject); };
58
+ }
59
+
60
+ public boolean compare(Long subject) {
61
+ return this.comparator.compare(subject);
62
+ }
63
+ }
@@ -0,0 +1,58 @@
1
+ package org.embulk.filter.row;
2
+
3
+ public class StringCondition implements Condition
4
+ {
5
+ private StringComparator comparator;
6
+
7
+ @FunctionalInterface
8
+ interface StringComparator {
9
+ boolean compare(String subject);
10
+ }
11
+
12
+ public StringCondition(String operator, String argument, boolean not) {
13
+ StringComparator comparator;
14
+ switch (operator.toUpperCase()) {
15
+ case "START_WITH":
16
+ comparator = (String subject) -> {
17
+ return subject == null ? false : subject.startsWith(argument);
18
+ };
19
+ break;
20
+ case "END_WITH":
21
+ comparator = (String subject) -> {
22
+ return subject == null ? false : subject.endsWith(argument);
23
+ };
24
+ break;
25
+ case "INCLUDE":
26
+ comparator = (String subject) -> {
27
+ return subject == null ? false : subject.contains(argument);
28
+ };
29
+ break;
30
+ case "IS NULL":
31
+ comparator = (String subject) -> {
32
+ return subject == null;
33
+ };
34
+ break;
35
+ case "IS NOT NULL":
36
+ comparator = (String subject) -> {
37
+ return subject != null;
38
+ };
39
+ break;
40
+ case "!=":
41
+ comparator = (String subject) -> {
42
+ return subject == null ? true : !subject.equals(argument);
43
+ };
44
+ break;
45
+ default: // case "==":
46
+ comparator = (String subject) -> {
47
+ return subject == null ? false : subject.equals(argument);
48
+ };
49
+ break;
50
+ }
51
+ this.comparator = comparator;
52
+ if (not) this.comparator = (String subject) -> { return !comparator.compare(subject); };
53
+ }
54
+
55
+ public boolean compare(String subject) {
56
+ return this.comparator.compare(subject);
57
+ }
58
+ }