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 package org.apache.openjpa.jdbc.kernel;
20
21 import java.sql.SQLException;
22
23 import org.apache.openjpa.jdbc.sql.Result;
24 import org.apache.openjpa.jdbc.sql.SQLExceptions;
25 import org.apache.openjpa.jdbc.sql.Select;
26 import org.apache.openjpa.jdbc.sql.SelectExecutor;
27 import org.apache.openjpa.lib.rop.ResultObjectProvider;
28 import org.apache.openjpa.util.StoreException;
29
30 /**
31 * Abstract provider implementation wrapped around a {@link Select}.
32 *
33 * @author Abe White
34 * @nojavadoc
35 */
36 public abstract class SelectResultObjectProvider
37 implements ResultObjectProvider {
38
39 private final SelectExecutor _sel;
40 private final JDBCStore _store;
41 private final JDBCFetchConfiguration _fetch;
42 private Result _res = null;
43 private int _size = -1;
44 private Boolean _ra = null;
45
46 /**
47 * Constructor.
48 *
49 * @param sel the select to execute
50 * @param store the store to delegate loading to
51 * @param fetch the fetch configuration, or null for the default
52 */
53 public SelectResultObjectProvider(SelectExecutor sel, JDBCStore store,
54 JDBCFetchConfiguration fetch) {
55 _sel = sel;
56 _store = store;
57 _fetch = fetch;
58 }
59
60 public SelectExecutor getSelect() {
61 return _sel;
62 }
63
64 public JDBCStore getStore() {
65 return _store;
66 }
67
68 public JDBCFetchConfiguration getFetchConfiguration() {
69 return _fetch;
70 }
71
72 public Result getResult() {
73 return _res;
74 }
75
76 public boolean supportsRandomAccess() {
77 if (_ra == null) {
78 boolean ra;
79 if (_res != null) {
80 try {
81 ra = _res.supportsRandomAccess();
82 } catch (SQLException se) {
83 throw SQLExceptions.getStore(se, _store.getDBDictionary());
84 }
85 } else
86 ra = _sel.supportsRandomAccess(_fetch.getReadLockLevel() > 0);
87 _ra = (ra) ? Boolean.TRUE : Boolean.FALSE;
88 }
89 return _ra.booleanValue();
90 }
91
92 public void open()
93 throws SQLException {
94 _res = _sel.execute(_store, _fetch);
95 }
96
97 public boolean next()
98 throws SQLException {
99 return _res.next();
100 }
101
102 public boolean absolute(int pos)
103 throws SQLException {
104 return _res.absolute(pos);
105 }
106
107 public int size()
108 throws SQLException {
109 if (_size == -1) {
110 // if res is null, don't cache size
111 if (_res == null)
112 return Integer.MAX_VALUE;
113
114 switch (_fetch.getLRSSize()) {
115 case LRSSizes.SIZE_UNKNOWN:
116 _size = Integer.MAX_VALUE;
117 break;
118 case LRSSizes.SIZE_LAST:
119 if (supportsRandomAccess())
120 _size = _res.size();
121 else
122 _size = Integer.MAX_VALUE;
123 break;
124 default: // query
125 _size = _sel.getCount(_store);
126 }
127 }
128 return _size;
129 }
130
131 /**
132 * Allow subclasses that know the size to set it; otherwise we calculate
133 * it internally.
134 */
135 protected void setSize(int size) {
136 if (_size == -1)
137 _size = size;
138 }
139
140 public void reset()
141 throws SQLException {
142 close();
143 open();
144 }
145
146 public void close() {
147 if (_res != null) {
148 _res.close();
149 _res = null;
150 }
151 }
152
153 public void handleCheckedException(Exception e) {
154 if (e instanceof SQLException)
155 throw SQLExceptions.getStore((SQLException) e,
156 _store.getDBDictionary());
157 throw new StoreException(e);
158 }
159 }