]> source.dussan.org Git - jackcess.git/commitdiff
merge branch newformats changes through r453
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 26 Mar 2010 12:42:12 +0000 (12:42 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 26 Mar 2010 12:42:12 +0000 (12:42 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@454 f203690c-595d-4dc9-a70b-905162fa7fd2

84 files changed:
CREDITS.txt
pom.xml
project.xml
src/java/com/healthmarketscience/jackcess/ByteUtil.java
src/java/com/healthmarketscience/jackcess/Database.java
src/java/com/healthmarketscience/jackcess/Index.java
src/java/com/healthmarketscience/jackcess/JetFormat.java
src/java/com/healthmarketscience/jackcess/PageChannel.java
src/java/com/healthmarketscience/jackcess/UsageMap.java
src/resources/com/healthmarketscience/jackcess/empty2003.mdb [new file with mode: 0644]
src/resources/com/healthmarketscience/jackcess/empty2007.accdb [new file with mode: 0644]
test/data/V1997/testV1997.mdb [new file with mode: 0644]
test/data/V2000/bigIndexTestV2000.mdb [new file with mode: 0644]
test/data/V2000/compIndexTestV2000.mdb [new file with mode: 0644]
test/data/V2000/delColTestV2000.mdb [new file with mode: 0644]
test/data/V2000/delTestV2000.mdb [new file with mode: 0644]
test/data/V2000/fixedNumericTestV2000.mdb [new file with mode: 0644]
test/data/V2000/fixedTextTestV2000.mdb [new file with mode: 0755]
test/data/V2000/indexCursorTestV2000.mdb [new file with mode: 0644]
test/data/V2000/indexTestV2000.mdb [new file with mode: 0644]
test/data/V2000/overflowTestV2000.mdb [new file with mode: 0644]
test/data/V2000/queryTestV2000.mdb [new file with mode: 0755]
test/data/V2000/test2V2000.mdb [new file with mode: 0644]
test/data/V2000/testIndexCodesV2000.mdb [new file with mode: 0644]
test/data/V2000/testIndexPropertiesV2000.mdb [new file with mode: 0644]
test/data/V2000/testPromotionV2000.mdb [new file with mode: 0644]
test/data/V2000/testV2000.mdb [new file with mode: 0644]
test/data/V2003/bigIndexTestV2003.mdb [new file with mode: 0644]
test/data/V2003/compIndexTestV2003.mdb [new file with mode: 0644]
test/data/V2003/delColTestV2003.mdb [new file with mode: 0644]
test/data/V2003/delTestV2003.mdb [new file with mode: 0644]
test/data/V2003/fixedNumericTestV2003.mdb [new file with mode: 0644]
test/data/V2003/fixedTextTestV2003.mdb [new file with mode: 0644]
test/data/V2003/indexCursorTestV2003.mdb [new file with mode: 0644]
test/data/V2003/indexTestV2003.mdb [new file with mode: 0644]
test/data/V2003/overflowTestV2003.mdb [new file with mode: 0644]
test/data/V2003/queryTestV2003.mdb [new file with mode: 0644]
test/data/V2003/test2V2003.mdb [new file with mode: 0644]
test/data/V2003/testIndexCodesV2003.mdb [new file with mode: 0644]
test/data/V2003/testIndexPropertiesV2003.mdb [new file with mode: 0644]
test/data/V2003/testPromotionV2003.mdb [new file with mode: 0644]
test/data/V2003/testV2003.mdb [new file with mode: 0644]
test/data/V2007/bigIndexTestV2007.accdb [new file with mode: 0644]
test/data/V2007/compIndexTestV2007.accdb [new file with mode: 0644]
test/data/V2007/delColTestV2007.accdb [new file with mode: 0644]
test/data/V2007/delTestV2007.accdb [new file with mode: 0644]
test/data/V2007/fixedNumericTestV2007.accdb [new file with mode: 0644]
test/data/V2007/fixedTextTestV2007.accdb [new file with mode: 0644]
test/data/V2007/indexCursorTestV2007.accdb [new file with mode: 0644]
test/data/V2007/indexTestV2007.accdb [new file with mode: 0644]
test/data/V2007/overflowTestV2007.accdb [new file with mode: 0644]
test/data/V2007/queryTestV2007.accdb [new file with mode: 0644]
test/data/V2007/test2V2007.accdb [new file with mode: 0644]
test/data/V2007/testIndexCodesV2007.accdb [new file with mode: 0644]
test/data/V2007/testIndexPropertiesV2007.accdb [new file with mode: 0644]
test/data/V2007/testPromotionV2007.accdb [new file with mode: 0644]
test/data/V2007/testV2007.accdb [new file with mode: 0644]
test/data/bigIndexTest.mdb [deleted file]
test/data/compIndexTest.mdb [deleted file]
test/data/delColTest.mdb [deleted file]
test/data/delTest.mdb [deleted file]
test/data/fixedNumericTest.mdb [deleted file]
test/data/fixedTextTest.mdb [deleted file]
test/data/indexCursorTest.mdb [deleted file]
test/data/indexTest.mdb [deleted file]
test/data/overflowTest.mdb [deleted file]
test/data/queryTest.mdb [deleted file]
test/data/test.mdb [deleted file]
test/data/test2.mdb [deleted file]
test/data/testIndexCodes.mdb [deleted file]
test/data/testIndexProperties.mdb [deleted file]
test/data/testPromotion.mdb [deleted file]
test/src/java/com/healthmarketscience/jackcess/BigIndexTest.java
test/src/java/com/healthmarketscience/jackcess/CursorBuilderTest.java
test/src/java/com/healthmarketscience/jackcess/CursorTest.java
test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java
test/src/java/com/healthmarketscience/jackcess/ErrorHandlerTest.java
test/src/java/com/healthmarketscience/jackcess/ImportTest.java
test/src/java/com/healthmarketscience/jackcess/IndexCodesTest.java
test/src/java/com/healthmarketscience/jackcess/IndexTest.java
test/src/java/com/healthmarketscience/jackcess/JetFormatTest.java [new file with mode: 0644]
test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java
test/src/java/com/healthmarketscience/jackcess/UsageMapTest.java [new file with mode: 0644]
test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java

index 78b627bad52baf18564f8709dae91cdb621fdb6d..f52f6e396061b0d2d7024fd3b68ea440f2242743 100644 (file)
@@ -5,3 +5,4 @@ James Ahlborn - Added support for NUMERIC data type
 Jon Iles - Added support for reading table definitions that span multiple pages
 James Schopp - added support for reading currency columns
 Patricia Donaldson - contributed RowFilter class
+Dan Rollo - added support for new DB file formats
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1822121f628eaf082e3d711bf60b42543508a18b..d3828a469cb1b0148e1e9df781ccd34487057775 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,7 @@
       <name>Dan Rollo</name>
       <id>bhamail</id>
       <email>bhamail@users.sf.net</email>
+      <organization>Composite Software, Inc.</organization>
       <timezone>-5</timezone>
     </developer>
   </developers>
index d7627f064a7a0150c3ae2f9eece86ea8160b8174..fa5f6c7b488bab36205ec537def7943b36aecd45 100644 (file)
       <organization>Health Market Science, Inc.</organization>
       <timezone>-5</timezone>
     </developer>
+    <developer>
+      <name>Dan Rollo</name>
+      <id>bhamail</id>
+      <email>bhamail@users.sf.net</email>
+      <organization>Composite Software, Inc.</organization>
+      <timezone>-5</timezone>
+    </developer>
   </developers>
   <licenses>
     <license>
index 701369561294471af443328adb9e7ecf2a4276bd..fbb152138adffd3f6419c93cb527aef8a4c740f9 100644 (file)
@@ -308,6 +308,23 @@ public final class ByteUtil {
     }
     return true;
   }
+
+  /**
+   * Searches for a pattern of bytes in the given buffer starting at the
+   * given offset.
+   * @return the offset of the pattern if a match is found, -1 otherwise
+   */
+  public static int findRange(ByteBuffer buffer, int start, byte[] pattern)
+  {
+    byte firstByte = pattern[0];
+    int limit = buffer.limit() - pattern.length;
+    for(int i = start; i < limit; ++i) {
+      if((firstByte == buffer.get(i)) && matchesRange(buffer, i, pattern)) {
+        return i;
+      }
+    }
+    return -1;
+  }
   
   /**
    * Convert a byte buffer to a hexadecimal string for display
index 8609b65cc422a103252f0d3d425fff4c5d19b4ac..5044de72bce625f6ccf0c5423ec146173f852a38 100644 (file)
@@ -168,9 +168,38 @@ public class Database
   private static final String CAT_COL_DATE_UPDATE = "DateUpdate";
   /** System catalog column name of the flags column */
   private static final String CAT_COL_FLAGS = "Flags";
+  /** System catalog column name of the properties column */
+  private static final String CAT_COL_PROPS = "LvProp";
   
-  /** Empty database template for creating new databases */
-  private static final String EMPTY_MDB = "com/healthmarketscience/jackcess/empty.mdb";
+  public static enum FileFormat {
+
+    V1997(null, JetFormat.VERSION_3), // v97 is not supported, so no empty template is provided
+    V2000("com/healthmarketscience/jackcess/empty.mdb", JetFormat.VERSION_4),
+    V2003("com/healthmarketscience/jackcess/empty2003.mdb", JetFormat.VERSION_4),
+    V2007("com/healthmarketscience/jackcess/empty2007.accdb", JetFormat.VERSION_5, ".accdb");
+
+    private final String _emptyFile;
+    private final JetFormat _format;
+    private final String _ext;
+
+    private FileFormat(String emptyDBFile, JetFormat jetFormat) {
+      this(emptyDBFile, jetFormat, ".mdb");
+    }
+
+    private FileFormat(String emptyDBFile, JetFormat jetFormat, String ext) {
+      _emptyFile = emptyDBFile;
+      _format = jetFormat;
+      _ext = ext;
+    }
+
+    public JetFormat getJetFormat() { return _format; }
+
+    public String getFileExtension() { return _ext; }
+
+    @Override
+    public String toString() { return name() + ", jetFormat: " + getJetFormat(); }
+  }
+
   /** Prefix for column or table names that are reserved words */
   private static final String ESCAPE_PREFIX = "x";
   /** Prefix that flags system tables */
@@ -183,6 +212,8 @@ public class Database
   private static final String TABLE_SYSTEM_RELATIONSHIPS = "MSysRelationships";
   /** Name of the table that contains queries */
   private static final String TABLE_SYSTEM_QUERIES = "MSysQueries";
+  /** Name of the table that contains queries */
+  private static final String OBJECT_NAME_DBPROPS = "MSysDb";
   /** System object type for table definitions */
   private static final Short TYPE_TABLE = (short) 1;
   /** System object type for query definitions */
@@ -269,6 +300,8 @@ public class Database
   private boolean _useBigIndex;
   /** optional error handler to use when row errors are encountered */
   private ErrorHandler _dbErrorHandler;
+  /** the file format of the database */
+  private FileFormat _fileFormat;
   
   /**
    * Open an existing Database.  If the existing file is not writeable, the
@@ -329,14 +362,14 @@ public class Database
     }
     return new Database(openChannel(mdbFile,
                                     (!mdbFile.canWrite() || readOnly)),
-                        autoSync);
+                        autoSync, null);
   }
   
   /**
-   * Create a new Database
+   * Create a new Access 2000 Database 
    * <p>
    * Equivalent to:
-   * {@code  create(mdbFile, DEFAULT_AUTO_SYNC);}
+   * {@code  create(FileFormat.V2000, mdbFile, DEFAULT_AUTO_SYNC);}
    * 
    * @param mdbFile Location to write the new database to.  <b>If this file
    *    already exists, it will be overwritten.</b>
@@ -348,7 +381,29 @@ public class Database
   }
   
   /**
-   * Create a new Database
+   * Create a new Database for the given fileFormat
+   * <p>
+   * Equivalent to:
+   * {@code  create(fileFormat, mdbFile, DEFAULT_AUTO_SYNC);}
+   * 
+   * @param fileFormat version of new database.
+   * @param mdbFile Location to write the new database to.  <b>If this file
+   *    already exists, it will be overwritten.</b>
+   *
+   * @see #create(File,boolean)
+   */
+  public static Database create(FileFormat fileFormat, File mdbFile) 
+    throws IOException 
+  {
+    return create(fileFormat, mdbFile, DEFAULT_AUTO_SYNC);
+  }
+  
+  /**
+   * Create a new Access 2000 Database
+   * <p>
+   * Equivalent to:
+   * {@code  create(FileFormat.V2000, mdbFile, DEFAULT_AUTO_SYNC);}
+   * 
    * @param mdbFile Location to write the new database to.  <b>If this file
    *    already exists, it will be overwritten.</b>
    * @param autoSync whether or not to enable auto-syncing on write.  if
@@ -362,19 +417,53 @@ public class Database
    */
   public static Database create(File mdbFile, boolean autoSync)
     throws IOException
-  {    
+  {
+    return create(FileFormat.V2000, mdbFile, autoSync);
+  }
+
+  /**
+   * Create a new Database for the given fileFormat
+   * @param fileFormat version of new database.
+   * @param mdbFile Location to write the new database to.  <b>If this file
+   *    already exists, it will be overwritten.</b>
+   * @param autoSync whether or not to enable auto-syncing on write.  if
+   *                 {@code true}, writes will be immediately flushed to disk.
+   *                 This leaves the database in a (fairly) consistent state
+   *                 on each write, but can be very inefficient for many
+   *                 updates.  if {@code false}, flushing to disk happens at
+   *                 the jvm's leisure, which can be much faster, but may
+   *                 leave the database in an inconsistent state if failures
+   *                 are encountered during writing.
+   */
+  public static Database create(FileFormat fileFormat, File mdbFile, 
+                                boolean autoSync)
+    throws IOException
+  {
     FileChannel channel = openChannel(mdbFile, false);
     channel.truncate(0);
     channel.transferFrom(Channels.newChannel(
         Thread.currentThread().getContextClassLoader().getResourceAsStream(
-            EMPTY_MDB)), 0, Integer.MAX_VALUE);
-    return new Database(channel, autoSync);
+            fileFormat._emptyFile)), 0, Integer.MAX_VALUE);
+    return new Database(channel, autoSync, fileFormat);
   }
-  
-  private static FileChannel openChannel(File mdbFile, boolean readOnly)
+
+  /**
+   * Package visible only to support unit tests via DatabaseTest.openChannel().
+   * @param mdbFile file to open
+   * @param readOnly true if read-only
+   * @return a FileChannel on the given file.
+   * @exception FileNotFoundException
+   *            if the mode is <tt>"r"</tt> but the given file object does
+   *            not denote an existing regular file, or if the mode begins
+   *            with <tt>"rw"</tt> but the given file object does not denote
+   *            an existing, writable regular file and a new regular file of
+   *            that name cannot be created, or if some other error occurs
+   *            while opening or creating the file
+   */
+  static FileChannel openChannel(final File mdbFile, final boolean readOnly)
     throws FileNotFoundException
   {
-    String mode = (readOnly ? "r" : "rw");
+    final String mode = (readOnly ? "r" : "rw");
     return new RandomAccessFile(mdbFile, mode).getChannel();
   }
   
@@ -384,9 +473,12 @@ public class Database
    *    FileChannel instead of a ReadableByteChannel because we need to
    *    randomly jump around to various points in the file.
    */
-  protected Database(FileChannel channel, boolean autoSync) throws IOException
+  protected Database(FileChannel channel, boolean autoSync, 
+                     FileFormat fileFormat)
+    throws IOException
   {
     _format = JetFormat.getFormat(channel);
+    _fileFormat = fileFormat;
     _pageChannel = new PageChannel(channel, _format, autoSync);
     // note, it's slighly sketchy to pass ourselves along partially
     // constructed, but only our _format and _pageChannel refs should be
@@ -449,6 +541,59 @@ public class Database
   public void setErrorHandler(ErrorHandler newErrorHandler) {
     _dbErrorHandler = newErrorHandler;
   }    
+
+  /**
+   * Returns the FileFormat of this database (which may involve inspecting the
+   * database itself).
+   * @throws IllegalStateException if the file format cannot be determined
+   */
+  public FileFormat getFileFormat()
+  {
+    if(_fileFormat == null) {
+
+      Map<Database.FileFormat,byte[]> possibleFileFormats =
+        getFormat().getPossibleFileFormats();
+
+      if(possibleFileFormats.size() == 1) {
+
+        // single possible format, easy enough
+        _fileFormat = possibleFileFormats.keySet().iterator().next();
+
+      } else {
+
+        // need to check the "AccessVersion" property
+        byte[] dbProps = null;
+        for(Map<String,Object> row :
+              Cursor.createCursor(_systemCatalog).iterable(
+                  Arrays.asList(CAT_COL_NAME, CAT_COL_PROPS))) {
+          if(OBJECT_NAME_DBPROPS.equals(row.get(CAT_COL_NAME))) {
+            dbProps = (byte[])row.get(CAT_COL_PROPS);
+            break;
+          }
+        }
+        
+        if(dbProps != null) {
+
+          // search for certain "version strings" in the properties (we
+          // can't fully parse the properties objects, but we can still
+          // find the byte pattern)
+          ByteBuffer dbPropBuf = ByteBuffer.wrap(dbProps);
+          for(Map.Entry<Database.FileFormat,byte[]> possible : 
+                possibleFileFormats.entrySet()) {
+            if(ByteUtil.findRange(dbPropBuf, 0, possible.getValue()) >= 0) {
+              _fileFormat = possible.getKey();
+              break;
+            }
+          }
+        }
+        
+        if(_fileFormat == null) {
+          throw new IllegalStateException("Could not determine FileFormat");
+        }
+      }
+    }
+    return _fileFormat;
+  }
   
   /**
    * Read the system catalog
index b629049ea756bbd33d13041298c8be3624700113..a2921e4341715463cc503bad7afa77ca0d1710ad 100644 (file)
@@ -1540,17 +1540,31 @@ public abstract class Index implements Comparable<Index> {
       boolean isNegative = ((valueBytes[0] & 0x80) != 0);
 
       // bit twiddling rules:
-      // isAsc && !isNeg => setReverseSignByte
-      // isAsc && isNeg => flipBytes, setReverseSignByte
-      // !isAsc && !isNeg => flipBytes, setReverseSignByte
-      // !isAsc && isNeg => setReverseSignByte
+      // isAsc && !isNeg => setReverseSignByte             => FF 00 00 ...
+      // isAsc && isNeg => flipBytes, setReverseSignByte   => 00 FF FF ...
+      // !isAsc && !isNeg => flipBytes, setReverseSignByte => FF FF FF ...
+      // !isAsc && isNeg => setReverseSignByte             => 00 00 00 ...
       
+      // v2007 bit twiddling rules (old ordering was a bug, MS kb 837148):
+      // isAsc && !isNeg => setSignByte 0xFF            => FF 00 00 ...
+      // isAsc && isNeg => setSignByte 0xFF, flipBytes  => 00 FF FF ...
+      // !isAsc && !isNeg => setSignByte 0xFF           => FF 00 00 ...
+      // !isAsc && isNeg => setSignByte 0xFF, flipBytes => 00 FF FF ...
+
+      boolean alwaysRevFirstByte = getColumn().getFormat().REVERSE_FIRST_BYTE_IN_DESC_NUMERIC_INDEXES;
+      if(alwaysRevFirstByte) {
+        // reverse the sign byte (before any byte flipping)
+        valueBytes[0] = (byte)0xFF;
+      }
+
       if(isNegative == isAscending()) {
         flipBytes(valueBytes);
       }
 
-      // reverse the sign byte (after any previous byte flipping)
-      valueBytes[0] = (isNegative ? (byte)0x00 : (byte)0xFF);
+      if(!alwaysRevFirstByte) {
+        // reverse the sign byte (after any previous byte flipping)
+        valueBytes[0] = (isNegative ? (byte)0x00 : (byte)0xFF);
+      }
       
       bout.write(valueBytes);
     }    
index 38b4bc52a86af7e2d677b1a5d7b6ff206ea65985..f5cc175f0bfd946dff0784c8324995e2224c333a 100644 (file)
@@ -31,6 +31,9 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.Map;
 
 /**
  * Encapsulates constants describing a specific version of the Access Jet format
@@ -46,12 +49,41 @@ public abstract class JetFormat {
   /** Maximum size of a text field */
   public static final short TEXT_FIELD_MAX_LENGTH = 255 * TEXT_FIELD_UNIT_SIZE;
   
-  /** Offset in the file that holds the byte describing the Jet format version */
+  /** Offset in the file that holds the byte describing the Jet format
+      version */
   private static final long OFFSET_VERSION = 20L;
   /** Version code for Jet version 3 */
   private static final byte CODE_VERSION_3 = 0x0;
   /** Version code for Jet version 4 */
   private static final byte CODE_VERSION_4 = 0x1;
+  /** Version code for Jet version 5 */
+  private static final byte CODE_VERSION_5 = 0x2;
+
+  /** value of the "AccessVersion" property for access 2000 dbs:
+      {@code "08.50"} */
+  private static final byte[] ACCESS_VERSION_2000 = new byte[] {
+    '0', 0, '8', 0, '.', 0, '5', 0, '0', 0};
+  /** value of the "AccessVersion" property for access 2002/2003 dbs
+      {@code "09.50"}  */
+  private static final byte[] ACCESS_VERSION_2003 = new byte[] {
+    '0', 0, '9', 0, '.', 0, '5', 0, '0', 0};
+
+  // use nested inner class to avoid problematic static init loops
+  private static final class PossibleFileFormats {
+    private static final Map<Database.FileFormat,byte[]> POSSIBLE_VERSION_3 = 
+      Collections.singletonMap(Database.FileFormat.V1997, (byte[])null);
+
+    private static final Map<Database.FileFormat,byte[]> POSSIBLE_VERSION_4 = 
+      new EnumMap<Database.FileFormat,byte[]>(Database.FileFormat.class);
+
+    private static final Map<Database.FileFormat,byte[]> POSSIBLE_VERSION_5 = 
+      Collections.singletonMap(Database.FileFormat.V2007, (byte[])null);
+
+    static {
+      POSSIBLE_VERSION_4.put(Database.FileFormat.V2000, ACCESS_VERSION_2000);
+      POSSIBLE_VERSION_4.put(Database.FileFormat.V2003, ACCESS_VERSION_2003);
+    }
+  }
 
   //These constants are populated by this class's constructor.  They can't be
   //populated by the subclass's constructor because they are final, and Java
@@ -128,13 +160,19 @@ public abstract class JetFormat {
   public final int MAX_TABLE_NAME_LENGTH;
   public final int MAX_COLUMN_NAME_LENGTH;
   public final int MAX_INDEX_NAME_LENGTH;
+
+  public final boolean REVERSE_FIRST_BYTE_IN_DESC_NUMERIC_INDEXES;
   
   public final Charset CHARSET;
   
+  public static final JetFormat VERSION_3 = new Jet3Format();
   public static final JetFormat VERSION_4 = new Jet4Format();
+  public static final JetFormat VERSION_5 = new Jet5Format();
 
   /**
+   * @param channel the database file.
    * @return The Jet Format represented in the passed-in file
+   * @throws IOException if the database file format is unsupported.
    */
   public static JetFormat getFormat(FileChannel channel) throws IOException {
     ByteBuffer buffer = ByteBuffer.allocate(1);
@@ -144,8 +182,12 @@ public abstract class JetFormat {
     }
     buffer.flip();
     byte version = buffer.get();
-    if (version == CODE_VERSION_4) {
+    if (version == CODE_VERSION_3) {
+      return VERSION_3;
+    } else if (version == CODE_VERSION_4) {
       return VERSION_4;
+    } else if (version == CODE_VERSION_5) {
+      return VERSION_5;
     }
     throw new IOException("Unsupported version: " + version);
   }
@@ -220,7 +262,8 @@ public abstract class JetFormat {
     MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength();
     MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength();
     MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength();
-
+    
+    REVERSE_FIRST_BYTE_IN_DESC_NUMERIC_INDEXES = defineReverseFirstByteInDescNumericIndexes();
     
     CHARSET = defineCharset();
   }
@@ -295,15 +338,23 @@ public abstract class JetFormat {
   
   protected abstract Charset defineCharset();
 
+  protected abstract boolean defineReverseFirstByteInDescNumericIndexes();
+
+  protected abstract Map<Database.FileFormat,byte[]> getPossibleFileFormats();
+
   @Override
   public String toString() {
     return _name;
   }
   
-  private static final class Jet4Format extends JetFormat {
+  private static class Jet4Format extends JetFormat {
 
     private Jet4Format() {
-      super("VERSION_4");
+      this("VERSION_4");
+    }
+
+    private Jet4Format(final String name) {
+      super(name);
     }
 
     @Override
@@ -434,8 +485,44 @@ public abstract class JetFormat {
     @Override
     protected int defineMaxIndexNameLength() { return 64; }
       
+    @Override
+    protected boolean defineReverseFirstByteInDescNumericIndexes() { return false; }
+
     @Override
     protected Charset defineCharset() { return Charset.forName("UTF-16LE"); }
+
+    @Override
+    protected Map<Database.FileFormat,byte[]> getPossibleFileFormats()
+    {
+      return PossibleFileFormats.POSSIBLE_VERSION_4;
+    }
+
   }
   
+  private static final class Jet3Format extends Jet4Format {
+      private Jet3Format() {
+        super("VERSION_3");
+      }
+
+    @Override
+    protected Map<Database.FileFormat,byte[]> getPossibleFileFormats() {
+      return PossibleFileFormats.POSSIBLE_VERSION_3;
+    }
+
+  }
+
+  private static final class Jet5Format extends Jet4Format {
+      private Jet5Format() {
+        super("VERSION_5");
+      }
+
+    @Override
+    protected boolean defineReverseFirstByteInDescNumericIndexes() { return true; }
+
+    @Override
+    protected Map<Database.FileFormat,byte[]> getPossibleFileFormats() {
+      return PossibleFileFormats.POSSIBLE_VERSION_5;
+    }
+  }
+
 }
index 8adf74bef9ac0106e1d8f0650205f0370cc5b65e..e72bcd74a34d5da73db366f87175058273e14462 100644 (file)
@@ -56,9 +56,9 @@ public class PageChannel implements Channel, Flushable {
     new byte[]{PageTypes.INVALID, (byte)0, (byte)0, (byte)0};
   
   /** Global usage map always lives on page 1 */
-  private static final int PAGE_GLOBAL_USAGE_MAP = 1;
+  static final int PAGE_GLOBAL_USAGE_MAP = 1;
   /** Global usage map always lives at row 0 */
-  private static final int ROW_GLOBAL_USAGE_MAP = 0;
+  static final int ROW_GLOBAL_USAGE_MAP = 0;
   
   /** Channel containing the database */
   private final FileChannel _channel;
index 6495f0ca979f856e1d5053b181d832e8e8bb8e3d..5e6ec1ed8f665f51bb333eefd622c8bbe38f63a4 100644 (file)
@@ -72,8 +72,11 @@ public class UsageMap
   /** the current handler implementation for reading/writing the specific
       usage map type.  note, this may change over time. */
   private Handler _handler;
-  
-  /**
+
+  /** Error message prefix used when map type is unrecognized. */
+  static final String MSG_PREFIX_UNRECOGNIZED_MAP = "Unrecognized map type: ";
+
+    /**
    * @param database database that contains this usage map
    * @param tableBuffer Buffer that contains this map's declaration
    * @param pageNum Page number that this usage map is contained in
@@ -139,7 +142,7 @@ public class UsageMap
     } else if (mapType == MAP_TYPE_REFERENCE) {
       _handler = new ReferenceHandler();
     } else {
-      throw new IOException("Unrecognized map type: " + mapType);
+      throw new IOException(MSG_PREFIX_UNRECOGNIZED_MAP + mapType);
     }
   }
   
diff --git a/src/resources/com/healthmarketscience/jackcess/empty2003.mdb b/src/resources/com/healthmarketscience/jackcess/empty2003.mdb
new file mode 100644 (file)
index 0000000..5c48a3d
Binary files /dev/null and b/src/resources/com/healthmarketscience/jackcess/empty2003.mdb differ
diff --git a/src/resources/com/healthmarketscience/jackcess/empty2007.accdb b/src/resources/com/healthmarketscience/jackcess/empty2007.accdb
new file mode 100644 (file)
index 0000000..95b32f8
Binary files /dev/null and b/src/resources/com/healthmarketscience/jackcess/empty2007.accdb differ
diff --git a/test/data/V1997/testV1997.mdb b/test/data/V1997/testV1997.mdb
new file mode 100644 (file)
index 0000000..2aa1060
Binary files /dev/null and b/test/data/V1997/testV1997.mdb differ
diff --git a/test/data/V2000/bigIndexTestV2000.mdb b/test/data/V2000/bigIndexTestV2000.mdb
new file mode 100644 (file)
index 0000000..abbb14d
Binary files /dev/null and b/test/data/V2000/bigIndexTestV2000.mdb differ
diff --git a/test/data/V2000/compIndexTestV2000.mdb b/test/data/V2000/compIndexTestV2000.mdb
new file mode 100644 (file)
index 0000000..b93db5b
Binary files /dev/null and b/test/data/V2000/compIndexTestV2000.mdb differ
diff --git a/test/data/V2000/delColTestV2000.mdb b/test/data/V2000/delColTestV2000.mdb
new file mode 100644 (file)
index 0000000..b931b0d
Binary files /dev/null and b/test/data/V2000/delColTestV2000.mdb differ
diff --git a/test/data/V2000/delTestV2000.mdb b/test/data/V2000/delTestV2000.mdb
new file mode 100644 (file)
index 0000000..915caa2
Binary files /dev/null and b/test/data/V2000/delTestV2000.mdb differ
diff --git a/test/data/V2000/fixedNumericTestV2000.mdb b/test/data/V2000/fixedNumericTestV2000.mdb
new file mode 100644 (file)
index 0000000..e329181
Binary files /dev/null and b/test/data/V2000/fixedNumericTestV2000.mdb differ
diff --git a/test/data/V2000/fixedTextTestV2000.mdb b/test/data/V2000/fixedTextTestV2000.mdb
new file mode 100755 (executable)
index 0000000..87de103
Binary files /dev/null and b/test/data/V2000/fixedTextTestV2000.mdb differ
diff --git a/test/data/V2000/indexCursorTestV2000.mdb b/test/data/V2000/indexCursorTestV2000.mdb
new file mode 100644 (file)
index 0000000..561c44c
Binary files /dev/null and b/test/data/V2000/indexCursorTestV2000.mdb differ
diff --git a/test/data/V2000/indexTestV2000.mdb b/test/data/V2000/indexTestV2000.mdb
new file mode 100644 (file)
index 0000000..7e8bd98
Binary files /dev/null and b/test/data/V2000/indexTestV2000.mdb differ
diff --git a/test/data/V2000/overflowTestV2000.mdb b/test/data/V2000/overflowTestV2000.mdb
new file mode 100644 (file)
index 0000000..f84a517
Binary files /dev/null and b/test/data/V2000/overflowTestV2000.mdb differ
diff --git a/test/data/V2000/queryTestV2000.mdb b/test/data/V2000/queryTestV2000.mdb
new file mode 100755 (executable)
index 0000000..4560710
Binary files /dev/null and b/test/data/V2000/queryTestV2000.mdb differ
diff --git a/test/data/V2000/test2V2000.mdb b/test/data/V2000/test2V2000.mdb
new file mode 100644 (file)
index 0000000..8da9633
Binary files /dev/null and b/test/data/V2000/test2V2000.mdb differ
diff --git a/test/data/V2000/testIndexCodesV2000.mdb b/test/data/V2000/testIndexCodesV2000.mdb
new file mode 100644 (file)
index 0000000..f884d4a
Binary files /dev/null and b/test/data/V2000/testIndexCodesV2000.mdb differ
diff --git a/test/data/V2000/testIndexPropertiesV2000.mdb b/test/data/V2000/testIndexPropertiesV2000.mdb
new file mode 100644 (file)
index 0000000..bb1c158
Binary files /dev/null and b/test/data/V2000/testIndexPropertiesV2000.mdb differ
diff --git a/test/data/V2000/testPromotionV2000.mdb b/test/data/V2000/testPromotionV2000.mdb
new file mode 100644 (file)
index 0000000..901c520
Binary files /dev/null and b/test/data/V2000/testPromotionV2000.mdb differ
diff --git a/test/data/V2000/testV2000.mdb b/test/data/V2000/testV2000.mdb
new file mode 100644 (file)
index 0000000..b9d004a
Binary files /dev/null and b/test/data/V2000/testV2000.mdb differ
diff --git a/test/data/V2003/bigIndexTestV2003.mdb b/test/data/V2003/bigIndexTestV2003.mdb
new file mode 100644 (file)
index 0000000..6020262
Binary files /dev/null and b/test/data/V2003/bigIndexTestV2003.mdb differ
diff --git a/test/data/V2003/compIndexTestV2003.mdb b/test/data/V2003/compIndexTestV2003.mdb
new file mode 100644 (file)
index 0000000..5c95d17
Binary files /dev/null and b/test/data/V2003/compIndexTestV2003.mdb differ
diff --git a/test/data/V2003/delColTestV2003.mdb b/test/data/V2003/delColTestV2003.mdb
new file mode 100644 (file)
index 0000000..62463c1
Binary files /dev/null and b/test/data/V2003/delColTestV2003.mdb differ
diff --git a/test/data/V2003/delTestV2003.mdb b/test/data/V2003/delTestV2003.mdb
new file mode 100644 (file)
index 0000000..92c9d81
Binary files /dev/null and b/test/data/V2003/delTestV2003.mdb differ
diff --git a/test/data/V2003/fixedNumericTestV2003.mdb b/test/data/V2003/fixedNumericTestV2003.mdb
new file mode 100644 (file)
index 0000000..5531c6c
Binary files /dev/null and b/test/data/V2003/fixedNumericTestV2003.mdb differ
diff --git a/test/data/V2003/fixedTextTestV2003.mdb b/test/data/V2003/fixedTextTestV2003.mdb
new file mode 100644 (file)
index 0000000..78ebfa3
Binary files /dev/null and b/test/data/V2003/fixedTextTestV2003.mdb differ
diff --git a/test/data/V2003/indexCursorTestV2003.mdb b/test/data/V2003/indexCursorTestV2003.mdb
new file mode 100644 (file)
index 0000000..dec11e0
Binary files /dev/null and b/test/data/V2003/indexCursorTestV2003.mdb differ
diff --git a/test/data/V2003/indexTestV2003.mdb b/test/data/V2003/indexTestV2003.mdb
new file mode 100644 (file)
index 0000000..62a40e0
Binary files /dev/null and b/test/data/V2003/indexTestV2003.mdb differ
diff --git a/test/data/V2003/overflowTestV2003.mdb b/test/data/V2003/overflowTestV2003.mdb
new file mode 100644 (file)
index 0000000..e49b0a5
Binary files /dev/null and b/test/data/V2003/overflowTestV2003.mdb differ
diff --git a/test/data/V2003/queryTestV2003.mdb b/test/data/V2003/queryTestV2003.mdb
new file mode 100644 (file)
index 0000000..a0dd166
Binary files /dev/null and b/test/data/V2003/queryTestV2003.mdb differ
diff --git a/test/data/V2003/test2V2003.mdb b/test/data/V2003/test2V2003.mdb
new file mode 100644 (file)
index 0000000..3a80fbc
Binary files /dev/null and b/test/data/V2003/test2V2003.mdb differ
diff --git a/test/data/V2003/testIndexCodesV2003.mdb b/test/data/V2003/testIndexCodesV2003.mdb
new file mode 100644 (file)
index 0000000..5f4f256
Binary files /dev/null and b/test/data/V2003/testIndexCodesV2003.mdb differ
diff --git a/test/data/V2003/testIndexPropertiesV2003.mdb b/test/data/V2003/testIndexPropertiesV2003.mdb
new file mode 100644 (file)
index 0000000..b61baa7
Binary files /dev/null and b/test/data/V2003/testIndexPropertiesV2003.mdb differ
diff --git a/test/data/V2003/testPromotionV2003.mdb b/test/data/V2003/testPromotionV2003.mdb
new file mode 100644 (file)
index 0000000..982de4b
Binary files /dev/null and b/test/data/V2003/testPromotionV2003.mdb differ
diff --git a/test/data/V2003/testV2003.mdb b/test/data/V2003/testV2003.mdb
new file mode 100644 (file)
index 0000000..a1a7fd8
Binary files /dev/null and b/test/data/V2003/testV2003.mdb differ
diff --git a/test/data/V2007/bigIndexTestV2007.accdb b/test/data/V2007/bigIndexTestV2007.accdb
new file mode 100644 (file)
index 0000000..3c76504
Binary files /dev/null and b/test/data/V2007/bigIndexTestV2007.accdb differ
diff --git a/test/data/V2007/compIndexTestV2007.accdb b/test/data/V2007/compIndexTestV2007.accdb
new file mode 100644 (file)
index 0000000..bbed311
Binary files /dev/null and b/test/data/V2007/compIndexTestV2007.accdb differ
diff --git a/test/data/V2007/delColTestV2007.accdb b/test/data/V2007/delColTestV2007.accdb
new file mode 100644 (file)
index 0000000..24a1cee
Binary files /dev/null and b/test/data/V2007/delColTestV2007.accdb differ
diff --git a/test/data/V2007/delTestV2007.accdb b/test/data/V2007/delTestV2007.accdb
new file mode 100644 (file)
index 0000000..96984b5
Binary files /dev/null and b/test/data/V2007/delTestV2007.accdb differ
diff --git a/test/data/V2007/fixedNumericTestV2007.accdb b/test/data/V2007/fixedNumericTestV2007.accdb
new file mode 100644 (file)
index 0000000..5ebe8c1
Binary files /dev/null and b/test/data/V2007/fixedNumericTestV2007.accdb differ
diff --git a/test/data/V2007/fixedTextTestV2007.accdb b/test/data/V2007/fixedTextTestV2007.accdb
new file mode 100644 (file)
index 0000000..8f93bc8
Binary files /dev/null and b/test/data/V2007/fixedTextTestV2007.accdb differ
diff --git a/test/data/V2007/indexCursorTestV2007.accdb b/test/data/V2007/indexCursorTestV2007.accdb
new file mode 100644 (file)
index 0000000..e108c4a
Binary files /dev/null and b/test/data/V2007/indexCursorTestV2007.accdb differ
diff --git a/test/data/V2007/indexTestV2007.accdb b/test/data/V2007/indexTestV2007.accdb
new file mode 100644 (file)
index 0000000..4930831
Binary files /dev/null and b/test/data/V2007/indexTestV2007.accdb differ
diff --git a/test/data/V2007/overflowTestV2007.accdb b/test/data/V2007/overflowTestV2007.accdb
new file mode 100644 (file)
index 0000000..3b43001
Binary files /dev/null and b/test/data/V2007/overflowTestV2007.accdb differ
diff --git a/test/data/V2007/queryTestV2007.accdb b/test/data/V2007/queryTestV2007.accdb
new file mode 100644 (file)
index 0000000..fd4c826
Binary files /dev/null and b/test/data/V2007/queryTestV2007.accdb differ
diff --git a/test/data/V2007/test2V2007.accdb b/test/data/V2007/test2V2007.accdb
new file mode 100644 (file)
index 0000000..9a7b0ec
Binary files /dev/null and b/test/data/V2007/test2V2007.accdb differ
diff --git a/test/data/V2007/testIndexCodesV2007.accdb b/test/data/V2007/testIndexCodesV2007.accdb
new file mode 100644 (file)
index 0000000..2b8d702
Binary files /dev/null and b/test/data/V2007/testIndexCodesV2007.accdb differ
diff --git a/test/data/V2007/testIndexPropertiesV2007.accdb b/test/data/V2007/testIndexPropertiesV2007.accdb
new file mode 100644 (file)
index 0000000..8617f01
Binary files /dev/null and b/test/data/V2007/testIndexPropertiesV2007.accdb differ
diff --git a/test/data/V2007/testPromotionV2007.accdb b/test/data/V2007/testPromotionV2007.accdb
new file mode 100644 (file)
index 0000000..a7ea027
Binary files /dev/null and b/test/data/V2007/testPromotionV2007.accdb differ
diff --git a/test/data/V2007/testV2007.accdb b/test/data/V2007/testV2007.accdb
new file mode 100644 (file)
index 0000000..67bea0c
Binary files /dev/null and b/test/data/V2007/testV2007.accdb differ
diff --git a/test/data/bigIndexTest.mdb b/test/data/bigIndexTest.mdb
deleted file mode 100644 (file)
index abbb14d..0000000
Binary files a/test/data/bigIndexTest.mdb and /dev/null differ
diff --git a/test/data/compIndexTest.mdb b/test/data/compIndexTest.mdb
deleted file mode 100644 (file)
index b93db5b..0000000
Binary files a/test/data/compIndexTest.mdb and /dev/null differ
diff --git a/test/data/delColTest.mdb b/test/data/delColTest.mdb
deleted file mode 100644 (file)
index b931b0d..0000000
Binary files a/test/data/delColTest.mdb and /dev/null differ
diff --git a/test/data/delTest.mdb b/test/data/delTest.mdb
deleted file mode 100644 (file)
index 915caa2..0000000
Binary files a/test/data/delTest.mdb and /dev/null differ
diff --git a/test/data/fixedNumericTest.mdb b/test/data/fixedNumericTest.mdb
deleted file mode 100644 (file)
index e329181..0000000
Binary files a/test/data/fixedNumericTest.mdb and /dev/null differ
diff --git a/test/data/fixedTextTest.mdb b/test/data/fixedTextTest.mdb
deleted file mode 100755 (executable)
index 87de103..0000000
Binary files a/test/data/fixedTextTest.mdb and /dev/null differ
diff --git a/test/data/indexCursorTest.mdb b/test/data/indexCursorTest.mdb
deleted file mode 100644 (file)
index 561c44c..0000000
Binary files a/test/data/indexCursorTest.mdb and /dev/null differ
diff --git a/test/data/indexTest.mdb b/test/data/indexTest.mdb
deleted file mode 100644 (file)
index 7e8bd98..0000000
Binary files a/test/data/indexTest.mdb and /dev/null differ
diff --git a/test/data/overflowTest.mdb b/test/data/overflowTest.mdb
deleted file mode 100644 (file)
index f84a517..0000000
Binary files a/test/data/overflowTest.mdb and /dev/null differ
diff --git a/test/data/queryTest.mdb b/test/data/queryTest.mdb
deleted file mode 100755 (executable)
index 4560710..0000000
Binary files a/test/data/queryTest.mdb and /dev/null differ
diff --git a/test/data/test.mdb b/test/data/test.mdb
deleted file mode 100644 (file)
index b9d004a..0000000
Binary files a/test/data/test.mdb and /dev/null differ
diff --git a/test/data/test2.mdb b/test/data/test2.mdb
deleted file mode 100644 (file)
index 8da9633..0000000
Binary files a/test/data/test2.mdb and /dev/null differ
diff --git a/test/data/testIndexCodes.mdb b/test/data/testIndexCodes.mdb
deleted file mode 100644 (file)
index f884d4a..0000000
Binary files a/test/data/testIndexCodes.mdb and /dev/null differ
diff --git a/test/data/testIndexProperties.mdb b/test/data/testIndexProperties.mdb
deleted file mode 100644 (file)
index bb1c158..0000000
Binary files a/test/data/testIndexProperties.mdb and /dev/null differ
diff --git a/test/data/testPromotion.mdb b/test/data/testPromotion.mdb
deleted file mode 100644 (file)
index 901c520..0000000
Binary files a/test/data/testPromotion.mdb and /dev/null differ
index f874aec9367fe66965608a82abb50d05f6a73ed8..c0ff64b99f7c731867d272545742224c09b79625 100644 (file)
@@ -27,7 +27,6 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -36,6 +35,7 @@ import java.util.Random;
 import junit.framework.TestCase;
 
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
 
 
 /**
@@ -67,157 +67,160 @@ public class BigIndexTest extends TestCase {
   
   public void testComplexIndex() throws Exception
   {
-    // this file has an index with "compressed" entries and node pages
-    Database db = open(new File("test/data/compIndexTest.mdb"));
-    Table t = db.getTable("Table1");
-    Index index = t.getIndex("CD_AGENTE");
-    assertFalse(index.isInitialized());
-    assertEquals(512, countRows(t));
-    assertEquals(512, index.getEntryCount());
-    db.close();
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.COMP_INDEX)) {
+      // this file has an index with "compressed" entries and node pages
+      Database db = open(testDB);
+      Table t = db.getTable("Table1");
+      Index index = t.getIndex("CD_AGENTE");
+      assertFalse(index.isInitialized());
+      assertEquals(512, countRows(t));
+      assertEquals(512, index.getEntryCount());
+      db.close();
+    }
   }
 
   public void testBigIndex() throws Exception
   {
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.BIG_INDEX)) {
     // this file has an index with "compressed" entries and node pages
-    File origFile = new File("test/data/bigIndexTest.mdb");
-    Database db = open(origFile);
-    Table t = db.getTable("Table1");
-    Index index = t.getIndex("col1");
-    assertFalse(index.isInitialized());
-    assertEquals(0, countRows(t));
-    assertEquals(0, index.getEntryCount());
-    db.close();
-
-    DatabaseTest._autoSync = false;
-    try {
-
-      String extraText = " some random text to fill out the index and make it fill up pages with lots of extra bytes so i will keep typing until i think that i probably have enough text in the index entry so that i do not need to add as many entries in order";
-      
-      // copy to temp file and attempt to edit
-      db = openCopy(origFile);
-      t = db.getTable("Table1");
-      index = t.getIndex("col1");
-
-      System.out.println("BigIndexTest: Index type: " + index.getClass());
-
-      // add 2,000 (pseudo) random entries to the table
-      Random rand = new Random(13L);
-      for(int i = 0; i < 2000; ++i) {
-        if((i == 850) || (i == 1850)) {
-          int end = i + 50;
-          List<Object[]> rows = new ArrayList<Object[]>(50);
-          for(; i < end; ++i) {
+      Database db = open(testDB);
+      Table t = db.getTable("Table1");
+      Index index = t.getIndex("col1");
+      assertFalse(index.isInitialized());
+      assertEquals(0, countRows(t));
+      assertEquals(0, index.getEntryCount());
+      db.close();
+
+      DatabaseTest._autoSync = false;
+      try {
+
+        String extraText = " some random text to fill out the index and make it fill up pages with lots of extra bytes so i will keep typing until i think that i probably have enough text in the index entry so that i do not need to add as many entries in order";
+
+        // copy to temp file and attempt to edit
+        db = openCopy(testDB);
+        t = db.getTable("Table1");
+        index = t.getIndex("col1");
+
+        System.out.println("BigIndexTest: Index type: " + index.getClass());
+
+        // add 2,000 (pseudo) random entries to the table
+        Random rand = new Random(13L);
+        for(int i = 0; i < 2000; ++i) {
+          if((i == 850) || (i == 1850)) {
+            int end = i + 50;
+            List<Object[]> rows = new ArrayList<Object[]>(50);
+            for(; i < end; ++i) {
+              int nextInt = rand.nextInt(Integer.MAX_VALUE);
+              String nextVal = "" + nextInt + extraText;
+              if(((i + 1) % 333) == 0) {
+                nextVal = null;
+              }
+              rows.add(new Object[]{nextVal,
+                                    "this is some row data " + nextInt});
+            }
+            t.addRows(rows);
+            --i;
+          } else {
             int nextInt = rand.nextInt(Integer.MAX_VALUE);
             String nextVal = "" + nextInt + extraText;
             if(((i + 1) % 333) == 0) {
               nextVal = null;
             }
-            rows.add(new Object[]{nextVal,
-                                  "this is some row data " + nextInt});
+            t.addRow(nextVal, "this is some row data " + nextInt);
           }
-          t.addRows(rows);
-          --i;
-        } else {
-          int nextInt = rand.nextInt(Integer.MAX_VALUE);
-          String nextVal = "" + nextInt + extraText;
-          if(((i + 1) % 333) == 0) {
-            nextVal = null;
+        }
+
+        ((BigIndex)index).validate();
+
+        db.flush();
+        t = db.getTable("Table1");
+        index = t.getIndex("col1");
+
+        // make sure all entries are there and correctly ordered
+        String firstValue = "      ";
+        String prevValue = firstValue;
+        int rowCount = 0;
+        List<String> firstTwo = new ArrayList<String>();
+        for(Map<String,Object> row : Cursor.createIndexCursor(t, index)) {
+          String origVal = (String)row.get("col1");
+          String val = origVal;
+          if(val == null) {
+            val = firstValue;
           }
-          t.addRow(nextVal, "this is some row data " + nextInt);
+          assertTrue("" + prevValue + " <= " + val + " " + rowCount,
+                     prevValue.compareTo(val) <= 0);
+          if(firstTwo.size() < 2) {
+            firstTwo.add(origVal);
+          }
+          prevValue = val;
+          ++rowCount;
         }
-      }
 
-      ((BigIndex)index).validate();
-      
-      db.flush();
-      t = db.getTable("Table1");
-      index = t.getIndex("col1");
-
-      // make sure all entries are there and correctly ordered
-      String firstValue = "      ";
-      String prevValue = firstValue;
-      int rowCount = 0;
-      List<String> firstTwo = new ArrayList<String>();
-      for(Map<String,Object> row : Cursor.createIndexCursor(t, index)) {
-        String origVal = (String)row.get("col1");
-        String val = origVal;
-        if(val == null) {
-          val = firstValue;
+        assertEquals(2000, rowCount);
+
+        ((BigIndex)index).validate();
+
+        // delete an entry in the middle
+        Cursor cursor = Cursor.createIndexCursor(t, index);
+        for(int i = 0; i < (rowCount / 2); ++i) {
+          assertTrue(cursor.moveToNextRow());
         }
-        assertTrue("" + prevValue + " <= " + val + " " + rowCount,
-                   prevValue.compareTo(val) <= 0);
-        if(firstTwo.size() < 2) {
-          firstTwo.add(origVal);
+        cursor.deleteCurrentRow();
+        --rowCount;
+
+        // remove all but the first two entries (from the end)
+        cursor.afterLast();
+        for(int i = 0; i < (rowCount - 2); ++i) {
+          assertTrue(cursor.moveToPreviousRow());
+          cursor.deleteCurrentRow();
         }
-        prevValue = val;
-        ++rowCount;
-      }
 
-      assertEquals(2000, rowCount);
+        ((BigIndex)index).validate();
 
-      ((BigIndex)index).validate();
-      
-      // delete an entry in the middle
-      Cursor cursor = Cursor.createIndexCursor(t, index);
-      for(int i = 0; i < (rowCount / 2); ++i) {
-        assertTrue(cursor.moveToNextRow());
-      }
-      cursor.deleteCurrentRow();
-      --rowCount;
-      
-      // remove all but the first two entries (from the end)
-      cursor.afterLast();
-      for(int i = 0; i < (rowCount - 2); ++i) {
-        assertTrue(cursor.moveToPreviousRow());
-        cursor.deleteCurrentRow();
-      }
+        List<String> found = new ArrayList<String>();
+        for(Map<String,Object> row : Cursor.createIndexCursor(t, index)) {
+          found.add((String)row.get("col1"));
+        }
 
-      ((BigIndex)index).validate();
-      
-      List<String> found = new ArrayList<String>();
-      for(Map<String,Object> row : Cursor.createIndexCursor(t, index)) {
-        found.add((String)row.get("col1"));
-      }      
+        assertEquals(firstTwo, found);
 
-      assertEquals(firstTwo, found);
+        // remove remaining entries
+        cursor = Cursor.createCursor(t);
+        for(int i = 0; i < 2; ++i) {
+          assertTrue(cursor.moveToNextRow());
+          cursor.deleteCurrentRow();
+        }
 
-      // remove remaining entries
-      cursor = Cursor.createCursor(t);
-      for(int i = 0; i < 2; ++i) {
-        assertTrue(cursor.moveToNextRow());
-        cursor.deleteCurrentRow();
-      }
+        assertFalse(cursor.moveToNextRow());
+        assertFalse(cursor.moveToPreviousRow());
+
+        ((BigIndex)index).validate();
+
+        // add 50 (pseudo) random entries to the table
+        rand = new Random(42L);
+        for(int i = 0; i < 50; ++i) {
+          int nextInt = rand.nextInt(Integer.MAX_VALUE);
+          String nextVal = "some prefix " + nextInt + extraText;
+          if(((i + 1) % 3333) == 0) {
+            nextVal = null;
+          }
+          t.addRow(nextVal, "this is some row data " + nextInt);
+        }
+
+        ((BigIndex)index).validate();
 
-      assertFalse(cursor.moveToNextRow());
-      assertFalse(cursor.moveToPreviousRow());
-      
-      ((BigIndex)index).validate();
-
-      // add 50 (pseudo) random entries to the table
-      rand = new Random(42L);
-      for(int i = 0; i < 50; ++i) {
-        int nextInt = rand.nextInt(Integer.MAX_VALUE);
-        String nextVal = "some prefix " + nextInt + extraText;
-        if(((i + 1) % 3333) == 0) {
-          nextVal = null;
+        cursor = Cursor.createIndexCursor(t, index);
+        while(cursor.moveToNextRow()) {
+          cursor.deleteCurrentRow();
         }
-        t.addRow(nextVal, "this is some row data " + nextInt);
-      }
 
-      ((BigIndex)index).validate();
+        ((BigIndex)index).validate();
 
-      cursor = Cursor.createIndexCursor(t, index);
-      while(cursor.moveToNextRow()) {
-        cursor.deleteCurrentRow();
+        db.close();
+
+      } finally {
+        DatabaseTest._autoSync = Database.DEFAULT_AUTO_SYNC;
       }
-      
-      ((BigIndex)index).validate();
-      
-      db.close();
-      
-    } finally {
-      DatabaseTest._autoSync = Database.DEFAULT_AUTO_SYNC;
     }
   }
 
index 2788f659a58572a25942de1c3057acb32feb975b..260238d5f44aa6e5920f9da6581f4bc3c2bba931 100644 (file)
@@ -29,6 +29,8 @@ package com.healthmarketscience.jackcess;
 
 import junit.framework.TestCase;
 
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
+
 /**
  * @author James Ahlborn
  */
@@ -50,117 +52,119 @@ public class CursorBuilderTest extends TestCase {
   
   public void test() throws Exception
   {
-    Database db = CursorTest.createTestIndexTable();
-
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
-
-    Cursor expected = Cursor.createCursor(table);
-    
-    Cursor found = new CursorBuilder(table).toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createIndexCursor(table, idx);
-    found = new CursorBuilder(table)
-      .setIndex(idx)
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createIndexCursor(table, idx);
-    found = new CursorBuilder(table)
-      .setIndexByName("id")
-      .toCursor();
-    assertCursor(expected, found);
-
-    try {
-      new CursorBuilder(table)
-        .setIndexByName("foo");
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException ignored) {
-      // success
-    }
-    
-    expected = Cursor.createIndexCursor(table, idx);
-    found = new CursorBuilder(table)
-      .setIndexByColumns(table.getColumn("id"))
-      .toCursor();
-    assertCursor(expected, found);
-
-    try {
-      new CursorBuilder(table)
-        .setIndexByColumns(table.getColumn("value"));
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException ignored) {
-      // success
-    }
-    
-    try {
-      new CursorBuilder(table)
-        .setIndexByColumns(table.getColumn("id"), table.getColumn("value"));
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException ignored) {
-      // success
+    for (final TestDB indexCursorDB : CursorTest.INDEX_CURSOR_DBS) {
+      Database db = CursorTest.createTestIndexTable(indexCursorDB);
+
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
+
+      Cursor expected = Cursor.createCursor(table);
+
+      Cursor found = new CursorBuilder(table).toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createIndexCursor(table, idx);
+      found = new CursorBuilder(table)
+        .setIndex(idx)
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createIndexCursor(table, idx);
+      found = new CursorBuilder(table)
+        .setIndexByName("id")
+        .toCursor();
+      assertCursor(expected, found);
+
+      try {
+        new CursorBuilder(table)
+          .setIndexByName("foo");
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException ignored) {
+        // success
+      }
+
+      expected = Cursor.createIndexCursor(table, idx);
+      found = new CursorBuilder(table)
+        .setIndexByColumns(table.getColumn("id"))
+        .toCursor();
+      assertCursor(expected, found);
+
+      try {
+        new CursorBuilder(table)
+          .setIndexByColumns(table.getColumn("value"));
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException ignored) {
+        // success
+      }
+
+      try {
+        new CursorBuilder(table)
+          .setIndexByColumns(table.getColumn("id"), table.getColumn("value"));
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException ignored) {
+        // success
+      }
+
+      expected = Cursor.createCursor(table);
+      expected.beforeFirst();
+      found = new CursorBuilder(table)
+        .beforeFirst()
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createCursor(table);
+      expected.afterLast();
+      found = new CursorBuilder(table)
+        .afterLast()
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createCursor(table);
+      expected.moveNextRows(2);
+      Cursor.Savepoint sp = expected.getSavepoint();
+      found = new CursorBuilder(table)
+        .afterLast()
+        .restoreSavepoint(sp)
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createIndexCursor(table, idx);
+      expected.moveNextRows(2);
+      sp = expected.getSavepoint();
+      found = new CursorBuilder(table)
+        .setIndex(idx)
+        .beforeFirst()
+        .restoreSavepoint(sp)
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createIndexCursor(table, idx,
+                                          idx.constructIndexRowFromEntry(3),
+                                          null);
+      found = new CursorBuilder(table)
+        .setIndex(idx)
+        .setStartEntry(3)
+        .toCursor();
+      assertCursor(expected, found);
+
+      expected = Cursor.createIndexCursor(table, idx,
+                                          idx.constructIndexRowFromEntry(3),
+                                          false,
+                                          idx.constructIndexRowFromEntry(7),
+                                          false);
+      found = new CursorBuilder(table)
+        .setIndex(idx)
+        .setStartEntry(3)
+        .setStartRowInclusive(false)
+        .setEndEntry(7)
+        .setEndRowInclusive(false)
+        .toCursor();
+      assertCursor(expected, found);
+
+
+
+      db.close();
     }
-    
-    expected = Cursor.createCursor(table);
-    expected.beforeFirst();
-    found = new CursorBuilder(table)
-      .beforeFirst()
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createCursor(table);
-    expected.afterLast();
-    found = new CursorBuilder(table)
-      .afterLast()
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createCursor(table);
-    expected.moveNextRows(2);
-    Cursor.Savepoint sp = expected.getSavepoint();
-    found = new CursorBuilder(table)
-      .afterLast()
-      .restoreSavepoint(sp)
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createIndexCursor(table, idx);
-    expected.moveNextRows(2);
-    sp = expected.getSavepoint();
-    found = new CursorBuilder(table)
-      .setIndex(idx)
-      .beforeFirst()
-      .restoreSavepoint(sp)
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createIndexCursor(table, idx,
-                                        idx.constructIndexRowFromEntry(3),
-                                        null);
-    found = new CursorBuilder(table)
-      .setIndex(idx)
-      .setStartEntry(3)
-      .toCursor();
-    assertCursor(expected, found);
-
-    expected = Cursor.createIndexCursor(table, idx,
-                                        idx.constructIndexRowFromEntry(3),
-                                        false,
-                                        idx.constructIndexRowFromEntry(7),
-                                        false);
-    found = new CursorBuilder(table)
-      .setIndex(idx)
-      .setStartEntry(3)
-      .setStartRowInclusive(false)
-      .setEndEntry(7)
-      .setEndRowInclusive(false)
-      .toCursor();
-    assertCursor(expected, found);
-
-
-    
-    db.close();
   }
   
 }
index 9cf15c9e7cfcb9871a41ef18a3cbb72cd2f9cac0..63eab0c312900a5c6e10418dd6e0634c9cc6e1f2 100644 (file)
@@ -27,7 +27,6 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -37,7 +36,9 @@ import java.util.TreeSet;
 
 import junit.framework.TestCase;
 
+import static com.healthmarketscience.jackcess.Database.*;
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
 
 /**
  * @author James Ahlborn
@@ -70,8 +71,8 @@ public class CursorTest extends TestCase {
     return expectedRows;
   }
   
-  private static Database createTestTable() throws Exception {
-    Database db = create();
+  private static Database createTestTable(final FileFormat fileFormat) throws Exception {
+    Database db = create(fileFormat);
 
     Table table = new TableBuilder("test")
       .addColumn(new ColumnBuilder("id", DataType.LONG).toColumn())
@@ -96,16 +97,18 @@ public class CursorTest extends TestCase {
     }
     return expectedRows;
   }  
-  
-  static Database createTestIndexTable() throws Exception {
-    Database db = openCopy(new File("test/data/indexCursorTest.mdb"));
+
+  static final TestDB[] INDEX_CURSOR_DBS = TestDB.getSupportedForBasename(Basename.INDEX_CURSOR);
+
+  static Database createTestIndexTable(final TestDB indexCursorDB) throws Exception {
+    Database db = openCopy(indexCursorDB);
 
     Table table = db.getTable("test");
 
     for(Map<String,Object> row : createUnorderedTestTableData()) {
       table.addRow(row.get("id"), row.get("value"));
     }
-    
+
     return db;
   }
 
@@ -139,16 +142,18 @@ public class CursorTest extends TestCase {
   }
   
   public void testSimple() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
-    Cursor cursor = Cursor.createCursor(table);
-    doTestSimple(table, cursor, null);
-    db.close();
+      Table table = db.getTable("test");
+      Cursor cursor = Cursor.createCursor(table);
+      doTestSimple(cursor, null);
+      db.close();
+    }
   }
 
-  private void doTestSimple(Table table, Cursor cursor,
-                            List<Map<String,Object>> expectedRows)
+  private void doTestSimple(Cursor cursor,
+                            List<Map<String, Object>> expectedRows)
     throws Exception
   {
     if(expectedRows == null) {
@@ -164,17 +169,19 @@ public class CursorTest extends TestCase {
   }
 
   public void testMove() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
-    Cursor cursor = Cursor.createCursor(table);
-    doTestMove(table, cursor, null);
-    
-    db.close();
+      Table table = db.getTable("test");
+      Cursor cursor = Cursor.createCursor(table);
+      doTestMove(cursor, null);
+
+      db.close();
+    }
   }
 
-  private void doTestMove(Table table, Cursor cursor,
-                          List<Map<String,Object>> expectedRows)
+  private void doTestMove(Cursor cursor,
+                          List<Map<String, Object>> expectedRows)
     throws Exception
   {
     if(expectedRows == null) {
@@ -221,13 +228,15 @@ public class CursorTest extends TestCase {
   }
 
   public void testSearch() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
-    Cursor cursor = Cursor.createCursor(table);
-    doTestSearch(table, cursor, null, 42, -13);
-    
-    db.close();
+      Table table = db.getTable("test");
+      Cursor cursor = Cursor.createCursor(table);
+      doTestSearch(table, cursor, null, 42, -13);
+
+      db.close();
+    }
   }
 
   private void doTestSearch(Table table, Cursor cursor, Index index,
@@ -303,17 +312,19 @@ public class CursorTest extends TestCase {
   }
 
   public void testReverse() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
-    Cursor cursor = Cursor.createCursor(table);
-    doTestReverse(table, cursor, null);
+      Table table = db.getTable("test");
+      Cursor cursor = Cursor.createCursor(table);
+      doTestReverse(cursor, null);
 
-    db.close();
+      db.close();
+    }
   }
 
-  private void doTestReverse(Table table, Cursor cursor,
-                             List<Map<String,Object>> expectedRows)
+  private void doTestReverse(Cursor cursor,
+                             List<Map<String, Object>> expectedRows)
     throws Exception
   {
     if(expectedRows == null) {
@@ -330,15 +341,17 @@ public class CursorTest extends TestCase {
   }
   
   public void testLiveAddition() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
+      Table table = db.getTable("test");
 
-    Cursor cursor1 = Cursor.createCursor(table);
-    Cursor cursor2 = Cursor.createCursor(table);
-    doTestLiveAddition(table, cursor1, cursor2, 11);
-    
-    db.close();
+      Cursor cursor1 = Cursor.createCursor(table);
+      Cursor cursor2 = Cursor.createCursor(table);
+      doTestLiveAddition(table, cursor1, cursor2, 11);
+
+      db.close();
+    }
   }
 
   private void doTestLiveAddition(Table table,
@@ -369,25 +382,27 @@ public class CursorTest extends TestCase {
 
   
   public void testLiveDeletion() throws Exception {
-    Database db = createTestTable();
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = createTestTable(fileFormat);
 
-    Table table = db.getTable("test");
+      Table table = db.getTable("test");
 
-    Cursor cursor1 = Cursor.createCursor(table);
-    Cursor cursor2 = Cursor.createCursor(table);
-    Cursor cursor3 = Cursor.createCursor(table);
-    Cursor cursor4 = Cursor.createCursor(table);
-    doTestLiveDeletion(table, cursor1, cursor2, cursor3, cursor4, 1);
-    
-    db.close();
+      Cursor cursor1 = Cursor.createCursor(table);
+      Cursor cursor2 = Cursor.createCursor(table);
+      Cursor cursor3 = Cursor.createCursor(table);
+      Cursor cursor4 = Cursor.createCursor(table);
+      doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 1);
+
+      db.close();
+    }
   }
 
-  private void doTestLiveDeletion(Table table,
-                                  Cursor cursor1,
-                                  Cursor cursor2,
-                                  Cursor cursor3,
-                                  Cursor cursor4,
-                                  int firstValue) throws Exception
+  private void doTestLiveDeletion(
+          Cursor cursor1,
+          Cursor cursor2,
+          Cursor cursor3,
+          Cursor cursor4,
+          int firstValue) throws Exception
   {
     assertEquals(2, cursor1.moveNextRows(2));
     assertEquals(3, cursor2.moveNextRows(3));
@@ -460,220 +475,246 @@ public class CursorTest extends TestCase {
   }
 
   public void testSimpleIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
 
-    assertTable(createUnorderedTestTableData(), table);
+      assertTable(createUnorderedTestTableData(), table);
 
-    Cursor cursor = Cursor.createIndexCursor(table, idx);
-    doTestSimple(table, cursor, null);
+      Cursor cursor = Cursor.createIndexCursor(table, idx);
+      doTestSimple(cursor, null);
 
-    db.close();
+      db.close();
+    }
   }
 
   public void testMoveIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
-    Cursor cursor = Cursor.createIndexCursor(table, idx);
-    doTestMove(table, cursor, null);
-    
-    db.close();
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
+      Cursor cursor = Cursor.createIndexCursor(table, idx);
+      doTestMove(cursor, null);
+
+      db.close();
+    }
   }
   
   public void testReverseIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
-    Cursor cursor = Cursor.createIndexCursor(table, idx);
-    doTestReverse(table, cursor, null);
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
+      Cursor cursor = Cursor.createIndexCursor(table, idx);
+      doTestReverse(cursor, null);
 
-    db.close();
+      db.close();
+    }
   }
 
   public void testSearchIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
-    Cursor cursor = Cursor.createIndexCursor(table, idx);
-    doTestSearch(table, cursor, idx, 42, -13);
-    
-    db.close();
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
+      Cursor cursor = Cursor.createIndexCursor(table, idx);
+      doTestSearch(table, cursor, idx, 42, -13);
+
+      db.close();
+    }
   }
 
   public void testLiveAdditionIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
 
-    Cursor cursor1 = Cursor.createIndexCursor(table, idx);
-    Cursor cursor2 = Cursor.createIndexCursor(table, idx);
-    doTestLiveAddition(table, cursor1, cursor2, 11);
-    
-    db.close();
+      Cursor cursor1 = Cursor.createIndexCursor(table, idx);
+      Cursor cursor2 = Cursor.createIndexCursor(table, idx);
+      doTestLiveAddition(table, cursor1, cursor2, 11);
+
+      db.close();
+    }
   }
 
   public void testLiveDeletionIndex() throws Exception {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
 
-    Cursor cursor1 = Cursor.createIndexCursor(table, idx);
-    Cursor cursor2 = Cursor.createIndexCursor(table, idx);
-    Cursor cursor3 = Cursor.createIndexCursor(table, idx);
-    Cursor cursor4 = Cursor.createIndexCursor(table, idx);
-    doTestLiveDeletion(table, cursor1, cursor2, cursor3, cursor4, 1);
-    
-    db.close();
+      Cursor cursor1 = Cursor.createIndexCursor(table, idx);
+      Cursor cursor2 = Cursor.createIndexCursor(table, idx);
+      Cursor cursor3 = Cursor.createIndexCursor(table, idx);
+      Cursor cursor4 = Cursor.createIndexCursor(table, idx);
+      doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 1);
+
+      db.close();
+    }
   }
 
   public void testSimpleIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor = createIndexSubRangeCursor(table, idx, i);
 
-      List<Map<String,Object>> expectedRows =
-        createTestTableData(3, 9);
+        List<Map<String,Object>> expectedRows =
+          createTestTableData(3, 9);
 
-      doTestSimple(table, cursor, expectedRows);
-    
-      db.close();
+        doTestSimple(cursor, expectedRows);
+
+        db.close();
+      }
     }
   }
   
   public void testMoveIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor = createIndexSubRangeCursor(table, idx, i);
 
-      List<Map<String,Object>> expectedRows =
-        createTestTableData(3, 9);
+        List<Map<String,Object>> expectedRows =
+          createTestTableData(3, 9);
 
-      doTestMove(table, cursor, expectedRows);
-    
-      db.close();
+        doTestMove(cursor, expectedRows);
+
+        db.close();
+      }
     }
   }
   
   public void testSearchIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor = createIndexSubRangeCursor(table, idx, i);
 
-      doTestSearch(table, cursor, idx, 2, 9);
-    
-      db.close();
+        doTestSearch(table, cursor, idx, 2, 9);
+
+        db.close();
+      }
     }
   }
 
   public void testReverseIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor = createIndexSubRangeCursor(table, idx, i);
 
-      List<Map<String,Object>> expectedRows =
-        createTestTableData(3, 9);
+        List<Map<String,Object>> expectedRows =
+          createTestTableData(3, 9);
 
-      doTestReverse(table, cursor, expectedRows);
+        doTestReverse(cursor, expectedRows);
 
-      db.close();
+        db.close();
+      }
     }
   }
 
   public void testLiveAdditionIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
-      Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
 
-      doTestLiveAddition(table, cursor1, cursor2, 8);
-    
-      db.close();
+        doTestLiveAddition(table, cursor1, cursor2, 8);
+
+        db.close();
+      }
     }
   }
   
   public void testLiveDeletionIndexSubRange() throws Exception {
-    for(int i = 0; i < 2; ++i) {
-      Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      for(int i = 0; i < 2; ++i) {
+        Database db = createTestIndexTable(indexCursorDB);
 
-      Table table = db.getTable("test");
-      Index idx = table.getIndexes().get(0);
+        Table table = db.getTable("test");
+        Index idx = table.getIndexes().get(0);
 
-      Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
-      Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
-      Cursor cursor3 = createIndexSubRangeCursor(table, idx, i);
-      Cursor cursor4 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor3 = createIndexSubRangeCursor(table, idx, i);
+        Cursor cursor4 = createIndexSubRangeCursor(table, idx, i);
 
-      doTestLiveDeletion(table, cursor1, cursor2, cursor3, cursor4, 4);
+        doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 4);
 
-      db.close();
-    }    
+        db.close();
+      }
+    }
   }
 
   public void testId() throws Exception
   {
-    Database db = createTestIndexTable();
+    for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
+      Database db = createTestIndexTable(indexCursorDB);
 
-    Table table = db.getTable("test");
-    Index idx = table.getIndexes().get(0);
+      Table table = db.getTable("test");
+      Index idx = table.getIndexes().get(0);
 
-    Cursor tCursor = Cursor.createCursor(table);
-    Cursor iCursor = Cursor.createIndexCursor(table, idx);
+      Cursor tCursor = Cursor.createCursor(table);
+      Cursor iCursor = Cursor.createIndexCursor(table, idx);
 
-    Cursor.Savepoint tSave = tCursor.getSavepoint();
-    Cursor.Savepoint iSave = iCursor.getSavepoint();
+      Cursor.Savepoint tSave = tCursor.getSavepoint();
+      Cursor.Savepoint iSave = iCursor.getSavepoint();
 
-    tCursor.restoreSavepoint(tSave);
-    iCursor.restoreSavepoint(iSave);
+      tCursor.restoreSavepoint(tSave);
+      iCursor.restoreSavepoint(iSave);
 
-    try {
-      tCursor.restoreSavepoint(iSave);
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
+      try {
+        tCursor.restoreSavepoint(iSave);
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    try {
-      iCursor.restoreSavepoint(tSave);
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
+      try {
+        iCursor.restoreSavepoint(tSave);
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    Cursor tCursor2 = Cursor.createCursor(table);
-    Cursor iCursor2 = Cursor.createIndexCursor(table, idx);
+      Cursor tCursor2 = Cursor.createCursor(table);
+      Cursor iCursor2 = Cursor.createIndexCursor(table, idx);
 
-    tCursor2.restoreSavepoint(tSave);
-    iCursor2.restoreSavepoint(iSave);
+      tCursor2.restoreSavepoint(tSave);
+      iCursor2.restoreSavepoint(iSave);
 
-    db.close();
+      db.close();
+    }
   }
   
 }
index 46432e4f9ab13424bd62e09f284af83ca39a0302..828f76d7bf5b72d43334aa82e6f1b0937fb80821 100644 (file)
@@ -55,122 +55,135 @@ import java.util.UUID;
 
 import junit.framework.TestCase;
 
+import static com.healthmarketscience.jackcess.Database.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
+
 /**
  * @author Tim McCune
  */
 public class DatabaseTest extends TestCase {
 
   static boolean _autoSync = Database.DEFAULT_AUTO_SYNC;
-  
+
+
   public DatabaseTest(String name) throws Exception {
     super(name);
   }
-   
-  public static Database open() throws Exception {
-    return open(new File("test/data/test.mdb"));
-  }
-  
-  public static Database open(File file) throws Exception {
-    return Database.open(file, true, _autoSync);
+
+  public static Database open(final TestDB testDB) throws Exception {
+    final Database db = Database.open(testDB.getFile(), true, _autoSync);
+    assertEquals("Wrong JetFormat.", testDB.getExpectedFormat(), db.getFormat());
+    assertEquals("Wrong FileFormat.", testDB.getExpectedFileFormat(), 
+                 db.getFileFormat());
+    return db;
   }
-  
-  public static Database create() throws Exception {
-    return create(false);
+
+  public static Database create(final Database.FileFormat fileFormat) throws Exception {
+    return create(fileFormat, false);
   }
 
-  public static Database create(boolean keep) throws Exception {
-    return Database.create(createTempFile(keep), _autoSync);
+  public static Database create(final Database.FileFormat fileFormat, boolean keep) throws Exception {
+    return Database.create(fileFormat, createTempFile(keep), _autoSync);
   }
 
-  public static Database openCopy(File srcFile) throws Exception {
-    return openCopy(srcFile, false);
+
+  public static Database openCopy(final TestDB testDB) throws Exception {
+    return openCopy(testDB, false);
   }
-  
-  public static Database openCopy(File srcFile, boolean keep) 
-    throws Exception 
+
+
+  public static Database openCopy(final TestDB testDB, boolean keep)
+    throws Exception
   {
     File tmp = createTempFile(keep);
-    copyFile(srcFile, tmp);
+    copyFile(testDB.getFile(), tmp);
     return Database.open(tmp, false, _autoSync);
   }
-  
+
+
   public void testInvalidTableDefs() throws Exception {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+
+      try {
+        db.createTable("test", Collections.<Column>emptyList());
+        fail("created table with no columns?");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    try {
-      db.createTable("test", Collections.<Column>emptyList());
-      fail("created table with no columns?");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
+      try {
+        new TableBuilder("test")
+          .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
+          .addColumn(new ColumnBuilder("a", DataType.MEMO).toColumn())
+          .toTable(db);
+        fail("created table with duplicate column names?");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    try {
-      new TableBuilder("test")
-        .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
-        .addColumn(new ColumnBuilder("a", DataType.MEMO).toColumn())
-        .toTable(db);
-      fail("created table with duplicate column names?");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
+      try {
+        new TableBuilder("test")
+          .addColumn(new ColumnBuilder("A", DataType.TEXT)
+                     .setLengthInUnits(352).toColumn())
+          .toTable(db);
+        fail("created table with invalid column length?");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    try {
-      new TableBuilder("test")
-        .addColumn(new ColumnBuilder("A", DataType.TEXT)
-                   .setLengthInUnits(352).toColumn())
-        .toTable(db);
-      fail("created table with invalid column length?");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
+      try {
+        new TableBuilder("test")
+          .addColumn(new ColumnBuilder("A_" + createString(70), DataType.TEXT)
+                     .toColumn())
+          .toTable(db);
+        fail("created table with too long column name?");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
 
-    try {
       new TableBuilder("test")
-        .addColumn(new ColumnBuilder("A_" + createString(70), DataType.TEXT)
-                   .toColumn())
+        .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
         .toTable(db);
-      fail("created table with too long column name?");
-    } catch(IllegalArgumentException e) {
-      // success
-    }
 
-    new TableBuilder("test")
-      .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
-      .toTable(db);
 
-    
-    try {
-      new TableBuilder("Test")
-        .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
-        .toTable(db);
-      fail("create duplicate tables?");
-    } catch(IllegalArgumentException e) {
-      // success
+      try {
+        new TableBuilder("Test")
+          .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
+          .toTable(db);
+        fail("create duplicate tables?");
+      } catch(IllegalArgumentException e) {
+        // success
+      }
     }
-
   }
       
   public void testReadDeletedRows() throws Exception {
-    Table table = open(new File("test/data/delTest.mdb")).getTable("Table");
-    int rows = 0;
-    while (table.getNextRow() != null) {
-      rows++;
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.DEL)) {
+      Table table = open(testDB).getTable("Table");
+      int rows = 0;
+      while (table.getNextRow() != null) {
+        rows++;
+      }
+      assertEquals(2, rows);
     }
-    assertEquals(2, rows); 
   }
   
   public void testGetColumns() throws Exception {
-    List<Column> columns = open().getTable("Table1").getColumns();
-    assertEquals(9, columns.size());
-    checkColumn(columns, 0, "A", DataType.TEXT);
-    checkColumn(columns, 1, "B", DataType.TEXT);
-    checkColumn(columns, 2, "C", DataType.BYTE);
-    checkColumn(columns, 3, "D", DataType.INT);
-    checkColumn(columns, 4, "E", DataType.LONG);
-    checkColumn(columns, 5, "F", DataType.DOUBLE);
-    checkColumn(columns, 6, "G", DataType.SHORT_DATE_TIME);
-    checkColumn(columns, 7, "H", DataType.MONEY);
-    checkColumn(columns, 8, "I", DataType.BOOLEAN);
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+
+      List<Column> columns = open(testDB).getTable("Table1").getColumns();
+      assertEquals(9, columns.size());
+      checkColumn(columns, 0, "A", DataType.TEXT);
+      checkColumn(columns, 1, "B", DataType.TEXT);
+      checkColumn(columns, 2, "C", DataType.BYTE);
+      checkColumn(columns, 3, "D", DataType.INT);
+      checkColumn(columns, 4, "E", DataType.LONG);
+      checkColumn(columns, 5, "F", DataType.DOUBLE);
+      checkColumn(columns, 6, "G", DataType.SHORT_DATE_TIME);
+      checkColumn(columns, 7, "H", DataType.MONEY);
+      checkColumn(columns, 8, "I", DataType.BOOLEAN);
+    }
   }
   
   static void checkColumn(List<Column> columns, int columnNumber, String name,
@@ -183,18 +196,34 @@ public class DatabaseTest extends TestCase {
   }
   
   public void testGetNextRow() throws Exception {
-    Database db = open();
-    assertEquals(4, db.getTableNames().size());
-    Table table = db.getTable("Table1");
-    
-    Map<String, Object> row = table.getNextRow();
-    assertEquals("abcdefg", row.get("A"));
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      final Database db = open(testDB);
+      assertEquals(4, db.getTableNames().size());
+      final Table table = db.getTable("Table1");
+
+      Map<String, Object> row1 = table.getNextRow();
+      Map<String, Object> row2 = table.getNextRow();
+
+      if(!"abcdefg".equals(row1.get("A"))) {
+        Map<String, Object> tmpRow = row1;
+        row1 = row2;
+        row2 = tmpRow;
+      }
+
+      checkTestDBTable1RowABCDEFG(testDB, table, row1);
+      checkTestDBTable1RowA(testDB, table, row2);
+    }
+  }
+
+  static void checkTestDBTable1RowABCDEFG(final TestDB testDB, final Table table, final Map<String, Object> row)
+          throws IOException {
+    assertEquals("testDB: " + testDB + "; table: " + table, "abcdefg", row.get("A"));
     assertEquals("hijklmnop", row.get("B"));
     assertEquals(new Byte((byte) 2), row.get("C"));
     assertEquals(new Short((short) 222), row.get("D"));
     assertEquals(new Integer(333333333), row.get("E"));
     assertEquals(new Double(444.555d), row.get("F"));
-    Calendar cal = Calendar.getInstance();
+    final Calendar cal = Calendar.getInstance();
     cal.setTime((Date) row.get("G"));
     assertEquals(Calendar.SEPTEMBER, cal.get(Calendar.MONTH));
     assertEquals(21, cal.get(Calendar.DAY_OF_MONTH));
@@ -204,15 +233,17 @@ public class DatabaseTest extends TestCase {
     assertEquals(0, cal.get(Calendar.SECOND));
     assertEquals(0, cal.get(Calendar.MILLISECOND));
     assertEquals(Boolean.TRUE, row.get("I"));
-    
-    row = table.getNextRow();
-    assertEquals("a", row.get("A"));
+  }
+
+  static void checkTestDBTable1RowA(final TestDB testDB, final Table table, final Map<String, Object> row)
+          throws IOException {
+    assertEquals("testDB: " + testDB + "; table: " + table, "a", row.get("A"));
     assertEquals("b", row.get("B"));
     assertEquals(new Byte((byte) 0), row.get("C"));
     assertEquals(new Short((short) 0), row.get("D"));
     assertEquals(new Integer(0), row.get("E"));
     assertEquals(new Double(0d), row.get("F"));
-    cal = Calendar.getInstance();
+    final Calendar cal = Calendar.getInstance();
     cal.setTime((Date) row.get("G"));
     assertEquals(Calendar.DECEMBER, cal.get(Calendar.MONTH));
     assertEquals(12, cal.get(Calendar.DAY_OF_MONTH));
@@ -223,245 +254,258 @@ public class DatabaseTest extends TestCase {
     assertEquals(0, cal.get(Calendar.MILLISECOND));
     assertEquals(Boolean.FALSE, row.get("I"));
   }
-  
-  public void testCreate() throws Exception {
-    Database db = create();
-    assertEquals(0, db.getTableNames().size());
+
+    public void testCreate() throws Exception {
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      assertEquals(0, db.getTableNames().size());
+    }
   }
   
   public void testWriteAndRead() throws Exception {
-    Database db = create();
-    createTestTable(db);
-    Object[] row = createTestRow();
-    row[3] = null;
-    Table table = db.getTable("Test");
-    int count = 1000;
-    for (int i = 0; i < count; i++) { 
-      table.addRow(row);
-    }
-    for (int i = 0; i < count; i++) {
-      Map<String, Object> readRow = table.getNextRow();
-      assertEquals(row[0], readRow.get("A"));
-      assertEquals(row[1], readRow.get("B"));
-      assertEquals(row[2], readRow.get("C"));
-      assertEquals(row[3], readRow.get("D"));
-      assertEquals(row[4], readRow.get("E"));
-      assertEquals(row[5], readRow.get("F"));
-      assertEquals(row[6], readRow.get("G"));
-      assertEquals(row[7], readRow.get("H"));
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      createTestTable(db);
+      Object[] row = createTestRow();
+      row[3] = null;
+      Table table = db.getTable("Test");
+      int count = 1000;
+      for (int i = 0; i < count; i++) {
+        table.addRow(row);
+      }
+      for (int i = 0; i < count; i++) {
+        Map<String, Object> readRow = table.getNextRow();
+        assertEquals(row[0], readRow.get("A"));
+        assertEquals(row[1], readRow.get("B"));
+        assertEquals(row[2], readRow.get("C"));
+        assertEquals(row[3], readRow.get("D"));
+        assertEquals(row[4], readRow.get("E"));
+        assertEquals(row[5], readRow.get("F"));
+        assertEquals(row[6], readRow.get("G"));
+        assertEquals(row[7], readRow.get("H"));
+      }
     }
   }
   
   public void testWriteAndReadInBatch() throws Exception {
-    Database db = create();
-    createTestTable(db);
-    int count = 1000;
-    List<Object[]> rows = new ArrayList<Object[]>(count);
-    Object[] row = createTestRow();
-    for (int i = 0; i < count; i++) {
-      rows.add(row);
-    }
-    Table table = db.getTable("Test");
-    table.addRows(rows);
-    for (int i = 0; i < count; i++) {
-      Map<String, Object> readRow = table.getNextRow();
-      assertEquals(row[0], readRow.get("A"));
-      assertEquals(row[1], readRow.get("B"));
-      assertEquals(row[2], readRow.get("C"));
-      assertEquals(row[3], readRow.get("D"));
-      assertEquals(row[4], readRow.get("E"));
-      assertEquals(row[5], readRow.get("F"));
-      assertEquals(row[6], readRow.get("G"));
-      assertEquals(row[7], readRow.get("H"));
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      createTestTable(db);
+      int count = 1000;
+      List<Object[]> rows = new ArrayList<Object[]>(count);
+      Object[] row = createTestRow();
+      for (int i = 0; i < count; i++) {
+        rows.add(row);
+      }
+      Table table = db.getTable("Test");
+      table.addRows(rows);
+      for (int i = 0; i < count; i++) {
+        Map<String, Object> readRow = table.getNextRow();
+        assertEquals(row[0], readRow.get("A"));
+        assertEquals(row[1], readRow.get("B"));
+        assertEquals(row[2], readRow.get("C"));
+        assertEquals(row[3], readRow.get("D"));
+        assertEquals(row[4], readRow.get("E"));
+        assertEquals(row[5], readRow.get("F"));
+        assertEquals(row[6], readRow.get("G"));
+        assertEquals(row[7], readRow.get("H"));
+      }
     }
   }
 
   public void testDeleteCurrentRow() throws Exception {
 
     // make sure correct row is deleted
-    Database db = create();
-    createTestTable(db);
-    Object[] row1 = createTestRow("Tim1");
-    Object[] row2 = createTestRow("Tim2");
-    Object[] row3 = createTestRow("Tim3");
-    Table table = db.getTable("Test");
-    table.addRows(Arrays.asList(row1, row2, row3));
-    assertRowCount(3, table);
-    
-    table.reset();
-    table.getNextRow();
-    table.getNextRow();
-    table.deleteCurrentRow();
-
-    table.reset();
-
-    Map<String, Object> outRow = table.getNextRow();
-    assertEquals("Tim1", outRow.get("A"));
-    outRow = table.getNextRow();
-    assertEquals("Tim3", outRow.get("A"));
-    assertRowCount(2, table);
-
-    // test multi row delete/add
-    db = create();
-    createTestTable(db);
-    Object[] row = createTestRow();
-    table = db.getTable("Test");
-    for (int i = 0; i < 10; i++) {
-      row[3] = i;
-      table.addRow(row);
-    }
-    row[3] = 1974;
-    assertRowCount(10, table);
-    table.reset();
-    table.getNextRow();
-    table.deleteCurrentRow();
-    assertRowCount(9, table);
-    table.reset();
-    table.getNextRow();
-    table.deleteCurrentRow();
-    assertRowCount(8, table);
-    table.reset();
-    for (int i = 0; i < 8; i++) {
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      createTestTable(db);
+      Object[] row1 = createTestRow("Tim1");
+      Object[] row2 = createTestRow("Tim2");
+      Object[] row3 = createTestRow("Tim3");
+      Table table = db.getTable("Test");
+      table.addRows(Arrays.asList(row1, row2, row3));
+      assertRowCount(3, table);
+
+      table.reset();
       table.getNextRow();
-    }
-    table.deleteCurrentRow();
-    assertRowCount(7, table);
-    table.addRow(row);
-    assertRowCount(8, table);
-    table.reset();
-    for (int i = 0; i < 3; i++) {
       table.getNextRow();
+      table.deleteCurrentRow();
+
+      table.reset();
+
+      Map<String, Object> outRow = table.getNextRow();
+      assertEquals("Tim1", outRow.get("A"));
+      outRow = table.getNextRow();
+      assertEquals("Tim3", outRow.get("A"));
+      assertRowCount(2, table);
+
+      // test multi row delete/add
+      db = create(fileFormat);
+      createTestTable(db);
+      Object[] row = createTestRow();
+      table = db.getTable("Test");
+      for (int i = 0; i < 10; i++) {
+        row[3] = i;
+        table.addRow(row);
+      }
+      row[3] = 1974;
+      assertRowCount(10, table);
+      table.reset();
+      table.getNextRow();
+      table.deleteCurrentRow();
+      assertRowCount(9, table);
+      table.reset();
+      table.getNextRow();
+      table.deleteCurrentRow();
+      assertRowCount(8, table);
+      table.reset();
+      for (int i = 0; i < 8; i++) {
+        table.getNextRow();
+      }
+      table.deleteCurrentRow();
+      assertRowCount(7, table);
+      table.addRow(row);
+      assertRowCount(8, table);
+      table.reset();
+      for (int i = 0; i < 3; i++) {
+        table.getNextRow();
+      }
+      table.deleteCurrentRow();
+      assertRowCount(7, table);
+      table.reset();
+      assertEquals(2, table.getNextRow().get("D"));
     }
-    table.deleteCurrentRow();
-    assertRowCount(7, table);
-    table.reset();
-    assertEquals(2, table.getNextRow().get("D"));
   }
 
   public void testReadLongValue() throws Exception {
 
-    Database db = open(new File("test/data/test2.mdb"));
-    Table table = db.getTable("MSP_PROJECTS");
-    Map<String, Object> row = table.getNextRow();
-    assertEquals("Jon Iles this is a a vawesrasoih aksdkl fas dlkjflkasjd flkjaslkdjflkajlksj dfl lkasjdf lkjaskldfj lkas dlk lkjsjdfkl; aslkdf lkasjkldjf lka skldf lka sdkjfl;kasjd falksjdfljaslkdjf laskjdfk jalskjd flkj aslkdjflkjkjasljdflkjas jf;lkasjd fjkas dasdf asd fasdf asdf asdmhf lksaiyudfoi jasodfj902384jsdf9 aw90se fisajldkfj lkasj dlkfslkd jflksjadf as", row.get("PROJ_PROP_AUTHOR"));
-    assertEquals("T", row.get("PROJ_PROP_COMPANY"));
-    assertEquals("Standard", row.get("PROJ_INFO_CAL_NAME"));
-    assertEquals("Project1", row.get("PROJ_PROP_TITLE"));
-    byte[] foundBinaryData = (byte[])row.get("RESERVED_BINARY_DATA");
-    byte[] expectedBinaryData =
-      toByteArray(new File("test/data/test2BinData.dat"));
-    assertTrue(Arrays.equals(expectedBinaryData, foundBinaryData));
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.TEST2)) {
+      Database db = open(testDB);
+      Table table = db.getTable("MSP_PROJECTS");
+      Map<String, Object> row = table.getNextRow();
+      assertEquals("Jon Iles this is a a vawesrasoih aksdkl fas dlkjflkasjd flkjaslkdjflkajlksj dfl lkasjdf lkjaskldfj lkas dlk lkjsjdfkl; aslkdf lkasjkldjf lka skldf lka sdkjfl;kasjd falksjdfljaslkdjf laskjdfk jalskjd flkj aslkdjflkjkjasljdflkjas jf;lkasjd fjkas dasdf asd fasdf asdf asdmhf lksaiyudfoi jasodfj902384jsdf9 aw90se fisajldkfj lkasj dlkfslkd jflksjadf as", row.get("PROJ_PROP_AUTHOR"));
+      assertEquals("T", row.get("PROJ_PROP_COMPANY"));
+      assertEquals("Standard", row.get("PROJ_INFO_CAL_NAME"));
+      assertEquals("Project1", row.get("PROJ_PROP_TITLE"));
+      byte[] foundBinaryData = (byte[])row.get("RESERVED_BINARY_DATA");
+      byte[] expectedBinaryData =
+        toByteArray(new File("test/data/test2BinData.dat"));
+      assertTrue(Arrays.equals(expectedBinaryData, foundBinaryData));
+    }
   }
 
   public void testWriteLongValue() throws Exception {
 
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    Table table = 
-    new TableBuilder("test")
-      .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("B", DataType.MEMO).toColumn())
-      .addColumn(new ColumnBuilder("C", DataType.OLE).toColumn())
-      .toTable(db);
+      Table table =
+      new TableBuilder("test")
+        .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("B", DataType.MEMO).toColumn())
+        .addColumn(new ColumnBuilder("C", DataType.OLE).toColumn())
+        .toTable(db);
 
-    String testStr = "This is a test";
-    String longMemo = createString(2030);
-    byte[] oleValue = toByteArray(new File("test/data/test2BinData.dat"));
-    
-    
-    table.addRow(testStr, testStr, null);
-    table.addRow(testStr, longMemo, oleValue);
+      String testStr = "This is a test";
+      String longMemo = createString(2030);
+      byte[] oleValue = toByteArray(new File("test/data/test2BinData.dat"));
 
-    table.reset();
 
-    Map<String, Object> row = table.getNextRow();
+      table.addRow(testStr, testStr, null);
+      table.addRow(testStr, longMemo, oleValue);
 
-    assertEquals(testStr, row.get("A"));
-    assertEquals(testStr, row.get("B"));
-    assertNull(row.get("C"));
+      table.reset();
 
-    row = table.getNextRow();
-    
-    assertEquals(testStr, row.get("A"));
-    assertEquals(longMemo, row.get("B"));
-    assertTrue(Arrays.equals(oleValue, (byte[])row.get("C")));
-    
+      Map<String, Object> row = table.getNextRow();
+
+      assertEquals(testStr, row.get("A"));
+      assertEquals(testStr, row.get("B"));
+      assertNull(row.get("C"));
+
+      row = table.getNextRow();
+
+      assertEquals(testStr, row.get("A"));
+      assertEquals(longMemo, row.get("B"));
+      assertTrue(Arrays.equals(oleValue, (byte[])row.get("C")));
+    }    
   }
 
   public void testManyMemos() throws Exception {
-    final int numColumns = 126;
-    Database db = create();
-    TableBuilder bigTableBuilder = new TableBuilder("test"); 
-    for (int i = 0; i < numColumns; i++) 
-    { 
-      Column column = new ColumnBuilder("column_" + i, DataType.MEMO)
-        .toColumn(); 
-      bigTableBuilder.addColumn(column); 
-    } 
-    Table bigTable = bigTableBuilder.toTable(db); 
-
-    List<Object[]> expectedRows = new ArrayList<Object[]>();
-    for (int j = 0; j < 3; j++) 
-    { 
-      Object[] rowData = new String[numColumns];
-      for (int i = 0; i < numColumns; i++) 
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      final int numColumns = 126;
+      TableBuilder bigTableBuilder = new TableBuilder("test");
+
+      for (int i = 0; i < numColumns; i++)
       {
-        rowData[i] = "v_" + i + ";" + (j + 999);
-      } 
-      expectedRows.add(rowData);
-      bigTable.addRow(rowData); 
-    } 
-
-    String extra1 = createString(100);
-    String extra2 = createString(2050);
-
-    for (int j = 0; j < 1; j++) 
-    { 
-      Object[] rowData = new String[numColumns];
-      for (int i = 0; i < numColumns; i++) 
+        Column column = new ColumnBuilder("column_" + i, DataType.MEMO)
+          .toColumn();
+        bigTableBuilder.addColumn(column);
+      }
+
+      Table bigTable = bigTableBuilder.toTable(db);
+
+      List<Object[]> expectedRows = new ArrayList<Object[]>();
+
+      for (int j = 0; j < 3; j++)
       {
-        rowData[i] = "v_" + i + ";" + (j + 999) + extra2;
-      } 
-      expectedRows.add(rowData);
-      bigTable.addRow(rowData); 
-    } 
-
-    for (int j = 0; j < 2; j++) 
-    { 
-      Object[] rowData = new String[numColumns];
-      for (int i = 0; i < numColumns; i++) 
+        Object[] rowData = new String[numColumns];
+        for (int i = 0; i < numColumns; i++)
+        {
+          rowData[i] = "v_" + i + ";" + (j + 999);
+        }
+        expectedRows.add(rowData);
+        bigTable.addRow(rowData);
+      }
+
+      String extra1 = createString(100);
+      String extra2 = createString(2050);
+
+      for (int j = 0; j < 1; j++)
       {
-        String tmp = "v_" + i + ";" + (j + 999);
-        if((i % 3) == 0) {
-          tmp += extra1;
-        } else if((i % 7) == 0) {
-          tmp += extra2;
+        Object[] rowData = new String[numColumns];
+        for (int i = 0; i < numColumns; i++)
+        {
+          rowData[i] = "v_" + i + ";" + (j + 999) + extra2;
         }
-        rowData[i] = tmp;
-      } 
-      expectedRows.add(rowData);
-      bigTable.addRow(rowData); 
-    } 
-
-    bigTable.reset();
-    Iterator<Object[]> expIter = expectedRows.iterator();
-    for(Map<?,?> row : bigTable) {
-      Object[] expectedRow = expIter.next();
-      assertEquals(Arrays.asList(expectedRow),
-                   new ArrayList<Object>(row.values()));
-    }
+        expectedRows.add(rowData);
+        bigTable.addRow(rowData);
+      }
+
+      for (int j = 0; j < 2; j++)
+      {
+        Object[] rowData = new String[numColumns];
+        for (int i = 0; i < numColumns; i++)
+        {
+          String tmp = "v_" + i + ";" + (j + 999);
+          if((i % 3) == 0) {
+            tmp += extra1;
+          } else if((i % 7) == 0) {
+            tmp += extra2;
+          }
+          rowData[i] = tmp;
+        }
+        expectedRows.add(rowData);
+        bigTable.addRow(rowData);
+      }
 
-    db.close();     
+      bigTable.reset();
+      Iterator<Object[]> expIter = expectedRows.iterator();
+      for(Map<?,?> row : bigTable) {
+        Object[] expectedRow = expIter.next();
+        assertEquals(Arrays.asList(expectedRow),
+                     new ArrayList<Object>(row.values()));
+      }
+
+      db.close();
+    }
   }
   
   public void testMissingFile() throws Exception {
     File bogusFile = new File("fooby-dooby.mdb");
     assertTrue(!bogusFile.exists());
     try {
-      open(bogusFile);
+      Database.open(bogusFile, true, _autoSync);
       fail("FileNotFoundException should have been thrown");
     } catch(FileNotFoundException e) {
     }
@@ -469,331 +513,363 @@ public class DatabaseTest extends TestCase {
   }
 
   public void testReadWithDeletedCols() throws Exception {
-    Table table = open(new File("test/data/delColTest.mdb")).getTable("Table1");
-
-    Map<String, Object> expectedRow0 = new LinkedHashMap<String, Object>();
-    expectedRow0.put("id", 0);
-    expectedRow0.put("id2", 2);
-    expectedRow0.put("data", "foo");
-    expectedRow0.put("data2", "foo2");
-
-    Map<String, Object> expectedRow1 = new LinkedHashMap<String, Object>();
-    expectedRow1.put("id", 3);
-    expectedRow1.put("id2", 5);
-    expectedRow1.put("data", "bar");
-    expectedRow1.put("data2", "bar2");
-
-    int rowNum = 0;
-    Map<String, Object> row = null;
-    while ((row = table.getNextRow()) != null) {
-      if(rowNum == 0) {
-        assertEquals(expectedRow0, row);
-      } else if(rowNum == 1) {
-        assertEquals(expectedRow1, row);
-      } else if(rowNum >= 2) {
-        fail("should only have 2 rows");
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.DEL_COL)) {
+      Table table = open(testDB).getTable("Table1");
+
+      Map<String, Object> expectedRow0 = new LinkedHashMap<String, Object>();
+      expectedRow0.put("id", 0);
+      expectedRow0.put("id2", 2);
+      expectedRow0.put("data", "foo");
+      expectedRow0.put("data2", "foo2");
+
+      Map<String, Object> expectedRow1 = new LinkedHashMap<String, Object>();
+      expectedRow1.put("id", 3);
+      expectedRow1.put("id2", 5);
+      expectedRow1.put("data", "bar");
+      expectedRow1.put("data2", "bar2");
+
+      int rowNum = 0;
+      Map<String, Object> row = null;
+      while ((row = table.getNextRow()) != null) {
+        if(rowNum == 0) {
+          assertEquals(expectedRow0, row);
+        } else if(rowNum == 1) {
+          assertEquals(expectedRow1, row);
+        } else if(rowNum >= 2) {
+          fail("should only have 2 rows");
+        }
+        rowNum++;
       }
-      rowNum++;
     }
   }
 
   public void testCurrency() throws Exception {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    Table table = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("A", DataType.MONEY).toColumn())
-      .toTable(db);
+      Table table = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("A", DataType.MONEY).toColumn())
+        .toTable(db);
 
-    table.addRow(new BigDecimal("-2341234.03450"));
-    table.addRow(37L);
-    table.addRow("10000.45");
+      table.addRow(new BigDecimal("-2341234.03450"));
+      table.addRow(37L);
+      table.addRow("10000.45");
 
-    table.reset();
+      table.reset();
 
-    List<Object> foundValues = new ArrayList<Object>();
-    Map<String, Object> row = null;
-    while((row = table.getNextRow()) != null) {
-      foundValues.add(row.get("A"));
-    }
-
-    assertEquals(Arrays.asList(
-                     new BigDecimal("-2341234.0345"),
-                     new BigDecimal("37.0000"),
-                     new BigDecimal("10000.4500")),
-                 foundValues);
+      List<Object> foundValues = new ArrayList<Object>();
+      Map<String, Object> row = null;
+      while((row = table.getNextRow()) != null) {
+        foundValues.add(row.get("A"));
+      }
 
-    try {
-      table.addRow(new BigDecimal("342523234145343543.3453"));
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // ignored
+      assertEquals(Arrays.asList(
+                       new BigDecimal("-2341234.0345"),
+                       new BigDecimal("37.0000"),
+                       new BigDecimal("10000.4500")),
+                   foundValues);
+
+      try {
+        table.addRow(new BigDecimal("342523234145343543.3453"));
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // ignored
+      }
     }
   }
 
   public void testGUID() throws Exception
   {
-    Database db = create();
-
-    Table table = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("A", DataType.GUID).toColumn())
-      .toTable(db);
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    table.addRow("{32A59F01-AA34-3E29-453F-4523453CD2E6}");
-    table.addRow("{32a59f01-aa34-3e29-453f-4523453cd2e6}");
-    table.addRow("{11111111-1111-1111-1111-111111111111}");
-    table.addRow("   {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}   ");
-    table.addRow(UUID.fromString("32a59f01-1234-3e29-4aaf-4523453cd2e6"));
+      Table table = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("A", DataType.GUID).toColumn())
+        .toTable(db);
 
-    table.reset();
+      table.addRow("{32A59F01-AA34-3E29-453F-4523453CD2E6}");
+      table.addRow("{32a59f01-aa34-3e29-453f-4523453cd2e6}");
+      table.addRow("{11111111-1111-1111-1111-111111111111}");
+      table.addRow("   {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}   ");
+      table.addRow(UUID.fromString("32a59f01-1234-3e29-4aaf-4523453cd2e6"));
 
-    List<Object> foundValues = new ArrayList<Object>();
-    Map<String, Object> row = null;
-    while((row = table.getNextRow()) != null) {
-      foundValues.add(row.get("A"));
-    }
+      table.reset();
 
-    assertEquals(Arrays.asList(
-                     "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
-                     "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
-                     "{11111111-1111-1111-1111-111111111111}",
-                     "{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}",
-                     "{32A59F01-1234-3E29-4AAF-4523453CD2E6}"),
-                 foundValues);
+      List<Object> foundValues = new ArrayList<Object>();
+      Map<String, Object> row = null;
+      while((row = table.getNextRow()) != null) {
+        foundValues.add(row.get("A"));
+      }
 
-    try {
-      table.addRow("3245234");
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // ignored
+      assertEquals(Arrays.asList(
+                       "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
+                       "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
+                       "{11111111-1111-1111-1111-111111111111}",
+                       "{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}",
+                       "{32A59F01-1234-3E29-4AAF-4523453CD2E6}"),
+                   foundValues);
+
+      try {
+        table.addRow("3245234");
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // ignored
+      }
     }
   }
 
   public void testNumeric() throws Exception
   {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    Column col = new ColumnBuilder("A", DataType.NUMERIC)
-      .setScale(4).setPrecision(8).toColumn();
-    assertTrue(col.isVariableLength());
-    
-    Table table = new TableBuilder("test")
-      .addColumn(col)
-      .addColumn(new ColumnBuilder("B", DataType.NUMERIC)
-                 .setScale(8).setPrecision(28).toColumn())
-      .toTable(db);
+      Column col = new ColumnBuilder("A", DataType.NUMERIC)
+        .setScale(4).setPrecision(8).toColumn();
+      assertTrue(col.isVariableLength());
 
-    table.addRow(new BigDecimal("-1234.03450"),
-                 new BigDecimal("23923434453436.36234219"));
-    table.addRow(37L, 37L);
-    table.addRow("1000.45", "-3452345321000");
+      Table table = new TableBuilder("test")
+        .addColumn(col)
+        .addColumn(new ColumnBuilder("B", DataType.NUMERIC)
+                   .setScale(8).setPrecision(28).toColumn())
+        .toTable(db);
 
-    table.reset();
+      table.addRow(new BigDecimal("-1234.03450"),
+                   new BigDecimal("23923434453436.36234219"));
+      table.addRow(37L, 37L);
+      table.addRow("1000.45", "-3452345321000");
 
-    List<Object> foundSmallValues = new ArrayList<Object>();
-    List<Object> foundBigValues = new ArrayList<Object>();
-    Map<String, Object> row = null;
-    while((row = table.getNextRow()) != null) {
-      foundSmallValues.add(row.get("A"));
-      foundBigValues.add(row.get("B"));
-    }
+      table.reset();
 
-    assertEquals(Arrays.asList(
-                     new BigDecimal("-1234.0345"),
-                     new BigDecimal("37.0000"),
-                     new BigDecimal("1000.4500")),
-                 foundSmallValues);
-    assertEquals(Arrays.asList(
-                     new BigDecimal("23923434453436.36234219"),
-                     new BigDecimal("37.00000000"),
-                     new BigDecimal("-3452345321000.00000000")),
-                 foundBigValues);
+      List<Object> foundSmallValues = new ArrayList<Object>();
+      List<Object> foundBigValues = new ArrayList<Object>();
+      Map<String, Object> row = null;
+      while((row = table.getNextRow()) != null) {
+        foundSmallValues.add(row.get("A"));
+        foundBigValues.add(row.get("B"));
+      }
 
-    try {
-      table.addRow(new BigDecimal("3245234.234"),
-                   new BigDecimal("3245234.234"));
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // ignored
+      assertEquals(Arrays.asList(
+                       new BigDecimal("-1234.0345"),
+                       new BigDecimal("37.0000"),
+                       new BigDecimal("1000.4500")),
+                   foundSmallValues);
+      assertEquals(Arrays.asList(
+                       new BigDecimal("23923434453436.36234219"),
+                       new BigDecimal("37.00000000"),
+                       new BigDecimal("-3452345321000.00000000")),
+                   foundBigValues);
+
+      try {
+        table.addRow(new BigDecimal("3245234.234"),
+                     new BigDecimal("3245234.234"));
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // ignored
+      }
     }
   }
 
   public void testFixedNumeric() throws Exception
   {
-    Database db = openCopy(new File("test/data/fixedNumericTest.mdb"));
-    Table t = db.getTable("test");
-
-    boolean first = true;
-    for(Column col : t.getColumns()) {
-      if(first) {
-        assertTrue(col.isVariableLength());
-        assertEquals(DataType.MEMO, col.getType());
-        first = false;
-      } else {
-        assertFalse(col.isVariableLength());
-        assertEquals(DataType.NUMERIC, col.getType());
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.FIXED_NUMERIC)) {
+      Database db = openCopy(testDB);
+      Table t = db.getTable("test");
+
+      boolean first = true;
+      for(Column col : t.getColumns()) {
+        if(first) {
+          assertTrue(col.isVariableLength());
+          assertEquals(DataType.MEMO, col.getType());
+          first = false;
+        } else {
+          assertFalse(col.isVariableLength());
+          assertEquals(DataType.NUMERIC, col.getType());
+        }
       }
-    }
-      
-    Map<String, Object> row = t.getNextRow();
-    assertEquals("some data", row.get("col1"));
-    assertEquals(new BigDecimal("1"), row.get("col2"));
-    assertEquals(new BigDecimal("0"), row.get("col3"));
-    assertEquals(new BigDecimal("0"), row.get("col4"));
-    assertEquals(new BigDecimal("4"), row.get("col5"));
-    assertEquals(new BigDecimal("-1"), row.get("col6"));
-    assertEquals(new BigDecimal("1"), row.get("col7"));
-
-    Object[] tmpRow = new Object[]{
-      "foo", new BigDecimal("1"), new BigDecimal(3), new BigDecimal("13"),
-      new BigDecimal("-17"), new BigDecimal("0"), new BigDecimal("8734")};
-    t.addRow(tmpRow);
-    t.reset();
-
-    t.getNextRow();
-    row = t.getNextRow();
-    assertEquals(tmpRow[0], row.get("col1"));
-    assertEquals(tmpRow[1], row.get("col2"));
-    assertEquals(tmpRow[2], row.get("col3"));
-    assertEquals(tmpRow[3], row.get("col4"));
-    assertEquals(tmpRow[4], row.get("col5"));
-    assertEquals(tmpRow[5], row.get("col6"));
-    assertEquals(tmpRow[6], row.get("col7"));
-    
-    db.close();
 
+      Map<String, Object> row = t.getNextRow();
+      assertEquals("some data", row.get("col1"));
+      assertEquals(new BigDecimal("1"), row.get("col2"));
+      assertEquals(new BigDecimal("0"), row.get("col3"));
+      assertEquals(new BigDecimal("0"), row.get("col4"));
+      assertEquals(new BigDecimal("4"), row.get("col5"));
+      assertEquals(new BigDecimal("-1"), row.get("col6"));
+      assertEquals(new BigDecimal("1"), row.get("col7"));
+
+      Object[] tmpRow = new Object[]{
+        "foo", new BigDecimal("1"), new BigDecimal(3), new BigDecimal("13"),
+        new BigDecimal("-17"), new BigDecimal("0"), new BigDecimal("8734")};
+      t.addRow(tmpRow);
+      t.reset();
+
+      t.getNextRow();
+      row = t.getNextRow();
+      assertEquals(tmpRow[0], row.get("col1"));
+      assertEquals(tmpRow[1], row.get("col2"));
+      assertEquals(tmpRow[2], row.get("col3"));
+      assertEquals(tmpRow[3], row.get("col4"));
+      assertEquals(tmpRow[4], row.get("col5"));
+      assertEquals(tmpRow[5], row.get("col6"));
+      assertEquals(tmpRow[6], row.get("col7"));
+
+      db.close();
+    }
   }  
 
   public void testMultiPageTableDef() throws Exception
   {
-    List<Column> columns = open().getTable("Table2").getColumns();
-    assertEquals(89, columns.size());
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      List<Column> columns = open(testDB).getTable("Table2").getColumns();
+      assertEquals(89, columns.size());
+    }
   }
 
   public void testOverflow() throws Exception
   {
-    Database mdb = open(new File("test/data/overflowTest.mdb"));
-    Table table = mdb.getTable("Table1");
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.OVERFLOW)) {
+      Database mdb = open(testDB);
+      Table table = mdb.getTable("Table1");
 
-    // 7 rows, 3 and 5 are overflow
-    table.getNextRow();
-    table.getNextRow();
+      // 7 rows, 3 and 5 are overflow
+      table.getNextRow();
+      table.getNextRow();
 
-    Map<String, Object> row = table.getNextRow();
-    assertEquals(Arrays.<Object>asList(
-                     null, "row3col3", null, null, null, null, null,
-                     "row3col9", null),
-                 new ArrayList<Object>(row.values()));
+      Map<String, Object> row = table.getNextRow();
+      assertEquals(Arrays.<Object>asList(
+                       null, "row3col3", null, null, null, null, null,
+                       "row3col9", null),
+                   new ArrayList<Object>(row.values()));
 
-    table.getNextRow();
+      table.getNextRow();
 
-    row = table.getNextRow();
-    assertEquals(Arrays.<Object>asList(
-                     null, "row5col2", null, null, null, null, null, null,
-                     null),
-                 new ArrayList<Object>(row.values()));
+      row = table.getNextRow();
+      assertEquals(Arrays.<Object>asList(
+                       null, "row5col2", null, null, null, null, null, null,
+                       null),
+                   new ArrayList<Object>(row.values()));
 
-    table.reset();
-    assertRowCount(7, table);
-    
+      table.reset();
+      assertRowCount(7, table);
+    }
   }
 
   public void testLongValueAsMiddleColumn() throws Exception
   {
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      Table newTable = new TableBuilder("NewTable")
+        .addColumn(new ColumnBuilder("a").setSQLType(Types.INTEGER).toColumn())
+        .addColumn(new ColumnBuilder("b").setSQLType(Types.LONGVARCHAR).toColumn())
+        .addColumn(new ColumnBuilder("c").setSQLType(Types.VARCHAR).toColumn())
+        .toTable(db);
 
-    Database db = create();
-    Table newTable = new TableBuilder("NewTable")
-      .addColumn(new ColumnBuilder("a").setSQLType(Types.INTEGER).toColumn())
-      .addColumn(new ColumnBuilder("b").setSQLType(Types.LONGVARCHAR).toColumn())
-      .addColumn(new ColumnBuilder("c").setSQLType(Types.VARCHAR).toColumn())
-      .toTable(db);
-    
-    String lval = createString(2000); // "--2000 chars long text--";
-    String tval = createString(40); // "--40chars long text--";
-    newTable.addRow(new Integer(1), lval, tval);
-
-    newTable = db.getTable("NewTable");
-    Map<String, Object> readRow = newTable.getNextRow();
-    assertEquals(new Integer(1), readRow.get("a"));
-    assertEquals(lval, readRow.get("b"));
-    assertEquals(tval, readRow.get("c"));
+      String lval = createString(2000); // "--2000 chars long text--";
+      String tval = createString(40); // "--40chars long text--";
+      newTable.addRow(new Integer(1), lval, tval);
 
+      newTable = db.getTable("NewTable");
+      Map<String, Object> readRow = newTable.getNextRow();
+      assertEquals(new Integer(1), readRow.get("a"));
+      assertEquals(lval, readRow.get("b"));
+      assertEquals(tval, readRow.get("c"));
+    }
   }
 
 
   public void testUsageMapPromotion() throws Exception {
-    Database db = openCopy(new File("test/data/testPromotion.mdb"));
-    Table t = db.getTable("jobDB1");
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.PROMOTION)) {
+      Database db = openCopy(testDB);
+      Table t = db.getTable("jobDB1");
 
-    String lval = createString(255); // "--255 chars long text--";
+      String lval = createString(255); // "--255 chars long text--";
 
-    for(int i = 0; i < 1000; ++i) {
-      t.addRow(i, 13, 57, 47.0d, lval, lval, lval, lval, lval, lval);
-    }
+      if (FileFormat.V2007.equals(testDB.getExpectedFileFormat())) {
+        // @todo Field order differs with V2007
+        System.err.println("\n*** TODO: " + getName()
+                + "(): Is OK that " + testDB.getExpectedFileFormat().name() + " field order differs?  ***");
+      }
 
-    Set<Integer> ids = new HashSet<Integer>();
-    for(Map<String,Object> row : t) {
-      ids.add((Integer)row.get("ID"));
-    }
-    assertEquals(1000, ids.size());
+      for(int i = 0; i < 1000; ++i) {
+        if (FileFormat.V2007.equals(testDB.getExpectedFileFormat())) {
+          // @todo Field order differs with V2007
+          t.addRow(i, 13, 57, lval, lval, lval, lval, lval, lval, 47.0d);
+        } else {
+          t.addRow(i, 13, 57, 47.0d, lval, lval, lval, lval, lval, lval);
+        }
+      }
+
+      Set<Integer> ids = new HashSet<Integer>();
+      for(Map<String,Object> row : t) {
+        ids.add((Integer)row.get("ID"));
+      }
+      assertEquals(1000, ids.size());
 
-    db.close();
+      db.close();
+    }
   }  
 
 
   public void testLargeTableDef() throws Exception {
-    final int numColumns = 90;
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    List<Column> columns = new ArrayList<Column>();
-    List<String> colNames = new ArrayList<String>();
-    for(int i = 0; i < numColumns; ++i) {
-      String colName = "MyColumnName" + i;
-      colNames.add(colName);
-      columns.add(new ColumnBuilder(colName, DataType.TEXT).toColumn());
-    }
+      final int numColumns = 90;
 
-    db.createTable("test", columns);
+      List<Column> columns = new ArrayList<Column>();
+      List<String> colNames = new ArrayList<String>();
+      for(int i = 0; i < numColumns; ++i) {
+        String colName = "MyColumnName" + i;
+        colNames.add(colName);
+        columns.add(new ColumnBuilder(colName, DataType.TEXT).toColumn());
+      }
 
-    Table t = db.getTable("test");
+      db.createTable("test", columns);
 
-    List<String> row = new ArrayList<String>();
-    Map<String,Object> expectedRowData = new LinkedHashMap<String, Object>();
-    for(int i = 0; i < numColumns; ++i) {
-      String value = "" + i + " some row data";
-      row.add(value);
-      expectedRowData.put(colNames.get(i), value);
-    }
+      Table t = db.getTable("test");
 
-    t.addRow(row.toArray());
+      List<String> row = new ArrayList<String>();
+      Map<String,Object> expectedRowData = new LinkedHashMap<String, Object>();
+      for(int i = 0; i < numColumns; ++i) {
+        String value = "" + i + " some row data";
+        row.add(value);
+        expectedRowData.put(colNames.get(i), value);
+      }
 
-    t.reset();
-    assertEquals(expectedRowData, t.getNextRow());
-    
-    db.close();
+      t.addRow(row.toArray());
+
+      t.reset();
+      assertEquals(expectedRowData, t.getNextRow());
+
+      db.close();
+    }
   }
 
   public void testAutoNumber() throws Exception {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    Table table = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("a", DataType.LONG)
-                .setAutoNumber(true).toColumn())
-      .addColumn(new ColumnBuilder("b", DataType.TEXT).toColumn())
-      .toTable(db);
+      Table table = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("a", DataType.LONG)
+                  .setAutoNumber(true).toColumn())
+        .addColumn(new ColumnBuilder("b", DataType.TEXT).toColumn())
+        .toTable(db);
 
-    doTestAutoNumber(table);
-    
-    db.close();
+      doTestAutoNumber(table);
+
+      db.close();
+    }
   }  
 
   public void testAutoNumberPK() throws Exception {
-    Database db = openCopy(new File("test/data/test.mdb"));
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      Database db = openCopy(testDB);
 
-    Table table = db.getTable("Table3");
+      Table table = db.getTable("Table3");
 
-    doTestAutoNumber(table);
-    
-    db.close();
+      doTestAutoNumber(table);
+
+      db.close();
+    }
   }  
 
   private void doTestAutoNumber(Table table) throws Exception
@@ -831,69 +907,71 @@ public class DatabaseTest extends TestCase {
   }
   
   public void testWriteAndReadDate() throws Exception {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
 
-    Table table = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME)
-                 .toColumn())
-      .toTable(db);
-    
-    // since jackcess does not really store millis, shave them off before
-    // storing the current date/time
-    long curTimeNoMillis = (System.currentTimeMillis() / 1000L);
-    curTimeNoMillis *= 1000L;
-    
-    DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
-    List<Date> dates =
-      new ArrayList<Date>(
-          Arrays.asList(
-              df.parse("19801231 00:00:00"),
-              df.parse("19930513 14:43:27"),
-              null,
-              df.parse("20210102 02:37:00"),
-              new Date(curTimeNoMillis)));
-
-    Calendar c = Calendar.getInstance();
-    for(int year = 1801; year < 2050; year +=3) {
-      for(int month = 0; month <= 12; ++month) {
-        for(int day = 1; day < 29; day += 3) {
-          c.clear();
-          c.set(Calendar.YEAR, year);
-          c.set(Calendar.MONTH, month);
-          c.set(Calendar.DAY_OF_MONTH, day);
-          dates.add(c.getTime());
+      Table table = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME)
+                   .toColumn())
+        .toTable(db);
+
+      // since jackcess does not really store millis, shave them off before
+      // storing the current date/time
+      long curTimeNoMillis = (System.currentTimeMillis() / 1000L);
+      curTimeNoMillis *= 1000L;
+
+      DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+      List<Date> dates =
+        new ArrayList<Date>(
+            Arrays.asList(
+                df.parse("19801231 00:00:00"),
+                df.parse("19930513 14:43:27"),
+                null,
+                df.parse("20210102 02:37:00"),
+                new Date(curTimeNoMillis)));
+
+      Calendar c = Calendar.getInstance();
+      for(int year = 1801; year < 2050; year +=3) {
+        for(int month = 0; month <= 12; ++month) {
+          for(int day = 1; day < 29; day += 3) {
+            c.clear();
+            c.set(Calendar.YEAR, year);
+            c.set(Calendar.MONTH, month);
+            c.set(Calendar.DAY_OF_MONTH, day);
+            dates.add(c.getTime());
+          }
         }
       }
-    }
 
-    for(Date d : dates) {
-      table.addRow("row " + d, d);
-    }
+      for(Date d : dates) {
+        table.addRow("row " + d, d);
+      }
 
-    List<Date> foundDates = new ArrayList<Date>();
-    for(Map<String,Object> row : table) {
-      foundDates.add((Date)row.get("date"));
-    }
+      List<Date> foundDates = new ArrayList<Date>();
+      for(Map<String,Object> row : table) {
+        foundDates.add((Date)row.get("date"));
+      }
 
-    assertEquals(dates.size(), foundDates.size());
-    for(int i = 0; i < dates.size(); ++i) {
-      Date expected = dates.get(i);
-      Date found = foundDates.get(i);
-      if(expected == null) {
-        assertNull(found);
-      } else {
-        // there are some rounding issues due to dates being stored as
-        // doubles, but it results in a 1 millisecond difference, so i'm not
-        // going to worry about it
-        long expTime = expected.getTime();
-        long foundTime = found.getTime();
-        try {
-          assertTrue((expTime == foundTime) ||
-                     (Math.abs(expTime - foundTime) <= 1));
-        } catch(Error e) {
-          System.err.println("Expected " + expTime + ", found " + foundTime);
-          throw e;
+      assertEquals(dates.size(), foundDates.size());
+      for(int i = 0; i < dates.size(); ++i) {
+        Date expected = dates.get(i);
+        Date found = foundDates.get(i);
+        if(expected == null) {
+          assertNull(found);
+        } else {
+          // there are some rounding issues due to dates being stored as
+          // doubles, but it results in a 1 millisecond difference, so i'm not
+          // going to worry about it
+          long expTime = expected.getTime();
+          long foundTime = found.getTime();
+          try {
+            assertTrue((expTime == foundTime) ||
+                       (Math.abs(expTime - foundTime) <= 1));
+          } catch(Error e) {
+            System.err.println("Expected " + expTime + ", found " + foundTime);
+            throw e;
+          }
         }
       }
     }
@@ -901,128 +979,143 @@ public class DatabaseTest extends TestCase {
 
   public void testSystemTable() throws Exception
   {
-    Database db = create();
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+
+      if (!FileFormat.V2003.equals(fileFormat)
+              && !FileFormat.V2007.equals(fileFormat)) {
+        assertNotNull("file format: " + fileFormat, db.getSystemTable("MSysAccessObjects"));
+      } else {
+        // @todo Does is matter that v2003, v2007 template files have no "MSysAccessObjects" table?
+        System.err.println("\n*** TODO: " + getName()
+                + "(): Is OK that " + fileFormat.name() + " template file has no \"MSysAccessObjects\" table?  ***");
+        assertNull("file format: " + fileFormat, db.getSystemTable("MSysAccessObjects"));
+      }
 
-    assertNotNull(db.getSystemTable("MSysAccessObjects"));
-    assertNotNull(db.getSystemTable("MSysObjects"));
-    assertNotNull(db.getSystemTable("MSysQueries"));
-    assertNotNull(db.getSystemTable("MSysACES"));
-    assertNotNull(db.getSystemTable("MSysRelationships"));
+      assertNotNull(db.getSystemTable("MSysObjects"));
+      assertNotNull(db.getSystemTable("MSysQueries"));
+      assertNotNull(db.getSystemTable("MSysACES"));
+      assertNotNull(db.getSystemTable("MSysRelationships"));
 
-    assertNull(db.getSystemTable("MSysBogus"));
+      assertNull(db.getSystemTable("MSysBogus"));
 
-    db.close();
+      db.close();
+    }
   }
 
   public void testUpdateRow() throws Exception
   {
-    Database db = create();
-
-    Table t = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("id", DataType.LONG)
-                 .setAutoNumber(true).toColumn())
-      .addColumn(new ColumnBuilder("data", DataType.TEXT)
-                 .setLength(JetFormat.TEXT_FIELD_MAX_LENGTH).toColumn())
-      .toTable(db);
+    for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+
+      Table t = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("id", DataType.LONG)
+                   .setAutoNumber(true).toColumn())
+        .addColumn(new ColumnBuilder("data", DataType.TEXT)
+                   .setLength(JetFormat.TEXT_FIELD_MAX_LENGTH).toColumn())
+        .toTable(db);
 
-    for(int i = 0; i < 10; ++i) {
-      t.addRow("row" + i, Column.AUTO_NUMBER, "initial data");
-    }
+      for(int i = 0; i < 10; ++i) {
+        t.addRow("row" + i, Column.AUTO_NUMBER, "initial data");
+      }
 
-    Cursor c = Cursor.createCursor(t);
-    c.reset();
-    c.moveNextRows(2);
-    Map<String,Object> row = c.getCurrentRow();
+      Cursor c = Cursor.createCursor(t);
+      c.reset();
+      c.moveNextRows(2);
+      Map<String,Object> row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row1", 
-                                   "id", 2,
-                                   "data", "initial data"),
-                 row);
+      assertEquals(createExpectedRow("name", "row1",
+                                     "id", 2,
+                                     "data", "initial data"),
+                   row);
 
-    c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "new data");
+      c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "new data");
 
-    c.moveNextRows(3);
-    row = c.getCurrentRow();
+      c.moveNextRows(3);
+      row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row4", 
-                                   "id", 5,
-                                   "data", "initial data"),
-                 row);
+      assertEquals(createExpectedRow("name", "row4",
+                                     "id", 5,
+                                     "data", "initial data"),
+                   row);
 
-    c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "a larger amount of new data");
+      c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "a larger amount of new data");
 
-    c.reset();
-    c.moveNextRows(2);
-    row = c.getCurrentRow();
+      c.reset();
+      c.moveNextRows(2);
+      row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row1", 
-                                   "id", 2,
-                                   "data", "new data"),
-                 row);
+      assertEquals(createExpectedRow("name", "row1",
+                                     "id", 2,
+                                     "data", "new data"),
+                   row);
 
-    c.moveNextRows(3);
-    row = c.getCurrentRow();
+      c.moveNextRows(3);
+      row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row4", 
-                                   "id", 5,
-                                   "data", "a larger amount of new data"),
-                 row);
+      assertEquals(createExpectedRow("name", "row4",
+                                     "id", 5,
+                                     "data", "a larger amount of new data"),
+                   row);
 
-    t.reset();
-    
-    String str = createString(100);
-    for(int i = 10; i < 50; ++i) {
-      t.addRow("row" + i, Column.AUTO_NUMBER, "big data_" + str);
-    }
+      t.reset();
 
-    c.reset();
-    c.moveNextRows(9);
-    row = c.getCurrentRow();
+      String str = createString(100);
+      for(int i = 10; i < 50; ++i) {
+        t.addRow("row" + i, Column.AUTO_NUMBER, "big data_" + str);
+      }
+
+      c.reset();
+      c.moveNextRows(9);
+      row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row8", 
-                                   "id", 9,
-                                   "data", "initial data"),
-                 row);
+      assertEquals(createExpectedRow("name", "row8",
+                                     "id", 9,
+                                     "data", "initial data"),
+                   row);
 
-    String newText = "updated big data_" + createString(200);
+      String newText = "updated big data_" + createString(200);
 
-    c.setCurrentRowValue(t.getColumn("data"), newText);
+      c.setCurrentRowValue(t.getColumn("data"), newText);
 
-    c.reset();
-    c.moveNextRows(9);
-    row = c.getCurrentRow();
+      c.reset();
+      c.moveNextRows(9);
+      row = c.getCurrentRow();
 
-    assertEquals(createExpectedRow("name", "row8", 
-                                   "id", 9,
-                                   "data", newText),
-                 row);
+      assertEquals(createExpectedRow("name", "row8",
+                                     "id", 9,
+                                     "data", newText),
+                   row);
 
-    db.close();
+      db.close();
+    }
   }
 
   public void testFixedText() throws Exception
   {
-    Database db = openCopy(new File("test/data/fixedTextTest.mdb"));
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.FIXED_TEXT)) {
+      Database db = openCopy(testDB);
 
-    Table t = db.getTable("users");
-    Column c = t.getColumn("c_flag_");
-    assertEquals(DataType.TEXT, c.getType());
-    assertEquals(false, c.isVariableLength());
-    assertEquals(2, c.getLength());
+      Table t = db.getTable("users");
+      Column c = t.getColumn("c_flag_");
+      assertEquals(DataType.TEXT, c.getType());
+      assertEquals(false, c.isVariableLength());
+      assertEquals(2, c.getLength());
 
-    Map<String,Object> row = t.getNextRow();
-    assertEquals("N", row.get("c_flag_"));
+      Map<String,Object> row = t.getNextRow();
+      assertEquals("N", row.get("c_flag_"));
 
-    t.addRow(3, "testFixedText", "boo", "foo", "bob", 3, 5, 9, "Y", 
-             new Date());
+      t.addRow(3, "testFixedText", "boo", "foo", "bob", 3, 5, 9, "Y",
+               new Date());
 
-    t.getNextRow();
-    row = t.getNextRow();
-    assertEquals("testFixedText", row.get("c_user_login"));
-    assertEquals("Y", row.get("c_flag_"));
+      t.getNextRow();
+      row = t.getNextRow();
+      assertEquals("testFixedText", row.get("c_user_login"));
+      assertEquals("Y", row.get("c_flag_"));
 
-    db.close();
+      db.close();
+    }
   }
     
   static Object[] createTestRow(String col1Val) {
@@ -1199,5 +1292,5 @@ public class DatabaseTest extends TestCase {
       istream.close();
     }
   }
-  
+
 }
index 8b46a8ae3dad7fb8253b59b71881cf13f6690c87..488f6bdff1371e846ee3feff56c791d952340e37 100644 (file)
@@ -35,6 +35,7 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
+import static com.healthmarketscience.jackcess.Database.*;
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
 
 /**
@@ -49,94 +50,96 @@ public class ErrorHandlerTest extends TestCase
 
   public void testErrorHandler() throws Exception
   {
-    Database db = create();
-
-    Table table = 
-      new TableBuilder("test")
-      .addColumn(new ColumnBuilder("col", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("val", DataType.LONG).toColumn())
-      .toTable(db);
-
-    table.addRow("row1", 1);
-    table.addRow("row2", 2);
-    table.addRow("row3", 3);
-
-    assertTable(createExpectedTable(
-                    createExpectedRow("col", "row1",
-                                      "val", 1),
-                    createExpectedRow("col", "row2",
-                                      "val", 2),
-                    createExpectedRow("col", "row3",
-                                      "val", 3)),
-                table);
-
-
-    replaceColumn(table, "val");
-
-    table.reset();
-    try {
-      table.getNextRow();
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // success
-    }
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+
+      Table table =
+        new TableBuilder("test")
+        .addColumn(new ColumnBuilder("col", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("val", DataType.LONG).toColumn())
+        .toTable(db);
+
+      table.addRow("row1", 1);
+      table.addRow("row2", 2);
+      table.addRow("row3", 3);
+
+      assertTable(createExpectedTable(
+                      createExpectedRow("col", "row1",
+                                        "val", 1),
+                      createExpectedRow("col", "row2",
+                                        "val", 2),
+                      createExpectedRow("col", "row3",
+                                        "val", 3)),
+                  table);
+
+
+      replaceColumn(table, "val");
+
+      table.reset();
+      try {
+        table.getNextRow();
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // success
+      }
 
-    table.reset();
-    table.setErrorHandler(new ReplacementErrorHandler());
-
-    assertTable(createExpectedTable(
-                    createExpectedRow("col", "row1",
-                                      "val", null),
-                    createExpectedRow("col", "row2",
-                                      "val", null),
-                    createExpectedRow("col", "row3",
-                                      "val", null)),
-                table);
-
-    Cursor c1 = Cursor.createCursor(table);
-    Cursor c2 = Cursor.createCursor(table);
-    Cursor c3 = Cursor.createCursor(table);
-
-    c2.setErrorHandler(new DebugErrorHandler("#error"));
-    c3.setErrorHandler(Database.DEFAULT_ERROR_HANDLER);
-
-    assertCursor(createExpectedTable(
-                    createExpectedRow("col", "row1",
-                                      "val", null),
-                    createExpectedRow("col", "row2",
-                                      "val", null),
-                    createExpectedRow("col", "row3",
-                                      "val", null)),
-                c1);
-
-    assertCursor(createExpectedTable(
-                    createExpectedRow("col", "row1",
-                                      "val", "#error"),
-                    createExpectedRow("col", "row2",
-                                      "val", "#error"),
-                    createExpectedRow("col", "row3",
-                                      "val", "#error")),
-                c2);
-
-    try {
-      c3.getNextRow();
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // success
-    }
+      table.reset();
+      table.setErrorHandler(new ReplacementErrorHandler());
+
+      assertTable(createExpectedTable(
+                      createExpectedRow("col", "row1",
+                                        "val", null),
+                      createExpectedRow("col", "row2",
+                                        "val", null),
+                      createExpectedRow("col", "row3",
+                                        "val", null)),
+                  table);
+
+      Cursor c1 = Cursor.createCursor(table);
+      Cursor c2 = Cursor.createCursor(table);
+      Cursor c3 = Cursor.createCursor(table);
+
+      c2.setErrorHandler(new DebugErrorHandler("#error"));
+      c3.setErrorHandler(Database.DEFAULT_ERROR_HANDLER);
+
+      assertCursor(createExpectedTable(
+                      createExpectedRow("col", "row1",
+                                        "val", null),
+                      createExpectedRow("col", "row2",
+                                        "val", null),
+                      createExpectedRow("col", "row3",
+                                        "val", null)),
+                  c1);
+
+      assertCursor(createExpectedTable(
+                      createExpectedRow("col", "row1",
+                                        "val", "#error"),
+                      createExpectedRow("col", "row2",
+                                        "val", "#error"),
+                      createExpectedRow("col", "row3",
+                                        "val", "#error")),
+                  c2);
+
+      try {
+        c3.getNextRow();
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // success
+      }
 
-    table.setErrorHandler(null);
-    c1.setErrorHandler(null);
-    c1.reset();
-    try {
-      c1.getNextRow();
-      fail("IOException should have been thrown");
-    } catch(IOException e) {
-      // success
-    }
+      table.setErrorHandler(null);
+      c1.setErrorHandler(null);
+      c1.reset();
+      try {
+        c1.getNextRow();
+        fail("IOException should have been thrown");
+      } catch(IOException e) {
+        // success
+      }
 
 
-    db.close();
+      db.close();
+    }
   }
 
   @SuppressWarnings("unchecked")
index ad2c8517044600870d2849809d9cd3b025392a6c..6403077a1ddacb269bec23fbc7e8e75a6c2b50da 100644 (file)
@@ -39,6 +39,7 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
+import static com.healthmarketscience.jackcess.Database.*;
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
 
 /** 
@@ -53,75 +54,81 @@ public class ImportTest extends TestCase
 
   public void testImportFromFile() throws Exception
   {
-    Database db = create();
-    db.importFile("test", new File("test/data/sample-input.tab"), "\\t");
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      db.importFile("test", new File("test/data/sample-input.tab"), "\\t");
+    }
   }
 
   public void testImportFromFileWithOnlyHeaders() throws Exception
   {
-    Database db = create();
-    db.importFile("test", new File("test/data/sample-input-only-headers.tab"),
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat);
+      db.importFile("test", new File("test/data/sample-input-only-headers.tab"),
                   "\\t");
+    }
   }
 
   public void testCopySqlHeaders() throws Exception
   {
-    TestResultSet rs = new TestResultSet();
-
-    rs.addColumn(Types.INTEGER, "col1");
-    rs.addColumn(Types.VARCHAR, "col2", 60, 0, 0);
-    rs.addColumn(Types.VARCHAR, "col3", 500, 0, 0);
-    rs.addColumn(Types.BINARY, "col4", 128, 0, 0);
-    rs.addColumn(Types.BINARY, "col5", 512, 0, 0);
-    rs.addColumn(Types.NUMERIC, "col6", 0, 7, 15);
-    rs.addColumn(Types.VARCHAR, "col7", Integer.MAX_VALUE, 0, 0);
-
-    Database db = create();
-    db.copyTable("Test1", (ResultSet)Proxy.newProxyInstance(
-                     Thread.currentThread().getContextClassLoader(),
-                     new Class[]{ResultSet.class},
-                     rs));
-
-    Table t = db.getTable("Test1");
-    List<Column> columns = t.getColumns();
-    assertEquals(7, columns.size());
-
-    Column c = columns.get(0);
-    assertEquals("col1", c.getName());
-    assertEquals(DataType.LONG, c.getType());
-
-    c = columns.get(1);
-    assertEquals("col2", c.getName());
-    assertEquals(DataType.TEXT, c.getType());
-    assertEquals(120, c.getLength());
-
-    c = columns.get(2);
-    assertEquals("col3", c.getName());
-    assertEquals(DataType.MEMO, c.getType());
-    assertEquals(0, c.getLength());
-
-    c = columns.get(3);
-    assertEquals("col4", c.getName());
-    assertEquals(DataType.BINARY, c.getType());
-    assertEquals(128, c.getLength());
-    
-    c = columns.get(4);
-    assertEquals("col5", c.getName());
-    assertEquals(DataType.OLE, c.getType());
-    assertEquals(0, c.getLength());
-    
-    c = columns.get(5);
-    assertEquals("col6", c.getName());
-    assertEquals(DataType.NUMERIC, c.getType());
-    assertEquals(17, c.getLength());
-    assertEquals(7, c.getScale());
-    assertEquals(15, c.getPrecision());
-    
-    c = columns.get(6);
-    assertEquals("col7", c.getName());
-    assertEquals(DataType.MEMO, c.getType());
-    assertEquals(0, c.getLength());
-
+    for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+
+      TestResultSet rs = new TestResultSet();
+
+      rs.addColumn(Types.INTEGER, "col1");
+      rs.addColumn(Types.VARCHAR, "col2", 60, 0, 0);
+      rs.addColumn(Types.VARCHAR, "col3", 500, 0, 0);
+      rs.addColumn(Types.BINARY, "col4", 128, 0, 0);
+      rs.addColumn(Types.BINARY, "col5", 512, 0, 0);
+      rs.addColumn(Types.NUMERIC, "col6", 0, 7, 15);
+      rs.addColumn(Types.VARCHAR, "col7", Integer.MAX_VALUE, 0, 0);
+
+      Database db = create(fileFormat);
+      db.copyTable("Test1", (ResultSet)Proxy.newProxyInstance(
+                       Thread.currentThread().getContextClassLoader(),
+                       new Class[]{ResultSet.class},
+                       rs));
+
+      Table t = db.getTable("Test1");
+      List<Column> columns = t.getColumns();
+      assertEquals(7, columns.size());
+
+      Column c = columns.get(0);
+      assertEquals("col1", c.getName());
+      assertEquals(DataType.LONG, c.getType());
+
+      c = columns.get(1);
+      assertEquals("col2", c.getName());
+      assertEquals(DataType.TEXT, c.getType());
+      assertEquals(120, c.getLength());
+
+      c = columns.get(2);
+      assertEquals("col3", c.getName());
+      assertEquals(DataType.MEMO, c.getType());
+      assertEquals(0, c.getLength());
+
+      c = columns.get(3);
+      assertEquals("col4", c.getName());
+      assertEquals(DataType.BINARY, c.getType());
+      assertEquals(128, c.getLength());
+
+      c = columns.get(4);
+      assertEquals("col5", c.getName());
+      assertEquals(DataType.OLE, c.getType());
+      assertEquals(0, c.getLength());
+
+      c = columns.get(5);
+      assertEquals("col6", c.getName());
+      assertEquals(DataType.NUMERIC, c.getType());
+      assertEquals(17, c.getLength());
+      assertEquals(7, c.getScale());
+      assertEquals(15, c.getPrecision());
+
+      c = columns.get(6);
+      assertEquals("col7", c.getName());
+      assertEquals(DataType.MEMO, c.getType());
+      assertEquals(0, c.getLength());
+    }
   }
 
 
index 2b9d6667b4c842e167f287dee0cd1e52a6a4e655..0e1efd76208ad969ba0ad4fd1353c99078263c7d 100644 (file)
@@ -27,7 +27,6 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess;
 
-import java.io.File;
 import java.lang.reflect.Field;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
@@ -40,6 +39,7 @@ import java.util.regex.Pattern;
 import junit.framework.TestCase;
 
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
 
 
 /**
@@ -66,19 +66,21 @@ public class IndexCodesTest extends TestCase {
 
   public void testIndexCodes() throws Exception
   {
-    Database db = open(new File("test/data/testIndexCodes.mdb"));
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX_CODES)) {
+      Database db = open(testDB);
 
-    for(Table t : db) {
-      for(Index index : t.getIndexes()) {
-//         System.out.println("Checking " + t.getName() + "." + index.getName());
-        checkIndexEntries(t, index);
+      for(Table t : db) {
+        for(Index index : t.getIndexes()) {
+  //         System.out.println("Checking " + t.getName() + "." + index.getName());
+          checkIndexEntries(testDB, t, index);
+        }
       }
+
+      db.close();
     }
-    
-    db.close();
   }
 
-  private static void checkIndexEntries(Table t, Index index) throws Exception
+  private static void checkIndexEntries(final TestDB testDB, Table t, Index index) throws Exception
   {
 //         index.initialize();
 //         System.out.println("Ind " + index);
@@ -90,7 +92,7 @@ public class IndexCodesTest extends TestCase {
       Cursor.Position curPos = cursor.getSavepoint().getCurrentPosition();
       boolean success = false;
       try {
-        findRow(t, index, row, curPos);
+        findRow(testDB, t, index, row, curPos);
         success = true;
       } finally {
         if(!success) {
@@ -103,7 +105,7 @@ public class IndexCodesTest extends TestCase {
     
   }
   
-  private static void findRow(Table t, Index index,
+  private static void findRow(final TestDB testDB, Table t, Index index,
                               Map<String,Object> expectedRow,
                               Cursor.Position expectedPos)
     throws Exception
@@ -123,7 +125,7 @@ public class IndexCodesTest extends TestCase {
         return;
       }
     }
-    fail("Could not find expected row " + expectedRow + " starting at " +
+    fail("testDB: " + testDB + ";\nCould not find expected row " + expectedRow + " starting at " +
          entryToString(startPos));
   }
 
@@ -140,120 +142,134 @@ public class IndexCodesTest extends TestCase {
 
   public void x_testCreateIsoFile() throws Exception
   {
-    Database db = create(true);
+    for (final Database.FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat, true);
 
-    Table t = new TableBuilder("test")
-      .addColumn(new ColumnBuilder("row", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
-      .toTable(db);
-    
-    for(int i = 0; i < 256; ++i) {
-      String str = "AA" + ((char)i) + "AA";
-      t.addRow("row" + i, str);
-    }
+      Table t = new TableBuilder("test")
+        .addColumn(new ColumnBuilder("row", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
+        .toTable(db);
+
+      for(int i = 0; i < 256; ++i) {
+        String str = "AA" + ((char)i) + "AA";
+        t.addRow("row" + i, str);
+      }
 
-    db.close();
+      db.close();
+    }
   }
 
   public void x_testCreateAltIsoFile() throws Exception
   {
-    Database db = openCopy(new File("/tmp/test_ind.mdb"), true);
-
-    Table t = db.getTable("Table1");
+    for (final TestDB testDB : TestDB.getSupportedForBasename(null)) {
+      // @todo Bank test dbFiles and create new TestDB here.
+      //Database db = openCopy(new File("/tmp/test_ind.mdb"), true);
+      Database db = openCopy(testDB, true);
+
+      Table t = db.getTable("Table1");
+
+      for(int i = 0; i < 256; ++i) {
+        String str = "AA" + ((char)i) + "AA";
+        t.addRow("row" + i, str,
+                 (byte)42 + i, (short)53 + i, 13 * i,
+                 (6.7d / i), null, null, true);
+      }
 
-    for(int i = 0; i < 256; ++i) {
-      String str = "AA" + ((char)i) + "AA";
-      t.addRow("row" + i, str,
-               (byte)42 + i, (short)53 + i, 13 * i,
-               (6.7d / i), null, null, true);
+      db.close();
     }
-    
-    db.close();
   }
 
   public void x_testWriteAllCodesMdb() throws Exception
   {
-    Database db = create(true);
-
-//     Table t = new TableBuilder("Table1")
-//       .addColumn(new ColumnBuilder("key", DataType.TEXT).toColumn())
-//       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
-//       .toTable(db);
-
-//     for(int i = 0; i <= 0xFFFF; ++i) {
-//       // skip non-char chars
-//       char c = (char)i;
-//       if(Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
-//         continue;
-//       }
-//       String key = toUnicodeStr(c);
-//       String str = "AA" + c + "AA";
-//       t.addRow(key, str);
-//     }
-
-    Table t = new TableBuilder("Table5")
-      .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
-      .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
-      .toTable(db);
-
-    char c = (char)0x3041;   // crazy 7F 02 ... A0
-    char c2 = (char)0x30A2;  // crazy 7F 02 ... 
-    char c3 = (char)0x2045;  // inat 27 ... 1C
-    char c4 = (char)0x3043;  // crazy 7F 03 ... A0
-    char c5 = (char)0x3046;  // crazy 7F 04 ... 
-    char c6 = (char)0x30F6;  // crazy 7F 0D ... A0
-    char c7 = (char)0x3099;  // unprint 03
-    char c8 = (char)0x0041;  // A
-    char c9 = (char)0x002D;  // - (unprint)
-    char c10 = (char)0x20E1; // unprint F2
-    char c11 = (char)0x309A; // unprint 04
-    char c12 = (char)0x01C4; // (long extra)
-    char c13 = (char)0x005F; // _ (long inline)
-    char c14 = (char)0xFFFE; // removed
-
-    char[] cs = new char[]{c7, c8, c3, c12, c13, c14, c, c2, c9};
-    addCombos(t, 0, "", cs, 5);
-
-//     t = new TableBuilder("Table2")
-//       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
-//       .toTable(db);
-    
-//     writeChars(0x0000, t);
-
-//     t = new TableBuilder("Table3")
-//       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
-//       .toTable(db);
-    
-//     writeChars(0x0400, t);
-
-
-    db.close();
+    for (final Database.FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
+      Database db = create(fileFormat, true);
+
+  //     Table t = new TableBuilder("Table1")
+  //       .addColumn(new ColumnBuilder("key", DataType.TEXT).toColumn())
+  //       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
+  //       .toTable(db);
+
+  //     for(int i = 0; i <= 0xFFFF; ++i) {
+  //       // skip non-char chars
+  //       char c = (char)i;
+  //       if(Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
+  //         continue;
+  //       }
+  //       String key = toUnicodeStr(c);
+  //       String str = "AA" + c + "AA";
+  //       t.addRow(key, str);
+  //     }
+
+      Table t = new TableBuilder("Table5")
+        .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
+        .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
+        .toTable(db);
+
+      char c = (char)0x3041;   // crazy 7F 02 ... A0
+      char c2 = (char)0x30A2;  // crazy 7F 02 ...
+      char c3 = (char)0x2045;  // inat 27 ... 1C
+      char c4 = (char)0x3043;  // crazy 7F 03 ... A0
+      char c5 = (char)0x3046;  // crazy 7F 04 ...
+      char c6 = (char)0x30F6;  // crazy 7F 0D ... A0
+      char c7 = (char)0x3099;  // unprint 03
+      char c8 = (char)0x0041;  // A
+      char c9 = (char)0x002D;  // - (unprint)
+      char c10 = (char)0x20E1; // unprint F2
+      char c11 = (char)0x309A; // unprint 04
+      char c12 = (char)0x01C4; // (long extra)
+      char c13 = (char)0x005F; // _ (long inline)
+      char c14 = (char)0xFFFE; // removed
+
+      char[] cs = new char[]{c7, c8, c3, c12, c13, c14, c, c2, c9};
+      addCombos(t, 0, "", cs, 5);
+
+  //     t = new TableBuilder("Table2")
+  //       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
+  //       .toTable(db);
+
+  //     writeChars(0x0000, t);
+
+  //     t = new TableBuilder("Table3")
+  //       .addColumn(new ColumnBuilder("data", DataType.TEXT).toColumn())
+  //       .toTable(db);
+
+  //     writeChars(0x0400, t);
+
+
+      db.close();
+    }
   }
 
   public void x_testReadAllCodesMdb() throws Exception
   {
-//     Database db = openCopy(new File("/data2/jackcess_test/testAllIndexCodes.mdb"));
-//     Database db = openCopy(new File("/data2/jackcess_test/testAllIndexCodes_orig.mdb"));
-//     Database db = openCopy(new File("/data2/jackcess_test/testSomeMoreCodes.mdb"));
-    Database db = openCopy(new File("/data2/jackcess_test/testStillMoreCodes.mdb"));
-    Table t = db.getTable("Table5");
-
-    Index ind = t.getIndexes().iterator().next();
-    ind.initialize();
-    
-    System.out.println("Ind " + ind);
+    for (final TestDB testDB : TestDB.getSupportedForBasename(null)) {
+
+  //     Database db = openCopy(new File("/data2/jackcess_test/testAllIndexCodes.mdb"));
+  //     Database db = openCopy(new File("/data2/jackcess_test/testAllIndexCodes_orig.mdb"));
+  //     Database db = openCopy(new File("/data2/jackcess_test/testSomeMoreCodes.mdb"));
+      // @todo Bank test dbFiles and create new TestDB here.
+      //Database db = openCopy(new File("/data2/jackcess_test/testStillMoreCodes.mdb"));
+      Database db = openCopy(testDB);
+
+      Table t = db.getTable("Table5");
+
+      Index ind = t.getIndexes().iterator().next();
+      ind.initialize();
+
+      System.out.println("Ind " + ind);
+
+      Cursor cursor = Cursor.createIndexCursor(t, ind);
+      while(cursor.moveToNextRow()) {
+        System.out.println("=======");
+        String entryStr =
+          entryToString(cursor.getSavepoint().getCurrentPosition());
+        System.out.println("Entry Bytes: " + entryStr);
+        System.out.println("Value: " + cursor.getCurrentRow() + "; " +
+                           toUnicodeStr(cursor.getCurrentRow().get("data")));
+      }
 
-    Cursor cursor = Cursor.createIndexCursor(t, ind);
-    while(cursor.moveToNextRow()) {
-      System.out.println("=======");
-      String entryStr = 
-        entryToString(cursor.getSavepoint().getCurrentPosition());
-      System.out.println("Entry Bytes: " + entryStr);
-      System.out.println("Value: " + cursor.getCurrentRow() + "; " +
-                         toUnicodeStr(cursor.getCurrentRow().get("data")));
+      db.close();
     }
-
-    db.close();
   }
 
   private int addCombos(Table t, int rowNum, String s, char[] cs, int len)
@@ -285,201 +301,209 @@ public class IndexCodesTest extends TestCase {
 
   public void x_testReadIsoMdb() throws Exception
   {
-//     Database db = open(new File("/tmp/test_ind.mdb"));
-//     Database db = open(new File("/tmp/test_ind2.mdb"));
-    Database db = open(new File("/tmp/test_ind3.mdb"));
-//     Database db = open(new File("/tmp/test_ind4.mdb"));
-
-    Table t = db.getTable("Table1");
-    Index index = t.getIndex("B");
-    index.initialize();
-    System.out.println("Ind " + index);
+    for (final TestDB testDB : TestDB.getSupportedForBasename(null)) {
+  //     Database db = open(new File("/tmp/test_ind.mdb"));
+  //     Database db = open(new File("/tmp/test_ind2.mdb"));
+      // @todo Bank test dbFiles and create new TestDB here.
+      //Database db = open(new File("/tmp/test_ind3.mdb"));
+      Database db = open(testDB);
+  //     Database db = open(new File("/tmp/test_ind4.mdb"));
+
+      Table t = db.getTable("Table1");
+      Index index = t.getIndex("B");
+      index.initialize();
+      System.out.println("Ind " + index);
+
+      Cursor cursor = Cursor.createIndexCursor(t, index);
+      while(cursor.moveToNextRow()) {
+        System.out.println("=======");
+        System.out.println("Savepoint: " + cursor.getSavepoint());
+        System.out.println("Value: " + cursor.getCurrentRow());
+      }
 
-    Cursor cursor = Cursor.createIndexCursor(t, index);
-    while(cursor.moveToNextRow()) {
-      System.out.println("=======");
-      System.out.println("Savepoint: " + cursor.getSavepoint());
-      System.out.println("Value: " + cursor.getCurrentRow());
+      db.close();
     }
-    
-    db.close();
   }
     
   public void x_testReverseIsoMdb() throws Exception
   {
-    Database db = open(new File("/data2/jackcess_test/testAllIndexCodes3.mdb"));
-
-    Table t = db.getTable("Table1");
-    Index index = t.getIndexes().iterator().next();
-    index.initialize();
-    System.out.println("Ind " + index);
-
-    Pattern inlinePat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 00");
-    Pattern unprintPat = Pattern.compile("01 01 01 80 (.+) 06 (.+) 00");
-    Pattern unprint2Pat = Pattern.compile("4A 4A 4A 4A 01 02 (.+) 00");
-    Pattern inatPat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 02 02 (.+) 00");
-    Pattern inat2Pat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 (02 02 (.+))?01 01 (.*)FF 02 80 FF 80 00");
-
-    Map<Character,String[]> inlineCodes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> unprintCodes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> unprint2Codes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> inatInlineCodes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> inatExtraCodes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> inat2Codes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> inat2ExtraCodes = new TreeMap<Character,String[]>();
-    Map<Character,String[]> inat2CrazyCodes = new TreeMap<Character,String[]>();
-    
-    
-    Cursor cursor = Cursor.createIndexCursor(t, index);
-    while(cursor.moveToNextRow()) {
-//       System.out.println("=======");
-//       System.out.println("Savepoint: " + cursor.getSavepoint());
-//       System.out.println("Value: " + cursor.getCurrentRow());
-      Cursor.Savepoint savepoint = cursor.getSavepoint();
-      String entryStr = entryToString(savepoint.getCurrentPosition());
+    for (final TestDB testDB : TestDB.getSupportedForBasename(null)) {
+       // @todo Bank test dbFiles and create new TestDB here.
+      //Database db = open(new File("/data2/jackcess_test/testAllIndexCodes3.mdb"));
+      Database db = open(testDB);
+
+      Table t = db.getTable("Table1");
+      Index index = t.getIndexes().iterator().next();
+      index.initialize();
+      System.out.println("Ind " + index);
+
+      Pattern inlinePat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 00");
+      Pattern unprintPat = Pattern.compile("01 01 01 80 (.+) 06 (.+) 00");
+      Pattern unprint2Pat = Pattern.compile("4A 4A 4A 4A 01 02 (.+) 00");
+      Pattern inatPat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 02 02 (.+) 00");
+      Pattern inat2Pat = Pattern.compile("7F 4A 4A (.*)4A 4A 01 (02 02 (.+))?01 01 (.*)FF 02 80 FF 80 00");
+
+      Map<Character,String[]> inlineCodes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> unprintCodes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> unprint2Codes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> inatInlineCodes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> inatExtraCodes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> inat2Codes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> inat2ExtraCodes = new TreeMap<Character,String[]>();
+      Map<Character,String[]> inat2CrazyCodes = new TreeMap<Character,String[]>();
+
+
+      Cursor cursor = Cursor.createIndexCursor(t, index);
+      while(cursor.moveToNextRow()) {
+  //       System.out.println("=======");
+  //       System.out.println("Savepoint: " + cursor.getSavepoint());
+  //       System.out.println("Value: " + cursor.getCurrentRow());
+        Cursor.Savepoint savepoint = cursor.getSavepoint();
+        String entryStr = entryToString(savepoint.getCurrentPosition());
+
+        Map<String,Object> row = cursor.getCurrentRow();
+        String value = (String)row.get("data");
+        String key = (String)row.get("key");
+        char c = value.charAt(2);
+        System.out.println("=======");
+        System.out.println("RowId: " +
+                           savepoint.getCurrentPosition().getRowId());
+        System.out.println("Entry: " + entryStr);
+  //         System.out.println("Row: " + row);
+        System.out.println("Value: (" + key + ")" + value);
+        System.out.println("Char: " + c + ", " + (int)c + ", " +
+                           toUnicodeStr(c));
+
+        String type = null;
+        if(entryStr.endsWith("01 00")) {
+
+          // handle inline codes
+          type = "INLINE";
+          Matcher m = inlinePat.matcher(entryStr);
+          m.find();
+          handleInlineEntry(m.group(1), c, inlineCodes);
+
+        } else if(entryStr.contains("01 01 01 80")) {
+
+          // handle most unprintable codes
+          type = "UNPRINTABLE";
+          Matcher m = unprintPat.matcher(entryStr);
+          m.find();
+          handleUnprintableEntry(m.group(2), c, unprintCodes);
+
+        } else if(entryStr.contains("01 02 02") &&
+                  !entryStr.contains("FF 02 80 FF 80")) {
+
+          // handle chars w/ symbols
+          type = "CHAR_WITH_SYMBOL";
+          Matcher m = inatPat.matcher(entryStr);
+          m.find();
+          handleInternationalEntry(m.group(1), m.group(2), c,
+                                   inatInlineCodes, inatExtraCodes);
+
+        } else if(entryStr.contains("4A 4A 4A 4A 01 02")) {
+
+          // handle chars w/ symbols
+          type = "UNPRINTABLE_2";
+          Matcher m = unprint2Pat.matcher(entryStr);
+          m.find();
+          handleUnprintable2Entry(m.group(1), c, unprint2Codes);
+
+        } else if(entryStr.contains("FF 02 80 FF 80")) {
+
+          type = "CRAZY_INAT";
+          Matcher m = inat2Pat.matcher(entryStr);
+          m.find();
+          handleInternational2Entry(m.group(1), m.group(3), m.group(4), c,
+                                    inat2Codes, inat2ExtraCodes,
+                                    inat2CrazyCodes);
 
-      Map<String,Object> row = cursor.getCurrentRow();
-      String value = (String)row.get("data");
-      String key = (String)row.get("key");
-      char c = value.charAt(2);
-      System.out.println("=======");
-      System.out.println("RowId: " +
-                         savepoint.getCurrentPosition().getRowId());
-      System.out.println("Entry: " + entryStr);
-//         System.out.println("Row: " + row);
-      System.out.println("Value: (" + key + ")" + value);
-      System.out.println("Char: " + c + ", " + (int)c + ", " +
-                         toUnicodeStr(c));
-
-      String type = null;
-      if(entryStr.endsWith("01 00")) {
-
-        // handle inline codes
-        type = "INLINE";
-        Matcher m = inlinePat.matcher(entryStr);
-        m.find();
-        handleInlineEntry(m.group(1), c, inlineCodes);
-
-      } else if(entryStr.contains("01 01 01 80")) {
-        
-        // handle most unprintable codes
-        type = "UNPRINTABLE";
-        Matcher m = unprintPat.matcher(entryStr);
-        m.find();
-        handleUnprintableEntry(m.group(2), c, unprintCodes);
-
-      } else if(entryStr.contains("01 02 02") && 
-                !entryStr.contains("FF 02 80 FF 80")) {
-
-        // handle chars w/ symbols
-        type = "CHAR_WITH_SYMBOL";
-        Matcher m = inatPat.matcher(entryStr);
-        m.find();
-        handleInternationalEntry(m.group(1), m.group(2), c,
-                                 inatInlineCodes, inatExtraCodes);
-        
-      } else if(entryStr.contains("4A 4A 4A 4A 01 02")) {
-
-        // handle chars w/ symbols
-        type = "UNPRINTABLE_2";
-        Matcher m = unprint2Pat.matcher(entryStr);
-        m.find();
-        handleUnprintable2Entry(m.group(1), c, unprint2Codes);
-        
-      } else if(entryStr.contains("FF 02 80 FF 80")) {
-
-        type = "CRAZY_INAT";
-        Matcher m = inat2Pat.matcher(entryStr);
-        m.find();
-        handleInternational2Entry(m.group(1), m.group(3), m.group(4), c,
-                                  inat2Codes, inat2ExtraCodes,
-                                  inat2CrazyCodes);
-
-      } else {
-
-        throw new RuntimeException("unhandled " + entryStr);
-      }      
-        
-      System.out.println("Type: " + type);
-    }
+        } else {
 
-    System.out.println("\n***CODES");
-    for(int i = 0; i <= 0xFFFF; ++i) {
+          throw new RuntimeException("unhandled " + entryStr);
+        }
 
-      if(i == 256) {
-        System.out.println("\n***EXTENDED CODES");
+        System.out.println("Type: " + type);
       }
 
-      // skip non-char chars
-      char c = (char)i;
-      if(Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
-        continue;
-      }
+      System.out.println("\n***CODES");
+      for(int i = 0; i <= 0xFFFF; ++i) {
 
-      if(c == (char)0xFFFE) {
-        // this gets replaced with FFFD, treat it the same
-        c = (char)0xFFFD;
-      }
+        if(i == 256) {
+          System.out.println("\n***EXTENDED CODES");
+        }
 
-      Character cc = c;
-      String[] chars = inlineCodes.get(cc);
-      if(chars != null) {
-        if((chars.length == 1) && (chars[0].length() == 0)) {
-          System.out.println("X");
-        } else {
-          System.out.println("S" + toByteString(chars));
+        // skip non-char chars
+        char c = (char)i;
+        if(Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
+          continue;
         }
-        continue;
-      }
 
-      chars = inatInlineCodes.get(cc);
-      if(chars != null) {
-        String[] extra = inatExtraCodes.get(cc);
-        System.out.println("I" + toByteString(chars) + "," +
-                           toByteString(extra));
-        continue;
-      }
-        
-      chars = unprintCodes.get(cc);
-      if(chars != null) {
-        System.out.println("U" + toByteString(chars));
-        continue;
-      }
+        if(c == (char)0xFFFE) {
+          // this gets replaced with FFFD, treat it the same
+          c = (char)0xFFFD;
+        }
 
-      chars = unprint2Codes.get(cc);
-      if(chars != null) {
-        if(chars.length > 1) {
-          throw new RuntimeException("long unprint codes");
+        Character cc = c;
+        String[] chars = inlineCodes.get(cc);
+        if(chars != null) {
+          if((chars.length == 1) && (chars[0].length() == 0)) {
+            System.out.println("X");
+          } else {
+            System.out.println("S" + toByteString(chars));
+          }
+          continue;
+        }
+
+        chars = inatInlineCodes.get(cc);
+        if(chars != null) {
+          String[] extra = inatExtraCodes.get(cc);
+          System.out.println("I" + toByteString(chars) + "," +
+                             toByteString(extra));
+          continue;
+        }
+
+        chars = unprintCodes.get(cc);
+        if(chars != null) {
+          System.out.println("U" + toByteString(chars));
+          continue;
         }
-        int val = Integer.parseInt(chars[0], 16) - 2;
-        String valStr = ByteUtil.toHexString(new byte[]{(byte)val}).trim();
-        System.out.println("P" + valStr);
-        continue;
-      }
 
-      chars = inat2Codes.get(cc);
-      if(chars != null) {
-        String [] crazyCodes = inat2CrazyCodes.get(cc);
-        String crazyCode = "";
-        if(crazyCodes != null) {
-          if((crazyCodes.length != 1) || !"A0".equals(crazyCodes[0])) {
-            throw new RuntimeException("CC " + Arrays.asList(crazyCodes));
+        chars = unprint2Codes.get(cc);
+        if(chars != null) {
+          if(chars.length > 1) {
+            throw new RuntimeException("long unprint codes");
           }
-          crazyCode = "1";
+          int val = Integer.parseInt(chars[0], 16) - 2;
+          String valStr = ByteUtil.toHexString(new byte[]{(byte)val}).trim();
+          System.out.println("P" + valStr);
+          continue;
         }
 
-        String[] extra = inat2ExtraCodes.get(cc);
-        System.out.println("Z" + toByteString(chars) + "," +
-                           toByteString(extra) + "," +
-                           crazyCode);
-        continue;
+        chars = inat2Codes.get(cc);
+        if(chars != null) {
+          String [] crazyCodes = inat2CrazyCodes.get(cc);
+          String crazyCode = "";
+          if(crazyCodes != null) {
+            if((crazyCodes.length != 1) || !"A0".equals(crazyCodes[0])) {
+              throw new RuntimeException("CC " + Arrays.asList(crazyCodes));
+            }
+            crazyCode = "1";
+          }
+
+          String[] extra = inat2ExtraCodes.get(cc);
+          System.out.println("Z" + toByteString(chars) + "," +
+                             toByteString(extra) + "," +
+                             crazyCode);
+          continue;
+        }
+
+        throw new RuntimeException("Unhandled char " + toUnicodeStr(c));
       }
+      System.out.println("\n***END CODES");
 
-      throw new RuntimeException("Unhandled char " + toUnicodeStr(c));
+      db.close();
     }
-    System.out.println("\n***END CODES");
-    
-    db.close();
   }
 
   private static String toByteString(String[] chars)
index 4e547dd3cfcbcf26bce7d402067ec8df38be64c2..adf9985c05f7f42491b3a1310c63fff56c0c98d2 100644 (file)
@@ -27,7 +27,6 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -40,6 +39,7 @@ import java.util.TreeSet;
 import junit.framework.TestCase;
 
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
 
 /**
  * @author James Ahlborn
@@ -84,131 +84,140 @@ public class IndexTest extends TestCase {
   }
 
   public void testPrimaryKey() throws Exception {
-    Table table = open().getTable("Table1");
-    Map<String, Boolean> foundPKs = new HashMap<String, Boolean>();
-    for(Index index : table.getIndexes()) {
-      foundPKs.put(index.getColumns().iterator().next().getName(),
-                   index.isPrimaryKey());
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      Table table = open(testDB).getTable("Table1");
+      Map<String, Boolean> foundPKs = new HashMap<String, Boolean>();
+      for(Index index : table.getIndexes()) {
+        foundPKs.put(index.getColumns().iterator().next().getName(),
+                     index.isPrimaryKey());
+      }
+      Map<String, Boolean> expectedPKs = new HashMap<String, Boolean>();
+      expectedPKs.put("A", Boolean.TRUE);
+      expectedPKs.put("B", Boolean.FALSE);
+      assertEquals(expectedPKs, foundPKs);
     }
-    Map<String, Boolean> expectedPKs = new HashMap<String, Boolean>();
-    expectedPKs.put("A", Boolean.TRUE);
-    expectedPKs.put("B", Boolean.FALSE);
-    assertEquals(expectedPKs, foundPKs);
   }
   
   public void testIndexSlots() throws Exception
   {
-    Database mdb = open(new File("test/data/indexTest.mdb"));
-
-    Table table = mdb.getTable("Table1");
-    for(Index idx : table.getIndexes()) {
-      idx.initialize();
-    }
-    assertEquals(4, table.getIndexes().size());
-    assertEquals(4, table.getIndexSlotCount());
-    checkIndexColumns(table,
-                      "id", "id",
-                      "PrimaryKey", "id",
-                      "Table2Table1", "otherfk1",
-                      "Table3Table1", "otherfk2");
-    
-    table = mdb.getTable("Table2");
-    for(Index idx : table.getIndexes()) {
-      idx.initialize();
-    }
-    assertEquals(2, table.getIndexes().size());
-    assertEquals(3, table.getIndexSlotCount());
-    checkIndexColumns(table,
-                      "id", "id",
-                      "PrimaryKey", "id");
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
+      Database mdb = open(testDB);
 
-    table = mdb.getTable("Table3");
-    for(Index idx : table.getIndexes()) {
-      idx.initialize();
+      Table table = mdb.getTable("Table1");
+      for(Index idx : table.getIndexes()) {
+        idx.initialize();
+      }
+      assertEquals(4, table.getIndexes().size());
+      assertEquals(4, table.getIndexSlotCount());
+      checkIndexColumns(table,
+                        "id", "id",
+                        "PrimaryKey", "id",
+                        "Table2Table1", "otherfk1",
+                        "Table3Table1", "otherfk2");
+
+      table = mdb.getTable("Table2");
+      for(Index idx : table.getIndexes()) {
+        idx.initialize();
+      }
+      assertEquals(2, table.getIndexes().size());
+      assertEquals(3, table.getIndexSlotCount());
+      checkIndexColumns(table,
+                        "id", "id",
+                        "PrimaryKey", "id");
+
+      table = mdb.getTable("Table3");
+      for(Index idx : table.getIndexes()) {
+        idx.initialize();
+      }
+      assertEquals(2, table.getIndexes().size());
+      assertEquals(3, table.getIndexSlotCount());
+      checkIndexColumns(table,
+                        "id", "id",
+                        "PrimaryKey", "id");
     }
-    assertEquals(2, table.getIndexes().size());
-    assertEquals(3, table.getIndexSlotCount());
-    checkIndexColumns(table,
-                      "id", "id",
-                      "PrimaryKey", "id");
   }
 
   public void testComplexIndex() throws Exception
   {
-    // this file has an index with "compressed" entries and node pages
-    File origFile = new File("test/data/compIndexTest.mdb");
-    Database db = open(origFile);
-    Table t = db.getTable("Table1");
-    Index index = t.getIndexes().get(0);
-    assertFalse(index.isInitialized());
-    assertEquals(512, countRows(t));
-    assertEquals(512, index.getEntryCount());
-    db.close();
-
-    // copy to temp file and attempt to edit
-    db = openCopy(origFile);
-    t = db.getTable("Table1");
-    index = t.getIndexes().get(0);
-
-    System.out.println("IndexTest: Index type: " + index.getClass());
-    try {
-      t.addRow(99, "abc", "def");
-      if(index instanceof SimpleIndex) {
-        // SimpleIndex doesn't support writing these indexes
-        fail("Should have thrown UnsupportedOperationException");
-      }
-    } catch(UnsupportedOperationException e) {
-      // success
-      if(index instanceof BigIndex) {
-        throw e;
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.COMP_INDEX)) {
+      // this file has an index with "compressed" entries and node pages
+      Database db = open(testDB);
+      Table t = db.getTable("Table1");
+      Index index = t.getIndexes().get(0);
+      assertFalse(index.isInitialized());
+      assertEquals(512, countRows(t));
+      assertEquals(512, index.getEntryCount());
+      db.close();
+
+      // copy to temp file and attempt to edit
+      db = openCopy(testDB);
+      t = db.getTable("Table1");
+      index = t.getIndexes().get(0);
+
+      System.out.println("IndexTest: Index type: " + index.getClass());
+      try {
+        t.addRow(99, "abc", "def");
+        if(index instanceof SimpleIndex) {
+          // SimpleIndex doesn't support writing these indexes
+          fail("Should have thrown UnsupportedOperationException");
+        }
+      } catch(UnsupportedOperationException e) {
+        // success
+        if(index instanceof BigIndex) {
+          throw e;
+        }
       }
     }
   }
 
   public void testEntryDeletion() throws Exception {
-    Table table = openCopy(new File("test/data/test.mdb")).getTable("Table1");
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      Table table = openCopy(testDB).getTable("Table1");
 
-    for(int i = 0; i < 10; ++i) {
-      table.addRow("foo" + i, "bar" + i, (byte)42 + i, (short)53 + i, 13 * i,
-                   (6.7d / i), null, null, true);
-    }
-    table.reset();
-    assertRowCount(12, table);
+      for(int i = 0; i < 10; ++i) {
+        table.addRow("foo" + i, "bar" + i, (byte)42 + i, (short)53 + i, 13 * i,
+                     (6.7d / i), null, null, true);
+      }
+      table.reset();
+      assertRowCount(12, table);
 
-    for(Index index : table.getIndexes()) {
-      assertEquals(12, index.getEntryCount());
-    }
+      for(Index index : table.getIndexes()) {
+        assertEquals(12, index.getEntryCount());
+      }
 
-    table.reset();
-    table.getNextRow();
-    table.getNextRow();
-    table.deleteCurrentRow();
-    table.getNextRow();
-    table.deleteCurrentRow();
-    table.getNextRow();
-    table.getNextRow();
-    table.deleteCurrentRow();
-    table.getNextRow();
-    table.getNextRow();
-    table.getNextRow();
-    table.deleteCurrentRow();
-
-    table.reset();
-    assertRowCount(8, table);
-
-    for(Index index : table.getIndexes()) {
-      assertEquals(8, index.getEntryCount());
+      table.reset();
+      table.getNextRow();
+      table.getNextRow();
+      table.deleteCurrentRow();
+      table.getNextRow();
+      table.deleteCurrentRow();
+      table.getNextRow();
+      table.getNextRow();
+      table.deleteCurrentRow();
+      table.getNextRow();
+      table.getNextRow();
+      table.getNextRow();
+      table.deleteCurrentRow();
+
+      table.reset();
+      assertRowCount(8, table);
+
+      for(Index index : table.getIndexes()) {
+        assertEquals(8, index.getEntryCount());
+      }
     }
   }
 
   public void testIgnoreNulls() throws Exception
   {
-    Database db = openCopy(new File("test/data/testIndexProperties.mdb"));
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX_PROPERTIES)) {
+      Database db = openCopy(testDB);
 
-    doTestIgnoreNulls(db, "TableIgnoreNulls1");
-    doTestIgnoreNulls(db, "TableIgnoreNulls2");    
+      doTestIgnoreNulls(db, "TableIgnoreNulls1");
+      doTestIgnoreNulls(db, "TableIgnoreNulls2");
 
-    db.close();
+      db.close();
+    }
   }
 
   private void doTestIgnoreNulls(Database db, String tableName)
@@ -250,41 +259,43 @@ public class IndexTest extends TestCase {
 
   public void testUnique() throws Exception
   {
-    Database db = openCopy(new File("test/data/testIndexProperties.mdb"));
-
-    Table t = db.getTable("TableUnique1_temp");
-    Index index = t.getIndex("DataIndex");
-
-    doTestUnique(t, index, 1,
-                 null, true,
-                 "unique data", true,
-                 null, true,
-                 "more", false,
-                 "stuff", false,
-                 "unique data", false);
-
-    t = db.getTable("TableUnique2_temp");
-    index = t.getIndex("DataIndex");
-
-    doTestUnique(t, index, 2,
-                 null, null, true,
-                 "unique data", 42, true,
-                 "unique data", null, true,
-                 null, null, true,
-                 "some", 42, true,
-                 "more unique data", 13, true,
-                 null, -4242, true,
-                 "another row", -3462, false,
-                 null, 49, false,
-                 "more", null, false,
-                 "unique data", 42, false,
-                 "unique data", null, false,
-                 null, -4242, false);
-    
-    db.close();
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX_PROPERTIES)) {
+      Database db = openCopy(testDB);
+
+      Table t = db.getTable("TableUnique1_temp");
+      Index index = t.getIndex("DataIndex");
+
+      doTestUnique(index, 1,
+                   null, true,
+                   "unique data", true,
+                   null, true,
+                   "more", false,
+                   "stuff", false,
+                   "unique data", false);
+
+      t = db.getTable("TableUnique2_temp");
+      index = t.getIndex("DataIndex");
+
+      doTestUnique(index, 2,
+                   null, null, true,
+                   "unique data", 42, true,
+                   "unique data", null, true,
+                   null, null, true,
+                   "some", 42, true,
+                   "more unique data", 13, true,
+                   null, -4242, true,
+                   "another row", -3462, false,
+                   null, 49, false,
+                   "more", null, false,
+                   "unique data", 42, false,
+                   "unique data", null, false,
+                   null, -4242, false);
+
+      db.close();
+    }
   }
 
-  private void doTestUnique(Table t, Index index, int numValues,
+  private void doTestUnique(Index index, int numValues,
                             Object... testData)
     throws Exception
   {
@@ -312,70 +323,79 @@ public class IndexTest extends TestCase {
   }
 
   public void testUniqueEntryCount() throws Exception {
-    Database db = openCopy(new File("test/data/test.mdb"));
-    Table table = db.getTable("Table1");
-    Index indA = table.getIndex("PrimaryKey");
-    Index indB = table.getIndex("B");
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      Database db = openCopy(testDB);
+      Table table = db.getTable("Table1");
+      Index indA = table.getIndex("PrimaryKey");
+      Index indB = table.getIndex("B");
 
-    assertEquals(2, indA.getUniqueEntryCount());
-    assertEquals(2, indB.getUniqueEntryCount());
+      assertEquals(2, indA.getUniqueEntryCount());
+      assertEquals(2, indB.getUniqueEntryCount());
 
-    List<String> bElems = Arrays.asList("bar", null, "baz", "argle", null,
-                                        "bazzle", "37", "bar", "bar", "BAZ");
-    
-    for(int i = 0; i < 10; ++i) {
-      table.addRow("foo" + i, bElems.get(i), (byte)42 + i, (short)53 + i,
-                   13 * i, (6.7d / i), null, null, true);
-    }
+      List<String> bElems = Arrays.asList("bar", null, "baz", "argle", null,
+                                          "bazzle", "37", "bar", "bar", "BAZ");
 
-    assertEquals(12, indA.getEntryCount());
-    assertEquals(12, indB.getEntryCount());
-    
-    assertEquals(12, indA.getUniqueEntryCount());
-    assertEquals(8, indB.getUniqueEntryCount());
+      for(int i = 0; i < 10; ++i) {
+        table.addRow("foo" + i, bElems.get(i), (byte)42 + i, (short)53 + i,
+                     13 * i, (6.7d / i), null, null, true);
+      }
 
-    table = null;
-    indA = null;
-    indB = null;
+      assertEquals(12, indA.getEntryCount());
+      assertEquals(12, indB.getEntryCount());
 
-    table = db.getTable("Table1");
-    indA = table.getIndex("PrimaryKey");
-    indB = table.getIndex("B");
-    
-    assertEquals(12, indA.getEntryCount());
-    assertEquals(12, indB.getEntryCount());
-    
-    assertEquals(12, indA.getUniqueEntryCount());
-    assertEquals(8, indB.getUniqueEntryCount());    
-
-    Cursor c = Cursor.createCursor(table);
-    assertTrue(c.moveToNextRow());
-    Map<String,Object> row = c.getCurrentRow();
-    assertEquals("abcdefg", row.get("A"));
-    assertEquals("hijklmnop", row.get("B"));
-    c.deleteCurrentRow();
-
-    assertEquals(11, indA.getEntryCount());
-    assertEquals(11, indB.getEntryCount());
-    
-    assertEquals(12, indA.getUniqueEntryCount());
-    assertEquals(8, indB.getUniqueEntryCount());        
-    
-    db.close();
+      assertEquals(12, indA.getUniqueEntryCount());
+      assertEquals(8, indB.getUniqueEntryCount());
+
+      table = null;
+      indA = null;
+      indB = null;
+
+      table = db.getTable("Table1");
+      indA = table.getIndex("PrimaryKey");
+      indB = table.getIndex("B");
+
+      assertEquals(12, indA.getEntryCount());
+      assertEquals(12, indB.getEntryCount());
+
+      assertEquals(12, indA.getUniqueEntryCount());
+      assertEquals(8, indB.getUniqueEntryCount());
+
+      Cursor c = Cursor.createCursor(table);
+      assertTrue(c.moveToNextRow());
+
+      final Map<String,Object> row = c.getCurrentRow();
+      // Row order is arbitrary, so v2007 row order difference is valid
+      if (Database.FileFormat.V2007.equals(testDB.getExpectedFileFormat())) {
+        DatabaseTest.checkTestDBTable1RowA(testDB, table, row);
+      } else {
+        DatabaseTest.checkTestDBTable1RowABCDEFG(testDB, table, row);
+      }
+      c.deleteCurrentRow();
+
+      assertEquals(11, indA.getEntryCount());
+      assertEquals(11, indB.getEntryCount());
+
+      assertEquals(12, indA.getUniqueEntryCount());
+      assertEquals(8, indB.getUniqueEntryCount());
+
+      db.close();
+    }
   }
   
   public void testReplId() throws Exception
   {
-    Database db = openCopy(new File("test/data/test.mdb"));
-    Table table = db.getTable("Table4");
+    for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+      Database db = openCopy(testDB);
+      Table table = db.getTable("Table4");
 
-    for(int i = 0; i< 20; ++i) {
-      table.addRow("row" + i, Column.AUTO_NUMBER);
-    }
+      for(int i = 0; i< 20; ++i) {
+        table.addRow("row" + i, Column.AUTO_NUMBER);
+      }
 
-    assertEquals(20, table.getRowCount());
-    
-    db.close();
+      assertEquals(20, table.getRowCount());
+
+      db.close();
+    }
   }
   
   private void checkIndexColumns(Table table, String... idxInfo)
diff --git a/test/src/java/com/healthmarketscience/jackcess/JetFormatTest.java b/test/src/java/com/healthmarketscience/jackcess/JetFormatTest.java
new file mode 100644 (file)
index 0000000..96365e4
--- /dev/null
@@ -0,0 +1,134 @@
+package com.healthmarketscience.jackcess;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/**
+ * @author Dan Rollo
+ *         Date: Mar 5, 2010
+ *         Time: 12:44:21 PM
+ */
+public final class JetFormatTest extends TestCase {
+
+    private static final File DIR_TEST_DATA = new File("test/data");
+
+    /**
+     * Defines known valid db test file base names.
+     */
+    public static enum Basename {
+
+        BIG_INDEX("bigIndexTest"),
+        COMP_INDEX("compIndexTest"),
+        DEL_COL("delColTest"),
+        DEL("delTest"),
+        FIXED_NUMERIC("fixedNumericTest"),
+        FIXED_TEXT("fixedTextTest"),
+        INDEX_CURSOR("indexCursorTest"),
+        INDEX("indexTest"),
+        OVERFLOW("overflowTest"),
+        QUERY("queryTest"),
+        TEST("test"),
+        TEST2("test2"),
+        INDEX_CODES("testIndexCodes"),
+        INDEX_PROPERTIES("testIndexProperties"),
+        PROMOTION("testPromotion"),
+        ;
+
+        private final String basename;
+
+        Basename(final String fileBasename) {
+          basename = fileBasename;
+        }
+
+    }
+
+    /** Defines currently supported db file formats. */
+    final static Database.FileFormat[] SUPPORTED_FILEFORMATS = new Database.FileFormat[] {
+            Database.FileFormat.V2000,
+            Database.FileFormat.V2003,
+            Database.FileFormat.V2007,
+            // @todo Uncomment these elements to run test other formats
+    };
+
+    /**
+     * Defines known valid test database files, and their jet format version.
+     */
+    public static final class TestDB {
+
+        private final File dbFile;
+        private final Database.FileFormat expectedFileFormat;
+
+        private TestDB(final File databaseFile, final Database.FileFormat expectedDBFileFormat) {
+
+            dbFile = databaseFile;
+            expectedFileFormat = expectedDBFileFormat;
+        }
+
+        public final File getFile() { return dbFile; }
+        public final Database.FileFormat  getExpectedFileFormat() { return expectedFileFormat; }
+        public final JetFormat getExpectedFormat() { return expectedFileFormat.getJetFormat(); }
+
+        public final String toString() {
+            return "dbFile: " + dbFile.getAbsolutePath()
+                    + "; expectedFileFormat: " + expectedFileFormat;
+        }
+
+        public static TestDB[] getSupportedForBasename(final Basename basename) {
+
+            final TestDB[] supportedTestDBs = new TestDB[SUPPORTED_FILEFORMATS.length];
+            int i = 0;
+            for (final Database.FileFormat fileFormat: SUPPORTED_FILEFORMATS) {
+                supportedTestDBs[i++] = new TestDB(
+                        getFileForBasename(basename, fileFormat),
+                        fileFormat);
+            }
+            return supportedTestDBs;
+        }
+
+        private static File getFileForBasename(Basename basename, Database.FileFormat fileFormat) {
+
+            return new File(DIR_TEST_DATA, 
+                            fileFormat.name() + "/" + basename.basename + fileFormat.name() + 
+                            fileFormat.getFileExtension());
+        }
+    }
+
+    static final TestDB UNSUPPORTED_TEST_V1997 = new TestDB(
+            TestDB.getFileForBasename(Basename.TEST, Database.FileFormat.V1997), Database.FileFormat.V1997);
+
+    static final TestDB[] SUPPORTED_DBS_TEST= TestDB.getSupportedForBasename(Basename.TEST);
+
+
+    public void testGetFormat() throws Exception {
+        try {
+            JetFormat.getFormat(null);
+            fail("npe");
+        } catch (NullPointerException e) {
+            assertNull(e.getMessage());
+        }
+
+        checkJetFormat(UNSUPPORTED_TEST_V1997);
+
+        for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+          checkJetFormat(testDB);
+        }
+    }
+
+    private static void checkJetFormat(final TestDB testDB)
+            throws IOException {
+
+        final FileChannel channel = Database.openChannel(testDB.dbFile, false);
+        try {
+
+            final JetFormat fmtActual = JetFormat.getFormat(channel);
+            assertEquals("Unexpected JetFormat for dbFile: " + testDB.dbFile.getAbsolutePath(),
+                    testDB.expectedFileFormat.getJetFormat(), fmtActual);
+
+        } finally {
+            channel.close();
+        }
+    }
+}
index 67ed71146d39d063336f65040c61661b1401cf1a..a6f3c4426589cfc85c92a3cefbe1468c6eaa9d39 100644 (file)
@@ -27,13 +27,13 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess;
 
-import java.io.File;
 import java.util.Arrays;
 import java.util.List;
 
 import junit.framework.TestCase;
 
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
 
 /**
  * @author James Ahlborn
@@ -45,50 +45,51 @@ public class RelationshipTest extends TestCase {
   }
 
   public void testSimple() throws Exception {
-    Database db = open(new File("test/data/indexTest.mdb"));
-    Table t1 = db.getTable("Table1");
-    Table t2 = db.getTable("Table2");
-    Table t3 = db.getTable("Table3");
-
-    List<Relationship> rels = db.getRelationships(t1, t2);
-    assertEquals(1, rels.size());
-    Relationship rel = rels.get(0);
-    assertEquals("Table2Table1", rel.getName());
-    assertEquals(t2, rel.getFromTable());
-    assertEquals(Arrays.asList(t2.getColumn("id")),
-                 rel.getFromColumns());
-    assertEquals(t1, rel.getToTable());
-    assertEquals(Arrays.asList(t1.getColumn("otherfk1")),
-                 rel.getToColumns());
-    assertTrue(rel.hasReferentialIntegrity());
-    assertEquals(0, rel.getFlags());
-    assertSameRelationships(rels, db.getRelationships(t2, t1));
-    
-    rels = db.getRelationships(t2, t3);
-    assertTrue(db.getRelationships(t2, t3).isEmpty());
-    assertSameRelationships(rels, db.getRelationships(t3, t2));
-    
-    rels = db.getRelationships(t1, t3);
-    assertEquals(1, rels.size());
-    rel = rels.get(0);
-    assertEquals("Table3Table1", rel.getName());
-    assertEquals(t3, rel.getFromTable());
-    assertEquals(Arrays.asList(t3.getColumn("id")),
-                 rel.getFromColumns());
-    assertEquals(t1, rel.getToTable());
-    assertEquals(Arrays.asList(t1.getColumn("otherfk2")),
-                 rel.getToColumns());
-    assertTrue(rel.hasReferentialIntegrity());
-    assertEquals(0, rel.getFlags());
-    assertSameRelationships(rels, db.getRelationships(t3, t1));
-
-    try {
-      db.getRelationships(t1, t1);
-      fail("IllegalArgumentException should have been thrown");
-    } catch(IllegalArgumentException ignored) {
-      // success
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
+      Database db = open(testDB);
+      Table t1 = db.getTable("Table1");
+      Table t2 = db.getTable("Table2");
+      Table t3 = db.getTable("Table3");
+
+      List<Relationship> rels = db.getRelationships(t1, t2);
+      assertEquals(1, rels.size());
+      Relationship rel = rels.get(0);
+      assertEquals("Table2Table1", rel.getName());
+      assertEquals(t2, rel.getFromTable());
+      assertEquals(Arrays.asList(t2.getColumn("id")),
+                   rel.getFromColumns());
+      assertEquals(t1, rel.getToTable());
+      assertEquals(Arrays.asList(t1.getColumn("otherfk1")),
+                   rel.getToColumns());
+      assertTrue(rel.hasReferentialIntegrity());
+      assertEquals(0, rel.getFlags());
+      assertSameRelationships(rels, db.getRelationships(t2, t1));
+
+      rels = db.getRelationships(t2, t3);
+      assertTrue(db.getRelationships(t2, t3).isEmpty());
+      assertSameRelationships(rels, db.getRelationships(t3, t2));
+
+      rels = db.getRelationships(t1, t3);
+      assertEquals(1, rels.size());
+      rel = rels.get(0);
+      assertEquals("Table3Table1", rel.getName());
+      assertEquals(t3, rel.getFromTable());
+      assertEquals(Arrays.asList(t3.getColumn("id")),
+                   rel.getFromColumns());
+      assertEquals(t1, rel.getToTable());
+      assertEquals(Arrays.asList(t1.getColumn("otherfk2")),
+                   rel.getToColumns());
+      assertTrue(rel.hasReferentialIntegrity());
+      assertEquals(0, rel.getFlags());
+      assertSameRelationships(rels, db.getRelationships(t3, t1));
+
+      try {
+        db.getRelationships(t1, t1);
+        fail("IllegalArgumentException should have been thrown");
+      } catch(IllegalArgumentException ignored) {
+        // success
+      }
     }
-
   }
 
   private void assertSameRelationships(
diff --git a/test/src/java/com/healthmarketscience/jackcess/UsageMapTest.java b/test/src/java/com/healthmarketscience/jackcess/UsageMapTest.java
new file mode 100644 (file)
index 0000000..85b0630
--- /dev/null
@@ -0,0 +1,57 @@
+package com.healthmarketscience.jackcess;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
+
+/**
+ * @author Dan Rollo
+ *         Date: Mar 5, 2010
+ *         Time: 2:21:22 PM
+ */
+public final class UsageMapTest extends TestCase {
+
+    public void testRead() throws Exception {
+        try {
+            Database.open(UNSUPPORTED_TEST_V1997.getFile());
+            fail("mdb v97 usage map unsupported");
+        } catch (IOException e) {
+            assertEquals(UsageMap.MSG_PREFIX_UNRECOGNIZED_MAP + 2, e.getMessage());
+        }
+
+        for (final TestDB testDB : SUPPORTED_DBS_TEST) {
+            final int expectedFirstPage;
+            final int expectedLastPage;
+            final Database.FileFormat expectedFileFormat = testDB.getExpectedFileFormat();
+            if (Database.FileFormat.V2000.equals(expectedFileFormat)) {
+                expectedFirstPage = 743;
+                expectedLastPage = 767;
+            } else if (Database.FileFormat.V2003.equals(expectedFileFormat)) {
+                expectedFirstPage = 16;
+                expectedLastPage = 799;
+            } else if (Database.FileFormat.V2007.equals(expectedFileFormat)) {
+                expectedFirstPage = 42;
+                expectedLastPage = 511;
+            } else {
+                throw new IllegalAccessException("Unknown file format: " + expectedFileFormat);
+            }
+            checkUsageMapRead(testDB.getFile(), expectedFirstPage, expectedLastPage);
+        }
+    }
+
+    private static void checkUsageMapRead(final File dbFile,
+                                          final int expectedFirstPage, final int expectedLastPage)
+            throws IOException {
+
+        final Database db = Database.open(dbFile);
+        final UsageMap usageMap = UsageMap.read(db,
+                PageChannel.PAGE_GLOBAL_USAGE_MAP,
+                PageChannel.ROW_GLOBAL_USAGE_MAP,
+                true);
+        assertEquals("Unexpected FirstPageNumber.", expectedFirstPage, usageMap.getFirstPageNumber());
+        assertEquals("Unexpected LastPageNumber.", expectedLastPage, usageMap.getLastPageNumber());
+    }
+}
index 751fbb4d48524067d221a7817c81e3bed92e2cca..0ba327205b74bc553242d57a1997909ea205a787 100644 (file)
@@ -27,7 +27,6 @@ King of Prussia, PA 19406
 
 package com.healthmarketscience.jackcess.query;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -45,6 +44,8 @@ import org.apache.commons.lang.StringUtils;
 import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR;
 import static com.healthmarketscience.jackcess.query.QueryFormat.*;
 
+import static com.healthmarketscience.jackcess.JetFormatTest.*;
+
 
 /**
  * @author James Ahlborn
@@ -199,68 +200,70 @@ public class QueryTest extends TestCase
 
   public void testReadQueries() throws Exception
   {
-    Map<String,String> expectedQueries = new HashMap<String,String>();
-    expectedQueries.put(
-        "SelectQuery", multiline(
-            "SELECT DISTINCT Table1.*, Table2.col1, Table2.col2, Table3.col3",
-            "FROM (Table1 LEFT JOIN Table3 ON Table1.col1 = Table3.col1) INNER JOIN Table2 ON (Table3.col1 = Table2.col1) AND (Table3.col1 = Table2.col2)",
-            "WHERE (((Table2.col2)=\"foo\" Or (Table2.col2) In (\"buzz\",\"bazz\")))",
-            "ORDER BY Table2.col1;"));
-    expectedQueries.put(
-        "DeleteQuery", multiline(
-            "DELETE Table1.col1, Table1.col2, Table1.col3",
-            "FROM Table1", 
-            "WHERE (((Table1.col1)>\"blah\"));"));
-    expectedQueries.put(
-        "AppendQuery",multiline(
-            "INSERT INTO Table3",
-            "SELECT [Table1].[col2], [Table2].[col2], [Table2].[col3]",
-            "FROM Table3, Table1 INNER JOIN Table2 ON [Table1].[col1]=[Table2].[col1];"));
-    expectedQueries.put(
-        "UpdateQuery",multiline(
-            "PARAMETERS User Name Text;",
-            "UPDATE Table1",
-            "SET Table1.col1 = \"foo\", Table1.col2 = [Table2].[col3], [[Table2]].[[col1]] = [User Name]",
-            "WHERE ((([Table2].[col1]) Is Not Null));"));
-    expectedQueries.put(
-        "MakeTableQuery",multiline(
-            "SELECT Max(Table2.col1) AS MaxOfcol1, Table2.col2, Table3.col2 INTO Table4",
-            "FROM (Table2 INNER JOIN Table1 ON Table2.col1 = Table1.col2) RIGHT JOIN Table3 ON Table1.col2 = Table3.col3",
-            "GROUP BY Table2.col2, Table3.col2",
-            "HAVING (((Max(Table2.col1))=\"buzz\") AND ((Table2.col2)<>\"blah\"));"));
-    expectedQueries.put(
-        "CrosstabQuery", multiline(
-            "TRANSFORM Count([Table2].[col2]) AS CountOfcol2",
-            "SELECT Table2_1.col1, [Table2].[col3], Avg(Table2_1.col2) AS AvgOfcol2",
-            "FROM (Table1 INNER JOIN Table2 ON [Table1].[col1]=[Table2].[col1]) INNER JOIN Table2 AS Table2_1 ON [Table2].[col1]=Table2_1.col3",
-            "WHERE ((([Table1].[col1])>\"10\") And ((Table2_1.col1) Is Not Null) And ((Avg(Table2_1.col2))>\"10\"))",
-            "GROUP BY Table2_1.col1, [Table2].[col3]",
-            "ORDER BY [Table2].[col3]",
-            "PIVOT [Table1].[col1];"));
-    expectedQueries.put(
-        "UnionQuery", multiline(
-            "Select Table1.col1, Table1.col2",
-            "where Table1.col1 = \"foo\"",
-            "UNION",
-            "Select Table2.col1, Table2.col2",
-            "UNION ALL Select Table3.col1, Table3.col2",
-            "where Table3.col3 > \"blah\";"));
-    expectedQueries.put(
-        "PassthroughQuery", multiline(
-            "ALTER TABLE Table4 DROP COLUMN col5;\0"));
-    expectedQueries.put(
-        "DataDefinitionQuery", multiline(
-            "CREATE TABLE Table5 (col1 CHAR, col2 CHAR);\0"));
-
-    Database db = DatabaseTest.open(new File("test/data/queryTest.mdb"));
-
-    for(Query q : db.getQueries()) {
-      assertEquals(expectedQueries.remove(q.getName()), q.toSQLString());
-    }
+    for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.QUERY)) {
+      Map<String,String> expectedQueries = new HashMap<String,String>();
+      expectedQueries.put(
+          "SelectQuery", multiline(
+              "SELECT DISTINCT Table1.*, Table2.col1, Table2.col2, Table3.col3",
+              "FROM (Table1 LEFT JOIN Table3 ON Table1.col1 = Table3.col1) INNER JOIN Table2 ON (Table3.col1 = Table2.col1) AND (Table3.col1 = Table2.col2)",
+              "WHERE (((Table2.col2)=\"foo\" Or (Table2.col2) In (\"buzz\",\"bazz\")))",
+              "ORDER BY Table2.col1;"));
+      expectedQueries.put(
+          "DeleteQuery", multiline(
+              "DELETE Table1.col1, Table1.col2, Table1.col3",
+              "FROM Table1",
+              "WHERE (((Table1.col1)>\"blah\"));"));
+      expectedQueries.put(
+          "AppendQuery",multiline(
+              "INSERT INTO Table3",
+              "SELECT [Table1].[col2], [Table2].[col2], [Table2].[col3]",
+              "FROM Table3, Table1 INNER JOIN Table2 ON [Table1].[col1]=[Table2].[col1];"));
+      expectedQueries.put(
+          "UpdateQuery",multiline(
+              "PARAMETERS User Name Text;",
+              "UPDATE Table1",
+              "SET Table1.col1 = \"foo\", Table1.col2 = [Table2].[col3], [[Table2]].[[col1]] = [User Name]",
+              "WHERE ((([Table2].[col1]) Is Not Null));"));
+      expectedQueries.put(
+          "MakeTableQuery",multiline(
+              "SELECT Max(Table2.col1) AS MaxOfcol1, Table2.col2, Table3.col2 INTO Table4",
+              "FROM (Table2 INNER JOIN Table1 ON Table2.col1 = Table1.col2) RIGHT JOIN Table3 ON Table1.col2 = Table3.col3",
+              "GROUP BY Table2.col2, Table3.col2",
+              "HAVING (((Max(Table2.col1))=\"buzz\") AND ((Table2.col2)<>\"blah\"));"));
+      expectedQueries.put(
+          "CrosstabQuery", multiline(
+              "TRANSFORM Count([Table2].[col2]) AS CountOfcol2",
+              "SELECT Table2_1.col1, [Table2].[col3], Avg(Table2_1.col2) AS AvgOfcol2",
+              "FROM (Table1 INNER JOIN Table2 ON [Table1].[col1]=[Table2].[col1]) INNER JOIN Table2 AS Table2_1 ON [Table2].[col1]=Table2_1.col3",
+              "WHERE ((([Table1].[col1])>\"10\") And ((Table2_1.col1) Is Not Null) And ((Avg(Table2_1.col2))>\"10\"))",
+              "GROUP BY Table2_1.col1, [Table2].[col3]",
+              "ORDER BY [Table2].[col3]",
+              "PIVOT [Table1].[col1];"));
+      expectedQueries.put(
+          "UnionQuery", multiline(
+              "Select Table1.col1, Table1.col2",
+              "where Table1.col1 = \"foo\"",
+              "UNION",
+              "Select Table2.col1, Table2.col2",
+              "UNION ALL Select Table3.col1, Table3.col2",
+              "where Table3.col3 > \"blah\";"));
+      expectedQueries.put(
+          "PassthroughQuery", multiline(
+              "ALTER TABLE Table4 DROP COLUMN col5;\0"));
+      expectedQueries.put(
+          "DataDefinitionQuery", multiline(
+              "CREATE TABLE Table5 (col1 CHAR, col2 CHAR);\0"));
+
+      Database db = DatabaseTest.open(testDB);
+
+      for(Query q : db.getQueries()) {
+        assertEquals(expectedQueries.remove(q.getName()), q.toSQLString());
+      }
 
-    assertTrue(expectedQueries.isEmpty());
+      assertTrue(expectedQueries.isEmpty());
 
-    db.close();
+      db.close();
+    }
   }
 
   private void doTestColumns(SelectQuery query) throws Exception