Index: src/odbcappender.cpp
===================================================================
RCS file: /home/cvspublic/logging-log4cxx/src/odbcappender.cpp,v
retrieving revision 1.15
diff -u -r1.15 odbcappender.cpp
--- src/odbcappender.cpp	4 May 2005 16:13:41 -0000	1.15
+++ src/odbcappender.cpp	8 Sep 2005 18:24:21 -0000
@@ -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 );
       }
    }
 
@@ -204,7 +234,7 @@
    }
    catch (SQLException& e)
    {
-      errorHandler->error(_T("Error closing connection"),
+      errorHandler->error(LOG4CXX_STR("Error closing connection"),
          e, ErrorCode::GENERIC_FAILURE);
    }
 
@@ -227,18 +257,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);
       }
    }
@@ -247,7 +279,7 @@
    buffer.clear();
 }
 
-void ODBCAppender::setSql(const String& s)
+void ODBCAppender::setSql(const LogString& s)
 {
    sqlStatement = s;
    if (getLayout() == 0)
