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
10*f7cf3d52SAndrew Rist  *
11*f7cf3d52SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f7cf3d52SAndrew Rist  *
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.
19*f7cf3d52SAndrew Rist  *
20*f7cf3d52SAndrew Rist  *************************************************************/
21*f7cf3d52SAndrew Rist 
22*f7cf3d52SAndrew Rist 
23cdf0e10cSrcweir package complex.dbaccess;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.container.ElementExistException;
26cdf0e10cSrcweir import com.sun.star.lang.IllegalArgumentException;
27cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException;
28cdf0e10cSrcweir import com.sun.star.sdb.CommandType;
29cdf0e10cSrcweir import com.sun.star.sdbc.SQLException;
30cdf0e10cSrcweir import connectivity.tools.HsqlColumnDescriptor;
31cdf0e10cSrcweir import connectivity.tools.HsqlTableDescriptor;
32cdf0e10cSrcweir import connectivity.tools.RowSet;
33cdf0e10cSrcweir import com.sun.star.sdbc.XStatement;
34cdf0e10cSrcweir import com.sun.star.sdbc.XResultSet;
35cdf0e10cSrcweir 
36cdf0e10cSrcweir // ---------- junit imports -----------------
37cdf0e10cSrcweir import org.junit.Test;
38cdf0e10cSrcweir import static org.junit.Assert.*;
39cdf0e10cSrcweir // ------------------------------------------
40cdf0e10cSrcweir 
41cdf0e10cSrcweir public class QueryInQuery extends CRMBasedTestCase
42cdf0e10cSrcweir {
43cdf0e10cSrcweir     private static final String QUERY_PRODUCTS = "query products";
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
46cdf0e10cSrcweir     @Override
createTestCase()47cdf0e10cSrcweir     protected void createTestCase()
48cdf0e10cSrcweir     {
49cdf0e10cSrcweir         try
50cdf0e10cSrcweir         {
51cdf0e10cSrcweir             super.createTestCase();
52cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery( QUERY_PRODUCTS,"SELECT * FROM \"products\"");
53cdf0e10cSrcweir         }
54cdf0e10cSrcweir         catch ( Exception e )
55cdf0e10cSrcweir         {
56cdf0e10cSrcweir             e.printStackTrace( System.err );
57cdf0e10cSrcweir             fail( "caught an exception (" + e.getMessage() + ") while creating the test case" );
58cdf0e10cSrcweir         }
59cdf0e10cSrcweir     }
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
verifyEqualRowSetContent( int _outerCommandType, String _outerCommand, int _innerCommandType, String _innerCommand )62cdf0e10cSrcweir     private void verifyEqualRowSetContent( int _outerCommandType, String _outerCommand, int _innerCommandType, String _innerCommand ) throws SQLException
63cdf0e10cSrcweir     {
64cdf0e10cSrcweir         final RowSet outerRowSet = m_database.getDatabase().createRowSet( _outerCommandType, _outerCommand );
65cdf0e10cSrcweir         outerRowSet.execute();
66cdf0e10cSrcweir 
67cdf0e10cSrcweir         final RowSet innerRowSet = m_database.getDatabase().createRowSet( _innerCommandType, _innerCommand );
68cdf0e10cSrcweir         innerRowSet.execute();
69cdf0e10cSrcweir 
70cdf0e10cSrcweir         outerRowSet.last();
71cdf0e10cSrcweir         innerRowSet.last();
72cdf0e10cSrcweir         assertTrue( "wrong record counts", outerRowSet.getRow() == innerRowSet.getRow() );
73cdf0e10cSrcweir 
74cdf0e10cSrcweir         outerRowSet.beforeFirst();
75cdf0e10cSrcweir         innerRowSet.beforeFirst();
76cdf0e10cSrcweir         assertTrue( "wrong column counts", outerRowSet.getColumnCount() == innerRowSet.getColumnCount() );
77cdf0e10cSrcweir 
78cdf0e10cSrcweir         while ( outerRowSet.next() && innerRowSet.next() )
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             for ( int i=1; i <= outerRowSet.getColumnCount(); ++i )
81cdf0e10cSrcweir             {
82cdf0e10cSrcweir                 assertTrue( "content of column " + i + " of row " + outerRowSet.getRow() + " not identical",
83cdf0e10cSrcweir                     innerRowSet.getString(i).equals( outerRowSet.getString(i) ) );
84cdf0e10cSrcweir             }
85cdf0e10cSrcweir         }
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
89cdf0e10cSrcweir     /** executes a SQL statement simply selecting all columns from a query
90cdf0e10cSrcweir      */
91cdf0e10cSrcweir     @Test
executeSimpleSelect()92cdf0e10cSrcweir     public void executeSimpleSelect() throws SQLException
93cdf0e10cSrcweir     {
94cdf0e10cSrcweir         verifyEqualRowSetContent(
95cdf0e10cSrcweir             CommandType.COMMAND, "SELECT * FROM \"query products\"",
96cdf0e10cSrcweir             CommandType.QUERY,QUERY_PRODUCTS);
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
100cdf0e10cSrcweir     /** verifies that aliases for inner queries work as expected
101cdf0e10cSrcweir      */
102cdf0e10cSrcweir     @Test
executeAliasedSelect()103cdf0e10cSrcweir     public void executeAliasedSelect() throws SQLException
104cdf0e10cSrcweir     {
105cdf0e10cSrcweir         verifyEqualRowSetContent(
106cdf0e10cSrcweir             CommandType.COMMAND, "SELECT \"PROD\".\"ID\" FROM \"query products\" AS \"PROD\"",
107cdf0e10cSrcweir             CommandType.COMMAND, "SELECT \"ID\" FROM \"products\"" );
108cdf0e10cSrcweir         verifyEqualRowSetContent(
109cdf0e10cSrcweir             CommandType.COMMAND, "SELECT \"PROD\".* FROM \"query products\" AS \"PROD\"",
110cdf0e10cSrcweir             CommandType.QUERY,QUERY_PRODUCTS);
111cdf0e10cSrcweir     }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
114cdf0e10cSrcweir     /** verifies that aliases for inner queries work as expected
115cdf0e10cSrcweir      */
116cdf0e10cSrcweir     @Test
checkNameCollisions()117cdf0e10cSrcweir     public void checkNameCollisions()
118cdf0e10cSrcweir     {
119cdf0e10cSrcweir         // create a query with a name which is used by a table
120cdf0e10cSrcweir         boolean caughtExpected = false;
121cdf0e10cSrcweir         try
122cdf0e10cSrcweir         {
123cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery( "products", "SELECT * FROM \"products\"" );
124cdf0e10cSrcweir         }
125cdf0e10cSrcweir         catch ( WrappedTargetException e ) { caughtExpected = true; }
126cdf0e10cSrcweir         catch ( IllegalArgumentException e ) {}
127cdf0e10cSrcweir         catch ( ElementExistException e ) { caughtExpected = true; }
128cdf0e10cSrcweir         assertTrue( "creating queries with the name of an existing table should not be possible",
129cdf0e10cSrcweir             caughtExpected );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir         // create a table with a name which is used by a query
132cdf0e10cSrcweir         final HsqlTableDescriptor table = new HsqlTableDescriptor( QUERY_PRODUCTS,
133cdf0e10cSrcweir             new HsqlColumnDescriptor[] {
134cdf0e10cSrcweir                 new HsqlColumnDescriptor( "ID", "INTEGER" ),
135cdf0e10cSrcweir                 new HsqlColumnDescriptor( "Name", "VARCHAR(50)" ) } );
136cdf0e10cSrcweir 
137cdf0e10cSrcweir         caughtExpected = false;
138cdf0e10cSrcweir         try
139cdf0e10cSrcweir         {
140cdf0e10cSrcweir             m_database.getDatabase().createTableInSDBCX( table );
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir         catch ( SQLException e ) { caughtExpected = true; }
143cdf0e10cSrcweir         catch ( ElementExistException ex ) { }
144cdf0e10cSrcweir         assertTrue( "creating tables with the name of an existing query should not be possible",
145cdf0e10cSrcweir             caughtExpected );
146cdf0e10cSrcweir     }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
149cdf0e10cSrcweir     @Test
checkCyclicReferences()150cdf0e10cSrcweir     public void checkCyclicReferences() throws ElementExistException, WrappedTargetException, IllegalArgumentException
151cdf0e10cSrcweir     {
152cdf0e10cSrcweir         // some queries which create a cycle in the sub query tree
153cdf0e10cSrcweir         m_database.getDatabase().getDataSource().createQuery( "orders level 1", "SELECT * FROM \"orders level 0\"" );
154cdf0e10cSrcweir         m_database.getDatabase().getDataSource().createQuery( "orders level 2", "SELECT * FROM \"orders level 1\"" );
155cdf0e10cSrcweir         m_database.getDatabase().getDataSource().createQuery( "orders level 3", "SELECT * FROM \"orders level 2\"" );
156cdf0e10cSrcweir         m_database.getDatabase().getDataSource().createQuery( "orders level 0", "SELECT * FROM \"orders level 3\"" );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         final RowSet rowSet = m_database.getDatabase().createRowSet( CommandType.QUERY, "orders level 0" );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir         boolean caughtExpected = false;
161cdf0e10cSrcweir         try { rowSet.execute(); }
162cdf0e10cSrcweir         catch ( SQLException e ) { caughtExpected = ( e.ErrorCode == -com.sun.star.sdb.ErrorCondition.PARSER_CYCLIC_SUB_QUERIES ); }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         assertTrue( "executing a query with cyclic nested sub queries should fail!", caughtExpected );
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
168cdf0e10cSrcweir     @Test
checkStatementQiQSupport()169cdf0e10cSrcweir     public void checkStatementQiQSupport()
170cdf0e10cSrcweir     {
171cdf0e10cSrcweir         try
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir             final XStatement statement = m_database.getConnection().createStatement();
174cdf0e10cSrcweir             final XResultSet resultSet = statement.executeQuery( "SELECT * FROM \"query products\"" );
175cdf0e10cSrcweir             assertTrue( "Result Set is null", resultSet != null );
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir         catch( SQLException e )
178cdf0e10cSrcweir         {
179cdf0e10cSrcweir             fail( "SDB level statements do not allow for queries in queries" );
180cdf0e10cSrcweir         }
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir }
183