Browse Source

Fix length in units calculation for Access 97 text fields. Fixes #151

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1258 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.2
James Ahlborn 5 years ago
parent
commit
c25109f673

+ 3
- 0
src/changes/changes.xml View File

irrelevant failures when reading databases which have invalid column irrelevant failures when reading databases which have invalid column
properties. properties.
</action> </action>
<action dev="jahlborn" type="fix" system="SourceForge2" issue="151">
Fix length in units calculation for Access 97 text fields.
</action>
</release> </release>
<release version="2.2.0" date="2018-09-08" <release version="2.2.0" date="2018-09-08"
description="Add support for expression evaluation"> description="Add support for expression evaluation">

+ 23
- 6
src/main/java/com/healthmarketscience/jackcess/DataType.java View File

return _unitSize; return _unitSize;
} }


public int getUnitSize(JetFormat format) {
if((format != null) && isTextual()) {
return format.SIZE_TEXT_FIELD_UNIT;
}
return _unitSize;
}

public int toUnitSize(int size) { public int toUnitSize(int size) {
return(size / getUnitSize());
return toUnitSize(size, null);
}

public int toUnitSize(int size, JetFormat format) {
return(size / getUnitSize(format));
} }


public int fromUnitSize(int unitSize) { public int fromUnitSize(int unitSize) {
return(unitSize * getUnitSize());
return fromUnitSize(unitSize, null);
}

public int fromUnitSize(int unitSize, JetFormat format) {
return(unitSize * getUnitSize(format));
} }


public boolean isValidSize(int size) { public boolean isValidSize(int size) {
if(rtnArr == null) { if(rtnArr == null) {
throw new SQLException("Unsupported SQL type: " + sqlType); throw new SQLException("Unsupported SQL type: " + sqlType);
} }
JetFormat format =
((fileFormat != null) ?
DatabaseImpl.getFileFormatDetails(fileFormat).getFormat() :
null);
DataType rtn = rtnArr[0]; DataType rtn = rtnArr[0];
if((rtnArr.length > 1) && (fileFormat != null)) {
if((rtnArr.length > 1) && (format != null)) {
// there are multiple possibilities, ordered from lowest version to // there are multiple possibilities, ordered from lowest version to
// highest version supported. go in opposite order to find the best // highest version supported. go in opposite order to find the best
// type for this format // type for this format
JetFormat format = DatabaseImpl.getFileFormatDetails(fileFormat)
.getFormat();
for(int i = rtnArr.length - 1; i >= 0; --i) { for(int i = rtnArr.length - 1; i >= 0; --i) {
DataType tmp = rtnArr[i]; DataType tmp = rtnArr[i];
if(format.isSupportedDataType(tmp)) { if(format.isSupportedDataType(tmp)) {
} }


// make sure size is reasonable // make sure size is reasonable
int size = rtn.fromUnitSize(lengthInUnits);
int size = rtn.fromUnitSize(lengthInUnits, format);
if(rtn.isVariableLength() && !rtn.isValidSize(size)) { if(rtn.isVariableLength() && !rtn.isValidSize(size)) {
// try alternate type. we always accept alternate "long value" types // try alternate type. we always accept alternate "long value" types
// regardless of the given lengthInUnits // regardless of the given lengthInUnits

+ 6
- 4
src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java View File

} }


@Override @Override
public short getLengthInUnits() {
protected int calcLengthInUnits() {
// the byte "length" includes the calculated field overhead. remove // the byte "length" includes the calculated field overhead. remove
// that to get the _actual_ data length (in units) // that to get the _actual_ data length (in units)
return (short)getType().toUnitSize(getLength() - CALC_EXTRA_DATA_LEN);
return getType().toUnitSize(getLength() - CALC_EXTRA_DATA_LEN,
getFormat());
} }


@Override @Override
} }


@Override @Override
protected int getMaxLengthInUnits() {
protected int calcMaxLengthInUnits() {
// the byte "length" includes the calculated field overhead. remove // the byte "length" includes the calculated field overhead. remove
// that to get the _actual_ data length (in units) // that to get the _actual_ data length (in units)
return getType().toUnitSize(getType().getMaxSize() - CALC_EXTRA_DATA_LEN);
return getType().toUnitSize(getType().getMaxSize() - CALC_EXTRA_DATA_LEN,
getFormat());
} }


@Override @Override

+ 13
- 2
src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java View File

/** auto numbers must be > 0 */ /** auto numbers must be > 0 */
static final int INVALID_AUTO_NUMBER = 0; static final int INVALID_AUTO_NUMBER = 0;


static final int INVALID_LENGTH = -1;



/** owning table */ /** owning table */
private final TableImpl _table; private final TableImpl _table;
private ColumnValidator _validator = SimpleColumnValidator.INSTANCE; private ColumnValidator _validator = SimpleColumnValidator.INSTANCE;
/** default value generator */ /** default value generator */
private ColDefaultValueEvalContext _defValue; private ColDefaultValueEvalContext _defValue;
/** length of the column in units, lazily computed */
private int _lengthInUnits = INVALID_LENGTH;


/** /**
* @usage _advanced_method_ * @usage _advanced_method_
return _columnLength; return _columnLength;
} }


public short getLengthInUnits() {
return (short)getType().toUnitSize(getLength());
public final short getLengthInUnits() {
if(_lengthInUnits == INVALID_LENGTH) {
_lengthInUnits = calcLengthInUnits();
}
return (short)_lengthInUnits;
}

protected int calcLengthInUnits() {
return getType().toUnitSize(getLength(), getFormat());
} }


public boolean isCalculated() { public boolean isCalculated() {

+ 126
- 117
src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java View File

* @author Tim McCune * @author Tim McCune
*/ */
public abstract class JetFormat { public abstract class JetFormat {
/** Maximum size of a record minus OLE objects and Memo fields */ /** Maximum size of a record minus OLE objects and Memo fields */
public static final int MAX_RECORD_SIZE = 1900; //2kb minus some overhead public static final int MAX_RECORD_SIZE = 1900; //2kb minus some overhead


public enum CodecType { public enum CodecType {
NONE, JET, MSISAM, OFFICE; NONE, JET, MSISAM, OFFICE;
} }
/** Offset in the file that holds the byte describing the Jet format /** Offset in the file that holds the byte describing the Jet format
version */ version */
private static final int OFFSET_VERSION = 20; private static final int OFFSET_VERSION = 20;
static final int LENGTH_ENGINE_NAME = 0xF; static final int LENGTH_ENGINE_NAME = 0xF;
/** amount of initial data to be read to determine database type */ /** amount of initial data to be read to determine database type */
private static final int HEADER_LENGTH = 21; private static final int HEADER_LENGTH = 21;
private final static byte[] MSISAM_ENGINE = new byte[] { private final static byte[] MSISAM_ENGINE = new byte[] {
'M', 'S', 'I', 'S', 'A', 'M', ' ', 'D', 'a', 't', 'a', 'b', 'a', 's', 'e' 'M', 'S', 'I', 'S', 'A', 'M', ' ', 'D', 'a', 't', 'a', 'b', 'a', 's', 'e'
}; };
(byte)0xC2, (byte)0x55, (byte)0xEB, (byte)0xA9, (byte)0x67, (byte)0x72, (byte)0xC2, (byte)0x55, (byte)0xEB, (byte)0xA9, (byte)0x67, (byte)0x72,
(byte)0x43, (byte)0x3F, (byte)0x00, (byte)0x9C, (byte)0x7A, (byte)0x9F, (byte)0x43, (byte)0x3F, (byte)0x00, (byte)0x9C, (byte)0x7A, (byte)0x9F,
(byte)0x90, (byte)0xFF, (byte)0x80, (byte)0x9A, (byte)0x31, (byte)0xC5, (byte)0x90, (byte)0xFF, (byte)0x80, (byte)0x9A, (byte)0x31, (byte)0xC5,
(byte)0x79, (byte)0xBA, (byte)0xED, (byte)0x30, (byte)0xBC, (byte)0xDF,
(byte)0x79, (byte)0xBA, (byte)0xED, (byte)0x30, (byte)0xBC, (byte)0xDF,
(byte)0xCC, (byte)0x9D, (byte)0x63, (byte)0xD9, (byte)0xE4, (byte)0xC3, (byte)0xCC, (byte)0x9D, (byte)0x63, (byte)0xD9, (byte)0xE4, (byte)0xC3,
(byte)0x7B, (byte)0x42, (byte)0xFB, (byte)0x8A, (byte)0xBC, (byte)0x4E, (byte)0x7B, (byte)0x42, (byte)0xFB, (byte)0x8A, (byte)0xBC, (byte)0x4E,
(byte)0x86, (byte)0xFB, (byte)0xEC, (byte)0x37, (byte)0x5D, (byte)0x44, (byte)0x86, (byte)0xFB, (byte)0xEC, (byte)0x37, (byte)0x5D, (byte)0x44,
(byte)0x9C, (byte)0xFA, (byte)0xC6, (byte)0x5E, (byte)0x28, (byte)0xE6,
(byte)0x9C, (byte)0xFA, (byte)0xC6, (byte)0x5E, (byte)0x28, (byte)0xE6,
(byte)0x13, (byte)0xB6, (byte)0x8A, (byte)0x60, (byte)0x54, (byte)0x94, (byte)0x13, (byte)0xB6, (byte)0x8A, (byte)0x60, (byte)0x54, (byte)0x94,
(byte)0x7B, (byte)0x36, (byte)0xF5, (byte)0x72, (byte)0xDF, (byte)0xB1, (byte)0x7B, (byte)0x36, (byte)0xF5, (byte)0x72, (byte)0xDF, (byte)0xB1,
(byte)0x77, (byte)0xF4, (byte)0x13, (byte)0x43, (byte)0xCF, (byte)0xAF, (byte)0x77, (byte)0xF4, (byte)0x13, (byte)0x43, (byte)0xCF, (byte)0xAF,
(byte)0x27, (byte)0x44, (byte)0xD2, (byte)0xEE, (byte)0xCF, (byte)0x65, (byte)0x27, (byte)0x44, (byte)0xD2, (byte)0xEE, (byte)0xCF, (byte)0x65,
(byte)0xED, (byte)0xFF, (byte)0x07, (byte)0xC7, (byte)0x46, (byte)0xA1, (byte)0xED, (byte)0xFF, (byte)0x07, (byte)0xC7, (byte)0x46, (byte)0xA1,
(byte)0x78, (byte)0x16, (byte)0x0C, (byte)0xED, (byte)0xE9, (byte)0x2D, (byte)0x78, (byte)0x16, (byte)0x0C, (byte)0xED, (byte)0xE9, (byte)0x2D,
(byte)0x62, (byte)0xD4};
(byte)0x62, (byte)0xD4};


/** value of the "AccessVersion" property for access 2000 dbs: /** value of the "AccessVersion" property for access 2000 dbs:
{@code "08.50"} */ {@code "08.50"} */


// use nested inner class to avoid problematic static init loops // use nested inner class to avoid problematic static init loops
private static final class PossibleFileFormats { private static final class PossibleFileFormats {
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_3 =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_3 =
Collections.singletonMap((String)null, Database.FileFormat.V1997); Collections.singletonMap((String)null, Database.FileFormat.V1997);


private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_4 =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_4 =
new HashMap<String,Database.FileFormat>(); new HashMap<String,Database.FileFormat>();


private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_12 =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_12 =
Collections.singletonMap((String)null, Database.FileFormat.V2007); Collections.singletonMap((String)null, Database.FileFormat.V2007);


private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_14 =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_14 =
Collections.singletonMap((String)null, Database.FileFormat.V2010); Collections.singletonMap((String)null, Database.FileFormat.V2010);


private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_16 =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_16 =
Collections.singletonMap((String)null, Database.FileFormat.V2016); Collections.singletonMap((String)null, Database.FileFormat.V2016);


private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_MSISAM =
private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_MSISAM =
Collections.singletonMap((String)null, Database.FileFormat.MSISAM); Collections.singletonMap((String)null, Database.FileFormat.MSISAM);


static { static {
} }


/** calculated types supported in version 14 */ /** calculated types supported in version 14 */
private static final Set<DataType> V14_CALC_TYPES =
private static final Set<DataType> V14_CALC_TYPES =
EnumSet.of(DataType.BOOLEAN, DataType.BYTE, DataType.INT, DataType.LONG, EnumSet.of(DataType.BOOLEAN, DataType.BYTE, DataType.INT, DataType.LONG,
DataType.FLOAT, DataType.DOUBLE, DataType.GUID,
DataType.SHORT_DATE_TIME, DataType.MONEY, DataType.NUMERIC,
DataType.FLOAT, DataType.DOUBLE, DataType.GUID,
DataType.SHORT_DATE_TIME, DataType.MONEY, DataType.NUMERIC,
DataType.TEXT, DataType.MEMO); DataType.TEXT, DataType.MEMO);


/** calculated types supported in version 16 */ /** calculated types supported in version 16 */


/** the name of this format */ /** the name of this format */
private final String _name; private final String _name;
/** the read/write mode of this format */ /** the read/write mode of this format */
public final boolean READ_ONLY; public final boolean READ_ONLY;
/** whether or not we can use indexes in this format */ /** whether or not we can use indexes in this format */
public final boolean INDEXES_SUPPORTED; public final boolean INDEXES_SUPPORTED;


/** type of page encoding supported */ /** type of page encoding supported */
public final CodecType CODEC_TYPE; public final CodecType CODEC_TYPE;
/** Database page size in bytes */ /** Database page size in bytes */
public final int PAGE_SIZE; public final int PAGE_SIZE;
public final long MAX_DATABASE_SIZE; public final long MAX_DATABASE_SIZE;
public final int MAX_ROW_SIZE; public final int MAX_ROW_SIZE;
public final int DATA_PAGE_INITIAL_FREE_SPACE; public final int DATA_PAGE_INITIAL_FREE_SPACE;


public final int OFFSET_OWNED_PAGES; public final int OFFSET_OWNED_PAGES;
public final int OFFSET_FREE_SPACE_PAGES; public final int OFFSET_FREE_SPACE_PAGES;
public final int OFFSET_INDEX_DEF_BLOCK; public final int OFFSET_INDEX_DEF_BLOCK;
public final int SIZE_INDEX_COLUMN_BLOCK; public final int SIZE_INDEX_COLUMN_BLOCK;
public final int SIZE_INDEX_INFO_BLOCK; public final int SIZE_INDEX_INFO_BLOCK;
public final int OFFSET_COLUMN_TYPE; public final int OFFSET_COLUMN_TYPE;
public final int OFFSET_COLUMN_NUMBER; public final int OFFSET_COLUMN_NUMBER;
public final int OFFSET_COLUMN_PRECISION; public final int OFFSET_COLUMN_PRECISION;
public final int OFFSET_COLUMN_VARIABLE_TABLE_INDEX; public final int OFFSET_COLUMN_VARIABLE_TABLE_INDEX;
public final int OFFSET_COLUMN_FIXED_DATA_OFFSET; public final int OFFSET_COLUMN_FIXED_DATA_OFFSET;
public final int OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET; public final int OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET;
public final int OFFSET_TABLE_DEF_LOCATION; public final int OFFSET_TABLE_DEF_LOCATION;
public final int OFFSET_ROW_START; public final int OFFSET_ROW_START;
public final int OFFSET_USAGE_MAP_START; public final int OFFSET_USAGE_MAP_START;
public final int OFFSET_USAGE_MAP_PAGE_DATA; public final int OFFSET_USAGE_MAP_PAGE_DATA;
public final int OFFSET_REFERENCE_MAP_PAGE_NUMBERS; public final int OFFSET_REFERENCE_MAP_PAGE_NUMBERS;
public final int OFFSET_FREE_SPACE; public final int OFFSET_FREE_SPACE;
public final int OFFSET_NUM_ROWS_ON_DATA_PAGE; public final int OFFSET_NUM_ROWS_ON_DATA_PAGE;
public final int MAX_NUM_ROWS_ON_DATA_PAGE; public final int MAX_NUM_ROWS_ON_DATA_PAGE;
public final int OFFSET_INDEX_COMPRESSED_BYTE_COUNT; public final int OFFSET_INDEX_COMPRESSED_BYTE_COUNT;
public final int OFFSET_INDEX_ENTRY_MASK; public final int OFFSET_INDEX_ENTRY_MASK;
public final int OFFSET_PREV_INDEX_PAGE; public final int OFFSET_PREV_INDEX_PAGE;
public final int OFFSET_NEXT_INDEX_PAGE; public final int OFFSET_NEXT_INDEX_PAGE;
public final int OFFSET_CHILD_TAIL_INDEX_PAGE; public final int OFFSET_CHILD_TAIL_INDEX_PAGE;
public final int SIZE_INDEX_DEFINITION; public final int SIZE_INDEX_DEFINITION;
public final int SIZE_COLUMN_HEADER; public final int SIZE_COLUMN_HEADER;
public final int SIZE_ROW_LOCATION; public final int SIZE_ROW_LOCATION;
public final int SIZE_NAME_LENGTH; public final int SIZE_NAME_LENGTH;
public final int SIZE_ROW_COLUMN_COUNT; public final int SIZE_ROW_COLUMN_COUNT;
public final int SIZE_ROW_VAR_COL_OFFSET; public final int SIZE_ROW_VAR_COL_OFFSET;
public final int USAGE_MAP_TABLE_BYTE_LENGTH; public final int USAGE_MAP_TABLE_BYTE_LENGTH;


public final int MAX_COLUMNS_PER_TABLE; public final int MAX_COLUMNS_PER_TABLE;
public final int MAX_INDEX_NAME_LENGTH; public final int MAX_INDEX_NAME_LENGTH;


public final boolean LEGACY_NUMERIC_INDEXES; public final boolean LEGACY_NUMERIC_INDEXES;
public final Charset CHARSET; public final Charset CHARSET;
public final ColumnImpl.SortOrder DEFAULT_SORT_ORDER; public final ColumnImpl.SortOrder DEFAULT_SORT_ORDER;
public final byte[] PROPERTY_MAP_TYPE; public final byte[] PROPERTY_MAP_TYPE;
public final int SIZE_TEXT_FIELD_UNIT;

/** /**
* @param channel the database file. * @param channel the database file.
* @return The Jet Format represented in the passed-in file * @return The Jet Format represented in the passed-in file
((version < CODE_VERSION_3) ? "older" : "newer") + ((version < CODE_VERSION_3) ? "older" : "newer") +
" version: " + version); " version: " + version);
} }
private JetFormat(String name) { private JetFormat(String name) {
_name = name; _name = name;
READ_ONLY = defineReadOnly(); READ_ONLY = defineReadOnly();
INDEXES_SUPPORTED = defineIndexesSupported(); INDEXES_SUPPORTED = defineIndexesSupported();
CODEC_TYPE = defineCodecType(); CODEC_TYPE = defineCodecType();
PAGE_SIZE = definePageSize(); PAGE_SIZE = definePageSize();
MAX_DATABASE_SIZE = defineMaxDatabaseSize(); MAX_DATABASE_SIZE = defineMaxDatabaseSize();
MAX_ROW_SIZE = defineMaxRowSize(); MAX_ROW_SIZE = defineMaxRowSize();
DATA_PAGE_INITIAL_FREE_SPACE = defineDataPageInitialFreeSpace(); DATA_PAGE_INITIAL_FREE_SPACE = defineDataPageInitialFreeSpace();
OFFSET_MASKED_HEADER = defineOffsetMaskedHeader(); OFFSET_MASKED_HEADER = defineOffsetMaskedHeader();
HEADER_MASK = defineHeaderMask(); HEADER_MASK = defineHeaderMask();
OFFSET_HEADER_DATE = defineOffsetHeaderDate(); OFFSET_HEADER_DATE = defineOffsetHeaderDate();
OFFSET_OWNED_PAGES = defineOffsetOwnedPages(); OFFSET_OWNED_PAGES = defineOffsetOwnedPages();
OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages(); OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages();
OFFSET_INDEX_DEF_BLOCK = defineOffsetIndexDefBlock(); OFFSET_INDEX_DEF_BLOCK = defineOffsetIndexDefBlock();
SIZE_INDEX_COLUMN_BLOCK = defineSizeIndexColumnBlock(); SIZE_INDEX_COLUMN_BLOCK = defineSizeIndexColumnBlock();
SIZE_INDEX_INFO_BLOCK = defineSizeIndexInfoBlock(); SIZE_INDEX_INFO_BLOCK = defineSizeIndexInfoBlock();
OFFSET_COLUMN_TYPE = defineOffsetColumnType(); OFFSET_COLUMN_TYPE = defineOffsetColumnType();
OFFSET_COLUMN_NUMBER = defineOffsetColumnNumber(); OFFSET_COLUMN_NUMBER = defineOffsetColumnNumber();
OFFSET_COLUMN_PRECISION = defineOffsetColumnPrecision(); OFFSET_COLUMN_PRECISION = defineOffsetColumnPrecision();
OFFSET_COLUMN_VARIABLE_TABLE_INDEX = defineOffsetColumnVariableTableIndex(); OFFSET_COLUMN_VARIABLE_TABLE_INDEX = defineOffsetColumnVariableTableIndex();
OFFSET_COLUMN_FIXED_DATA_OFFSET = defineOffsetColumnFixedDataOffset(); OFFSET_COLUMN_FIXED_DATA_OFFSET = defineOffsetColumnFixedDataOffset();
OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET = defineOffsetColumnFixedDataRowOffset(); OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET = defineOffsetColumnFixedDataRowOffset();
OFFSET_TABLE_DEF_LOCATION = defineOffsetTableDefLocation(); OFFSET_TABLE_DEF_LOCATION = defineOffsetTableDefLocation();
OFFSET_ROW_START = defineOffsetRowStart(); OFFSET_ROW_START = defineOffsetRowStart();
OFFSET_USAGE_MAP_START = defineOffsetUsageMapStart(); OFFSET_USAGE_MAP_START = defineOffsetUsageMapStart();
OFFSET_USAGE_MAP_PAGE_DATA = defineOffsetUsageMapPageData(); OFFSET_USAGE_MAP_PAGE_DATA = defineOffsetUsageMapPageData();
OFFSET_REFERENCE_MAP_PAGE_NUMBERS = defineOffsetReferenceMapPageNumbers(); OFFSET_REFERENCE_MAP_PAGE_NUMBERS = defineOffsetReferenceMapPageNumbers();
OFFSET_FREE_SPACE = defineOffsetFreeSpace(); OFFSET_FREE_SPACE = defineOffsetFreeSpace();
OFFSET_NUM_ROWS_ON_DATA_PAGE = defineOffsetNumRowsOnDataPage(); OFFSET_NUM_ROWS_ON_DATA_PAGE = defineOffsetNumRowsOnDataPage();
MAX_NUM_ROWS_ON_DATA_PAGE = defineMaxNumRowsOnDataPage(); MAX_NUM_ROWS_ON_DATA_PAGE = defineMaxNumRowsOnDataPage();
OFFSET_INDEX_COMPRESSED_BYTE_COUNT = defineOffsetIndexCompressedByteCount(); OFFSET_INDEX_COMPRESSED_BYTE_COUNT = defineOffsetIndexCompressedByteCount();
OFFSET_INDEX_ENTRY_MASK = defineOffsetIndexEntryMask(); OFFSET_INDEX_ENTRY_MASK = defineOffsetIndexEntryMask();
OFFSET_PREV_INDEX_PAGE = defineOffsetPrevIndexPage(); OFFSET_PREV_INDEX_PAGE = defineOffsetPrevIndexPage();
OFFSET_NEXT_INDEX_PAGE = defineOffsetNextIndexPage(); OFFSET_NEXT_INDEX_PAGE = defineOffsetNextIndexPage();
OFFSET_CHILD_TAIL_INDEX_PAGE = defineOffsetChildTailIndexPage(); OFFSET_CHILD_TAIL_INDEX_PAGE = defineOffsetChildTailIndexPage();
SIZE_INDEX_DEFINITION = defineSizeIndexDefinition(); SIZE_INDEX_DEFINITION = defineSizeIndexDefinition();
SIZE_COLUMN_HEADER = defineSizeColumnHeader(); SIZE_COLUMN_HEADER = defineSizeColumnHeader();
SIZE_ROW_LOCATION = defineSizeRowLocation(); SIZE_ROW_LOCATION = defineSizeRowLocation();
MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength(); MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength();
MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength(); MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength();
MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength(); MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength();
LEGACY_NUMERIC_INDEXES = defineLegacyNumericIndexes(); LEGACY_NUMERIC_INDEXES = defineLegacyNumericIndexes();
CHARSET = defineCharset(); CHARSET = defineCharset();
DEFAULT_SORT_ORDER = defineDefaultSortOrder(); DEFAULT_SORT_ORDER = defineDefaultSortOrder();
PROPERTY_MAP_TYPE = definePropMapType(); PROPERTY_MAP_TYPE = definePropMapType();
SIZE_TEXT_FIELD_UNIT = defineSizeTextFieldUnit();
} }
protected abstract boolean defineReadOnly(); protected abstract boolean defineReadOnly();
protected abstract boolean defineIndexesSupported(); protected abstract boolean defineIndexesSupported();
protected abstract CodecType defineCodecType(); protected abstract CodecType defineCodecType();
protected abstract int definePageSize(); protected abstract int definePageSize();
protected abstract long defineMaxDatabaseSize(); protected abstract long defineMaxDatabaseSize();
protected abstract int defineMaxRowSize(); protected abstract int defineMaxRowSize();
protected abstract int defineDataPageInitialFreeSpace(); protected abstract int defineDataPageInitialFreeSpace();
protected abstract int defineOffsetMaskedHeader(); protected abstract int defineOffsetMaskedHeader();
protected abstract byte[] defineHeaderMask(); protected abstract byte[] defineHeaderMask();
protected abstract int defineOffsetHeaderDate(); protected abstract int defineOffsetHeaderDate();
protected abstract int defineOffsetOwnedPages(); protected abstract int defineOffsetOwnedPages();
protected abstract int defineOffsetFreeSpacePages(); protected abstract int defineOffsetFreeSpacePages();
protected abstract int defineOffsetIndexDefBlock(); protected abstract int defineOffsetIndexDefBlock();
protected abstract int defineSizeIndexColumnBlock(); protected abstract int defineSizeIndexColumnBlock();
protected abstract int defineSizeIndexInfoBlock(); protected abstract int defineSizeIndexInfoBlock();
protected abstract int defineOffsetColumnType(); protected abstract int defineOffsetColumnType();
protected abstract int defineOffsetColumnNumber(); protected abstract int defineOffsetColumnNumber();
protected abstract int defineOffsetColumnPrecision(); protected abstract int defineOffsetColumnPrecision();
protected abstract int defineOffsetColumnVariableTableIndex(); protected abstract int defineOffsetColumnVariableTableIndex();
protected abstract int defineOffsetColumnFixedDataOffset(); protected abstract int defineOffsetColumnFixedDataOffset();
protected abstract int defineOffsetColumnFixedDataRowOffset(); protected abstract int defineOffsetColumnFixedDataRowOffset();
protected abstract int defineOffsetTableDefLocation(); protected abstract int defineOffsetTableDefLocation();
protected abstract int defineOffsetRowStart(); protected abstract int defineOffsetRowStart();
protected abstract int defineOffsetUsageMapStart(); protected abstract int defineOffsetUsageMapStart();
protected abstract int defineOffsetUsageMapPageData(); protected abstract int defineOffsetUsageMapPageData();
protected abstract int defineOffsetReferenceMapPageNumbers(); protected abstract int defineOffsetReferenceMapPageNumbers();
protected abstract int defineOffsetFreeSpace(); protected abstract int defineOffsetFreeSpace();
protected abstract int defineOffsetNumRowsOnDataPage(); protected abstract int defineOffsetNumRowsOnDataPage();
protected abstract int defineMaxNumRowsOnDataPage(); protected abstract int defineMaxNumRowsOnDataPage();
protected abstract int defineOffsetIndexCompressedByteCount(); protected abstract int defineOffsetIndexCompressedByteCount();
protected abstract int defineOffsetIndexEntryMask(); protected abstract int defineOffsetIndexEntryMask();
protected abstract int defineOffsetPrevIndexPage(); protected abstract int defineOffsetPrevIndexPage();
protected abstract int defineOffsetNextIndexPage(); protected abstract int defineOffsetNextIndexPage();
protected abstract int defineOffsetChildTailIndexPage(); protected abstract int defineOffsetChildTailIndexPage();
protected abstract int defineSizeIndexDefinition(); protected abstract int defineSizeIndexDefinition();
protected abstract int defineSizeColumnHeader(); protected abstract int defineSizeColumnHeader();
protected abstract int defineSizeRowLocation(); protected abstract int defineSizeRowLocation();
protected abstract int defineMaxTableNameLength(); protected abstract int defineMaxTableNameLength();
protected abstract int defineMaxColumnNameLength(); protected abstract int defineMaxColumnNameLength();
protected abstract int defineMaxIndexNameLength(); protected abstract int defineMaxIndexNameLength();
protected abstract Charset defineCharset(); protected abstract Charset defineCharset();
protected abstract ColumnImpl.SortOrder defineDefaultSortOrder(); protected abstract ColumnImpl.SortOrder defineDefaultSortOrder();
protected abstract byte[] definePropMapType(); protected abstract byte[] definePropMapType();
protected abstract int defineSizeTextFieldUnit();


protected abstract boolean defineLegacyNumericIndexes(); protected abstract boolean defineLegacyNumericIndexes();


public String toString() { public String toString() {
return _name; return _name;
} }
private static class Jet3Format extends JetFormat { private static class Jet3Format extends JetFormat {


private Jet3Format() { private Jet3Format() {


@Override @Override
protected boolean defineReadOnly() { return true; } protected boolean defineReadOnly() { return true; }
@Override @Override
protected boolean defineIndexesSupported() { return false; } protected boolean defineIndexesSupported() { return false; }


@Override @Override
protected CodecType defineCodecType() {
return CodecType.JET;
protected CodecType defineCodecType() {
return CodecType.JET;
} }
@Override @Override
protected int definePageSize() { return 2048; } protected int definePageSize() { return 2048; }
@Override @Override
protected long defineMaxDatabaseSize() { protected long defineMaxDatabaseSize() {
return (1L * 1024L * 1024L * 1024L); return (1L * 1024L * 1024L * 1024L);
} }
@Override @Override
protected int defineMaxRowSize() { return 2012; } protected int defineMaxRowSize() { return 2012; }
@Override @Override
protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; } protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
@Override @Override
protected int defineOffsetMaskedHeader() { return 24; } protected int defineOffsetMaskedHeader() { return 24; }
@Override @Override
protected byte[] defineHeaderMask() {
return ByteUtil.copyOf(BASE_HEADER_MASK, BASE_HEADER_MASK.length - 2);
protected byte[] defineHeaderMask() {
return ByteUtil.copyOf(BASE_HEADER_MASK, BASE_HEADER_MASK.length - 2);
} }
@Override @Override
protected int defineOffsetHeaderDate() { return -1; } protected int defineOffsetHeaderDate() { return -1; }
protected int defineSizeIndexColumnBlock() { return 39; } protected int defineSizeIndexColumnBlock() { return 39; }
@Override @Override
protected int defineSizeIndexInfoBlock() { return 20; } protected int defineSizeIndexInfoBlock() { return 20; }
@Override @Override
protected int defineOffsetColumnType() { return 0; } protected int defineOffsetColumnType() { return 0; }
@Override @Override
protected int defineOffsetColumnFixedDataOffset() { return 14; } protected int defineOffsetColumnFixedDataOffset() { return 14; }
@Override @Override
protected int defineOffsetColumnFixedDataRowOffset() { return 1; } protected int defineOffsetColumnFixedDataRowOffset() { return 1; }
@Override @Override
protected int defineOffsetTableDefLocation() { return 4; } protected int defineOffsetTableDefLocation() { return 4; }
@Override @Override
protected int defineOffsetRowStart() { return 10; } protected int defineOffsetRowStart() { return 10; }
@Override @Override
protected int defineOffsetUsageMapStart() { return 5; } protected int defineOffsetUsageMapStart() { return 5; }
@Override @Override
protected int defineOffsetUsageMapPageData() { return 4; } protected int defineOffsetUsageMapPageData() { return 4; }
@Override @Override
protected int defineOffsetReferenceMapPageNumbers() { return 1; } protected int defineOffsetReferenceMapPageNumbers() { return 1; }
@Override @Override
protected int defineOffsetFreeSpace() { return 2; } protected int defineOffsetFreeSpace() { return 2; }
@Override @Override
protected int defineOffsetNumRowsOnDataPage() { return 8; } protected int defineOffsetNumRowsOnDataPage() { return 8; }
@Override @Override
protected int defineMaxNumRowsOnDataPage() { return 255; } protected int defineMaxNumRowsOnDataPage() { return 255; }
@Override @Override
protected int defineOffsetIndexCompressedByteCount() { return 20; } protected int defineOffsetIndexCompressedByteCount() { return 20; }
@Override @Override
protected int defineOffsetNextIndexPage() { return 12; } protected int defineOffsetNextIndexPage() { return 12; }
@Override @Override
protected int defineOffsetChildTailIndexPage() { return 16; } protected int defineOffsetChildTailIndexPage() { return 16; }
@Override @Override
protected int defineSizeIndexDefinition() { return 8; } protected int defineSizeIndexDefinition() { return 8; }
@Override @Override
protected int defineSizeRowColumnCount() { return 1; } protected int defineSizeRowColumnCount() { return 1; }
@Override @Override
protected int defineSizeRowVarColOffset() { return 1; } protected int defineSizeRowVarColOffset() { return 1; }
@Override @Override
protected int defineUsageMapTableByteLength() { return 128; } protected int defineUsageMapTableByteLength() { return 128; }
@Override @Override
protected int defineMaxColumnsPerTable() { return 255; } protected int defineMaxColumnsPerTable() { return 255; }
@Override @Override
protected int defineMaxIndexesPerTable() { return 32; } protected int defineMaxIndexesPerTable() { return 32; }
@Override @Override
protected int defineMaxTableNameLength() { return 64; } protected int defineMaxTableNameLength() { return 64; }
@Override @Override
protected int defineMaxColumnNameLength() { return 64; } protected int defineMaxColumnNameLength() { return 64; }
@Override @Override
protected int defineMaxIndexNameLength() { return 64; } protected int defineMaxIndexNameLength() { return 64; }
@Override @Override
protected boolean defineLegacyNumericIndexes() { return true; } protected boolean defineLegacyNumericIndexes() { return true; }


protected byte[] definePropMapType() { protected byte[] definePropMapType() {
return PROPERTY_MAP_TYPES[1]; return PROPERTY_MAP_TYPES[1];
} }

@Override
protected int defineSizeTextFieldUnit() { return 1; }

@Override @Override
protected Map<String,Database.FileFormat> getPossibleFileFormats() protected Map<String,Database.FileFormat> getPossibleFileFormats()
{ {
return false; return false;
} }
} }
private static class Jet4Format extends JetFormat { private static class Jet4Format extends JetFormat {


private Jet4Format() { private Jet4Format() {


@Override @Override
protected boolean defineReadOnly() { return false; } protected boolean defineReadOnly() { return false; }
@Override @Override
protected boolean defineIndexesSupported() { return true; } protected boolean defineIndexesSupported() { return true; }
@Override @Override
protected CodecType defineCodecType() {
return CodecType.JET;
protected CodecType defineCodecType() {
return CodecType.JET;
} }


@Override @Override
protected int definePageSize() { return 4096; } protected int definePageSize() { return 4096; }
@Override @Override
protected long defineMaxDatabaseSize() { protected long defineMaxDatabaseSize() {
return (2L * 1024L * 1024L * 1024L); return (2L * 1024L * 1024L * 1024L);
} }
@Override @Override
protected int defineMaxRowSize() { return 4060; } protected int defineMaxRowSize() { return 4060; }
@Override @Override
protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; } protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
@Override @Override
protected int defineOffsetMaskedHeader() { return 24; } protected int defineOffsetMaskedHeader() { return 24; }
@Override @Override
protected int defineSizeIndexColumnBlock() { return 52; } protected int defineSizeIndexColumnBlock() { return 52; }
@Override @Override
protected int defineSizeIndexInfoBlock() { return 28; } protected int defineSizeIndexInfoBlock() { return 28; }
@Override @Override
protected int defineOffsetColumnType() { return 0; } protected int defineOffsetColumnType() { return 0; }
@Override @Override
protected int defineOffsetColumnFixedDataOffset() { return 21; } protected int defineOffsetColumnFixedDataOffset() { return 21; }
@Override @Override
protected int defineOffsetColumnFixedDataRowOffset() { return 2; } protected int defineOffsetColumnFixedDataRowOffset() { return 2; }
@Override @Override
protected int defineOffsetTableDefLocation() { return 4; } protected int defineOffsetTableDefLocation() { return 4; }
@Override @Override
protected int defineOffsetRowStart() { return 14; } protected int defineOffsetRowStart() { return 14; }
@Override @Override
protected int defineOffsetUsageMapStart() { return 5; } protected int defineOffsetUsageMapStart() { return 5; }
@Override @Override
protected int defineOffsetUsageMapPageData() { return 4; } protected int defineOffsetUsageMapPageData() { return 4; }
@Override @Override
protected int defineOffsetReferenceMapPageNumbers() { return 1; } protected int defineOffsetReferenceMapPageNumbers() { return 1; }
@Override @Override
protected int defineOffsetFreeSpace() { return 2; } protected int defineOffsetFreeSpace() { return 2; }
@Override @Override
protected int defineOffsetNumRowsOnDataPage() { return 12; } protected int defineOffsetNumRowsOnDataPage() { return 12; }
@Override @Override
protected int defineMaxNumRowsOnDataPage() { return 255; } protected int defineMaxNumRowsOnDataPage() { return 255; }
@Override @Override
protected int defineOffsetIndexCompressedByteCount() { return 24; } protected int defineOffsetIndexCompressedByteCount() { return 24; }
@Override @Override
protected int defineOffsetNextIndexPage() { return 16; } protected int defineOffsetNextIndexPage() { return 16; }
@Override @Override
protected int defineOffsetChildTailIndexPage() { return 20; } protected int defineOffsetChildTailIndexPage() { return 20; }
@Override @Override
protected int defineSizeIndexDefinition() { return 12; } protected int defineSizeIndexDefinition() { return 12; }
@Override @Override
protected int defineSizeRowColumnCount() { return 2; } protected int defineSizeRowColumnCount() { return 2; }
@Override @Override
protected int defineSizeRowVarColOffset() { return 2; } protected int defineSizeRowVarColOffset() { return 2; }
@Override @Override
protected int defineUsageMapTableByteLength() { return 64; } protected int defineUsageMapTableByteLength() { return 64; }
@Override @Override
protected int defineMaxColumnsPerTable() { return 255; } protected int defineMaxColumnsPerTable() { return 255; }
@Override @Override
protected int defineMaxIndexesPerTable() { return 32; } protected int defineMaxIndexesPerTable() { return 32; }
@Override @Override
protected int defineMaxTableNameLength() { return 64; } protected int defineMaxTableNameLength() { return 64; }
@Override @Override
protected int defineMaxColumnNameLength() { return 64; } protected int defineMaxColumnNameLength() { return 64; }
@Override @Override
protected int defineMaxIndexNameLength() { return 64; } protected int defineMaxIndexNameLength() { return 64; }
@Override @Override
protected boolean defineLegacyNumericIndexes() { return true; } protected boolean defineLegacyNumericIndexes() { return true; }


return PROPERTY_MAP_TYPES[0]; return PROPERTY_MAP_TYPES[0];
} }


@Override
protected int defineSizeTextFieldUnit() { return TEXT_FIELD_UNIT_SIZE; }

@Override @Override
protected Map<String,Database.FileFormat> getPossibleFileFormats() protected Map<String,Database.FileFormat> getPossibleFileFormats()
{ {
return false; return false;
} }
} }
private static final class MSISAMFormat extends Jet4Format { private static final class MSISAMFormat extends Jet4Format {
private MSISAMFormat() { private MSISAMFormat() {
super("MSISAM"); super("MSISAM");
} }


@Override @Override
protected CodecType defineCodecType() {
return CodecType.MSISAM;
protected CodecType defineCodecType() {
return CodecType.MSISAM;
} }


@Override @Override
} }


@Override @Override
protected CodecType defineCodecType() {
return CodecType.OFFICE;
protected CodecType defineCodecType() {
return CodecType.OFFICE;
} }


@Override @Override


@Override @Override
protected int defineOffsetColumnComplexId() { return 11; } protected int defineOffsetColumnComplexId() { return 11; }
@Override @Override
public boolean isSupportedDataType(DataType type) { public boolean isSupportedDataType(DataType type) {
return (type != DataType.BIG_INT); return (type != DataType.BIG_INT);
private Jet16Format() { private Jet16Format() {
super("VERSION_16"); super("VERSION_16");
} }
@Override @Override
public boolean isSupportedDataType(DataType type) { public boolean isSupportedDataType(DataType type) {
return true; return true;

+ 10
- 2
src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java View File



/** Holds additional info for writing long values */ /** Holds additional info for writing long values */
private LongValueBufferHolder _lvalBufferH; private LongValueBufferHolder _lvalBufferH;
private int _maxLenInUnits = INVALID_LENGTH;


LongValueColumnImpl(InitArgs args) throws IOException LongValueColumnImpl(InitArgs args) throws IOException
{ {
super.postTableLoadInit(); super.postTableLoadInit();
} }


protected int getMaxLengthInUnits() {
return getType().toUnitSize(getType().getMaxSize());
protected final int getMaxLengthInUnits() {
if(_maxLenInUnits == INVALID_LENGTH) {
_maxLenInUnits = calcMaxLengthInUnits();
}
return _maxLenInUnits;
}

protected int calcMaxLengthInUnits() {
return getType().toUnitSize(getType().getMaxSize(), getFormat());
} }


@Override @Override

Loading…
Cancel
Save