⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constraint.java

📁 hsqldb是100%java实现的数据库,是一个开放源代码的JAVA数据库 l 具有标准的SQL语法和JAVA接口 l HSQLDB可以自由使用和分发 l 非常简洁和快速的
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     *  Returns true if an index is part this constraint and the constraint is set for
     *  a unique constraint. Used for tests before dropping an index.
     */
    boolean isIndexUnique(Index index) {
        return (constType == UNIQUE && core.mainIndex == index);
    }

    /**
     * Only for check constraints
     */
    boolean hasColumn(Table table, String colname) {

        if (constType != CHECK) {
            return false;
        }

        Expression.Collector coll = new Expression.Collector();

        coll.addAll(core.check, Expression.COLUMN);

        Iterator it = coll.iterator();

        for (; it.hasNext(); ) {
            Expression e = (Expression) it.next();

            if (e.getColumnName().equals(colname)
                    && table.tableName.name.equals(e.getTableName())) {
                return true;
            }
        }

        return false;
    }

    boolean hasColumn(int colIndex) {

        if (constType == MAIN) {
            return ArrayUtil.find(core.mainColArray, colIndex) != -1;
        } else if (constType == FOREIGN_KEY) {
            return ArrayUtil.find(core.refColArray, colIndex) != -1;
        }

        return false;
    }

// fredt@users 20020225 - patch 1.7.0 by fredt - duplicate constraints

    /**
     * Compares this with another constraint column set. This implementation
     * only checks UNIQUE constraints.
     */
    boolean isEquivalent(int[] col, int type) {

        if (type != constType || constType != UNIQUE
                || core.colLen != col.length) {
            return false;
        }

        return ArrayUtil.haveEqualSets(core.mainColArray, col, core.colLen);
    }

    /**
     * Compares this with another constraint column set. This implementation
     * only checks FOREIGN KEY constraints.
     */
    boolean isEquivalent(Table tablemain, int[] colmain, Table tableref,
                         int[] colref) {

        if (constType != Constraint.MAIN
                && constType != Constraint.FOREIGN_KEY) {
            return false;
        }

        if (tablemain != core.mainTable || tableref != core.refTable) {
            return false;
        }

        return ArrayUtil.areEqualSets(core.mainColArray, colmain)
               && ArrayUtil.areEqualSets(core.refColArray, colref);
    }

    /**
     *  Used to update constrains to reflect structural changes in a table.
     *  Prior checks must ensure that this method does not throw.
     *
     * @param  oldt reference to the old version of the table
     * @param  newt referenct to the new version of the table
     * @param  colindex index at which table column is added or removed
     * @param  adjust -1, 0, +1 to indicate if column is added or removed
     * @throws  HsqlException
     */
    void replaceTable(Table oldt, Table newt, int colindex,
                      int adjust) throws HsqlException {

        if (oldt == core.mainTable) {
            core.mainTable = newt;

            // exclude CHECK
            if (core.mainIndex != null) {
                core.mainIndex =
                    core.mainTable.getIndex(core.mainIndex.getName().name);
                core.mainColArray =
                    ArrayUtil.toAdjustedColumnArray(core.mainColArray,
                                                    colindex, adjust);
            }
        }

        if (oldt == core.refTable) {
            core.refTable = newt;

            if (core.refIndex != null) {
                core.refIndex =
                    core.refTable.getIndex(core.refIndex.getName().name);

                if (core.refIndex != core.mainIndex) {
                    core.refColArray =
                        ArrayUtil.toAdjustedColumnArray(core.refColArray,
                                                        colindex, adjust);
                }
            }
        }
    }

    /**
     * Checks for foreign key or check constraint violation when
     * inserting a row into the child table.
     */
    void checkInsert(Session session, Object[] row) throws HsqlException {

        if (constType == Constraint.MAIN || constType == Constraint.UNIQUE
                || constType == Constraint.PRIMARY_KEY) {

            // inserts in the main table are never a problem
            // unique constraints are checked by the unique index
            return;
        }

        if (constType == Constraint.CHECK) {
            checkCheckConstraint(session, row);

            return;
        }

        if (Index.isNull(row, core.refColArray)) {
            return;
        }

        // a record must exist in the main table
        boolean exists = core.mainIndex.exists(session, row,
                                               core.refColArray);

        if (!exists) {

            // special case: self referencing table and self referencing row
            if (core.mainTable == core.refTable) {
                boolean match = true;

                for (int i = 0; i < core.colLen; i++) {
                    if (!row[core.refColArray[i]].equals(
                            row[core.mainColArray[i]])) {
                        match = false;

                        break;
                    }
                }

                if (match) {
                    return;
                }
            }

            throw Trace.error(Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT,
                              Trace.Constraint_violation, new Object[] {
                core.fkName.name, core.mainTable.getName().name
            });
        }
    }

    /*
     * Tests a row against this CHECK constraint.
     */
    void checkCheckConstraint(Session session,
                              Object[] row) throws HsqlException {

        core.checkFilter.currentData = row;

        boolean nomatch = Boolean.FALSE.equals(core.check.test(session));

        core.checkFilter.currentData = null;

        if (nomatch) {
            throw Trace.error(Trace.CHECK_CONSTRAINT_VIOLATION,
                              Trace.Constraint_violation, new Object[] {
                constName.name, core.mainTable.tableName.name
            });
        }
    }

// fredt@users 20020225 - patch 1.7.0 - cascading deletes

    /**
     * New method to find any referencing row for a
     * foreign key (finds row in child table). If ON DELETE CASCADE is
     * supported by this constraint, then the method finds the first row
     * among the rows of the table ordered by the index and doesn't throw.
     * Without ON DELETE CASCADE, the method attempts to finds any row that
     * exists, in which case it throws an exception. If no row is found,
     * null is returned.
     * (fredt@users)
     *
     * @param  row array of objects for a database row
     * @param  forDelete should we allow 'ON DELETE CASCADE' or 'ON UPDATE CASCADE'
     * @return Node object or null
     * @throws  HsqlException
     */
    RowIterator findFkRef(Session session, Object[] row,
                          boolean delete) throws HsqlException {

        if (row == null || Index.isNull(row, core.mainColArray)) {
            return core.refIndex.emptyIterator();
        }

        return delete
               ? core.refIndex.findFirstRowForDelete(session, row,
                   core.mainColArray)
               : core.refIndex.findFirstRow(session, row, core.mainColArray);
    }

    /**
     * For the candidate table row, finds any referring node in the main table.
     * This is used to check referential integrity when updating a node. We
     * have to make sure that the main table still holds a valid main record.
     * If a valid row is found the corresponding <code>Node</code> is returned.
     * Otherwise a 'INTEGRITY VIOLATION' Exception gets thrown.
     */
    boolean hasMainRef(Session session, Object[] row) throws HsqlException {

        if (Index.isNull(row, core.refColArray)) {
            return false;
        }

        boolean exists = core.mainIndex.exists(session, row,
                                               core.refColArray);

        // -- there has to be a valid node in the main table
        // --
        if (!exists) {
            throw Trace.error(Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT,
                              Trace.Constraint_violation, new Object[] {
                core.fkName.name, core.refTable.getName().name
            });
        }

        return exists;
    }

    /**
     * Test used before adding a new foreign key constraint. This method
     * returns true if the given row has a corresponding row in the main
     * table. Also returns true if any column covered by the foreign key
     * constraint has a null value.
     */
    private static boolean hasReferencedRow(Session session,
            Object[] rowdata, int[] rowColArray,
            Index mainIndex) throws HsqlException {

        if (Index.isNull(rowdata, rowColArray)) {
            return true;
        }

        // else a record must exist in the main index
        return mainIndex.exists(session, rowdata, rowColArray);
    }

    /**
     * Check used before creating a new foreign key cosntraint, this method
     * checks all rows of a table to ensure they all have a corresponding
     * row in the main table.
     */
    static void checkReferencedRows(Session session, Table table,
                                    int[] rowColArray,
                                    Index mainIndex) throws HsqlException {

        RowIterator it = table.getPrimaryIndex().firstRow(session);

        while (true) {
            Row row = it.next();

            if (row == null) {
                break;
            }

            Object[] rowdata = row.getData();

            if (!Constraint.hasReferencedRow(session, rowdata, rowColArray,
                                             mainIndex)) {
                String colvalues = "";

                for (int i = 0; i < rowColArray.length; i++) {
                    Object o = rowdata[rowColArray[i]];

                    colvalues += o;
                    colvalues += ",";
                }

                throw Trace.error(
                    Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT,
                    Trace.Constraint_violation, new Object[] {
                    colvalues, table.getName().name
                });
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -