/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.google; import static org.junit.Assert.*; import java.util.Properties; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; import org.teiid.api.exception.query.QueryParserException; import org.teiid.cdk.CommandBuilder; import org.teiid.dqp.internal.datamgr.LanguageBridgeFactory; import org.teiid.language.Command; import org.teiid.language.Delete; import org.teiid.language.Expression; import org.teiid.language.Insert; import org.teiid.language.Select; import org.teiid.language.Update; import org.teiid.metadata.MetadataFactory; import org.teiid.query.metadata.CompositeMetadataStore; import org.teiid.query.metadata.QueryMetadataInterface; import org.teiid.query.metadata.SystemMetadata; import org.teiid.query.metadata.TransformationMetadata; import org.teiid.query.parser.QueryParser; import org.teiid.query.unittest.RealMetadataFactory; import org.teiid.translator.google.api.GoogleSpreadsheetConnection; import org.teiid.translator.google.api.SpreadsheetOperationException; import org.teiid.translator.google.api.metadata.Column; import org.teiid.translator.google.api.metadata.SpreadsheetColumnType; import org.teiid.translator.google.api.metadata.SpreadsheetInfo; import org.teiid.translator.google.api.metadata.Util; import org.teiid.translator.google.api.metadata.Worksheet; import org.teiid.translator.google.visitor.SpreadsheetDeleteVisitor; import org.teiid.translator.google.visitor.SpreadsheetInsertVisitor; import org.teiid.translator.google.visitor.SpreadsheetSQLVisitor; import org.teiid.translator.google.visitor.SpreadsheetUpdateVisitor; /** * Tests transformation from Teiid Query to worksheet Query. * * @author fnguyen * */ @SuppressWarnings("nls") public class TestSQLtoSpreadsheetQuery { static SpreadsheetInfo people; @BeforeClass public static void createSpreadSheetInfo() { people= new SpreadsheetInfo("People"); Worksheet worksheet = people.createWorksheet("PeopleList"); for (int i = 1; i <= 4; i++) { Column newCol = new Column(); newCol.setAlphaName(Util.convertColumnIDtoString(i)); worksheet.addColumn(newCol.getAlphaName(), newCol); } worksheet.getColumns().get("C").setDataType(SpreadsheetColumnType.NUMBER); worksheet.getColumns().get("D").setDataType(SpreadsheetColumnType.BOOLEAN); } private QueryMetadataInterface dummySpreadsheetMetadata() throws Exception { GoogleSpreadsheetConnection conn = Mockito.mock(GoogleSpreadsheetConnection.class); Mockito.stub(conn.getSpreadsheetInfo()).toReturn(people); MetadataFactory factory = new MetadataFactory("", 1, "", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), ""); GoogleMetadataProcessor processor = new GoogleMetadataProcessor(); processor.process(factory, conn); return new TransformationMetadata(null, new CompositeMetadataStore(factory.asMetadataStore()), null, RealMetadataFactory.SFM.getSystemFunctions(), null); } public Command getCommand(String sql) throws Exception { CommandBuilder builder = new CommandBuilder(dummySpreadsheetMetadata()); return builder.getCommand(sql); } private void testConversion(String sql, String expectedSpreadsheetQuery) throws Exception{ Select select = (Select)getCommand(sql); SpreadsheetSQLVisitor spreadsheetVisitor = new SpreadsheetSQLVisitor(people); spreadsheetVisitor.translateSQL(select); assertEquals(expectedSpreadsheetQuery, spreadsheetVisitor.getTranslatedSQL()); } private void testUpdateConversion(String sql, String expectedCriteria) throws Exception { Update update = (Update)getCommand(sql); SpreadsheetUpdateVisitor spreadsheetVisitor = new SpreadsheetUpdateVisitor(people); spreadsheetVisitor.visit(update); assertEquals(expectedCriteria, spreadsheetVisitor.getCriteriaQuery()); } private void testDeleteConversion(String sql, String expectedCriteria) throws Exception { Delete delete = (Delete)getCommand(sql); SpreadsheetDeleteVisitor spreadsheetVisitor = new SpreadsheetDeleteVisitor(people); spreadsheetVisitor.visit(delete); assertEquals(expectedCriteria, spreadsheetVisitor.getCriteriaQuery()); } private SpreadsheetSQLVisitor getVisitorAndTranslateSQL(String sql) throws Exception{ Select select = (Select)getCommand(sql); SpreadsheetSQLVisitor spreadsheetVisitor = new SpreadsheetSQLVisitor(people); spreadsheetVisitor.translateSQL(select); return spreadsheetVisitor; } private void testVisitorValues(SpreadsheetSQLVisitor visitor,String worksheetTitle, Integer limitValue, Integer offsetvalue) { assertEquals(worksheetTitle, visitor.getWorksheetTitle()); assertEquals(limitValue, visitor.getLimitValue()); assertEquals(offsetvalue, visitor.getOffsetValue()); } @Test public void testSelectFrom1() throws Exception { testConversion("select A,B from PeopleList", "SELECT A, B"); testConversion("select C from PeopleList", "SELECT C"); testConversion("select * from PeopleList", "SELECT A, B, C, D"); testConversion("select A,B from PeopleList where A like '%car%' AND A NOT like '_car_'", "SELECT A, B WHERE A LIKE '%car%' AND (A NOT LIKE '_car_' AND A IS NOT NULL)"); testConversion("select A,B from PeopleList where A='car'", "SELECT A, B WHERE A = 'car'"); testConversion("select A,B from PeopleList where A >1 and B='bike'", "SELECT A, B WHERE A > '1' AND B = 'bike'"); testConversion("select A,B from PeopleList where A<1 or B <> 'bike'", "SELECT A, B WHERE (A < '1' AND A IS NOT NULL) OR (B <> 'bike' AND B IS NOT NULL)"); testConversion("select A,B from PeopleList limit 2", "SELECT A, B"); testConversion("select A,B from PeopleList offset 2 row", "SELECT A, B"); testConversion("select A,B from PeopleList limit 2,2", "SELECT A, B"); testConversion("select max(A),B from PeopleList group by B", "SELECT MAX(A), B GROUP BY B"); testConversion("select A,B from PeopleList where B like 'Filip%' order by B desc", "SELECT A, B WHERE B LIKE 'Filip%' ORDER BY B DESC"); testConversion("select A,B from PeopleList where B like 'Filip%' order by B asc", "SELECT A, B WHERE B LIKE 'Filip%' ORDER BY B"); testConversion("select A,B from PeopleList where B like 'Filip%' order by B asc", "SELECT A, B WHERE B LIKE 'Filip%' ORDER BY B"); testConversion("select ucase(A),lower(B) from PeopleList", "SELECT upper(A), lower(B)"); } @Test public void testUpdateCriteria() throws Exception { testUpdateConversion("update PeopleList set A=1 where C>1","c > 1.0"); testUpdateConversion("update PeopleList set A=1 where C=10.5","c = 10.5"); testUpdateConversion("update PeopleList set A=1 where C <= 1000 and C !=5","(c <= 1000.0 AND c <> \"\") AND (c <> 5.0 AND c <> \"\")"); testUpdateConversion("update PeopleList set A=1 where C >= 50 or C <=60.1","c >= 50.0 OR (c <= 60.1 AND c <> \"\")"); testUpdateConversion("update PeopleList set A=1 where A = 'car'","a = \"car\""); } @Test public void testDeleteCriteria() throws Exception { testDeleteConversion("delete from PeopleList where C > 1","c > 1.0"); testDeleteConversion("delete from PeopleList where C=10.5","c = 10.5"); testDeleteConversion("delete from PeopleList where C <= 1000 and C !=5","(c <= 1000.0 AND c <> \"\") AND (c <> 5.0 AND c <> \"\")"); testDeleteConversion("delete from PeopleList where C >= 50 or C <=60.1","c >= 50.0 OR (c <= 60.1 AND c <> \"\")"); testDeleteConversion("delete from PeopleList where A = 'car'","a = \"car\""); testDeleteConversion("delete from PeopleList where D = true","d = true"); } @Test public void testLiterals() throws Exception { helpTestExpression("1", "1"); helpTestExpression("true", "TRUE"); helpTestExpression("null", "NULL"); helpTestExpression("{d '2001-02-02'}", "date \"2001-02-02\""); helpTestExpression("{t '02:23:34'}", "timeofday \"02:23:34\""); helpTestExpression("{ts '2012-03-04 02:23:34.10001'}", "datetime \"2012-03-04 02:23:34.100\""); } private void helpTestExpression(String expression, String expected) throws QueryParserException { LanguageBridgeFactory lbf = new LanguageBridgeFactory(RealMetadataFactory.example1Cached()); Expression ex = lbf.translate(QueryParser.getQueryParser().parseExpression(expression)); SpreadsheetSQLVisitor spreadsheetVisitor = new SpreadsheetSQLVisitor(people); spreadsheetVisitor.translateSQL(ex); assertEquals(expected, spreadsheetVisitor.getTranslatedSQL()); } @Test public void testSelectVisitorValues() throws Exception { SpreadsheetSQLVisitor visitor=getVisitorAndTranslateSQL("select * from PeopleList where A = 'car' limit 2"); testVisitorValues(visitor, "PeopleList",2,null); visitor=getVisitorAndTranslateSQL("select * from PeopleList where A = 'car' offset 5 row"); testVisitorValues(visitor, "PeopleList",Integer.MAX_VALUE,5); visitor=getVisitorAndTranslateSQL("select A,B from PeopleList where B like 'Filip%' order by B desc"); testVisitorValues(visitor, "PeopleList",null,null); visitor=getVisitorAndTranslateSQL("select A,B from PeopleList limit 2,3"); testVisitorValues(visitor, "PeopleList",3,2); } @Test public void testInsertVisitor() throws Exception { String sql="insert into PeopleList(A,B,C) values ('String,String', 'String@String', 15.5)"; SpreadsheetInsertVisitor visitor=new SpreadsheetInsertVisitor(people); visitor.visit((Insert)getCommand(sql)); assertEquals(3, visitor.getColumnNameValuePair().size()); assertEquals("'String,String",visitor.getColumnNameValuePair().get("A")); assertEquals("'String@String",visitor.getColumnNameValuePair().get("B")); assertEquals("15.5",visitor.getColumnNameValuePair().get("C")); } @Test public void testInsertVisitorNull() throws Exception { String sql="insert into PeopleList(A,B,C) values ('String,String', null, 15.5)"; SpreadsheetInsertVisitor visitor=new SpreadsheetInsertVisitor(people); visitor.visit((Insert)getCommand(sql)); assertEquals(2, visitor.getColumnNameValuePair().size()); assertEquals("'String,String",visitor.getColumnNameValuePair().get("A")); assertEquals("15.5",visitor.getColumnNameValuePair().get("C")); } @Test public void testUpdateVisitor() throws Exception { String sql="UPDATE PeopleList set A = 'String,String', C = 1.5"; SpreadsheetUpdateVisitor visitor=new SpreadsheetUpdateVisitor(people); visitor.visit((Update)getCommand(sql)); assertEquals(2,visitor.getChanges().size()); assertEquals("A", visitor.getChanges().get(0).getColumnID()); assertEquals("'String,String", visitor.getChanges().get(0).getValue()); assertEquals("C", visitor.getChanges().get(1).getColumnID()); assertEquals("1.5", visitor.getChanges().get(1).getValue()); assertNull(visitor.getCriteriaQuery()); } @Test public void testUpdateVisitorNull() throws Exception { String sql="UPDATE PeopleList set A = 'String,String', C = null where A='Str,Str'"; SpreadsheetUpdateVisitor visitor=new SpreadsheetUpdateVisitor(people); visitor.visit((Update)getCommand(sql)); assertEquals(2,visitor.getChanges().size()); assertEquals("A", visitor.getChanges().get(0).getColumnID()); assertEquals("'String,String", visitor.getChanges().get(0).getValue()); assertEquals("C", visitor.getChanges().get(1).getColumnID()); assertEquals("", visitor.getChanges().get(1).getValue()); assertEquals("a = \"Str,Str\"", visitor.getCriteriaQuery()); } //should fail as the null string would be treated as empty @Test(expected=SpreadsheetOperationException.class) public void testUpdateVisitorNullString() throws Exception { String sql="UPDATE PeopleList set A = null where A='Str,Str'"; SpreadsheetUpdateVisitor visitor=new SpreadsheetUpdateVisitor(people); visitor.visit((Update)getCommand(sql)); } }