1*f7cf3d52SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*f7cf3d52SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*f7cf3d52SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*f7cf3d52SAndrew Rist * distributed with this work for additional information 6*f7cf3d52SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*f7cf3d52SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*f7cf3d52SAndrew Rist * "License"); you may not use this file except in compliance 9*f7cf3d52SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*f7cf3d52SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*f7cf3d52SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*f7cf3d52SAndrew Rist * software distributed under the License is distributed on an 15*f7cf3d52SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*f7cf3d52SAndrew Rist * KIND, either express or implied. See the License for the 17*f7cf3d52SAndrew Rist * specific language governing permissions and limitations 18*f7cf3d52SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*f7cf3d52SAndrew Rist *************************************************************/ 21*f7cf3d52SAndrew Rist 22*f7cf3d52SAndrew Rist 23cdf0e10cSrcweir package complex.dbaccess; 24cdf0e10cSrcweir 25cdf0e10cSrcweir import com.sun.star.beans.XPropertySet; 26cdf0e10cSrcweir import com.sun.star.container.XIndexAccess; 27cdf0e10cSrcweir import com.sun.star.sdb.XParametersSupplier; 28cdf0e10cSrcweir import com.sun.star.sdb.XSingleSelectQueryComposer; 29cdf0e10cSrcweir import com.sun.star.sdbc.DataType; 30cdf0e10cSrcweir import com.sun.star.sdbc.SQLException; 31cdf0e10cSrcweir import com.sun.star.uno.Exception; 32cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 33cdf0e10cSrcweir 34cdf0e10cSrcweir 35cdf0e10cSrcweir // ---------- junit imports ----------------- 36cdf0e10cSrcweir import org.junit.Test; 37cdf0e10cSrcweir import static org.junit.Assert.*; 38cdf0e10cSrcweir // ------------------------------------------ 39cdf0e10cSrcweir 40cdf0e10cSrcweir public class Parser extends CRMBasedTestCase 41cdf0e10cSrcweir { 42cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 43cdf0e10cSrcweir @Override createTestCase()44cdf0e10cSrcweir protected void createTestCase() 45cdf0e10cSrcweir { 46cdf0e10cSrcweir try 47cdf0e10cSrcweir { 48cdf0e10cSrcweir super.createTestCase(); 49cdf0e10cSrcweir m_database.getDatabase().getDataSource().createQuery( "query products", "SELECT * FROM \"products\"" ); 50cdf0e10cSrcweir } 51cdf0e10cSrcweir catch ( Exception e ) 52cdf0e10cSrcweir { 53cdf0e10cSrcweir e.printStackTrace( System.err ); 54cdf0e10cSrcweir fail( "caught an exception (" + e.getMessage() + ") while creating the test case"); 55cdf0e10cSrcweir } 56cdf0e10cSrcweir } 57cdf0e10cSrcweir 58cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 59cdf0e10cSrcweir @Test checkWhere()60cdf0e10cSrcweir public void checkWhere() throws Exception 61cdf0e10cSrcweir { 62cdf0e10cSrcweir final XSingleSelectQueryComposer composer = createQueryComposer(); 63cdf0e10cSrcweir final String SELECT = "SELECT \"products\".\"Name\" FROM \"products\" WHERE "; 64cdf0e10cSrcweir final String[] queries = new String[] 65cdf0e10cSrcweir { 66cdf0e10cSrcweir "\"ID\" in ( 1,2,3,4)" 67cdf0e10cSrcweir ,"not ( \"ID\" in ( 1,2,3,4))" 68cdf0e10cSrcweir ,"(1 = 1) is true" 69cdf0e10cSrcweir ,"(1 = 1) is not false" 70cdf0e10cSrcweir ,"(1 = 1) is not null" 71cdf0e10cSrcweir ,"not ( (1 = 1) is not null)" 72cdf0e10cSrcweir ,"'a' like 'a%'" 73cdf0e10cSrcweir ,"not ( 'a' like 'a%')" 74cdf0e10cSrcweir ,"'a' not like 'a%'" 75cdf0e10cSrcweir ,"1 between 0 and 2" 76cdf0e10cSrcweir ,"not ( 1 between 0 and 2 )" 77cdf0e10cSrcweir ,"1 not between 3 and 4" 78cdf0e10cSrcweir ,"1 not between ( select \"ID\" from \"categories\") and ( select \"ID\" from \"categories\")" 79cdf0e10cSrcweir ,"1 = 1" 80cdf0e10cSrcweir ,"0 < 1" 81cdf0e10cSrcweir ,"not(0 < 1)" 82cdf0e10cSrcweir ,"1 > 0" 83cdf0e10cSrcweir ,"not(1 > 0)" 84cdf0e10cSrcweir ,"1 <> 0" 85cdf0e10cSrcweir ,"(1 <> 0 and 'a' = 'a' and 'c' = 'd') or (1 = 1 and 2 = 2 and 3 = 4)" 86cdf0e10cSrcweir ,"not ( 1 <> 0 )" 87cdf0e10cSrcweir ,"\"CategoryID\" in ( select \"ID\" from \"categories\")" 88cdf0e10cSrcweir ,"not (\"CategoryID\" in ( select \"ID\" from \"categories\"))" 89cdf0e10cSrcweir ,"\"CategoryID\" not in ( select \"ID\" from \"categories\")" 90cdf0e10cSrcweir }; 91cdf0e10cSrcweir for (int i = 0; i < queries.length; i++) 92cdf0e10cSrcweir { 93cdf0e10cSrcweir composer.setQuery( SELECT + queries[i]); 94cdf0e10cSrcweir } 95cdf0e10cSrcweir } 96cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 97cdf0e10cSrcweir /** verifies that aliases for inner queries work as expected 98cdf0e10cSrcweir */ 99cdf0e10cSrcweir @Test checkJoinSyntax()100cdf0e10cSrcweir public void checkJoinSyntax() throws Exception 101cdf0e10cSrcweir { 102cdf0e10cSrcweir final XSingleSelectQueryComposer composer = createQueryComposer(); 103cdf0e10cSrcweir 104cdf0e10cSrcweir // feed the composer with some statements. If any of those cannot be parsed, the composer 105cdf0e10cSrcweir // will throw an exception - which is a regression then 106cdf0e10cSrcweir composer.setQuery( 107cdf0e10cSrcweir "SELECT \"categories\".\"Name\", " + 108cdf0e10cSrcweir "\"products\".\"Name\" " + 109cdf0e10cSrcweir "FROM \"products\" RIGHT OUTER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" ); 110cdf0e10cSrcweir 111cdf0e10cSrcweir composer.setQuery( 112cdf0e10cSrcweir "SELECT \"categories\".\"Name\", " + 113cdf0e10cSrcweir "\"products\".\"Name\" " + 114cdf0e10cSrcweir "FROM \"products\" LEFT OUTER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" ); 115cdf0e10cSrcweir 116cdf0e10cSrcweir composer.setQuery( 117cdf0e10cSrcweir "SELECT \"categories\".\"Name\", " + 118cdf0e10cSrcweir "\"products\".\"Name\" " + 119cdf0e10cSrcweir "FROM \"products\" CROSS JOIN \"categories\" AS \"categories\"" ); 120cdf0e10cSrcweir 121cdf0e10cSrcweir composer.setQuery( 122cdf0e10cSrcweir "SELECT \"categories\".\"Name\", " + 123cdf0e10cSrcweir "\"products\".\"Name\" " + 124cdf0e10cSrcweir "FROM \"products\" INNER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" ); 125cdf0e10cSrcweir 126cdf0e10cSrcweir // just to be sure the composer *really* parses upon setting the query: feed it with 127cdf0e10cSrcweir // an unparseable statement 128cdf0e10cSrcweir boolean caughtExpected = false; 129cdf0e10cSrcweir try 130cdf0e10cSrcweir { 131cdf0e10cSrcweir composer.setQuery( "NONSENSE" ); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir catch( SQLException e ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir caughtExpected = true; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir assertTrue( "pre-condition not met: parser should except on unparseable statements, else the complete" + 138cdf0e10cSrcweir "test is bogus!", caughtExpected ); 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- impl_checkParameters( final String _statement, final String[] _expectedParameterNames, final int[] _expectedParameterTypes,final String _context )142cdf0e10cSrcweir private void impl_checkParameters( final String _statement, final String[] _expectedParameterNames, final int[] _expectedParameterTypes,final String _context ) throws Exception 143cdf0e10cSrcweir { 144cdf0e10cSrcweir final XSingleSelectQueryComposer composer = createQueryComposer(); 145cdf0e10cSrcweir composer.setQuery( _statement ); 146cdf0e10cSrcweir 147cdf0e10cSrcweir assertEquals( "checkParameterTypes: internal error", _expectedParameterNames.length, _expectedParameterTypes.length ); 148cdf0e10cSrcweir 149cdf0e10cSrcweir final XParametersSupplier paramSupp = UnoRuntime.queryInterface(XParametersSupplier.class, composer); 150cdf0e10cSrcweir final XIndexAccess parameters = paramSupp.getParameters(); 151cdf0e10cSrcweir 152cdf0e10cSrcweir assertEquals( "(ctx: " + _context + ") unexpected parameter count", _expectedParameterNames.length, parameters.getCount() ); 153cdf0e10cSrcweir for ( int i=0; i<parameters.getCount(); ++i ) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir final XPropertySet parameter = UnoRuntime.queryInterface(XPropertySet.class, parameters.getByIndex(i)); 156cdf0e10cSrcweir 157cdf0e10cSrcweir final String name = (String)parameter.getPropertyValue( "Name" ); 158cdf0e10cSrcweir assertEquals( "(ctx: " + _context + ") unexpected parameter name for parameter number " + ( i + 1 ), _expectedParameterNames[i], name ); 159cdf0e10cSrcweir 160cdf0e10cSrcweir final int type = ((Integer)parameter.getPropertyValue( "Type" )).intValue(); 161cdf0e10cSrcweir assertEquals( "(ctx: " + _context + ") unexpected data type for parameter number " + ( i + 1 ), _expectedParameterTypes[i], type ); 162cdf0e10cSrcweir } 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 166cdf0e10cSrcweir /** verifies that the parser properly recognizes the types of parameters 167cdf0e10cSrcweir */ 168cdf0e10cSrcweir @Test checkParameterTypes()169cdf0e10cSrcweir public void checkParameterTypes() throws Exception 170cdf0e10cSrcweir { 171cdf0e10cSrcweir impl_checkParameters( 172cdf0e10cSrcweir "SELECT * FROM \"all orders\" " + 173cdf0e10cSrcweir "WHERE ( \"Order Date\" >= :order_date ) " + 174cdf0e10cSrcweir " AND ( ( \"Customer Name\" LIKE :customer ) " + 175cdf0e10cSrcweir " OR ( \"Product Name\" LIKE ? ) " + 176cdf0e10cSrcweir " )", 177cdf0e10cSrcweir new String[] { "order_date", "customer", "Product Name" }, 178cdf0e10cSrcweir new int[] { DataType.DATE, DataType.VARCHAR, DataType.VARCHAR }, 179cdf0e10cSrcweir ">= && LIKE" 180cdf0e10cSrcweir ); 181cdf0e10cSrcweir 182cdf0e10cSrcweir impl_checkParameters( 183cdf0e10cSrcweir "SELECT * FROM \"categories\" " + 184cdf0e10cSrcweir "WHERE \"ID\" BETWEEN :id_lo AND :id_hi", 185cdf0e10cSrcweir new String[] { "id_lo", "id_hi" }, 186cdf0e10cSrcweir new int[] { DataType.INTEGER, DataType.INTEGER }, 187cdf0e10cSrcweir "BETWEEN" 188cdf0e10cSrcweir ); 189cdf0e10cSrcweir 190cdf0e10cSrcweir impl_checkParameters( 191cdf0e10cSrcweir "SELECT CONCAT( :prefix, CONCAT( \"Name\", :suffix ) ) FROM \"customers\"", 192cdf0e10cSrcweir new String[] { "prefix", "suffix" }, 193cdf0e10cSrcweir new int[] { DataType.VARCHAR, DataType.VARCHAR }, 194cdf0e10cSrcweir "CONCAT" 195cdf0e10cSrcweir ); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir } 198