package net.sourceforge.mayfly.evaluation.command;
import net.sourceforge.mayfly.MayflyException;
import net.sourceforge.mayfly.datastore.Columns;
import net.sourceforge.mayfly.datastore.DataStore;
import net.sourceforge.mayfly.datastore.TableData;
import net.sourceforge.mayfly.datastore.TableReference;
import net.sourceforge.mayfly.datastore.constraint.Action;
import net.sourceforge.mayfly.datastore.constraint.Constraint;
import net.sourceforge.mayfly.datastore.constraint.ForeignKey;
import net.sourceforge.mayfly.parser.Location;
public class UnresolvedForeignKey extends UnresolvedConstraint {
private final String referencingColumn;
private final UnresolvedTableReference targetTable;
private final String targetColumn;
private final Action onDelete;
private final Action onUpdate;
private String constraintName;
private final Location location;
public UnresolvedForeignKey(String referencingColumn,
UnresolvedTableReference targetTable, String targetColumn,
Action onDelete, Action onUpdate, String constraintName,
Location location) {
this.referencingColumn = referencingColumn;
this.targetTable = targetTable;
this.targetColumn = targetColumn;
this.onDelete = onDelete;
this.onUpdate = onUpdate;
this.constraintName = constraintName;
this.location = location;
}
@Override
public Constraint resolve(ConstraintsBuilder builder) {
if (this.constraintName == null) {
this.constraintName = builder.assignForeignKeyName();
}
if (builder.columns != null) {
builder.columns.columnFromName(referencingColumn, location);
}
return resolve(builder.store, builder.schema, builder.table);
}
@Override
public Constraint resolve(DataStore store, String schema, String table,
Columns columns) {
columns.columnFromName(referencingColumn, location);
return resolve(store, schema, table);
}
@Override
public Constraint resolve(DataStore store, String schema, String table) {
TableReference resolvedTargetTable =
targetTable.resolve(store, schema, table);
if (resolvedTargetTable.tableName().equalsIgnoreCase(table)) {
// self-reference case. For now, don't worry about primary
// keys.
}
else {
TableData targetTableData = store.table(resolvedTargetTable);
if (!targetTableData.canBeTargetOfForeignKey(targetColumn)) {
throw new MayflyException("foreign key refers to " +
resolvedTargetTable.displayName(schema) +
"(" + targetColumn + ")" +
" which is not unique or a primary key",
location
);
}
}
return new ForeignKey(
schema,
table,
referencingColumn,
resolvedTargetTable,
targetColumn,
onDelete,
onUpdate,
constraintName
);
}
}