001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.constraint;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.constant.ErrorCode;
011: import org.h2.engine.Session;
012: import org.h2.expression.Expression;
013: import org.h2.index.Index;
014: import org.h2.message.Message;
015: import org.h2.result.LocalResult;
016: import org.h2.result.Row;
017: import org.h2.schema.Schema;
018: import org.h2.table.Column;
019: import org.h2.table.Table;
020: import org.h2.table.TableFilter;
021: import org.h2.util.StringUtils;
022:
023: /**
024: * A check constraint.
025: */
026: public class ConstraintCheck extends Constraint {
027:
028: private TableFilter filter;
029: private Expression expr;
030:
031: public ConstraintCheck(Schema schema, int id, String name,
032: Table table) {
033: super (schema, id, name, table);
034: }
035:
036: public String getConstraintType() {
037: return Constraint.CHECK;
038: }
039:
040: public void setTableFilter(TableFilter filter) {
041: this .filter = filter;
042: }
043:
044: public void setExpression(Expression expr) {
045: this .expr = expr;
046: }
047:
048: public String getCreateSQLForCopy(Table table, String quotedName) {
049: StringBuffer buff = new StringBuffer();
050: buff.append("ALTER TABLE ");
051: buff.append(table.getSQL());
052: buff.append(" ADD CONSTRAINT ");
053: buff.append(quotedName);
054: if (comment != null) {
055: buff.append(" COMMENT ");
056: buff.append(StringUtils.quoteStringSQL(comment));
057: }
058: buff.append(" CHECK");
059: buff.append(StringUtils.enclose(expr.getSQL()));
060: buff.append(" NOCHECK");
061: return buff.toString();
062: }
063:
064: public String getShortDescription() {
065: StringBuffer buff = new StringBuffer();
066: buff.append(getName());
067: buff.append(": ");
068: buff.append(expr.getSQL());
069: return buff.toString();
070: }
071:
072: public String getCreateSQLWithoutIndexes() {
073: return getCreateSQL();
074: }
075:
076: public String getCreateSQL() {
077: return getCreateSQLForCopy(table, getSQL());
078: }
079:
080: public void removeChildrenAndResources(Session session)
081: throws SQLException {
082: table.removeConstraint(this );
083: database.removeMeta(session, getId());
084: filter = null;
085: expr = null;
086: table = null;
087: invalidate();
088: }
089:
090: public void checkRow(Session session, Table t, Row oldRow,
091: Row newRow) throws SQLException {
092: if (newRow == null) {
093: return;
094: }
095: filter.set(newRow);
096: // Both TRUE and NULL are ok
097: if (Boolean.FALSE.equals(expr.getValue(session).getBoolean())) {
098: throw Message.getSQLException(
099: ErrorCode.CHECK_CONSTRAINT_VIOLATED_1,
100: getShortDescription());
101: }
102: }
103:
104: public boolean usesIndex(Index index) {
105: return false;
106: }
107:
108: public void setIndexOwner(Index index) {
109: throw Message.getInternalError();
110: }
111:
112: public boolean containsColumn(Column col) {
113: // TODO check constraints / containsColumn: this is cheating, maybe the
114: // column is not referenced
115: String s = col.getSQL();
116: String sql = getCreateSQL();
117: return sql.indexOf(s) >= 0;
118: }
119:
120: public Expression getExpression() {
121: return expr;
122: }
123:
124: public boolean isBefore() {
125: return true;
126: }
127:
128: public void checkExistingData(Session session) throws SQLException {
129: if (session.getDatabase().isStarting()) {
130: // don't check at startup
131: return;
132: }
133: StringBuffer buff = new StringBuffer();
134: buff.append("SELECT 1 FROM ");
135: buff.append(filter.getTable().getSQL());
136: buff.append(" WHERE NOT(");
137: buff.append(expr.getSQL());
138: buff.append(")");
139: String sql = buff.toString();
140: LocalResult r = session.prepare(sql).query(1);
141: if (r.next()) {
142: throw Message.getSQLException(
143: ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, getName());
144: }
145: }
146:
147: }
|