Source Code Cross Referenced for DeleteCascadeResultSet.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » execute » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.sql.execute 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.execute.DeleteCascadeResultSet
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:        import org.apache.derby.iapi.sql.execute.ConstantAction;
027:        import org.apache.derby.iapi.sql.execute.CursorResultSet;
028:        import org.apache.derby.iapi.sql.execute.RowChanger;
029:        import org.apache.derby.iapi.sql.execute.NoPutResultSet;
030:        import org.apache.derby.iapi.sql.Activation;
031:        import org.apache.derby.iapi.sql.ResultDescription;
032:        import org.apache.derby.iapi.types.DataValueDescriptor;
033:        import org.apache.derby.iapi.sql.ResultSet;
034:        import org.apache.derby.iapi.store.access.ConglomerateController;
035:        import org.apache.derby.iapi.store.access.TransactionController;
036:        import org.apache.derby.iapi.sql.execute.ExecRow;
037:        import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
038:
039:        import org.apache.derby.iapi.reference.SQLState;
040:
041:        import java.util.Vector;
042:        import java.util.Hashtable;
043:        import java.util.Enumeration;
044:
045:        /**
046:         * Delete the rows from the specified  base table and executes delete/update
047:         * on dependent tables depending on the referential actions specified.
048:         * Note:(beetle:5197) Dependent Resultsets of DeleteCascade Resultset can  in
049:         * any one of the multiple resultsets generated for the same table because of
050:         * multiple foreign key relationship to  the same table. At the bind time ,
051:         * dependents are binded only once per table.
052:         * We can not depend on mainNodeTable Flag to fire actions on dependents,
053:         * it should be done based on whether the resultset has dependent resultsets or not.
054:         *
055:         */
056:        public class DeleteCascadeResultSet extends DeleteResultSet {
057:
058:            public ResultSet[] dependentResultSets;
059:            private int noDependents = 0;
060:            private CursorResultSet parentSource;
061:            private FKInfo parentFKInfo;
062:            private long fkIndexConglomNumber;
063:            private String resultSetId;
064:            private boolean mainNodeForTable = true;
065:            private boolean affectedRows = false;
066:            private int tempRowHolderId; //this result sets temporary row holder id 
067:
068:            /*
069:             * class interface
070:             * @exception StandardException		Thrown on error
071:             */
072:            public DeleteCascadeResultSet(NoPutResultSet source,
073:                    Activation activation, int constantActionItem,
074:                    ResultSet[] dependentResultSets, String resultSetId)
075:                    throws StandardException {
076:
077:                super (source, ((constantActionItem == -1) ? activation
078:                        .getConstantAction() : (ConstantAction) activation
079:                        .getPreparedStatement().getSavedObject(
080:                                constantActionItem)), activation);
081:
082:                ConstantAction passedInConstantAction;
083:                if (constantActionItem == -1)
084:                    passedInConstantAction = activation.getConstantAction(); //root table
085:                else {
086:                    passedInConstantAction = (ConstantAction) activation
087:                            .getPreparedStatement().getSavedObject(
088:                                    constantActionItem);
089:                    resultDescription = constants.resultDescription;
090:                }
091:                cascadeDelete = true;
092:                this .resultSetId = resultSetId;
093:
094:                if (dependentResultSets != null) {
095:                    noDependents = dependentResultSets.length;
096:                    this .dependentResultSets = dependentResultSets;
097:                }
098:
099:            }
100:
101:            /**
102:            	@exception StandardException Standard Cloudscape error policy
103:             */
104:            public void open() throws StandardException {
105:
106:                try {
107:                    setup();
108:                    if (isMultipleDeletePathsExist()) {
109:                        setRowHoldersTypeToUniqueStream();
110:                        //collect until there are no more rows to found
111:                        while (collectAffectedRows(false))
112:                            ;
113:                    } else {
114:                        collectAffectedRows(false);
115:                    }
116:                    if (!affectedRows) {
117:                        activation.addWarning(StandardException
118:                                .newWarning(SQLState.LANG_NO_ROW_FOUND));
119:                    }
120:
121:                    runFkChecker(true); //check for only RESTRICT referential action rule violations
122:                    Hashtable mntHashTable = new Hashtable(); //Hash Table to identify  mutiple node for same table cases. 
123:                    mergeRowHolders(mntHashTable);
124:                    fireBeforeTriggers(mntHashTable);
125:                    deleteDeferredRows();
126:                    runFkChecker(false); //check for all constraint violations
127:                    rowChangerFinish();
128:                    fireAfterTriggers();
129:                    cleanUp();
130:                } finally {
131:                    //clear the parent result sets hash table
132:                    activation.clearParentResultSets();
133:                }
134:
135:                endTime = getCurrentTimeMillis();
136:
137:            }
138:
139:            /**
140:             *Gathers the rows that needs to be deleted/updated 
141:             *and creates a temporary resulsets that will be passed
142:             *as source to its  dependent result sets.
143:             */
144:            void setup() throws StandardException {
145:
146:                /* Cache query plan text for source, before it gets blown away */
147:                if (lcc.getRunTimeStatisticsMode()) {
148:                    /* savedSource nulled after run time statistics generation */
149:                    savedSource = source;
150:                }
151:
152:                super .setup();
153:                activation.setParentResultSet(rowHolder, resultSetId);
154:                Vector sVector = (Vector) activation
155:                        .getParentResultSet(resultSetId);
156:                tempRowHolderId = sVector.size() - 1;
157:                for (int i = 0; i < noDependents; i++) {
158:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
159:                        ((UpdateResultSet) dependentResultSets[i]).setup();
160:                    } else {
161:                        ((DeleteCascadeResultSet) dependentResultSets[i])
162:                                .setup();
163:                    }
164:                }
165:
166:            }
167:
168:            boolean collectAffectedRows(boolean rowsFound)
169:                    throws StandardException {
170:                if (super .collectAffectedRows()) {
171:                    affectedRows = true;
172:                    rowsFound = true;
173:                }
174:
175:                for (int i = 0; i < noDependents; i++) {
176:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
177:                        if (((UpdateResultSet) dependentResultSets[i])
178:                                .collectAffectedRows())
179:                            rowsFound = true;
180:                    } else {
181:                        if (((DeleteCascadeResultSet) dependentResultSets[i])
182:                                .collectAffectedRows(rowsFound))
183:                            rowsFound = true;
184:                    }
185:                }
186:
187:                return rowsFound;
188:            }
189:
190:            void fireBeforeTriggers(Hashtable msht) throws StandardException {
191:                if (!mainNodeForTable) {
192:                    /*to handle case where no table node had qualified rows, in which case no node for
193:                     * the table get marked as mainNodeFor table , one way to identify
194:                     * such case is to look at the mutinode hash table and see if the result id exist ,
195:                     *if it does not means none of the table nodes resulsets got marked
196:                     * as main node for table. If that is the case we mark this
197:                     * resultset as mainNodeTable and put entry in the hash table.
198:                     */
199:                    if (!msht.containsKey(resultSetId)) {
200:                        mainNodeForTable = true;
201:                        msht.put(resultSetId, resultSetId);
202:                    }
203:                }
204:
205:                //execute the before triggers on the dependents
206:                //Defect 5743: Before enabling BEFORE triggers, check DB2 behavior.
207:                for (int i = 0; i < noDependents; i++) {
208:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
209:                        ((UpdateResultSet) dependentResultSets[i])
210:                                .fireBeforeTriggers();
211:                    } else {
212:                        ((DeleteCascadeResultSet) dependentResultSets[i])
213:                                .fireBeforeTriggers(msht);
214:                    }
215:                }
216:
217:                //If there is more than one node for the same table
218:                //only one node fires the triggers
219:                if (mainNodeForTable && constants.deferred)
220:                    super .fireBeforeTriggers();
221:            }
222:
223:            void fireAfterTriggers() throws StandardException {
224:                //fire the After Triggers on the dependent tables, if any rows changed
225:                for (int i = 0; i < noDependents && affectedRows; i++) {
226:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
227:                        ((UpdateResultSet) dependentResultSets[i])
228:                                .fireAfterTriggers();
229:                    } else {
230:
231:                        ((DeleteCascadeResultSet) dependentResultSets[i])
232:                                .fireAfterTriggers();
233:                    }
234:                }
235:
236:                //If there is more than one node for the same table
237:                //, we let only one node fire the triggers.
238:                if (mainNodeForTable && constants.deferred)
239:                    super .fireAfterTriggers();
240:            }
241:
242:            void deleteDeferredRows() throws StandardException {
243:
244:                //delete the rows in the  dependents tables
245:                for (int i = 0; i < noDependents; i++) {
246:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
247:                        ((UpdateResultSet) dependentResultSets[i])
248:                                .updateDeferredRows();
249:                    } else {
250:                        ((DeleteCascadeResultSet) dependentResultSets[i])
251:                                .deleteDeferredRows();
252:                    }
253:                }
254:
255:                //If there is more than one node for the same table
256:                //only one node deletes all the rows.
257:                if (mainNodeForTable)
258:                    super .deleteDeferredRows();
259:            }
260:
261:            void runFkChecker(boolean restrictCheckOnly)
262:                    throws StandardException {
263:
264:                //run the Foreign key or primary key Checker on the dependent tables
265:                for (int i = 0; i < noDependents; i++) {
266:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
267:                        ((UpdateResultSet) dependentResultSets[i])
268:                                .runChecker(restrictCheckOnly);
269:                    } else {
270:                        ((DeleteCascadeResultSet) dependentResultSets[i])
271:                                .runFkChecker(restrictCheckOnly);
272:                    }
273:                }
274:
275:                //If there  is more than one node for the same table
276:                //only one node does all foreign key checks.
277:                if (mainNodeForTable)
278:                    super .runFkChecker(restrictCheckOnly);
279:            }
280:
281:            public void cleanUp() throws StandardException {
282:
283:                super .cleanUp();
284:                for (int i = 0; i < noDependents; i++) {
285:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
286:                        ((UpdateResultSet) dependentResultSets[i]).cleanUp();
287:                    } else {
288:                        ((DeleteCascadeResultSet) dependentResultSets[i])
289:                                .cleanUp();
290:                    }
291:                }
292:
293:                endTime = getCurrentTimeMillis();
294:            }
295:
296:            private void rowChangerFinish() throws StandardException {
297:
298:                rc.finish();
299:                for (int i = 0; i < noDependents; i++) {
300:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
301:                        ((UpdateResultSet) dependentResultSets[i])
302:                                .rowChangerFinish();
303:                    } else {
304:                        ((DeleteCascadeResultSet) dependentResultSets[i])
305:                                .rowChangerFinish();
306:                    }
307:                }
308:            }
309:
310:            //if there is more than one node for the same table, copy the rows
311:            // into one node , so that we don't fire trigger more than once.
312:            private void mergeRowHolders(Hashtable msht)
313:                    throws StandardException {
314:                if (msht.containsKey(resultSetId) || rowCount == 0) {
315:                    //there is already another resultset node that is marked as main
316:                    //node for this table or this resultset has no rows qualified.
317:                    //when none of the  resultset nodes for the table has any rows then
318:                    //we mark them as one them as main node in fireBeforeTriggers().
319:                    mainNodeForTable = false;
320:                } else {
321:                    mergeResultSets();
322:                    mainNodeForTable = true;
323:                    msht.put(resultSetId, resultSetId);
324:                }
325:
326:                for (int i = 0; i < noDependents; i++) {
327:                    if (dependentResultSets[i] instanceof  UpdateResultSet) {
328:                        return;
329:                    } else {
330:                        ((DeleteCascadeResultSet) dependentResultSets[i])
331:                                .mergeRowHolders(msht);
332:                    }
333:                }
334:            }
335:
336:            private void mergeResultSets() throws StandardException {
337:                Vector sVector = (Vector) activation
338:                        .getParentResultSet(resultSetId);
339:                int size = sVector.size();
340:                // if there is more than one source, we need to merge them into onc
341:                // temporary result set.
342:                if (size > 1) {
343:                    ExecRow row = null;
344:                    int rowHolderId = 0;
345:                    //copy all the vallues in the result set to the current resultset row holder
346:                    while (rowHolderId < size) {
347:                        if (rowHolderId == tempRowHolderId) {
348:                            //skipping the row holder that  we are copying the rows into.
349:                            rowHolderId++;
350:                            continue;
351:                        }
352:                        TemporaryRowHolder currentRowHolder = (TemporaryRowHolder) sVector
353:                                .elementAt(rowHolderId);
354:                        CursorResultSet rs = currentRowHolder.getResultSet();
355:                        rs.open();
356:                        while ((row = rs.getNextRow()) != null) {
357:                            rowHolder.insert(row);
358:                        }
359:                        rs.close();
360:                        rowHolderId++;
361:                    }
362:
363:                }
364:            }
365:
366:            public void finish() throws StandardException {
367:                super .finish();
368:
369:                //clear the parent result sets hash table
370:                //This is necessary in case if we hit any error conditions
371:                activation.clearParentResultSets();
372:            }
373:
374:            /* check whether we have mutiple path delete scenario, if
375:             ** find any retun true.	Multiple delete paths exist if we find more than
376:             ** one parent source resultset for a table involved in the delete cascade
377:             **/
378:            private boolean isMultipleDeletePathsExist() {
379:                Hashtable parentResultSets = activation.getParentResultSets();
380:                for (Enumeration e = parentResultSets.keys(); e
381:                        .hasMoreElements();) {
382:                    String rsId = (String) e.nextElement();
383:                    Vector sVector = (Vector) activation
384:                            .getParentResultSet(rsId);
385:                    int size = sVector.size();
386:                    if (size > 1) {
387:                        return true;
388:                    }
389:                }
390:                return false;
391:            }
392:
393:            /*
394:             **Incases where we have multiple paths we could get the same
395:             **rows to be deleted  mutiple time and also in case of cycles
396:             **there might be new rows getting added to the row holders through
397:             **multiple iterations. To handle these case we set the temporary row holders
398:             ** to be  'uniqStream' type.
399:             **/
400:            private void setRowHoldersTypeToUniqueStream() {
401:                Hashtable parentResultSets = activation.getParentResultSets();
402:                for (Enumeration e = parentResultSets.keys(); e
403:                        .hasMoreElements();) {
404:                    String rsId = (String) e.nextElement();
405:                    Vector sVector = (Vector) activation
406:                            .getParentResultSet(rsId);
407:                    int size = sVector.size();
408:                    int rowHolderId = 0;
409:                    while (rowHolderId < size) {
410:                        TemporaryRowHolder currentRowHolder = (TemporaryRowHolder) sVector
411:                                .elementAt(rowHolderId);
412:                        currentRowHolder.setRowHolderTypeToUniqueStream();
413:                        rowHolderId++;
414:                    }
415:                }
416:            }
417:
418:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.