]> source.dussan.org Git - jackcess.git/commitdiff
add more methods to Database for retrieving Relationships
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 31 May 2013 03:49:51 +0000 (03:49 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 31 May 2013 03:49:51 +0000 (03:49 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@732 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/java/com/healthmarketscience/jackcess/Database.java
test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java

index 260f2667cb900474e1a425f8dd88ddcde8670820..c5b95758de5300a54a48edc777a0eb52d1d7e278 100644 (file)
@@ -9,6 +9,9 @@
         Fix partial page updates when using CodecHandlers which can only do
         full page encoding.
       </action>
+      <action dev="jahlborn" type="update">
+        Add more methods to Database for retrieving Relationships.
+      </action>
     </release>
     <release version="1.2.12" date="2013-05-09">
       <action dev="jahlborn" type="fix" system="SourceForge2" issue="94">
index 28675878b61390bbde1602fd431ab187dbbe4ea8..3a720b2652aa01ca370f250c168b57d3c21c1077 100644 (file)
@@ -1524,14 +1524,6 @@ public class Database
   public List<Relationship> 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<Relationship> 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 <i>non-system</i> tables.
+   * </p>
+   * Warning, this may load <i>all</i> the Tables (metadata, not data) in the
+   * database which could cause memory issues.
+   * @usage _intermediate_method_
+   */
+  public List<Relationship> getRelationships()
+    throws IOException
+  {
+    return getRelationshipsImpl(null, null, false);
+  }
+      
+  /**
+   * Finds <i>all</i> the relationships in the database, <i>including system
+   * tables</i>.
+   * </p>
+   * Warning, this may load <i>all</i> the Tables (metadata, not data) in the
+   * database which could cause memory issues.
+   * @usage _intermediate_method_
+   */
+  public List<Relationship> getSystemRelationships()
+    throws IOException
+  {
+    return getRelationshipsImpl(null, null, true);
+  }
+      
+  private List<Relationship> 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<Relationship> relationships = new ArrayList<Relationship>();
-    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<Relationship> relationships)
+      List<Relationship> relationships, boolean includeSystemTables)
+    throws IOException
   {
+    String fromTableName = ((fromTable != null) ? fromTable.getName() : null);
+    String toTableName = ((toTable != null) ? toTable.getName() : null);
+
     for(Map<String,Object> 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);
index 4f3175fd1688230fc603d2c8b91932cfb393b43f..e49b9bb503918c8ea40485eaa00606e73c3d441c 100644 (file)
@@ -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<Relationship> REL_COMP = new Comparator<Relationship>() {
+    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<Relationship> expected, List<Relationship> 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<Relationship> expected = new ArrayList<Relationship>();
+      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<Relationship> expected = new ArrayList<Relationship>();
+      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<Relationship> expected, List<Relationship> 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);