Browse Source

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
tags/jackcess-1.2.13
James Ahlborn 11 years ago
parent
commit
99f648a340

+ 3
- 0
src/changes/changes.xml View 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">

+ 102
- 22
src/java/com/healthmarketscience/jackcess/Database.java View 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);

+ 52
- 8
test/src/java/com/healthmarketscience/jackcess/RelationshipTest.java View 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);

Loading…
Cancel
Save