/*
 *  OpenDBX - A simple but extensible database abstraction layer
 *  Copyright (C) 2004-2008 Norbert Sendetzky and others
 *
 *  Distributed under the terms of the GNU Library General Public Licence
 * version 2 or (at your option) any later version.
 */



#include "lib/odbx_iface.hpp"
#include "lib/opendbx/api"
#include <vector>
#include <string>
#include <map>



#ifndef ODBX_IMPL_HPP
#define ODBX_IMPL_HPP



namespace OpenDBX
{
	using std::string;
	using std::vector;
	using std::map;



	class Lob_Impl : public Lob_Iface
	{
		odbx_lo_t* m_lo;
		odbx_result_t* m_result;
		bool m_close;

	public:

		Lob_Impl( odbx_result_t* result, const char* value );
		~Lob_Impl() throw();

		void close();

		ssize_t read( void* buffer, size_t buflen );
		ssize_t write( void* buffer, size_t buflen );
	};



	class Result_Impl : public Result_Iface
	{
		odbx_t* m_handle;
		odbx_result_t* m_result;
		map<const string, unsigned long> m_pos;

	public:

		Result_Impl( odbx_t* handle );
		~Result_Impl() throw();

		void finish();

		odbxres getResult( struct timeval* timeout, unsigned long chunk );

		odbxrow getRow();
		uint64_t rowsAffected();

		unsigned long columnCount();
		unsigned long columnPos( const string& name );
		const string columnName( unsigned long pos );
		odbxtype columnType( unsigned long pos );

		unsigned long fieldLength( unsigned long pos );
		const char* fieldValue( unsigned long pos );

		Lob_Iface* getLob( const char* value );
	};



	class Stmt_Impl : public Stmt_Iface
	{
		odbx_t* m_handle;

	protected:

	odbx_t* _getHandle() const throw();

	public:

		Stmt_Impl( odbx_t* handle );
	};



	class StmtSimple_Impl : public Stmt_Impl
	{
		string m_sql;
		vector<int> m_flags;
		vector<size_t> m_pos;
		vector<const void*> m_binds;
		vector<unsigned long> m_bindsize;
		size_t m_bufsize;
		char* m_buffer;

	protected:

// 		inline void _exec_params();
		inline void _exec_noparams();

	public:

		StmtSimple_Impl( odbx_t* handle, const string& sql );
		StmtSimple_Impl();
		~StmtSimple_Impl() throw();

// 		void bind( const void* data, unsigned long size, size_t pos, int flags );
// 		size_t count();

		Result_Iface* execute();
	};



	class Conn_Impl : public Conn_Iface
	{
		odbx_t* m_handle;
		char* m_escbuf;
		unsigned long m_escsize;
		bool m_unbind, m_finish;

	protected:

		inline char* _resize( char* buffer, size_t size );

	public:

		Conn_Impl( const char* backend, const char* host, const char* port );
		~Conn_Impl() throw();
		void finish();

		void bind( const char* database, const char* who, const char* cred, odbxbind method = ODBX_BIND_SIMPLE );
		void unbind();

		bool getCapability( odbxcap cap );

		void getOption( odbxopt option, void* value );
		void setOption( odbxopt option, void* value );

		string& escape( const char* from, unsigned long fromlen, string& to );

		Stmt_Iface* create( const string& sql, Stmt::Type type );
	};

}   // namespace



#endif
