/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.constraint;
import java.util.HashSet;
import org.h2.command.Parser;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.Table;
import org.h2.util.New;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
/**
* A unique constraint. This object always backed by a unique index.
*/
public class ConstraintUnique extends Constraint {
private Index index;
private boolean indexOwner;
private IndexColumn[] columns;
private boolean primaryKey;
public ConstraintUnique(Schema schema, int id, String name, Table table, boolean primaryKey) {
super(schema, id, name, table);
this.primaryKey = primaryKey;
}
public String getConstraintType() {
return primaryKey ? Constraint.PRIMARY_KEY : Constraint.UNIQUE;
}
public String getCreateSQLForCopy(Table forTable, String quotedName) {
return getCreateSQLForCopy(forTable, quotedName, true);
}
private String getCreateSQLForCopy(Table forTable, String quotedName, boolean internalIndex) {
StatementBuilder buff = new StatementBuilder("ALTER TABLE ");
buff.append(forTable.getSQL()).append(" ADD CONSTRAINT ");
if (forTable.isHidden()) {
buff.append("IF NOT EXISTS ");
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
}
buff.append(' ').append(getTypeName()).append('(');
for (IndexColumn c : columns) {
buff.appendExceptFirst(", ");
buff.append(Parser.quoteIdentifier(c.column.getName()));
}
buff.append(')');
if (internalIndex && indexOwner && forTable == this.table) {
buff.append(" INDEX ").append(index.getSQL());
}
return buff.toString();
}
private String getTypeName() {
if (primaryKey) {
return "PRIMARY KEY";
}
return "UNIQUE";
}
public String getCreateSQLWithoutIndexes() {
return getCreateSQLForCopy(table, getSQL(), false);
}
public String getCreateSQL() {
return getCreateSQLForCopy(table, getSQL());
}
public void setColumns(IndexColumn[] columns) {
this.columns = columns;
}
public IndexColumn[] getColumns() {
return columns;
}
/**
* Set the index to use for this unique constraint.
*
* @param index the index
* @param isOwner true if the index is generated by the system and belongs
* to this constraint
*/
public void setIndex(Index index, boolean isOwner) {
this.index = index;
this.indexOwner = isOwner;
}
public void removeChildrenAndResources(Session session) {
table.removeConstraint(this);
if (indexOwner) {
table.removeIndexOrTransferOwnership(session, index);
}
database.removeMeta(session, getId());
index = null;
columns = null;
table = null;
invalidate();
}
public void checkRow(Session session, Table t, Row oldRow, Row newRow) {
// unique index check is enough
}
public boolean usesIndex(Index idx) {
return idx == index;
}
public void setIndexOwner(Index index) {
indexOwner = true;
}
public HashSet<Column> getReferencedColumns(Table table) {
HashSet<Column> result = New.hashSet();
for (IndexColumn c : columns) {
result.add(c.column);
}
return result;
}
public boolean isBefore() {
return true;
}
public void checkExistingData(Session session) {
// no need to check: when creating the unique index any problems are found
}
public Index getUniqueIndex() {
return index;
}
public void rebuild() {
// nothing to do
}
}