001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.RISetChecker
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025: import org.apache.derby.iapi.error.StandardException;
026:
027: import org.apache.derby.iapi.sql.execute.ExecRow;
028: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
029: import org.apache.derby.iapi.store.access.TransactionController;
030:
031: /**
032: * Checks a set or referential integrity constraints. Used
033: * to shield the caller from ReferencedKeyRIChecker and
034: * ForeignKeyRICheckers.
035: */
036: public class RISetChecker {
037: private GenericRIChecker[] checkers;
038:
039: /**
040: * @param tc the xact controller
041: * @param fkInfo the foreign key information
042: *
043: * @exception StandardException Thrown on failure
044: */
045: public RISetChecker(TransactionController tc, FKInfo fkInfo[])
046: throws StandardException {
047: if (fkInfo == null) {
048: return;
049: }
050:
051: checkers = new GenericRIChecker[fkInfo.length];
052:
053: for (int i = 0; i < fkInfo.length; i++) {
054: checkers[i] = (fkInfo[i].type == FKInfo.FOREIGN_KEY) ? (GenericRIChecker) new ForeignKeyRIChecker(
055: tc, fkInfo[i])
056: : (GenericRIChecker) new ReferencedKeyRIChecker(tc,
057: fkInfo[i]);
058: }
059: }
060:
061: /**
062: * Do any work needed to reopen our ri checkers
063: * for another round of checks. Must do a close()
064: * first.
065: *
066: * @exception StandardException on error
067: */
068: void reopen() throws StandardException {
069: // currently a noop
070: }
071:
072: /**
073: * Check that there are no referenced primary keys in
074: * the passed in row. So for each foreign key that
075: * references a primary key constraint, make sure
076: * that there is no row that matches the values in
077: * the passed in row.
078: *
079: * @param row the row to check
080: *
081: * @exception StandardException on unexpected error, or
082: * on a primary/unique key violation
083: */
084: public void doPKCheck(ExecRow row, boolean restrictCheckOnly)
085: throws StandardException {
086: if (checkers == null)
087: return;
088:
089: for (int i = 0; i < checkers.length; i++) {
090: if (checkers[i] instanceof ReferencedKeyRIChecker) {
091: checkers[i].doCheck(row, restrictCheckOnly);
092: }
093: }
094: }
095:
096: /**
097: * Check that everything in the row is ok, i.e.
098: * that there are no foreign keys in the passed
099: * in row that have invalid values.
100: *
101: * @param row the row to check
102: *
103: * @exception StandardException on unexpected error, or
104: * on a primary/unique key violation
105: */
106: public void doFKCheck(ExecRow row) throws StandardException {
107: if (checkers == null)
108: return;
109:
110: for (int i = 0; i < checkers.length; i++) {
111: if (checkers[i] instanceof ForeignKeyRIChecker) {
112: checkers[i].doCheck(row);
113: }
114: }
115: }
116:
117: /**
118: * Execute the specific RI check on the passed in row.
119: *
120: * @param index index into fkInfo
121: * @param row the row to check
122: *
123: * @exception StandardException on unexpected error, or
124: * on a primary/unique key violation
125: */
126: public void doRICheck(int index, ExecRow row,
127: boolean restrictCheckOnly) throws StandardException {
128: if (SanityManager.DEBUG) {
129: if (checkers == null) {
130: SanityManager
131: .THROWASSERT("no checkers, how can i execute checker "
132: + index);
133: }
134:
135: if (index >= checkers.length) {
136: SanityManager.THROWASSERT("there are only "
137: + checkers.length + " checkers, " + index
138: + " is invalid");
139: }
140: }
141:
142: checkers[index].doCheck(row, restrictCheckOnly);
143: }
144:
145: /**
146: * clean up
147: *
148: * @exception StandardException on error
149: */
150: public void close() throws StandardException {
151: if (checkers == null)
152: return;
153:
154: for (int i = 0; i < checkers.length; i++) {
155: checkers[i].close();
156: }
157: }
158: }
|