KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > queryframework > DatasourceCallQueryMechanism


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.queryframework;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.helper.*;
26 import oracle.toplink.essentials.internal.databaseaccess.DatasourceCall;
27 import oracle.toplink.essentials.internal.databaseaccess.DatabaseCall;
28 import oracle.toplink.essentials.exceptions.*;
29 import oracle.toplink.essentials.queryframework.*;
30 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
31 import oracle.toplink.essentials.internal.sessions.AbstractSession;
32
33 /**
34  * <p><b>Purpose</b>:
35  * Mechanism used for call queries.
36  * <p>
37  * <p><b>Responsibilities</b>:
38  * Executes the appropriate call.
39  *
40  * @author James Sutherland
41  * @since OracleAS TopLink 10<i>g</i> (10.0.3)
42  */

43 public class DatasourceCallQueryMechanism extends DatabaseQueryMechanism {
44     protected DatasourceCall call;
45
46     /** Normally only a single call is used, however multiple table may require multiple calls on write. */
47     protected Vector calls;
48
49     /**
50      * Initialize the state of the query
51      * @param query - owner of mechanism
52      */

53     public DatasourceCallQueryMechanism(DatabaseQuery query) {
54         super(query);
55     }
56
57     /**
58      * Initialize the state of the query
59      * @param query - owner of mechanism
60      */

61     public DatasourceCallQueryMechanism(DatabaseQuery query, DatasourceCall call) {
62         super(query);
63         this.call = call;
64         call.setQuery(query);
65     }
66
67     /**
68      * Add the call.
69      */

70     public void addCall(DatasourceCall call) {
71         getCalls().addElement(call);
72         call.setQuery(getQuery());
73     }
74
75     /**
76      * Read all rows from the database using a cursored stream.
77      * @exception DatabaseException - an error has occurred on the database
78      */

79     public DatabaseCall cursorSelectAllRows() throws DatabaseException {
80         try {
81             return (DatabaseCall)executeCall();
82         } catch (java.lang.ClassCastException JavaDoc e) {
83             throw QueryException.mustUseCursorStreamPolicy();
84         }
85     }
86
87     /**
88      * INTERNAL:
89      * Delete a collection of objects. Assume call is correct.
90      * @exception DatabaseException - an error has occurred on the database
91      */

92     public Integer JavaDoc deleteAll() throws DatabaseException {
93         if(((DeleteAllQuery)getQuery()).isPreparedUsingTempStorage()) {
94             return deleteAllUsingTempTables();
95         } else {
96             if (hasMultipleCalls()) {
97                 Integer JavaDoc returnedRowCount = null;
98                 
99                 // Deletion must occur in reverse order.
100
for (int index = getCalls().size() - 1; index >= 0; index--) {
101                     DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
102                     returnedRowCount = (Integer JavaDoc)executeCall(databseCall);
103                 }
104                 // returns the number of rows removed from the first table in insert order
105
return returnedRowCount;
106             } else {
107                 return (Integer JavaDoc)executeCall();
108             }
109         }
110     }
111
112     /**
113      * Execute deleteAll using temp tables
114      * @exception DatabaseException - an error has occurred on the database.
115      * @return the row count.
116      */

117     public Integer JavaDoc deleteAllUsingTempTables() throws DatabaseException {
118         DatabaseException ex = null;
119         Integer JavaDoc returnedRowCount = null;
120         
121         // Deletion must occur in reverse order.
122

123         // first call - crete temp table.
124
// may fail in case global temp table already exists.
125
try {
126             DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(getCalls().size() - 1);
127             executeCall(databseCall);
128         } catch (DatabaseException databaseEx) {
129             // ignore
130
}
131
132         // second call - populate temp table.
133
// if that fails save the exception and untill cleanup
134
if(ex == null) {
135             try {
136                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(getCalls().size() - 2);
137                 executeCall(databseCall);
138             } catch (DatabaseException databaseEx) {
139                 ex = databaseEx;
140             }
141         }
142         
143         // third (a call per table) - delete from original tables calls.
144
// if that fails save the exception untill cleanup
145
for (int index = getCalls().size() - 3; index >= 1 && ex == null; index--) {
146             DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
147             try {
148                 // returns the number of rows removed from the first table in insert order
149
returnedRowCount = (Integer JavaDoc)executeCall(databseCall);
150             } catch (DatabaseException databaseEx) {
151                 ex = databaseEx;
152             }
153         }
154
155         // last call - cleanup temp table.
156
// ignore exceptions here.
157
try {
158             DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(0);
159             executeCall(databseCall);
160         } catch (DatabaseException databaseEx) {
161             // ignore
162
}
163
164         if(ex != null) {
165             throw ex;
166         }
167         
168         return returnedRowCount;
169     }
170
171     /**
172      * INTERNAL:
173      * Delete an object. Assume call is correct
174      * @exception DatabaseException - an error has occurred on the database
175      */

176     public Integer JavaDoc deleteObject() throws DatabaseException {
177         if (hasMultipleCalls()) {
178             Integer JavaDoc returnedRowCount = null;
179
180             // Deletion must occur in reverse order.
181
for (int index = getCalls().size() - 1; index >= 0; index--) {
182                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
183                 Integer JavaDoc rowCount = (Integer JavaDoc)executeCall(databseCall);
184                 if ((index == (getCalls().size() - 1)) || (rowCount.intValue() <= 0)) {// Row count returned must be from first table or zero if any are zero.
185
returnedRowCount = rowCount;
186                 }
187             }
188             return returnedRowCount;
189         } else {
190             return (Integer JavaDoc)executeCall();
191         }
192     }
193
194     /**
195      * Execute the call. It is assumed the call has been fully prepared.
196      * @exception DatabaseException - an error has occurred on the database.
197      */

198     protected Object JavaDoc executeCall() throws DatabaseException {
199         return executeCall(getCall());
200     }
201
202     /**
203      * Execute the call. It is assumed the call has been fully prepared.
204      * @exception DatabaseException - an error has occurred on the database.
205      */

206     protected Object JavaDoc executeCall(DatasourceCall databaseCall) throws DatabaseException {
207         // For CR 2923 must move to session we will execute call on now
208
// so correct DatasourcePlatform used by translate.
209
AbstractSession sessionToUse = getSession().getExecutionSession(getQuery());
210         DatasourceCall clonedCall = (DatasourceCall)databaseCall.clone();
211         clonedCall.setQuery(getQuery());
212         clonedCall.translate(getTranslationRow(), getModifyRow(), sessionToUse);
213         return sessionToUse.executeCall(clonedCall, getTranslationRow(), getQuery());
214     }
215
216     /**
217      * Execute a non selecting call.
218      * @exception DatabaseException - an error has occurred on the database.
219      * @return the row count.
220      */

221     public Integer JavaDoc executeNoSelect() throws DatabaseException {
222         return executeNoSelectCall();
223     }
224
225     /**
226      * Execute a non selecting call.
227      * @exception DatabaseException - an error has occurred on the database.
228      * @return the row count.
229      */

230     public Integer JavaDoc executeNoSelectCall() throws DatabaseException {
231         if (hasMultipleCalls()) {
232             Integer JavaDoc returnedRowCount = null;
233             for (int index = 0; index < getCalls().size(); index++) {
234                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
235                 Integer JavaDoc rowCount = (Integer JavaDoc)executeCall(databseCall);
236                 if ((index == 0) || (rowCount.intValue() <= 0)) {// Row count returned must be from first table or zero if any are zero.
237
returnedRowCount = rowCount;
238                 }
239             }
240             return returnedRowCount;
241         } else {
242             return (Integer JavaDoc)executeCall();
243         }
244     }
245
246     /**
247      * INTERNAL:
248      * Execute a selecting call.
249      * @exception DatabaseException - an error has occurred on the database
250      */

251     public Vector executeSelect() throws DatabaseException {
252         return executeSelectCall();
253     }
254
255     /**
256      * INTERNAL:
257      * Execute a selecting call.
258      * @exception DatabaseException - an error has occurred on the database
259      */

260     public Vector executeSelectCall() throws DatabaseException {
261         if (hasMultipleCalls()) {
262             Vector results = new Vector();
263             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
264                 DatasourceCall databseCall = (DatasourceCall)callsEnum.nextElement();
265                 Helper.addAllToVector(results, (Vector)executeCall(databseCall));
266             }
267
268             return results;
269         } else {
270             return (Vector)executeCall();
271         }
272     }
273
274     /**
275      * Return the call.
276      */

277     public DatasourceCall getCall() {
278         return call;
279     }
280
281     /**
282      * Normally only a single call is used, however multiple table may require multiple calls on write.
283      * This is lazy initialied to conserv space.
284      */

285     public Vector getCalls() {
286         if (calls == null) {
287             calls = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(3);
288         }
289         return calls;
290     }
291
292     /**
293      * Normally only a single call is used, however multiple table may require multiple calls on write.
294      * This is lazy initialied to conserv space.
295      */

296     public boolean hasMultipleCalls() {
297         return (calls != null) && (!calls.isEmpty());
298     }
299
300     /**
301      * Insert the object. Assume the call is correct
302      * @exception DatabaseException - an error has occurred on the database
303      */

304     public void insertObject() throws DatabaseException {
305         Class JavaDoc cls = ((DatabaseQuery)getQuery()).getReferenceClass();
306         boolean usesSequencing = getDescriptor().usesSequenceNumbers();
307         boolean shouldAcquireValueAfterInsert = false;
308         if (usesSequencing) {
309             shouldAcquireValueAfterInsert = getSession().getSequencing().shouldAcquireValueAfterInsert(cls);
310         }
311         Collection returnFields = null;
312
313         // Check to see if sequence number should be retrieved after insert
314
if (usesSequencing && !shouldAcquireValueAfterInsert) {
315             // This is the normal case. Update object with sequence number before insert.
316
updateObjectAndRowWithSequenceNumber();
317         }
318
319         if (hasMultipleCalls()) {
320             for (int index = 0; index < getCalls().size(); index++) {
321                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
322                 executeCall(databseCall);
323                 if (returnFields != null) {
324                     updateObjectAndRowWithReturnRow(returnFields, index == 0);
325                 }
326                 if ((index == 0) && usesSequencing && shouldAcquireValueAfterInsert) {
327                     updateObjectAndRowWithSequenceNumber();
328                 }
329             }
330         } else {
331             executeCall();
332             if (returnFields != null) {
333                 updateObjectAndRowWithReturnRow(returnFields, true);
334             }
335             if (usesSequencing && shouldAcquireValueAfterInsert) {
336                 updateObjectAndRowWithSequenceNumber();
337             }
338         }
339
340         // Bug 3110860: RETURNINGPOLICY-OBTAINED PK CAUSES LOB TO BE INSERTED INCORRECTLY
341
// The deferred locator SELECT calls should be generated and executed after ReturningPolicy
342
// merges PK obtained from the db into the object held by the query.
343
//
344
//Oracle thin driver handles LOB differently. During the insert, empty lob would be
345
//insert first, and then the LOb locator is retrieved and LOB data are written through
346
//the locator.
347
//
348
// Bug 2804663 - LOBValueWriter is no longer a singleton, so we execute any deferred
349
// select calls through the DatabaseAccessor which holds the writer instance
350
AbstractSession executionSession = getSession().getExecutionSession(getQuery());
351         executionSession.getAccessor().flushSelectCalls(executionSession);
352     }
353
354     /**
355      * Return true if this is a call query mechanism
356      */

357     public boolean isCallQueryMechanism() {
358         return true;
359     }
360
361     /**
362      * INTERNAL:
363      * This is different from 'prepareForExecution' in that this is called on the original query,
364      * and the other is called on the copy of the query.
365      * This query is copied for concurrency so this prepare can only setup things that
366      * will apply to any future execution of this query.
367      */

368     public void prepare() {
369         if ((!hasMultipleCalls()) && (getCall() == null)) {
370             throw QueryException.sqlStatementNotSetProperly(getQuery());
371         }
372     }
373
374     /**
375      * INTERNAL:
376      * This is different from 'prepareForExecution' in that this is called on the original query,
377      * and the other is called on the copy of the query.
378      * This query is copied for concurrency so this prepare can only setup things that
379      * will apply to any future execution of this query.
380      */

381     public void prepareCall() throws QueryException {
382         DatabaseQuery query = getQuery();
383         AbstractSession executionSession = getSession().getExecutionSession(query);
384         if (hasMultipleCalls()) {
385             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
386                 DatasourceCall call = (DatasourceCall)callsEnum.nextElement();
387                 call.prepare(executionSession);
388             }
389         } else if (getCall() != null) {
390             getCall().prepare(executionSession);
391         }
392     }
393
394     /**
395      * Pre-build configure the call.
396      */

397     public void prepareCursorSelectAllRows() throws QueryException {
398         getCall().returnCursor();
399         prepareCall();
400     }
401
402     /**
403      * Pre-build configure the call.
404      */

405     public void prepareDeleteAll() {
406         if (hasMultipleCalls()) {
407             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
408                 DatasourceCall call = (DatasourceCall)callsEnum.nextElement();
409                 call.returnNothing();
410             }
411         } else {
412             getCall().returnNothing();
413         }
414         prepareCall();
415     }
416
417     /**
418      * Pre-build configure the call.
419      */

420     public void prepareDeleteObject() {
421         if (hasMultipleCalls()) {
422             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
423                 DatasourceCall call = (DatasourceCall)callsEnum.nextElement();
424                 call.returnNothing();
425             }
426         } else {
427             getCall().returnNothing();
428         }
429         prepareCall();
430     }
431
432     /**
433      * Pre-build configure the call.
434      */

435     public void prepareDoesExist(DatabaseField field) {
436         if (hasMultipleCalls()) {
437             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
438                 ((DatasourceCall)callsEnum.nextElement()).returnOneRow();
439             }
440         } else {
441             getCall().returnOneRow();
442         }
443         prepareCall();
444     }
445
446     /**
447      * Pre-build configure the call.
448      */

449     public void prepareExecuteNoSelect() {
450         if (hasMultipleCalls()) {
451             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
452                 ((DatasourceCall)callsEnum.nextElement()).returnNothing();
453             }
454         } else {
455             getCall().returnNothing();
456         }
457         prepareCall();
458     }
459
460     /**
461      * Pre-build configure the call.
462      */

463     public void prepareExecuteSelect() {
464         if (hasMultipleCalls()) {
465             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
466                 DatasourceCall databseCall = (DatasourceCall)callsEnum.nextElement();
467                 databseCall.returnManyRows();
468             }
469         } else {
470             getCall().returnManyRows();
471         }
472         prepareCall();
473     }
474
475     /**
476      * Pre-build configure the call.
477      */

478     public void prepareInsertObject() {
479         if (hasMultipleCalls()) {
480             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
481                 ((DatasourceCall)callsEnum.nextElement()).returnNothing();
482             }
483         } else {
484             getCall().returnNothing();
485         }
486         prepareCall();
487     }
488
489     /**
490      * Prepare the report items. Indexes of results needs to be calculates
491      */

492     protected void prepareReportQueryItems(){
493         //calculate indexes after normalize to insure expressions are set up correctly
494
int itemOffset = 0;
495         for (Iterator items = ((ReportQuery)getQuery()).getItems().iterator(); items.hasNext();){
496             ReportItem item = (ReportItem) items.next();
497             item.setResultIndex(itemOffset);
498             if (item.getAttributeExpression() != null){
499                 JoinedAttributeManager joinManager = item.getJoinedAttributeManager();
500                 if (joinManager.hasJoinedExpressions()){
501                     itemOffset = joinManager.computeJoiningMappingIndexes(true, getSession(),itemOffset);
502                 }else{
503                     if (item.getDescriptor() != null){
504                         itemOffset += item.getDescriptor().getAllFields().size();
505                     }else {
506                         ++itemOffset; //only a single attribute can be selected
507
}
508                 }
509             }
510         }
511         
512     }
513     /**
514      * Pre-build configure the call.
515      */

516     public void prepareReportQuerySelectAllRows() {
517         prepareReportQueryItems();
518         prepareExecuteSelect();
519     }
520
521     /**
522      * Prepare for a sub select using a call.
523      */

524     public void prepareReportQuerySubSelect() {
525         prepareReportQueryItems();
526         prepareCall();
527     }
528
529     /**
530      * Pre-build configure the call.
531      */

532     public void prepareSelectAllRows() {
533         if (hasMultipleCalls()) {
534             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
535                 DatasourceCall databseCall = (DatasourceCall)callsEnum.nextElement();
536                 databseCall.returnManyRows();
537             }
538         } else {
539             getCall().returnManyRows();
540         }
541         prepareCall();
542     }
543
544     /**
545      * Pre-build configure the call.
546      */

547     public void prepareSelectOneRow() {
548         if (hasMultipleCalls()) {
549             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
550                 DatasourceCall databseCall = (DatasourceCall)callsEnum.nextElement();
551                 databseCall.returnOneRow();
552             }
553         } else {
554             getCall().returnOneRow();
555         }
556         prepareCall();
557     }
558
559     /**
560      * Pre-build configure the call.
561      */

562     public void prepareUpdateObject() {
563         if (hasMultipleCalls()) {
564             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
565                 DatasourceCall call = (DatasourceCall)callsEnum.nextElement();
566                 call.returnNothing();
567             }
568         } else if (getCall() != null) {
569             getCall().returnNothing();
570         }
571         prepareCall();
572     }
573
574     /**
575        * Pre-build configure the call.
576        */

577     public void prepareUpdateAll() {
578         if (getCall() != null) {
579             getCall().returnNothing();
580         }
581
582         prepareCall();
583     }
584
585     /**
586      * Read all rows from the database. Assume call is correct returns the required fields.
587      * @return Vector containing the database rows
588      * @exception DatabaseException - an error has occurred on the database
589      */

590     public Vector selectAllReportQueryRows() throws DatabaseException {
591         return executeSelect();
592     }
593
594     /**
595      * Read all rows from the database. Assume call is correct returns the required fields.
596      * @return Vector containing the database rows
597      * @exception DatabaseException - an error has occurred on the database
598      */

599     public Vector selectAllRows() throws DatabaseException {
600         return executeSelectCall();
601     }
602
603     /**
604      * Read a single row from the database. Assume call is correct.
605      * @return row containing data
606      * @exception DatabaseException - an error has occurred on the database
607      */

608     public AbstractRecord selectOneRow() throws DatabaseException {
609         if (hasMultipleCalls()) {
610             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
611                 DatasourceCall databaseCall = (DatasourceCall)callsEnum.nextElement();
612                 AbstractRecord result = (AbstractRecord)executeCall(databaseCall);
613                 if (result != null) {
614                     return result;
615                 }
616             }
617
618             return null;
619         } else {
620             return (AbstractRecord)executeCall();
621         }
622     }
623
624     /**
625      * Perform a does exist check
626      * @param field - the field used for does exist check
627      * @return the associated row from the database
628      * @exception DatabaseException - an error has occurred on the database
629      */

630     public AbstractRecord selectRowForDoesExist(DatabaseField field) throws DatabaseException {
631         if (hasMultipleCalls()) {
632             for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
633                 DatasourceCall databaseCall = (DatasourceCall)callsEnum.nextElement();
634                 AbstractRecord result = (AbstractRecord)executeCall(databaseCall);
635                 if (result != null) {
636                     return result;
637                 }
638             }
639
640             return null;
641         } else {
642             return (AbstractRecord)executeCall();
643         }
644     }
645
646     /**
647      * Set the call.
648      */

649     public void setCall(DatasourceCall call) {
650         this.call = call;
651         if (call != null) {
652             call.setQuery(getQuery());
653         }
654     }
655
656     /**
657      * Normally only a single call is used, however multiple table may require multiple calls on write.
658      * This is lazy initialied to conserv space.
659      */

660     protected void setCalls(Vector calls) {
661         this.calls = calls;
662     }
663
664     /**
665      * Update the object. Assume the call is correct.
666      * @exception DatabaseException - an error has occurred on the database.
667      * @return the row count.
668      */

669     public Integer JavaDoc updateObject() throws DatabaseException {
670         Collection returnFields = null;
671         Integer JavaDoc returnedRowCount = null;
672         if (hasMultipleCalls()) {
673             for (int index = 0; index < getCalls().size(); index++) {
674                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
675                 Integer JavaDoc rowCount = (Integer JavaDoc)executeCall(databseCall);
676                 if ((index == 0) || (rowCount.intValue() <= 0)) {// Row count returned must be from first table or zero if any are zero.
677
returnedRowCount = rowCount;
678                 }
679                 if (returnFields != null) {
680                     updateObjectAndRowWithReturnRow(returnFields, false);
681                 }
682             }
683         } else {
684             returnedRowCount = (Integer JavaDoc)executeCall();
685             if (returnFields != null) {
686                 updateObjectAndRowWithReturnRow(returnFields, false);
687             }
688         }
689
690         //Oracle thin driver handles LOB differently. During the insert, empty lob would be
691
//insert first, and then the LOb locator is retrieved and LOB data are written through
692
//the locator.
693
//
694
// Bug 2804663 - LOBValueWriter is no longer a singleton, so we execute any deferred
695
// select calls through the DatabaseAccessor which holds the writer instance
696
//
697
// Building of SELECT statements is no longer done in DatabaseAccessor.basicExecuteCall
698
// because DatabaseCall.isUpdateCall() can't recognize update in case StoredProcedureCall
699
// is used.
700
AbstractSession executionSession = getSession().getExecutionSession(getQuery());
701         executionSession.getAccessor().flushSelectCalls(executionSession);
702         return returnedRowCount;
703     }
704
705     /**
706        * Update the rows on the database. Assume the call is correct.
707        * @exception DatabaseException - an error has occurred on the database.
708        */

709     public Integer JavaDoc updateAll() throws DatabaseException {
710         if(((UpdateAllQuery)getQuery()).isPreparedUsingTempStorage() && getSession().getPlatform().supportsTempTables()) {
711             return updateAllUsingTempTables();
712         } else {
713             Integer JavaDoc rowCount = executeNoSelectCall();
714             if(((UpdateAllQuery)getQuery()).isPreparedUsingTempStorage()) {
715                 // the query was prepared using Oracle anonymous block
716
AbstractRecord outputRow = (AbstractRecord)getQuery().getProperty("output");
717                 rowCount = (Integer JavaDoc)outputRow.get("ROW_COUNT");
718             }
719             return rowCount;
720         }
721     }
722
723     /**
724      * Execute updateAll using temp tables
725      * @exception DatabaseException - an error has occurred on the database.
726      * @return the row count.
727      */

728     public Integer JavaDoc updateAllUsingTempTables() throws DatabaseException {
729         int nTables = getCalls().size() / 4;
730         DatabaseException ex = null;
731         Integer JavaDoc returnedRowCount = null;
732         
733         // first quarter - crete temp tables calls.
734
// may fail in case global temp table already exists.
735
for (int index = 0; index < nTables; index++) {
736             try {
737                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
738                 executeCall(databseCall);
739             } catch (DatabaseException databaseEx) {
740                 // ignore
741
}
742         }
743
744         // second quarter - populate temp tables calls.
745
// if that fails save the exception and untill cleanup
746
for (int index = nTables; index < nTables*2 && ex == null; index++) {
747             try {
748                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
749                 executeCall(databseCall);
750             } catch (DatabaseException databaseEx) {
751                 ex = databaseEx;
752             }
753         }
754         
755         // third quarter - update original tables calls.
756
// if that fails save the exception and untill cleanup
757
for (int index = nTables*2; index < nTables*3 && ex == null; index++) {
758             try {
759                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
760                 Integer JavaDoc rowCount = (Integer JavaDoc)executeCall(databseCall);
761                 if ((index == nTables*2) || (rowCount.intValue() <= 0)) {// Row count returned must be from first table or zero if any are zero.
762
returnedRowCount = rowCount;
763                 }
764             } catch (DatabaseException databaseEx) {
765                 ex = databaseEx;
766             }
767         }
768         
769         // last quarter - cleanup temp tables calls.
770
// ignore exceptions here.
771
for (int index = nTables*3; index < nTables*4; index++) {
772             try {
773                 DatasourceCall databseCall = (DatasourceCall)getCalls().elementAt(index);
774                 executeCall(databseCall);
775                 } catch (DatabaseException databaseEx) {
776                     // ignore
777
}
778         }
779
780         if(ex != null) {
781             throw ex;
782         }
783         
784         return returnedRowCount;
785     }
786
787     /**
788      * Update the foreign key fields when resolving a bi-directonal reference in a UOW.
789      * This is rare to occur for non-relational, however if it does each of the calls must be re-executed.
790      */

791     protected void updateForeignKeyFieldAfterInsert(WriteObjectQuery writeQuery) {
792         writeQuery.setModifyRow(this.getDescriptor().getObjectBuilder().buildRow(writeQuery.getObject(), this.getSession()));
793
794         // For CR 2923 must move to session we will execute call on now
795
// so correct DatasourcePlatform used by translate.
796
AbstractSession sessionToUse = getSession().getExecutionSession(getQuery());
797
798         // yes - this is a bit ugly...
799
Vector calls = ((DatasourceCallQueryMechanism)this.getDescriptor().getQueryManager().getUpdateQuery().getQueryMechanism()).getCalls();
800         for (Enumeration stream = calls.elements(); stream.hasMoreElements();) {
801             DatasourceCall call = (DatasourceCall)((DatasourceCall)stream.nextElement()).clone();
802             call.setQuery(writeQuery);
803             sessionToUse.executeCall(call, this.getTranslationRow(), writeQuery);
804         }
805     }
806 }
807
Popular Tags