View Javadoc
1   /*
2   Copyright (c) 2005 Health Market Science, Inc.
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess.impl;
18  
19  import java.io.IOException;
20  import java.nio.ByteBuffer;
21  import java.nio.channels.FileChannel;
22  import java.nio.charset.Charset;
23  import java.nio.charset.StandardCharsets;
24  import java.util.Collections;
25  import java.util.EnumSet;
26  import java.util.HashMap;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import com.healthmarketscience.jackcess.DataType;
31  import com.healthmarketscience.jackcess.Database;
32  
33  /**
34   * Encapsulates constants describing a specific version of the Access Jet format
35   * @author Tim McCune
36   */
37  public abstract class JetFormat {
38  
39    /** Maximum size of a record minus OLE objects and Memo fields */
40    public static final int MAX_RECORD_SIZE = 1900;  //2kb minus some overhead
41  
42    /** the "unit" size for text fields */
43    public static final short TEXT_FIELD_UNIT_SIZE = 2;
44    /** Maximum size of a text field */
45    public static final short TEXT_FIELD_MAX_LENGTH = 255 * TEXT_FIELD_UNIT_SIZE;
46  
47    public enum CodecType {
48      NONE, JET, MSISAM, OFFICE;
49    }
50  
51    /** Offset in the file that holds the byte describing the Jet format
52        version */
53    private static final int OFFSET_VERSION = 20;
54    /** Version code for Jet version 3 */
55    private static final byte CODE_VERSION_3 = 0x0;
56    /** Version code for Jet version 4 */
57    private static final byte CODE_VERSION_4 = 0x1;
58    /** Version code for Jet version 12.0 */
59    private static final byte CODE_VERSION_12 = 0x2;
60    /** Version code for Jet version 14.0 */
61    private static final byte CODE_VERSION_14 = 0x3;
62    /** Version code for Jet version 16.0 */
63    private static final byte CODE_VERSION_16 = 0x5;
64    /** Version code for Jet version 17.0 */
65    private static final byte CODE_VERSION_17 = 0x6;
66  
67    /** location of the engine name in the header */
68    public static final int OFFSET_ENGINE_NAME = 0x4;
69    /** length of the engine name in the header */
70    public static final int LENGTH_ENGINE_NAME = 0xF;
71    /** amount of initial data to be read to determine database type */
72    private static final int HEADER_LENGTH = 21;
73  
74    private final static byte[] MSISAM_ENGINE = new byte[] {
75      'M', 'S', 'I', 'S', 'A', 'M', ' ', 'D', 'a', 't', 'a', 'b', 'a', 's', 'e'
76    };
77  
78    /** mask used to obfuscate the db header */
79    private static final byte[] BASE_HEADER_MASK = new byte[]{
80      (byte)0xB5, (byte)0x6F, (byte)0x03, (byte)0x62, (byte)0x61, (byte)0x08,
81      (byte)0xC2, (byte)0x55, (byte)0xEB, (byte)0xA9, (byte)0x67, (byte)0x72,
82      (byte)0x43, (byte)0x3F, (byte)0x00, (byte)0x9C, (byte)0x7A, (byte)0x9F,
83      (byte)0x90, (byte)0xFF, (byte)0x80, (byte)0x9A, (byte)0x31, (byte)0xC5,
84      (byte)0x79, (byte)0xBA, (byte)0xED, (byte)0x30, (byte)0xBC, (byte)0xDF,
85      (byte)0xCC, (byte)0x9D, (byte)0x63, (byte)0xD9, (byte)0xE4, (byte)0xC3,
86      (byte)0x7B, (byte)0x42, (byte)0xFB, (byte)0x8A, (byte)0xBC, (byte)0x4E,
87      (byte)0x86, (byte)0xFB, (byte)0xEC, (byte)0x37, (byte)0x5D, (byte)0x44,
88      (byte)0x9C, (byte)0xFA, (byte)0xC6, (byte)0x5E, (byte)0x28, (byte)0xE6,
89      (byte)0x13, (byte)0xB6, (byte)0x8A, (byte)0x60, (byte)0x54, (byte)0x94,
90      (byte)0x7B, (byte)0x36, (byte)0xF5, (byte)0x72, (byte)0xDF, (byte)0xB1,
91      (byte)0x77, (byte)0xF4, (byte)0x13, (byte)0x43, (byte)0xCF, (byte)0xAF,
92      (byte)0xB1, (byte)0x33, (byte)0x34, (byte)0x61, (byte)0x79, (byte)0x5B,
93      (byte)0x92, (byte)0xB5, (byte)0x7C, (byte)0x2A, (byte)0x05, (byte)0xF1,
94      (byte)0x7C, (byte)0x99, (byte)0x01, (byte)0x1B, (byte)0x98, (byte)0xFD,
95      (byte)0x12, (byte)0x4F, (byte)0x4A, (byte)0x94, (byte)0x6C, (byte)0x3E,
96      (byte)0x60, (byte)0x26, (byte)0x5F, (byte)0x95, (byte)0xF8, (byte)0xD0,
97      (byte)0x89, (byte)0x24, (byte)0x85, (byte)0x67, (byte)0xC6, (byte)0x1F,
98      (byte)0x27, (byte)0x44, (byte)0xD2, (byte)0xEE, (byte)0xCF, (byte)0x65,
99      (byte)0xED, (byte)0xFF, (byte)0x07, (byte)0xC7, (byte)0x46, (byte)0xA1,
100     (byte)0x78, (byte)0x16, (byte)0x0C, (byte)0xED, (byte)0xE9, (byte)0x2D,
101     (byte)0x62, (byte)0xD4};
102 
103   /** value of the "AccessVersion" property for access 2000 dbs:
104       {@code "08.50"} */
105   private static final String ACCESS_VERSION_2000 = "08.50";
106   /** value of the "AccessVersion" property for access 2002/2003 dbs
107       {@code "09.50"}  */
108   private static final String ACCESS_VERSION_2003 = "09.50";
109 
110   /** known intro bytes for property maps */
111   static final byte[][] PROPERTY_MAP_TYPES = {
112     new byte[]{'M', 'R', '2', '\0'}, // access 2000+
113     new byte[]{'K', 'K', 'D', '\0'}};  // access 97
114 
115   // use nested inner class to avoid problematic static init loops
116   private static final class PossibleFileFormats {
117     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_3 =
118       Collections.singletonMap((String)null, Database.FileFormat.V1997);
119 
120     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_4 =
121       new HashMap<String,Database.FileFormat>();
122 
123     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_12 =
124       Collections.singletonMap((String)null, Database.FileFormat.V2007);
125 
126     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_14 =
127       Collections.singletonMap((String)null, Database.FileFormat.V2010);
128 
129     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_16 =
130       Collections.singletonMap((String)null, Database.FileFormat.V2016);
131 
132     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_17 =
133       Collections.singletonMap((String)null, Database.FileFormat.V2019);
134 
135     private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_MSISAM =
136       Collections.singletonMap((String)null, Database.FileFormat.MSISAM);
137 
138     static {
139       POSSIBLE_VERSION_4.put(ACCESS_VERSION_2000, Database.FileFormat.V2000);
140       POSSIBLE_VERSION_4.put(ACCESS_VERSION_2003, Database.FileFormat.V2003);
141       POSSIBLE_VERSION_4.put(null, Database.FileFormat.GENERIC_JET4);
142     }
143   }
144 
145   /** calculated types supported in version 14 */
146   private static final Set<DataType> V14_CALC_TYPES =
147     EnumSet.of(DataType.BOOLEAN, DataType.BYTE, DataType.INT, DataType.LONG,
148                DataType.FLOAT, DataType.DOUBLE, DataType.GUID,
149                DataType.SHORT_DATE_TIME, DataType.MONEY, DataType.NUMERIC,
150                DataType.TEXT, DataType.MEMO);
151 
152   /** calculated types supported in version 16 */
153   private static final Set<DataType> V16_CALC_TYPES = EnumSet.of(DataType.BIG_INT);
154   static {
155     V16_CALC_TYPES.addAll(V14_CALC_TYPES);
156   }
157 
158   private static final Set<DataType> V16_UNSUPP_TYPES =
159     EnumSet.of(DataType.EXT_DATE_TIME);
160   private static final Set<DataType> V12_UNSUPP_TYPES =
161     EnumSet.of(DataType.BIG_INT);
162   private static final Set<DataType> V3_UNSUPP_TYPES =
163     EnumSet.of(DataType.COMPLEX_TYPE);
164 
165   static {
166     V12_UNSUPP_TYPES.addAll(V16_UNSUPP_TYPES);
167     V3_UNSUPP_TYPES.addAll(V12_UNSUPP_TYPES);
168   }
169 
170   /** the JetFormat constants for the Jet database version "3" */
171   public static final JetFormat VERSION_3 = new Jet3Format();
172   /** the JetFormat constants for the Jet database version "4" */
173   public static final JetFormat VERSION_4 = new Jet4Format();
174   /** the JetFormat constants for the MSISAM database */
175   public static final JetFormat VERSION_MSISAM = new MSISAMFormat();
176   /** the JetFormat constants for the Jet database version "12.0" */
177   public static final JetFormat VERSION_12 = new Jet12Format();
178   /** the JetFormat constants for the Jet database version "14.0" */
179   public static final JetFormat VERSION_14 = new Jet14Format();
180   /** the JetFormat constants for the Jet database version "16.0" */
181   public static final JetFormat VERSION_16 = new Jet16Format();
182   /** the JetFormat constants for the Jet database version "17.0" */
183   public static final JetFormat VERSION_17 = new Jet17Format();
184 
185   //These constants are populated by this class's constructor.  They can't be
186   //populated by the subclass's constructor because they are final, and Java
187   //doesn't allow this; hence all the abstract defineXXX() methods.
188 
189   /** the name of this format */
190   private final String _name;
191 
192   /** the read/write mode of this format */
193   public final boolean READ_ONLY;
194 
195   /** whether or not we can use indexes in this format */
196   public final boolean INDEXES_SUPPORTED;
197 
198   /** type of page encoding supported */
199   public final CodecType CODEC_TYPE;
200 
201   /** Database page size in bytes */
202   public final int PAGE_SIZE;
203   public final long MAX_DATABASE_SIZE;
204 
205   public final int MAX_ROW_SIZE;
206   public final int DATA_PAGE_INITIAL_FREE_SPACE;
207 
208   public final int OFFSET_MASKED_HEADER;
209   public final byte[] HEADER_MASK;
210   public final int OFFSET_HEADER_DATE;
211   public final int OFFSET_PASSWORD;
212   public final int SIZE_PASSWORD;
213   public final int OFFSET_SORT_ORDER;
214   public final int SIZE_SORT_ORDER;
215   public final int OFFSET_CODE_PAGE;
216   public final int OFFSET_ENCODING_KEY;
217   public final int OFFSET_NEXT_TABLE_DEF_PAGE;
218   public final int OFFSET_NUM_ROWS;
219   public final int OFFSET_NEXT_AUTO_NUMBER;
220   public final int OFFSET_NEXT_COMPLEX_AUTO_NUMBER;
221   public final int OFFSET_TABLE_TYPE;
222   public final int OFFSET_MAX_COLS;
223   public final int OFFSET_NUM_VAR_COLS;
224   public final int OFFSET_NUM_COLS;
225   public final int OFFSET_NUM_INDEX_SLOTS;
226   public final int OFFSET_NUM_INDEXES;
227   public final int OFFSET_OWNED_PAGES;
228   public final int OFFSET_FREE_SPACE_PAGES;
229   public final int OFFSET_INDEX_DEF_BLOCK;
230 
231   public final int SIZE_INDEX_COLUMN_BLOCK;
232   public final int SIZE_INDEX_INFO_BLOCK;
233 
234   public final int OFFSET_COLUMN_TYPE;
235   public final int OFFSET_COLUMN_NUMBER;
236   public final int OFFSET_COLUMN_PRECISION;
237   public final int OFFSET_COLUMN_SCALE;
238   public final int OFFSET_COLUMN_SORT_ORDER;
239   public final int OFFSET_COLUMN_CODE_PAGE;
240   public final int OFFSET_COLUMN_COMPLEX_ID;
241   public final int OFFSET_COLUMN_FLAGS;
242   public final int OFFSET_COLUMN_EXT_FLAGS;
243   public final int OFFSET_COLUMN_LENGTH;
244   public final int OFFSET_COLUMN_VARIABLE_TABLE_INDEX;
245   public final int OFFSET_COLUMN_FIXED_DATA_OFFSET;
246   public final int OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET;
247 
248   public final int OFFSET_TABLE_DEF_LOCATION;
249 
250   public final int OFFSET_ROW_START;
251   public final int OFFSET_USAGE_MAP_START;
252 
253   public final int OFFSET_USAGE_MAP_PAGE_DATA;
254 
255   public final int OFFSET_REFERENCE_MAP_PAGE_NUMBERS;
256 
257   public final int OFFSET_FREE_SPACE;
258   public final int OFFSET_NUM_ROWS_ON_DATA_PAGE;
259   public final int MAX_NUM_ROWS_ON_DATA_PAGE;
260 
261   public final int OFFSET_INDEX_COMPRESSED_BYTE_COUNT;
262   public final int OFFSET_INDEX_ENTRY_MASK;
263   public final int OFFSET_PREV_INDEX_PAGE;
264   public final int OFFSET_NEXT_INDEX_PAGE;
265   public final int OFFSET_CHILD_TAIL_INDEX_PAGE;
266 
267   public final int SIZE_INDEX_DEFINITION;
268   public final int SIZE_COLUMN_HEADER;
269   public final int SIZE_ROW_LOCATION;
270   public final int SIZE_LONG_VALUE_DEF;
271   public final int MAX_INLINE_LONG_VALUE_SIZE;
272   public final int MAX_LONG_VALUE_ROW_SIZE;
273   public final int MAX_COMPRESSED_UNICODE_SIZE;
274   public final int SIZE_TDEF_HEADER;
275   public final int SIZE_TDEF_TRAILER;
276   public final int SIZE_COLUMN_DEF_BLOCK;
277   public final int SIZE_INDEX_ENTRY_MASK;
278   public final int SKIP_BEFORE_INDEX_FLAGS;
279   public final int SKIP_AFTER_INDEX_FLAGS;
280   public final int SKIP_BEFORE_INDEX_SLOT;
281   public final int SKIP_AFTER_INDEX_SLOT;
282   public final int SKIP_BEFORE_INDEX;
283   public final int SIZE_NAME_LENGTH;
284   public final int SIZE_ROW_COLUMN_COUNT;
285   public final int SIZE_ROW_VAR_COL_OFFSET;
286 
287   public final int USAGE_MAP_TABLE_BYTE_LENGTH;
288 
289   public final int MAX_COLUMNS_PER_TABLE;
290   public final int MAX_INDEXES_PER_TABLE;
291   public final int MAX_TABLE_NAME_LENGTH;
292   public final int MAX_COLUMN_NAME_LENGTH;
293   public final int MAX_INDEX_NAME_LENGTH;
294 
295   public final boolean LEGACY_NUMERIC_INDEXES;
296 
297   public final Charset CHARSET;
298   public final ColumnImpl.SortOrder DEFAULT_SORT_ORDER;
299   public final byte[] PROPERTY_MAP_TYPE;
300   public final int SIZE_TEXT_FIELD_UNIT;
301 
302   /**
303    * @param channel the database file.
304    * @return The Jet Format represented in the passed-in file
305    * @throws IOException if the database file format is unsupported.
306    */
307   public static JetFormat getFormat(FileChannel channel) throws IOException {
308     ByteBuffer buffer = ByteBuffer.allocate(HEADER_LENGTH);
309     int bytesRead = channel.read(buffer, 0L);
310     if(bytesRead < HEADER_LENGTH) {
311       throw new IOException("Empty database file");
312     }
313     buffer.flip();
314     byte version = buffer.get(OFFSET_VERSION);
315     if (version == CODE_VERSION_3) {
316       return VERSION_3;
317     } else if (version == CODE_VERSION_4) {
318       if(ByteUtil.matchesRange(buffer, OFFSET_ENGINE_NAME, MSISAM_ENGINE)) {
319         return VERSION_MSISAM;
320       }
321       return VERSION_4;
322     } else if (version == CODE_VERSION_12) {
323       return VERSION_12;
324     } else if (version == CODE_VERSION_14) {
325       return VERSION_14;
326     } else if (version == CODE_VERSION_16) {
327       return VERSION_16;
328     } else if (version == CODE_VERSION_17) {
329       return VERSION_17;
330     }
331     throw new IOException("Unsupported " +
332                           ((version < CODE_VERSION_3) ? "older" : "newer") +
333                           " version: " + version);
334   }
335 
336   private JetFormat(String name) {
337     _name = name;
338 
339     READ_ONLY = defineReadOnly();
340     INDEXES_SUPPORTED = defineIndexesSupported();
341     CODEC_TYPE = defineCodecType();
342 
343     PAGE_SIZE = definePageSize();
344     MAX_DATABASE_SIZE = defineMaxDatabaseSize();
345 
346     MAX_ROW_SIZE = defineMaxRowSize();
347     DATA_PAGE_INITIAL_FREE_SPACE = defineDataPageInitialFreeSpace();
348 
349     OFFSET_MASKED_HEADER = defineOffsetMaskedHeader();
350     HEADER_MASK = defineHeaderMask();
351     OFFSET_HEADER_DATE = defineOffsetHeaderDate();
352     OFFSET_PASSWORD = defineOffsetPassword();
353     SIZE_PASSWORD = defineSizePassword();
354     OFFSET_SORT_ORDER = defineOffsetSortOrder();
355     SIZE_SORT_ORDER = defineSizeSortOrder();
356     OFFSET_CODE_PAGE = defineOffsetCodePage();
357     OFFSET_ENCODING_KEY = defineOffsetEncodingKey();
358     OFFSET_NEXT_TABLE_DEF_PAGE = defineOffsetNextTableDefPage();
359     OFFSET_NUM_ROWS = defineOffsetNumRows();
360     OFFSET_NEXT_AUTO_NUMBER = defineOffsetNextAutoNumber();
361     OFFSET_NEXT_COMPLEX_AUTO_NUMBER = defineOffsetNextComplexAutoNumber();
362     OFFSET_TABLE_TYPE = defineOffsetTableType();
363     OFFSET_MAX_COLS = defineOffsetMaxCols();
364     OFFSET_NUM_VAR_COLS = defineOffsetNumVarCols();
365     OFFSET_NUM_COLS = defineOffsetNumCols();
366     OFFSET_NUM_INDEX_SLOTS = defineOffsetNumIndexSlots();
367     OFFSET_NUM_INDEXES = defineOffsetNumIndexes();
368     OFFSET_OWNED_PAGES = defineOffsetOwnedPages();
369     OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages();
370     OFFSET_INDEX_DEF_BLOCK = defineOffsetIndexDefBlock();
371 
372     SIZE_INDEX_COLUMN_BLOCK = defineSizeIndexColumnBlock();
373     SIZE_INDEX_INFO_BLOCK = defineSizeIndexInfoBlock();
374 
375     OFFSET_COLUMN_TYPE = defineOffsetColumnType();
376     OFFSET_COLUMN_NUMBER = defineOffsetColumnNumber();
377     OFFSET_COLUMN_PRECISION = defineOffsetColumnPrecision();
378     OFFSET_COLUMN_SCALE = defineOffsetColumnScale();
379     OFFSET_COLUMN_SORT_ORDER = defineOffsetColumnSortOrder();
380     OFFSET_COLUMN_CODE_PAGE = defineOffsetColumnCodePage();
381     OFFSET_COLUMN_COMPLEX_ID = defineOffsetColumnComplexId();
382     OFFSET_COLUMN_FLAGS = defineOffsetColumnFlags();
383     OFFSET_COLUMN_EXT_FLAGS = defineOffsetColumnExtFlags();
384     OFFSET_COLUMN_LENGTH = defineOffsetColumnLength();
385     OFFSET_COLUMN_VARIABLE_TABLE_INDEX = defineOffsetColumnVariableTableIndex();
386     OFFSET_COLUMN_FIXED_DATA_OFFSET = defineOffsetColumnFixedDataOffset();
387     OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET = defineOffsetColumnFixedDataRowOffset();
388 
389     OFFSET_TABLE_DEF_LOCATION = defineOffsetTableDefLocation();
390 
391     OFFSET_ROW_START = defineOffsetRowStart();
392     OFFSET_USAGE_MAP_START = defineOffsetUsageMapStart();
393 
394     OFFSET_USAGE_MAP_PAGE_DATA = defineOffsetUsageMapPageData();
395 
396     OFFSET_REFERENCE_MAP_PAGE_NUMBERS = defineOffsetReferenceMapPageNumbers();
397 
398     OFFSET_FREE_SPACE = defineOffsetFreeSpace();
399     OFFSET_NUM_ROWS_ON_DATA_PAGE = defineOffsetNumRowsOnDataPage();
400     MAX_NUM_ROWS_ON_DATA_PAGE = defineMaxNumRowsOnDataPage();
401 
402     OFFSET_INDEX_COMPRESSED_BYTE_COUNT = defineOffsetIndexCompressedByteCount();
403     OFFSET_INDEX_ENTRY_MASK = defineOffsetIndexEntryMask();
404     OFFSET_PREV_INDEX_PAGE = defineOffsetPrevIndexPage();
405     OFFSET_NEXT_INDEX_PAGE = defineOffsetNextIndexPage();
406     OFFSET_CHILD_TAIL_INDEX_PAGE = defineOffsetChildTailIndexPage();
407 
408     SIZE_INDEX_DEFINITION = defineSizeIndexDefinition();
409     SIZE_COLUMN_HEADER = defineSizeColumnHeader();
410     SIZE_ROW_LOCATION = defineSizeRowLocation();
411     SIZE_LONG_VALUE_DEF = defineSizeLongValueDef();
412     MAX_INLINE_LONG_VALUE_SIZE = defineMaxInlineLongValueSize();
413     MAX_LONG_VALUE_ROW_SIZE = defineMaxLongValueRowSize();
414     MAX_COMPRESSED_UNICODE_SIZE = defineMaxCompressedUnicodeSize();
415     SIZE_TDEF_HEADER = defineSizeTdefHeader();
416     SIZE_TDEF_TRAILER = defineSizeTdefTrailer();
417     SIZE_COLUMN_DEF_BLOCK = defineSizeColumnDefBlock();
418     SIZE_INDEX_ENTRY_MASK = defineSizeIndexEntryMask();
419     SKIP_BEFORE_INDEX_FLAGS = defineSkipBeforeIndexFlags();
420     SKIP_AFTER_INDEX_FLAGS = defineSkipAfterIndexFlags();
421     SKIP_BEFORE_INDEX_SLOT = defineSkipBeforeIndexSlot();
422     SKIP_AFTER_INDEX_SLOT = defineSkipAfterIndexSlot();
423     SKIP_BEFORE_INDEX = defineSkipBeforeIndex();
424     SIZE_NAME_LENGTH = defineSizeNameLength();
425     SIZE_ROW_COLUMN_COUNT = defineSizeRowColumnCount();
426     SIZE_ROW_VAR_COL_OFFSET = defineSizeRowVarColOffset();
427 
428     USAGE_MAP_TABLE_BYTE_LENGTH = defineUsageMapTableByteLength();
429 
430     MAX_COLUMNS_PER_TABLE = defineMaxColumnsPerTable();
431     MAX_INDEXES_PER_TABLE = defineMaxIndexesPerTable();
432     MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength();
433     MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength();
434     MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength();
435 
436     LEGACY_NUMERIC_INDEXES = defineLegacyNumericIndexes();
437 
438     CHARSET = defineCharset();
439     DEFAULT_SORT_ORDER = defineDefaultSortOrder();
440     PROPERTY_MAP_TYPE = definePropMapType();
441     SIZE_TEXT_FIELD_UNIT = defineSizeTextFieldUnit();
442   }
443 
444   protected abstract boolean defineReadOnly();
445   protected abstract boolean defineIndexesSupported();
446   protected abstract CodecType defineCodecType();
447 
448   protected abstract int definePageSize();
449   protected abstract long defineMaxDatabaseSize();
450 
451   protected abstract int defineMaxRowSize();
452   protected abstract int defineDataPageInitialFreeSpace();
453 
454   protected abstract int defineOffsetMaskedHeader();
455   protected abstract byte[] defineHeaderMask();
456   protected abstract int defineOffsetHeaderDate();
457   protected abstract int defineOffsetPassword();
458   protected abstract int defineSizePassword();
459   protected abstract int defineOffsetSortOrder();
460   protected abstract int defineSizeSortOrder();
461   protected abstract int defineOffsetCodePage();
462   protected abstract int defineOffsetEncodingKey();
463   protected abstract int defineOffsetNextTableDefPage();
464   protected abstract int defineOffsetNumRows();
465   protected abstract int defineOffsetNextAutoNumber();
466   protected abstract int defineOffsetNextComplexAutoNumber();
467   protected abstract int defineOffsetTableType();
468   protected abstract int defineOffsetMaxCols();
469   protected abstract int defineOffsetNumVarCols();
470   protected abstract int defineOffsetNumCols();
471   protected abstract int defineOffsetNumIndexSlots();
472   protected abstract int defineOffsetNumIndexes();
473   protected abstract int defineOffsetOwnedPages();
474   protected abstract int defineOffsetFreeSpacePages();
475   protected abstract int defineOffsetIndexDefBlock();
476 
477   protected abstract int defineSizeIndexColumnBlock();
478   protected abstract int defineSizeIndexInfoBlock();
479 
480   protected abstract int defineOffsetColumnType();
481   protected abstract int defineOffsetColumnNumber();
482   protected abstract int defineOffsetColumnPrecision();
483   protected abstract int defineOffsetColumnScale();
484   protected abstract int defineOffsetColumnSortOrder();
485   protected abstract int defineOffsetColumnCodePage();
486   protected abstract int defineOffsetColumnComplexId();
487   protected abstract int defineOffsetColumnFlags();
488   protected abstract int defineOffsetColumnExtFlags();
489   protected abstract int defineOffsetColumnLength();
490   protected abstract int defineOffsetColumnVariableTableIndex();
491   protected abstract int defineOffsetColumnFixedDataOffset();
492   protected abstract int defineOffsetColumnFixedDataRowOffset();
493 
494   protected abstract int defineOffsetTableDefLocation();
495 
496   protected abstract int defineOffsetRowStart();
497   protected abstract int defineOffsetUsageMapStart();
498 
499   protected abstract int defineOffsetUsageMapPageData();
500 
501   protected abstract int defineOffsetReferenceMapPageNumbers();
502 
503   protected abstract int defineOffsetFreeSpace();
504   protected abstract int defineOffsetNumRowsOnDataPage();
505   protected abstract int defineMaxNumRowsOnDataPage();
506 
507   protected abstract int defineOffsetIndexCompressedByteCount();
508   protected abstract int defineOffsetIndexEntryMask();
509   protected abstract int defineOffsetPrevIndexPage();
510   protected abstract int defineOffsetNextIndexPage();
511   protected abstract int defineOffsetChildTailIndexPage();
512 
513   protected abstract int defineSizeIndexDefinition();
514   protected abstract int defineSizeColumnHeader();
515   protected abstract int defineSizeRowLocation();
516   protected abstract int defineSizeLongValueDef();
517   protected abstract int defineMaxInlineLongValueSize();
518   protected abstract int defineMaxLongValueRowSize();
519   protected abstract int defineMaxCompressedUnicodeSize();
520   protected abstract int defineSizeTdefHeader();
521   protected abstract int defineSizeTdefTrailer();
522   protected abstract int defineSizeColumnDefBlock();
523   protected abstract int defineSizeIndexEntryMask();
524   protected abstract int defineSkipBeforeIndexFlags();
525   protected abstract int defineSkipAfterIndexFlags();
526   protected abstract int defineSkipBeforeIndexSlot();
527   protected abstract int defineSkipAfterIndexSlot();
528   protected abstract int defineSkipBeforeIndex();
529   protected abstract int defineSizeNameLength();
530   protected abstract int defineSizeRowColumnCount();
531   protected abstract int defineSizeRowVarColOffset();
532 
533   protected abstract int defineUsageMapTableByteLength();
534 
535   protected abstract int defineMaxColumnsPerTable();
536   protected abstract int defineMaxIndexesPerTable();
537   protected abstract int defineMaxTableNameLength();
538   protected abstract int defineMaxColumnNameLength();
539   protected abstract int defineMaxIndexNameLength();
540 
541   protected abstract Charset defineCharset();
542   protected abstract ColumnImpl.SortOrder defineDefaultSortOrder();
543   protected abstract byte[] definePropMapType();
544   protected abstract int defineSizeTextFieldUnit();
545 
546   protected abstract boolean defineLegacyNumericIndexes();
547 
548   protected abstract Map<String,Database.FileFormat> getPossibleFileFormats();
549 
550   public abstract boolean isSupportedDataType(DataType type);
551 
552   public abstract boolean isSupportedCalculatedDataType(DataType type);
553 
554   @Override
555   public String toString() {
556     return _name;
557   }
558 
559   private static class Jet3Format extends JetFormat {
560 
561     private Jet3Format() {
562       super("VERSION_3");
563     }
564 
565     @Override
566     protected boolean defineReadOnly() { return true; }
567 
568     @Override
569     protected boolean defineIndexesSupported() { return true; }
570 
571     @Override
572     protected CodecType defineCodecType() {
573       return CodecType.JET;
574     }
575 
576     @Override
577     protected int definePageSize() { return 2048; }
578 
579     @Override
580     protected long defineMaxDatabaseSize() {
581       return (1L * 1024L * 1024L * 1024L);
582     }
583 
584     @Override
585     protected int defineMaxRowSize() { return 2012; }
586     @Override
587     protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
588 
589     @Override
590     protected int defineOffsetMaskedHeader() { return 24; }
591     @Override
592     protected byte[] defineHeaderMask() {
593       return ByteUtil.copyOf(BASE_HEADER_MASK, BASE_HEADER_MASK.length - 2);
594     }
595     @Override
596     protected int defineOffsetHeaderDate() { return -1; }
597     @Override
598     protected int defineOffsetPassword() { return 66; }
599     @Override
600     protected int defineSizePassword() { return 20; }
601     @Override
602     protected int defineOffsetSortOrder() { return 58; }
603     @Override
604     protected int defineSizeSortOrder() { return 2; }
605     @Override
606     protected int defineOffsetCodePage() { return 60; }
607     @Override
608     protected int defineOffsetEncodingKey() { return 62; }
609     @Override
610     protected int defineOffsetNextTableDefPage() { return 4; }
611     @Override
612     protected int defineOffsetNumRows() { return 12; }
613     @Override
614     protected int defineOffsetNextAutoNumber() { return 20; }
615     @Override
616     protected int defineOffsetNextComplexAutoNumber() { return -1; }
617     @Override
618     protected int defineOffsetTableType() { return 20; }
619     @Override
620     protected int defineOffsetMaxCols() { return 21; }
621     @Override
622     protected int defineOffsetNumVarCols() { return 23; }
623     @Override
624     protected int defineOffsetNumCols() { return 25; }
625     @Override
626     protected int defineOffsetNumIndexSlots() { return 27; }
627     @Override
628     protected int defineOffsetNumIndexes() { return 31; }
629     @Override
630     protected int defineOffsetOwnedPages() { return 35; }
631     @Override
632     protected int defineOffsetFreeSpacePages() { return 39; }
633     @Override
634     protected int defineOffsetIndexDefBlock() { return 43; }
635 
636     @Override
637     protected int defineSizeIndexColumnBlock() { return 39; }
638     @Override
639     protected int defineSizeIndexInfoBlock() { return 20; }
640 
641     @Override
642     protected int defineOffsetColumnType() { return 0; }
643     @Override
644     protected int defineOffsetColumnNumber() { return 1; }
645     @Override
646     protected int defineOffsetColumnPrecision() { return 11; }
647     @Override
648     protected int defineOffsetColumnScale() { return 12; }
649     @Override
650     protected int defineOffsetColumnSortOrder() { return 9; }
651     @Override
652     protected int defineOffsetColumnCodePage() { return 11; }
653     @Override
654     protected int defineOffsetColumnComplexId() { return -1; }
655     @Override
656     protected int defineOffsetColumnFlags() { return 13; }
657     @Override
658     protected int defineOffsetColumnExtFlags() { return -1; }
659     @Override
660     protected int defineOffsetColumnLength() { return 16; }
661     @Override
662     protected int defineOffsetColumnVariableTableIndex() { return 3; }
663     @Override
664     protected int defineOffsetColumnFixedDataOffset() { return 14; }
665     @Override
666     protected int defineOffsetColumnFixedDataRowOffset() { return 1; }
667 
668     @Override
669     protected int defineOffsetTableDefLocation() { return 4; }
670 
671     @Override
672     protected int defineOffsetRowStart() { return 10; }
673     @Override
674     protected int defineOffsetUsageMapStart() { return 5; }
675 
676     @Override
677     protected int defineOffsetUsageMapPageData() { return 4; }
678 
679     @Override
680     protected int defineOffsetReferenceMapPageNumbers() { return 1; }
681 
682     @Override
683     protected int defineOffsetFreeSpace() { return 2; }
684     @Override
685     protected int defineOffsetNumRowsOnDataPage() { return 8; }
686     @Override
687     protected int defineMaxNumRowsOnDataPage() { return 255; }
688 
689     @Override
690     protected int defineOffsetIndexCompressedByteCount() { return 20; }
691     @Override
692     protected int defineOffsetIndexEntryMask() { return 22; }
693     @Override
694     protected int defineOffsetPrevIndexPage() { return 8; }
695     @Override
696     protected int defineOffsetNextIndexPage() { return 12; }
697     @Override
698     protected int defineOffsetChildTailIndexPage() { return 16; }
699 
700     @Override
701     protected int defineSizeIndexDefinition() { return 8; }
702     @Override
703     protected int defineSizeColumnHeader() { return 18; }
704     @Override
705     protected int defineSizeRowLocation() { return 2; }
706     @Override
707     protected int defineSizeLongValueDef() { return 12; }
708     @Override
709     protected int defineMaxInlineLongValueSize() { return 64; }
710     @Override
711     protected int defineMaxLongValueRowSize() { return 2032; }
712     @Override
713     protected int defineMaxCompressedUnicodeSize() { return 1024; }
714     @Override
715     protected int defineSizeTdefHeader() { return 43; }
716     @Override
717     protected int defineSizeTdefTrailer() { return 2; }
718     @Override
719     protected int defineSizeColumnDefBlock() { return 25; }
720     @Override
721     protected int defineSizeIndexEntryMask() { return 226; }
722     @Override
723     protected int defineSkipBeforeIndexFlags() { return 0; }
724     @Override
725     protected int defineSkipAfterIndexFlags() { return 0; }
726     @Override
727     protected int defineSkipBeforeIndexSlot() { return 0; }
728     @Override
729     protected int defineSkipAfterIndexSlot() { return 0; }
730     @Override
731     protected int defineSkipBeforeIndex() { return 0; }
732     @Override
733     protected int defineSizeNameLength() { return 1; }
734     @Override
735     protected int defineSizeRowColumnCount() { return 1; }
736     @Override
737     protected int defineSizeRowVarColOffset() { return 1; }
738 
739     @Override
740     protected int defineUsageMapTableByteLength() { return 128; }
741 
742     @Override
743     protected int defineMaxColumnsPerTable() { return 255; }
744 
745     @Override
746     protected int defineMaxIndexesPerTable() { return 32; }
747 
748     @Override
749     protected int defineMaxTableNameLength() { return 64; }
750 
751     @Override
752     protected int defineMaxColumnNameLength() { return 64; }
753 
754     @Override
755     protected int defineMaxIndexNameLength() { return 64; }
756 
757     @Override
758     protected boolean defineLegacyNumericIndexes() { return true; }
759 
760     @Override
761     protected Charset defineCharset() { return Charset.defaultCharset(); }
762 
763     @Override
764     protected ColumnImpl.SortOrder defineDefaultSortOrder() {
765       return ColumnImpl.GENERAL_97_SORT_ORDER;
766     }
767 
768     @Override
769     protected byte[] definePropMapType() {
770       return PROPERTY_MAP_TYPES[1];
771     }
772 
773     @Override
774     protected int defineSizeTextFieldUnit() { return 1; }
775 
776     @Override
777     protected Map<String,Database.FileFormat> getPossibleFileFormats()
778     {
779       return PossibleFileFormats.POSSIBLE_VERSION_3;
780     }
781 
782     @Override
783     public boolean isSupportedDataType(DataType type) {
784       return !V3_UNSUPP_TYPES.contains(type);
785     }
786 
787     @Override
788     public boolean isSupportedCalculatedDataType(DataType type) {
789       return false;
790     }
791   }
792 
793   private static class Jet4Format extends JetFormat {
794 
795     private Jet4Format() {
796       this("VERSION_4");
797     }
798 
799     private Jet4Format(String name) {
800       super(name);
801     }
802 
803     @Override
804     protected boolean defineReadOnly() { return false; }
805 
806     @Override
807     protected boolean defineIndexesSupported() { return true; }
808 
809     @Override
810     protected CodecType defineCodecType() {
811       return CodecType.JET;
812     }
813 
814     @Override
815     protected int definePageSize() { return 4096; }
816 
817     @Override
818     protected long defineMaxDatabaseSize() {
819       return (2L * 1024L * 1024L * 1024L);
820     }
821 
822     @Override
823     protected int defineMaxRowSize() { return 4060; }
824     @Override
825     protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
826 
827     @Override
828     protected int defineOffsetMaskedHeader() { return 24; }
829     @Override
830     protected byte[] defineHeaderMask() { return BASE_HEADER_MASK; }
831     @Override
832     protected int defineOffsetHeaderDate() { return 114; }
833     @Override
834     protected int defineOffsetPassword() { return 66; }
835     @Override
836     protected int defineSizePassword() { return 40; }
837     @Override
838     protected int defineOffsetSortOrder() { return 110; }
839     @Override
840     protected int defineSizeSortOrder() { return 4; }
841     @Override
842     protected int defineOffsetCodePage() { return 60; }
843     @Override
844     protected int defineOffsetEncodingKey() { return 62; }
845     @Override
846     protected int defineOffsetNextTableDefPage() { return 4; }
847     @Override
848     protected int defineOffsetNumRows() { return 16; }
849     @Override
850     protected int defineOffsetNextAutoNumber() { return 20; }
851     @Override
852     protected int defineOffsetNextComplexAutoNumber() { return -1; }
853     @Override
854     protected int defineOffsetTableType() { return 40; }
855     @Override
856     protected int defineOffsetMaxCols() { return 41; }
857     @Override
858     protected int defineOffsetNumVarCols() { return 43; }
859     @Override
860     protected int defineOffsetNumCols() { return 45; }
861     @Override
862     protected int defineOffsetNumIndexSlots() { return 47; }
863     @Override
864     protected int defineOffsetNumIndexes() { return 51; }
865     @Override
866     protected int defineOffsetOwnedPages() { return 55; }
867     @Override
868     protected int defineOffsetFreeSpacePages() { return 59; }
869     @Override
870     protected int defineOffsetIndexDefBlock() { return 63; }
871 
872     @Override
873     protected int defineSizeIndexColumnBlock() { return 52; }
874     @Override
875     protected int defineSizeIndexInfoBlock() { return 28; }
876 
877     @Override
878     protected int defineOffsetColumnType() { return 0; }
879     @Override
880     protected int defineOffsetColumnNumber() { return 5; }
881     @Override
882     protected int defineOffsetColumnPrecision() { return 11; }
883     @Override
884     protected int defineOffsetColumnScale() { return 12; }
885     @Override
886     protected int defineOffsetColumnSortOrder() { return 11; }
887     @Override
888     protected int defineOffsetColumnCodePage() { return -1; }
889     @Override
890     protected int defineOffsetColumnComplexId() { return -1; }
891     @Override
892     protected int defineOffsetColumnFlags() { return 15; }
893     @Override
894     protected int defineOffsetColumnExtFlags() { return 16; }
895     @Override
896     protected int defineOffsetColumnLength() { return 23; }
897     @Override
898     protected int defineOffsetColumnVariableTableIndex() { return 7; }
899     @Override
900     protected int defineOffsetColumnFixedDataOffset() { return 21; }
901     @Override
902     protected int defineOffsetColumnFixedDataRowOffset() { return 2; }
903 
904     @Override
905     protected int defineOffsetTableDefLocation() { return 4; }
906 
907     @Override
908     protected int defineOffsetRowStart() { return 14; }
909     @Override
910     protected int defineOffsetUsageMapStart() { return 5; }
911 
912     @Override
913     protected int defineOffsetUsageMapPageData() { return 4; }
914 
915     @Override
916     protected int defineOffsetReferenceMapPageNumbers() { return 1; }
917 
918     @Override
919     protected int defineOffsetFreeSpace() { return 2; }
920     @Override
921     protected int defineOffsetNumRowsOnDataPage() { return 12; }
922     @Override
923     protected int defineMaxNumRowsOnDataPage() { return 255; }
924 
925     @Override
926     protected int defineOffsetIndexCompressedByteCount() { return 24; }
927     @Override
928     protected int defineOffsetIndexEntryMask() { return 27; }
929     @Override
930     protected int defineOffsetPrevIndexPage() { return 12; }
931     @Override
932     protected int defineOffsetNextIndexPage() { return 16; }
933     @Override
934     protected int defineOffsetChildTailIndexPage() { return 20; }
935 
936     @Override
937     protected int defineSizeIndexDefinition() { return 12; }
938     @Override
939     protected int defineSizeColumnHeader() { return 25; }
940     @Override
941     protected int defineSizeRowLocation() { return 2; }
942     @Override
943     protected int defineSizeLongValueDef() { return 12; }
944     @Override
945     protected int defineMaxInlineLongValueSize() { return 64; }
946     @Override
947     protected int defineMaxLongValueRowSize() { return 4076; }
948     @Override
949     protected int defineMaxCompressedUnicodeSize() { return 1024; }
950     @Override
951     protected int defineSizeTdefHeader() { return 63; }
952     @Override
953     protected int defineSizeTdefTrailer() { return 2; }
954     @Override
955     protected int defineSizeColumnDefBlock() { return 25; }
956     @Override
957     protected int defineSizeIndexEntryMask() { return 453; }
958     @Override
959     protected int defineSkipBeforeIndexFlags() { return 4; }
960     @Override
961     protected int defineSkipAfterIndexFlags() { return 5; }
962     @Override
963     protected int defineSkipBeforeIndexSlot() { return 4; }
964     @Override
965     protected int defineSkipAfterIndexSlot() { return 4; }
966     @Override
967     protected int defineSkipBeforeIndex() { return 4; }
968     @Override
969     protected int defineSizeNameLength() { return 2; }
970     @Override
971     protected int defineSizeRowColumnCount() { return 2; }
972     @Override
973     protected int defineSizeRowVarColOffset() { return 2; }
974 
975     @Override
976     protected int defineUsageMapTableByteLength() { return 64; }
977 
978     @Override
979     protected int defineMaxColumnsPerTable() { return 255; }
980 
981     @Override
982     protected int defineMaxIndexesPerTable() { return 32; }
983 
984     @Override
985     protected int defineMaxTableNameLength() { return 64; }
986 
987     @Override
988     protected int defineMaxColumnNameLength() { return 64; }
989 
990     @Override
991     protected int defineMaxIndexNameLength() { return 64; }
992 
993     @Override
994     protected boolean defineLegacyNumericIndexes() { return true; }
995 
996     @Override
997     protected Charset defineCharset() { return StandardCharsets.UTF_16LE; }
998 
999     @Override
1000     protected ColumnImpl.SortOrder defineDefaultSortOrder() {
1001       return ColumnImpl.GENERAL_LEGACY_SORT_ORDER;
1002     }
1003 
1004     @Override
1005     protected byte[] definePropMapType() {
1006       return PROPERTY_MAP_TYPES[0];
1007     }
1008 
1009     @Override
1010     protected int defineSizeTextFieldUnit() { return TEXT_FIELD_UNIT_SIZE; }
1011 
1012     @Override
1013     protected Map<String,Database.FileFormat> getPossibleFileFormats()
1014     {
1015       return PossibleFileFormats.POSSIBLE_VERSION_4;
1016     }
1017 
1018     @Override
1019     public boolean isSupportedDataType(DataType type) {
1020       return !V3_UNSUPP_TYPES.contains(type);
1021     }
1022 
1023     @Override
1024     public boolean isSupportedCalculatedDataType(DataType type) {
1025       return false;
1026     }
1027   }
1028 
1029   private static final class MSISAMFormat extends Jet4Format {
1030     private MSISAMFormat() {
1031       super("MSISAM");
1032     }
1033 
1034     @Override
1035     protected CodecType defineCodecType() {
1036       return CodecType.MSISAM;
1037     }
1038 
1039     @Override
1040     protected Map<String,Database.FileFormat> getPossibleFileFormats()
1041     {
1042       return PossibleFileFormats.POSSIBLE_VERSION_MSISAM;
1043     }
1044   }
1045 
1046   private static class Jet12Format extends Jet4Format {
1047     private Jet12Format() {
1048       super("VERSION_12");
1049     }
1050 
1051     private Jet12Format(String name) {
1052       super(name);
1053     }
1054 
1055     @Override
1056     protected CodecType defineCodecType() {
1057       return CodecType.OFFICE;
1058     }
1059 
1060     @Override
1061     protected boolean defineLegacyNumericIndexes() { return false; }
1062 
1063     @Override
1064     protected Map<String,Database.FileFormat> getPossibleFileFormats() {
1065       return PossibleFileFormats.POSSIBLE_VERSION_12;
1066     }
1067 
1068     @Override
1069     protected int defineOffsetNextComplexAutoNumber() { return 28; }
1070 
1071     @Override
1072     protected int defineOffsetColumnComplexId() { return 11; }
1073 
1074     @Override
1075     public boolean isSupportedDataType(DataType type) {
1076       return !V12_UNSUPP_TYPES.contains(type);
1077     }
1078 
1079     @Override
1080     public boolean isSupportedCalculatedDataType(DataType type) {
1081       return false;
1082     }
1083   }
1084 
1085   private static class Jet14Format extends Jet12Format {
1086     private Jet14Format() {
1087       super("VERSION_14");
1088     }
1089 
1090     private Jet14Format(String name) {
1091       super(name);
1092     }
1093 
1094     @Override
1095     protected ColumnImpl.SortOrder defineDefaultSortOrder() {
1096       return ColumnImpl.GENERAL_SORT_ORDER;
1097     }
1098 
1099     @Override
1100     protected byte[] definePropMapType() {
1101       return PROPERTY_MAP_TYPES[0];
1102     }
1103 
1104     @Override
1105     protected Map<String,Database.FileFormat> getPossibleFileFormats() {
1106       return PossibleFileFormats.POSSIBLE_VERSION_14;
1107     }
1108 
1109     @Override
1110     public boolean isSupportedCalculatedDataType(DataType type) {
1111       return V14_CALC_TYPES.contains(type);
1112     }
1113   }
1114 
1115   private static class Jet16Format extends Jet14Format {
1116 
1117     private Jet16Format() {
1118       super("VERSION_16");
1119     }
1120 
1121     private Jet16Format(String name) {
1122       super(name);
1123     }
1124 
1125     @Override
1126     public boolean isSupportedDataType(DataType type) {
1127       return !V16_UNSUPP_TYPES.contains(type);
1128     }
1129 
1130     @Override
1131     protected Map<String,Database.FileFormat> getPossibleFileFormats() {
1132       return PossibleFileFormats.POSSIBLE_VERSION_16;
1133     }
1134 
1135     @Override
1136     public boolean isSupportedCalculatedDataType(DataType type) {
1137       return V16_CALC_TYPES.contains(type);
1138     }
1139   }
1140 
1141   private static final class Jet17Format extends Jet16Format {
1142 
1143     private Jet17Format() {
1144       super("VERSION_17");
1145     }
1146 
1147     @Override
1148     public boolean isSupportedDataType(DataType type) {
1149       return true;
1150     }
1151 
1152     @Override
1153     protected Map<String,Database.FileFormat> getPossibleFileFormats() {
1154       return PossibleFileFormats.POSSIBLE_VERSION_17;
1155     }
1156   }
1157 
1158 }