From bb4ce1424cf8e4ef6c62e969e68884a6a0096024 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Mon, 18 Apr 2011 01:52:57 +0000 Subject: [PATCH] add Index.getReferencedIndex for retrieving the referenced index of a foreign key index git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@555 f203690c-595d-4dc9-a70b-905162fa7fd2 --- src/changes/changes.xml | 4 ++ .../jackcess/Database.java | 25 ++++++++++ .../healthmarketscience/jackcess/Index.java | 47 +++++++++++++++++++ .../jackcess/IndexTest.java | 42 +++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 5d97102..17d877c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,10 @@ Access expects a row to be at least big enough to hold all fixed values, even if they are null. + + Add Index.getReferencedIndex for retrieving the referenced Index for a + foreign key index. + diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java index 3691e22..3029881 100644 --- a/src/java/com/healthmarketscience/jackcess/Database.java +++ b/src/java/com/healthmarketscience/jackcess/Database.java @@ -1017,6 +1017,31 @@ public class Database return getTable(name, false, useBigIndex); } + /** + * @param tableDefPageNumber the page number of a table definition + * @return The table, or null if it doesn't exist + */ + protected Table getTable(int tableDefPageNumber) throws IOException { + + // first, check for existing table + Table table = _tableCache.get(tableDefPageNumber); + if(table != null) { + return table; + } + + // lookup table info from system catalog + Map objectRow = _tableFinder.getObjectRow( + tableDefPageNumber, SYSTEM_CATALOG_COLUMNS); + if(objectRow == null) { + return null; + } + + String name = (String)objectRow.get(CAT_COL_NAME); + int flags = (Integer)objectRow.get(CAT_COL_FLAGS); + + return readTable(name, tableDefPageNumber, flags, defaultUseBigIndex()); + } + /** * @param name Table name * @param includeSystemTables whether to consider returning a system table diff --git a/src/java/com/healthmarketscience/jackcess/Index.java b/src/java/com/healthmarketscience/jackcess/Index.java index c9c2bf4..532b4e1 100644 --- a/src/java/com/healthmarketscience/jackcess/Index.java +++ b/src/java/com/healthmarketscience/jackcess/Index.java @@ -164,6 +164,53 @@ public class Index implements Comparable { return _reference; } + /** + * @return the Index referenced by this Index's ForeignKeyReference (if it + * has one), otherwise {@code null}. + */ + public Index getReferencedIndex() throws IOException { + + if(_reference == null) { + return null; + } + + Table refTable = getTable().getDatabase().getTable( + _reference.getOtherTablePageNumber()); + + if(refTable == null) { + throw new IOException("Reference to missing table " + + _reference.getOtherTablePageNumber()); + } + + Index refIndex = null; + int idxNumber = _reference.getOtherIndexNumber(); + for(Index idx : refTable.getIndexes()) { + if(idx.getIndexNumber() == idxNumber) { + refIndex = idx; + break; + } + } + + if(refIndex == null) { + throw new IOException("Reference to missing index " + idxNumber + + " on table " + refTable.getName()); + } + + // finally verify that we found the expected index (should reference this + // index) + ForeignKeyReference otherRef = refIndex.getReference(); + if((otherRef == null) || + (otherRef.getOtherTablePageNumber() != + getTable().getTableDefPageNumber()) || + (otherRef.getOtherIndexNumber() != _indexNumber)) { + throw new IOException("Found unexpected index " + refIndex.getName() + + " on table " + refTable.getName() + + " with reference " + otherRef); + } + + return refIndex; + } + /** * Whether or not {@code null} values are actually recorded in the index. */ diff --git a/test/src/java/com/healthmarketscience/jackcess/IndexTest.java b/test/src/java/com/healthmarketscience/jackcess/IndexTest.java index 1e326c3..3ebfff6 100644 --- a/test/src/java/com/healthmarketscience/jackcess/IndexTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/IndexTest.java @@ -466,6 +466,48 @@ public class IndexTest extends TestCase { } } + public void testGetForeignKeyIndex() throws Exception + { + for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX, true)) { + Database db = open(testDB); + Table t1 = db.getTable("Table1"); + Table t2 = db.getTable("Table2"); + Table t3 = db.getTable("Table3"); + + Index t2t1 = t1.getIndex(IndexTest.getRelationshipName( + db.getFormat(), "Table2Table1")); + Index t3t1 = t1.getIndex(IndexTest.getRelationshipName( + db.getFormat(), "Table3Table1")); + + + assertTrue(t2t1.isForeignKey()); + assertNotNull(t2t1.getReference()); + assertFalse(t2t1.getReference().isPrimaryTable()); + doCheckForeignKeyIndex(t1, t2t1, t2); + + assertTrue(t3t1.isForeignKey()); + assertNotNull(t3t1.getReference()); + assertFalse(t3t1.getReference().isPrimaryTable()); + doCheckForeignKeyIndex(t1, t3t1, t3); + + Index t1pk = t1.getIndex(IndexBuilder.PRIMARY_KEY_NAME); + assertNotNull(t1pk); + assertNull(t1pk.getReference()); + assertNull(t1pk.getReferencedIndex()); + } + } + + private void doCheckForeignKeyIndex(Table ta, Index ia, Table tb) + throws Exception + { + Index ib = ia.getReferencedIndex(); + assertNotNull(ib); + assertSame(tb, ib.getTable()); + + assertNotNull(ib.getReference()); + assertSame(ia, ib.getReferencedIndex()); + } + private void checkIndexColumns(Table table, String... idxInfo) throws Exception { -- 2.39.5