From c190f7216c07da257eebad77d587ee7a21654899 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Tue, 17 Nov 2009 03:39:11 +0000 Subject: [PATCH] support reading/writing fixed length text columns (fixe #2886370) git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@411 f203690c-595d-4dc9-a70b-905162fa7fd2 --- src/changes/changes.xml | 6 +++ .../healthmarketscience/jackcess/Column.java | 36 +++++++++++++++++- .../jackcess/DataType.java | 15 +++++++- .../healthmarketscience/jackcess/Table.java | 5 +-- test/data/fixedTextTest.mdb | Bin 0 -> 135168 bytes .../jackcess/DatabaseTest.java | 24 ++++++++++++ 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100755 test/data/fixedTextTest.mdb diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 2be53cf..f22ad4e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -9,6 +9,12 @@ Add support for updating GUID indexes and for auto-number GUID fields. + + Add support for updating rows in a table. + + + Support reading/writing fixed length text fields. + diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index a41b450..85ebde0 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -345,6 +345,12 @@ public class Column implements Comparable { return; } + if((_autoNumberGenerator != null) && + (_autoNumberGenerator.getType() == _type)) { + // keep existing + return; + } + switch(_type) { case LONG: _autoNumberGenerator = new LongAutoNumberGenerator(); @@ -1098,7 +1104,7 @@ public class Column implements Comparable { public ByteBuffer writeFixedLengthField(Object obj, ByteOrder order) throws IOException { - int size = getType().getFixedSize(); + int size = getType().getFixedSize(_columnLength); // create buffer for data ByteBuffer buffer = getPageChannel().createBuffer(size, order); @@ -1132,6 +1138,19 @@ public class Column implements Comparable { case MONEY: writeCurrencyValue(buffer, obj); break; + case TEXT: + // apparently text numeric values are also occasionally written as fixed + // length... + CharSequence text = toCharSequence(obj); + int numChars = getLengthInUnits(); + if (text.length() != numChars) { + throw new IOException( + "Text is invalid for fixed length column, length " + numChars + + ", got " + text.length()); + } + // force uncompressed encoding for fixed length text + buffer.put(encodeUncompressedText(text, getFormat())); + break; case GUID: writeGUIDValue(buffer, obj, order); break; @@ -1538,6 +1557,11 @@ public class Column implements Comparable { * Returns the flags used when writing this column. */ public abstract int getColumnFlags(); + + /** + * Returns the type of values generated by this generator. + */ + public abstract DataType getType(); } private final class LongAutoNumberGenerator extends AutoNumberGenerator @@ -1560,6 +1584,11 @@ public class Column implements Comparable { public int getColumnFlags() { return AUTO_NUMBER_FLAG_MASK; } + + @Override + public DataType getType() { + return DataType.LONG; + } } private final class GuidAutoNumberGenerator extends AutoNumberGenerator @@ -1584,6 +1613,11 @@ public class Column implements Comparable { public int getColumnFlags() { return AUTO_NUMBER_GUID_FLAG_MASK; } + + @Override + public DataType getType() { + return DataType.GUID; + } } } diff --git a/src/java/com/healthmarketscience/jackcess/DataType.java b/src/java/com/healthmarketscience/jackcess/DataType.java index 0537103..0f5b27a 100644 --- a/src/java/com/healthmarketscience/jackcess/DataType.java +++ b/src/java/com/healthmarketscience/jackcess/DataType.java @@ -287,12 +287,23 @@ public enum DataType { public boolean getHasScalePrecision() { return _hasScalePrecision; } - + public int getFixedSize() { + return getFixedSize(null); + } + + public int getFixedSize(Short colLength) { if(_fixedSize != null) { + if(colLength != null) { + return Math.max(_fixedSize, colLength); + } return _fixedSize; } - throw new IllegalArgumentException("FIX ME"); + if(colLength != null) { + return colLength; + } + throw new IllegalArgumentException("Unexpected fixed length column " + + this); } public int getMinSize() { diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java index a358406..f17fd30 100644 --- a/src/java/com/healthmarketscience/jackcess/Table.java +++ b/src/java/com/healthmarketscience/jackcess/Table.java @@ -486,7 +486,7 @@ public class Table // read fixed length value (non-boolean at this point) int dataStart = rowStart + 2; colDataPos = dataStart + column.getFixedDataOffset(); - colDataLen = column.getType().getFixedSize(); + colDataLen = column.getType().getFixedSize(column.getLength()); } else { @@ -882,8 +882,7 @@ public class Table buffer.putShort((short) 0); } else { buffer.putShort(fixedOffset); - fixedOffset += Math.max(col.getType().getFixedSize(), - col.getLength()); + fixedOffset += col.getType().getFixedSize(col.getLength()); } if(!col.getType().isLongValue()) { buffer.putShort(col.getLength()); //Column length diff --git a/test/data/fixedTextTest.mdb b/test/data/fixedTextTest.mdb new file mode 100755 index 0000000000000000000000000000000000000000..87de103cc4e044072a205fe7db1940cf808ef93f GIT binary patch literal 135168 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 row = t.getNextRow(); + assertEquals("N", row.get("c_flag_")); + + t.addRow(3, "testFixedText", "boo", "foo", "bob", 3, 5, 9, "Y", + new Date()); + + t.getNextRow(); + row = t.getNextRow(); + assertEquals("testFixedText", row.get("c_user_login")); + assertEquals("Y", row.get("c_flag_")); + + db.close(); + } static Object[] createTestRow(String col1Val) { return new Object[] {col1Val, "R", "McCune", 1234, (byte) 0xad, 555.66d, -- 2.39.5