KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > access > jdbc > SelectAction


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.access.jdbc;
21
22 import java.sql.Connection JavaDoc;
23 import java.sql.PreparedStatement JavaDoc;
24 import java.sql.ResultSet JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.List JavaDoc;
27
28 import org.apache.cayenne.access.OperationObserver;
29 import org.apache.cayenne.access.QueryLogger;
30 import org.apache.cayenne.access.ResultIterator;
31 import org.apache.cayenne.access.trans.SelectTranslator;
32 import org.apache.cayenne.access.util.DistinctResultIterator;
33 import org.apache.cayenne.dba.DbAdapter;
34 import org.apache.cayenne.map.EntityResolver;
35 import org.apache.cayenne.query.PrefetchProcessor;
36 import org.apache.cayenne.query.PrefetchTreeNode;
37 import org.apache.cayenne.query.QueryMetadata;
38 import org.apache.cayenne.query.SelectQuery;
39
40 /**
41  * A SQLAction that handles SelectQuery execution.
42  *
43  * @since 1.2
44  * @author Andrus Adamchik
45  */

46 public class SelectAction extends BaseSQLAction {
47
48     protected SelectQuery query;
49
50     public SelectAction(SelectQuery query, DbAdapter adapter,
51             EntityResolver entityResolver) {
52         super(adapter, entityResolver);
53         this.query = query;
54     }
55
56     protected SelectTranslator createTranslator(Connection JavaDoc connection) {
57         SelectTranslator translator = new SelectTranslator();
58         translator.setQuery(query);
59         translator.setAdapter(adapter);
60         translator.setEntityResolver(getEntityResolver());
61         translator.setConnection(connection);
62         return translator;
63     }
64
65     public void performAction(Connection JavaDoc connection, OperationObserver observer)
66             throws SQLException JavaDoc, Exception JavaDoc {
67
68         long t1 = System.currentTimeMillis();
69
70         SelectTranslator translator = createTranslator(connection);
71         PreparedStatement JavaDoc prepStmt = translator.createStatement();
72         ResultSet JavaDoc rs = prepStmt.executeQuery();
73
74         RowDescriptor descriptor = new RowDescriptor(
75                 translator.getResultColumns(),
76                 getAdapter().getExtendedTypes());
77         JDBCResultIterator workerIterator = new JDBCResultIterator(
78                 connection,
79                 prepStmt,
80                 rs,
81                 descriptor,
82                 query.getFetchLimit());
83
84         workerIterator.setPostProcessor(DataRowPostProcessor
85                 .createPostProcessor(translator));
86
87         ResultIterator it = workerIterator;
88
89         // wrap result iterator if distinct has to be suppressed
90
if (translator.isSuppressingDistinct()) {
91
92             // a joint prefetch warrants full row compare
93

94             final boolean[] compareFullRows = new boolean[1];
95
96             QueryMetadata md = query.getMetaData(getEntityResolver());
97             final PrefetchTreeNode rootPrefetch = md.getPrefetchTree();
98
99             if (rootPrefetch != null) {
100                 rootPrefetch.traverse(new PrefetchProcessor() {
101
102                     public void finishPrefetch(PrefetchTreeNode node) {
103                     }
104
105                     public boolean startDisjointPrefetch(PrefetchTreeNode node) {
106                         // continue to children only if we are at root
107
return rootPrefetch == node;
108                     }
109
110                     public boolean startUnknownPrefetch(PrefetchTreeNode node) {
111                         // continue to children only if we are at root
112
return rootPrefetch == node;
113                     }
114
115                     public boolean startJointPrefetch(PrefetchTreeNode node) {
116                         if (rootPrefetch != node) {
117                             compareFullRows[0] = true;
118                             return false;
119                         }
120
121                         return true;
122                     }
123
124                     public boolean startPhantomPrefetch(PrefetchTreeNode node) {
125                         return true;
126                     }
127                 });
128             }
129
130             it = new DistinctResultIterator(
131                     workerIterator,
132                     translator.getRootDbEntity(),
133                     compareFullRows[0]);
134         }
135
136         // TODO: Should do something about closing ResultSet and PreparedStatement in this
137
// method, instead of relying on DefaultResultIterator to do that later
138

139         if (!observer.isIteratedResult()) {
140             // note that we don't need to close ResultIterator
141
// since "dataRows" will do it internally
142
List JavaDoc resultRows = it.dataRows(true);
143             QueryLogger
144                     .logSelectCount(resultRows.size(), System.currentTimeMillis() - t1);
145
146             observer.nextDataRows(query, resultRows);
147         }
148         else {
149             try {
150                 workerIterator.setClosingConnection(true);
151                 observer.nextDataRows(translator.getQuery(), it);
152             }
153             catch (Exception JavaDoc ex) {
154                 it.close();
155                 throw ex;
156             }
157         }
158     }
159 }
160
Popular Tags