Author: carnold
Date: Fri Nov  4 09:45:00 2005
New Revision: 330853

URL: http://svn.apache.org/viewcvs?rev=330853&view=rev
Log:
LOGCXX-100: Fixes for ODBCAppender

Modified:
    logging/log4cxx/trunk/include/log4cxx/db/odbcappender.h
    logging/log4cxx/trunk/include/log4cxx/log4cxx.hw
    logging/log4cxx/trunk/src/class.cpp
    logging/log4cxx/trunk/src/odbcappender.cpp
    logging/log4cxx/trunk/tests/src/db/odbcappendertestcase.cpp

Modified: logging/log4cxx/trunk/include/log4cxx/db/odbcappender.h
URL: 
http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/db/odbcappender.h?rev=330853&r1=330852&r2=330853&view=diff
==============================================================================
--- logging/log4cxx/trunk/include/log4cxx/db/odbcappender.h (original)
+++ logging/log4cxx/trunk/include/log4cxx/db/odbcappender.h Fri Nov  4 09:45:00 
2005
@@ -16,7 +16,7 @@
 
 #ifndef _LOG4CXX_DB_ODBC_APPENDER_H
 #define _LOG4CXX_DB_ODBC_APPENDER_H
-
+#include <log4cxx/log4cxx.h>
 
 #ifdef LOG4CXX_HAVE_ODBC
 
@@ -25,7 +25,7 @@
 #include <log4cxx/spi/loggingevent.h>
 #include <list>
 
-#ifdef LOG4CXX_HAVE_MS_ODBC
+#ifdef _WIN32
 #include <windows.h>
 #endif
 
@@ -38,17 +38,12 @@
                 class LOG4CXX_EXPORT SQLException : public helpers::Exception
                 {
                 public:
-                        SQLException(int code) : code(code) {}
-                        SQLException(const SQLException& src) : 
Exception(src), code(src.code) {
-                        }
-                        const char* what() const throw() {
-                                return "SQLException";
+                   SQLException(const std::string& msg) : Exception(msg) {}
+                        SQLException(const SQLException& src) : Exception(src) 
{
                         }
-                        virtual ~SQLException() throw() {}
 
                 private:
                         SQLException& operator=(const SQLException&);
-                        int code;
                 };
 
                 class ODBCAppender;
@@ -168,7 +163,7 @@
                         /**
                         * Adds the event to the buffer.  When full the buffer 
is flushed.
                         */
-                        void append(const spi::LoggingEventPtr& event);
+                  void append(const spi::LoggingEventPtr& event, 
log4cxx::helpers::Pool&);
 
                         /**
                         * By default getLogStatement sends the event to the 
required Layout object.
@@ -179,7 +174,8 @@
                         *
                         */
                 protected:
-                        LogString getLogStatement(const spi::LoggingEventPtr& 
event) const;
+                        LogString getLogStatement(const spi::LoggingEventPtr& 
event,
+                     helpers::Pool& p) const;
 
                         /**
                         *
@@ -189,7 +185,7 @@
                         * end.  I use a connection pool outside of 
ODBCAppender which is
                         * accessed in an override of this method.
                         * */
-                        void execute(const LogString& sql) 
/*throw(SQLException)*/;
+                        virtual void execute(const LogString& sql) 
/*throw(SQLException)*/;
 
                         /**
                         * Override this to return the connection to a pool, or 
to clean up the
@@ -200,6 +196,8 @@
                         */
                         virtual void closeConnection(SQLHDBC con);
 
+                  virtual std::string GetErrorMessage( SQLSMALLINT 
fHandleType, SQLHANDLE hInput, const char* szMsg );
+
                         /**
                         * Override this to link with your connection pooling 
system.
                         *
@@ -222,7 +220,7 @@
                         *
                         * If a statement fails the LoggingEvent stays in the 
buffer!
                         */
-                        void flushBuffer();
+                        virtual void flushBuffer();
 
                         /**
                         * ODBCAppender requires a layout.

Modified: logging/log4cxx/trunk/include/log4cxx/log4cxx.hw
URL: 
http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/log4cxx.hw?rev=330853&r1=330852&r2=330853&view=diff
==============================================================================
--- logging/log4cxx/trunk/include/log4cxx/log4cxx.hw (original)
+++ logging/log4cxx/trunk/include/log4cxx/log4cxx.hw Fri Nov  4 09:45:00 2005
@@ -16,9 +16,9 @@
 #ifndef LOG4CXX_LOG4CXX_H
 #define LOG4CXX_LOG4CXX_H
 
-/* GENERATED FILE WARNING!  DO NOT EDIT log4cxx_private.h
+/* GENERATED FILE WARNING!  DO NOT EDIT log4cxx.h
  *
- * Edit log4cxx_private.h.in instead
+ * Edit log4cxx.hw instead
  *
  */
 
@@ -54,6 +54,8 @@
 #define LOG4CXX_LOCALE_ENCODING_UTF8 0
 #define LOG4CXX_LOCALE_ENCODING_ISO_8859_1 0
 #define LOG4CXX_LOCALE_ENCODING_US_ASCII 0
+
+#define LOG4CXX_HAVE_ODBC 1
 
 #endif
 

Modified: logging/log4cxx/trunk/src/class.cpp
URL: 
http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/class.cpp?rev=330853&r1=330852&r2=330853&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/class.cpp (original)
+++ logging/log4cxx/trunk/src/class.cpp Fri Nov  4 09:45:00 2005
@@ -19,6 +19,7 @@
 #include <log4cxx/helpers/object.h>
 #include <map>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/log4cxx.h>
 #include <log4cxx/private/log4cxx_private.h>
 
 
@@ -134,7 +135,7 @@
         ConsoleAppender::registerClass();
         FileAppender::registerClass();
 #ifdef LOG4CXX_HAVE_ODBC
-        ODBCAppender::registerClass();
+      log4cxx::db::ODBCAppender::registerClass();
 #endif
 #if defined(WIN32) || defined(_WIN32)
         NTEventLogAppender::registerClass();

Modified: logging/log4cxx/trunk/src/odbcappender.cpp
URL: 
http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/odbcappender.cpp?rev=330853&r1=330852&r2=330853&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/odbcappender.cpp (original)
+++ logging/log4cxx/trunk/src/odbcappender.cpp Fri Nov  4 09:45:00 2005
@@ -26,6 +26,7 @@
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/transcoder.h>
 #include <log4cxx/patternlayout.h>
 
 using namespace log4cxx;
@@ -35,6 +36,8 @@
 
 IMPLEMENT_LOG4CXX_OBJECT(ODBCAppender)
 
+
+
 ODBCAppender::ODBCAppender()
 : connection(SQL_NULL_HDBC), env(SQL_NULL_HENV), bufferSize(1)
 {
@@ -45,27 +48,27 @@
    finalize();
 }
 
-void ODBCAppender::setOption(const String& option,
-   const String& value)
+void ODBCAppender::setOption(const LogString& option, const LogString& value)
 {
-   if (StringHelper::equalsIgnoreCase(option, _T("buffersize")))
+   if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFERSIZE"), 
LOG4CXX_STR("buffersize")))
    {
       setBufferSize((size_t)OptionConverter::toInt(value, 1));
    }
-   else if (StringHelper::equalsIgnoreCase(option, _T("password")))
+   else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PASSWORD"), 
LOG4CXX_STR("password")))
    {
       setPassword(value);
    }
-   else if (StringHelper::equalsIgnoreCase(option, _T("sql")))
+   else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SQL"), 
LOG4CXX_STR("sql")))
    {
       setSql(value);
    }
-   else if (StringHelper::equalsIgnoreCase(option, _T("url"))
-      || StringHelper::equalsIgnoreCase(option, _T("dns")))
+   else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("URL"), 
LOG4CXX_STR("url"))
+      || StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DSN"), 
LOG4CXX_STR("dsn"))
+      || StringHelper::equalsIgnoreCase(option, 
LOG4CXX_STR("CONNECTIONSTRING"), LOG4CXX_STR("connectionstring"))  )
    {
       setURL(value);
    }
-   else if (StringHelper::equalsIgnoreCase(option, _T("user")))
+   else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("USER"), 
LOG4CXX_STR("user")))
    {
       setUser(value);
    }
@@ -75,7 +78,7 @@
    }
 }
 
-void ODBCAppender::append(const spi::LoggingEventPtr& event)
+void ODBCAppender::append(const spi::LoggingEventPtr& event, 
log4cxx::helpers::Pool& p)
 {
    buffer.push_back(event);
 
@@ -83,14 +86,14 @@
       flushBuffer();
 }
 
-String ODBCAppender::getLogStatement(const spi::LoggingEventPtr& event) const
+LogString ODBCAppender::getLogStatement(const spi::LoggingEventPtr& event, 
log4cxx::helpers::Pool& p) const
 {
-   StringBuffer sbuf;
-   getLayout()->format(sbuf, event);
-   return sbuf.str();
+   LogString sbuf;
+   getLayout()->format(sbuf, event, p);
+   return sbuf;
 }
 
-void ODBCAppender::execute(const String& sql)
+void ODBCAppender::execute(const LogString& sql)
 {
    SQLRETURN ret;
    SQLHDBC con = SQL_NULL_HDBC;
@@ -100,21 +103,18 @@
    {
       con = getConnection();
 
-      ret = SQLAllocHandle(SQL_HANDLE_STMT, con, &stmt);
+      ret = SQLAllocHandle( SQL_HANDLE_STMT, con, &stmt);
       if (ret < 0)
       {
-         throw SQLException(ret);
+         throw SQLException( GetErrorMessage( SQL_HANDLE_DBC, con, "Failed to 
allocate sql handle.") );
       }
 
-#if defined(LOG4CXX_HAVE_MS_ODBC)
-      ret = SQLExecDirect(stmt, (SQLTCHAR *)sql.c_str(), SQL_NTS);
-#else
-      USES_CONVERSION;
-      ret = SQLExecDirect(stmt, (SQLCHAR *)T2A(sql.c_str()), SQL_NTS);
-#endif
-      if (ret < 0)
+      LOG4CXX_ENCODE_CHAR( strEncodedSql, sql );
+      ret = SQLExecDirect(stmt, (SQLCHAR *)strEncodedSql.c_str(), SQL_NTS);
+
+     if (ret < 0)
       {
-         throw SQLException(ret);
+         throw SQLException( GetErrorMessage( SQL_HANDLE_STMT, stmt, "Failed 
to execute sql statement.") );
       }
    }
    catch (SQLException& e)
@@ -123,13 +123,13 @@
       {
          SQLFreeHandle(SQL_HANDLE_STMT, stmt);
       }
-
+   
       throw e;
    }
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    closeConnection(con);
 
-   //tcout << _T("Execute: ") << sql << std::endl;
+   //tcout << LOG4CXX_STR("Execute: ") << sql << std::endl;
 }
 
 /* The default behavior holds a single connection open until the appender
@@ -138,6 +138,34 @@
 {
 }
 
+std::string ODBCAppender::GetErrorMessage(SQLSMALLINT fHandleType, SQLHANDLE 
hInput, const char* szMsg )
+{
+   SQLCHAR       SqlState[6];
+   SQLCHAR       SQLStmt[100];
+   SQLCHAR       Msg[SQL_MAX_MESSAGE_LENGTH];
+   SQLINTEGER    NativeError;
+   SQLSMALLINT   i;
+   SQLSMALLINT   MsgLen;
+   SQLRETURN     rc2;
+
+   std::string   strReturn(szMsg);
+   strReturn += " - ";
+
+   // Get the status records.
+   i = 1;
+   while ((rc2 = SQLGetDiagRec(fHandleType, hInput, i, SqlState, &NativeError,
+                        Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) 
+   {
+      strReturn += (const char*) Msg;
+      i++;
+   }
+
+   return strReturn;
+}
+
+
+
+
 SQLHDBC ODBCAppender::getConnection()
 {
    SQLRETURN ret;
@@ -147,16 +175,18 @@
       ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
       if (ret < 0)
       {
+        std::string strErr = GetErrorMessage(SQL_HANDLE_ENV, env, "Failed to 
allocate SQL handle.");
          env = SQL_NULL_HENV;
-         throw SQLException(ret);
+         throw SQLException( strErr );
       }
 
       ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) 
SQL_OV_ODBC3, SQL_IS_INTEGER);
       if (ret < 0)
       {
+       std::string strErr = GetErrorMessage(SQL_HANDLE_ENV, env, "Failed to 
set odbc version.");
          SQLFreeHandle(SQL_HANDLE_ENV, env);
          env = SQL_NULL_HENV;
-         throw SQLException(ret);
+         throw SQLException( strErr );
       }
    }
 
@@ -165,31 +195,31 @@
       ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &connection);
       if (ret < 0)
       {
+       std::string strErr = GetErrorMessage(SQL_HANDLE_DBC, connection, 
"Failed to allocate sql handle.");
          connection = SQL_NULL_HDBC;
-         throw SQLException(ret);
+         throw SQLException( strErr );
       }
 
 
-#if defined(LOG4CXX_HAVE_MS_ODBC)
-      ret = SQLConnect(connection,
-         (SQLTCHAR *)databaseURL.c_str(), SQL_NTS,
-         (SQLTCHAR *)databaseUser.c_str(), SQL_NTS,
-         (SQLTCHAR *)databasePassword.c_str(), SQL_NTS);
-#else
-      USES_CONVERSION;
-      std::string URL = T2A(databaseURL.c_str());
-      std::string user = T2A(databaseUser.c_str());
-      std::string password = T2A(databasePassword.c_str());
-      ret = SQLConnect(connection,
-         (SQLCHAR *)URL.c_str(), SQL_NTS,
-         (SQLCHAR *)user.c_str(), SQL_NTS,
-         (SQLCHAR *)password.c_str(), SQL_NTS);
-#endif
-      if (ret < 0)
+     LOG4CXX_ENCODE_CHAR( URL, databaseURL );
+     LOG4CXX_ENCODE_CHAR( user, databaseUser );
+     LOG4CXX_ENCODE_CHAR( password, databasePassword );
+
+     SQLCHAR szOutConnectionString[1024];
+     SQLSMALLINT nOutConnctionLength = 0;
+
+     ret = SQLDriverConnect( connection, NULL, 
+            (SQLCHAR *)URL.c_str(), SQL_NTS, 
+            szOutConnectionString, sizeof( szOutConnectionString ),
+            &nOutConnctionLength, SQL_DRIVER_NOPROMPT );
+
+
+     if (ret < 0)
       {
+       std::string strErr = GetErrorMessage( SQL_HANDLE_DBC, connection, 
"Failed to connect to database.");
          SQLFreeHandle(SQL_HANDLE_DBC, connection);
          connection = SQL_NULL_HDBC;
-         throw SQLException(ret);
+         throw SQLException( strErr );
       }
    }
 
@@ -199,7 +229,7 @@
 void ODBCAppender::close()
 {
    if (closed) {
-       return true;
+       return;
    }
    try
    {
@@ -207,7 +237,7 @@
    }
    catch (SQLException& e)
    {
-      errorHandler->error(_T("Error closing connection"),
+      errorHandler->error(LOG4CXX_STR("Error closing connection"),
          e, ErrorCode::GENERIC_FAILURE);
    }
 
@@ -230,18 +260,20 @@
    //Do the actual logging
    //removes.ensureCapacity(buffer.size());
 
+   Pool p;
+
    std::list<spi::LoggingEventPtr>::iterator i;
    for (i = buffer.begin(); i != buffer.end(); i++)
    {
       try
       {
          const LoggingEventPtr& logEvent = *i;
-         String sql = getLogStatement(logEvent);
+         LogString sql = getLogStatement(logEvent, p);
          execute(sql);
       }
       catch (SQLException& e)
       {
-         errorHandler->error(_T("Failed to excute sql"), e,
+         errorHandler->error(LOG4CXX_STR("Failed to excute sql"), e,
             ErrorCode::FLUSH_FAILURE);
       }
    }
@@ -250,7 +282,7 @@
    buffer.clear();
 }
 
-void ODBCAppender::setSql(const String& s)
+void ODBCAppender::setSql(const LogString& s)
 {
    sqlStatement = s;
    if (getLayout() == 0)

Modified: logging/log4cxx/trunk/tests/src/db/odbcappendertestcase.cpp
URL: 
http://svn.apache.org/viewcvs/logging/log4cxx/trunk/tests/src/db/odbcappendertestcase.cpp?rev=330853&r1=330852&r2=330853&view=diff
==============================================================================
--- logging/log4cxx/trunk/tests/src/db/odbcappendertestcase.cpp (original)
+++ logging/log4cxx/trunk/tests/src/db/odbcappendertestcase.cpp Fri Nov  4 
09:45:00 2005
@@ -45,7 +45,7 @@
 public:
 
         AppenderSkeleton* createAppenderSkeleton() const {
-          return new log4cxx::db::ODBCAppender();
+         return new log4cxx::db::ODBCAppender();
         }
 };
 


Reply via email to