KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > dba > sqlserver > SQLServerProcedureAction


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

19
20 package org.apache.cayenne.dba.sqlserver;
21
22 import java.sql.CallableStatement JavaDoc;
23 import java.sql.Connection JavaDoc;
24 import java.sql.ResultSet JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29
30 import org.apache.cayenne.access.OperationObserver;
31 import org.apache.cayenne.access.QueryLogger;
32 import org.apache.cayenne.access.ResultIterator;
33 import org.apache.cayenne.access.jdbc.ProcedureAction;
34 import org.apache.cayenne.access.jdbc.RowDescriptor;
35 import org.apache.cayenne.access.trans.ProcedureTranslator;
36 import org.apache.cayenne.dba.DbAdapter;
37 import org.apache.cayenne.map.EntityResolver;
38 import org.apache.cayenne.query.ProcedureQuery;
39 import org.apache.cayenne.query.Query;
40
41 /**
42  * ProcedureAction for SQLServer MS JDBC driver. Customizes OUT parameter processing - it
43  * has to be done AFTER the ResultSets are read (note that jTDS driver works fine with
44  * normal ProcedureAction).
45  * <p>
46  * <i>See JIRA CAY-251 for details. </i>
47  * </p>
48  *
49  * @since 1.2
50  * @author Andrus Adamchik
51  */

52 public class SQLServerProcedureAction extends ProcedureAction {
53
54     public SQLServerProcedureAction(ProcedureQuery query, DbAdapter adapter,
55             EntityResolver entityResolver) {
56         super(query, adapter, entityResolver);
57     }
58
59     public void performAction(Connection JavaDoc connection, OperationObserver observer)
60             throws SQLException JavaDoc, Exception JavaDoc {
61
62         ProcedureTranslator transl = createTranslator(connection);
63         CallableStatement JavaDoc statement = (CallableStatement JavaDoc) transl.createStatement();
64
65         try {
66             // stored procedure may contain a mixture of update counts and result sets,
67
// and out parameters. Read out parameters first, then
68
// iterate until we exhaust all results
69
boolean hasResultSet = statement.execute();
70
71             // local observer to cache results and provide them to the external observer
72
// in the order consistent with other adapters.
73

74             Observer localObserver = new Observer(observer);
75
76             // read query, using local observer
77

78             while (true) {
79                 if (hasResultSet) {
80                     ResultSet JavaDoc rs = statement.getResultSet();
81                     try {
82                         RowDescriptor descriptor = describeResultSet(
83                                 rs,
84                                 processedResultSets++);
85                         readResultSet(rs, descriptor, query, localObserver);
86                     }
87                     finally {
88                         try {
89                             rs.close();
90                         }
91                         catch (SQLException JavaDoc ex) {
92                         }
93                     }
94                 }
95                 else {
96                     int updateCount = statement.getUpdateCount();
97                     if (updateCount == -1) {
98                         break;
99                     }
100                     QueryLogger.logUpdateCount(updateCount);
101                     localObserver.nextCount(query, updateCount);
102                 }
103
104                 hasResultSet = statement.getMoreResults();
105             }
106
107             // read out parameters to the main observer ... AFTER the main result set
108
// TODO: I hope SQLServer does not support ResultSets as OUT parameters,
109
// otherwise
110
// the order of custom result descriptors will be messed up
111
readProcedureOutParameters(statement, observer);
112
113             // add results back to main observer
114
localObserver.flushResults(query);
115         }
116         finally {
117             try {
118                 statement.close();
119             }
120             catch (SQLException JavaDoc ex) {
121
122             }
123         }
124     }
125
126     class Observer implements OperationObserver {
127
128         List JavaDoc results;
129         List JavaDoc counts;
130         OperationObserver observer;
131
132         Observer(OperationObserver observer) {
133             this.observer = observer;
134         }
135
136         void flushResults(Query query) {
137             if (results != null) {
138                 Iterator JavaDoc it = results.iterator();
139                 while (it.hasNext()) {
140                     observer.nextDataRows(query, (List JavaDoc) it.next());
141                 }
142
143                 results = null;
144             }
145
146             if (counts != null) {
147                 Iterator JavaDoc it = counts.iterator();
148                 while (it.hasNext()) {
149                     observer.nextCount(query, ((Number JavaDoc) it.next()).intValue());
150                 }
151
152                 counts = null;
153             }
154         }
155
156         public void nextBatchCount(Query query, int[] resultCount) {
157             observer.nextBatchCount(query, resultCount);
158         }
159
160         public void nextCount(Query query, int resultCount) {
161             // does not delegate to wrapped observer
162
// but instead caches results locally.
163
if (counts == null) {
164                 counts = new ArrayList JavaDoc();
165             }
166
167             counts.add(new Integer JavaDoc(resultCount));
168         }
169
170         public void nextDataRows(Query query, List JavaDoc dataRows) {
171             // does not delegate to wrapped observer
172
// but instead caches results locally.
173
if (results == null) {
174                 results = new ArrayList JavaDoc();
175             }
176
177             results.add(dataRows);
178         }
179
180         public void nextDataRows(Query q, ResultIterator it) {
181             observer.nextDataRows(q, it);
182         }
183
184         public void nextGlobalException(Exception JavaDoc ex) {
185             observer.nextGlobalException(ex);
186         }
187
188         public void nextGeneratedDataRows(Query query, ResultIterator keysIterator) {
189             observer.nextGeneratedDataRows(query, keysIterator);
190         }
191
192         public void nextQueryException(Query query, Exception JavaDoc ex) {
193             observer.nextQueryException(query, ex);
194         }
195
196         public boolean isIteratedResult() {
197             return observer.isIteratedResult();
198         }
199     }
200 }
201
Popular Tags