001: /*
002: * Craftsman Spy.
003: * Copyright (C) 2005 Sébastien LECACHEUR
004: *
005: * This program is free software; you can redistribute it and/or modify
006: * it under the terms of the GNU General Public License as published by
007: * the Free Software Foundation; either version 2 of the License, or
008: * (at your option) any later version.
009: *
010: * This program is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU General Public License for more details.
014: *
015: * You should have received a copy of the GNU General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: */
019: package craftsman.spy;
020:
021: import java.sql.CallableStatement;
022: import java.sql.Connection;
023: import java.sql.DatabaseMetaData;
024: import java.sql.PreparedStatement;
025: import java.sql.ResultSet;
026: import java.sql.SQLException;
027: import java.sql.SQLWarning;
028: import java.sql.Savepoint;
029: import java.sql.Statement;
030: import java.util.Map;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: /**
036: * This classe represents the JDBC connection to the database.
037: *
038: * @author Sébastien LECACHEUR
039: */
040: public class SpyConnection implements Connection {
041: /**
042: * Internal used logger.
043: */
044: protected Log log = LogFactory.getLog(this .getClass().getName());
045:
046: /**
047: * The real JDBC connection instance.
048: */
049: private Connection real = null;
050:
051: /**
052: * The JDBC connection ID.
053: */
054: private int id = 0;
055:
056: /**
057: * Constructs a new Spy JDBC connection.
058: * @param con Connection The real JDBC connection.
059: * @param conIdSql String The SQL string to execute
060: * in order to retrieve the real JDBC connection ID.
061: */
062: protected SpyConnection(Connection con, String conIdSql) {
063: real = con;
064: id = hashCode();
065:
066: if (conIdSql != null) {
067: try {
068: Statement s = con.createStatement();
069: ResultSet r = s.executeQuery(conIdSql);
070: if (r.next()) {
071: id = r.getInt(1);
072: }
073: r.close();
074: s.close();
075: } catch (SQLException e) {
076: e.printStackTrace();
077: }
078: }
079: }
080:
081: /**
082: * Returns the used JDBC connection identifier.
083: * @return int The JDBC connection SPID or hash code
084: * otherwise <code>0</code>.
085: */
086: protected int getId() {
087: return id;
088: }
089:
090: /**
091: * @see Connection#getHoldability()
092: */
093: public int getHoldability() throws SQLException {
094: return real.getHoldability();
095: }
096:
097: /**
098: * @see Connection#getTransactionIsolation()
099: */
100: public int getTransactionIsolation() throws SQLException {
101: return real.getTransactionIsolation();
102: }
103:
104: /**
105: * @see Connection#clearWarnings()
106: */
107: public void clearWarnings() throws SQLException {
108: real.clearWarnings();
109: }
110:
111: /**
112: * @see Connection#close()
113: */
114: public void close() throws SQLException {
115: real.close();
116: }
117:
118: /**
119: * @see Connection#commit()
120: */
121: public void commit() throws SQLException {
122: long end, start = System.currentTimeMillis();
123:
124: try {
125: real.commit();
126: end = System.currentTimeMillis();
127: if (log.isInfoEnabled())
128: log.info(getId() + ":commit succeed (" + (end - start)
129: + " ms)");
130: } catch (SQLException e) {
131: end = System.currentTimeMillis();
132: if (log.isErrorEnabled())
133: log.error(getId() + ":commit failed state="
134: + e.getSQLState() + ",code=" + e.getErrorCode()
135: + " (" + (end - start) + " ms)", e);
136: throw e;
137: }
138: }
139:
140: /**
141: * @see Connection#rollback()
142: */
143: public void rollback() throws SQLException {
144: long end, start = System.currentTimeMillis();
145:
146: try {
147: real.rollback();
148: end = System.currentTimeMillis();
149: if (log.isInfoEnabled())
150: log.info(getId() + ":rollback succeed ("
151: + (end - start) + " ms)");
152: } catch (SQLException e) {
153: end = System.currentTimeMillis();
154: if (log.isErrorEnabled())
155: log.error(getId() + ":rollback failed state="
156: + e.getSQLState() + ",code=" + e.getErrorCode()
157: + " (" + (end - start) + " ms)", e);
158: throw e;
159: }
160: }
161:
162: /**
163: * @see Connection#getAutoCommit()
164: */
165: public boolean getAutoCommit() throws SQLException {
166: return real.getAutoCommit();
167: }
168:
169: /**
170: * @see Connection#isClosed()
171: */
172: public boolean isClosed() throws SQLException {
173: return real.isClosed();
174: }
175:
176: /**
177: * @see Connection#isReadOnly()
178: */
179: public boolean isReadOnly() throws SQLException {
180: return real.isReadOnly();
181: }
182:
183: /**
184: * @see Connection#setHoldability(int)
185: */
186: public void setHoldability(int holdability) throws SQLException {
187: real.setHoldability(holdability);
188: }
189:
190: /**
191: * @see Connection#setTransactionIsolation(int)
192: */
193: public void setTransactionIsolation(int level) throws SQLException {
194: real.setTransactionIsolation(level);
195: }
196:
197: /**
198: * @see Connection#setAutoCommit(boolean)
199: */
200: public void setAutoCommit(boolean autoCommit) throws SQLException {
201: long end, start = System.currentTimeMillis();
202:
203: try {
204: real.setAutoCommit(autoCommit);
205: end = System.currentTimeMillis();
206: if (log.isInfoEnabled())
207: log.info(getId() + ":autocommit(" + autoCommit
208: + ") succeed (" + (end - start) + " ms)");
209: } catch (SQLException e) {
210: end = System.currentTimeMillis();
211: if (log.isErrorEnabled())
212: log.error(getId() + ":autocommit(" + autoCommit
213: + ") failed state=" + e.getSQLState()
214: + ",code=" + e.getErrorCode() + " ("
215: + (end - start) + " ms)", e);
216: throw e;
217: }
218: }
219:
220: /**
221: * @see Connection#setReadOnly(boolean)
222: */
223: public void setReadOnly(boolean readOnly) throws SQLException {
224: real.setReadOnly(readOnly);
225: }
226:
227: /**
228: * @see Connection#getCatalog()
229: */
230: public String getCatalog() throws SQLException {
231: return real.getCatalog();
232: }
233:
234: /**
235: * @see Connection#setCatalog(java.lang.String)
236: */
237: public void setCatalog(String catalog) throws SQLException {
238: real.setCatalog(catalog);
239: }
240:
241: /**
242: * @see Connection#getMetaData()
243: */
244: public DatabaseMetaData getMetaData() throws SQLException {
245: return real.getMetaData();
246: }
247:
248: /**
249: * @see Connection#getWarnings()
250: */
251: public SQLWarning getWarnings() throws SQLException {
252: SQLWarning current, sw = real.getWarnings();
253:
254: if ((current = sw) != null) {
255: do {
256: if (log.isInfoEnabled())
257: log.info(getId() + ":sql warning state="
258: + current.getSQLState() + ",code="
259: + current.getErrorCode() + ",message="
260: + current.getMessage());
261: } while ((current = current.getNextWarning()) != null);
262: }
263:
264: return sw;
265: }
266:
267: /**
268: * @see Connection#setSavepoint()
269: */
270: public Savepoint setSavepoint() throws SQLException {
271: long end, start = System.currentTimeMillis();
272: Savepoint savepoint = null;
273:
274: try {
275: savepoint = real.setSavepoint();
276: end = System.currentTimeMillis();
277: if (log.isInfoEnabled())
278: log.info(getId() + ":savepoint("
279: + savepoint.getSavepointName() + ") succeed ("
280: + (end - start) + " ms)");
281: } catch (SQLException e) {
282: end = System.currentTimeMillis();
283: if (log.isErrorEnabled())
284: log.error(getId() + ":savepoint(" + "unnamed"
285: + ") failed state=" + e.getSQLState()
286: + ",code=" + e.getErrorCode() + " ("
287: + (end - start) + " ms)", e);
288: throw e;
289: }
290:
291: return savepoint;
292: }
293:
294: /**
295: * @see Connection#releaseSavepoint(java.sql.Savepoint)
296: */
297: public void releaseSavepoint(Savepoint savepoint)
298: throws SQLException {
299: long end, start = System.currentTimeMillis();
300:
301: try {
302: real.releaseSavepoint(savepoint);
303: end = System.currentTimeMillis();
304: if (log.isInfoEnabled())
305: log.info(getId() + ":savepoint("
306: + savepoint.getSavepointName() + ") succeed ("
307: + (end - start) + " ms)");
308: } catch (SQLException e) {
309: end = System.currentTimeMillis();
310: if (log.isErrorEnabled())
311: log.error(getId() + ":release savepoint("
312: + savepoint.getSavepointName()
313: + ") failed state=" + e.getSQLState()
314: + ",code=" + e.getErrorCode() + " ("
315: + (end - start) + " ms)", e);
316: throw e;
317: }
318: }
319:
320: /**
321: * @see Connection#rollback(java.sql.Savepoint)
322: */
323: public void rollback(Savepoint savepoint) throws SQLException {
324: real.rollback(savepoint);
325: }
326:
327: /**
328: * @see Connection#createStatement()
329: */
330: public Statement createStatement() throws SQLException {
331: return new SpyStatement(this , real.createStatement());
332: }
333:
334: /**
335: * @see Connection#createStatement(int, int)
336: */
337: public Statement createStatement(int resultSetType,
338: int resultSetConcurrency) throws SQLException {
339: return new SpyStatement(this , real.createStatement(
340: resultSetType, resultSetConcurrency));
341: }
342:
343: /**
344: * @see Connection#createStatement(int, int, int)
345: */
346: public Statement createStatement(int resultSetType,
347: int resultSetConcurrency, int resultSetHoldability)
348: throws SQLException {
349: return new SpyStatement(this , real.createStatement(
350: resultSetType, resultSetConcurrency,
351: resultSetHoldability));
352: }
353:
354: /**
355: * @see Connection#getTypeMap()
356: */
357: public Map getTypeMap() throws SQLException {
358: return real.getTypeMap();
359: }
360:
361: /**
362: * @see Connection#setTypeMap(java.util.Map)
363: */
364: public void setTypeMap(Map map) throws SQLException {
365: real.setTypeMap(map);
366: }
367:
368: /**
369: * @see Connection#nativeSQL(java.lang.String)
370: */
371: public String nativeSQL(String sql) throws SQLException {
372: return real.nativeSQL(sql);
373: }
374:
375: /**
376: * @see Connection#prepareCall(java.lang.String)
377: */
378: public CallableStatement prepareCall(String sql)
379: throws SQLException {
380: return new SpyCallableStatement(this , real.prepareCall(sql),
381: sql);
382: }
383:
384: /**
385: * @see Connection#prepareCall(java.lang.String, int, int)
386: */
387: public CallableStatement prepareCall(String sql, int resultSetType,
388: int resultSetConcurrency) throws SQLException {
389: return new SpyCallableStatement(this , real.prepareCall(sql,
390: resultSetType, resultSetConcurrency), sql);
391: }
392:
393: /**
394: * @see Connection#prepareCall(java.lang.String, int, int, int)
395: */
396: public CallableStatement prepareCall(String sql, int resultSetType,
397: int resultSetConcurrency, int resultSetHoldability)
398: throws SQLException {
399: return new SpyCallableStatement(this , real.prepareCall(sql,
400: resultSetType, resultSetConcurrency,
401: resultSetHoldability), sql);
402: }
403:
404: /**
405: * @see Connection#prepareStatement(java.lang.String)
406: */
407: public PreparedStatement prepareStatement(String sql)
408: throws SQLException {
409: return new SpyPreparedStatement(this , real
410: .prepareStatement(sql), sql);
411: }
412:
413: /**
414: * @see Connection#prepareStatement(java.lang.String, int)
415: */
416: public PreparedStatement prepareStatement(String sql,
417: int autoGeneratedKeys) throws SQLException {
418: return new SpyPreparedStatement(this , real.prepareStatement(
419: sql, autoGeneratedKeys), sql);
420: }
421:
422: /**
423: * @see Connection#prepareStatement(java.lang.String, int, int)
424: */
425: public PreparedStatement prepareStatement(String sql,
426: int resultSetType, int resultSetConcurrency)
427: throws SQLException {
428: return new SpyPreparedStatement(this , real.prepareStatement(
429: sql, resultSetType, resultSetConcurrency), sql);
430: }
431:
432: /**
433: * @see Connection#prepareStatement(java.lang.String, int, int, int)
434: */
435: public PreparedStatement prepareStatement(String sql,
436: int resultSetType, int resultSetConcurrency,
437: int resultSetHoldability) throws SQLException {
438: return new SpyPreparedStatement(this , real.prepareStatement(
439: sql, resultSetType, resultSetConcurrency,
440: resultSetHoldability), sql);
441: }
442:
443: /**
444: * @see Connection#prepareStatement(java.lang.String, int[])
445: */
446: public PreparedStatement prepareStatement(String sql,
447: int[] columnIndexes) throws SQLException {
448: return new SpyPreparedStatement(this , real.prepareStatement(
449: sql, columnIndexes), sql);
450: }
451:
452: /**
453: * @see Connection#setSavepoint(java.lang.String)
454: */
455: public Savepoint setSavepoint(String name) throws SQLException {
456: long end, start = System.currentTimeMillis();
457: Savepoint savepoint = null;
458:
459: try {
460: savepoint = real.setSavepoint(name);
461: end = System.currentTimeMillis();
462: if (log.isInfoEnabled())
463: log.info(getId() + ":savepoint(" + name + ") succeed ("
464: + (end - start) + " ms)");
465: } catch (SQLException e) {
466: end = System.currentTimeMillis();
467: if (log.isErrorEnabled())
468: log.error(getId() + ":savepoint(" + name
469: + ") failed state=" + e.getSQLState()
470: + ",code=" + e.getErrorCode() + " ("
471: + (end - start) + " ms)", e);
472: throw e;
473: }
474:
475: return savepoint;
476: }
477:
478: /**
479: * @see Connection#prepareStatement(java.lang.String, java.lang.String[])
480: */
481: public PreparedStatement prepareStatement(String sql,
482: String[] columnNames) throws SQLException {
483: return new SpyPreparedStatement(this, real.prepareStatement(
484: sql, columnNames), sql);
485: }
486: }
|