Repository: cayenne Updated Branches: refs/heads/master d3c5b72d1 -> 617628c7f
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c8709542/cayenne-server/src/test/java/org/apache/cayenne/velocity/ResultDirectiveIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/velocity/ResultDirectiveIT.java b/cayenne-server/src/test/java/org/apache/cayenne/velocity/ResultDirectiveIT.java new file mode 100644 index 0000000..3c291b8 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/velocity/ResultDirectiveIT.java @@ -0,0 +1,188 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cayenne.velocity; + +import org.apache.cayenne.DataRow; +import org.apache.cayenne.access.DataNode; +import org.apache.cayenne.access.MockOperationObserver; +import org.apache.cayenne.access.jdbc.SQLTemplateAction; +import org.apache.cayenne.access.jdbc.reader.RowReaderFactory; +import org.apache.cayenne.configuration.server.ServerRuntime; +import org.apache.cayenne.dba.JdbcAdapter; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.query.CapsStrategy; +import org.apache.cayenne.query.SQLTemplate; +import org.apache.cayenne.query.SelectQuery; +import org.apache.cayenne.test.jdbc.DBHelper; +import org.apache.cayenne.testdo.testmap.Artist; +import org.apache.cayenne.unit.di.server.ServerCase; +import org.apache.cayenne.unit.di.server.UseServerRuntime; + +import java.sql.Connection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.Mockito.mock; + +/** + * Test for Result directive to check if we could use ResultDitrective optionally. + */ +@UseServerRuntime(ServerCase.TESTMAP_PROJECT) +public class ResultDirectiveIT extends ServerCase { + + @Inject + private ServerRuntime runtime; + + @Inject + private DBHelper dbHelper; + + @Inject + private JdbcAdapter dbAdapter; + + @Override + protected void setUpAfterInjection() throws Exception { + dbHelper.deleteAll("PAINTING_INFO"); + dbHelper.deleteAll("PAINTING"); + dbHelper.deleteAll("PAINTING1"); + dbHelper.deleteAll("ARTIST_EXHIBIT"); + dbHelper.deleteAll("ARTIST_GROUP"); + dbHelper.deleteAll("ARTIST"); + dbHelper.deleteAll("EXHIBIT"); + dbHelper.deleteAll("GALLERY"); + } + + public void testWithoutResultDirective() throws Exception { + String sql = "SELECT ARTIST_ID, ARTIST_NAME FROM ARTIST"; + Map<String, Object> artist = insertArtist(); + Map<String, Object> selectResult = selectForQuery(sql); + + assertEquals(artist.get("ARTIST_ID"), selectResult.get("ARTIST_ID")); + assertEquals(artist.get("ARTIST_NAME"), selectResult.get("ARTIST_NAME")); + } + + public void testWithOnlyResultDirective() throws Exception { + String sql = "SELECT #result('ARTIST_ID' 'java.lang.Integer')," + + " #result('ARTIST_NAME' 'java.lang.String')" + + " FROM ARTIST"; + Map<String, Object> artist = insertArtist(); + Map<String, Object> selectResult = selectForQuery(sql); + + assertEquals(artist.get("ARTIST_ID"), selectResult.get("ARTIST_ID")); + assertEquals(artist.get("ARTIST_NAME"), selectResult + .get("ARTIST_NAME") + .toString() + .trim()); + } + + public void testWithMixedDirectiveUse1() throws Exception { + String sql = "SELECT ARTIST_ID," + + " #result('ARTIST_NAME' 'java.lang.String')" + + " FROM ARTIST"; + Map<String, Object> artist = insertArtist(); + Map<String, Object> selectResult = selectForQuery(sql); + + assertEquals(artist.get("ARTIST_ID"), selectResult.get("ARTIST_ID")); + assertEquals(artist.get("ARTIST_NAME"), selectResult + .get("ARTIST_NAME") + .toString() + .trim()); + } + + public void testWithMixedDirectiveUse2() throws Exception { + String sql = "SELECT #result('ARTIST_ID' 'java.lang.Integer')," + + " ARTIST_NAME " + + " FROM ARTIST"; + Map<String, Object> artist = insertArtist(); + Map<String, Object> selectResult = selectForQuery(sql); + + assertEquals(artist.get("ARTIST_ID"), selectResult.get("ARTIST_ID")); + assertEquals(artist.get("ARTIST_NAME"), selectResult.get("ARTIST_NAME")); + } + + private Map<String, Object> selectForQuery(String sql) { + SQLTemplate template = new SQLTemplate(Artist.class, sql); + template.setColumnNamesCapitalization(CapsStrategy.UPPER); + MockOperationObserver observer = new MockOperationObserver(); + runtime.getDataDomain().performQueries( + Collections.singletonList(template), + observer); + + List<Map<String, Object>> data = observer.rowsForQuery(template); + assertEquals(1, data.size()); + Map<String, Object> row = data.get(0); + return row; + } + + /** + * Inserts one Artist + * + * @return Inserted Artist as a DataRow + */ + private Map<String, Object> insertArtist() throws Exception { + Map<String, Object> parameters = new HashMap<String, Object>(); + parameters.put("id", new Integer(1)); + parameters.put("name", "ArtistToTestResult"); + String templateString = "INSERT INTO ARTIST (ARTIST_ID, ARTIST_NAME, DATE_OF_BIRTH) " + + "VALUES (#bind($id), #bind($name), #bind($dob))"; + + SQLTemplate template = new SQLTemplate(Object.class, templateString); + + template.setParameters(parameters); + + DataNode node = new DataNode(); + node.setEntityResolver(runtime.getDataDomain().getEntityResolver()); + node.setRowReaderFactory(mock(RowReaderFactory.class)); + node.setAdapter(dbAdapter); + + SQLTemplateAction action = new SQLTemplateAction(template, node); + + Connection c = runtime + .getDataDomain() + .getDataNodes() + .iterator() + .next() + .getDataSource() + .getConnection(); + try { + MockOperationObserver observer = new MockOperationObserver(); + action.performAction(c, observer); + + int[] batches = observer.countsForQuery(template); + assertNotNull(batches); + assertEquals(1, batches.length); + assertEquals(1, batches[0]); + } + finally { + c.close(); + } + + MockOperationObserver observer = new MockOperationObserver(); + SelectQuery query = new SelectQuery(Artist.class); + runtime + .getDataDomain() + .performQueries(Collections.singletonList(query), observer); + + List<?> data = observer.rowsForQuery(query); + assertEquals(1, data.size()); + DataRow row = (DataRow) data.get(0); + return row; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c8709542/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorChainTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorChainTest.java b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorChainTest.java new file mode 100644 index 0000000..d0e812a --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorChainTest.java @@ -0,0 +1,221 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cayenne.velocity; + +import org.apache.cayenne.access.jdbc.SQLStatement; +import org.apache.cayenne.velocity.SQLTemplateProcessor; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class SQLTemplateProcessorChainTest { + + @Test + public void testProcessTemplateNoChunks() throws Exception { + // whatever is inside the chain, it should render as empty if there + // is no chunks... + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + "#chain(' AND ') #end", + Collections.EMPTY_MAP); + + assertEquals("", compiled.getSql()); + + compiled = new SQLTemplateProcessor().processTemplate( + "#chain(' AND ') garbage #end", + Collections.EMPTY_MAP); + + assertEquals("", compiled.getSql()); + + compiled = new SQLTemplateProcessor().processTemplate( + "#chain(' AND ' 'PREFIX') #end", + Collections.EMPTY_MAP); + + assertEquals("", compiled.getSql()); + compiled = new SQLTemplateProcessor().processTemplate( + "#chain(' AND ' 'PREFIX') garbage #end", + Collections.EMPTY_MAP); + + assertEquals("", compiled.getSql()); + } + + @Test + public void testProcessTemplateFullChain() throws Exception { + String template = "#chain(' OR ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", "[A]"); + map.put("b", "[B]"); + map.put("c", "[C]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("[A] OR [B] OR [C]", compiled.getSql()); + } + + @Test + public void testProcessTemplateFullChainAndPrefix() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", "[A]"); + map.put("b", "[B]"); + map.put("c", "[C]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [A] OR [B] OR [C]", compiled.getSql()); + } + + @Test + public void testProcessTemplatePartialChainMiddle() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", "[A]"); + map.put("c", "[C]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [A] OR [C]", compiled.getSql()); + } + + @Test + public void testProcessTemplatePartialChainStart() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("b", "[B]"); + map.put("c", "[C]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [B] OR [C]", compiled.getSql()); + } + + @Test + public void testProcessTemplatePartialChainEnd() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", "[A]"); + map.put("b", "[B]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [A] OR [B]", compiled.getSql()); + } + + @Test + public void testProcessTemplateChainWithGarbage() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + " some other stuff" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", "[A]"); + map.put("c", "[C]"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [A] some other stuff OR [C]", compiled.getSql()); + } + + @Test + public void testProcessTemplateChainUnconditionalChunks() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk()C1#end" + + "#chunk()C2#end" + + "#chunk()C3#end" + + "#end"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + template, + Collections.EMPTY_MAP); + assertEquals("WHERE C1 OR C2 OR C3", compiled.getSql()); + } + + @Test + public void testProcessTemplateEmptyChain() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + template, + Collections.EMPTY_MAP); + assertEquals("", compiled.getSql()); + } + + @Test + public void testProcessTemplateWithFalseOrZero1() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)[A]#end" + + "#chunk($b)[B]#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", false); + map.put("b", 0); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE [A] OR [B]", compiled.getSql()); + } + + @Test + public void testProcessTemplateWithFalseOrZero2() throws Exception { + String template = "#chain(' OR ' 'WHERE ')" + + "#chunk($a)$a#end" + + "#chunk($b)$b#end" + + "#chunk($c)$c#end" + + "#end"; + + Map map = new HashMap(); + map.put("a", false); + map.put("b", 0); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(template, map); + assertEquals("WHERE false OR 0", compiled.getSql()); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c8709542/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorSelectTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorSelectTest.java b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorSelectTest.java new file mode 100644 index 0000000..3481982 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorSelectTest.java @@ -0,0 +1,112 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cayenne.velocity; + +import org.apache.cayenne.access.jdbc.ColumnDescriptor; +import org.apache.cayenne.access.jdbc.SQLStatement; +import org.apache.cayenne.velocity.SQLTemplateProcessor; +import org.junit.Test; + +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class SQLTemplateProcessorSelectTest { + + @Test + public void testProcessTemplateUnchanged() throws Exception { + String sqlTemplate = "SELECT * FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + sqlTemplate, + Collections.EMPTY_MAP); + + assertEquals(sqlTemplate, compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + assertEquals(0, compiled.getResultColumns().length); + } + + @Test + public void testProcessSelectTemplate1() throws Exception { + String sqlTemplate = "SELECT #result('A') FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + sqlTemplate, + Collections.EMPTY_MAP); + + assertEquals("SELECT A FROM ME", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + assertEquals(1, compiled.getResultColumns().length); + assertEquals("A", compiled.getResultColumns()[0].getName()); + assertNull(compiled.getResultColumns()[0].getJavaClass()); + } + + @Test + public void testProcessSelectTemplate2() throws Exception { + String sqlTemplate = "SELECT #result('A' 'String') FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + sqlTemplate, + Collections.EMPTY_MAP); + + assertEquals("SELECT A FROM ME", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + + assertEquals(1, compiled.getResultColumns().length); + assertEquals("A", compiled.getResultColumns()[0].getName()); + assertEquals("java.lang.String", compiled.getResultColumns()[0].getJavaClass()); + } + + @Test + public void testProcessSelectTemplate3() throws Exception { + String sqlTemplate = "SELECT #result('A' 'String' 'B') FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + sqlTemplate, + Collections.EMPTY_MAP); + + assertEquals("SELECT A AS B FROM ME", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + + assertEquals(1, compiled.getResultColumns().length); + ColumnDescriptor column = compiled.getResultColumns()[0]; + assertEquals("A", column.getName()); + assertEquals("B", column.getDataRowKey()); + assertEquals("java.lang.String", column.getJavaClass()); + } + + @Test + public void testProcessSelectTemplate4() throws Exception { + String sqlTemplate = "SELECT #result('A'), #result('B'), #result('C') FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate( + sqlTemplate, + Collections.EMPTY_MAP); + + assertEquals("SELECT A, B, C FROM ME", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + + assertEquals(3, compiled.getResultColumns().length); + assertEquals("A", compiled.getResultColumns()[0].getName()); + assertEquals("B", compiled.getResultColumns()[1].getName()); + assertEquals("C", compiled.getResultColumns()[2].getName()); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c8709542/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorTest.java b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorTest.java new file mode 100644 index 0000000..89f48dc --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateProcessorTest.java @@ -0,0 +1,235 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cayenne.velocity; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.sql.Types; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.cayenne.CayenneDataObject; +import org.apache.cayenne.DataObject; +import org.apache.cayenne.ObjectId; +import org.apache.cayenne.access.jdbc.ParameterBinding; +import org.apache.cayenne.access.jdbc.SQLStatement; +import org.junit.Test; + +public class SQLTemplateProcessorTest { + + @Test + public void testProcessTemplateUnchanged1() throws Exception { + String sqlTemplate = "SELECT * FROM ME"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, + Collections.<String, Object> emptyMap()); + + assertEquals(sqlTemplate, compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + } + + @Test + public void testProcessTemplateUnchanged2() throws Exception { + String sqlTemplate = "SELECT a.b as XYZ FROM $SYSTEM_TABLE"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, + Collections.<String, Object> emptyMap()); + + assertEquals(sqlTemplate, compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + } + + @Test + public void testProcessTemplateSimpleDynamicContent() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE $a"; + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE VALUE_OF_A", compiled.getSql()); + + // bindings are not populated, since no "bind" macro is used. + assertEquals(0, compiled.getBindings().length); + } + + @Test + public void testProcessTemplateBind() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE " + + "COLUMN1 = #bind($a 'VARCHAR') AND COLUMN2 = #bind($b 'INTEGER')"; + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN1 = ? AND COLUMN2 = ?", compiled.getSql()); + assertEquals(2, compiled.getBindings().length); + assertBindingValue("VALUE_OF_A", compiled.getBindings()[0]); + assertBindingValue(null, compiled.getBindings()[1]); + } + + @Test + public void testProcessTemplateBindGuessVarchar() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN1 = #bind($a)"; + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals(1, compiled.getBindings().length); + assertBindingType(Types.VARCHAR, compiled.getBindings()[0]); + } + + @Test + public void testProcessTemplateBindGuessInteger() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN1 = #bind($a)"; + Map<String, Object> map = Collections.<String, Object> singletonMap("a", 4); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals(1, compiled.getBindings().length); + assertBindingType(Types.INTEGER, compiled.getBindings()[0]); + } + + @Test + public void testProcessTemplateBindEqual() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN #bindEqual($a 'VARCHAR')"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, + Collections.<String, Object> emptyMap()); + + assertEquals("SELECT * FROM ME WHERE COLUMN IS NULL", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + + compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN = ?", compiled.getSql()); + assertEquals(1, compiled.getBindings().length); + assertBindingValue("VALUE_OF_A", compiled.getBindings()[0]); + } + + @Test + public void testProcessTemplateBindNotEqual() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN #bindNotEqual($a 'VARCHAR')"; + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, + Collections.<String, Object> emptyMap()); + + assertEquals("SELECT * FROM ME WHERE COLUMN IS NOT NULL", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + + compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN <> ?", compiled.getSql()); + assertEquals(1, compiled.getBindings().length); + assertBindingValue("VALUE_OF_A", compiled.getBindings()[0]); + } + + @Test + public void testProcessTemplateID() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN1 = #bind($helper.cayenneExp($a, 'db:ID_COLUMN'))"; + + DataObject dataObject = new CayenneDataObject(); + dataObject.setObjectId(new ObjectId("T", "ID_COLUMN", 5)); + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", dataObject); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN1 = ?", compiled.getSql()); + assertEquals(1, compiled.getBindings().length); + assertBindingValue(new Integer(5), compiled.getBindings()[0]); + } + + @Test + public void testProcessTemplateNotEqualID() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE " + + "COLUMN1 #bindNotEqual($helper.cayenneExp($a, 'db:ID_COLUMN1')) " + + "AND COLUMN2 #bindNotEqual($helper.cayenneExp($a, 'db:ID_COLUMN2'))"; + + Map<String, Object> idMap = new HashMap<String, Object>(); + idMap.put("ID_COLUMN1", new Integer(3)); + idMap.put("ID_COLUMN2", "aaa"); + ObjectId id = new ObjectId("T", idMap); + DataObject dataObject = new CayenneDataObject(); + dataObject.setObjectId(id); + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", dataObject); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN1 <> ? AND COLUMN2 <> ?", compiled.getSql()); + assertEquals(2, compiled.getBindings().length); + assertBindingValue(new Integer(3), compiled.getBindings()[0]); + assertBindingValue("aaa", compiled.getBindings()[1]); + } + + @Test + public void testProcessTemplateConditions() throws Exception { + String sqlTemplate = "SELECT * FROM ME #if($a) WHERE COLUMN1 > #bind($a)#end"; + + Map<String, Object> map = Collections.<String, Object> singletonMap("a", "VALUE_OF_A"); + + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN1 > ?", compiled.getSql()); + assertEquals(1, compiled.getBindings().length); + assertBindingValue("VALUE_OF_A", compiled.getBindings()[0]); + + compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, Collections.<String, Object> emptyMap()); + + assertEquals("SELECT * FROM ME ", compiled.getSql()); + assertEquals(0, compiled.getBindings().length); + } + + @Test + public void testProcessTemplateBindCollection() throws Exception { + String sqlTemplate = "SELECT * FROM ME WHERE COLUMN IN (#bind($list 'VARCHAR'))"; + + Map<String, Object> map = Collections.<String, Object> singletonMap("list", Arrays.asList("a", "b", "c")); + SQLStatement compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + + assertEquals("SELECT * FROM ME WHERE COLUMN IN (?,?,?)", compiled.getSql()); + assertEquals(3, compiled.getBindings().length); + + compiled = new SQLTemplateProcessor().processTemplate(sqlTemplate, map); + assertBindingValue("a", compiled.getBindings()[0]); + assertBindingValue("b", compiled.getBindings()[1]); + assertBindingValue("c", compiled.getBindings()[2]); + } + + protected void assertBindingValue(Object expectedValue, Object binding) { + assertTrue("Not a binding!", binding instanceof ParameterBinding); + assertEquals(expectedValue, ((ParameterBinding) binding).getValue()); + } + + protected void assertBindingType(int expectedType, Object binding) { + assertTrue("Not a binding!", binding instanceof ParameterBinding); + assertEquals(expectedType, ((ParameterBinding) binding).getJdbcType()); + } + + protected void assertBindingPrecision(int expectedPrecision, Object binding) { + assertTrue("Not a binding!", binding instanceof ParameterBinding); + assertEquals(expectedPrecision, ((ParameterBinding) binding).getScale()); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c8709542/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateResourceManagerTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateResourceManagerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateResourceManagerTest.java new file mode 100644 index 0000000..725788c --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/velocity/SQLTemplateResourceManagerTest.java @@ -0,0 +1,77 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cayenne.velocity; + +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.Reader; + +import org.apache.velocity.Template; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.RuntimeServices; +import org.apache.velocity.runtime.parser.node.SimpleNode; +import org.apache.velocity.runtime.resource.Resource; +import org.apache.velocity.runtime.resource.ResourceManager; +import org.junit.Before; +import org.junit.Test; + +public class SQLTemplateResourceManagerTest { + + private SQLTemplateResourceManager rm; + + @Before + public void before() throws Exception { + + RuntimeServices rs = mock(RuntimeServices.class); + when(rs.parse(any(Reader.class), anyString(), anyBoolean())).thenReturn(new SimpleNode(1)); + when(rs.parse(any(Reader.class), anyString())).thenReturn(new SimpleNode(1)); + + this.rm = new SQLTemplateResourceManager(); + rm.initialize(rs); + } + + @Test + public void testFetResource() throws Exception { + + Resource resource = rm.getResource("abc", ResourceManager.RESOURCE_TEMPLATE, RuntimeConstants.ENCODING_DEFAULT); + + assertTrue(resource instanceof Template); + + // must be cached... + assertSame(resource, + rm.getResource("abc", ResourceManager.RESOURCE_TEMPLATE, RuntimeConstants.ENCODING_DEFAULT)); + + // new resource must be different + assertNotSame(resource, + rm.getResource("xyz", ResourceManager.RESOURCE_TEMPLATE, RuntimeConstants.ENCODING_DEFAULT)); + + // after clearing cache, resource must be refreshed + rm.clearCache(); + assertNotSame(resource, + rm.getResource("abc", ResourceManager.RESOURCE_TEMPLATE, RuntimeConstants.ENCODING_DEFAULT)); + } +}
