001: /*
002: * Copyright 2003 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package velosurf.sql;
018:
019: import java.sql.ResultSet;
020: import java.sql.SQLException;
021: import java.sql.Statement;
022: import java.util.List;
023: import java.util.Map;
024: import java.util.Set;
025: import java.util.HashSet;
026: import java.util.TreeMap;
027:
028: import velosurf.context.RowIterator;
029: import velosurf.model.Entity;
030: import velosurf.util.Logger;
031:
032: /** this class encapsulates a jdbc Statement.
033: *
034: * @author <a href=mailto:claude.brisson@gmail.com>Claude Brisson</a>
035: *
036: */
037: public class PooledSimpleStatement extends PooledStatement {
038:
039: /** build a new PooledStatement.
040: *
041: * @param connection database connection
042: * @param statement wrapped Statement
043: */
044: public PooledSimpleStatement(ConnectionWrapper connection,
045: Statement statement) {
046: this .connection = connection;
047: this .statement = statement;
048: }
049:
050: /** get the resultset for this statement.
051: *
052: * @param query SQL query
053: * @exception SQLException thrown by the database engine
054: * @return resulting RowIterator
055: */
056: public synchronized RowIterator query(String query)
057: throws SQLException {
058: return query(query, null);
059: }
060:
061: /** get the resultset for this statement, specifying the entity the results belong to.
062: *
063: * @param query SQL query
064: * @param resultEntity entity
065: * @exception SQLException thrown by the database engine
066: * @return the resulting RowIterator
067: */
068: public synchronized RowIterator query(String query,
069: Entity resultEntity) throws SQLException {
070: notifyInUse();
071: Logger.trace("query-" + query);
072: connection.enterBusyState();
073: RowIterator result = new RowIterator(this , statement
074: .executeQuery(query), resultEntity);
075: connection.leaveBusyState();
076: return result;
077: }
078:
079: /** fetch a single row.
080: *
081: * @param query SQL query
082: * @exception SQLException thrown by the database engine
083: * @return fetched row
084: */
085: public synchronized Object fetch(String query) throws SQLException {
086: return fetch(query, null);
087: }
088:
089: /** fetch a single row, specyfing the entity it belongs to.
090: *
091: * @param query SQL query
092: * @param resultEntity entity
093: * @exception SQLException thrown by the database engine
094: * @return the fetched Instance
095: */
096: public synchronized Object fetch(String query, Entity resultEntity)
097: throws SQLException {
098: try {
099: notifyInUse();
100: Logger.trace("fetch-" + query);
101: connection.enterBusyState();
102: resultSet = statement.executeQuery(query);
103: boolean hasNext = resultSet.next();
104: connection.leaveBusyState();
105: Map<String, Object> row = null;
106: if (hasNext) {
107: if (resultEntity != null)
108: row = resultEntity.newInstance(
109: new ReadOnlyMap(this ), true);
110: else {
111: row = new TreeMap<String, Object>();
112: if (columnNames == null) {
113: columnNames = SqlUtil.getColumnNames(resultSet);
114: }
115: for (String column : columnNames) {
116: Object value = resultSet.getObject(column);
117: row.put(Database.adaptContextCase(column),
118: value);
119: }
120: }
121: }
122: return row;
123: } finally {
124: notifyOver();
125: }
126: }
127:
128: /** get specified column as an object.
129: *
130: * @param key column
131: * @exception SQLException thrown by the database engine
132: * @return object value
133: */
134: public Object get(Object key) throws SQLException {
135: if (!(key instanceof String))
136: return null;
137: return resultSet.getObject((String) key);
138: }
139:
140: public Set<String> keySet() throws SQLException {
141: return new HashSet<String>(SqlUtil.getColumnNames(resultSet));
142: }
143:
144: /** evaluates the SQL query as a scalar.
145: *
146: * @param query SQL query
147: * @exception SQLException thrown by the database engine
148: * @return found scalar
149: */
150: public synchronized Object evaluate(String query)
151: throws SQLException {
152: notifyInUse();
153: Logger.trace("evaluate-" + query);
154: Object result = null;
155: ResultSet rs = null;
156: try {
157: connection.enterBusyState();
158: rs = statement.executeQuery(query);
159: boolean hasNext = rs.next();
160: connection.leaveBusyState();
161: if (hasNext)
162: result = rs.getObject(1);
163: } finally {
164: if (rs != null)
165: rs.close();
166: notifyOver();
167: return result;
168: }
169: }
170:
171: /** issue the update contained in the query.
172: *
173: * @param query SQL query
174: * @exception SQLException thrown by the database engine
175: * @return number of affected rows
176: */
177: public synchronized int update(String query) throws SQLException {
178: Logger.trace("update-" + query);
179: connection.enterBusyState();
180: int result = statement.executeUpdate(query);
181: connection.leaveBusyState();
182: return result;
183: }
184:
185: /** close this statement.
186: *
187: * @exception SQLException thrown by the database engine
188: */
189: public void close() throws SQLException {
190: if (statement != null)
191: statement.close();
192: }
193:
194: /** notify this statement is no more used and can be recycled.
195: */
196: public void notifyOver() {
197: super .notifyOver();
198: }
199:
200: /** gets the last insert id.
201: *
202: * @exception SQLException thrown by the database engine
203: * @return last insert id
204: */
205: public long getLastInsertID() throws SQLException {
206: return ((ConnectionWrapper) connection)
207: .getLastInsertId(statement);
208: }
209:
210: /** get statement's Connection.
211: *
212: * @return the Connection object (usually a ConnectionWrapper object)
213: */
214: public ConnectionWrapper getConnection() {
215: return connection;
216: }
217:
218: /** database connection.
219: */
220: private ConnectionWrapper connection = null;
221: /** result set.
222: */
223: private ResultSet resultSet = null;
224: /** column names in natural order.
225: */
226: private List<String> columnNames = null;
227: /** wrapped statement.
228: */
229: private Statement statement = null;
230: }
|