From 130789d1f0a997288c13a6df763a453641545cc9 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Thu, 23 Oct 2008 03:06:34 +0000 Subject: [PATCH] Add Database.getSystemTable method for accessing system tables git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@380 f203690c-595d-4dc9-a70b-905162fa7fd2 --- src/changes/changes.xml | 3 ++ .../healthmarketscience/jackcess/Column.java | 7 +++- .../jackcess/DataType.java | 11 +++-- .../jackcess/Database.java | 41 +++++++++++++++---- .../jackcess/DatabaseTest.java | 15 +++++++ 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 8b9ed1f..d04f725 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -9,6 +9,9 @@ Add RowFilter contributed by Patricia Donaldson. + + Add Database.getSystemTable method for accessing system tables. + diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index 570d104..c27a699 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -430,8 +430,10 @@ public class Column implements Comparable { return readNumericValue(buffer); } else if (_type == DataType.GUID) { return readGUIDValue(buffer); - } else if (_type == DataType.UNKNOWN_0D) { - return null; + } else if ((_type == DataType.UNKNOWN_0D) || + (_type == DataType.UNKNOWN_11)) { + // treat like "binary" data + return data; } else { throw new IOException("Unrecognized data type: " + _type); } @@ -973,6 +975,7 @@ public class Column implements Comparable { break; case BINARY: + case UNKNOWN_0D: // should already be "encoded" break; default: diff --git a/src/java/com/healthmarketscience/jackcess/DataType.java b/src/java/com/healthmarketscience/jackcess/DataType.java index 022b521..bf32c09 100644 --- a/src/java/com/healthmarketscience/jackcess/DataType.java +++ b/src/java/com/healthmarketscience/jackcess/DataType.java @@ -122,9 +122,9 @@ public enum DataType { MEMO((byte) 0x0C, Types.LONGVARCHAR, null, true, true, 0, null, 0xFFFFFF, JetFormat.TEXT_FIELD_UNIT_SIZE), /** - * Unknown data. Accepts {@code null}. + * Unknown data. Handled like BINARY. */ - UNKNOWN_0D((byte) 0x0D), + UNKNOWN_0D((byte) 0x0D, null, null, true, false, 0, 255, 255, 1), /** * Corresponds to a java String with the pattern * "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}". Accepts any @@ -140,7 +140,12 @@ public enum DataType { */ // for some reason numeric is "var len" even though it has a fixed size... NUMERIC((byte) 0x10, Types.NUMERIC, 17, true, false, 17, 17, 17, - true, 0, 0, 28, 1, 18, 28, 1); + true, 0, 0, 28, 1, 18, 28, 1), + /** + * Unknown data (seems to be an alternative OLE type, used by + * MSysAccessObjects table). Handled like a fixed length BINARY/OLE. + */ + UNKNOWN_11((byte) 0x11, null, 3992); /** Map of SQL types to Access data types */ private static Map SQL_TYPES = new HashMap(); diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java index 5eb2c40..df4b0c1 100644 --- a/src/java/com/healthmarketscience/jackcess/Database.java +++ b/src/java/com/healthmarketscience/jackcess/Database.java @@ -237,8 +237,6 @@ public class Database private Table _systemCatalog; /** System access control entries table */ private Table _accessControlEntries; - /** page number of the system relationships table */ - private Integer _relationshipsPageNumber; /** System relationships table (initialized on first use) */ private Table _relationships; /** SIDs to use for the ACEs added for new tables */ @@ -408,8 +406,6 @@ public class Database int pageNumber = (Integer)row.get(CAT_COL_ID); _accessControlEntries = readTable(TABLE_SYSTEM_ACES, pageNumber, defaultUseBigIndex()); - } else if(TABLE_SYSTEM_RELATIONSHIPS.equals(name)) { - _relationshipsPageNumber = (Integer)row.get(CAT_COL_ID); } } else if (SYSTEM_OBJECT_NAME_TABLES.equals(name)) { _tableParentId = (Integer) row.get(CAT_COL_ID); @@ -541,12 +537,10 @@ public class Database { // the relationships table does not get loaded until first accessed if(_relationships == null) { - if(_relationshipsPageNumber == null) { + _relationships = getSystemTable(TABLE_SYSTEM_RELATIONSHIPS); + if(_relationships == null) { throw new IOException("Could not find system relationships table"); } - _relationships = readTable(TABLE_SYSTEM_RELATIONSHIPS, - _relationshipsPageNumber, - defaultUseBigIndex()); } int nameCmp = table1.getName().compareTo(table2.getName()); @@ -574,6 +568,37 @@ public class Database return relationships; } + /** + * Returns a reference to any available table in this access + * database, including system tables. + *

+ * Warning, this method is not designed for common use, only for the + * occassional time when access to a system table is necessary. Messing + * with system tables can strip the paint off your house and give your whole + * family a permanent, orange afro. You have been warned. + * + * @param tableName Table name, may be a system table + * @return The table, or {@code null} if it doesn't exist + */ + public Table getSystemTable(String tableName) + throws IOException + { + for(Map row : + Cursor.createCursor(_systemCatalog).iterable( + SYSTEM_CATALOG_COLUMNS)) + { + String name = (String) row.get(CAT_COL_NAME); + if (tableName.equalsIgnoreCase(name) && + TYPE_TABLE.equals(row.get(CAT_COL_TYPE))) { + Integer pageNumber = (Integer) row.get(CAT_COL_ID); + if(pageNumber != null) { + return readTable(name, pageNumber, defaultUseBigIndex()); + } + } + } + return null; + } + /** * Finds the relationships matching the given from and to tables from the * given cursor and adds them to the given list. diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index 19078ee..136780e 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -896,6 +896,21 @@ public class DatabaseTest extends TestCase { } } } + + public void testSystemTable() throws Exception + { + Database db = create(); + + assertNotNull(db.getSystemTable("MSysAccessObjects")); + assertNotNull(db.getSystemTable("MSysObjects")); + assertNotNull(db.getSystemTable("MSysQueries")); + assertNotNull(db.getSystemTable("MSysACES")); + assertNotNull(db.getSystemTable("MSysRelationships")); + + assertNull(db.getSystemTable("MSysBogus")); + + db.close(); + } static Object[] createTestRow(String col1Val) { return new Object[] {col1Val, "R", "McCune", 1234, (byte) 0xad, 555.66d, -- 2.39.5