From: James Ahlborn
Date: Fri, 31 May 2013 03:49:51 +0000 (+0000)
Subject: add more methods to Database for retrieving Relationships
X-Git-Tag: jackcess-1.2.13~6
X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=99f648a340dd45967550a511f8a27a16c2c5b5f3;p=jackcess.git
add more methods to Database for retrieving Relationships
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@732 f203690c-595d-4dc9-a70b-905162fa7fd2
---
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 260f266..c5b9575 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -9,6 +9,9 @@
Fix partial page updates when using CodecHandlers which can only do
full page encoding.
+
+ Add more methods to Database for retrieving Relationships.
+
diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java
index 2867587..3a720b2 100644
--- a/src/java/com/healthmarketscience/jackcess/Database.java
+++ b/src/java/com/healthmarketscience/jackcess/Database.java
@@ -1524,14 +1524,6 @@ public class Database
public List getRelationships(Table table1, Table table2)
throws IOException
{
- // the relationships table does not get loaded until first accessed
- if(_relationships == null) {
- _relationships = getSystemTable(TABLE_SYSTEM_RELATIONSHIPS);
- if(_relationships == null) {
- throw new IOException("Could not find system relationships table");
- }
- }
-
int nameCmp = table1.getName().compareTo(table2.getName());
if(nameCmp == 0) {
throw new IllegalArgumentException("Must provide two different tables");
@@ -1544,15 +1536,79 @@ public class Database
table1 = table2;
table2 = tmp;
}
+
+ return getRelationshipsImpl(table1, table2, true);
+ }
+ /**
+ * Finds all the relationships in the database for the given table.
+ * @usage _intermediate_method_
+ */
+ public List getRelationships(Table table)
+ throws IOException
+ {
+ if(table == null) {
+ throw new IllegalArgumentException("Must provide a table");
+ }
+ // since we are getting relationships specific to certain table include
+ // all tables
+ return getRelationshipsImpl(table, null, true);
+ }
+
+ /**
+ * Finds all the relationships in the database in non-system tables.
+ *
+ * Warning, this may load all the Tables (metadata, not data) in the
+ * database which could cause memory issues.
+ * @usage _intermediate_method_
+ */
+ public List getRelationships()
+ throws IOException
+ {
+ return getRelationshipsImpl(null, null, false);
+ }
+
+ /**
+ * Finds all the relationships in the database, including system
+ * tables.
+ *
+ * Warning, this may load all the Tables (metadata, not data) in the
+ * database which could cause memory issues.
+ * @usage _intermediate_method_
+ */
+ public List getSystemRelationships()
+ throws IOException
+ {
+ return getRelationshipsImpl(null, null, true);
+ }
+
+ private List getRelationshipsImpl(Table table1, Table table2,
+ boolean includeSystemTables)
+ throws IOException
+ {
+ // the relationships table does not get loaded until first accessed
+ if(_relationships == null) {
+ _relationships = getSystemTable(TABLE_SYSTEM_RELATIONSHIPS);
+ if(_relationships == null) {
+ throw new IOException("Could not find system relationships table");
+ }
+ }
List relationships = new ArrayList();
- Cursor cursor = createCursorWithOptionalIndex(
- _relationships, REL_COL_FROM_TABLE, table1.getName());
- collectRelationships(cursor, table1, table2, relationships);
- cursor = createCursorWithOptionalIndex(
- _relationships, REL_COL_TO_TABLE, table1.getName());
- collectRelationships(cursor, table2, table1, relationships);
+
+ if(table1 != null) {
+ Cursor cursor = createCursorWithOptionalIndex(
+ _relationships, REL_COL_FROM_TABLE, table1.getName());
+ collectRelationships(cursor, table1, table2, relationships,
+ includeSystemTables);
+ cursor = createCursorWithOptionalIndex(
+ _relationships, REL_COL_TO_TABLE, table1.getName());
+ collectRelationships(cursor, table2, table1, relationships,
+ includeSystemTables);
+ } else {
+ collectRelationships(new CursorBuilder(_relationships).toCursor(),
+ null, null, relationships, includeSystemTables);
+ }
return relationships;
}
@@ -1760,17 +1816,22 @@ public class Database
* Finds the relationships matching the given from and to tables from the
* given cursor and adds them to the given list.
*/
- private static void collectRelationships(
+ private void collectRelationships(
Cursor cursor, Table fromTable, Table toTable,
- List relationships)
+ List relationships, boolean includeSystemTables)
+ throws IOException
{
+ String fromTableName = ((fromTable != null) ? fromTable.getName() : null);
+ String toTableName = ((toTable != null) ? toTable.getName() : null);
+
for(Map row : cursor) {
String fromName = (String)row.get(REL_COL_FROM_TABLE);
String toName = (String)row.get(REL_COL_TO_TABLE);
- if(fromTable.getName().equalsIgnoreCase(fromName) &&
- toTable.getName().equalsIgnoreCase(toName))
- {
+ if(((fromTableName == null) ||
+ fromTableName.equalsIgnoreCase(fromName)) &&
+ ((toTableName == null) ||
+ toTableName.equalsIgnoreCase(toName))) {
String relName = (String)row.get(REL_COL_NAME);
@@ -1784,20 +1845,39 @@ public class Database
}
}
+ Table relFromTable = fromTable;
+ if(relFromTable == null) {
+ relFromTable = getTable(fromName, includeSystemTables,
+ defaultUseBigIndex());
+ if(relFromTable == null) {
+ // invalid table or ignoring system tables, just ignore
+ continue;
+ }
+ }
+ Table relToTable = toTable;
+ if(relToTable == null) {
+ relToTable = getTable(toName, includeSystemTables,
+ defaultUseBigIndex());
+ if(relToTable == null) {
+ // invalid table or ignoring system tables, just ignore
+ continue;
+ }
+ }
+
if(rel == null) {
// new relationship
int numCols = (Integer)row.get(REL_COL_COLUMN_COUNT);
int flags = (Integer)row.get(REL_COL_FLAGS);
- rel = new Relationship(relName, fromTable, toTable,
+ rel = new Relationship(relName, relFromTable, relToTable,
flags, numCols);
relationships.add(rel);
}
// add column info
int colIdx = (Integer)row.get(REL_COL_COLUMN_INDEX);
- Column fromCol = fromTable.getColumn(
+ Column fromCol = relFromTable.getColumn(
(String)row.get(REL_COL_FROM_COLUMN));
- Column toCol = toTable.getColumn(
+ Column toCol = relToTable.getColumn(
(String)row.get(REL_COL_TO_COLUMN));
rel.getFromColumns().set(colIdx, fromCol);
diff --git a/test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java b/test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java
index 4f3175f..e49b9bb 100644
--- a/test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java
+++ b/test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java
@@ -27,24 +27,32 @@ King of Prussia, PA 19406
package com.healthmarketscience.jackcess;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
-import junit.framework.TestCase;
-
import static com.healthmarketscience.jackcess.DatabaseTest.*;
import static com.healthmarketscience.jackcess.JetFormatTest.*;
+import junit.framework.TestCase;
/**
* @author James Ahlborn
*/
public class RelationshipTest extends TestCase {
+ private static final Comparator REL_COMP = new Comparator() {
+ public int compare(Relationship r1, Relationship r2) {
+ return String.CASE_INSENSITIVE_ORDER.compare(r1.getName(), r2.getName());
+ }
+ };
+
public RelationshipTest(String name) throws Exception {
super(name);
}
- public void testSimple() throws Exception {
+ public void testTwoTables() throws Exception {
for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX, true)) {
Database db = open(testDB);
Table t1 = db.getTable("Table1");
@@ -64,11 +72,11 @@ public class RelationshipTest extends TestCase {
assertTrue(rel.hasReferentialIntegrity());
assertEquals(4096, rel.getFlags());
assertTrue(rel.cascadeDeletes());
- assertSameRelationships(rels, db.getRelationships(t2, t1));
+ assertSameRelationships(rels, db.getRelationships(t2, t1), true);
rels = db.getRelationships(t2, t3);
assertTrue(db.getRelationships(t2, t3).isEmpty());
- assertSameRelationships(rels, db.getRelationships(t3, t2));
+ assertSameRelationships(rels, db.getRelationships(t3, t2), true);
rels = db.getRelationships(t1, t3);
assertEquals(1, rels.size());
@@ -83,7 +91,7 @@ public class RelationshipTest extends TestCase {
assertTrue(rel.hasReferentialIntegrity());
assertEquals(256, rel.getFlags());
assertTrue(rel.cascadeUpdates());
- assertSameRelationships(rels, db.getRelationships(t3, t1));
+ assertSameRelationships(rels, db.getRelationships(t3, t1), true);
try {
db.getRelationships(t1, t1);
@@ -94,10 +102,46 @@ public class RelationshipTest extends TestCase {
}
}
- private void assertSameRelationships(
- List expected, List found)
+ public void testOneTable() 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");
+
+ List expected = new ArrayList();
+ expected.addAll(db.getRelationships(t1, t2));
+ expected.addAll(db.getRelationships(t2, t3));
+
+ assertSameRelationships(expected, db.getRelationships(t2), false);
+
+ }
+ }
+
+ public void testNoTables() 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");
+
+ List expected = new ArrayList();
+ expected.addAll(db.getRelationships(t1, t2));
+ expected.addAll(db.getRelationships(t2, t3));
+ expected.addAll(db.getRelationships(t1, t3));
+
+ assertSameRelationships(expected, db.getRelationships(), false);
+ }
+ }
+
+ private static void assertSameRelationships(
+ List expected, List found, boolean ordered)
{
assertEquals(expected.size(), found.size());
+ if(!ordered) {
+ Collections.sort(expected, REL_COMP);
+ Collections.sort(found, REL_COMP);
+ }
for(int i = 0; i < expected.size(); ++i) {
Relationship eRel = expected.get(i);
Relationship fRel = found.get(i);