You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2008/03/10 21:53:46 UTC

svn commit: r635687 - in /logging/log4cxx/trunk/src: changes/changes.xml main/cpp/exception.cpp main/cpp/odbcappender.cpp main/include/log4cxx/db/odbcappender.h main/include/log4cxx/helpers/exception.h

Author: carnold
Date: Mon Mar 10 13:53:41 2008
New Revision: 635687

URL: http://svn.apache.org/viewvc?rev=635687&view=rev
Log:
LOGCXX-248: ODBCAppender has Unicode issues

Modified:
    logging/log4cxx/trunk/src/changes/changes.xml
    logging/log4cxx/trunk/src/main/cpp/exception.cpp
    logging/log4cxx/trunk/src/main/cpp/odbcappender.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/db/odbcappender.h
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/exception.h

Modified: logging/log4cxx/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/changes/changes.xml?rev=635687&r1=635686&r2=635687&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/changes/changes.xml (original)
+++ logging/log4cxx/trunk/src/changes/changes.xml Mon Mar 10 13:53:41 2008
@@ -22,7 +22,7 @@
 <title>Apache log4cxx</title>
 </properties>
 <body>
-<release version="0.10.0" date="2008-02-29" description="First Apache release">
+<release version="0.10.0" date="2008-03-17" description="First Apache release">
 <action issue="LOGCXX-2">logger.h includes config.h</action>
 <action issue="LOGCXX-3">Missing #else</action>
 <action issue="LOGCXX-4">initialization not working on many OS's</action>
@@ -217,6 +217,7 @@
 <action issue="LOGCXX-242">Eliminate log4cxx proxies for APR types</action>
 <action issue="LOGCXX-243">Problem Compile in Doxy</action>
 <action issue="LOGCXX-247">MSVC project has wrong additional include directories</action>
+<action issue="LOGCXX-248">ODBCAppender has unicode issues</action>
 </release>
 <release version="0.9.7" date="2004-05-10">
 <action type="fix">Fixed examples source code in the "Short introduction to log4cxx".</action>

Modified: logging/log4cxx/trunk/src/main/cpp/exception.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/exception.cpp?rev=635687&r1=635686&r2=635687&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/exception.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/exception.cpp Mon Mar 10 13:53:41 2008
@@ -41,6 +41,20 @@
   msg[len] = 0;
 }
 
+Exception::Exception(const std::string& m) {
+  size_t len = m.size();
+  if (len > MSG_SIZE) {
+      len = MSG_SIZE;
+  }
+#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
+  memcpy_s(msg, sizeof msg, m.data(), len);
+#else
+  memcpy(msg, m.data(), len);
+#endif
+  msg[len] = 0;
+}
+
+
 Exception::Exception(const Exception& src) : std::exception() {
 #if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
       strcpy_s(msg, sizeof msg, src.msg);

Modified: logging/log4cxx/trunk/src/main/cpp/odbcappender.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/odbcappender.cpp?rev=635687&r1=635686&r2=635687&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/odbcappender.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/odbcappender.cpp Mon Mar 10 13:53:41 2008
@@ -38,6 +38,48 @@
 using namespace log4cxx::db;
 using namespace log4cxx::spi;
 
+SQLException::SQLException(short fHandleType, 
+                           void* hInput, const char* prolog) 
+                           : Exception(formatMessage(fHandleType, hInput, prolog)) {
+}
+
+
+SQLException::SQLException(const std::string& msg) 
+   : Exception(msg) {
+}
+
+SQLException::SQLException(const SQLException& src) 
+   : Exception(src) {
+}
+
+std::string SQLException::formatMessage(short fHandleType,
+                          void* hInput, const char* prolog) {
+   std::string strReturn(prolog);
+   strReturn.append(" - ");
+#if LOG4CXX_HAVE_ODBC
+   SQLCHAR       SqlState[6];
+   SQLCHAR       Msg[SQL_MAX_MESSAGE_LENGTH];
+   SQLINTEGER    NativeError;
+   SQLSMALLINT   i;
+   SQLSMALLINT   MsgLen;
+   SQLRETURN     rc2;
+
+   // Get the status records.
+   i = 1;
+   while ((rc2 = SQLGetDiagRecA(fHandleType, hInput, i, SqlState, &NativeError,
+                        Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) 
+   {
+      strReturn.append((char*) Msg);
+      i++;
+   }
+#else
+   strReturn.append("log4cxx built without ODBC support");
+#endif
+
+   return strReturn;
+}
+
+
 IMPLEMENT_LOG4CXX_OBJECT(ODBCAppender)
 
 
@@ -89,13 +131,13 @@
 }
 
 
-void ODBCAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& /* p */)
+void ODBCAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p)
 {
 #if LOG4CXX_HAVE_ODBC
    buffer.push_back(event);
 
    if (buffer.size() >= bufferSize)
-      flushBuffer();
+      flushBuffer(p);
 #endif      
 }
 
@@ -106,7 +148,7 @@
    return sbuf;
 }
 
-void ODBCAppender::execute(const LogString& sql)
+void ODBCAppender::execute(const LogString& sql, log4cxx::helpers::Pool& p)
 {
 #if LOG4CXX_HAVE_ODBC
    SQLRETURN ret;
@@ -115,22 +157,20 @@
 
    try
    {
-      con = getConnection();
+      con = getConnection(p);
 
       ret = SQLAllocHandle( SQL_HANDLE_STMT, con, &stmt);
       if (ret < 0)
       {
-       LOG4CXX_DECODE_CHAR(msg, GetErrorMessage( SQL_HANDLE_DBC, con, "Failed to allocate sql handle."));
-         throw SQLException( msg );
+         throw SQLException( SQL_HANDLE_DBC, con, "Failed to allocate sql handle.");
       }
 
-      LOG4CXX_ENCODE_CHAR( strEncodedSql, sql );
-      ret = SQLExecDirect(stmt, (SQLCHAR *)strEncodedSql.c_str(), SQL_NTS);
+      SQLWCHAR* wsql = Transcoder::wencode(sql, p); 
+      ret = SQLExecDirectW(stmt, wsql, SQL_NTS);
 
      if (ret < 0)
       {
-       LOG4CXX_DECODE_CHAR(msg, GetErrorMessage( SQL_HANDLE_STMT, stmt, "Failed to execute sql statement."));
-         throw SQLException( msg );
+         throw SQLException(SQL_HANDLE_STMT, stmt, "Failed to execute sql statement.");
       }
    }
    catch (SQLException& e)
@@ -145,7 +185,7 @@
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    closeConnection(con);
 #else
-    throw SQLException(LOG4CXX_STR("log4cxx build without ODBC support"));
+    throw SQLException("log4cxx build without ODBC support");
 #endif
 }
 
@@ -155,39 +195,11 @@
 {
 }
 
-std::string ODBCAppender::GetErrorMessage(ODBCAppender::SQLSMALLINT fHandleType, 
-    ODBCAppender::SQLHANDLE hInput, const char* szMsg )
-{
-#if LOG4CXX_HAVE_ODBC
-   SQLCHAR       SqlState[6];
-   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;
-#else
-   return "log4cxx built without ODBC support";
-#endif   
-}
 
 
 
 
-ODBCAppender::SQLHDBC ODBCAppender::getConnection()
+ODBCAppender::SQLHDBC ODBCAppender::getConnection(log4cxx::helpers::Pool& p)
 {
 #if LOG4CXX_HAVE_ODBC
    SQLRETURN ret;
@@ -197,18 +209,18 @@
       ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
       if (ret < 0)
       {
-         LOG4CXX_DECODE_CHAR(strErr, GetErrorMessage(SQL_HANDLE_ENV, env, "Failed to allocate SQL handle."));
+         SQLException ex(SQL_HANDLE_ENV, env, "Failed to allocate SQL handle.");
          env = SQL_NULL_HENV;
-         throw SQLException( strErr );
+         throw ex;
       }
 
       ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
       if (ret < 0)
       {
-         LOG4CXX_DECODE_CHAR(strErr, GetErrorMessage(SQL_HANDLE_ENV, env, "Failed to set odbc version."));
+         SQLException ex(SQL_HANDLE_ENV, env, "Failed to set odbc version.");
          SQLFreeHandle(SQL_HANDLE_ENV, env);
          env = SQL_NULL_HENV;
-         throw SQLException( strErr );
+         throw ex;
       }
    }
 
@@ -217,31 +229,29 @@
       ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &connection);
       if (ret < 0)
       {
-         LOG4CXX_DECODE_CHAR(strErr, GetErrorMessage(SQL_HANDLE_DBC, connection, "Failed to allocate sql handle."));
+         SQLException ex(SQL_HANDLE_DBC, connection, "Failed to allocate sql handle.");
          connection = SQL_NULL_HDBC;
-         throw SQLException( strErr );
+         throw ex;
       }
 
 
-     LOG4CXX_ENCODE_CHAR( URL, databaseURL );
-     LOG4CXX_ENCODE_CHAR( user, databaseUser );
-     LOG4CXX_ENCODE_CHAR( password, databasePassword );
+     SQLWCHAR* wURL = Transcoder::wencode(databaseURL, p);
 
-     SQLCHAR szOutConnectionString[1024];
+     wchar_t szOutConnectionString[1024];
      SQLSMALLINT nOutConnctionLength = 0;
 
-     ret = SQLDriverConnect( connection, NULL, 
-            (SQLCHAR *)URL.c_str(), SQL_NTS, 
+     ret = SQLDriverConnectW( connection, NULL, 
+            wURL, SQL_NTS, 
             szOutConnectionString, sizeof( szOutConnectionString ),
             &nOutConnctionLength, SQL_DRIVER_NOPROMPT );
 
 
      if (ret < 0)
       {
-         LOG4CXX_DECODE_CHAR(strErr, GetErrorMessage( SQL_HANDLE_DBC, connection, "Failed to connect to database."));
+         SQLException ex(SQL_HANDLE_DBC, connection, "Failed to connect to database.");
          SQLFreeHandle(SQL_HANDLE_DBC, connection);
          connection = SQL_NULL_HDBC;
-         throw SQLException( strErr );
+         throw ex;
       }
    }
 
@@ -256,9 +266,10 @@
    if (closed) {
        return;
    }
+   Pool p;
    try
    {
-      flushBuffer();
+      flushBuffer(p);
    }
    catch (SQLException& e)
    {
@@ -280,13 +291,8 @@
    this->closed = true;
 }
 
-void ODBCAppender::flushBuffer()
+void ODBCAppender::flushBuffer(Pool& p)
 {
-   //Do the actual logging
-   //removes.ensureCapacity(buffer.size());
-
-   Pool p;
-
    std::list<spi::LoggingEventPtr>::iterator i;
    for (i = buffer.begin(); i != buffer.end(); i++)
    {
@@ -294,7 +300,7 @@
       {
          const LoggingEventPtr& logEvent = *i;
          LogString sql = getLogStatement(logEvent, p);
-         execute(sql);
+         execute(sql, p);
       }
       catch (SQLException& e)
       {

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/db/odbcappender.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/db/odbcappender.h?rev=635687&r1=635686&r2=635687&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/db/odbcappender.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/db/odbcappender.h Mon Mar 10 13:53:41 2008
@@ -35,19 +35,16 @@
 {
         namespace db
         {
-            class LOG4CXX_EXPORT SQLException : public log4cxx::helpers::Exception
-                {
-                public:
-                SQLException(const LogString& msg) : log4cxx::helpers::Exception(msg) {
-                }
-                SQLException(const SQLException& src) : log4cxx::helpers::Exception(src) {
-                }
-
-                private:
-                SQLException& operator=(const SQLException&);
-                };
-
-                class ODBCAppender;
+            class LOG4CXX_EXPORT SQLException : public log4cxx::helpers::Exception {
+            public:
+                SQLException(short fHandleType, 
+                            void* hInput, const char* prolog);
+                SQLException(const std::string& msg);
+                SQLException(const SQLException& src);
+            private:
+                std::string formatMessage(short fHandleType,
+                    void* hInput, const char* prolog);
+            };
 
                 /**
                 <p><b>WARNING: This version of ODBCAppender
@@ -195,7 +192,8 @@
                         * end.  I use a connection pool outside of ODBCAppender which is
                         * accessed in an override of this method.
                         * */
-                        virtual void execute(const LogString& sql) /*throw(SQLException)*/;
+                        virtual void execute(const LogString& sql,
+                            log4cxx::helpers::Pool& p) /*throw(SQLException)*/;
 
                         /**
                         * Override this to return the connection to a pool, or to clean up the
@@ -206,15 +204,13 @@
                         */
                         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.
                         *
                         * By default this creates a single connection which is held open
                         * until the object is garbage collected.
                         */
-                        virtual SQLHDBC getConnection() /*throw(SQLException)*/;
+                        virtual SQLHDBC getConnection(log4cxx::helpers::Pool& p) /*throw(SQLException)*/;
 
                         /**
                         * Closes the appender, flushing the buffer first then closing the default
@@ -230,7 +226,7 @@
                         *
                         * If a statement fails the LoggingEvent stays in the buffer!
                         */
-                        virtual void flushBuffer();
+                        virtual void flushBuffer(log4cxx::helpers::Pool& p);
 
                         /**
                         * ODBCAppender requires a layout.

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/exception.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/exception.h?rev=635687&r1=635686&r2=635687&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/exception.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/exception.h Mon Mar 10 13:53:41 2008
@@ -32,6 +32,7 @@
                 class LOG4CXX_EXPORT Exception : public ::std::exception
                 {
                 public:
+                        Exception(const std::string& msg);
                         Exception(const LogString& msg);
                         Exception(const Exception& src);
                         Exception& operator=(const Exception& src);