Home » apache-openjpa-1.1.0-source » org.apache.openjpa.lib » jdbc » [javadoc | source]
    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.lib.jdbc;
   20   
   21   import java.io.InputStream;
   22   import java.io.Reader;
   23   import java.math.BigDecimal;
   24   import java.sql.Array;
   25   import java.sql.BatchUpdateException;
   26   import java.sql.Blob;
   27   import java.sql.Clob;
   28   import java.sql.Connection;
   29   import java.sql.DatabaseMetaData;
   30   import java.sql.Date;
   31   import java.sql.PreparedStatement;
   32   import java.sql.Ref;
   33   import java.sql.ResultSet;
   34   import java.sql.ResultSetMetaData;
   35   import java.sql.SQLException;
   36   import java.sql.SQLWarning;
   37   import java.sql.Savepoint;
   38   import java.sql.Statement;
   39   import java.sql.Time;
   40   import java.sql.Timestamp;
   41   import java.util.ArrayList;
   42   import java.util.Arrays;
   43   import java.util.Calendar;
   44   import java.util.Iterator;
   45   import java.util.List;
   46   
   47   import org.apache.openjpa.lib.log.Log;
   48   import org.apache.openjpa.lib.util.J2DoPrivHelper;
   49   
   50   /**
   51    * A {@link ConnectionDecorator} that creates logging connections and
   52    * {@link ReportingSQLException}s.
   53    *
   54    * @author Marc Prud'hommeaux
   55    * @nojavadoc
   56    */
   57   public class LoggingConnectionDecorator implements ConnectionDecorator {
   58   
   59       private static final String SEP = J2DoPrivHelper.getLineSeparator();
   60   
   61       private static final int WARN_IGNORE = 0;
   62       private static final int WARN_LOG_TRACE = 1;
   63       private static final int WARN_LOG_INFO = 2;
   64       private static final int WARN_LOG_WARN = 3;
   65       private static final int WARN_LOG_ERROR = 4;
   66       private static final int WARN_THROW = 5;
   67       private static final int WARN_HANDLE = 6;
   68       private static final String[] WARNING_ACTIONS = new String[7];
   69   
   70       static {
   71           WARNING_ACTIONS[WARN_IGNORE] = "ignore";
   72           WARNING_ACTIONS[WARN_LOG_TRACE] = "trace";
   73           WARNING_ACTIONS[WARN_LOG_INFO] = "info";
   74           WARNING_ACTIONS[WARN_LOG_WARN] = "warn";
   75           WARNING_ACTIONS[WARN_LOG_ERROR] = "error";
   76           WARNING_ACTIONS[WARN_THROW] = "throw";
   77           WARNING_ACTIONS[WARN_HANDLE] = "handle";
   78       }
   79   
   80       private final DataSourceLogs _logs = new DataSourceLogs();
   81       private SQLFormatter _formatter;
   82       private boolean _prettyPrint;
   83       private int _prettyPrintLineLength = 60;
   84       private int _warningAction = WARN_IGNORE;
   85       private SQLWarningHandler _warningHandler;
   86       private boolean _trackParameters = true;
   87   
   88       /**
   89        * If set to <code>true</code>, pretty-print SQL by running it
   90        * through {@link SQLFormatter#prettyPrint}. If
   91        * <code>false</code>, don't pretty-print, and output SQL logs in
   92        * a single line. Pretty-printed SQL can be easier for a human to
   93        * read, but is harder to parse with tools like grep.
   94        */
   95       public void setPrettyPrint(boolean prettyPrint) {
   96           _prettyPrint = prettyPrint;
   97           if (_formatter == null && _prettyPrint) {
   98               _formatter = new SQLFormatter();
   99               _formatter.setLineLength(_prettyPrintLineLength);
  100           } else if (!_prettyPrint)
  101               _formatter = null;
  102       }
  103   
  104       /**
  105        * @see #setPrettyPrint
  106        */
  107       public boolean getPrettyPrint() {
  108           return _prettyPrint;
  109       }
  110   
  111       /**
  112        * The number of characters to print per line when
  113        * pretty-printing of SQL is enabled. Defaults to 60 to provide
  114        * some space for any ant-related characters on the left of a
  115        * standard 80-character display.
  116        */
  117       public void setPrettyPrintLineLength(int length) {
  118           _prettyPrintLineLength = length;
  119           if (_formatter != null)
  120               _formatter.setLineLength(length);
  121       }
  122   
  123       /**
  124        * @see #setPrettyPrintLineLength
  125        */
  126       public int getPrettyPrintLineLength() {
  127           return _prettyPrintLineLength;
  128       }
  129   
  130       /**
  131        * Whether to track parameters for the purposes of reporting exceptions.
  132        */
  133       public void setTrackParameters(boolean trackParameters) {
  134           _trackParameters = trackParameters;
  135       }
  136   
  137       /**
  138        * Whether to track parameters for the purposes of reporting exceptions.
  139        */
  140       public boolean getTrackParameters() {
  141           return _trackParameters;
  142       }
  143   
  144       /**
  145        * What to do with SQL warnings.
  146        */
  147       public void setWarningAction(String warningAction) {
  148           int index = Arrays.asList(WARNING_ACTIONS).indexOf(warningAction);
  149           if (index < 0)
  150               index = WARN_IGNORE;
  151           _warningAction = index;
  152       }
  153   
  154       /**
  155        * What to do with SQL warnings.
  156        */
  157       public String getWarningAction() {
  158           return WARNING_ACTIONS[_warningAction];
  159       }
  160   
  161       /**
  162        * What to do with SQL warnings.
  163        */
  164       public void setWarningHandler(SQLWarningHandler warningHandler) {
  165           _warningHandler = warningHandler;
  166       }
  167   
  168       /**
  169        * What to do with SQL warnings.
  170        */
  171       public SQLWarningHandler getWarningHandler() {
  172           return _warningHandler;
  173       }
  174   
  175       /**
  176        * The log to write to.
  177        */
  178       public DataSourceLogs getLogs() {
  179           return _logs;
  180       }
  181   
  182       public Connection decorate(Connection conn) throws SQLException {
  183           return new LoggingConnection(conn);
  184       }
  185   
  186       /**
  187        * Include SQL in exception.
  188        */
  189       private SQLException wrap(SQLException sqle, Statement stmnt) {
  190           if (sqle instanceof ReportingSQLException)
  191               return (ReportingSQLException) sqle;
  192           return new ReportingSQLException(sqle, stmnt);
  193       }
  194   
  195       /**
  196        * Include SQL in exception.
  197        */
  198       private SQLException wrap(SQLException sqle, String sql) {
  199           if (sqle instanceof ReportingSQLException)
  200               return (ReportingSQLException) sqle;
  201           return new ReportingSQLException(sqle, sql);
  202       }
  203   
  204       /**
  205        * Interface that allows customization of what to do when
  206        * {@link SQLWarning}s occur.
  207        */
  208       public static interface SQLWarningHandler {
  209   
  210           public void handleWarning(SQLWarning warning) throws SQLException;
  211       }
  212   
  213       /**
  214        * Logging connection.
  215        */
  216       private class LoggingConnection extends DelegatingConnection {
  217   
  218           public LoggingConnection(Connection conn) throws SQLException {
  219               super(conn);
  220           }
  221   
  222           protected PreparedStatement prepareStatement(String sql, boolean wrap)
  223               throws SQLException {
  224               try {
  225                   PreparedStatement stmnt = super.prepareStatement(sql, false);
  226                   return new LoggingPreparedStatement(stmnt, sql);
  227               } catch (SQLException se) {
  228                   throw wrap(se, sql);
  229               }
  230           }
  231   
  232           protected PreparedStatement prepareStatement(String sql, int rsType,
  233               int rsConcur, boolean wrap) throws SQLException {
  234               try {
  235                   PreparedStatement stmnt = super.prepareStatement
  236                       (sql, rsType, rsConcur, false);
  237                   return new LoggingPreparedStatement(stmnt, sql);
  238               } catch (SQLException se) {
  239                   throw wrap(se, sql);
  240               }
  241           }
  242   
  243           protected Statement createStatement(boolean wrap) throws SQLException {
  244               Statement stmnt = super.createStatement(false);
  245               return new LoggingStatement(stmnt);
  246           }
  247   
  248           protected Statement createStatement(int type, int concurrency,
  249               boolean wrap) throws SQLException {
  250               Statement stmnt = super.createStatement(type, concurrency, false);
  251               return new LoggingStatement(stmnt);
  252           }
  253   
  254           public void commit() throws SQLException {
  255               long start = System.currentTimeMillis();
  256               try {
  257                   super.commit();
  258               } finally {
  259                   if (_logs.isJDBCEnabled())
  260                       _logs.logJDBC("commit", start, this);
  261                   handleSQLWarning();
  262               }
  263           }
  264   
  265           public void rollback() throws SQLException {
  266               long start = System.currentTimeMillis();
  267               try {
  268                   super.rollback();
  269               } finally {
  270                   if (_logs.isJDBCEnabled())
  271                       _logs.logJDBC("rollback", start, this);
  272                   handleSQLWarning();
  273               }
  274           }
  275   
  276           public void close() throws SQLException {
  277               long start = System.currentTimeMillis();
  278               try {
  279                   super.close();
  280               } finally {
  281                   if (_logs.isJDBCEnabled())
  282                       _logs.logJDBC("close", start, this);
  283               }
  284           }
  285   
  286           public Savepoint setSavepoint() throws SQLException {
  287               long start = System.currentTimeMillis();
  288               try {
  289                   return super.setSavepoint();
  290               } finally {
  291                   if (_logs.isJDBCEnabled())
  292                       _logs.logJDBC("savepoint", start, this);
  293                   handleSQLWarning();
  294               }
  295           }
  296   
  297           public Savepoint setSavepoint(String name) throws SQLException {
  298               long start = System.currentTimeMillis();
  299               try {
  300                   return super.setSavepoint(name);
  301               } finally {
  302                   if (_logs.isJDBCEnabled())
  303                       _logs.logJDBC("savepoint: " + name, start, this);
  304                   handleSQLWarning();
  305               }
  306           }
  307   
  308           public void rollback(Savepoint savepoint) throws SQLException {
  309               long start = System.currentTimeMillis();
  310               try {
  311                   super.rollback(savepoint);
  312               } finally {
  313                   if (_logs.isJDBCEnabled()) {
  314                       String name = null;
  315                       try {
  316                           name = savepoint.getSavepointName();
  317                       } catch (SQLException sqe) {
  318                           name = String.valueOf(savepoint.getSavepointId());
  319                       }
  320                       _logs.logJDBC("rollback: " + name, start, this);
  321                   }
  322                   handleSQLWarning();
  323               }
  324           }
  325   
  326           public void releaseSavepoint(Savepoint savepoint) throws SQLException {
  327               long start = System.currentTimeMillis();
  328               try {
  329                   super.releaseSavepoint(savepoint);
  330               } finally {
  331                   if (_logs.isJDBCEnabled()) {
  332                       String name = null;
  333                       try {
  334                           name = savepoint.getSavepointName();
  335                       } catch (SQLException sqe) {
  336                           name = String.valueOf(savepoint.getSavepointId());
  337                       }
  338                       _logs.logJDBC("release: " + name, start, this);
  339                   }
  340                   handleSQLWarning();
  341               }
  342           }
  343   
  344           protected Statement createStatement(int resultSetType,
  345               int resultSetConcurrency, int resultSetHoldability, boolean wrap)
  346               throws SQLException {
  347               Statement stmnt = super.createStatement(resultSetType,
  348                   resultSetConcurrency, resultSetHoldability, false);
  349               handleSQLWarning();
  350               return new LoggingStatement(stmnt);
  351           }
  352   
  353           protected PreparedStatement prepareStatement(String sql,
  354               int resultSetType, int resultSetConcurrency,
  355               int resultSetHoldability, boolean wrap) throws SQLException {
  356               try {
  357                   PreparedStatement stmnt = super.prepareStatement
  358                       (sql, resultSetType, resultSetConcurrency,
  359                           resultSetHoldability, false);
  360                   handleSQLWarning();
  361                   return new LoggingPreparedStatement(stmnt, sql);
  362               } catch (SQLException se) {
  363                   throw wrap(se, sql);
  364               }
  365           }
  366   
  367           protected PreparedStatement prepareStatement(String sql,
  368               int autoGeneratedKeys, boolean wrap) throws SQLException {
  369               try {
  370                   PreparedStatement stmnt = super.prepareStatement
  371                       (sql, autoGeneratedKeys, false);
  372                   handleSQLWarning();
  373                   return new LoggingPreparedStatement(stmnt, sql);
  374               } catch (SQLException se) {
  375                   throw wrap(se, sql);
  376               }
  377           }
  378   
  379           protected PreparedStatement prepareStatement(String sql,
  380               int[] columnIndexes, boolean wrap) throws SQLException {
  381               try {
  382                   PreparedStatement stmnt = super.prepareStatement
  383                       (sql, columnIndexes, false);
  384                   handleSQLWarning();
  385                   return new LoggingPreparedStatement(stmnt, sql);
  386               } catch (SQLException se) {
  387                   throw wrap(se, sql);
  388               }
  389           }
  390   
  391           protected PreparedStatement prepareStatement(String sql,
  392               String[] columnNames, boolean wrap) throws SQLException {
  393               try {
  394                   PreparedStatement stmnt = super.prepareStatement
  395                       (sql, columnNames, false);
  396                   handleSQLWarning();
  397                   return new LoggingPreparedStatement(stmnt, sql);
  398               } catch (SQLException se) {
  399                   throw wrap(se, sql);
  400               }
  401           }
  402   
  403           protected DatabaseMetaData getMetaData(boolean wrap)
  404               throws SQLException {
  405               return new LoggingDatabaseMetaData(super.getMetaData(false));
  406           }
  407   
  408           /**
  409            * Log time elapsed since given start.
  410            */
  411           private void logTime(long startTime) throws SQLException {
  412               if (_logs.isSQLEnabled())
  413                   _logs.logSQL("spent", startTime, this); 
  414           }
  415   
  416           /**
  417            * Log time elapsed since given start.
  418            */
  419           private void logSQL(Statement stmnt) throws SQLException {
  420               if (_logs.isSQLEnabled())
  421                   _logs.logSQL("executing " + stmnt, this);
  422           }
  423   
  424           /**
  425            * Log time elapsed since given start.
  426            */
  427           private void logBatchSQL(Statement stmnt) throws SQLException {
  428               if (_logs.isSQLEnabled())
  429                   _logs.logSQL("executing batch " + stmnt, this);
  430           }
  431   
  432           /**
  433            * Handle any {@link SQLWarning}s on the current {@link Connection}.
  434            *
  435            * @see #handleSQLWarning(SQLWarning)
  436            */
  437           private void handleSQLWarning() throws SQLException {
  438               if (_warningAction == WARN_IGNORE)
  439                   return;
  440   
  441               try {
  442                   handleSQLWarning(getWarnings());
  443               } finally {
  444                   clearWarnings();
  445               }
  446           }
  447   
  448           /**
  449            * Handle any {@link SQLWarning}s on the specified {@link Statement}.
  450            *
  451            * @see #handleSQLWarning(SQLWarning)
  452            */
  453           private void handleSQLWarning(Statement stmnt) throws SQLException {
  454               if (_warningAction == WARN_IGNORE)
  455                   return;
  456   
  457               try {
  458                   handleSQLWarning(stmnt.getWarnings());
  459               } finally {
  460                   stmnt.clearWarnings();
  461               }
  462           }
  463   
  464           /**
  465            * Handle any {@link SQLWarning}s on the specified {@link ResultSet}.
  466            *
  467            * @see #handleSQLWarning(SQLWarning)
  468            */
  469           private void handleSQLWarning(ResultSet rs) throws SQLException {
  470               if (_warningAction == WARN_IGNORE)
  471                   return;
  472   
  473               try {
  474                   handleSQLWarning(rs.getWarnings());
  475               } finally {
  476                   rs.clearWarnings();
  477               }
  478           }
  479   
  480           /**
  481            * Handle the specified {@link SQLWarning} depending on the
  482            * setting of the {@link #setWarningAction} attribute.
  483            *
  484            * @param warning the warning to handle
  485            */
  486           private void handleSQLWarning(SQLWarning warning) throws SQLException {
  487               if (warning == null)
  488                   return;
  489               if (_warningAction == WARN_IGNORE)
  490                   return;
  491   
  492               Log log = _logs.getJDBCLog();
  493               for (; warning != null; warning = warning.getNextWarning()) {
  494                   switch (_warningAction) {
  495                       case WARN_LOG_TRACE:
  496                           if (log.isTraceEnabled())
  497                               log.trace(warning);
  498                           break;
  499                       case WARN_LOG_INFO:
  500                           if (log.isInfoEnabled())
  501                               log.info(warning);
  502                           break;
  503                       case WARN_LOG_WARN:
  504                           if (log.isWarnEnabled())
  505                               log.warn(warning);
  506                           break;
  507                       case WARN_LOG_ERROR:
  508                           if (log.isErrorEnabled())
  509                               log.error(warning);
  510                           break;
  511                       case WARN_THROW:
  512                           // just throw it as if it were a SQLException
  513                           throw warning;
  514                       case WARN_HANDLE:
  515                           if (_warningHandler != null)
  516                               _warningHandler.handleWarning(warning);
  517                           break;
  518                       default:
  519                           // ignore
  520                           break;
  521                   }
  522               }
  523           }
  524   
  525           /**
  526            * Metadata wrapper that logs actions.
  527            */
  528           private class LoggingDatabaseMetaData
  529               extends DelegatingDatabaseMetaData {
  530   
  531               public LoggingDatabaseMetaData(DatabaseMetaData meta) {
  532                   super(meta, LoggingConnection.this);
  533               }
  534   
  535               public ResultSet getBestRowIdentifier(String catalog,
  536                   String schema, String table, int scope, boolean nullable)
  537                   throws SQLException {
  538                   if (_logs.isJDBCEnabled())
  539                       _logs.logJDBC("getBestRowIdentifier: "
  540                           + catalog + ", " + schema + ", " + table,
  541                           LoggingConnection.this);
  542                   return super.getBestRowIdentifier(catalog, schema,
  543                       table, scope, nullable);
  544               }
  545   
  546               public ResultSet getCatalogs() throws SQLException {
  547                   if (_logs.isJDBCEnabled())
  548                       _logs.logJDBC("getCatalogs", LoggingConnection.this);
  549                   return super.getCatalogs();
  550               }
  551   
  552               public ResultSet getColumnPrivileges(String catalog, String schema,
  553                   String table, String columnNamePattern) throws SQLException {
  554                   if (_logs.isJDBCEnabled())
  555                       _logs.logJDBC("getColumnPrivileges: "
  556                           + catalog + ", " + schema + ", " + table,
  557                           LoggingConnection.this);
  558                   return super.getColumnPrivileges(catalog, schema,
  559                       table, columnNamePattern);
  560               }
  561   
  562               public ResultSet getColumns(String catalog, String schemaPattern,
  563                   String tableNamePattern, String columnNamePattern)
  564                   throws SQLException {
  565                   if (_logs.isJDBCEnabled())
  566                       _logs.logJDBC("getColumns: "
  567                           + catalog + ", " + schemaPattern + ", "
  568                           + tableNamePattern + ", " + columnNamePattern,
  569                           LoggingConnection.this);
  570                   return super.getColumns(catalog, schemaPattern,
  571                       tableNamePattern, columnNamePattern);
  572               }
  573   
  574               public ResultSet getCrossReference(String primaryCatalog,
  575                   String primarySchema, String primaryTable,
  576                   String foreignCatalog, String foreignSchema,
  577                   String foreignTable) throws SQLException {
  578                   if (_logs.isJDBCEnabled())
  579                       _logs.logJDBC("getCrossReference: "
  580                           + primaryCatalog + ", " + primarySchema + ", "
  581                           + primaryTable + ", " + foreignCatalog + ", "
  582                           + foreignSchema + ", " + foreignSchema,
  583                           LoggingConnection.this);
  584                   return super.getCrossReference(primaryCatalog, primarySchema,
  585                       primaryTable, foreignCatalog, foreignSchema, foreignTable);
  586               }
  587   
  588               public ResultSet getExportedKeys(String catalog, String schema,
  589                   String table) throws SQLException {
  590                   if (_logs.isJDBCEnabled())
  591                       _logs.logJDBC("getExportedKeys: "
  592                           + catalog + ", " + schema + ", " + table,
  593                           LoggingConnection.this);
  594                   return super.getExportedKeys(catalog, schema, table);
  595               }
  596   
  597               public ResultSet getImportedKeys(String catalog, String schema,
  598                   String table) throws SQLException {
  599                   if (_logs.isJDBCEnabled())
  600                       _logs.logJDBC("getImportedKeys: "
  601                           + catalog + ", " + schema + ", " + table,
  602                           LoggingConnection.this);
  603                   return super.getImportedKeys(catalog, schema, table);
  604               }
  605   
  606               public ResultSet getIndexInfo(String catalog, String schema,
  607                   String table, boolean unique, boolean approximate)
  608                   throws SQLException {
  609                   if (_logs.isJDBCEnabled())
  610                       _logs.logJDBC("getIndexInfo: "
  611                           + catalog + ", " + schema + ", " + table,
  612                           LoggingConnection.this);
  613                   return super.getIndexInfo(catalog, schema, table, unique,
  614                       approximate);
  615               }
  616   
  617               public ResultSet getPrimaryKeys(String catalog, String schema,
  618                   String table) throws SQLException {
  619                   if (_logs.isJDBCEnabled())
  620                       _logs.logJDBC("getPrimaryKeys: "
  621                           + catalog + ", " + schema + ", " + table,
  622                           LoggingConnection.this);
  623                   return super.getPrimaryKeys(catalog, schema, table);
  624               }
  625   
  626               public ResultSet getProcedureColumns(String catalog,
  627                   String schemaPattern, String procedureNamePattern,
  628                   String columnNamePattern) throws SQLException {
  629                   if (_logs.isJDBCEnabled())
  630                       _logs.logJDBC("getProcedureColumns: "
  631                           + catalog + ", " + schemaPattern + ", "
  632                           + procedureNamePattern + ", " + columnNamePattern,
  633                           LoggingConnection.this);
  634                   return super.getProcedureColumns(catalog, schemaPattern,
  635                       procedureNamePattern, columnNamePattern);
  636               }
  637   
  638               public ResultSet getProcedures(String catalog,
  639                   String schemaPattern, String procedureNamePattern)
  640                   throws SQLException {
  641                   if (_logs.isJDBCEnabled())
  642                       _logs.logJDBC("getProcedures: "
  643                           + catalog + ", " + schemaPattern + ", "
  644                           + procedureNamePattern, LoggingConnection.this);
  645                   return super.getProcedures(catalog, schemaPattern,
  646                       procedureNamePattern);
  647               }
  648   
  649               public ResultSet getSchemas() throws SQLException {
  650                   if (_logs.isJDBCEnabled())
  651                       _logs.logJDBC("getSchemas", LoggingConnection.this);
  652                   return super.getSchemas();
  653               }
  654   
  655               public ResultSet getTablePrivileges(String catalog,
  656                   String schemaPattern, String tableNamePattern)
  657                   throws SQLException {
  658                   if (_logs.isJDBCEnabled())
  659                       _logs.logJDBC("getTablePrivileges", LoggingConnection.this);
  660                   return super.getTablePrivileges(catalog, schemaPattern,
  661                       tableNamePattern);
  662               }
  663   
  664               public ResultSet getTables(String catalog, String schemaPattern,
  665                   String tableNamePattern, String[] types) throws SQLException {
  666                   if (_logs.isJDBCEnabled())
  667                       _logs.logJDBC("getTables: "
  668                           + catalog + ", " + schemaPattern + ", "
  669                           + tableNamePattern, LoggingConnection.this);
  670                   return super.getTables(catalog, schemaPattern,
  671                       tableNamePattern, types);
  672               }
  673   
  674               public ResultSet getTableTypes() throws SQLException {
  675                   if (_logs.isJDBCEnabled())
  676                       _logs.logJDBC("getTableTypes", LoggingConnection.this);
  677                   return super.getTableTypes();
  678               }
  679   
  680               public ResultSet getTypeInfo() throws SQLException {
  681                   if (_logs.isJDBCEnabled())
  682                       _logs.logJDBC("getTypeInfo", LoggingConnection.this);
  683                   return super.getTypeInfo();
  684               }
  685   
  686               public ResultSet getUDTs(String catalog, String schemaPattern,
  687                   String typeNamePattern, int[] types) throws SQLException {
  688                   if (_logs.isJDBCEnabled())
  689                       _logs.logJDBC("getUDTs", LoggingConnection.this);
  690                   return super.getUDTs(catalog, schemaPattern,
  691                       typeNamePattern, types);
  692               }
  693   
  694               public ResultSet getVersionColumns(String catalog,
  695                   String schema, String table) throws SQLException {
  696                   if (_logs.isJDBCEnabled())
  697                       _logs.logJDBC("getVersionColumns: "
  698                           + catalog + ", " + schema + ", " + table,
  699                           LoggingConnection.this);
  700                   return super.getVersionColumns(catalog, schema, table);
  701               }
  702           }
  703   
  704           /**
  705            * Statement wrapper that logs SQL to the parent data source and
  706            * remembers the last piece of SQL to be executed on it.
  707            */
  708           private class LoggingStatement extends DelegatingStatement {
  709   
  710               private String _sql = null;
  711   
  712               public LoggingStatement(Statement stmnt) throws SQLException {
  713                   super(stmnt, LoggingConnection.this);
  714               }
  715   
  716               public void appendInfo(StringBuffer buf) {
  717                   if (_sql != null) {
  718                       buf.append(" ");
  719                       if (_formatter != null) {
  720                           buf.append(SEP);
  721                           buf.append(_formatter.prettyPrint(_sql));
  722                       } else {
  723                           buf.append(_sql);
  724                       }
  725                   }
  726               }
  727   
  728               protected ResultSet wrapResult(ResultSet rs, boolean wrap) {
  729                   if (!wrap || rs == null)
  730                       return super.wrapResult(rs, wrap);
  731                   return new LoggingResultSet(rs, this);
  732               }
  733   
  734               public void cancel() throws SQLException {
  735                   if (_logs.isJDBCEnabled())
  736                       _logs.logJDBC("cancel " + this, LoggingConnection.this);
  737                   super.cancel();
  738               }
  739   
  740               protected ResultSet executeQuery(String sql, boolean wrap)
  741                   throws SQLException {
  742                   _sql = sql;
  743                   logSQL(this);
  744                   long start = System.currentTimeMillis();
  745                   try {
  746                       return super.executeQuery(sql, wrap);
  747                   } catch (SQLException se) {
  748                       throw wrap(se, LoggingStatement.this);
  749                   } finally {
  750                       logTime(start);
  751                       handleSQLWarning(LoggingStatement.this);
  752                   }
  753               }
  754   
  755               public int executeUpdate(String sql) throws SQLException {
  756                   _sql = sql;
  757                   logSQL(this);
  758                   long start = System.currentTimeMillis();
  759                   try {
  760                       return super.executeUpdate(sql);
  761                   } catch (SQLException se) {
  762                       throw wrap(se, LoggingStatement.this);
  763                   } finally {
  764                       logTime(start);
  765                       handleSQLWarning(LoggingStatement.this);
  766                   }
  767               }
  768   
  769               public boolean execute(String sql) throws SQLException {
  770                   _sql = sql;
  771                   logSQL(this);
  772                   long start = System.currentTimeMillis();
  773                   try {
  774                       return super.execute(sql);
  775                   } catch (SQLException se) {
  776                       throw wrap(se, LoggingStatement.this);
  777                   } finally {
  778                       logTime(start);
  779                       handleSQLWarning(LoggingStatement.this);
  780                   }
  781               }
  782           }
  783   
  784           private class LoggingPreparedStatement
  785               extends DelegatingPreparedStatement {
  786   
  787               private final String _sql;
  788               private List _params = null;
  789               private List _paramBatch = null;
  790   
  791               public LoggingPreparedStatement(PreparedStatement stmnt, String sql)
  792                   throws SQLException {
  793                   super(stmnt, LoggingConnection.this);
  794                   _sql = sql;
  795               }
  796   
  797               protected ResultSet wrapResult(ResultSet rs, boolean wrap) {
  798                   if (!wrap || rs == null)
  799                       return super.wrapResult(rs, wrap);
  800                   return new LoggingResultSet(rs, this);
  801               }
  802   
  803               protected ResultSet executeQuery(String sql, boolean wrap)
  804                   throws SQLException {
  805                   logSQL(this);
  806                   long start = System.currentTimeMillis();
  807                   try {
  808                       return super.executeQuery(sql, wrap);
  809                   } catch (SQLException se) {
  810                       throw wrap(se, LoggingPreparedStatement.this);
  811                   } finally {
  812                       logTime(start);
  813                       clearLogParameters(true);
  814                       handleSQLWarning(LoggingPreparedStatement.this);
  815                   }
  816               }
  817   
  818               public int executeUpdate(String sql) throws SQLException {
  819                   logSQL(this);
  820                   long start = System.currentTimeMillis();
  821                   try {
  822                       return super.executeUpdate(sql);
  823                   } catch (SQLException se) {
  824                       throw wrap(se, LoggingPreparedStatement.this);
  825                   } finally {
  826                       logTime(start);
  827                       clearLogParameters(true);
  828                       handleSQLWarning(LoggingPreparedStatement.this);
  829                   }
  830               }
  831   
  832               public boolean execute(String sql) throws SQLException {
  833                   logSQL(this);
  834                   long start = System.currentTimeMillis();
  835                   try {
  836                       return super.execute(sql);
  837                   } catch (SQLException se) {
  838                       throw wrap(se, LoggingPreparedStatement.this);
  839                   } finally {
  840                       logTime(start);
  841                       clearLogParameters(true);
  842                       handleSQLWarning(LoggingPreparedStatement.this);
  843                   }
  844               }
  845   
  846               protected ResultSet executeQuery(boolean wrap) throws SQLException {
  847                   logSQL(this);
  848                   long start = System.currentTimeMillis();
  849                   try {
  850                       return super.executeQuery(wrap);
  851                   } catch (SQLException se) {
  852                       throw wrap(se, LoggingPreparedStatement.this);
  853                   } finally {
  854                       logTime(start);
  855                       clearLogParameters(true);
  856                       handleSQLWarning(LoggingPreparedStatement.this);
  857                   }
  858               }
  859   
  860               public int executeUpdate() throws SQLException {
  861                   logSQL(this);
  862                   long start = System.currentTimeMillis();
  863                   try {
  864                       return super.executeUpdate();
  865                   } catch (SQLException se) {
  866                       throw wrap(se, LoggingPreparedStatement.this);
  867                   } finally {
  868                       logTime(start);
  869                       clearLogParameters(true);
  870                       handleSQLWarning(LoggingPreparedStatement.this);
  871                   }
  872               }
  873   
  874               public int[] executeBatch() throws SQLException {
  875                   logBatchSQL(this);
  876                   long start = System.currentTimeMillis();
  877                   try {
  878                       return super.executeBatch();
  879                   } catch (SQLException se) {
  880                       // if the exception is a BatchUpdateException, and
  881                       // we are tracking parameters, then set the current
  882                       // parameter set to be the index of the failed
  883                       // statement so that the ReportingSQLException will
  884                       // show the correct param
  885                       if (se instanceof BatchUpdateException
  886                           && _paramBatch != null && shouldTrackParameters()) {
  887                           int[] count = ((BatchUpdateException) se).
  888                               getUpdateCounts();
  889                           if (count != null && count.length <= _paramBatch.size())
  890                           {
  891                               int index = -1;
  892                               for (int i = 0; i < count.length; i++) {
  893                                   // -3 is Statement.STATEMENT_FAILED, but is
  894                                   // only available in JDK 1.4+
  895                                   if (count[i] == -3) {
  896                                       index = i;
  897                                       break;
  898                                   }
  899                               }
  900   
  901                               // no -3 element: it may be that the server stopped
  902                               // processing, so the size of the count will be
  903                               // the index
  904                               if (index == -1)
  905                                   index = count.length + 1;
  906   
  907                               // set the current params to the saved values
  908                               if (index < _paramBatch.size())
  909                                   _params = (List) _paramBatch.get(index);
  910                           }
  911                       }
  912                       throw wrap(se, LoggingPreparedStatement.this);
  913                   } finally {
  914                       logTime(start);
  915                       clearLogParameters(true);
  916                       handleSQLWarning(LoggingPreparedStatement.this);
  917                   }
  918               }
  919   
  920               public boolean execute() throws SQLException {
  921                   logSQL(this);
  922                   long start = System.currentTimeMillis();
  923                   try {
  924                       return super.execute();
  925                   } catch (SQLException se) {
  926                       throw wrap(se, LoggingPreparedStatement.this);
  927                   } finally {
  928                       logTime(start);
  929                       clearLogParameters(true);
  930                       handleSQLWarning(LoggingPreparedStatement.this);
  931                   }
  932               }
  933   
  934               public void cancel() throws SQLException {
  935                   if (_logs.isJDBCEnabled())
  936                       _logs.logJDBC("cancel " + this + ": " + _sql,
  937                           LoggingConnection.this);
  938   
  939                   super.cancel();
  940               }
  941   
  942               public void setNull(int i1, int i2) throws SQLException {
  943                   setLogParameter(i1, "null", null);
  944                   super.setNull(i1, i2);
  945               }
  946   
  947               public void setBoolean(int i, boolean b) throws SQLException {
  948                   setLogParameter(i, b);
  949                   super.setBoolean(i, b);
  950               }
  951   
  952               public void setByte(int i, byte b) throws SQLException {
  953                   setLogParameter(i, b);
  954                   super.setByte(i, b);
  955               }
  956   
  957               public void setShort(int i, short s) throws SQLException {
  958                   setLogParameter(i, s);
  959                   super.setShort(i, s);
  960               }
  961   
  962               public void setInt(int i1, int i2) throws SQLException {
  963                   setLogParameter(i1, i2);
  964                   super.setInt(i1, i2);
  965               }
  966   
  967               public void setLong(int i, long l) throws SQLException {
  968                   setLogParameter(i, l);
  969                   super.setLong(i, l);
  970               }
  971   
  972               public void setFloat(int i, float f) throws SQLException {
  973                   setLogParameter(i, f);
  974                   super.setFloat(i, f);
  975               }
  976   
  977               public void setDouble(int i, double d) throws SQLException {
  978                   setLogParameter(i, d);
  979                   super.setDouble(i, d);
  980               }
  981   
  982               public void setBigDecimal(int i, BigDecimal bd)
  983                   throws SQLException {
  984                   setLogParameter(i, "BigDecimal", bd);
  985                   super.setBigDecimal(i, bd);
  986               }
  987   
  988               public void setString(int i, String s) throws SQLException {
  989                   setLogParameter(i, "String", s);
  990                   super.setString(i, s);
  991               }
  992   
  993               public void setBytes(int i, byte[] b) throws SQLException {
  994                   setLogParameter(i, "byte[]", b);
  995                   super.setBytes(i, b);
  996               }
  997   
  998               public void setDate(int i, Date d) throws SQLException {
  999                   setLogParameter(i, "Date", d);
 1000                   super.setDate(i, d);
 1001               }
 1002   
 1003               public void setTime(int i, Time t) throws SQLException {
 1004                   setLogParameter(i, "Time", t);
 1005                   super.setTime(i, t);
 1006               }
 1007   
 1008               public void setTimestamp(int i, Timestamp t) throws SQLException {
 1009                   setLogParameter(i, "Timestamp", t);
 1010                   super.setTimestamp(i, t);
 1011               }
 1012   
 1013               public void setAsciiStream(int i1, InputStream is, int i2)
 1014                   throws SQLException {
 1015                   setLogParameter(i1, "InputStream", is);
 1016                   super.setAsciiStream(i1, is, i2);
 1017               }
 1018   
 1019               public void setUnicodeStream(int i1, InputStream is, int i2)
 1020                   throws SQLException {
 1021                   setLogParameter(i1, "InputStream", is);
 1022                   super.setUnicodeStream(i2, is, i2);
 1023               }
 1024   
 1025               public void setBinaryStream(int i1, InputStream is, int i2)
 1026                   throws SQLException {
 1027                   setLogParameter(i1, "InputStream", is);
 1028                   super.setBinaryStream(i1, is, i2);
 1029               }
 1030   
 1031               public void clearParameters() throws SQLException {
 1032                   clearLogParameters(false);
 1033                   super.clearParameters();
 1034               }
 1035   
 1036               public void setObject(int i1, Object o, int i2, int i3)
 1037                   throws SQLException {
 1038                   setLogParameter(i1, "Object", o);
 1039                   super.setObject(i1, o, i2, i3);
 1040               }
 1041   
 1042               public void setObject(int i1, Object o, int i2)
 1043                   throws SQLException {
 1044                   setLogParameter(i1, "Object", o);
 1045                   super.setObject(i1, o, i2);
 1046               }
 1047   
 1048               public void setObject(int i, Object o) throws SQLException {
 1049                   setLogParameter(i, "Object", o);
 1050                   super.setObject(i, o);
 1051               }
 1052   
 1053               public void addBatch() throws SQLException {
 1054                   if (_logs.isSQLEnabled())
 1055                       _logs.logSQL("batching " + this, LoggingConnection.this);
 1056                   long start = System.currentTimeMillis();
 1057                   try {
 1058                       super.addBatch();
 1059                       if (shouldTrackParameters()) {
 1060                           // make sure our list is initialized
 1061                           if (_paramBatch == null)
 1062                               _paramBatch = new ArrayList();
 1063                           // copy parameters since they will be re-used
 1064                           if (_params != null)
 1065                               _paramBatch.add(new ArrayList(_params));
 1066                           else
 1067                               _paramBatch.add(null);
 1068                       }
 1069                   }
 1070                   finally {
 1071                       logTime(start);
 1072                   }
 1073               }
 1074   
 1075               public void setCharacterStream(int i1, Reader r, int i2)
 1076                   throws SQLException {
 1077                   setLogParameter(i1, "Reader", r);
 1078                   super.setCharacterStream(i1, r, i2);
 1079               }
 1080   
 1081               public void setRef(int i, Ref r) throws SQLException {
 1082                   setLogParameter(i, "Ref", r);
 1083                   super.setRef(i, r);
 1084               }
 1085   
 1086               public void setBlob(int i, Blob b) throws SQLException {
 1087                   setLogParameter(i, "Blob", b);
 1088                   super.setBlob(i, b);
 1089               }
 1090   
 1091               public void setClob(int i, Clob c) throws SQLException {
 1092                   setLogParameter(i, "Clob", c);
 1093                   super.setClob(i, c);
 1094               }
 1095   
 1096               public void setArray(int i, Array a) throws SQLException {
 1097                   setLogParameter(i, "Array", a);
 1098                   super.setArray(i, a);
 1099               }
 1100   
 1101               public ResultSetMetaData getMetaData() throws SQLException {
 1102                   return super.getMetaData();
 1103               }
 1104   
 1105               public void setDate(int i, Date d, Calendar c) throws SQLException {
 1106                   setLogParameter(i, "Date", d);
 1107                   super.setDate(i, d, c);
 1108               }
 1109   
 1110               public void setTime(int i, Time t, Calendar c) throws SQLException {
 1111                   setLogParameter(i, "Time", t);
 1112                   super.setTime(i, t, c);
 1113               }
 1114   
 1115               public void setTimestamp(int i, Timestamp t, Calendar c)
 1116                   throws SQLException {
 1117                   setLogParameter(i, "Timestamp", t);
 1118                   super.setTimestamp(i, t, c);
 1119               }
 1120   
 1121               public void setNull(int i1, int i2, String s) throws SQLException {
 1122                   setLogParameter(i1, "null", null);
 1123                   super.setNull(i1, i2, s);
 1124               }
 1125   
 1126               protected void appendInfo(StringBuffer buf) {
 1127                   buf.append(" ");
 1128                   if (_formatter != null) {
 1129                       buf.append(SEP);
 1130                       buf.append(_formatter.prettyPrint(_sql));
 1131                       buf.append(SEP);
 1132                   } else {
 1133                       buf.append(_sql);
 1134                   }
 1135   
 1136                   StringBuffer paramBuf = null;
 1137                   if (_params != null && !_params.isEmpty()) {
 1138                       paramBuf = new StringBuffer();
 1139                       for (Iterator itr = _params.iterator(); itr.hasNext();) {
 1140                           paramBuf.append(itr.next());
 1141                           if (itr.hasNext())
 1142                               paramBuf.append(", ");
 1143                       }
 1144                   }
 1145   
 1146                   if (paramBuf != null) {
 1147                       if (!_prettyPrint)
 1148                           buf.append(" ");
 1149                       buf.append("[params=").
 1150                           append(paramBuf.toString()).append("]");
 1151                   }
 1152                   super.appendInfo(buf);
 1153               }
 1154   
 1155               private void clearLogParameters(boolean batch) {
 1156                   if (_params != null)
 1157                       _params.clear();
 1158                   if (batch && _paramBatch != null)
 1159                       _paramBatch.clear();
 1160               }
 1161   
 1162               private boolean shouldTrackParameters() {
 1163                   return _trackParameters || _logs.isSQLEnabled();
 1164               }
 1165   
 1166               private void setLogParameter(int index, boolean val) {
 1167                   if (shouldTrackParameters())
 1168                       setLogParameter(index, "(boolean) " + val);
 1169               }
 1170   
 1171               private void setLogParameter(int index, byte val) {
 1172                   if (shouldTrackParameters())
 1173                       setLogParameter(index, "(byte) " + val);
 1174               }
 1175   
 1176               private void setLogParameter(int index, double val) {
 1177                   if (shouldTrackParameters())
 1178                       setLogParameter(index, "(double) " + val);
 1179               }
 1180   
 1181               private void setLogParameter(int index, float val) {
 1182                   if (shouldTrackParameters())
 1183                       setLogParameter(index, "(float) " + val);
 1184               }
 1185   
 1186               private void setLogParameter(int index, int val) {
 1187                   if (shouldTrackParameters())
 1188                       setLogParameter(index, "(int) " + val);
 1189               }
 1190   
 1191               private void setLogParameter(int index, long val) {
 1192                   if (shouldTrackParameters())
 1193                       setLogParameter(index, "(long) " + val);
 1194               }
 1195   
 1196               private void setLogParameter(int index, short val) {
 1197                   if (shouldTrackParameters())
 1198                       setLogParameter(index, "(short) " + val);
 1199               }
 1200   
 1201               private void setLogParameter(int index, String type, Object val) {
 1202                   if (shouldTrackParameters())
 1203                       setLogParameter(index, "(" + type + ") " + val);
 1204               }
 1205   
 1206               private void setLogParameter(int index, String val) {
 1207                   if (_params == null)
 1208                       _params = new ArrayList();
 1209                   while (_params.size() < index)
 1210                       _params.add(null);
 1211                   if (val.length() > 80)
 1212                       val = val.substring(0, 77) + "...";
 1213                   _params.set(index - 1, val);
 1214               }
 1215           }
 1216   
 1217           /**
 1218            * Warning-handling result set.
 1219            */
 1220           private class LoggingResultSet extends DelegatingResultSet {
 1221   
 1222               public LoggingResultSet(ResultSet rs, Statement stmnt) {
 1223                   super(rs, stmnt);
 1224               }
 1225   
 1226               public boolean next() throws SQLException {
 1227                   try {
 1228                       return super.next();
 1229                   } finally {
 1230                       handleSQLWarning(LoggingResultSet.this);
 1231                   }
 1232               }
 1233   
 1234               public void close() throws SQLException {
 1235                   try {
 1236                       super.close();
 1237                   } finally {
 1238                       handleSQLWarning(LoggingResultSet.this);
 1239                   }
 1240               }
 1241   
 1242               public void beforeFirst() throws SQLException {
 1243                   try {
 1244                       super.beforeFirst();
 1245                   } finally {
 1246                       handleSQLWarning(LoggingResultSet.this);
 1247                   }
 1248               }
 1249   
 1250               public void afterLast() throws SQLException {
 1251                   try {
 1252                       super.afterLast();
 1253                   } finally {
 1254                       handleSQLWarning(LoggingResultSet.this);
 1255                   }
 1256               }
 1257   
 1258               public boolean first() throws SQLException {
 1259                   try {
 1260                       return super.first();
 1261                   } finally {
 1262                       handleSQLWarning(LoggingResultSet.this);
 1263                   }
 1264               }
 1265   
 1266               public boolean last() throws SQLException {
 1267                   try {
 1268                       return super.last();
 1269                   } finally {
 1270                       handleSQLWarning(LoggingResultSet.this);
 1271                   }
 1272               }
 1273   
 1274               public boolean absolute(int a) throws SQLException {
 1275                   try {
 1276                       return super.absolute(a);
 1277                   } finally {
 1278                       handleSQLWarning(LoggingResultSet.this);
 1279                   }
 1280               }
 1281   
 1282               public boolean relative(int a) throws SQLException {
 1283                   try {
 1284                       return super.relative(a);
 1285                   } finally {
 1286                       handleSQLWarning(LoggingResultSet.this);
 1287                   }
 1288               }
 1289   
 1290               public boolean previous() throws SQLException {
 1291                   try {
 1292                       return super.previous();
 1293                   } finally {
 1294                       handleSQLWarning(LoggingResultSet.this);
 1295                   }
 1296               }
 1297           }
 1298       }
 1299   }

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa.lib » jdbc » [javadoc | source]