aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2018-12-31 15:30:00 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2018-12-31 15:30:00 +0000
commitc25109f67386c6d5b5c7875cd6f82d9191b2751c (patch)
tree78e49adeffaf25176da0e3a5d451b61f33c6a964
parentf3a4168bd5943cb6c9bf210c037fa33ac5d9f95e (diff)
downloadjackcess-c25109f67386c6d5b5c7875cd6f82d9191b2751c.tar.gz
jackcess-c25109f67386c6d5b5c7875cd6f82d9191b2751c.zip
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
-rw-r--r--src/changes/changes.xml3
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/DataType.java29
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java10
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java15
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java243
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java12
6 files changed, 181 insertions, 131 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 904992d..efa4a64 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -27,6 +27,9 @@
irrelevant failures when reading databases which have invalid column
properties.
</action>
+ <action dev="jahlborn" type="fix" system="SourceForge2" issue="151">
+ Fix length in units calculation for Access 97 text fields.
+ </action>
</release>
<release version="2.2.0" date="2018-09-08"
description="Add support for expression evaluation">
diff --git a/src/main/java/com/healthmarketscience/jackcess/DataType.java b/src/main/java/com/healthmarketscience/jackcess/DataType.java
index 33496cf..380f7f1 100644
--- a/src/main/java/com/healthmarketscience/jackcess/DataType.java
+++ b/src/main/java/com/healthmarketscience/jackcess/DataType.java
@@ -389,12 +389,27 @@ public enum DataType {
return _unitSize;
}
+ public int getUnitSize(JetFormat format) {
+ if((format != null) && isTextual()) {
+ return format.SIZE_TEXT_FIELD_UNIT;
+ }
+ return _unitSize;
+ }
+
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) {
- return(unitSize * getUnitSize());
+ return fromUnitSize(unitSize, null);
+ }
+
+ public int fromUnitSize(int unitSize, JetFormat format) {
+ return(unitSize * getUnitSize(format));
}
public boolean isValidSize(int size) {
@@ -474,13 +489,15 @@ public enum DataType {
if(rtnArr == null) {
throw new SQLException("Unsupported SQL type: " + sqlType);
}
+ JetFormat format =
+ ((fileFormat != null) ?
+ DatabaseImpl.getFileFormatDetails(fileFormat).getFormat() :
+ null);
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
// highest version supported. go in opposite order to find the best
// type for this format
- JetFormat format = DatabaseImpl.getFileFormatDetails(fileFormat)
- .getFormat();
for(int i = rtnArr.length - 1; i >= 0; --i) {
DataType tmp = rtnArr[i];
if(format.isSupportedDataType(tmp)) {
@@ -491,7 +508,7 @@ public enum DataType {
}
// make sure size is reasonable
- int size = rtn.fromUnitSize(lengthInUnits);
+ int size = rtn.fromUnitSize(lengthInUnits, format);
if(rtn.isVariableLength() && !rtn.isValidSize(size)) {
// try alternate type. we always accept alternate "long value" types
// regardless of the given lengthInUnits
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java b/src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java
index fb76ad7..9aa7d17 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/CalculatedColumnUtil.java
@@ -242,10 +242,11 @@ class CalculatedColumnUtil
}
@Override
- public short getLengthInUnits() {
+ protected int calcLengthInUnits() {
// the byte "length" includes the calculated field overhead. remove
// 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
@@ -285,10 +286,11 @@ class CalculatedColumnUtil
}
@Override
- protected int getMaxLengthInUnits() {
+ protected int calcMaxLengthInUnits() {
// the byte "length" includes the calculated field overhead. remove
// 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
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
index 0016687..3445ba3 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
@@ -159,6 +159,8 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
/** auto numbers must be > 0 */
static final int INVALID_AUTO_NUMBER = 0;
+ static final int INVALID_LENGTH = -1;
+
/** owning table */
private final TableImpl _table;
@@ -192,6 +194,8 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
private ColumnValidator _validator = SimpleColumnValidator.INSTANCE;
/** default value generator */
private ColDefaultValueEvalContext _defValue;
+ /** length of the column in units, lazily computed */
+ private int _lengthInUnits = INVALID_LENGTH;
/**
* @usage _advanced_method_
@@ -429,8 +433,15 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
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() {
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java b/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
index a230edf..6ca0dd1 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
@@ -34,7 +34,7 @@ import com.healthmarketscience.jackcess.Database;
* @author Tim McCune
*/
public abstract class JetFormat {
-
+
/** Maximum size of a record minus OLE objects and Memo fields */
public static final int MAX_RECORD_SIZE = 1900; //2kb minus some overhead
@@ -46,7 +46,7 @@ public abstract class JetFormat {
public enum CodecType {
NONE, JET, MSISAM, OFFICE;
}
-
+
/** Offset in the file that holds the byte describing the Jet format
version */
private static final int OFFSET_VERSION = 20;
@@ -67,7 +67,7 @@ public abstract class JetFormat {
static final int LENGTH_ENGINE_NAME = 0xF;
/** amount of initial data to be read to determine database type */
private static final int HEADER_LENGTH = 21;
-
+
private final static byte[] MSISAM_ENGINE = new byte[] {
'M', 'S', 'I', 'S', 'A', 'M', ' ', 'D', 'a', 't', 'a', 'b', 'a', 's', 'e'
};
@@ -78,11 +78,11 @@ public abstract class JetFormat {
(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)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)0x7B, (byte)0x42, (byte)0xFB, (byte)0x8A, (byte)0xBC, (byte)0x4E,
(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)0x7B, (byte)0x36, (byte)0xF5, (byte)0x72, (byte)0xDF, (byte)0xB1,
(byte)0x77, (byte)0xF4, (byte)0x13, (byte)0x43, (byte)0xCF, (byte)0xAF,
@@ -95,7 +95,7 @@ public abstract class JetFormat {
(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)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:
{@code "08.50"} */
@@ -111,22 +111,22 @@ public abstract class JetFormat {
// use nested inner class to avoid problematic static init loops
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);
- 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>();
- 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);
- 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);
- 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);
- 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);
static {
@@ -137,10 +137,10 @@ public abstract class JetFormat {
}
/** 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,
- 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);
/** calculated types supported in version 16 */
@@ -168,20 +168,20 @@ public abstract class JetFormat {
/** the name of this format */
private final String _name;
-
+
/** the read/write mode of this format */
public final boolean READ_ONLY;
-
+
/** whether or not we can use indexes in this format */
public final boolean INDEXES_SUPPORTED;
/** type of page encoding supported */
public final CodecType CODEC_TYPE;
-
+
/** Database page size in bytes */
public final int PAGE_SIZE;
public final long MAX_DATABASE_SIZE;
-
+
public final int MAX_ROW_SIZE;
public final int DATA_PAGE_INITIAL_FREE_SPACE;
@@ -207,10 +207,10 @@ public abstract class JetFormat {
public final int OFFSET_OWNED_PAGES;
public final int OFFSET_FREE_SPACE_PAGES;
public final int OFFSET_INDEX_DEF_BLOCK;
-
+
public final int SIZE_INDEX_COLUMN_BLOCK;
public final int SIZE_INDEX_INFO_BLOCK;
-
+
public final int OFFSET_COLUMN_TYPE;
public final int OFFSET_COLUMN_NUMBER;
public final int OFFSET_COLUMN_PRECISION;
@@ -224,26 +224,26 @@ public abstract class JetFormat {
public final int OFFSET_COLUMN_VARIABLE_TABLE_INDEX;
public final int OFFSET_COLUMN_FIXED_DATA_OFFSET;
public final int OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET;
-
+
public final int OFFSET_TABLE_DEF_LOCATION;
-
+
public final int OFFSET_ROW_START;
public final int OFFSET_USAGE_MAP_START;
-
+
public final int OFFSET_USAGE_MAP_PAGE_DATA;
-
+
public final int OFFSET_REFERENCE_MAP_PAGE_NUMBERS;
-
+
public final int OFFSET_FREE_SPACE;
public final int OFFSET_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_ENTRY_MASK;
public final int OFFSET_PREV_INDEX_PAGE;
public final int OFFSET_NEXT_INDEX_PAGE;
public final int OFFSET_CHILD_TAIL_INDEX_PAGE;
-
+
public final int SIZE_INDEX_DEFINITION;
public final int SIZE_COLUMN_HEADER;
public final int SIZE_ROW_LOCATION;
@@ -263,7 +263,7 @@ public abstract class JetFormat {
public final int SIZE_NAME_LENGTH;
public final int SIZE_ROW_COLUMN_COUNT;
public final int SIZE_ROW_VAR_COL_OFFSET;
-
+
public final int USAGE_MAP_TABLE_BYTE_LENGTH;
public final int MAX_COLUMNS_PER_TABLE;
@@ -273,11 +273,12 @@ public abstract class JetFormat {
public final int MAX_INDEX_NAME_LENGTH;
public final boolean LEGACY_NUMERIC_INDEXES;
-
+
public final Charset CHARSET;
public final ColumnImpl.SortOrder DEFAULT_SORT_ORDER;
public final byte[] PROPERTY_MAP_TYPE;
-
+ public final int SIZE_TEXT_FIELD_UNIT;
+
/**
* @param channel the database file.
* @return The Jet Format represented in the passed-in file
@@ -309,20 +310,20 @@ public abstract class JetFormat {
((version < CODE_VERSION_3) ? "older" : "newer") +
" version: " + version);
}
-
+
private JetFormat(String name) {
_name = name;
-
+
READ_ONLY = defineReadOnly();
INDEXES_SUPPORTED = defineIndexesSupported();
CODEC_TYPE = defineCodecType();
-
+
PAGE_SIZE = definePageSize();
MAX_DATABASE_SIZE = defineMaxDatabaseSize();
-
+
MAX_ROW_SIZE = defineMaxRowSize();
DATA_PAGE_INITIAL_FREE_SPACE = defineDataPageInitialFreeSpace();
-
+
OFFSET_MASKED_HEADER = defineOffsetMaskedHeader();
HEADER_MASK = defineHeaderMask();
OFFSET_HEADER_DATE = defineOffsetHeaderDate();
@@ -345,10 +346,10 @@ public abstract class JetFormat {
OFFSET_OWNED_PAGES = defineOffsetOwnedPages();
OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages();
OFFSET_INDEX_DEF_BLOCK = defineOffsetIndexDefBlock();
-
+
SIZE_INDEX_COLUMN_BLOCK = defineSizeIndexColumnBlock();
SIZE_INDEX_INFO_BLOCK = defineSizeIndexInfoBlock();
-
+
OFFSET_COLUMN_TYPE = defineOffsetColumnType();
OFFSET_COLUMN_NUMBER = defineOffsetColumnNumber();
OFFSET_COLUMN_PRECISION = defineOffsetColumnPrecision();
@@ -362,26 +363,26 @@ public abstract class JetFormat {
OFFSET_COLUMN_VARIABLE_TABLE_INDEX = defineOffsetColumnVariableTableIndex();
OFFSET_COLUMN_FIXED_DATA_OFFSET = defineOffsetColumnFixedDataOffset();
OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET = defineOffsetColumnFixedDataRowOffset();
-
+
OFFSET_TABLE_DEF_LOCATION = defineOffsetTableDefLocation();
-
+
OFFSET_ROW_START = defineOffsetRowStart();
OFFSET_USAGE_MAP_START = defineOffsetUsageMapStart();
-
+
OFFSET_USAGE_MAP_PAGE_DATA = defineOffsetUsageMapPageData();
-
+
OFFSET_REFERENCE_MAP_PAGE_NUMBERS = defineOffsetReferenceMapPageNumbers();
-
+
OFFSET_FREE_SPACE = defineOffsetFreeSpace();
OFFSET_NUM_ROWS_ON_DATA_PAGE = defineOffsetNumRowsOnDataPage();
MAX_NUM_ROWS_ON_DATA_PAGE = defineMaxNumRowsOnDataPage();
-
+
OFFSET_INDEX_COMPRESSED_BYTE_COUNT = defineOffsetIndexCompressedByteCount();
OFFSET_INDEX_ENTRY_MASK = defineOffsetIndexEntryMask();
OFFSET_PREV_INDEX_PAGE = defineOffsetPrevIndexPage();
OFFSET_NEXT_INDEX_PAGE = defineOffsetNextIndexPage();
OFFSET_CHILD_TAIL_INDEX_PAGE = defineOffsetChildTailIndexPage();
-
+
SIZE_INDEX_DEFINITION = defineSizeIndexDefinition();
SIZE_COLUMN_HEADER = defineSizeColumnHeader();
SIZE_ROW_LOCATION = defineSizeRowLocation();
@@ -409,24 +410,25 @@ public abstract class JetFormat {
MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength();
MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength();
MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength();
-
+
LEGACY_NUMERIC_INDEXES = defineLegacyNumericIndexes();
-
+
CHARSET = defineCharset();
DEFAULT_SORT_ORDER = defineDefaultSortOrder();
PROPERTY_MAP_TYPE = definePropMapType();
+ SIZE_TEXT_FIELD_UNIT = defineSizeTextFieldUnit();
}
-
+
protected abstract boolean defineReadOnly();
protected abstract boolean defineIndexesSupported();
protected abstract CodecType defineCodecType();
-
+
protected abstract int definePageSize();
protected abstract long defineMaxDatabaseSize();
-
+
protected abstract int defineMaxRowSize();
protected abstract int defineDataPageInitialFreeSpace();
-
+
protected abstract int defineOffsetMaskedHeader();
protected abstract byte[] defineHeaderMask();
protected abstract int defineOffsetHeaderDate();
@@ -449,10 +451,10 @@ public abstract class JetFormat {
protected abstract int defineOffsetOwnedPages();
protected abstract int defineOffsetFreeSpacePages();
protected abstract int defineOffsetIndexDefBlock();
-
+
protected abstract int defineSizeIndexColumnBlock();
protected abstract int defineSizeIndexInfoBlock();
-
+
protected abstract int defineOffsetColumnType();
protected abstract int defineOffsetColumnNumber();
protected abstract int defineOffsetColumnPrecision();
@@ -466,26 +468,26 @@ public abstract class JetFormat {
protected abstract int defineOffsetColumnVariableTableIndex();
protected abstract int defineOffsetColumnFixedDataOffset();
protected abstract int defineOffsetColumnFixedDataRowOffset();
-
+
protected abstract int defineOffsetTableDefLocation();
-
+
protected abstract int defineOffsetRowStart();
protected abstract int defineOffsetUsageMapStart();
-
+
protected abstract int defineOffsetUsageMapPageData();
-
+
protected abstract int defineOffsetReferenceMapPageNumbers();
-
+
protected abstract int defineOffsetFreeSpace();
protected abstract int defineOffsetNumRowsOnDataPage();
protected abstract int defineMaxNumRowsOnDataPage();
-
+
protected abstract int defineOffsetIndexCompressedByteCount();
protected abstract int defineOffsetIndexEntryMask();
protected abstract int defineOffsetPrevIndexPage();
protected abstract int defineOffsetNextIndexPage();
protected abstract int defineOffsetChildTailIndexPage();
-
+
protected abstract int defineSizeIndexDefinition();
protected abstract int defineSizeColumnHeader();
protected abstract int defineSizeRowLocation();
@@ -513,10 +515,11 @@ public abstract class JetFormat {
protected abstract int defineMaxTableNameLength();
protected abstract int defineMaxColumnNameLength();
protected abstract int defineMaxIndexNameLength();
-
+
protected abstract Charset defineCharset();
protected abstract ColumnImpl.SortOrder defineDefaultSortOrder();
protected abstract byte[] definePropMapType();
+ protected abstract int defineSizeTextFieldUnit();
protected abstract boolean defineLegacyNumericIndexes();
@@ -530,7 +533,7 @@ public abstract class JetFormat {
public String toString() {
return _name;
}
-
+
private static class Jet3Format extends JetFormat {
private Jet3Format() {
@@ -539,33 +542,33 @@ public abstract class JetFormat {
@Override
protected boolean defineReadOnly() { return true; }
-
+
@Override
protected boolean defineIndexesSupported() { return false; }
@Override
- protected CodecType defineCodecType() {
- return CodecType.JET;
+ protected CodecType defineCodecType() {
+ return CodecType.JET;
}
-
+
@Override
protected int definePageSize() { return 2048; }
-
+
@Override
protected long defineMaxDatabaseSize() {
return (1L * 1024L * 1024L * 1024L);
}
-
+
@Override
protected int defineMaxRowSize() { return 2012; }
@Override
protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
-
+
@Override
protected int defineOffsetMaskedHeader() { return 24; }
@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
protected int defineOffsetHeaderDate() { return -1; }
@@ -612,7 +615,7 @@ public abstract class JetFormat {
protected int defineSizeIndexColumnBlock() { return 39; }
@Override
protected int defineSizeIndexInfoBlock() { return 20; }
-
+
@Override
protected int defineOffsetColumnType() { return 0; }
@Override
@@ -639,28 +642,28 @@ public abstract class JetFormat {
protected int defineOffsetColumnFixedDataOffset() { return 14; }
@Override
protected int defineOffsetColumnFixedDataRowOffset() { return 1; }
-
+
@Override
protected int defineOffsetTableDefLocation() { return 4; }
-
+
@Override
protected int defineOffsetRowStart() { return 10; }
@Override
protected int defineOffsetUsageMapStart() { return 5; }
-
+
@Override
protected int defineOffsetUsageMapPageData() { return 4; }
-
+
@Override
protected int defineOffsetReferenceMapPageNumbers() { return 1; }
-
+
@Override
protected int defineOffsetFreeSpace() { return 2; }
@Override
protected int defineOffsetNumRowsOnDataPage() { return 8; }
@Override
protected int defineMaxNumRowsOnDataPage() { return 255; }
-
+
@Override
protected int defineOffsetIndexCompressedByteCount() { return 20; }
@Override
@@ -671,7 +674,7 @@ public abstract class JetFormat {
protected int defineOffsetNextIndexPage() { return 12; }
@Override
protected int defineOffsetChildTailIndexPage() { return 16; }
-
+
@Override
protected int defineSizeIndexDefinition() { return 8; }
@Override
@@ -710,25 +713,25 @@ public abstract class JetFormat {
protected int defineSizeRowColumnCount() { return 1; }
@Override
protected int defineSizeRowVarColOffset() { return 1; }
-
+
@Override
protected int defineUsageMapTableByteLength() { return 128; }
-
+
@Override
protected int defineMaxColumnsPerTable() { return 255; }
-
+
@Override
protected int defineMaxIndexesPerTable() { return 32; }
-
+
@Override
protected int defineMaxTableNameLength() { return 64; }
-
+
@Override
protected int defineMaxColumnNameLength() { return 64; }
-
+
@Override
protected int defineMaxIndexNameLength() { return 64; }
-
+
@Override
protected boolean defineLegacyNumericIndexes() { return true; }
@@ -744,7 +747,10 @@ public abstract class JetFormat {
protected byte[] definePropMapType() {
return PROPERTY_MAP_TYPES[1];
}
-
+
+ @Override
+ protected int defineSizeTextFieldUnit() { return 1; }
+
@Override
protected Map<String,Database.FileFormat> getPossibleFileFormats()
{
@@ -762,7 +768,7 @@ public abstract class JetFormat {
return false;
}
}
-
+
private static class Jet4Format extends JetFormat {
private Jet4Format() {
@@ -775,28 +781,28 @@ public abstract class JetFormat {
@Override
protected boolean defineReadOnly() { return false; }
-
+
@Override
protected boolean defineIndexesSupported() { return true; }
-
+
@Override
- protected CodecType defineCodecType() {
- return CodecType.JET;
+ protected CodecType defineCodecType() {
+ return CodecType.JET;
}
@Override
protected int definePageSize() { return 4096; }
-
+
@Override
protected long defineMaxDatabaseSize() {
return (2L * 1024L * 1024L * 1024L);
}
-
+
@Override
protected int defineMaxRowSize() { return 4060; }
@Override
protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
-
+
@Override
protected int defineOffsetMaskedHeader() { return 24; }
@Override
@@ -846,7 +852,7 @@ public abstract class JetFormat {
protected int defineSizeIndexColumnBlock() { return 52; }
@Override
protected int defineSizeIndexInfoBlock() { return 28; }
-
+
@Override
protected int defineOffsetColumnType() { return 0; }
@Override
@@ -873,28 +879,28 @@ public abstract class JetFormat {
protected int defineOffsetColumnFixedDataOffset() { return 21; }
@Override
protected int defineOffsetColumnFixedDataRowOffset() { return 2; }
-
+
@Override
protected int defineOffsetTableDefLocation() { return 4; }
-
+
@Override
protected int defineOffsetRowStart() { return 14; }
@Override
protected int defineOffsetUsageMapStart() { return 5; }
-
+
@Override
protected int defineOffsetUsageMapPageData() { return 4; }
-
+
@Override
protected int defineOffsetReferenceMapPageNumbers() { return 1; }
-
+
@Override
protected int defineOffsetFreeSpace() { return 2; }
@Override
protected int defineOffsetNumRowsOnDataPage() { return 12; }
@Override
protected int defineMaxNumRowsOnDataPage() { return 255; }
-
+
@Override
protected int defineOffsetIndexCompressedByteCount() { return 24; }
@Override
@@ -905,7 +911,7 @@ public abstract class JetFormat {
protected int defineOffsetNextIndexPage() { return 16; }
@Override
protected int defineOffsetChildTailIndexPage() { return 20; }
-
+
@Override
protected int defineSizeIndexDefinition() { return 12; }
@Override
@@ -944,25 +950,25 @@ public abstract class JetFormat {
protected int defineSizeRowColumnCount() { return 2; }
@Override
protected int defineSizeRowVarColOffset() { return 2; }
-
+
@Override
protected int defineUsageMapTableByteLength() { return 64; }
-
+
@Override
protected int defineMaxColumnsPerTable() { return 255; }
-
+
@Override
protected int defineMaxIndexesPerTable() { return 32; }
-
+
@Override
protected int defineMaxTableNameLength() { return 64; }
-
+
@Override
protected int defineMaxColumnNameLength() { return 64; }
-
+
@Override
protected int defineMaxIndexNameLength() { return 64; }
-
+
@Override
protected boolean defineLegacyNumericIndexes() { return true; }
@@ -980,6 +986,9 @@ public abstract class JetFormat {
}
@Override
+ protected int defineSizeTextFieldUnit() { return TEXT_FIELD_UNIT_SIZE; }
+
+ @Override
protected Map<String,Database.FileFormat> getPossibleFileFormats()
{
return PossibleFileFormats.POSSIBLE_VERSION_4;
@@ -996,15 +1005,15 @@ public abstract class JetFormat {
return false;
}
}
-
+
private static final class MSISAMFormat extends Jet4Format {
private MSISAMFormat() {
super("MSISAM");
}
@Override
- protected CodecType defineCodecType() {
- return CodecType.MSISAM;
+ protected CodecType defineCodecType() {
+ return CodecType.MSISAM;
}
@Override
@@ -1024,8 +1033,8 @@ public abstract class JetFormat {
}
@Override
- protected CodecType defineCodecType() {
- return CodecType.OFFICE;
+ protected CodecType defineCodecType() {
+ return CodecType.OFFICE;
}
@Override
@@ -1041,7 +1050,7 @@ public abstract class JetFormat {
@Override
protected int defineOffsetColumnComplexId() { return 11; }
-
+
@Override
public boolean isSupportedDataType(DataType type) {
return (type != DataType.BIG_INT);
@@ -1088,7 +1097,7 @@ public abstract class JetFormat {
private Jet16Format() {
super("VERSION_16");
}
-
+
@Override
public boolean isSupportedDataType(DataType type) {
return true;
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java
index f878562..d1b2a07 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/LongValueColumnImpl.java
@@ -55,6 +55,7 @@ class LongValueColumnImpl extends ColumnImpl
/** Holds additional info for writing long values */
private LongValueBufferHolder _lvalBufferH;
+ private int _maxLenInUnits = INVALID_LENGTH;
LongValueColumnImpl(InitArgs args) throws IOException
{
@@ -84,8 +85,15 @@ class LongValueColumnImpl extends ColumnImpl
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