/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LOG4CXX_DB_ODBC_APPENDER_H
#define _LOG4CXX_DB_ODBC_APPENDER_H

#if defined(_MSC_VER)
	#pragma warning ( push )
	#pragma warning ( disable: 4231 4251 4275 4786 )
#endif


#include <log4cxx/log4cxx.h>

#include <log4cxx/helpers/exception.h>
#include <log4cxx/appenderskeleton.h>
#include <log4cxx/spi/loggingevent.h>
#include <list>

namespace log4cxx
{
namespace db
{
class LOG4CXX_EXPORT SQLException : public log4cxx::helpers::Exception
{
	public:
		SQLException(short fHandleType,
			void* hInput, const char* prolog,
			log4cxx::helpers::Pool& p);
		SQLException(const char* msg);
		SQLException(const SQLException& src);
	private:
		const char* formatMessage(short fHandleType,
			void* hInput, const char* prolog,
			log4cxx::helpers::Pool& p);
};

/**
<p><b>WARNING: This version of ODBCAppender
is very likely to be completely replaced in the future. Moreoever,
it does not log exceptions.</b> </p>

The ODBCAppender provides for sending log events to a database.


<p>Each append call adds to an <code>ArrayList</code> buffer.  When
the buffer is filled each log event is placed in a sql statement
(configurable) and executed.

<b>BufferSize</b>, <b>db URL</b>, <b>User</b>, & <b>Password</b> are
configurable options in the standard log4j ways.

<p>The <code>setSql(String sql)</code> sets the SQL statement to be
used for logging -- this statement is sent to a
<code>PatternLayout</code> (either created automaticly by the
appender or added by the user).  Therefore by default all the
conversion patterns in <code>PatternLayout</code> can be used
inside of the statement.  (see the test cases for examples)

<p>Overriding the {@link #getLogStatement} method allows more
explicit control of the statement used for logging.

<p>For use as a base class:

<ul>

<li>Override getConnection() to pass any connection
you want.  Typically this is used to enable application wide
connection pooling.

<li>Override closeConnection -- if
you override getConnection make sure to implement
<code>closeConnection</code> to handle the connection you
generated.  Typically this would return the connection to the
pool it came from.

<li>Override getLogStatement to
produce specialized or dynamic statements. The default uses the
sql option value.

</ul>
*/

class LOG4CXX_EXPORT ODBCAppender : public AppenderSkeleton
{
	protected:
		/**
		* URL of the DB for default connection handling
		*/
		LogString databaseURL;

		/**
		* User to connect as for default connection handling
		*/
		LogString databaseUser;

		/**
		* User to use for default connection handling
		*/
		LogString databasePassword;

		typedef void* SQLHDBC;
		typedef void* SQLHENV;
		typedef void* SQLHANDLE;
		typedef short SQLSMALLINT;

		/**
		* Connection used by default.  The connection is opened the first time it
		* is needed and then held open until the appender is closed (usually at
		* garbage collection).  This behavior is best modified by creating a
		* sub-class and overriding the <code>getConnection</code> and
		* <code>closeConnection</code> methods.
		*/
		SQLHDBC connection;
		SQLHENV env;

		/**
		* Stores the string given to the pattern layout for conversion into a SQL
		* statement, eg: insert into LogTable (Thread, File, Message) values
		* ("%t", "%F", "%m")
		*
		* Be careful of quotes in your messages!
		*
		* Also see PatternLayout.
		*/
		LogString sqlStatement;

		/**
		* size of LoggingEvent buffer before writing to the database.
		* Default is 1.
		*/
		size_t bufferSize;

		/**
		* ArrayList holding the buffer of Logging Events.
		*/
		std::list<spi::LoggingEventPtr> buffer;

	public:
		DECLARE_LOG4CXX_OBJECT(ODBCAppender)
		BEGIN_LOG4CXX_CAST_MAP()
		LOG4CXX_CAST_ENTRY(ODBCAppender)
		LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
		END_LOG4CXX_CAST_MAP()

		ODBCAppender();
		virtual ~ODBCAppender();

		/**
		Set options
		*/
		virtual void setOption(const LogString& option, const LogString& value);

		/**
		Activate the specified options.
		*/
		virtual void activateOptions(log4cxx::helpers::Pool& p);

		/**
		* Adds the event to the buffer.  When full the buffer is flushed.
		*/
		void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool&);

		/**
		* By default getLogStatement sends the event to the required Layout object.
		* The layout will format the given pattern into a workable SQL string.
		*
		* Overriding this provides direct access to the LoggingEvent
		* when constructing the logging statement.
		*
		*/
	protected:
		LogString getLogStatement(const spi::LoggingEventPtr& event,
			helpers::Pool& p) const;

		/**
		*
		* Override this to provide an alertnate method of getting
		* connections (such as caching).  One method to fix this is to open
		* connections at the start of flushBuffer() and close them at the
		* end.  I use a connection pool outside of ODBCAppender which is
		* accessed in an override of this method.
		* */
		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
		* resource.
		*
		* The default behavior holds a single connection open until the appender
		* is closed (typically when garbage collected).
		*/
		virtual void closeConnection(SQLHDBC con);

		/**
		* 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(log4cxx::helpers::Pool& p) /*throw(SQLException)*/;

		/**
		* Closes the appender, flushing the buffer first then closing the default
		* connection if it is open.
		*/
	public:
		virtual void close();

		/**
		* loops through the buffer of LoggingEvents, gets a
		* sql string from getLogStatement() and sends it to execute().
		* Errors are sent to the errorHandler.
		*
		* If a statement fails the LoggingEvent stays in the buffer!
		*/
		virtual void flushBuffer(log4cxx::helpers::Pool& p);

		/**
		* ODBCAppender requires a layout.
		* */
		virtual bool requiresLayout() const
		{
			return true;
		}

		/**
		* Set pre-formated statement eg: insert into LogTable (msg) values ("%m")
		*/
		void setSql(const LogString& s);

		/**
		* Returns pre-formated statement eg: insert into LogTable (msg) values ("%m")
		*/
		inline const LogString& getSql() const
		{
			return sqlStatement;
		}


		inline void setUser(const LogString& user)
		{
			databaseUser = user;
		}


		inline void setURL(const LogString& url)
		{
			databaseURL = url;
		}


		inline void setPassword(const LogString& password)
		{
			databasePassword = password;
		}


		inline void setBufferSize(size_t newBufferSize)
		{
			bufferSize = newBufferSize;
		}

		inline const LogString& getUser() const
		{
			return databaseUser;
		}


		inline const LogString& getURL() const
		{
			return databaseURL;
		}


		inline const LogString& getPassword() const
		{
			return databasePassword;
		}

		inline size_t getBufferSize() const
		{
			return bufferSize;
		}
	private:
		ODBCAppender(const ODBCAppender&);
		ODBCAppender& operator=(const ODBCAppender&);
		static void encode(wchar_t** dest, const LogString& src,
			log4cxx::helpers::Pool& p);
		static void encode(unsigned short** dest, const LogString& src,
			log4cxx::helpers::Pool& p);
}; // class ODBCAppender
LOG4CXX_PTR_DEF(ODBCAppender);

} // namespace db
} // namespace log4cxx

#if defined(_MSC_VER)
	#pragma warning ( pop )
#endif

#endif // _LOG4CXX_DB_ODBC_APPENDER_H
