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