From c190f7216c07da257eebad77d587ee7a21654899 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Tue, 17 Nov 2009 03:39:11 +0000 Subject: 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 ++++ .../com/healthmarketscience/jackcess/Column.java | 36 ++++++++++++++++++++- .../com/healthmarketscience/jackcess/DataType.java | 15 +++++++-- .../com/healthmarketscience/jackcess/Table.java | 5 ++- test/data/fixedTextTest.mdb | Bin 0 -> 135168 bytes .../healthmarketscience/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 0000000..87de103 Binary files /dev/null and b/test/data/fixedTextTest.mdb differ diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index cb42a90..46432e4 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -1000,6 +1000,30 @@ public class DatabaseTest extends TestCase { db.close(); } + + public void testFixedText() throws Exception + { + Database db = openCopy(new File("test/data/fixedTextTest.mdb")); + + Table t = db.getTable("users"); + Column c = t.getColumn("c_flag_"); + assertEquals(DataType.TEXT, c.getType()); + assertEquals(false, c.isVariableLength()); + assertEquals(2, c.getLength()); + + Map 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, -- cgit v1.2.3