View Javadoc
1   package com.healthmarketscience.jackcess.impl;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.nio.channels.FileChannel;
6   import java.util.ArrayList;
7   import java.util.EnumSet;
8   import java.util.List;
9   import java.util.Set;
10  
11  import com.healthmarketscience.jackcess.Database;
12  import static com.healthmarketscience.jackcess.Database.*;
13  import com.healthmarketscience.jackcess.DatabaseBuilder;
14  import junit.framework.TestCase;
15  import static com.healthmarketscience.jackcess.TestUtil.*;
16  
17  
18  /**
19   * @author Dan Rollo
20   *         Date: Mar 5, 2010
21   *         Time: 12:44:21 PM
22   */
23  public class JetFormatTest extends TestCase {
24  
25    public static final File DIR_TEST_DATA = new File("src/test/data");
26  
27    /**
28     * Defines known valid db test file base names.
29     */
30    public static enum Basename {
31  
32      BIG_INDEX("bigIndexTest"),
33      COMP_INDEX("compIndexTest"),
34      DEL_COL("delColTest"),
35      DEL("delTest"),
36      FIXED_NUMERIC("fixedNumericTest"),
37      FIXED_TEXT("fixedTextTest"),
38      INDEX_CURSOR("indexCursorTest"),
39      INDEX("indexTest"),
40      OVERFLOW("overflowTest"),
41      QUERY("queryTest"),
42      TEST("test"),
43      TEST2("test2"),
44      INDEX_CODES("testIndexCodes"),
45      INDEX_PROPERTIES("testIndexProperties"),
46      PROMOTION("testPromotion"),
47      COMPLEX("complexDataTest"),
48      UNSUPPORTED("unsupportedFieldsTest"),
49      LINKED("linkerTest"),
50      BLOB("testOle"),
51      CALC_FIELD("calcFieldTest"),
52      BINARY_INDEX("binIdxTest"),
53      OLD_DATES("oldDates");
54  
55      private final String _basename;
56  
57      Basename(String fileBasename) {
58        _basename = fileBasename;
59      }
60  
61      @Override
62      public String toString() { return _basename; }
63    }
64  
65    /** Defines currently supported db file formats.  (can be modified at
66        runtime via the system property
67        "com.healthmarketscience.jackcess.testFormats") */
68    public final static FileFormat[] SUPPORTED_FILEFORMATS;
69    public final static FileFormat[] SUPPORTED_FILEFORMATS_FOR_READ;
70  
71    static {
72      String testFormatStr = System.getProperty("com.healthmarketscience.jackcess.testFormats");
73      Set<FileFormat> testFormats = EnumSet.allOf(FileFormat.class);
74      if((testFormatStr != null) && (testFormatStr.length() > 0)) {
75        testFormats.clear();
76        for(String tmp : testFormatStr.split(",")) {
77          testFormats.add(FileFormat.valueOf(tmp.toUpperCase()));
78        }
79      }
80  
81      List<FileFormat> supported = new ArrayList<FileFormat>();
82      List<FileFormat> supportedForRead = new ArrayList<FileFormat>();
83      for(FileFormat ff : FileFormat.values()) {
84        if(!testFormats.contains(ff)) {
85          continue;
86        }
87        supportedForRead.add(ff);
88        if(DatabaseImpl.getFileFormatDetails(ff).getFormat().READ_ONLY ||
89           (ff == FileFormat.MSISAM)) {
90          continue;
91        }
92        supported.add(ff);
93      }
94  
95      SUPPORTED_FILEFORMATS = supported.toArray(new FileFormat[0]);
96      SUPPORTED_FILEFORMATS_FOR_READ = 
97        supportedForRead.toArray(new FileFormat[0]);
98    }
99  
100   /**
101    * Defines known valid test database files, and their jet format version.
102    */
103   public static final class TestDB {
104 
105     private final File dbFile;
106     private final FileFormat expectedFileFormat;
107 
108     private TestDB(File databaseFile, 
109                    FileFormat expectedDBFileFormat) {
110 
111       dbFile = databaseFile;
112       expectedFileFormat = expectedDBFileFormat;
113     }
114 
115     public final File getFile() { return dbFile; }
116 
117     public final FileFormat  getExpectedFileFormat() { 
118       return expectedFileFormat; 
119     }
120 
121     public final JetFormat getExpectedFormat() { 
122       return DatabaseImpl.getFileFormatDetails(expectedFileFormat).getFormat(); 
123     }
124 
125     @Override
126     public final String toString() {
127       return "dbFile: " + dbFile.getAbsolutePath()
128         + "; expectedFileFormat: " + expectedFileFormat;
129     }
130 
131     public static List<TestDB> getSupportedForBasename(Basename basename) {
132       return getSupportedForBasename(basename, false);
133     }
134 
135     public static List<TestDB> getSupportedForBasename(Basename basename,
136                                                        boolean readOnly) {
137 
138       List<TestDB> supportedTestDBs = new ArrayList<TestDB>();
139       for (FileFormat fileFormat : 
140              (readOnly ? SUPPORTED_FILEFORMATS_FOR_READ :
141               SUPPORTED_FILEFORMATS)) {
142         File testFile = getFileForBasename(basename, fileFormat);
143         if(!testFile.exists()) {
144           continue;
145         }
146         
147         // verify that the db is the file format expected
148         try {
149           Database db = new DatabaseBuilder(testFile).setReadOnly(true).open();
150           FileFormat dbFileFormat = db.getFileFormat();
151           db.close();
152           if(dbFileFormat != fileFormat) {
153             throw new IllegalStateException("Expected " + fileFormat +
154                                             " was " + dbFileFormat);
155           }
156         } catch(Exception e) {
157           throw new RuntimeException(e);
158         }
159 
160         supportedTestDBs.add(new TestDB(testFile, fileFormat));
161       }
162       return supportedTestDBs;
163     }
164 
165     private static File getFileForBasename(
166         Basename basename, FileFormat fileFormat) {
167 
168       return new File(DIR_TEST_DATA, 
169                       fileFormat.name() + File.separator +
170                       basename + fileFormat.name() + 
171                       fileFormat.getFileExtension());
172     }
173   }
174 
175   public static final List<TestDB> SUPPORTED_DBS_TEST = 
176     TestDB.getSupportedForBasename(Basename.TEST);
177   public static final List<TestDB> SUPPORTED_DBS_TEST_FOR_READ = 
178     TestDB.getSupportedForBasename(Basename.TEST, true);
179 
180 
181   public void testGetFormat() throws Exception {
182     try {
183       JetFormat.getFormat(null);
184       fail("npe");
185     } catch (NullPointerException e) {
186       // success
187     }
188 
189     for (final TestDB testDB : SUPPORTED_DBS_TEST_FOR_READ) {
190 
191       final FileChannel channel = DatabaseImpl.openChannel(testDB.dbFile, false);
192       try {
193 
194         JetFormat fmtActual = JetFormat.getFormat(channel);
195         assertEquals("Unexpected JetFormat for dbFile: " + 
196                      testDB.dbFile.getAbsolutePath(),
197                      testDB.getExpectedFormat(), fmtActual);
198 
199       } finally {
200         channel.close();
201       }
202 
203     }
204   }
205 
206   public void testReadOnlyFormat() throws Exception {
207 
208     for (final TestDB testDB : SUPPORTED_DBS_TEST_FOR_READ) {
209 
210       Database db = null;
211       IOException failure = null;
212       try {
213         db = openCopy(testDB);
214       } catch(IOException e) {
215         failure = e;
216       } finally {
217         if(db != null) {
218           db.close();
219         }
220       }
221 
222       if(!testDB.getExpectedFormat().READ_ONLY) {
223         assertNull(failure);
224       } else {
225         assertTrue(failure.getMessage().contains("does not support writing"));
226       }
227 
228     }
229   }
230 
231   public void testFileFormat() throws Exception {
232 
233     for (final TestDB testDB : SUPPORTED_DBS_TEST_FOR_READ) {
234 
235       Database db = null;
236       try {
237         db = open(testDB);
238         assertEquals(testDB.getExpectedFileFormat(), db.getFileFormat());
239       } finally {
240         if(db != null) {
241           db.close();
242         }
243       }
244     }
245 
246     Database db = null;
247     try {
248       db = open(Database.FileFormat.GENERIC_JET4,
249                 new File(DIR_TEST_DATA, "adox_jet4.mdb"));
250       assertEquals(Database.FileFormat.GENERIC_JET4, db.getFileFormat());
251     } finally {
252       if(db != null) {
253         db.close();
254       }
255     }
256   }
257 
258 }