1*c3ab0d6aSAndrew Rist /**************************************************************
2*c3ab0d6aSAndrew Rist  *
3*c3ab0d6aSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*c3ab0d6aSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*c3ab0d6aSAndrew Rist  * distributed with this work for additional information
6*c3ab0d6aSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*c3ab0d6aSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*c3ab0d6aSAndrew Rist  * "License"); you may not use this file except in compliance
9*c3ab0d6aSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*c3ab0d6aSAndrew Rist  *
11*c3ab0d6aSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*c3ab0d6aSAndrew Rist  *
13*c3ab0d6aSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*c3ab0d6aSAndrew Rist  * software distributed under the License is distributed on an
15*c3ab0d6aSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*c3ab0d6aSAndrew Rist  * KIND, either express or implied.  See the License for the
17*c3ab0d6aSAndrew Rist  * specific language governing permissions and limitations
18*c3ab0d6aSAndrew Rist  * under the License.
19*c3ab0d6aSAndrew Rist  *
20*c3ab0d6aSAndrew Rist  *************************************************************/
21*c3ab0d6aSAndrew Rist 
22cdf0e10cSrcweir package complex.connectivity;
23cdf0e10cSrcweir 
24cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
25cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory;
26cdf0e10cSrcweir import com.sun.star.sdb.CommandType;
27cdf0e10cSrcweir import com.sun.star.sdbc.SQLException;
28cdf0e10cSrcweir import com.sun.star.util.Date;
29cdf0e10cSrcweir import complexlib.ComplexTestCase;
30cdf0e10cSrcweir import connectivity.tools.CsvDatabase;
31cdf0e10cSrcweir import connectivity.tools.RowSet;
32cdf0e10cSrcweir import java.io.File;
33cdf0e10cSrcweir import java.io.FileOutputStream;
34cdf0e10cSrcweir import java.io.PrintWriter;
35cdf0e10cSrcweir import java.util.ArrayList;
36cdf0e10cSrcweir import java.util.List;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir public class FlatFileAccess extends ComplexTestCase
39cdf0e10cSrcweir {
FlatFileAccess()40cdf0e10cSrcweir     public FlatFileAccess()
41cdf0e10cSrcweir     {
42cdf0e10cSrcweir         super();
43cdf0e10cSrcweir     }
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     @Override
getTestMethodNames()46cdf0e10cSrcweir     public String[] getTestMethodNames()
47cdf0e10cSrcweir     {
48cdf0e10cSrcweir         return new String[] {
49cdf0e10cSrcweir             "testBasicAccess",
50cdf0e10cSrcweir             "testCalendarFunctions",
51cdf0e10cSrcweir             "testSortingByFunction"
52cdf0e10cSrcweir         };
53cdf0e10cSrcweir     }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir     @Override
getTestObjectName()56cdf0e10cSrcweir     public String getTestObjectName()
57cdf0e10cSrcweir     {
58cdf0e10cSrcweir         return "FlatFileAccess";
59cdf0e10cSrcweir     }
60cdf0e10cSrcweir 
before()61cdf0e10cSrcweir     public void before() throws Exception
62cdf0e10cSrcweir     {
63cdf0e10cSrcweir         m_database = new CsvDatabase( (XMultiServiceFactory)param.getMSF() );
64cdf0e10cSrcweir 
65cdf0e10cSrcweir         // proper settings
66cdf0e10cSrcweir         final XPropertySet dataSourceSettings = m_database.getDataSource().geSettings();
67cdf0e10cSrcweir         dataSourceSettings.setPropertyValue( "Extension", "csv" );
68cdf0e10cSrcweir         dataSourceSettings.setPropertyValue( "HeaderLine", Boolean.TRUE );
69cdf0e10cSrcweir         dataSourceSettings.setPropertyValue( "FieldDelimiter", " " );
70cdf0e10cSrcweir         m_database.store();
71cdf0e10cSrcweir 
72cdf0e10cSrcweir         // write the table(s) for our test
73cdf0e10cSrcweir         final String tableLocation = m_database.getTableFileLocation().getAbsolutePath();
74cdf0e10cSrcweir         final PrintWriter tableWriter = new PrintWriter( new FileOutputStream( tableLocation + File.separatorChar + "dates.csv", false ) );
75cdf0e10cSrcweir         tableWriter.println( "ID date" );
76cdf0e10cSrcweir         tableWriter.println( "1 2013-01-01" );
77cdf0e10cSrcweir         tableWriter.println( "2 2012-02-02" );
78cdf0e10cSrcweir         tableWriter.println( "3 2011-03-03" );
79cdf0e10cSrcweir         tableWriter.close();
80cdf0e10cSrcweir     }
81cdf0e10cSrcweir 
after()82cdf0e10cSrcweir     public void after()
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir     }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     private class EqualityDate extends Date
87cdf0e10cSrcweir     {
EqualityDate( short i_day, short i_month, short i_year )88cdf0e10cSrcweir         EqualityDate( short i_day, short i_month, short i_year )
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             super( i_day, i_month, i_year );
91cdf0e10cSrcweir         }
92cdf0e10cSrcweir 
EqualityDate( Date i_date )93cdf0e10cSrcweir         EqualityDate( Date i_date )
94cdf0e10cSrcweir         {
95cdf0e10cSrcweir             super( i_date.Day, i_date.Month, i_date.Year );
96cdf0e10cSrcweir         }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir         @Override
equals( Object i_compare )99cdf0e10cSrcweir         public boolean equals( Object i_compare )
100cdf0e10cSrcweir         {
101cdf0e10cSrcweir             if ( !( i_compare instanceof Date ) )
102cdf0e10cSrcweir                 return false;
103cdf0e10cSrcweir             return  Day   == ((Date)i_compare).Day
104cdf0e10cSrcweir                 &&  Month == ((Date)i_compare).Month
105cdf0e10cSrcweir                 &&  Year  == ((Date)i_compare).Year;
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir     }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     /**
110cdf0e10cSrcweir      * ensures simple SELECTs from our table(s) work, and deliver the expected results
111cdf0e10cSrcweir      */
testBasicAccess()112cdf0e10cSrcweir     public void testBasicAccess()
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         testRowSetResults(
115cdf0e10cSrcweir             "SELECT * FROM \"dates\"",
116cdf0e10cSrcweir             new RowSetIntGetter(1),
117cdf0e10cSrcweir             new Integer[] { 1, 2, 3 },
118cdf0e10cSrcweir             "simple select", "wrong IDs"
119cdf0e10cSrcweir         );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         testRowSetResults(
122cdf0e10cSrcweir             "SELECT * FROM \"dates\"",
123cdf0e10cSrcweir             new RowSetDateGetter( 2 ),
124cdf0e10cSrcweir             new EqualityDate[] { new EqualityDate( (short)1, (short)1, (short)2013 ),
125cdf0e10cSrcweir                                  new EqualityDate( (short)2, (short)2, (short)2012 ),
126cdf0e10cSrcweir                                  new EqualityDate( (short)3, (short)3, (short)2011 )
127cdf0e10cSrcweir             },
128cdf0e10cSrcweir             "simple select", "wrong dates"
129cdf0e10cSrcweir         );
130cdf0e10cSrcweir         testRowSetResults(
131cdf0e10cSrcweir             "SELECT \"date\", \"ID\" FROM \"dates\" ORDER BY \"ID\" DESC",
132cdf0e10cSrcweir             new RowSetIntGetter( 2 ),
133cdf0e10cSrcweir             new Integer[] { 3, 2, 1 },
134cdf0e10cSrcweir             "explicit column selection, sorted by IDs", "wrong IDs"
135cdf0e10cSrcweir         );
136cdf0e10cSrcweir         testRowSetResults(
137cdf0e10cSrcweir             "SELECT * FROM \"dates\" ORDER BY \"date\"",
138cdf0e10cSrcweir             new RowSetIntGetter( 1 ),
139cdf0e10cSrcweir             new Integer[] { 3, 2, 1 },
140cdf0e10cSrcweir             "sorted by date", "wrong IDs"
141cdf0e10cSrcweir         );
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     /**
145cdf0e10cSrcweir      * ensures the basic functionality for selecting calendar functions from a CSV table - this is a prerequisite for
146cdf0e10cSrcweir      * later tests.
147cdf0e10cSrcweir      */
testCalendarFunctions()148cdf0e10cSrcweir     public void testCalendarFunctions()
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         // simple check for proper results of the calendar functions (DATE/MONTH)
151cdf0e10cSrcweir         // The * at the first position is crucial here - there was code which wrongly calculated
152cdf0e10cSrcweir         // column positions of function columns when * was present in the statement
153cdf0e10cSrcweir         testRowSetResults(
154cdf0e10cSrcweir             "SELECT \"dates\".*, YEAR( \"date\" ) FROM \"dates\"",
155cdf0e10cSrcweir             new RowSetIntGetter( 3 ),
156cdf0e10cSrcweir             new Integer[] { 2013, 2012, 2011 },
157cdf0e10cSrcweir             "YEAR function", "wrong calculated years"
158cdf0e10cSrcweir         );
159cdf0e10cSrcweir         testRowSetResults(
160cdf0e10cSrcweir             "SELECT \"dates\".*, MONTH( \"date\" ) FROM \"dates\"",
161cdf0e10cSrcweir             new RowSetIntGetter( 3 ),
162cdf0e10cSrcweir             new Integer[] { 1, 2, 3 },
163cdf0e10cSrcweir             "MONTH function", "wrong calculated months"
164cdf0e10cSrcweir         );
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     /**
168cdf0e10cSrcweir      * ensures that sorting by a function column works
169cdf0e10cSrcweir      */
testSortingByFunction()170cdf0e10cSrcweir     public void testSortingByFunction()
171cdf0e10cSrcweir     {
172cdf0e10cSrcweir         // most simple case: select a function, and sort by it
173cdf0e10cSrcweir         testRowSetResults(
174cdf0e10cSrcweir             "SELECT YEAR( \"date\" ) AS \"year\" FROM \"dates\" ORDER BY \"year\"",
175cdf0e10cSrcweir             new RowSetIntGetter(1),
176cdf0e10cSrcweir             new Integer[] { 2011, 2012, 2013 },
177cdf0e10cSrcweir             "single YEAR selection, sorted by years", "wrong calculated years"
178cdf0e10cSrcweir         );
179cdf0e10cSrcweir         // somewhat more "difficult" (this used to crash): Select all columns, plus a function, so the calculated
180cdf0e10cSrcweir         // column has a position greater than column count
181cdf0e10cSrcweir         testRowSetResults(
182cdf0e10cSrcweir             "SELECT \"dates\".*, YEAR( \"date\" ) AS \"year\" FROM \"dates\" ORDER BY \"year\" DESC",
183cdf0e10cSrcweir             new RowSetIntGetter(3),
184cdf0e10cSrcweir             new Integer[] { 2013, 2012, 2011 },
185cdf0e10cSrcweir             "extended YEAR selection, sorted by years", "wrong calculated years"
186cdf0e10cSrcweir         );
187cdf0e10cSrcweir     }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir     private interface RowSetValueGetter
190cdf0e10cSrcweir     {
getValue( final RowSet i_rowSet )191cdf0e10cSrcweir         public Object getValue( final RowSet i_rowSet ) throws SQLException;
192cdf0e10cSrcweir     }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     private abstract class RowSetColumnValueGetter implements RowSetValueGetter
195cdf0e10cSrcweir     {
RowSetColumnValueGetter( final int i_columnIndex )196cdf0e10cSrcweir         RowSetColumnValueGetter( final int i_columnIndex )
197cdf0e10cSrcweir         {
198cdf0e10cSrcweir             m_columnIndex = i_columnIndex;
199cdf0e10cSrcweir         }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir         protected final int m_columnIndex;
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     private class RowSetIntGetter extends RowSetColumnValueGetter
205cdf0e10cSrcweir     {
RowSetIntGetter( final int i_columnIndex )206cdf0e10cSrcweir         RowSetIntGetter( final int i_columnIndex )
207cdf0e10cSrcweir         {
208cdf0e10cSrcweir             super( i_columnIndex );
209cdf0e10cSrcweir         }
210cdf0e10cSrcweir 
getValue( final RowSet i_rowSet )211cdf0e10cSrcweir         public Object getValue( final RowSet i_rowSet ) throws SQLException
212cdf0e10cSrcweir         {
213cdf0e10cSrcweir             return i_rowSet.getInt( m_columnIndex );
214cdf0e10cSrcweir         }
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     private class RowSetDateGetter extends RowSetColumnValueGetter
218cdf0e10cSrcweir     {
RowSetDateGetter( final int i_columnIndex )219cdf0e10cSrcweir         RowSetDateGetter( final int i_columnIndex )
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             super( i_columnIndex );
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir 
getValue( final RowSet i_rowSet )224cdf0e10cSrcweir         public Object getValue( final RowSet i_rowSet ) throws SQLException
225cdf0e10cSrcweir         {
226cdf0e10cSrcweir             return i_rowSet.getDate( m_columnIndex );
227cdf0e10cSrcweir         }
228cdf0e10cSrcweir     }
229cdf0e10cSrcweir 
testRowSetResults( String i_command, RowSetValueGetter i_getter, T[] i_expectedValues, String i_context, String i_failureDesc )230cdf0e10cSrcweir     private <T> void testRowSetResults( String i_command, RowSetValueGetter i_getter,
231cdf0e10cSrcweir         T[] i_expectedValues, String i_context, String i_failureDesc )
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         RowSet rowSet = null;
234cdf0e10cSrcweir         try
235cdf0e10cSrcweir         {
236cdf0e10cSrcweir             rowSet = m_database.createRowSet( CommandType.COMMAND, i_command );
237cdf0e10cSrcweir             rowSet.execute();
238cdf0e10cSrcweir 
239cdf0e10cSrcweir             List< T > values = new ArrayList< T >();
240cdf0e10cSrcweir             while ( rowSet.next() )
241cdf0e10cSrcweir             {
242cdf0e10cSrcweir                 values.add( (T)i_getter.getValue( rowSet ) );
243cdf0e10cSrcweir             }
244cdf0e10cSrcweir             assureEquals( i_context + ": " + i_failureDesc, i_expectedValues, values.toArray(), true );
245cdf0e10cSrcweir         }
246cdf0e10cSrcweir         catch( final SQLException e )
247cdf0e10cSrcweir         {
248cdf0e10cSrcweir             failed( i_context + ": caught an exception: " + e.toString(), false );
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir         finally
251cdf0e10cSrcweir         {
252cdf0e10cSrcweir             if ( rowSet != null )
253cdf0e10cSrcweir                 rowSet.dispose();
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     private CsvDatabase m_database = null;
258cdf0e10cSrcweir }
259