KickJava   Java API By Example, From Geeks To Geeks.

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


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.expressions.*;
26 import oracle.toplink.essentials.internal.databaseaccess.*;
27 import oracle.toplink.essentials.expressions.*;
28 import oracle.toplink.essentials.internal.helper.*;
29 import oracle.toplink.essentials.exceptions.*;
30 import oracle.toplink.essentials.queryframework.*;
31 import oracle.toplink.essentials.sessions.SessionProfiler;
32
33 /**
34  * <p><b>Purpose</b>:
35  * Mechanism used for all statement objects.
36  * <p>
37  * <p><b>Responsibilities</b>:
38  * Executes the appropriate statement.
39  *
40  * @author Yvon Lavoie
41  * @since TOPLink/Java 1.0
42  */

43 public class StatementQueryMechanism extends CallQueryMechanism {
44     protected SQLStatement sqlStatement;
45
46     /** Normally only a single statement is used, however multiple table may require multiple statements on write. */
47     protected Vector sqlStatements;
48
49     /**
50      * INTERNAL:
51      * Return a new mechanism for the query
52      * @param query - owner of mechanism
53      */

54     public StatementQueryMechanism(DatabaseQuery query) {
55         super(query);
56     }
57
58     /**
59      * Return a new mechanism for the query
60      * @param query - owner of mechanism
61      * @param statement - sql statement
62      */

63     public StatementQueryMechanism(DatabaseQuery query, SQLStatement statement) {
64         super(query);
65         this.sqlStatement = statement;
66     }
67
68     /**
69      * The statement is no longer require after prepare so can be released.
70      */

71     public void clearStatement() {
72         // Only clear the statement if it is an expression query, otherwise the statement may still be needed.
73
if (isExpressionQueryMechanism()) {
74             setSQLStatement(null);
75             setSQLStatements(null);
76         }
77     }
78
79     /**
80      * Clone the mechanism for the specified query clone.
81      */

82     public DatabaseQueryMechanism clone(DatabaseQuery queryClone) {
83         StatementQueryMechanism clone = (StatementQueryMechanism)super.clone(queryClone);
84         if ((!hasMultipleStatements()) && (getSQLStatement() != null)) {
85             clone.setSQLStatement((SQLStatement)sqlStatement.clone());
86         } else {
87             Vector currentStatements = getSQLStatements();
88             if (currentStatements != null) {
89                 Vector statementClone = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(currentStatements.size());
90                 Enumeration enumtr = currentStatements.elements();
91                 while (enumtr.hasMoreElements()) {
92                     statementClone.addElement(((SQLStatement)enumtr.nextElement()).clone());
93                 }
94                 clone.setSQLStatements(statementClone);
95             }
96         }
97         return clone;
98     }
99
100     /**
101      * INTERNAL:
102      * delete the object
103      * @exception DatabaseException - an error has occurred on the database.
104      * @return the row count.
105      */

106     public Integer JavaDoc deleteObject() throws DatabaseException {
107         // Prepare the calls if not already set (prepare may not have had the modify row).
108
if ((!hasMultipleCalls()) && (getCall() == null)) {
109             prepareDeleteObject();
110             if ((!hasMultipleCalls()) && (getCall() == null)) {
111                 return new Integer JavaDoc(1);// Must be 1 otherwise locking error will occur.
112
}
113         }
114
115         return super.deleteObject();
116     }
117
118     /**
119      * Update the object
120      * @exception DatabaseException - an error has occurred on the database.
121      * @return the row count.
122      */

123     public Integer JavaDoc executeNoSelect() throws DatabaseException {
124         // Prepare the calls if not already set (prepare may not have had the modify row).
125
if ((!hasMultipleCalls()) && (getCall() == null)) {
126             prepareExecuteNoSelect();
127         }
128
129         return super.executeNoSelect();
130     }
131
132     /**
133      * Return the selection criteria for the statement.
134      */

135     public Expression getSelectionCriteria() {
136         return getSQLStatement().getWhereClause();
137     }
138
139     /**
140      * INTERNAL:
141      * Return the sqlStatement
142      */

143     public SQLStatement getSQLStatement() {
144         return sqlStatement;
145     }
146
147     /**
148      * Normally only a single statement is used, however multiple table may require multiple statements on write.
149      * This is lazy initialied to conserv space.
150      */

151     public Vector getSQLStatements() {
152         if (sqlStatements == null) {
153             sqlStatements = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(3);
154         }
155         return sqlStatements;
156     }
157
158     /**
159      * Normally only a single statement is used, however multiple table may require multiple statements on write.
160      * This is lazy initialied to conserv space.
161      */

162     public boolean hasMultipleStatements() {
163         return (sqlStatements != null) && (!sqlStatements.isEmpty());
164     }
165
166     /**
167      * Insert the object
168      * @exception DatabaseException - an error has occurred on the database.
169      */

170     public void insertObject() throws DatabaseException {
171         // Prepare the calls if not already set (prepare may not have had the modify row).
172
if ((!hasMultipleCalls()) && (getCall() == null)) {
173             prepareInsertObject();
174         }
175
176         super.insertObject();
177     }
178
179     /**
180      * Insert the object if the reprepare flag is set, first reprepare the query.
181      * Added for CR#3237
182      * @param boolean reprepare - whether to reprepare the query.
183      */

184     public void insertObject(boolean reprepare) {
185         if (reprepare) {
186             // Clear old calls, and reprepare.
187
setCalls(null);
188             prepareInsertObject();
189         }
190         insertObject();
191     }
192
193     /**
194      * Return true if this is a call query mechanism
195      */

196     public boolean isCallQueryMechanism() {
197         return false;
198     }
199
200     /**
201      * Return true if this is a statement query mechanism
202      */

203     public boolean isStatementQueryMechanism() {
204         return true;
205     }
206
207     /**
208      * INTERNAL:
209      * This is different from 'prepareForExecution' in that this is called on the original query,
210      * and the other is called on the copy of the query.
211      * This query is copied for concurrency so this prepare can only setup things that
212      * will apply to any future execution of this query.
213      */

214     public void prepare() {
215         if ((!hasMultipleStatements()) && (getSQLStatement() == null)) {
216             throw QueryException.sqlStatementNotSetProperly(getQuery());
217         }
218
219         // Cannot call super yet as the call is not built.
220
}
221
222     /**
223      * Pre-build the SQL call from the statement.
224      */

225     public void prepareCursorSelectAllRows() {
226         setCallFromStatement();
227         // The statement is no longer require so can be released.
228
clearStatement();
229
230         super.prepareCursorSelectAllRows();
231     }
232
233     /**
234      * Pre-build the SQL call from the statement.
235      */

236     public void prepareDeleteAll() {
237         setCallFromStatement();
238         // The statement is no longer require so can be released.
239
clearStatement();
240
241         super.prepareDeleteAll();
242     }
243
244     /**
245      * Pre-build the SQL call from the statement.
246      */

247     public void prepareDeleteObject() {
248         setCallFromStatement();
249         // The statement is no longer require so can be released.
250
clearStatement();
251
252         super.prepareDeleteObject();
253     }
254
255     /**
256      * Pre-build the SQL call from the statement.
257      */

258     public void prepareDoesExist(DatabaseField field) {
259         setCallFromStatement();
260         // The statement is no longer require so can be released.
261
clearStatement();
262
263         getCall().returnOneRow();
264         prepareCall();
265     }
266
267     /**
268      * Pre-build the SQL call from the statement.
269      */

270     public void prepareExecuteNoSelect() {
271         setCallFromStatement();
272         // The statement is no longer require so can be released.
273
clearStatement();
274
275         super.prepareExecuteNoSelect();
276     }
277
278     /**
279      * Pre-build the SQL call from the statement.
280      */

281     public void prepareExecuteSelect() {
282         setCallFromStatement();
283         // The statement is no longer require so can be released.
284
clearStatement();
285
286         super.prepareExecuteSelect();
287     }
288
289     /**
290      * Pre-build the SQL call from the statement.
291      */

292     public void prepareInsertObject() {
293         // Require modify row to prepare.
294
if (getModifyRow() == null) {
295             return;
296         }
297
298         if (hasMultipleStatements()) {
299             for (Enumeration statementEnum = getSQLStatements().elements();
300                      statementEnum.hasMoreElements();) {
301                 ((SQLModifyStatement)statementEnum.nextElement()).setModifyRow(getModifyRow());
302             }
303         } else if (getSQLStatement() != null) {
304             ((SQLModifyStatement)getSQLStatement()).setModifyRow(getModifyRow());
305         }
306         setCallFromStatement();
307         // The statement is no longer require so can be released.
308
clearStatement();
309
310         super.prepareInsertObject();
311     }
312
313     /**
314      * Pre-build the SQL call from the statement.
315      */

316     public void prepareSelectAllRows() {
317         setCallFromStatement();
318         // The statement is no longer require so can be released.
319
clearStatement();
320
321         super.prepareSelectAllRows();
322     }
323
324     /**
325      * Pre-build the SQL call from the statement.
326      */

327     public void prepareSelectOneRow() {
328         setCallFromStatement();
329         // The statement is no longer require so can be released.
330
clearStatement();
331
332         super.prepareSelectOneRow();
333     }
334
335     /**
336      * Pre-build the SQL call from the statement.
337      */

338     public void prepareUpdateObject() {
339         // Require modify row to prepare.
340
if (getModifyRow() == null) {
341             return;
342         }
343
344         if (hasMultipleStatements()) {
345             for (Enumeration statementEnum = getSQLStatements().elements();
346                      statementEnum.hasMoreElements();) {
347                 ((SQLModifyStatement)statementEnum.nextElement()).setModifyRow(getModifyRow());
348             }
349         } else if (getSQLStatement() != null) {
350             ((SQLModifyStatement)getSQLStatement()).setModifyRow(getModifyRow());
351         }
352         setCallFromStatement();
353         // The statement is no longer require so can be released.
354
clearStatement();
355
356         super.prepareUpdateObject();
357     }
358
359     /**
360      * Pre-build the SQL call from the statement.
361      */

362     public void prepareUpdateAll() {
363         setCallFromStatement();// Will build an SQLUpdateAllStatement
364
clearStatement();// The statement is no longer require so can be released.
365
super.prepareUpdateAll();
366     }
367
368     /**
369      * Pre-build the SQL call from the statement.
370      */

371     protected void setCallFromStatement() {
372         // Profile SQL generation.
373
getSession().startOperationProfile(SessionProfiler.SQL_GENERATION);
374         if (hasMultipleStatements()) {
375             for (Enumeration statementEnum = getSQLStatements().elements();
376                      statementEnum.hasMoreElements();) {
377                 // DatabaseCall call = ((SQLStatement) statementEnum.nextElement()).buildCall(getSession());
378
DatabaseCall call = null;
379                 if (getDescriptor() != null) {
380                     call = getDescriptor().buildCallFromStatement((SQLStatement)statementEnum.nextElement(), getSession());
381                 } else {
382                     call = ((SQLStatement)statementEnum.nextElement()).buildCall(getSession());
383                 }
384
385                 // In case of update call may be null if no update required.
386
if (call != null) {
387                     addCall(call);
388                 }
389             }
390         } else {
391             DatabaseCall call = null;
392             if (getDescriptor() != null) {
393                 call = getDescriptor().buildCallFromStatement(getSQLStatement(), getSession());
394             } else {
395                 call = getSQLStatement().buildCall(getSession());
396             }
397
398             // In case of update call may be null if no update required.
399
if (call != null) {
400                 setCall(call);
401             }
402         }
403
404         // Profile SQL generation.
405
getSession().endOperationProfile(SessionProfiler.SQL_GENERATION);
406     }
407
408     /**
409      * Set the sqlStatement
410      */

411     public void setSQLStatement(SQLStatement statement) {
412         this.sqlStatement = statement;
413     }
414
415     /**
416      * Normally only a single statement is used, however multiple table may require multiple statements on write.
417      * This is lazy initialied to conserv space.
418      */

419     protected void setSQLStatements(Vector sqlStatements) {
420         this.sqlStatements = sqlStatements;
421     }
422
423     /**
424      * Update the object
425      * @exception DatabaseException - an error has occurred on the database.
426      * @return the row count.
427      */

428     public Integer JavaDoc updateObject() throws DatabaseException {
429         // Prepare the calls if not already set (prepare may not have had the modify row).
430
if ((!hasMultipleCalls()) && (getCall() == null)) {
431             prepareUpdateObject();
432             if ((!hasMultipleCalls()) && (getCall() == null)) {
433                 return new Integer JavaDoc(1);// Must be 1 otherwise locking error will occur.
434
}
435         }
436
437         return super.updateObject();
438     }
439 }
440
Popular Tags