[logback-dev] svn commit: r607 - in logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db: . dialect

noreply.seb at qos.ch noreply.seb at qos.ch
Tue Sep 26 18:14:59 CEST 2006


Author: seb
Date: Tue Sep 26 18:14:59 2006
New Revision: 607

Added:
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql

Log:
- Created DBAppenderBase, and modified DBAppender accordingly
- Moved classes to Core module when possible.

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,60 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.spi.LifeCycle;
+
+
+/**
+ *  The <id>ConnectionSource</id> interface provides a pluggable means of
+ *  transparently obtaining JDBC {@link java.sql.Connection}s for logback classes
+ *  that require the use of a {@link java.sql.Connection}.
+ *
+ *  @author <a href="mailto:rdecampo at twcny.rr.com">Ray DeCampo</a>
+ */
+public interface ConnectionSource extends LifeCycle {
+
+  final int UNKNOWN_DIALECT = 0;
+  final int POSTGRES_DIALECT = 1;
+  final int MYSQL_DIALECT = 2;
+  final int ORACLE_DIALECT = 3;
+  final int MSSQL_DIALECT = 4;
+  final int HSQL_DIALECT = 5;  
+  /**
+   *  Obtain a {@link java.sql.Connection} for use.  The client is
+   *  responsible for closing the {@link java.sql.Connection} when it is no
+   *  longer required.
+   *
+   *  @throws SQLException  if a {@link java.sql.Connection} could not be
+   *                        obtained
+   */
+  Connection getConnection() throws SQLException;
+
+  /**
+   * Get the SQL dialect that should be used for this connection. Note that the
+   * dialect is not needed if the JDBC driver supports the getGeneratedKeys 
+   * method.
+   */
+  int getSQLDialectCode();
+  
+  /**
+   * If the connection supports the JDBC 3.0 getGeneratedKeys method, then
+   * we do not need any specific dialect support.
+   */
+  boolean supportsGetGeneratedKeys();
+  
+  /**
+   * If the connection does not support batch updates, we will avoid using them.
+   */  
+  public boolean supportsBatchUpdates();
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,119 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.db.dialect.DBUtil;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+
+/**
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public abstract class ConnectionSourceBase extends ContextAwareBase implements ConnectionSource {
+  
+  private boolean started;
+  
+  private String user = null;
+  private String password = null;
+
+  // initially we have an unkonw dialect
+  private int dialectCode = UNKNOWN_DIALECT;
+  private boolean supportsGetGeneratedKeys = false;
+  private boolean supportsBatchUpdates = false;
+
+
+  /**
+   * Learn relevant information about this connection source.
+   *
+   */
+  public void discoverConnnectionProperties() {
+    try {
+      Connection connection = getConnection();
+      if (connection == null) {
+        addWarn("Could not get a connection");
+        return;
+      }
+      DatabaseMetaData meta = connection.getMetaData();
+      DBUtil util = new DBUtil();
+      util.setContext(getContext());
+      supportsGetGeneratedKeys = util.supportsGetGeneratedKeys(meta);
+      supportsBatchUpdates = util.supportsBatchUpdates(meta);
+      dialectCode = DBUtil.discoverSQLDialect(meta);
+    } catch (SQLException se) {
+      addWarn("Could not discover the dialect to use.", se);
+    }
+  }
+
+  /**
+   * Does this connection support the JDBC Connection.getGeneratedKeys method?
+   */
+  public final boolean supportsGetGeneratedKeys() {
+    return supportsGetGeneratedKeys;
+  }
+
+  public final int getSQLDialectCode() {
+    return dialectCode;
+  }
+
+  /**
+   * Get the password for this connection source.
+   */
+  public final String getPassword() {
+    return password;
+  }
+
+  /**
+   * Sets the password.
+   * @param password The password to set
+   */
+  public final void setPassword(final String password) {
+    this.password = password;
+  }
+
+  /**
+   * Get the user for this connection source.
+   */
+  public final String getUser() {
+    return user;
+  }
+
+  /**
+   * Sets the username.
+   * @param username The username to set
+   */
+  public final void setUser(final String username) {
+    this.user = username;
+  }
+
+  /**
+   * Does this connection support batch updates?
+   */
+  public final boolean supportsBatchUpdates() {
+    return supportsBatchUpdates;
+  }
+
+  public boolean isStarted() {
+    return started;
+  }
+
+  public void start() {
+    started = true;
+  }
+
+  public void stop() {
+    started = false;
+  }
+  
+  
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,261 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.db.dialect.DBUtil;
+import ch.qos.logback.core.db.dialect.SQLDialect;
+
+/**
+ * @author Ceki G&uuml;lc&uuml;
+ * @author Ray DeCampo
+ * @author S&eacute;bastien Pennec
+ */
+public abstract class DBAppenderBase extends AppenderBase {
+  protected static final String insertPropertiesSQL = "INSERT INTO  logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
+  protected static final String insertExceptionSQL = "INSERT INTO  logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
+  protected static final String insertSQL;
+  protected static final Method GET_GENERATED_KEYS_METHOD;
+
+  static {
+    StringBuffer sql = new StringBuffer();
+    sql.append("INSERT INTO logging_event (");
+    sql.append("timestmp, ");
+    sql.append("formatted_message, ");
+    sql.append("logger_name, ");
+    sql.append("level_string, ");
+    sql.append("thread_name, ");
+    sql.append("reference_flag, ");
+    sql.append("caller_filename, ");
+    sql.append("caller_class, ");
+    sql.append("caller_method, ");
+    sql.append("caller_line) ");
+    sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?,?)");
+    insertSQL = sql.toString();
+    //
+    // PreparedStatement.getGeneratedKeys added in JDK 1.4
+    //
+    Method getGeneratedKeysMethod;
+    try {
+      getGeneratedKeysMethod = PreparedStatement.class.getMethod(
+          "getGeneratedKeys", (Class[]) null);
+    } catch (Exception ex) {
+      getGeneratedKeysMethod = null;
+    }
+    GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
+  }
+
+  protected ConnectionSource connectionSource;
+  protected boolean cnxSupportsGetGeneratedKeys = false;
+  protected boolean cnxSupportsBatchUpdates = false;
+  protected SQLDialect sqlDialect;
+
+  public DBAppenderBase() {
+  }
+
+  @Override
+  public void start() {
+
+    if (connectionSource == null) {
+      throw new IllegalStateException(
+          "DBAppender cannot function without a connection source");
+    }
+
+    sqlDialect = DBUtil
+        .getDialectFromCode(connectionSource.getSQLDialectCode());
+    if (GET_GENERATED_KEYS_METHOD != null) {
+      cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
+    } else {
+      cnxSupportsGetGeneratedKeys = false;
+    }
+    cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
+    if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
+      throw new IllegalStateException(
+          "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
+    }
+
+    // all nice and dandy on the eastern front
+    super.start();
+  }
+
+  /**
+   * @return Returns the connectionSource.
+   */
+  public ConnectionSource getConnectionSource() {
+    return connectionSource;
+  }
+
+  /**
+   * @param connectionSource
+   *          The connectionSource to set.
+   */
+  public void setConnectionSource(ConnectionSource connectionSource) {
+    this.connectionSource = connectionSource;
+  }
+
+  @Override
+  public void append(Object eventObject) {
+    // LoggingEvent event = (LoggingEvent) eventObject;
+    Connection connection = null;
+    try {
+      connection = connectionSource.getConnection();
+      connection.setAutoCommit(false);
+
+      PreparedStatement insertStatement = connection
+          .prepareStatement(insertSQL);
+
+      subAppend(eventObject, connection, insertStatement);
+
+      // we no longer need the insertStatement
+      if (insertStatement != null) {
+        insertStatement.close();
+        insertStatement = null;
+      }
+
+      connection.commit();
+    } catch (Throwable sqle) {
+      addError("problem appending event", sqle);
+    } finally {
+      DBHelper.closeConnection(connection);
+    }
+  }
+
+  protected abstract void subAppend(Object eventObject, Connection connection,
+      PreparedStatement statement) throws Throwable;
+
+  protected int getEventId(PreparedStatement insertStatement,
+      Connection connection) throws SQLException, InvocationTargetException {
+    ResultSet rs = null;
+    Statement idStatement = null;
+    boolean gotGeneratedKeys = false;
+    if (cnxSupportsGetGeneratedKeys) {
+      try {
+        rs = (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(insertStatement,
+            (Object[]) null);
+        gotGeneratedKeys = true;
+      } catch (InvocationTargetException ex) {
+        Throwable target = ex.getTargetException();
+        if (target instanceof SQLException) {
+          throw (SQLException) target;
+        }
+        throw ex;
+      } catch (IllegalAccessException ex) {
+        addWarn(
+            "IllegalAccessException invoking PreparedStatement.getGeneratedKeys",
+            ex);
+      }
+    }
+
+    if (!gotGeneratedKeys) {
+      insertStatement.close();
+      insertStatement = null;
+
+      idStatement = connection.createStatement();
+      idStatement.setMaxRows(1);
+      rs = idStatement.executeQuery(sqlDialect.getSelectInsertId());
+    }
+
+    // A ResultSet cursor is initially positioned before the first row;
+    // the
+    // first call to the method next makes the first row the current row
+    rs.next();
+    int eventId = rs.getInt(1);
+
+    rs.close();
+
+    if (idStatement != null) {
+      idStatement.close();
+      idStatement = null;
+    }
+
+    return eventId;
+  }
+
+  protected void insertProperties(Map<String, String> mergedMap,
+      Connection connection, int eventId) throws SQLException {
+    Set propertiesKeys = mergedMap.keySet();
+    if (propertiesKeys.size() > 0) {
+      PreparedStatement insertPropertiesStatement = connection
+          .prepareStatement(insertPropertiesSQL);
+
+      for (Iterator i = propertiesKeys.iterator(); i.hasNext();) {
+        String key = (String) i.next();
+        String value = (String) mergedMap.get(key);
+
+        insertPropertiesStatement.setInt(1, eventId);
+        insertPropertiesStatement.setString(2, key);
+        insertPropertiesStatement.setString(3, value);
+
+        if (cnxSupportsBatchUpdates) {
+          insertPropertiesStatement.addBatch();
+        } else {
+          insertPropertiesStatement.execute();
+        }
+      }
+
+      if (cnxSupportsBatchUpdates) {
+        insertPropertiesStatement.executeBatch();
+      }
+
+      insertPropertiesStatement.close();
+      insertPropertiesStatement = null;
+    }
+  }
+
+  protected void insertThrowable(String[] strRep, Connection connection,
+      int eventId) throws SQLException {
+
+    PreparedStatement insertExceptionStatement = connection
+        .prepareStatement(insertExceptionSQL);
+
+    for (short i = 0; i < strRep.length; i++) {
+      insertExceptionStatement.setInt(1, eventId);
+      insertExceptionStatement.setShort(2, i);
+      insertExceptionStatement.setString(3, strRep[i]);
+      if (cnxSupportsBatchUpdates) {
+        insertExceptionStatement.addBatch();
+      } else {
+        insertExceptionStatement.execute();
+      }
+    }
+    if (cnxSupportsBatchUpdates) {
+      insertExceptionStatement.executeBatch();
+    }
+    insertExceptionStatement.close();
+    insertExceptionStatement = null;
+
+  }
+
+  @Override
+  public void stop() {
+    super.stop();
+  }
+
+  public Layout getLayout() {
+    return null;
+  }
+
+  public void setLayout(Layout layout) {
+  }
+
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,42 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * @author Ceki G&uuml;lc&uuml;
+ * 
+ */
+public class DBHelper {
+
+  static public void closeConnection(Connection connection) {
+    if (connection != null) {
+      try {
+        connection.close();
+      } catch (SQLException sqle) {
+        // static utility classes should not log without an explicit repository
+        // reference
+      }
+    }
+  }
+
+  public static void closeStatement(Statement statement) {
+    if (statement != null) {
+      try {
+        statement.close();
+      } catch (SQLException sqle) {
+      }
+    }
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,78 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db;
+
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+
+/**
+ *  The DataSourceConnectionSource is an implementation of {@link ConnectionSource}
+ *  that obtains the Connection in the recommended JDBC manner based on
+ *  a {@link javax.sql.DataSource DataSource}.
+ *  <p>
+ *
+ *  @author Ray DeCampo
+ *  @author Ceki G&uuml;lc&uuml;
+ */
+public class DataSourceConnectionSource extends ConnectionSourceBase {
+
+  private DataSource dataSource;
+
+  @Override
+  public void start() {
+    //LogLog.debug("**********DataSourceConnectionSource.activateOptions called");
+    if (dataSource == null) {
+      addWarn("WARNING: No data source specified");
+    } else {
+      Connection connection = null;
+      try {
+        connection = getConnection();
+      } catch(SQLException se) {
+        addWarn("Could not get a connection to discover the dialect to use.", se);
+      }
+      if(connection != null) {
+        discoverConnnectionProperties();
+      } 
+      if(!supportsGetGeneratedKeys() && getSQLDialectCode() == ConnectionSource.UNKNOWN_DIALECT) {
+        addWarn("Connection does not support GetGeneratedKey method and could not discover the dialect.");
+      }
+    }
+    super.start();
+  }
+
+  /**
+   * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
+   */
+  public Connection getConnection() throws SQLException {
+    if (dataSource == null) {
+      addError("WARNING: No data source specified");
+      return null;
+    }
+
+    if (getUser() == null) {
+      return dataSource.getConnection();
+    } else {
+      return dataSource.getConnection(getUser(), getPassword());
+    }
+  }
+
+  public DataSource getDataSource() {
+    return dataSource;
+  }
+
+  public void setDataSource(DataSource dataSource) {
+    this.dataSource = dataSource;
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,129 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+ * The DriverManagerConnectionSource is an implementation of
+ * {@link ConnectionSource} that obtains the Connection in the traditional JDBC
+ * manner based on the connection URL.
+ * <p>
+ * Note that this class will establish a new Connection for each call to
+ * {@link #getConnection()}. It is recommended that you either use a JDBC
+ * driver that natively supported Connection pooling or that you create your own
+ * implementation of {@link ConnectionSource} that taps into whatever pooling
+ * mechanism you are already using. (If you have access to a JNDI implementation
+ * that supports {@link javax.sql.DataSource}s, e.g. within a J2EE application
+ * server, see {@link JNDIConnectionSource}). See <a href="#dbcp">below</a>
+ * for a configuration example that uses the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * package from Apache.
+ * <p>
+ * Sample configuration:<br>
+ * 
+ * <pre>
+ *      &lt;connectionSource class=&quot;org.apache.log4j.jdbc.DriverManagerConnectionSource&quot;&gt;
+ *         &lt;param name=&quot;driver&quot; value=&quot;com.mysql.jdbc.Driver&quot; /&gt;
+ *         &lt;param name=&quot;url&quot; value=&quot;jdbc:mysql://localhost:3306/mydb&quot; /&gt;
+ *         &lt;param name=&quot;username&quot; value=&quot;myUser&quot; /&gt;
+ *         &lt;param name=&quot;password&quot; value=&quot;myPassword&quot; /&gt;
+ *      &lt;/connectionSource&gt;
+ * </pre>
+ * 
+ * <p>
+ * <a name="dbcp">If</a> you do not have another connection pooling mechanism
+ * built into your application, you can use the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * package from Apache:<br>
+ * 
+ * <pre>
+ *      &lt;connectionSource class=&quot;org.apache.log4j.jdbc.DriverManagerConnectionSource&quot;&gt;
+ *         &lt;param name=&quot;driver&quot; value=&quot;org.apache.commons.dbcp.PoolingDriver&quot; /&gt;
+ *         &lt;param name=&quot;url&quot; value=&quot;jdbc:apache:commons:dbcp:/myPoolingDriver&quot; /&gt;
+ *      &lt;/connectionSource&gt;
+ * </pre>
+ * 
+ * Then the configuration information for the commons-dbcp package goes into the
+ * file myPoolingDriver.jocl and is placed in the classpath. See the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * documentation for details.
+ * 
+ * @author <a href="mailto:rdecampo at twcny.rr.com">Ray DeCampo</a>
+ */
+public class DriverManagerConnectionSource extends ConnectionSourceBase {
+  private String driverClass = null;
+  private String url = null;
+
+  public void start() {
+    try {
+      if (driverClass != null) {
+        Class.forName(driverClass);
+        discoverConnnectionProperties();
+      } else {
+        addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource.");
+      }
+    } catch (final ClassNotFoundException cnfe) {
+      addError("Could not load JDBC driver class: " + driverClass, cnfe);
+    }
+  }
+
+  /**
+   * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
+   */
+  public Connection getConnection() throws SQLException {
+    if (getUser() == null) {
+      return DriverManager.getConnection(url);
+    } else {
+      return DriverManager.getConnection(url, getUser(), getPassword());
+    }
+  }
+
+  /**
+   * Returns the url.
+   * 
+   * @return String
+   */
+  public String getUrl() {
+    return url;
+  }
+
+  /**
+   * Sets the url.
+   * 
+   * @param url
+   *          The url to set
+   */
+  public void setUrl(String url) {
+    this.url = url;
+  }
+
+  /**
+   * Returns the name of the driver class.
+   * 
+   * @return String
+   */
+  public String getDriverClass() {
+    return driverClass;
+  }
+
+  /**
+   * Sets the driver class.
+   * 
+   * @param driverClass
+   *          The driver class to set
+   */
+  public void setDriverClass(String driverClass) {
+    this.driverClass = driverClass;
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,140 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+// PortableRemoteObject was introduced in JDK 1.3. We won't use it.
+// import javax.rmi.PortableRemoteObject;
+import javax.sql.DataSource;
+
+/**
+ * The <id>JNDIConnectionSource</id> is an implementation of
+ * {@link ConnectionSource} that obtains a {@link javax.sql.DataSource} from a
+ * JNDI provider and uses it to obtain a {@link java.sql.Connection}. It is
+ * primarily designed to be used inside of J2EE application servers or
+ * application server clients, assuming the application server supports remote
+ * access of {@link javax.sql.DataSource}s. In this way one can take advantage
+ * of connection pooling and whatever other goodies the application server
+ * provides.
+ * <p>
+ * Sample configuration:<br>
+ * 
+ * <pre>
+ *     &lt;connectionSource class=&quot;org.apache.log4j.jdbc.JNDIConnectionSource&quot;&gt;
+ *         &lt;param name=&quot;jndiLocation&quot; value=&quot;jdbc/MySQLDS&quot; /&gt;
+ *     &lt;/connectionSource&gt;
+ * </pre>
+ * 
+ * <p>
+ * Sample configuration (with username and password):<br>
+ * 
+ * <pre>
+ *     &lt;connectionSource class=&quot;org.apache.log4j.jdbc.JNDIConnectionSource&quot;&gt;
+ *         &lt;param name=&quot;jndiLocation&quot; value=&quot;jdbc/MySQLDS&quot; /&gt;
+ *         &lt;param name=&quot;username&quot; value=&quot;myUser&quot; /&gt;
+ *         &lt;param name=&quot;password&quot; value=&quot;myPassword&quot; /&gt;
+ *     &lt;/connectionSource&gt;
+ * </pre>
+ * 
+ * <p>
+ * Note that this class will obtain an {@link javax.naming.InitialContext} using
+ * the no-argument constructor. This will usually work when executing within a
+ * J2EE environment. When outside the J2EE environment, make sure that you
+ * provide a jndi.properties file as described by your JNDI provider's
+ * documentation.
+ * 
+ * @author <a href="mailto:rdecampo at twcny.rr.com">Ray DeCampo</a>
+ */
+public class JNDIConnectionSource extends ConnectionSourceBase {
+  private String jndiLocation = null;
+  private DataSource dataSource = null;
+
+  /**
+   * @see org.apache.log4j.spi.OptionHandler#activateOptions()
+   */
+  public void start() {
+    if (jndiLocation == null) {
+      addError("No JNDI location specified for JNDIConnectionSource.");
+    }
+
+    discoverConnnectionProperties();
+
+  }
+
+  /**
+   * @see org.apache.log4j.db.ConnectionSource#getConnection()
+   */
+  public Connection getConnection() throws SQLException {
+    Connection conn = null;
+    try {
+
+      if (dataSource == null) {
+        dataSource = lookupDataSource();
+      }
+      if (getUser() == null) {
+        conn = dataSource.getConnection();
+      } else {
+        conn = dataSource.getConnection(getUser(), getPassword());
+      }
+    } catch (final NamingException ne) {
+      addError("Error while getting data source", ne);
+      throw new SQLException("NamingException while looking up DataSource: "
+          + ne.getMessage());
+    } catch (final ClassCastException cce) {
+      addError("ClassCastException while looking up DataSource.", cce);
+      throw new SQLException("ClassCastException while looking up DataSource: "
+          + cce.getMessage());
+    }
+
+    return conn;
+  }
+
+  /**
+   * Returns the jndiLocation.
+   * 
+   * @return String
+   */
+  public String getJndiLocation() {
+    return jndiLocation;
+  }
+
+  /**
+   * Sets the jndiLocation.
+   * 
+   * @param jndiLocation
+   *          The jndiLocation to set
+   */
+  public void setJndiLocation(String jndiLocation) {
+    this.jndiLocation = jndiLocation;
+  }
+
+  private DataSource lookupDataSource() throws NamingException, SQLException {
+    DataSource ds;
+    Context ctx = new InitialContext();
+    Object obj = ctx.lookup(jndiLocation);
+
+    // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
+    // ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
+    ds = (DataSource) obj;
+
+    if (ds == null) {
+      throw new SQLException("Failed to obtain data source from JNDI location "
+          + jndiLocation);
+    } else {
+      return ds;
+    }
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,118 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db.dialect;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.db.ConnectionSource;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+/**
+ * 
+ * @author Ceki Gulcu
+ * 
+ */
+public class DBUtil extends ContextAwareBase {
+  private static final String POSTGRES_PART = "postgresql";
+  private static final String MYSQL_PART = "mysql";
+  private static final String ORACLE_PART = "oracle";
+  // private static final String MSSQL_PART = "mssqlserver4";
+  private static final String MSSQL_PART = "microsoft";
+  private static final String HSQL_PART = "hsql";
+
+  public static int discoverSQLDialect(DatabaseMetaData meta) {
+    int dialectCode = 0;
+
+    try {
+
+      String dbName = meta.getDatabaseProductName().toLowerCase();
+
+      if (dbName.indexOf(POSTGRES_PART) != -1) {
+        return ConnectionSource.POSTGRES_DIALECT;
+      } else if (dbName.indexOf(MYSQL_PART) != -1) {
+        return ConnectionSource.MYSQL_DIALECT;
+      } else if (dbName.indexOf(ORACLE_PART) != -1) {
+        return ConnectionSource.ORACLE_DIALECT;
+      } else if (dbName.indexOf(MSSQL_PART) != -1) {
+        return ConnectionSource.MSSQL_DIALECT;
+      } else if (dbName.indexOf(HSQL_PART) != -1) {
+        return ConnectionSource.HSQL_DIALECT;
+      } else {
+        return ConnectionSource.UNKNOWN_DIALECT;
+      }
+    } catch (SQLException sqle) {
+      // we can't do much here
+    }
+
+    return dialectCode;
+  }
+
+  public static SQLDialect getDialectFromCode(int dialectCode) {
+    SQLDialect sqlDialect = null;
+
+    switch (dialectCode) {
+    case ConnectionSource.POSTGRES_DIALECT:
+      sqlDialect = new PostgreSQLDialect();
+
+      break;
+    case ConnectionSource.MYSQL_DIALECT:
+      sqlDialect = new MySQLDialect();
+
+      break;
+    case ConnectionSource.ORACLE_DIALECT:
+      sqlDialect = new OracleDialect();
+
+      break;
+    case ConnectionSource.MSSQL_DIALECT:
+      sqlDialect = new MsSQLDialect();
+
+      break;
+    case ConnectionSource.HSQL_DIALECT:
+      sqlDialect = new HSQLDBDialect();
+
+      break;
+    }
+    return sqlDialect;
+  }
+
+  /**
+   * This method handles cases where the
+   * {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the
+   * JDBC driver implementation.
+   */
+  public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) {
+    try {
+      //
+      // invoking JDK 1.4 method by reflection
+      //
+      return ((Boolean) DatabaseMetaData.class.getMethod(
+          "supportsGetGeneratedKeys", (Class[]) null).invoke(meta,
+          (Object[]) null)).booleanValue();
+    } catch (Throwable e) {
+      addInfo("Could not call supportsGetGeneratedKeys method. This may be recoverable");
+      return false;
+    }
+  }
+
+  /**
+   * This method handles cases where the
+   * {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the JDBC
+   * driver implementation.
+   */
+  public boolean supportsBatchUpdates(DatabaseMetaData meta) {
+    try {
+      return meta.supportsBatchUpdates();
+    } catch (Throwable e) {
+      addInfo("Missing DatabaseMetaData.supportsBatchUpdates method.");
+      return false;
+    }
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,23 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db.dialect; 
+
+/** 
+ * The HSQLDB dialect. 
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+*/ 
+public class HSQLDBDialect implements SQLDialect { 
+ public static final String SELECT_CURRVAL = "CALL IDENTITY()"; 
+
+ public String getSelectInsertId() { 
+   return SELECT_CURRVAL; 
+ } 
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,27 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db.dialect; 
+
+/** 
+* The MS SQL Server dialect is untested. 
+* 
+* Note that the dialect is not needed if your JDBC driver supports 
+* the getGeneratedKeys method introduced in JDBC 3.0 specification.
+* 
+* @author James Stauffer 
+*/ 
+public class MsSQLDialect implements SQLDialect { 
+ public static final String SELECT_CURRVAL = "SELECT @@identity id"; 
+
+ public String getSelectInsertId() { 
+   return SELECT_CURRVAL; 
+ } 
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,24 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db.dialect;
+
+/**
+ * 
+ * 
+ * @author Ceki
+ *
+ */
+public class MySQLDialect implements SQLDialect {
+  public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";
+  
+  public String getSelectInsertId() {
+    return SELECT_LAST_INSERT_ID;
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,26 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db.dialect;
+
+/**
+ * The Oracle dialect. Tested successfully on Oracle9i Release 9.2.0.3.0 by 
+ * James Stauffer.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public class OracleDialect implements SQLDialect {
+  public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual";
+
+  public String getSelectInsertId() {
+    return SELECT_CURRVAL;
+  }
+
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,28 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.db.dialect;
+
+
+/**
+ * 
+ * @author ceki
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class PostgreSQLDialect
+       implements SQLDialect {
+  public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')";
+
+  public String getSelectInsertId() {
+    return SELECT_CURRVAL;
+  }
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,20 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.db.dialect;
+
+/**
+ * @author ceki
+ *
+ */
+public interface SQLDialect {
+  
+  public String getSelectInsertId();
+  
+}

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,48 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for IBM DB2 databases.
+#
+# WARNING  WARNING WARNING  WARNING 
+# =================================
+# This SQL script has not been tested on an actual DB2
+# instance. It may contain errors or even invalid SQL
+# statements.
+
+DROP TABLE  logging_event_property;
+DROP TABLE  logging_event_exception;
+DROP TABLE  logging_event;
+
+CREATE TABLE logging_event 
+  (
+    sequence_number   BIGINT NOT NULL,
+    timestamp         BIGINT NOT NULL,
+    rendered_message  VARCHAR(4000) NOT NULL,
+    logger_name       VARCHAR(254) NOT NULL,
+    level_string      VARCHAR(254) NOT NULL,
+    ndc               VARCHAR(4000),
+    thread_name       VARCHAR(254),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR(254) NOT NULL,
+    caller_class      VARCHAR(254) NOT NULL,
+    caller_method     VARCHAR(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1)
+  );
+
+CREATE TABLE logging_event_property
+  (
+    event_id	      INTEGER NOT NULL,
+    mapped_key        VARCHAR(254) NOT NULL,
+    mapped_value      VARCHAR(1024),
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+
+CREATE TABLE logging_event_exception
+  (
+    event_id         INTEGER NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR(254) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,46 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for PostgreSQL databases.
+
+DROP TABLE    logging_event_property;
+DROP TABLE    logging_event_exception;
+DROP TABLE    logging_event;
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
+
+
+CREATE TABLE logging_event 
+  (
+    sequence_number   BIGINT NOT NULL,
+    timestamp         BIGINT NOT NULL,
+    rendered_message  TEXT NOT NULL,
+    logger_name       VARCHAR(254) NOT NULL,
+    level_string      VARCHAR(254) NOT NULL,
+    ndc               TEXT,
+    thread_name       VARCHAR(254),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR(254) NOT NULL,
+    caller_class      VARCHAR(254) NOT NULL,
+    caller_method     VARCHAR(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          INT IDENTITY GENERATED ALWAYS PRIMARY KEY
+  );
+
+CREATE TABLE logging_event_property
+  (
+    event_id	      INT NOT NULL,
+    mapped_key        VARCHAR(254) NOT NULL,
+    mapped_value      VARCHAR(1024),
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+
+CREATE TABLE logging_event_exception
+  (
+    event_id         INT NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR(254) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,44 @@
+// This SQL script creates the required tables by
+// ch.qos.logback.classic.db.DBAppender.
+//
+// It is intended for HSQLDB. 
+//
+
+DROP TABLE logging_event_exception IF EXISTS;
+DROP TABLE logging_event_property IF EXISTS;
+DROP TABLE logging_event IF EXISTS;
+
+
+CREATE TABLE logging_event 
+  (
+    timestmp         BIGINT NOT NULL,
+    formatted_message  LONGVARCHAR NOT NULL,
+    logger_name       VARCHAR(256) NOT NULL,
+    level_string      VARCHAR(256) NOT NULL,
+    thread_name       VARCHAR(256),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR(256), 
+    caller_class      VARCHAR(256), 
+    caller_method     VARCHAR(256), 
+    caller_line       CHAR(4), 
+    event_id          INT NOT NULL IDENTITY
+  );
+
+
+CREATE TABLE logging_event_property
+  (
+    event_id	      INT NOT NULL,
+    mapped_key        VARCHAR(254) NOT NULL,
+    mapped_value      LONGVARCHAR,
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+
+CREATE TABLE logging_event_exception
+  (
+    event_id         INT NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR(256) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,44 @@
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+-- 
+-- It is intended for MS SQL Server databases.  This has been tested with version 7.0. 
+
+DROP TABLE logging_event_property 
+DROP TABLE logging_event_exception 
+DROP TABLE logging_event 
+
+CREATE TABLE logging_event 
+  ( 
+    sequence_number   DECIMAL(20) NOT NULL, 
+    timestamp         DECIMAL(20) NOT NULL, 
+    rendered_message  VARCHAR(4000) NOT NULL, 
+    logger_name       VARCHAR(254) NOT NULL, 
+    level_string      VARCHAR(254) NOT NULL, 
+    ndc               VARCHAR(4000), 
+    thread_name       VARCHAR(254), 
+    reference_flag    SMALLINT, 
+    caller_filename   VARCHAR(254) NOT NULL,
+    caller_class      VARCHAR(254) NOT NULL,
+    caller_method     VARCHAR(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          INT NOT NULL identity, 
+    PRIMARY KEY(event_id) 
+  ) 
+
+CREATE TABLE logging_event_property 
+  ( 
+    event_id          INT NOT NULL, 
+    mapped_key        VARCHAR(254) NOT NULL, 
+    mapped_value      VARCHAR(1024), 
+    PRIMARY KEY(event_id, mapped_key), 
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id) 
+  ) 
+
+CREATE TABLE logging_event_exception 
+  ( 
+    event_id         INT NOT NULL, 
+    i                SMALLINT NOT NULL, 
+    trace_line       VARCHAR(254) NOT NULL, 
+    PRIMARY KEY(event_id, i), 
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id) 
+  ) 
+

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,51 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender.
+#
+# It is intended for MySQL databases. It has been tested on MySQL 5.0.22 with 
+# INNODB tables.
+
+
+BEGIN;
+DROP TABLE IF EXISTS logging_event_property;
+DROP TABLE IF EXISTS logging_event_exception;
+DROP TABLE IF EXISTS logging_event;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE logging_event 
+  (
+    timestmp         BIGINT NOT NULL,
+   	formatted_message  TEXT NOT NULL,
+    logger_name       VARCHAR(254) NOT NULL,
+    level_string      VARCHAR(254) NOT NULL,
+    thread_name       VARCHAR(254),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR(254) NOT NULL,
+    caller_class      VARCHAR(254) NOT NULL,
+    caller_method     VARCHAR(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          INT NOT NULL AUTO_INCREMENT PRIMARY KEY
+  );
+COMMIT;
+
+BEGIN;
+CREATE TABLE logging_event_property
+  (
+    event_id	      INT NOT NULL,
+    mapped_key        VARCHAR(254) NOT NULL,
+    mapped_value      TEXT,
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+COMMIT;
+
+BEGIN;
+CREATE TABLE logging_event_exception
+  (
+    event_id         INT NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR(254) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+COMMIT;
\ No newline at end of file

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,66 @@
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+--
+-- It is intended for Oracle databases.
+
+-- Tested successfully on Oracle9i Release 9.2.0.3.0 by James Stauffer
+
+-- The following lines are useful in cleaning any previous tables 
+
+--drop TRIGGER logging_event_id_seq_trig; 
+--drop SEQUENCE logging_event_id_seq; 
+--drop table logging_event_property; 
+--drop table logging_event_exception; 
+--drop table logging_event; 
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START WITH 1;
+
+CREATE TABLE logging_event 
+  (
+    sequence_number   NUMBER(20) NOT NULL,
+    timestamp         NUMBER(20) NOT NULL,
+    rendered_message  VARCHAR2(4000) NOT NULL,
+    logger_name       VARCHAR2(254) NOT NULL,
+    level_string      VARCHAR2(254) NOT NULL,
+    ndc               VARCHAR2(4000),
+    thread_name       VARCHAR2(254),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR2(254) NOT NULL,
+    caller_class      VARCHAR2(254) NOT NULL,
+    caller_method     VARCHAR2(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          NUMBER(10) PRIMARY KEY
+  );
+
+
+CREATE TRIGGER logging_event_id_seq_trig
+  BEFORE INSERT ON logging_event
+  FOR EACH ROW  
+  BEGIN  
+    SELECT logging_event_id_seq.NEXTVAL 
+    INTO   :NEW.event_id 
+    FROM   DUAL;  
+  END logging_event_id_seq_trig;
+
+
+CREATE TABLE logging_event_property
+  (
+    event_id	      NUMBER(10) NOT NULL,
+    mapped_key        VARCHAR2(254) NOT NULL,
+    mapped_value      VARCHAR2(1024),
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+  
+CREATE TABLE logging_event_exception
+  (
+    event_id         NUMBER(10) NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR2(254) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+  
+
+
+

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql	Tue Sep 26 18:14:59 2006
@@ -0,0 +1,47 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for PostgreSQL databases.
+
+DROP TABLE    logging_event_property;
+DROP TABLE    logging_event_exception;
+DROP SEQUENCE logging_event_id_seq;
+DROP TABLE    logging_event;
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
+
+
+CREATE TABLE logging_event 
+  (
+    sequence_number   BIGINT NOT NULL,
+    timestamp         BIGINT NOT NULL,
+    rendered_message  TEXT NOT NULL,
+    logger_name       VARCHAR(254) NOT NULL,
+    level_string      VARCHAR(254) NOT NULL,
+    ndc               TEXT,
+    thread_name       VARCHAR(254),
+    reference_flag    SMALLINT,
+    caller_filename   VARCHAR(254) NOT NULL,
+    caller_class      VARCHAR(254) NOT NULL,
+    caller_method     VARCHAR(254) NOT NULL,
+    caller_line       CHAR(4) NOT NULL,
+    event_id          INT DEFAULT nextval('logging_event_id_seq') PRIMARY KEY
+  );
+
+CREATE TABLE logging_event_property
+  (
+    event_id	      INT NOT NULL,
+    mapped_key        VARCHAR(254) NOT NULL,
+    mapped_value      VARCHAR(1024),
+    PRIMARY KEY(event_id, mapped_key),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );
+
+CREATE TABLE logging_event_exception
+  (
+    event_id         INT NOT NULL,
+    i                SMALLINT NOT NULL,
+    trace_line       VARCHAR(254) NOT NULL,
+    PRIMARY KEY(event_id, i),
+    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+  );



More information about the logback-dev mailing list