diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderDao.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderDao.java index 245c91da3..d5268098b 100644 --- a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderDao.java +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderDao.java @@ -19,9 +19,11 @@ import java.io.IOException; import java.io.InputStream; import java.sql.Date; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLXML; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -46,6 +48,8 @@ import org.xml.sax.SAXException; @SuppressWarnings("nls") public class PostgreSqlOrderDao extends PostgresqlDao implements OrderDao { + public static final String ORDERS = "orders"; + /** * @param tx */ @@ -60,7 +64,7 @@ public class PostgreSqlOrderDao extends PostgresqlDao implements OrderDao @Override protected String getTableName() { - return "orders"; + return ORDERS; } @Override @@ -157,7 +161,29 @@ public class PostgreSqlOrderDao extends PostgresqlDao implements OrderDao @Override public List doQuery(OrderQuery query, OrderVisitor orderVisitor) { - // TODO Auto-generated method stub - return null; + + PostgreSqlOrderQueryVisitor queryVisitor = new PostgreSqlOrderQueryVisitor("id, asxml"); + query.accept(queryVisitor); + queryVisitor.validate(); + + List list = new ArrayList<>(); + + String sql = queryVisitor.getSql(); + try (PreparedStatement ps = PostgreSqlOrderDao.this.tx.getConnection().prepareStatement(sql)) { + queryVisitor.setValues(ps); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + String id = result.getString("id"); + SQLXML sqlxml = result.getSQLXML("asxml"); + Order t = parseFromXml(id, queryVisitor.getType(), sqlxml); + list.add(orderVisitor.visit(t)); + } + } + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e); + } + + return list; } } diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderQueryVisitor.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderQueryVisitor.java new file mode 100644 index 000000000..4ba9288cb --- /dev/null +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlOrderQueryVisitor.java @@ -0,0 +1,56 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.persistence.postgresql; + +import li.strolch.model.Tags; +import li.strolch.model.query.DateSelection; +import li.strolch.model.query.OrderQueryVisitor; +import li.strolch.model.query.StateSelection; + +/** + * @author Robert von Burg + */ +public class PostgreSqlOrderQueryVisitor extends PostgreSqlQueryVisitor implements OrderQueryVisitor { + + /** + * @param fields + */ + public PostgreSqlOrderQueryVisitor(String fields) { + super(fields); + } + + protected String getClassName() { + return Tags.ORDER; + } + + protected String getTableName() { + return PostgreSqlOrderDao.ORDERS; + } + + @Override + public void visit(DateSelection selection) { + sb.append(indent); + sb.append("date = ?\n"); + values.add(selection.getDate()); + } + + @Override + public void visit(StateSelection selection) { + sb.append(indent); + sb.append("stae = ?\n"); + values.add(selection.getState().name()); + } +} diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlQueryVisitor.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlQueryVisitor.java new file mode 100644 index 000000000..15fff09b6 --- /dev/null +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlQueryVisitor.java @@ -0,0 +1,307 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.persistence.postgresql; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import li.strolch.model.query.AndSelection; +import li.strolch.model.query.IdSelection; +import li.strolch.model.query.NameSelection; +import li.strolch.model.query.NotSelection; +import li.strolch.model.query.OrSelection; +import li.strolch.model.query.ParameterSelection.BooleanParameterSelection; +import li.strolch.model.query.ParameterSelection.DateParameterSelection; +import li.strolch.model.query.ParameterSelection.DateRangeParameterSelection; +import li.strolch.model.query.ParameterSelection.FloatParameterSelection; +import li.strolch.model.query.ParameterSelection.IntegerParameterSelection; +import li.strolch.model.query.ParameterSelection.LongParameterSelection; +import li.strolch.model.query.ParameterSelection.StringListParameterSelection; +import li.strolch.model.query.ParameterSelection.StringParameterSelection; +import li.strolch.model.query.ParameterSelectionVisitor; +import li.strolch.model.query.Selection; +import li.strolch.model.query.StrolchElementSelectionVisitor; +import li.strolch.model.query.StrolchTypeNavigation; +import ch.eitchnet.utils.StringMatchMode; +import ch.eitchnet.utils.dbc.DBC; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public abstract class PostgreSqlQueryVisitor implements StrolchElementSelectionVisitor, ParameterSelectionVisitor { + + protected StringBuilder sql; + protected StringBuilder sb; + protected String type; + protected List values; + protected boolean any; + protected String indent; + private String sqlAsString; + + public PostgreSqlQueryVisitor(String fields) { + this.indent = ""; + this.sql = new StringBuilder(); + this.sb = new StringBuilder(); + this.values = new ArrayList<>(); + + this.sql.append("select "); + this.sql.append(fields); + this.sql.append("\nfrom\n"); + this.sql.append(" "); + this.sql.append(getTableName()); + this.indent = " "; + } + + public String getSql() { + if (sqlAsString != null) + return sqlAsString; + + this.sql.append("\nwhere\n"); + this.sql.append(this.indent); + + if (this.any) { + this.sql.append("type = ?"); + sqlAsString = this.sql.toString(); + return sqlAsString; + } + + this.sql.append("type = ? and\n"); + + this.sql.append(this.sb.toString()); + sqlAsString = this.sql.toString(); + return sqlAsString; + } + + /** + * @return the any + */ + public boolean isAny() { + return this.any; + } + + /** + * @return the values + */ + public List getValues() { + return this.values; + } + + public String getType() { + return this.type; + } + + public void validate() { + DBC.INTERIM.assertNotEmpty("No navigation was set!", this.type); + } + + protected abstract String getClassName(); + + protected abstract String getTableName(); + + @Override + public void visit(StrolchTypeNavigation navigation) { + this.type = navigation.getType(); + } + + @Override + public void visit(IdSelection selection) { + this.sb.append(this.indent); + List ids = selection.getIds(); + if (ids.isEmpty()) + return; + int size = ids.size(); + if (size == 1) { + this.sb.append("id = ?\n"); + this.values.add(ids.get(0)); + } else { + this.sb.append("id in ("); + Iterator iter = ids.iterator(); + while (iter.hasNext()) { + String id = iter.next(); + this.sb.append("?"); + this.values.add(id); + if (iter.hasNext()) + this.sb.append(", "); + } + this.sb.append(" )\n"); + } + } + + @Override + public void visit(NameSelection selection) { + this.sb.append(this.indent); + String name = selection.getName(); + + // CS EQ + // 1. x x + // 2. x o + // 3. o x + // 4. o o + + StringMatchMode mm = selection.getMatchMode(); + if (mm.isCaseSensitve() && mm.isEquals()) { + this.sb.append("name = ?\n"); + this.values.add(name); + } else if (!mm.isCaseSensitve() && mm.isEquals()) { + this.sb.append("lower(name) = lower(?)\n"); + this.values.add(name); + } else if (!mm.isEquals() && mm.isCaseSensitve()) { + this.sb.append("name like ?"); + this.values.add("%" + name + "%"); + } else { + this.sb.append("lower(name) like ?"); + this.values.add(name.toLowerCase()); + } + } + + @Override + public void visitAny() { + this.any = true; + } + + @Override + public void visitAnd(AndSelection andSelection) { + this.sb.append(this.indent); + List selections = andSelection.getSelections(); + this.sb.append("( \n"); + Iterator iter = selections.iterator(); + String indent = this.indent; + this.indent += " "; + while (iter.hasNext()) { + Selection selection = iter.next(); + selection.accept(this); + if (iter.hasNext()) { + this.sb.append(indent); + this.sb.append("and\n"); + } + } + this.indent = indent; + this.sb.append(this.indent); + this.sb.append(")\n"); + } + + @Override + public void visitOr(OrSelection orSelection) { + this.sb.append(this.indent); + List selections = orSelection.getSelections(); + this.sb.append("( \n"); + Iterator iter = selections.iterator(); + String indent = this.indent; + this.indent += " "; + while (iter.hasNext()) { + Selection selection = iter.next(); + selection.accept(this); + if (iter.hasNext()) { + this.sb.append(indent); + this.sb.append("or\n"); + } + } + this.indent = indent; + this.sb.append(this.indent); + this.sb.append(")\n"); + } + + @Override + public void visitNot(NotSelection notSelection) { + this.sb.append(this.indent); + List selections = notSelection.getSelections(); + this.sb.append("not ( \n"); + Iterator iter = selections.iterator(); + String indent = this.indent; + this.indent += " "; + while (iter.hasNext()) { + Selection selection = iter.next(); + selection.accept(this); + if (iter.hasNext()) { + this.sb.append(indent); + this.sb.append("and\n"); + } + } + this.indent = indent; + this.sb.append(this.indent); + this.sb.append(")\n"); + } + + private void xpath(String bagKey, String paramKey, String paramValue) { + this.sb.append(this.indent); + String xpath = "cast(xpath('//Resource/ParameterBag[@Id=\"${bagKey}\"]/Parameter[@Id=\"${paramKey}\" and @Value=\"${paramValue}\"]', asxml) as text[]) != '{}'\n"; + xpath = xpath.replace("${bagKey}", bagKey); + xpath = xpath.replace("${paramKey}", paramKey); + xpath = xpath.replace("${paramValue}", paramValue); + this.sb.append(xpath); + } + + @Override + public void visit(StringParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue()); + } + + @Override + public void visit(IntegerParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString()); + } + + @Override + public void visit(BooleanParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString()); + } + + @Override + public void visit(LongParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString()); + } + + @Override + public void visit(FloatParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString()); + } + + @Override + public void visit(DateParameterSelection selection) { + xpath(selection.getBagKey(), selection.getParamKey(), + ISO8601FormatFactory.getInstance().formatDate(selection.getValue())); + } + + @Override + public void visit(DateRangeParameterSelection selection) { + throw new UnsupportedOperationException("Not yet supported!"); + } + + @Override + public void visit(StringListParameterSelection selection) { + throw new UnsupportedOperationException("Not yet supported!"); + } + + /** + * @param ps + * @throws SQLException + */ + public void setValues(PreparedStatement ps) throws SQLException { + if (this.any) { + ps.setString(1, this.type); + return; + } + + ps.setString(1, this.type); + for (int i = 0; i < this.values.size(); i++) { + ps.setObject(i + 2, this.values.get(i)); + } + } +} diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceDao.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceDao.java index d0455a956..4545b8a88 100644 --- a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceDao.java +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceDao.java @@ -18,9 +18,11 @@ package li.strolch.persistence.postgresql; import java.io.IOException; import java.io.InputStream; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLXML; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; @@ -44,6 +46,8 @@ import org.xml.sax.SAXException; @SuppressWarnings("nls") public class PostgreSqlResourceDao extends PostgresqlDao implements ResourceDao { + public static final String RESOURCES = "resources"; + protected PostgreSqlResourceDao(PostgreSqlStrolchTransaction tx) { super(tx); } @@ -55,7 +59,7 @@ public class PostgreSqlResourceDao extends PostgresqlDao implements Re @Override protected String getTableName() { - return "resources"; + return RESOURCES; } @Override @@ -146,7 +150,29 @@ public class PostgreSqlResourceDao extends PostgresqlDao implements Re @Override public List doQuery(ResourceQuery query, ResourceVisitor resourceVisitor) { - // TODO Auto-generated method stub - return null; + + PostgreSqlResourceQueryVisitor queryVisitor = new PostgreSqlResourceQueryVisitor("id, asxml"); + query.accept(queryVisitor); + queryVisitor.validate(); + + List list = new ArrayList<>(); + + String sql = queryVisitor.getSql(); + try (PreparedStatement ps = PostgreSqlResourceDao.this.tx.getConnection().prepareStatement(sql)) { + queryVisitor.setValues(ps); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + String id = result.getString("id"); + SQLXML sqlxml = result.getSQLXML("asxml"); + Resource t = parseFromXml(id, queryVisitor.getType(), sqlxml); + list.add(resourceVisitor.visit(t)); + } + } + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e); + } + + return list; } } diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceQueryVisitor.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceQueryVisitor.java new file mode 100644 index 000000000..349641144 --- /dev/null +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlResourceQueryVisitor.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.persistence.postgresql; + +import li.strolch.model.Tags; +import li.strolch.model.query.ResourceQueryVisitor; + +/** + * @author Robert von Burg + */ +public class PostgreSqlResourceQueryVisitor extends PostgreSqlQueryVisitor implements ResourceQueryVisitor { + + /** + * @param fields + */ + public PostgreSqlResourceQueryVisitor(String fields) { + super(fields); + } + + protected String getClassName() { + return Tags.RESOURCE; + } + + protected String getTableName() { + return PostgreSqlResourceDao.RESOURCES; + } +} diff --git a/src/test/java/li/strolch/persistence/postgresql/dao/test/QueryTest.java b/src/test/java/li/strolch/persistence/postgresql/dao/test/QueryTest.java new file mode 100644 index 000000000..aef53c158 --- /dev/null +++ b/src/test/java/li/strolch/persistence/postgresql/dao/test/QueryTest.java @@ -0,0 +1,223 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.persistence.postgresql.dao.test; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import li.strolch.model.query.IdSelection; +import li.strolch.model.query.NameSelection; +import li.strolch.model.query.OrSelection; +import li.strolch.model.query.OrderQuery; +import li.strolch.model.query.ParameterSelection; +import li.strolch.model.query.ResourceQuery; +import li.strolch.model.query.StrolchTypeNavigation; +import li.strolch.persistence.postgresql.PostgreSqlOrderQueryVisitor; +import li.strolch.persistence.postgresql.PostgreSqlQueryVisitor; +import li.strolch.persistence.postgresql.PostgreSqlResourceQueryVisitor; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class QueryTest { + + private static final Logger logger = LoggerFactory.getLogger(QueryTest.class); + + public Connection openConn() throws SQLException { + String url = "jdbc:postgresql://localhost/testdb"; + String username = "testuser"; + String password = "test"; + Connection connection = DriverManager.getConnection(url, username, password); + connection.setAutoCommit(false); + return connection; + } + + @Test + public void shouldQueryOrderAll() throws SQLException { + + OrderQuery query = new OrderQuery(new StrolchTypeNavigation("QTestType1")); + query.withAny(); + performOrderQuery(query, Arrays.asList("myTestOrder1")); + } + + @Test + public void shouldQueryResourceAll() throws SQLException { + + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.withAny(); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + } + + @Test + public void shouldQueryOrder1() throws SQLException { + + OrderQuery query = new OrderQuery(new StrolchTypeNavigation("QTestType1")); + query.and().with(new IdSelection("myTestOrder1", "@2"), + new NameSelection("Test Name", StringMatchMode.EQUALS_CASE_SENSITIVE)); + performOrderQuery(query, Arrays.asList("myTestOrder1")); + } + + @Test + public void shouldQueryOrder2() throws SQLException { + + OrderQuery query = new OrderQuery(new StrolchTypeNavigation("QTestType1")); + query.or().with(new IdSelection("myTestOrder1", "@2"), + new NameSelection("Test Name", StringMatchMode.EQUALS_CASE_SENSITIVE)); + performOrderQuery(query, Arrays.asList("myTestOrder1")); + } + + @Test + public void shouldQueryResource1() throws SQLException { + + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.or().with(new IdSelection("@_00000000", "@_00000001"), + new NameSelection("Test Name", StringMatchMode.EQUALS_CASE_SENSITIVE)); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001")); + } + + @Test + public void shouldQueryResource2() throws SQLException { + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with( + new OrSelection(new IdSelection("@_00000000"), new IdSelection("@_00000001")), + new OrSelection(new NameSelection("My Resource 0", StringMatchMode.EQUALS_CASE_SENSITIVE), + new NameSelection("My Resource 1", StringMatchMode.EQUALS_CASE_SENSITIVE))); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001")); + } + + @Test + public void shouldQueryResourceByBooleParam() throws SQLException { + + // select id, name, type, asxml + // from + // resources + // where + // type = 'MyType1' and + // ( + // cast(xpath('//Resource/ParameterBag/Parameter[@Id="@param1" and @Value="true"]', asxml) as text[]) != '{}' + // ) + + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with(ParameterSelection.booleanSelection("@bag01", "@param1", true)); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + } + + @Test + public void shouldQueryResourceByFloagParam() throws SQLException { + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with(ParameterSelection.floatSelection("@bag01", "@param2", 44.3)); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + } + + @Test + public void shouldQueryResourceByIntegerParam() throws SQLException { + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with(ParameterSelection.integerSelection("@bag01", "@param3", 77)); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + } + + @Test + public void shouldQueryResourceByLongParam() throws SQLException { + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with(ParameterSelection.longSelection("@bag01", "@param4", 4453234566L)); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + } + + @Test + public void shouldQueryResourceByStringParam() throws SQLException { + + List expected = Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004"); + + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with( + ParameterSelection.stringSelection("@bag01", "@param5", "Strolch", + StringMatchMode.EQUALS_CASE_SENSITIVE)); + performResourceQuery(query, expected); + + query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with( + ParameterSelection.stringSelection("@bag01", "@param5", "strolch", + StringMatchMode.EQUALS_CASE_SENSITIVE)); + performResourceQuery(query, Arrays. asList()); + + query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with( + ParameterSelection.stringSelection("@bag01", "@param5", "strolch", + StringMatchMode.EQUALS_CASE_INSENSITIVE)); + performResourceQuery(query, expected); + + query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with( + ParameterSelection.stringSelection("@bag01", "@param5", "olch", + StringMatchMode.CONTAINS_CASE_INSENSITIVE)); + performResourceQuery(query, expected); + } + + @Test + public void shouldQueryResourceByDateParam() throws SQLException { + ResourceQuery query = new ResourceQuery(new StrolchTypeNavigation("MyType1")); + query.and().with(ParameterSelection.dateSelection("@bag01", "@param6", new Date(1354295525628L))); + performResourceQuery(query, Arrays.asList("@_00000000", "@_00000001", "@_00000002", "@_00000003", "@_00000004")); + + } + + private void performOrderQuery(OrderQuery query, List expected) throws SQLException { + PostgreSqlOrderQueryVisitor visitor = new PostgreSqlOrderQueryVisitor("id"); + query.accept(visitor); + List ids = queryIds(visitor); + assertEquals(expected, ids); + } + + private void performResourceQuery(ResourceQuery query, List expected) throws SQLException { + PostgreSqlResourceQueryVisitor visitor = new PostgreSqlResourceQueryVisitor("id"); + query.accept(visitor); + List ids = queryIds(visitor); + assertEquals(expected, ids); + } + + private List queryIds(PostgreSqlQueryVisitor visitor) throws SQLException { + String sql = visitor.getSql(); + logger.info("\n" + sql); + List ids = new ArrayList<>(); + try (Connection con = openConn()) { + try (PreparedStatement ps = con.prepareStatement(sql)) { + visitor.setValues(ps); + + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + ids.add(rs.getString(1)); + } + } + } + + return ids; + } +}