blob: 9fb0ac08dfb5eae9bb93bf6955e498a0a7af387b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.empire.db;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.UnexpectedReturnValueException;
/**
* This class creates a DBReferene object for a foreing key relation.
*
*
*/
public class DBRelation extends DBObject
{
// *Deprecated* private static final long serialVersionUID = 1L;
/**
* DBCascadeAction enum
* <pre>
* This enum specifies options for a relation when deleting records
* (see DBRelation.setOnDeleteAction)
*
* - NONE: No Action is performed and the operation will fail if depending records exist.
*
* - CASCADE: Delete (or update) any depending records. This action will be performed by the database and thus
* the option "ON DELETE CASCADE" is added to the DDL generated for the relation.
*
* - CASCADE_RECORDS: This option allows to handle the cascade in code. All depending records will be selected
* by the framework and for each record DBRowSet.deleteRecord() will be called.
* The option "ON DELETE CASCADE" will NOT be added to the DDL generated for the relation.
*
* </pre>
*/
public static enum DBCascadeAction
{
NONE,
CASCADE,
CASCADE_RECORDS
}
public static class DBReference // *Deprecated* implements Serializable
{
// *Deprecated* private static final long serialVersionUID = 1L;
private DBTableColumn sourceColumn;
private DBTableColumn targetColumn;
public DBReference(DBTableColumn sourceColumn, DBTableColumn targetColumn)
{
this.sourceColumn = sourceColumn;
this.targetColumn = targetColumn;
}
public DBTableColumn getSourceColumn()
{
return sourceColumn;
}
public DBTableColumn getTargetColumn()
{
return targetColumn;
}
}
// Members
private DBDatabase db;
private String name;
private DBReference[] references;
private DBCascadeAction onDeleteAction;
/**
* Creates a DBRelation object for a foreing key relation.
*
* @param db the database object
* @param name the name
* @param references the references for this relation
* @param onDeleteAction specifies the action performed when deleting affected records.
*/
public DBRelation(DBDatabase db, String name, DBReference[] references, DBCascadeAction onDeleteAction)
{
this.db = db;
this.name = name;
this.references = references;
this.onDeleteAction = onDeleteAction;
}
/**
* Creates a DBRelation object for a foreing key relation.
*
* @param db the database object
* @param name the name
* @param references the references for this relation
*/
public DBRelation(DBDatabase db, String name, DBReference[] references)
{
this(db, name, references, DBCascadeAction.NONE);
}
/**
* Returns the name.
*
* @return Returns the name
*/
public String getName()
{
return name;
}
/**
* Returns the full qualified table name.
*
* @return the full qualified table name
*/
public String getFullName()
{
String schema = db.getSchema();
return (schema!=null) ? schema+"."+name : name;
}
/**
* Returns the references.
*
* @return the references
*/
public DBReference[] getReferences()
{
return references;
}
/**
* Returns the table that is containing the foreign key (source table)
* @return true if the relation's source table is the given table
*/
public DBTable getForeignKeyTable()
{
return (DBTable)references[0].getSourceColumn().getRowSet();
}
/**
* Returns the table that is referenced by this foreign key relation (target table)
* @return true if the relation's target table
*/
public DBTable getReferencedTable()
{
return (DBTable)references[0].getTargetColumn().getRowSet();
}
@SuppressWarnings("unchecked")
@Override
public final DBDatabase getDatabase()
{
return db;
}
/**
* return the action to perform when deleting affected records.
* See DBCascadeAction enum for details.
*
* @return the action to perform when deleting affected records
*/
public DBCascadeAction getOnDeleteAction()
{
return onDeleteAction;
}
/**
* sets the action taken when deleting records that affect this foreign key relation
* See DBCascadeAction enum for details.
*
* @param onDeleteAction the action to perform when deleting affected records
*/
public void setOnDeleteAction(DBCascadeAction onDeleteAction)
{
this.onDeleteAction = onDeleteAction;
}
/**
* short for
* <pre>
* setOnDeleteAction(DBCascadeAction.CASCADE);
* </pre>
* See DBCascadeAction enum for details.
*/
public void onDeleteCascade()
{
setOnDeleteAction(DBCascadeAction.CASCADE);
}
/**
* short for
* <pre>
* setOnDeleteAction(DBCascadeAction.CASCADE);
* </pre>
* See DBCascadeAction enum for details.
*/
public void onDeleteCascadeRecords()
{
setOnDeleteAction(DBCascadeAction.CASCADE_RECORDS);
}
/**
* Appends the required DLL command to enable or disable a foreign key constraint to the supplied DBDQLScript.
* @param enable true if the constraint should be enabled or false to disable the constraint
* @param context the context for which to enable or disable the relation
*/
public String getEnableDisableStmt(boolean enable, DBContext context)
{
if (context==null)
throw new InvalidArgumentException("context", context);
// get Statement
DBSQLScript script = new DBSQLScript(context);
context.getDbms().appendEnableRelationStmt(this, enable, script);
if (script.getCount()!=1)
throw new UnexpectedReturnValueException(script.getCount(), "dbms.addEnableRelationStatement");
return script.getStmt(0);
}
@Override
public String toString()
{
StringBuilder b = new StringBuilder();
b.append("\"");
b.append(this.getForeignKeyTable().getName());
b.append("\" CONSTRAINT \"");
b.append(this.name);
b.append("\" FOREIGN KEY (");
for (int i=0; i<references.length; i++)
{
b.append((i>0) ? ", \"" : "\"");
b.append(references[i].getSourceColumn().getName());
b.append("\"");
}
b.append(") REFERENCES \"");
b.append(this.getReferencedTable().getName());
b.append("\" (");
for (int i=0; i<references.length; i++)
{
b.append((i>0) ? ", \"" : "\"");
b.append(references[i].getTargetColumn().getName());
b.append("\"");
}
b.append(")");
return b.toString();
}
}