From 840ccbde0f0729e976fde4cec1a2fbfe55559b7b Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Tue, 6 May 2014 04:22:46 +0000 Subject: [PATCH] add convenience methods to Row for getting values cast to specific types git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@859 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../com/healthmarketscience/jackcess/Row.java | 71 ++++++++++++++++++ .../jackcess/impl/ComplexColumnSupport.java | 6 +- .../jackcess/impl/DatabaseImpl.java | 74 +++++++++---------- .../jackcess/impl/RowImpl.java | 48 ++++++++++++ .../jackcess/impl/query/QueryImpl.java | 16 ++-- .../jackcess/util/OleBlob.java | 2 +- .../jackcess/BigIndexTest.java | 8 +- .../jackcess/ComplexColumnTest.java | 16 ++-- .../jackcess/CursorTest.java | 26 +++---- .../jackcess/DatabaseTest.java | 30 ++++---- .../jackcess/IndexTest.java | 2 +- .../jackcess/PropertiesTest.java | 6 +- .../jackcess/impl/CodecHandlerTest.java | 11 +-- .../jackcess/impl/FKEnforcerTest.java | 4 +- .../jackcess/impl/IndexCodesTest.java | 21 +++--- .../jackcess/util/JoinerTest.java | 2 +- .../jackcess/util/OleBlobTest.java | 11 ++- 17 files changed, 237 insertions(+), 117 deletions(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/Row.java b/src/main/java/com/healthmarketscience/jackcess/Row.java index 2385e90..da3a4c6 100644 --- a/src/main/java/com/healthmarketscience/jackcess/Row.java +++ b/src/main/java/com/healthmarketscience/jackcess/Row.java @@ -19,7 +19,12 @@ USA package com.healthmarketscience.jackcess; +import java.util.Date; import java.util.Map; +import java.math.BigDecimal; + +import com.healthmarketscience.jackcess.complex.ComplexValueForeignKey; + /** * A row of data as column name->value pairs. Values are strongly typed, and @@ -34,4 +39,70 @@ public interface Row extends Map * @return the id of this row */ public RowId getId(); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a String. + */ + public String getString(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Boolean. + */ + public Boolean getBoolean(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Byte. + */ + public Byte getByte(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Short. + */ + public Short getShort(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Integer. + */ + public Integer getInt(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a BigDecimal. + */ + public BigDecimal getBigDecimal(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Float. + */ + public Float getFloat(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Double. + */ + public Double getDouble(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a Date. + */ + public Date getDate(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a byte[]. + */ + public byte[] getBytes(String name); + + /** + * Convenience method which gets the value for the row with the given name, + * casting it to a ComplexValueForeignKey. + */ + public ComplexValueForeignKey getForeignKey(String name); } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ComplexColumnSupport.java b/src/main/java/com/healthmarketscience/jackcess/impl/ComplexColumnSupport.java index 533e1ef..469a720 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/ComplexColumnSupport.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ComplexColumnSupport.java @@ -79,14 +79,14 @@ public class ComplexColumnSupport complexTypeId); } Row cColRow = cursor.getCurrentRow(); - int tableId = (Integer)cColRow.get(COL_TABLE_ID); + int tableId = cColRow.getInt(COL_TABLE_ID); if(tableId != column.getTable().getTableDefPageNumber()) { throw new IOException( "Found complex column for table " + tableId + " but expected table " + column.getTable().getTableDefPageNumber()); } - int flatTableId = (Integer)cColRow.get(COL_FLAT_TABLE_ID); - int typeObjId = (Integer)cColRow.get(COL_COMPLEX_TYPE_OBJECT_ID); + int flatTableId = cColRow.getInt(COL_FLAT_TABLE_ID); + int typeObjId = cColRow.getInt(COL_COMPLEX_TYPE_OBJECT_ID); TableImpl typeObjTable = db.getTable(typeObjId); TableImpl flatTable = db.getTable(flatTableId); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java index 8ddc4a0..548833b 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java @@ -874,8 +874,8 @@ public class DatabaseImpl implements Database return null; } - String name = (String)objectRow.get(CAT_COL_NAME); - int flags = (Integer)objectRow.get(CAT_COL_FLAGS); + String name = objectRow.getString(CAT_COL_NAME); + int flags = objectRow.getInt(CAT_COL_FLAGS); return readTable(name, tableDefPageNumber, flags); } @@ -1093,10 +1093,10 @@ public class DatabaseImpl implements Database CursorImpl.createCursor(_systemCatalog).newIterable().setColumnNames( SYSTEM_CATALOG_COLUMNS)) { - String name = (String) row.get(CAT_COL_NAME); + String name = row.getString(CAT_COL_NAME); if (name != null && TYPE_QUERY.equals(row.get(CAT_COL_TYPE))) { queryInfo.add(row); - Integer id = (Integer)row.get(CAT_COL_ID); + Integer id = row.getInt(CAT_COL_ID); queryRowMap.put(id, new ArrayList()); } } @@ -1116,9 +1116,9 @@ public class DatabaseImpl implements Database // lastly, generate all the queries List queries = new ArrayList(); for(Row row : queryInfo) { - String name = (String) row.get(CAT_COL_NAME); - Integer id = (Integer)row.get(CAT_COL_ID); - int flags = (Integer)row.get(CAT_COL_FLAGS); + String name = row.getString(CAT_COL_NAME); + Integer id = row.getInt(CAT_COL_ID); + int flags = row.getInt(CAT_COL_FLAGS); List queryRows = queryRowMap.get(id); queries.add(QueryImpl.create(flags, name, queryRows, id)); } @@ -1164,7 +1164,7 @@ public class DatabaseImpl implements Database byte[] propsBytes = null; RowIdImpl rowId = null; if(objectRow != null) { - propsBytes = (byte[])objectRow.get(CAT_COL_PROPS); + propsBytes = objectRow.getBytes(CAT_COL_PROPS); rowId = (RowIdImpl)objectRow.getId(); } return readProperties(propsBytes, objectId, rowId); @@ -1191,8 +1191,8 @@ public class DatabaseImpl implements Database int objectId = -1; RowIdImpl rowId = null; if(objectRow != null) { - propsBytes = (byte[])objectRow.get(CAT_COL_PROPS); - objectId = (Integer)objectRow.get(CAT_COL_ID); + propsBytes = objectRow.getBytes(CAT_COL_PROPS); + objectId = objectRow.getInt(CAT_COL_ID); rowId = (RowIdImpl)objectRow.getId(); } return readProperties(propsBytes, objectId, rowId); @@ -1257,15 +1257,15 @@ public class DatabaseImpl implements Database String toTableName = ((toTable != null) ? toTable.getName() : null); for(Row row : cursor) { - String fromName = (String)row.get(REL_COL_FROM_TABLE); - String toName = (String)row.get(REL_COL_TO_TABLE); + String fromName = row.getString(REL_COL_FROM_TABLE); + String toName = row.getString(REL_COL_TO_TABLE); if(((fromTableName == null) || fromTableName.equalsIgnoreCase(fromName)) && ((toTableName == null) || toTableName.equalsIgnoreCase(toName))) { - String relName = (String)row.get(REL_COL_NAME); + String relName = row.getString(REL_COL_NAME); // found more info for a relationship. see if we already have some // info for this relationship @@ -1296,19 +1296,19 @@ public class DatabaseImpl implements Database if(rel == null) { // new relationship - int numCols = (Integer)row.get(REL_COL_COLUMN_COUNT); - int flags = (Integer)row.get(REL_COL_FLAGS); + int numCols = row.getInt(REL_COL_COLUMN_COUNT); + int flags = row.getInt(REL_COL_FLAGS); rel = new RelationshipImpl(relName, relFromTable, relToTable, flags, numCols); relationships.add(rel); } // add column info - int colIdx = (Integer)row.get(REL_COL_COLUMN_INDEX); + int colIdx = row.getInt(REL_COL_COLUMN_INDEX); ColumnImpl fromCol = relFromTable.getColumn( - (String)row.get(REL_COL_FROM_COLUMN)); + row.getString(REL_COL_FROM_COLUMN)); ColumnImpl toCol = relToTable.getColumn( - (String)row.get(REL_COL_TO_COLUMN)); + row.getString(REL_COL_TO_COLUMN)); rel.getFromColumns().set(colIdx, fromCol); rel.getToColumns().set(colIdx, toCol); @@ -1400,9 +1400,9 @@ public class DatabaseImpl implements Database getAccessControlEntries(), ACE_COL_OBJECT_ID, _tableParentId); for(Row row : cursor) { - Integer objId = (Integer)row.get(ACE_COL_OBJECT_ID); + Integer objId = row.getInt(ACE_COL_OBJECT_ID); if(_tableParentId.equals(objId)) { - _newTableSIDs.add((byte[])row.get(ACE_COL_SID)); + _newTableSIDs.add(row.getBytes(ACE_COL_SID)); } } @@ -1842,10 +1842,10 @@ public class DatabaseImpl implements Database for(Row row : getTableNamesCursor().newIterable().setColumnNames( SYSTEM_CATALOG_TABLE_NAME_COLUMNS)) { - String tableName = (String)row.get(CAT_COL_NAME); - int flags = (Integer)row.get(CAT_COL_FLAGS); - Short type = (Short)row.get(CAT_COL_TYPE); - int parentId = (Integer)row.get(CAT_COL_PARENT_ID); + String tableName = row.getString(CAT_COL_NAME); + int flags = row.getInt(CAT_COL_FLAGS); + Short type = row.getShort(CAT_COL_TYPE); + int parentId = row.getInt(CAT_COL_PARENT_ID); if((parentId == _tableParentId) && isTableType(type) && (isSystemObject(flags) == systemTables)) { @@ -1923,17 +1923,17 @@ public class DatabaseImpl implements Database Row row = _systemCatalogCursor.getCurrentRow( SYSTEM_CATALOG_COLUMNS); - Integer pageNumber = (Integer)row.get(CAT_COL_ID); - String realName = (String)row.get(CAT_COL_NAME); - int flags = (Integer)row.get(CAT_COL_FLAGS); - Short type = (Short)row.get(CAT_COL_TYPE); + Integer pageNumber = row.getInt(CAT_COL_ID); + String realName = row.getString(CAT_COL_NAME); + int flags = row.getInt(CAT_COL_FLAGS); + Short type = row.getShort(CAT_COL_TYPE); if(!isTableType(type)) { return null; } - String linkedDbName = (String)row.get(CAT_COL_DATABASE); - String linkedTableName = (String)row.get(CAT_COL_FOREIGN_NAME); + String linkedDbName = row.getString(CAT_COL_DATABASE); + String linkedTableName = row.getString(CAT_COL_FOREIGN_NAME); return createTableInfo(realName, pageNumber, flags, type, linkedDbName, linkedTableName); @@ -1999,25 +1999,25 @@ public class DatabaseImpl implements Database for(Row row : _systemCatalogCursor.newIterable().setColumnNames( SYSTEM_CATALOG_TABLE_NAME_COLUMNS)) { - Short type = (Short)row.get(CAT_COL_TYPE); + Short type = row.getShort(CAT_COL_TYPE); if(!isTableType(type)) { continue; } - int parentId = (Integer)row.get(CAT_COL_PARENT_ID); + int parentId = row.getInt(CAT_COL_PARENT_ID); if(parentId != _tableParentId) { continue; } - String realName = (String)row.get(CAT_COL_NAME); + String realName = row.getString(CAT_COL_NAME); if(!tableName.equalsIgnoreCase(realName)) { continue; } - Integer pageNumber = (Integer)row.get(CAT_COL_ID); - int flags = (Integer)row.get(CAT_COL_FLAGS); - String linkedDbName = (String)row.get(CAT_COL_DATABASE); - String linkedTableName = (String)row.get(CAT_COL_FOREIGN_NAME); + Integer pageNumber = row.getInt(CAT_COL_ID); + int flags = row.getInt(CAT_COL_FLAGS); + String linkedDbName = row.getString(CAT_COL_DATABASE); + String linkedTableName = row.getString(CAT_COL_FOREIGN_NAME); return createTableInfo(realName, pageNumber, flags, type, linkedDbName, linkedTableName); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/RowImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/RowImpl.java index 2191bf2..34071ad 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/RowImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/RowImpl.java @@ -20,8 +20,12 @@ USA package com.healthmarketscience.jackcess.impl; import java.util.LinkedHashMap; +import java.util.Date; +import java.math.BigDecimal; import com.healthmarketscience.jackcess.Row; +import com.healthmarketscience.jackcess.complex.ComplexValueForeignKey; + /** * A row of data as column->value pairs. @@ -55,6 +59,50 @@ public class RowImpl extends LinkedHashMap implements Row return _id; } + public String getString(String name) { + return (String)get(name); + } + + public Boolean getBoolean(String name) { + return (Boolean)get(name); + } + + public Byte getByte(String name) { + return (Byte)get(name); + } + + public Short getShort(String name) { + return (Short)get(name); + } + + public Integer getInt(String name) { + return (Integer)get(name); + } + + public BigDecimal getBigDecimal(String name) { + return (BigDecimal)get(name); + } + + public Float getFloat(String name) { + return (Float)get(name); + } + + public Double getDouble(String name) { + return (Double)get(name); + } + + public Date getDate(String name) { + return (Date)get(name); + } + + public byte[] getBytes(String name) { + return (byte[])get(name); + } + + public ComplexValueForeignKey getForeignKey(String name) { + return (ComplexValueForeignKey)get(name); + } + @Override public String toString() { return CustomToStringStyle.valueBuilder("Row[" + _id + "]") diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java index 94c8e41..90032eb 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java @@ -582,14 +582,14 @@ public abstract class QueryImpl implements Query public Row(com.healthmarketscience.jackcess.Row tableRow) { this(tableRow.getId(), - (Byte)tableRow.get(COL_ATTRIBUTE), - (String)tableRow.get(COL_EXPRESSION), - (Short)tableRow.get(COL_FLAG), - (Integer)tableRow.get(COL_EXTRA), - (String)tableRow.get(COL_NAME1), - (String)tableRow.get(COL_NAME2), - (Integer)tableRow.get(COL_OBJECTID), - (byte[])tableRow.get(COL_ORDER)); + tableRow.getByte(COL_ATTRIBUTE), + tableRow.getString(COL_EXPRESSION), + tableRow.getShort(COL_FLAG), + tableRow.getInt(COL_EXTRA), + tableRow.getString(COL_NAME1), + tableRow.getString(COL_NAME2), + tableRow.getInt(COL_OBJECTID), + tableRow.getBytes(COL_ORDER)); } public Row(RowId id, Byte attribute, String expression, Short flag, diff --git a/src/main/java/com/healthmarketscience/jackcess/util/OleBlob.java b/src/main/java/com/healthmarketscience/jackcess/util/OleBlob.java index 893eac5..18ae5b7 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/OleBlob.java +++ b/src/main/java/com/healthmarketscience/jackcess/util/OleBlob.java @@ -56,7 +56,7 @@ import com.healthmarketscience.jackcess.impl.OleUtil; *

* Example for interpreting an existing OLE field: *

- *   byte[] oleBytes = (byte[])row.get("MyOleColumn");
+ *   byte[] oleBytes = row.getBytes("MyOleColumn");
  *   OleBlob oleBlob = null;
  *   try {
  *     oleBlob = OleBlob.Builder.fromInternalData(oleBlob);
diff --git a/src/test/java/com/healthmarketscience/jackcess/BigIndexTest.java b/src/test/java/com/healthmarketscience/jackcess/BigIndexTest.java
index 32f228e..0485557 100644
--- a/src/test/java/com/healthmarketscience/jackcess/BigIndexTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/BigIndexTest.java
@@ -125,8 +125,8 @@ public class BigIndexTest extends TestCase {
         String prevValue = firstValue;
         int rowCount = 0;
         List firstTwo = new ArrayList();
-        for(Map row : CursorBuilder.createCursor(index)) {
-          String origVal = (String)row.get("col1");
+        for(Row row : CursorBuilder.createCursor(index)) {
+          String origVal = row.getString("col1");
           String val = origVal;
           if(val == null) {
             val = firstValue;
@@ -162,8 +162,8 @@ public class BigIndexTest extends TestCase {
         index.getIndexData().validate();
 
         List found = new ArrayList();
-        for(Map row : CursorBuilder.createCursor(index)) {
-          found.add((String)row.get("col1"));
+        for(Row row : CursorBuilder.createCursor(index)) {
+          found.add(row.getString("col1"));
         }
 
         assertEquals(firstTwo, found);
diff --git a/src/test/java/com/healthmarketscience/jackcess/ComplexColumnTest.java b/src/test/java/com/healthmarketscience/jackcess/ComplexColumnTest.java
index 8e2ba6d..8aae78c 100644
--- a/src/test/java/com/healthmarketscience/jackcess/ComplexColumnTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/ComplexColumnTest.java
@@ -64,8 +64,8 @@ public class ComplexColumnTest extends TestCase
       assertEquals(ComplexDataType.VERSION_HISTORY,
                    verCol.getComplexInfo().getType());
 
-      for(Map row : t1) {
-        String rowId = (String)row.get("id");
+      for(Row row : t1) {
+        String rowId = row.getString("id");
         ComplexValueForeignKey complexValueFk =
           (ComplexValueForeignKey)verCol.getRowValue(row);
 
@@ -166,8 +166,8 @@ public class ComplexColumnTest extends TestCase
       assertEquals(ComplexDataType.ATTACHMENT,
                    col.getComplexInfo().getType());
 
-      for(Map row : t1) {
-        String rowId = (String)row.get("id");
+      for(Row row : t1) {
+        String rowId = row.getString("id");
         ComplexValueForeignKey complexValueFk =
           (ComplexValueForeignKey)col.getRowValue(row);
 
@@ -251,8 +251,8 @@ public class ComplexColumnTest extends TestCase
       assertEquals(ComplexDataType.MULTI_VALUE,
                    col.getComplexInfo().getType());
 
-      for(Map row : t1) {
-        String rowId = (String)row.get("id");
+      for(Row row : t1) {
+        String rowId = row.getString("id");
         ComplexValueForeignKey complexValueFk =
           (ComplexValueForeignKey)col.getRowValue(row);
 
@@ -322,8 +322,8 @@ public class ComplexColumnTest extends TestCase
       assertEquals(ComplexDataType.UNSUPPORTED,
                    col.getComplexInfo().getType());
 
-      for(Map row : t1) {
-        Integer rowId = (Integer)row.get("ID");
+      for(Row row : t1) {
+        Integer rowId = row.getInt("ID");
         ComplexValueForeignKey complexValueFk =
           (ComplexValueForeignKey)col.getRowValue(row);
 
diff --git a/src/test/java/com/healthmarketscience/jackcess/CursorTest.java b/src/test/java/com/healthmarketscience/jackcess/CursorTest.java
index d10d18b..bafee57 100644
--- a/src/test/java/com/healthmarketscience/jackcess/CursorTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/CursorTest.java
@@ -1102,18 +1102,18 @@ public class CursorTest extends TestCase {
       IndexCursor cursor = CursorBuilder.createCursor(idx);
 
       List expectedData = new ArrayList();
-      for(Map row : cursor.newEntryIterable(1)
+      for(Row row : cursor.newEntryIterable(1)
             .addColumnNames("data")) {
-        expectedData.add((String)row.get("data"));
+        expectedData.add(row.getString("data"));
       }
 
       assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
 
       expectedData = new ArrayList();
-      for(Iterator> iter = 
+      for(Iterator iter = 
             cursor.newEntryIterable(1).iterator();
           iter.hasNext(); ) {
-        expectedData.add((String)iter.next().get("data"));
+        expectedData.add(iter.next().getString("data"));
         iter.remove();
         try {
           iter.remove();
@@ -1135,9 +1135,9 @@ public class CursorTest extends TestCase {
       assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
       
       expectedData = new ArrayList();
-      for(Map row : cursor.newEntryIterable(1)
+      for(Row row : cursor.newEntryIterable(1)
             .addColumnNames("data")) {
-        expectedData.add((String)row.get("data"));
+        expectedData.add(row.getString("data"));
       }
 
       assertTrue(expectedData.isEmpty());
@@ -1155,21 +1155,21 @@ public class CursorTest extends TestCase {
       Cursor cursor = CursorBuilder.createCursor(t1);
 
       List expectedData = new ArrayList();
-      for(Map row : cursor.newIterable().setColumnNames(
+      for(Row row : cursor.newIterable().setColumnNames(
               Arrays.asList("otherfk1", "data"))) {
         if(row.get("otherfk1").equals(1)) {
-          expectedData.add((String)row.get("data"));
+          expectedData.add(row.getString("data"));
         }
       }
 
       assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
 
       expectedData = new ArrayList();
-      for(Iterator> iter = cursor.iterator();
+      for(Iterator iter = cursor.iterator();
           iter.hasNext(); ) {
-        Map row = iter.next();
+        Row row = iter.next();
         if(row.get("otherfk1").equals(1)) {
-          expectedData.add((String)row.get("data"));
+          expectedData.add(row.getString("data"));
           iter.remove();
           try {
             iter.remove();
@@ -1192,10 +1192,10 @@ public class CursorTest extends TestCase {
       assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
       
       expectedData = new ArrayList();
-      for(Map row : cursor.newIterable().setColumnNames(
+      for(Row row : cursor.newIterable().setColumnNames(
               Arrays.asList("otherfk1", "data"))) {
         if(row.get("otherfk1").equals(1)) {
-          expectedData.add((String)row.get("data"));
+          expectedData.add(row.getString("data"));
         }
       }
 
diff --git a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
index 24fe758..ab80183 100644
--- a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
@@ -278,11 +278,11 @@ public class DatabaseTest extends TestCase
       assertEquals(4, db.getTableNames().size());
       final Table table = db.getTable("Table1");
 
-      Map row1 = table.getNextRow();
-      Map row2 = table.getNextRow();
+      Row row1 = table.getNextRow();
+      Row row2 = table.getNextRow();
 
       if(!"abcdefg".equals(row1.get("A"))) {
-        Map tmpRow = row1;
+        Row tmpRow = row1;
         row1 = row2;
         row2 = tmpRow;
       }
@@ -294,7 +294,7 @@ public class DatabaseTest extends TestCase
     }
   }
 
-  static void checkTestDBTable1RowABCDEFG(final TestDB testDB, final Table table, final Map row)
+  static void checkTestDBTable1RowABCDEFG(final TestDB testDB, final Table table, final Row row)
           throws IOException {
     assertEquals("testDB: " + testDB + "; table: " + table, "abcdefg", row.get("A"));
     assertEquals("hijklmnop", row.get("B"));
@@ -303,7 +303,7 @@ public class DatabaseTest extends TestCase
     assertEquals(new Integer(333333333), row.get("E"));
     assertEquals(new Double(444.555d), row.get("F"));
     final Calendar cal = Calendar.getInstance();
-    cal.setTime((Date) row.get("G"));
+    cal.setTime(row.getDate("G"));
     assertEquals(Calendar.SEPTEMBER, cal.get(Calendar.MONTH));
     assertEquals(21, cal.get(Calendar.DAY_OF_MONTH));
     assertEquals(1974, cal.get(Calendar.YEAR));
@@ -314,7 +314,7 @@ public class DatabaseTest extends TestCase
     assertEquals(Boolean.TRUE, row.get("I"));
   }
 
-  static void checkTestDBTable1RowA(final TestDB testDB, final Table table, final Map row)
+  static void checkTestDBTable1RowA(final TestDB testDB, final Table table, final Row row)
           throws IOException {
     assertEquals("testDB: " + testDB + "; table: " + table, "a", row.get("A"));
     assertEquals("b", row.get("B"));
@@ -323,7 +323,7 @@ public class DatabaseTest extends TestCase
     assertEquals(new Integer(0), row.get("E"));
     assertEquals(new Double(0d), row.get("F"));
     final Calendar cal = Calendar.getInstance();
-    cal.setTime((Date) row.get("G"));
+    cal.setTime(row.getDate("G"));
     assertEquals(Calendar.DECEMBER, cal.get(Calendar.MONTH));
     assertEquals(12, cal.get(Calendar.DAY_OF_MONTH));
     assertEquals(1981, cal.get(Calendar.YEAR));
@@ -513,12 +513,12 @@ public class DatabaseTest extends TestCase
     for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.TEST2, true)) {
       Database db = open(testDB);
       Table table = db.getTable("MSP_PROJECTS");
-      Map row = table.getNextRow();
+      Row row = table.getNextRow();
       assertEquals("Jon Iles this is a a vawesrasoih aksdkl fas dlkjflkasjd flkjaslkdjflkajlksj dfl lkasjdf lkjaskldfj lkas dlk lkjsjdfkl; aslkdf lkasjkldjf lka skldf lka sdkjfl;kasjd falksjdfljaslkdjf laskjdfk jalskjd flkj aslkdjflkjkjasljdflkjas jf;lkasjd fjkas dasdf asd fasdf asdf asdmhf lksaiyudfoi jasodfj902384jsdf9 aw90se fisajldkfj lkasj dlkfslkd jflksjadf as", row.get("PROJ_PROP_AUTHOR"));
       assertEquals("T", row.get("PROJ_PROP_COMPANY"));
       assertEquals("Standard", row.get("PROJ_INFO_CAL_NAME"));
       assertEquals("Project1", row.get("PROJ_PROP_TITLE"));
-      byte[] foundBinaryData = (byte[])row.get("RESERVED_BINARY_DATA");
+      byte[] foundBinaryData = row.getBytes("RESERVED_BINARY_DATA");
       byte[] expectedBinaryData =
         toByteArray(new File("src/test/data/test2BinData.dat"));
       assertTrue(Arrays.equals(expectedBinaryData, foundBinaryData));
@@ -549,7 +549,7 @@ public class DatabaseTest extends TestCase
 
       table.reset();
 
-      Map row = table.getNextRow();
+      Row row = table.getNextRow();
 
       assertEquals(testStr, row.get("A"));
       assertEquals(testStr, row.get("B"));
@@ -559,7 +559,7 @@ public class DatabaseTest extends TestCase
 
       assertEquals(testStr, row.get("A"));
       assertEquals(longMemo, row.get("B"));
-      assertTrue(Arrays.equals(oleValue, (byte[])row.get("C")));
+      assertTrue(Arrays.equals(oleValue, row.getBytes("C")));
 
       db.close();
     }    
@@ -937,8 +937,8 @@ public class DatabaseTest extends TestCase
       }
 
       Set ids = new HashSet();
-      for(Map row : t) {
-        ids.add((Integer)row.get("ID"));
+      for(Row row : t) {
+        ids.add(row.getInt("ID"));
       }
       assertEquals(1000, ids.size());
 
@@ -1103,8 +1103,8 @@ public class DatabaseTest extends TestCase
       }
 
       List foundDates = new ArrayList();
-      for(Map row : table) {
-        foundDates.add((Date)row.get("date"));
+      for(Row row : table) {
+        foundDates.add(row.getDate("date"));
       }
 
       assertEquals(dates.size(), foundDates.size());
diff --git a/src/test/java/com/healthmarketscience/jackcess/IndexTest.java b/src/test/java/com/healthmarketscience/jackcess/IndexTest.java
index aad0376..c2d058a 100644
--- a/src/test/java/com/healthmarketscience/jackcess/IndexTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/IndexTest.java
@@ -387,7 +387,7 @@ public class IndexTest extends TestCase {
       Cursor c = CursorBuilder.createCursor(table);
       assertTrue(c.moveToNextRow());
 
-      final Map row = c.getCurrentRow();
+      final Row row = c.getCurrentRow();
       // Row order is arbitrary, so v2007 row order difference is valid
       if (testDB.getExpectedFileFormat().ordinal() >= 
           Database.FileFormat.V2007.ordinal()) {
diff --git a/src/test/java/com/healthmarketscience/jackcess/PropertiesTest.java b/src/test/java/com/healthmarketscience/jackcess/PropertiesTest.java
index aa98ce5..182e637 100644
--- a/src/test/java/com/healthmarketscience/jackcess/PropertiesTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/PropertiesTest.java
@@ -191,9 +191,9 @@ public class PropertiesTest extends TestCase
         assertTrue(((String)dbProps.getValue(PropertyMap.ACCESS_VERSION_PROP))
                    .matches("[0-9]{2}[.][0-9]{2}"));
 
-        for(Map row : ((DatabaseImpl)db).getSystemCatalog()) {
-          int id = (Integer)row.get("Id");
-          byte[] propBytes = (byte[])row.get("LvProp");
+        for(Row row : ((DatabaseImpl)db).getSystemCatalog()) {
+          int id = row.getInt("Id");
+          byte[] propBytes = row.getBytes("LvProp");
           PropertyMaps propMaps = ((DatabaseImpl)db).getPropertiesForObject(id);
           int byteLen = ((propBytes != null) ? propBytes.length : 0);
           if(byteLen == 0) {
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
index 47a832a..e680fd9 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
@@ -45,6 +45,7 @@ import com.healthmarketscience.jackcess.DatabaseBuilder;
 import com.healthmarketscience.jackcess.DatabaseTest;
 import com.healthmarketscience.jackcess.DatabaseTest;
 import com.healthmarketscience.jackcess.IndexBuilder;
+import com.healthmarketscience.jackcess.Row;
 import com.healthmarketscience.jackcess.Table;
 import com.healthmarketscience.jackcess.TableBuilder;
 import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
@@ -134,8 +135,8 @@ public class CodecHandlerTest extends TestCase
       Cursor c2 = t2.newCursor().setIndex(t2.getPrimaryKeyIndex())
         .toCursor();
 
-      Iterator> i1 = c1.iterator();
-      Iterator> i2 = c2.newIterable().reverse().iterator();
+      Iterator i1 = c1.iterator();
+      Iterator i2 = c2.newIterable().reverse().iterator();
 
       int t1rows = 0;
       int t2rows = 0;
@@ -156,10 +157,10 @@ public class CodecHandlerTest extends TestCase
       assertEquals(100, t2rows);
   }
 
-  private static void checkRow(Map row)
+  private static void checkRow(Row row)
   {
-    int id = (Integer)row.get("id");
-    String value = (String)row.get("data");
+    int id = row.getInt("id");
+    String value = row.getString("data");
     String valuePrefix = "rowdata-" + id;
     assertTrue(value.startsWith(valuePrefix));
     assertEquals(valuePrefix.length() + 100, value.length());
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/FKEnforcerTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/FKEnforcerTest.java
index 7ea3123..70c2b94 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/FKEnforcerTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/FKEnforcerTest.java
@@ -107,8 +107,8 @@ public class FKEnforcerTest extends TestCase
 
       Cursor c = CursorBuilder.createCursor(t3);
       Column col = t3.getColumn("id");
-      for(Map row : c) {
-        int id = (Integer)row.get("id");
+      for(Row row : c) {
+        int id = row.getInt("id");
         id += 20;
         c.setCurrentRowValue(col, id);
       }
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/IndexCodesTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/IndexCodesTest.java
index 62565ac..ddee491 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/IndexCodesTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/IndexCodesTest.java
@@ -44,6 +44,7 @@ import com.healthmarketscience.jackcess.DataType;
 import com.healthmarketscience.jackcess.Database;
 import static com.healthmarketscience.jackcess.DatabaseTest.*;
 import com.healthmarketscience.jackcess.Index;
+import com.healthmarketscience.jackcess.Row;
 import com.healthmarketscience.jackcess.Table;
 import com.healthmarketscience.jackcess.TableBuilder;
 import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
@@ -95,7 +96,7 @@ public class IndexCodesTest extends TestCase {
     Cursor cursor = CursorBuilder.createCursor(index);
     while(cursor.moveToNextRow()) {
 
-      Map row = cursor.getCurrentRow();
+      Row row = cursor.getCurrentRow();
       Cursor.Position curPos = cursor.getSavepoint().getCurrentPosition();
       boolean success = false;
       try {
@@ -113,7 +114,7 @@ public class IndexCodesTest extends TestCase {
   }
   
   private static void findRow(final TestDB testDB, Table t, Index index,
-                              Map expectedRow,
+                              Row expectedRow,
                               Cursor.Position expectedPos)
     throws Exception
   {
@@ -124,7 +125,7 @@ public class IndexCodesTest extends TestCase {
     
     cursor.beforeFirst();
     while(cursor.moveToNextRow()) {
-      Map row = cursor.getCurrentRow();
+      Row row = cursor.getCurrentRow();
       if(expectedRow.equals(row)) {
         // verify that the entries are indeed equal
         Cursor.Position curPos = cursor.getSavepoint().getCurrentPosition();
@@ -136,7 +137,7 @@ public class IndexCodesTest extends TestCase {
     // TODO long rows not handled completely yet in V2010
     // seems to truncate entry at 508 bytes with some trailing 2 byte seq
     if(testDB.getExpectedFileFormat() == Database.FileFormat.V2010) {
-      String rowId = (String)expectedRow.get("name");
+      String rowId = expectedRow.getString("name");
       String tName = t.getName();
       if(("Table11".equals(tName) || "Table11_desc".equals(tName)) &&
          ("row10".equals(rowId) || "row11".equals(rowId) || 
@@ -363,9 +364,9 @@ public class IndexCodesTest extends TestCase {
       Cursor.Savepoint savepoint = cursor.getSavepoint();
       String entryStr = entryToString(savepoint.getCurrentPosition());
 
-      Map row = cursor.getCurrentRow();
-      String value = (String)row.get("data");
-      String key = (String)row.get("key");
+      Row row = cursor.getCurrentRow();
+      String value = row.getString("data");
+      String key = row.getString("key");
       char c = value.charAt(2);
 
       System.out.println("=======");
@@ -542,9 +543,9 @@ public class IndexCodesTest extends TestCase {
       Cursor.Savepoint savepoint = cursor.getSavepoint();
       String entryStr = entryToString(savepoint.getCurrentPosition());
 
-      Map row = cursor.getCurrentRow();
-      String value = (String)row.get("data");
-      String key = (String)row.get("key");
+      Row row = cursor.getCurrentRow();
+      String value = row.getString("data");
+      String key = row.getString("key");
       char c = value.charAt(2);
       System.out.println("=======");
       System.out.println("RowId: " +
diff --git a/src/test/java/com/healthmarketscience/jackcess/util/JoinerTest.java b/src/test/java/com/healthmarketscience/jackcess/util/JoinerTest.java
index f6de03b..35feaa0 100644
--- a/src/test/java/com/healthmarketscience/jackcess/util/JoinerTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/util/JoinerTest.java
@@ -93,7 +93,7 @@ public class JoinerTest extends TestCase {
 
     Joiner revJoin = join.createReverse();
     for(Row row : join.getFromTable()) {
-      Integer id = (Integer)row.get("id");
+      Integer id = row.getInt("id");
 
       List joinedRows =
         new ArrayList();
diff --git a/src/test/java/com/healthmarketscience/jackcess/util/OleBlobTest.java b/src/test/java/com/healthmarketscience/jackcess/util/OleBlobTest.java
index b519664..3a1cc05 100644
--- a/src/test/java/com/healthmarketscience/jackcess/util/OleBlobTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/util/OleBlobTest.java
@@ -102,12 +102,12 @@ public class OleBlobTest extends TestCase
       for(Row row : t) {
         try {
           blob = OleBlob.Builder.fromInternalData(
-              (byte[])row.get("ole"));
+              row.getBytes("ole"));
           OleBlob.Content content = blob.getContent();
           assertSame(blob, content.getBlob());
           assertSame(content, blob.getContent());
 
-          switch((Integer)row.get("id")) {
+          switch(row.getInt("id")) {
           case 1:
             assertEquals(OleBlob.ContentType.SIMPLE_PACKAGE, content.getType());
             OleBlob.SimplePackageContent spc = (OleBlob.SimplePackageContent)content;
@@ -170,13 +170,12 @@ public class OleBlobTest extends TestCase
         OleBlob oleBlob = null;
         try {
 
-          String name = (String)row.get("name");
-          oleBlob = OleBlob.Builder.fromInternalData((byte[])row.get("ole_data"));
+          String name = row.getString("name");
+          oleBlob = OleBlob.Builder.fromInternalData(row.getBytes("ole_data"));
           OleBlob.Content content = oleBlob.getContent();
           Attachment attach = null;
           if(content.getType() != OleBlob.ContentType.LINK) {
-            attach = ((ComplexValueForeignKey)row.get("attach_data"))
-              .getAttachments().get(0);
+            attach = row.getForeignKey("attach_data").getAttachments().get(0);
           }
 
           switch(content.getType()) {
-- 
2.39.5