summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2008-10-23 03:06:34 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2008-10-23 03:06:34 +0000
commit130789d1f0a997288c13a6df763a453641545cc9 (patch)
tree82ded4c613d78316b04c79d0d110e4ba49807477
parent30b338ad938fcbce23cf951a00326d9cfa9d2b9d (diff)
downloadjackcess-130789d1f0a997288c13a6df763a453641545cc9.tar.gz
jackcess-130789d1f0a997288c13a6df763a453641545cc9.zip
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
-rw-r--r--src/changes/changes.xml3
-rw-r--r--src/java/com/healthmarketscience/jackcess/Column.java7
-rw-r--r--src/java/com/healthmarketscience/jackcess/DataType.java11
-rw-r--r--src/java/com/healthmarketscience/jackcess/Database.java41
-rw-r--r--test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java15
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 @@
<action dev="jahlborn" type="add">
Add RowFilter contributed by Patricia Donaldson.
</action>
+ <action dev="jahlborn" type="update">
+ Add Database.getSystemTable method for accessing system tables.
+ </action>
</release>
<release version="1.1.17" date="2008-09-23">
<action dev="jahlborn" type="fix" issue="2043499">
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<Column> {
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<Column> {
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
* <code>"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"</code>. 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<Integer, DataType> SQL_TYPES = new HashMap<Integer, DataType>();
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());
@@ -575,6 +569,37 @@ public class Database
}
/**
+ * Returns a reference to <i>any</i> available table in this access
+ * database, including system tables.
+ * <p>
+ * 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<String,Object> 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,