diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java index 8d83a82c7..985e2aa01 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java @@ -63,25 +63,29 @@ public class RegistryCodeSqlBuilder { } - // todo fix it, see build public ImdgPredicate buildPredicate(ImdgPredicateBuilder pb) { - List conditions = new ArrayList<>(); + List conditionsOr = new ArrayList<>(); for (RegistryTradingParams tradingParams : this.registryTradingParams) { + List conditionsAnd = new ArrayList<>(4); if (tradingParams.registryDesignation() != null) { - conditions.add(pb.equals("registryDesignation", tradingParams.registryDesignation().getKey())); + conditionsAnd.add(pb.equals("registryDesignation", tradingParams.registryDesignation().getKey())); } if (tradingParams.registryInstrumentType() != null) { - conditions.add(pb.equals("registryInstrumentType", tradingParams.registryInstrumentType().getKey())); + conditionsAnd.add(pb.equals("registryInstrumentType", tradingParams.registryInstrumentType().getKey())); } if (tradingParams.registryCapacity() != null) { - conditions.add(pb.equals("registryCapacity", tradingParams.registryCapacity().getKey())); + conditionsAnd.add(pb.equals("registryCapacity", tradingParams.registryCapacity().getKey())); } if (tradingParams.registryUnit() != null) { - conditions.add(pb.equals("registryUnit", tradingParams.registryUnit().getKey())); + conditionsAnd.add(pb.equals("registryUnit", tradingParams.registryUnit().getKey())); } + if (conditionsAnd.size() == 1) + conditionsOr.add(conditionsAnd.get(0)); + else if (conditionsAnd.size() > 1) + conditionsOr.add(pb.and(conditionsAnd.toArray(new ImdgPredicate[conditionsAnd.size()]))); } - if (conditions.isEmpty()) return null; - if (conditions.size() == 1) return conditions.get(0); - return pb.and(conditions.toArray(new ImdgPredicate[conditions.size()])); + if (conditionsOr.isEmpty()) return null; + if (conditionsOr.size() == 1) return conditionsOr.get(0); + return pb.or(conditionsOr.toArray(new ImdgPredicate[conditionsOr.size()])); } } diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/sql/ImdgPredicateBuilderSqlMock.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/sql/ImdgPredicateBuilderSqlMock.java new file mode 100644 index 000000000..e45b0f4f3 --- /dev/null +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/sql/ImdgPredicateBuilderSqlMock.java @@ -0,0 +1,125 @@ +package ru.spcex.platform.imdg.api.predicate.sql; + +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Для тестирования (unit-тесты). Не использовать в основном коде. + */ +public class ImdgPredicateBuilderSqlMock implements ImdgPredicateBuilder { + protected static final ImdgPredicateBuilderSqlMock instance = new ImdgPredicateBuilderSqlMock(); + + public static ImdgPredicateBuilderSqlMock instance() { + return instance; + } + + + @Override + public ImdgPredicate equals(String key, Object value) { + return new SimpleSQLPredicate(key + " = " + escape(value)); + } + + @Override + public ImdgPredicate greatEqual(String key, Comparable cmpValue) { + return new SimpleSQLPredicate(key + " >= " + escape(cmpValue)); + } + + @Override + public ImdgPredicate lessEqual(String key, Comparable cmpValue) { + return new SimpleSQLPredicate(key + " <= " + escape(cmpValue)); + } + + @Override + public ImdgPredicate greater(String key, Comparable cmpValue) { + return new SimpleSQLPredicate(key + " > " + escape(cmpValue)); + } + + @Override + public ImdgPredicate less(String key, Comparable cmpValue) { + return new SimpleSQLPredicate(key + " < " + escape(cmpValue)); + } + + @Override + public ImdgPredicate notNull(String key) { + return new SimpleSQLPredicate(key + " is not null"); + } + + @Override + public ImdgPredicate in(String key, Comparable[] values) { + String enumiration = Arrays.stream(values).map(this::escape).collect(Collectors.joining(", ")); + return new SimpleSQLPredicate(key + " in (" + enumiration + ")"); + } + + @Override + public ImdgPredicate ilike(String key, String pattern) { + return new SimpleSQLPredicate(key + " ilike " + escape(pattern)); + } + + @Override + public ImdgPredicate not(ImdgPredicate param) { + return new SimpleSQLPredicate("not (" + param.toString() + ")"); + } + + @Override + public ImdgPredicate and(ImdgPredicate paramA, ImdgPredicate paramB) { + return new SimpleSQLPredicate("(" + paramA + ") and (" + paramB + ")"); + } + + @Override + public ImdgPredicate and(ImdgPredicate... param) { + return new SimpleSQLPredicate(Arrays.stream(param) + .map(p -> "(" + p + ")").collect(Collectors.joining(" and "))); + } + + @Override + public ImdgPredicate or(ImdgPredicate paramA, ImdgPredicate paramB) { + return new SimpleSQLPredicate("(" + paramA + ") or (" + paramB + ")"); + } + + @Override + public ImdgPredicate or(ImdgPredicate... param) { + return new SimpleSQLPredicate(Arrays.stream(param) + .map(p -> "(" + p + ")").collect(Collectors.joining(" or "))); + } + + @Override + public ImdgPredicate sql(String sql) { + return new SimpleSQLPredicate(sql); + } + + @Override + public ImdgPredicate regex(String key, String regex) { + throw new IllegalStateException("Test stump predicate buiulder not support regexp to SQL translation"); + } + + @Override + public ImdgPredicate alwaysTrue() { + return sql("true"); + } + + static class SimpleSQLPredicate implements ImdgPredicate { + protected String sql; + + public SimpleSQLPredicate(String sql) { + this.sql = sql; + } + + @Override + public String toString() { + return sql; + } + } + + protected String escape(Object val) { + if (val == null) return "null"; + String text = val.toString(); + if (val instanceof CharSequence) { + text = text.replace("'", "''"); + return "'" + text + "'"; + } + return text; + } +} diff --git a/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java b/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java index 0410b7c4f..9e07d115d 100644 --- a/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java +++ b/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java @@ -3,6 +3,8 @@ package ru.spcex.platform.imdg.api.predicate.specific; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.api.predicate.sql.ImdgPredicateBuilderSqlMock; public class RegistryCodeSqlBuilderTest { @@ -49,7 +51,7 @@ public class RegistryCodeSqlBuilderTest { } @Test - public void test(){ + public void test() { RegistryTradingParams registryTradingParamsL = new RegistryTradingParams(RegistryDesignation.L, RegistryInstrumentType.S, null, RegistryUnit.T); RegistryTradingParams registryTradingParamsC = new RegistryTradingParams(RegistryDesignation.C, @@ -58,4 +60,56 @@ public class RegistryCodeSqlBuilderTest { Assertions.assertEquals("(registryDesignation = 'L' and registryInstrumentType = 'S' and registryUnit = 'T') or (registryDesignation = 'C' and registryInstrumentType = 'M')", registryCodeSqlBuilder.build()); } + + + @Test + public void testBuildPredicateByOneObject() { + ImdgPredicateBuilder pb = new ImdgPredicateBuilderSqlMock(); + RegistryTradingParams registryTradingParams = new RegistryTradingParams(RegistryDesignation.C, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + String sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("(registryDesignation = 'C') and (registryInstrumentType = 'M') and (registryCapacity = 'B') and (registryUnit = 'R')", sql); + + registryTradingParams = new RegistryTradingParams(null, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("(registryInstrumentType = 'M') and (registryCapacity = 'B') and (registryUnit = 'R')", sql); + + registryTradingParams = new RegistryTradingParams(RegistryDesignation.C, null, null, RegistryUnit.R); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("(registryDesignation = 'C') and (registryUnit = 'R')", sql); + } + + @Test + public void testBuildPredicateByFewObjects() { + ImdgPredicateBuilder pb = new ImdgPredicateBuilderSqlMock(); + RegistryTradingParams registryTradingParams_first = new RegistryTradingParams(RegistryDesignation.C, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + RegistryTradingParams registryTradingParams_second = new RegistryTradingParams(RegistryDesignation.O, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + String sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("((registryDesignation = 'C') and (registryInstrumentType = 'M') and (registryCapacity = 'B') and (registryUnit = 'R'))" + + " or ((registryDesignation = 'O') and (registryInstrumentType = 'S') and (registryCapacity = 'A') and (registryUnit = 'F'))", sql); + + registryTradingParams_first = new RegistryTradingParams(null, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + registryTradingParams_second = new RegistryTradingParams(null, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("((registryInstrumentType = 'M') and (registryCapacity = 'B') and (registryUnit = 'R')) or " + + "((registryInstrumentType = 'S') and (registryCapacity = 'A') and (registryUnit = 'F'))", sql); + + registryTradingParams_first = new RegistryTradingParams(RegistryDesignation.C, null, null, RegistryUnit.R); + registryTradingParams_second = new RegistryTradingParams(null, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("((registryDesignation = 'C') and (registryUnit = 'R')) or " + + "((registryInstrumentType = 'S') and (registryCapacity = 'A') and (registryUnit = 'F'))", sql); + + registryTradingParams_first = new RegistryTradingParams(RegistryDesignation.C, null, null, null); + registryTradingParams_second = new RegistryTradingParams(null, RegistryInstrumentType.S, null, RegistryUnit.F); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + sql = registryCodeSqlBuilder.buildPredicate(pb).toString(); + Assertions.assertEquals("(registryDesignation = 'C') or " + + "((registryInstrumentType = 'S') and (registryUnit = 'F'))", sql); + } }