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();
}
};