KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > ForeignKeyRIChecker


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.ForeignKeyRIChecker
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.execute;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25 import org.apache.derby.iapi.error.StandardException;
26
27 import org.apache.derby.iapi.sql.StatementUtil;
28 import org.apache.derby.iapi.sql.execute.ExecRow;
29 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
30 import org.apache.derby.iapi.reference.SQLState;
31 import org.apache.derby.iapi.store.access.ScanController;
32 import org.apache.derby.iapi.store.access.TransactionController;
33
34 /**
35  * A Referential Integrity checker for a foreign
36  * key constraint. It makes sure the foreign key is
37  * intact. This is used for a change to a foreign
38  * key column. see ReferencedKeyRIChecker for the code
39  * that validates changes to referenced keys.
40  */

41 public class ForeignKeyRIChecker extends GenericRIChecker
42 {
43     /**
44      * @param tc the xact controller
45      * @param fkinfo the foreign key information
46      *
47      * @exception StandardException Thrown on failure
48      */

49     ForeignKeyRIChecker(TransactionController tc, FKInfo fkinfo)
50         throws StandardException
51     {
52         super(tc, fkinfo);
53
54         if (SanityManager.DEBUG)
55         {
56             if (fkInfo.type != FKInfo.FOREIGN_KEY)
57             {
58                 SanityManager.THROWASSERT("invalid type "+fkInfo.type+" for a ForeignKeyRIChecker");
59             }
60         }
61     }
62
63     /**
64      * Check that the row either has a null column(s), or
65      * corresponds to a row in the referenced key.
66      * <p>
67      * If the referenced key is found, then it is locked
68      * when this method returns. The lock is held until
69      * the next call to doCheck() or close().
70      *
71      * @param row the row to check
72      *
73      * @exception StandardException on unexped error, or
74      * on a foreign key violation
75      */

76     void doCheck(ExecRow row, boolean restrictCheckOnly) throws StandardException
77     {
78
79         if(restrictCheckOnly) //RESTRICT rule checks are not valid here.
80
return;
81
82         /*
83         ** If any of the columns are null, then the
84         ** check always succeeds.
85         */

86         if (isAnyFieldNull(row))
87         {
88             return;
89         }
90
91         /*
92         ** Otherwise, we had better find this row in the
93         ** referenced key
94         */

95         ScanController scan = getScanController(fkInfo.refConglomNumber, refScoci, refDcoci, row);
96         if (!scan.next())
97         {
98             close();
99             StandardException se = StandardException.newException(SQLState.LANG_FK_VIOLATION, fkInfo.fkConstraintNames[0],
100                                         fkInfo.tableName,
101                                         StatementUtil.typeName(fkInfo.stmtType),
102                                         RowUtil.toString(row, fkInfo.colArray));
103
104             throw se;
105         }
106         
107         /*
108         ** If we found the row, we are currently positioned on
109         ** the row when we leave this method. So we hold the
110         ** lock on the referenced key, which is very important.
111         */

112     }
113
114     /**
115      * Get the isolation level for the scan for
116      * the RI check.
117      *
118      * NOTE: The level will eventually be instantaneous
119      * locking once the implemenation changes.
120      *
121      * @return The isolation level for the scan for
122      * the RI check.
123      */

124     int getRICheckIsolationLevel()
125     {
126         return TransactionController.ISOLATION_READ_COMMITTED;
127     }
128 }
129
Popular Tags