]> source.dussan.org Git - jackcess.git/commitdiff
support reading/writing fixed length text columns (fixe #2886370)
authorJames Ahlborn <jtahlborn@yahoo.com>
Tue, 17 Nov 2009 03:39:11 +0000 (03:39 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Tue, 17 Nov 2009 03:39:11 +0000 (03:39 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@411 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/java/com/healthmarketscience/jackcess/Column.java
src/java/com/healthmarketscience/jackcess/DataType.java
src/java/com/healthmarketscience/jackcess/Table.java
test/data/fixedTextTest.mdb [new file with mode: 0755]
test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java

index 2be53cf0c210b44e40d6f3354bcb332e1b70f23d..f22ad4e3d7f97fc17f52b6c1d0d5788520200ecb 100644 (file)
@@ -9,6 +9,12 @@
         Add support for updating GUID indexes and for auto-number GUID
         fields.
       </action>
+      <action dev="jahlborn" type="update" issue="2802845">
+        Add support for updating rows in a table.
+      </action>
+      <action dev="jahlborn" type="fix" issue="2886370">
+        Support reading/writing fixed length text fields.
+      </action>
     </release>
     <release version="1.1.19" date="2009-06-13">
       <action dev="jahlborn" type="add">
index a41b450324be62690f3339c321daedb5f7eff80b..85ebde048ae1e622c06e427a11902c3ea87fa8d2 100644 (file)
@@ -345,6 +345,12 @@ public class Column implements Comparable<Column> {
       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<Column> {
   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<Column> {
     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<Column> {
      * 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<Column> {
     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<Column> {
     public int getColumnFlags() {
       return AUTO_NUMBER_GUID_FLAG_MASK;
     }
+
+    @Override
+    public DataType getType() {
+      return DataType.GUID;
+    }
   }
 
 }
index 0537103c8bca5c80a88165963d6d9ae73c773185..0f5b27afc1f34b8f71c040d0bb2594ad24f5c8e5 100644 (file)
@@ -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() {
index a358406460a92a34b76d5fa097d8fd6059cb1d91..f17fd301d397c00f36307316054c31900ef1baaf 100644 (file)
@@ -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 (executable)
index 0000000..87de103
Binary files /dev/null and b/test/data/fixedTextTest.mdb differ
index cb42a901205d4b223294f9a9e60a89d06e88cc7d..46432e4f9ab13424bd62e09f284af83ca39a0302 100644 (file)
@@ -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<String,Object> 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,