001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029: package com.caucho.db.jdbc;
030:
031: import com.caucho.db.Database;
032: import com.caucho.db.sql.Query;
033: import com.caucho.db.store.Transaction;
034: import com.caucho.log.Log;
035: import com.caucho.util.L10N;
036:
037: import java.sql.Array;
038: import java.sql.Blob;
039: import java.sql.CallableStatement;
040: import java.sql.Clob;
041: import java.sql.NClob;
042: import java.sql.SQLClientInfoException;
043: import java.sql.SQLException;
044: import java.sql.SQLWarning;
045: import java.sql.SQLXML;
046: import java.sql.Savepoint;
047: import java.sql.Statement;
048: import java.sql.Struct;
049: import java.util.ArrayList;
050: import java.util.Map;
051: import java.util.Properties;
052: import java.util.logging.Level;
053: import java.util.logging.Logger;
054:
055: /**
056: * The JDBC connection implementation.
057: */
058: public class ConnectionImpl implements java.sql.Connection {
059: private static final L10N L = new L10N(ConnectionImpl.class);
060: private static final Logger log = Log.open(ConnectionImpl.class);
061:
062: private Database _db;
063: private PooledConnectionImpl _pooledConnection;
064:
065: private boolean _isClosed;
066: private boolean _isAutoCommit = true;
067:
068: private Transaction _xa;
069:
070: private StatementImpl _statement;
071: private ArrayList<StatementImpl> _statements;
072:
073: public ConnectionImpl(PooledConnectionImpl pooledConnection) {
074: _pooledConnection = pooledConnection;
075: _db = pooledConnection.getDatabase();
076:
077: if (_db == null)
078: throw new NullPointerException();
079: }
080:
081: public ConnectionImpl(Database db) {
082: _db = db;
083:
084: if (_db == null)
085: throw new NullPointerException();
086: }
087:
088: Database getDatabase() {
089: return _db;
090: }
091:
092: public void clearWarnings() {
093: }
094:
095: public void setTransaction(Transaction xa) {
096: _xa = xa;
097: }
098:
099: public Transaction getTransaction() {
100: if (_isAutoCommit) {
101: Transaction xa = Transaction.create(this );
102: // XXX: value?
103: // xa.setTransactionTimeout(15000);
104: xa.setAutoCommit(true);
105: return xa;
106: } else if (_xa == null) {
107: _xa = Transaction.create(this );
108:
109: if (log.isLoggable(Level.FINER))
110: log.finer("start transaction " + this + " " + _xa);
111: }
112:
113: _xa.setAutoCommit(false);
114:
115: return _xa;
116: }
117:
118: public void commit() throws SQLException {
119: if (log.isLoggable(Level.FINER))
120: log.finer("commit " + this + " " + _xa);
121:
122: Transaction xa = _xa;
123: _xa = null;
124:
125: if (xa != null)
126: xa.commit();
127: }
128:
129: public void rollback() throws SQLException {
130: Transaction xa = _xa;
131: _xa = null;
132:
133: if (xa != null) {
134: if (log.isLoggable(Level.FINER))
135: log.finer("rollback " + this + " " + _xa);
136:
137: xa.rollback();
138: }
139: }
140:
141: public java.sql.Statement createStatement() throws SQLException {
142: if (_db == null)
143: throw new SQLException(L.l("Connection is already closed"));
144:
145: StatementImpl stmt = new StatementImpl(this );
146:
147: if (_statement == null)
148: _statement = stmt;
149: else {
150: if (_statements == null)
151: _statements = new ArrayList<StatementImpl>();
152: _statements.add(stmt);
153: }
154:
155: return stmt;
156: }
157:
158: public java.sql.Statement createStatement(int resultSetType,
159: int resultSetConcurrency) throws SQLException {
160: return createStatement();
161: }
162:
163: public boolean getAutoCommit() {
164: return _isAutoCommit;
165: }
166:
167: public void setAutoCommit(boolean autoCommit) throws SQLException {
168: if (!_isAutoCommit && autoCommit) {
169: Transaction xa = _xa;
170: _xa = null;
171:
172: if (xa != null)
173: xa.commit();
174: }
175:
176: _isAutoCommit = autoCommit;
177: }
178:
179: public String getCatalog() {
180: return null;
181: }
182:
183: public void setCatalog(String catalog) throws SQLException {
184: }
185:
186: public java.sql.DatabaseMetaData getMetaData() throws SQLException {
187: return new DatabaseMetaDataImpl(this );
188: }
189:
190: public int getTransactionIsolation() {
191: return TRANSACTION_NONE;
192: }
193:
194: public void setTransactionIsolation(int level) {
195: }
196:
197: public Map getTypeMap() {
198: return null;
199: }
200:
201: public void setTypeMap(Map<String, Class<?>> map) {
202: }
203:
204: public SQLWarning getWarnings() {
205: return null;
206: }
207:
208: public boolean isClosed() {
209: return _isClosed;
210: }
211:
212: public boolean isReadOnly() {
213: return false;
214: }
215:
216: public void setReadOnly(boolean readOnly) {
217: }
218:
219: public String nativeSQL(String sql) {
220: return null;
221: }
222:
223: public CallableStatement prepareCall(String sql)
224: throws SQLException {
225: return null;
226: }
227:
228: public CallableStatement prepareCall(String sql, int resultSetType,
229: int resultSetConcurrency) throws SQLException {
230: return null;
231: }
232:
233: public java.sql.PreparedStatement prepareStatement(String sql)
234: throws SQLException {
235: return prepareStatementImpl(sql);
236: }
237:
238: public java.sql.PreparedStatement prepareStatement(String sql,
239: int autoGeneratedKeys) throws SQLException {
240: PreparedStatementImpl pstmt = prepareStatementImpl(sql);
241:
242: if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS)
243: pstmt.setReturnGeneratedKeys(true);
244:
245: return pstmt;
246: }
247:
248: public java.sql.PreparedStatement prepareStatement(String sql,
249: int[] columnIndices) throws SQLException {
250: PreparedStatementImpl pstmt = prepareStatementImpl(sql);
251:
252: pstmt.setReturnGeneratedKeys(true);
253:
254: return pstmt;
255: }
256:
257: public java.sql.PreparedStatement prepareStatement(String sql,
258: String[] columnNames) throws SQLException {
259: PreparedStatementImpl pstmt = prepareStatementImpl(sql);
260:
261: pstmt.setReturnGeneratedKeys(true);
262:
263: return pstmt;
264: }
265:
266: public java.sql.PreparedStatement prepareStatement(String sql,
267: int resultSetType, int resultSetConcurrency)
268: throws SQLException {
269: return prepareStatement(sql);
270: }
271:
272: public java.sql.PreparedStatement prepareStatement(String sql,
273: int resultSetType, int resultSetConcurrency,
274: int resultSetHoldability) throws SQLException {
275: return prepareStatement(sql);
276: }
277:
278: /**
279: * Prepares the statement implementation.
280: */
281: private PreparedStatementImpl prepareStatementImpl(String sql)
282: throws SQLException {
283: Query query = _db.parseQuery(sql);
284:
285: PreparedStatementImpl stmt = new PreparedStatementImpl(this ,
286: query);
287:
288: if (_statement == null)
289: _statement = stmt;
290: else {
291: if (_statements == null)
292: _statements = new ArrayList<StatementImpl>();
293: _statements.add(stmt);
294: }
295:
296: return stmt;
297: }
298:
299: public void rollback(Savepoint savepoint) throws SQLException {
300: }
301:
302: public void releaseSavepoint(Savepoint savepoint)
303: throws SQLException {
304: }
305:
306: public Savepoint setSavepoint(String savepoint) throws SQLException {
307: return null;
308: }
309:
310: public Savepoint setSavepoint() throws SQLException {
311: return null;
312: }
313:
314: public int getHoldability() throws SQLException {
315: return 0;
316: }
317:
318: public void setHoldability(int hold) throws SQLException {
319: }
320:
321: public java.sql.Statement createStatement(int resultSetType,
322: int resultSetConcurrency, int resultSetHoldability)
323: throws SQLException {
324: return createStatement();
325: }
326:
327: public CallableStatement prepareCall(String sql, int resultSetType,
328: int resultSetConcurrency, int holdability)
329: throws SQLException {
330: return null;
331: }
332:
333: void closeStatement(StatementImpl stmt) {
334: if (_statement == stmt)
335: _statement = null;
336:
337: if (_statements != null)
338: _statements.remove(stmt);
339: }
340:
341: public void close() throws SQLException {
342: synchronized (this ) {
343: if (_isClosed)
344: return;
345:
346: _isClosed = true;
347: _db = null;
348: }
349:
350: StatementImpl stmt = _statement;
351: _statement = null;
352:
353: if (stmt != null)
354: _statement = null;
355:
356: if (_statements != null) {
357: for (int i = 0; i < _statements.size(); i++) {
358: stmt = _statements.get(i);
359:
360: stmt.close();
361: }
362: }
363:
364: if (_pooledConnection != null)
365: _pooledConnection.closeEvent(this );
366: }
367:
368: public Clob createClob() throws SQLException {
369: throw new UnsupportedOperationException("Not supported yet.");
370: }
371:
372: public Blob createBlob() throws SQLException {
373: throw new UnsupportedOperationException("Not supported yet.");
374: }
375:
376: public NClob createNClob() throws SQLException {
377: throw new UnsupportedOperationException("Not supported yet.");
378: }
379:
380: public SQLXML createSQLXML() throws SQLException {
381: throw new UnsupportedOperationException("Not supported yet.");
382: }
383:
384: public boolean isValid(int timeout) throws SQLException {
385: throw new UnsupportedOperationException("Not supported yet.");
386: }
387:
388: public void setClientInfo(String name, String value)
389: throws SQLClientInfoException {
390: throw new UnsupportedOperationException("Not supported yet.");
391: }
392:
393: public void setClientInfo(Properties properties)
394: throws SQLClientInfoException {
395: throw new UnsupportedOperationException("Not supported yet.");
396: }
397:
398: public String getClientInfo(String name) throws SQLException {
399: throw new UnsupportedOperationException("Not supported yet.");
400: }
401:
402: public Properties getClientInfo() throws SQLException {
403: throw new UnsupportedOperationException("Not supported yet.");
404: }
405:
406: public Array createArrayOf(String typeName, Object[] elements)
407: throws SQLException {
408: throw new UnsupportedOperationException("Not supported yet.");
409: }
410:
411: public Struct createStruct(String typeName, Object[] attributes)
412: throws SQLException {
413: throw new UnsupportedOperationException("Not supported yet.");
414: }
415:
416: public <T> T unwrap(Class<T> iface) throws SQLException {
417: throw new UnsupportedOperationException("Not supported yet.");
418: }
419:
420: public boolean isWrapperFor(Class<?> iface) throws SQLException {
421: throw new UnsupportedOperationException("Not supported yet.");
422: }
423: }
|