text: //
  // Binder.h
  //
  // Library: Data/ODBC
  // Package: ODBC
  // Module:  Binder
  //
  // Definition of the Binder class.
  //
  // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
  // and Contributors.
  //
  // SPDX-License-Identifier:	BSL-1.0
  //
  
  
  #ifndef Data_ODBC_Binder_INCLUDED
  #define Data_ODBC_Binder_INCLUDED
  
  
  #include "Poco/Data/ODBC/ODBC.h"
  #include "Poco/Data/AbstractBinder.h"
  #include "Poco/Data/LOB.h"
  #include "Poco/Data/ODBC/Handle.h"
  #include "Poco/Data/ODBC/Parameter.h"
  #include "Poco/Data/ODBC/ODBCMetaColumn.h"
  #include "Poco/Data/ODBC/Utility.h"
  #include "Poco/Data/ODBC/TypeInfo.h"
  #include "Poco/Exception.h"
  #include <vector>
  #include <deque>
  #include <list>
  #include <map>
  #ifdef POCO_OS_FAMILY_WINDOWS
  #include <windows.h>
  #endif
  #include <sqlext.h>
  
  
  namespace Poco {
  
  
  class DateTime;
  
  
  namespace Data {
  
  
  class Date;
  class Time;
  
  
  namespace ODBC {
  
  
  class ODBC_API Binder: public Poco::Data::AbstractBinder
  	/// Binds placeholders in the sql query to the provided values. Performs data types mapping.
  {
  public:
  	typedef AbstractBinder::Direction Direction;
  	typedef std::map<SQLPOINTER, SQLLEN> ParamMap;
  
  	static const size_t DEFAULT_PARAM_SIZE = 1024;
  
  	enum ParameterBinding
  	{
  		PB_IMMEDIATE,
  		PB_AT_EXEC
  	};
  
  	Binder(const StatementHandle& rStmt,
  		std::size_t maxFieldSize,
  		ParameterBinding dataBinding = PB_IMMEDIATE,
  		const TypeInfo* pDataTypes = 0);
  		/// Creates the Binder.
  
  	~Binder();
  		/// Destroys the Binder.
  
  	void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
  		/// Binds an Int8.
  
  	void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir);
  		/// Binds an Int8 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir);
  		/// Binds an Int8 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir);
  		/// Binds an Int8 list.
  
  	void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
  		/// Binds an UInt8.
  
  	void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir);
  		/// Binds an UInt8 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir);
  		/// Binds an UInt8 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir);
  		/// Binds an UInt8 list.
  
  	void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
  		/// Binds an Int16.
  	
  	void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir);
  		/// Binds an Int16 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir);
  		/// Binds an Int16 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir);
  		/// Binds an Int16 list.
  
  	void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
  		/// Binds an UInt16.
  
  	void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir);
  		/// Binds an UInt16 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir);
  		/// Binds an UInt16 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir);
  		/// Binds an UInt16 list.
  
  	void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
  		/// Binds an Int32.
  
  	void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir);
  		/// Binds an Int32 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir);
  		/// Binds an Int32 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir);
  		/// Binds an Int32 list.
  
  	void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
  		/// Binds an UInt32.
  
  	void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir);
  		/// Binds an UInt32 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir);
  		/// Binds an UInt32 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir);
  		/// Binds an UInt32 list.
  
  	void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
  		/// Binds an Int64.
  
  	void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir);
  		/// Binds an Int64 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir);
  		/// Binds an Int64 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir);
  		/// Binds an Int64 list.
  
  	void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
  		/// Binds an UInt64.
  
  	void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir);
  		/// Binds an UInt64 vector.
  
  	void bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir);
  		/// Binds an UInt64 deque.
  
  	void bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir);
  		/// Binds an UInt64 list.
  
  #ifndef POCO_INT64_IS_LONG
  	void bind(std::size_t pos, const long& val, Direction dir);
  		/// Binds a long.
  
  	void bind(std::size_t pos, const unsigned long& val, Direction dir);
  		/// Binds an unsigned long.
  
  	void bind(std::size_t pos, const std::vector<long>& val, Direction dir);
  		/// Binds a long vector.
  
  	void bind(std::size_t pos, const std::deque<long>& val, Direction dir);
  		/// Binds a long deque.
  
  	void bind(std::size_t pos, const std::list<long>& val, Direction dir);
  		/// Binds a long list.
  #endif
  
  	void bind(std::size_t pos, const bool& val, Direction dir);
  		/// Binds a boolean.
  
  	void bind(std::size_t pos, const std::vector<bool>& val, Direction dir);
  		/// Binds a boolean vector.
  
  	void bind(std::size_t pos, const std::deque<bool>& val, Direction dir);
  		/// Binds a boolean deque.
  
  	void bind(std::size_t pos, const std::list<bool>& val, Direction dir);
  		/// Binds a boolean list.
  
  	void bind(std::size_t pos, const float& val, Direction dir);
  		/// Binds a float.
  
  	void bind(std::size_t pos, const std::vector<float>& val, Direction dir);
  		/// Binds a float vector.
  
  	void bind(std::size_t pos, const std::deque<float>& val, Direction dir);
  		/// Binds a float deque.
  
  	void bind(std::size_t pos, const std::list<float>& val, Direction dir);
  		/// Binds a float list.
  
  	void bind(std::size_t pos, const double& val, Direction dir);
  		/// Binds a double.
  
  	void bind(std::size_t pos, const std::vector<double>& val, Direction dir);
  		/// Binds a double vector.
  
  	void bind(std::size_t pos, const std::deque<double>& val, Direction dir);
  		/// Binds a double deque.
  
  	void bind(std::size_t pos, const std::list<double>& val, Direction dir);
  		/// Binds a double list.
  
  	void bind(std::size_t pos, const char& val, Direction dir);
  		/// Binds a single character.
  
  	void bind(std::size_t pos, const std::vector<char>& val, Direction dir);
  		/// Binds a character vector.
  
  	void bind(std::size_t pos, const std::deque<char>& val, Direction dir);
  		/// Binds a character deque.
  
  	void bind(std::size_t pos, const std::list<char>& val, Direction dir);
  		/// Binds a character list.
  
  	void bind(std::size_t pos, const std::string& val, Direction dir);
  		/// Binds a string.
  
  	void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir);
  		/// Binds a string vector.
  
  	void bind(std::size_t pos, const std::deque<std::string>& val, Direction dir);
  		/// Binds a string deque.
  
  	void bind(std::size_t pos, const std::list<std::string>& val, Direction dir);
  		/// Binds a string list.
  
  	void bind(std::size_t pos, const UTF16String& val, Direction dir);
  		/// Binds a string.
  
  	void bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir);
  		/// Binds a string vector.
  
  	void bind(std::size_t pos, const std::deque<UTF16String>& val, Direction dir);
  		/// Binds a string deque.
  
  	void bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir);
  		/// Binds a string list.
  
  	void bind(std::size_t pos, const BLOB& val, Direction dir);
  		/// Binds a BLOB. In-bound only.
  
  	void bind(std::size_t pos, const CLOB& val, Direction dir);
  		/// Binds a CLOB. In-bound only.
  
  	void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir);
  		/// Binds a BLOB vector.
  
  	void bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir);
  		/// Binds a BLOB deque.
  
  	void bind(std::size_t pos, const std::list<BLOB>& val, Direction dir);
  		/// Binds a BLOB list.
  
  	void bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir);
  		/// Binds a CLOB vector.
  
  	void bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir);
  		/// Binds a CLOB deque.
  
  	void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir);
  		/// Binds a CLOB list.
  
  	void bind(std::size_t pos, const Date& val, Direction dir);
  		/// Binds a Date.
  
  	void bind(std::size_t pos, const std::vector<Date>& val, Direction dir);
  		/// Binds a Date vector.
  
  	void bind(std::size_t pos, const std::deque<Date>& val, Direction dir);
  		/// Binds a Date deque.
  
  	void bind(std::size_t pos, const std::list<Date>& val, Direction dir);
  		/// Binds a Date list.
  
  	void bind(std::size_t pos, const Time& val, Direction dir);
  		/// Binds a Time.
  
  	void bind(std::size_t pos, const std::vector<Time>& val, Direction dir);
  		/// Binds a Time vector.
  
  	void bind(std::size_t pos, const std::deque<Time>& val, Direction dir);
  		/// Binds a Time deque.
  
  	void bind(std::size_t pos, const std::list<Time>& val, Direction dir);
  		/// Binds a Time list.
  
  	void bind(std::size_t pos, const DateTime& val, Direction dir);
  		/// Binds a DateTime.
  
  	void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir);
  		/// Binds a DateTime vector.
  
  	void bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir);
  		/// Binds a DateTime deque.
  
  	void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
  		/// Binds a DateTime list.
  
  	void bind(std::size_t pos, const NullData& val, Direction dir);
  		/// Binds a null. In-bound only.
  
  	void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir);
  		/// Binds a null vector.
  
  	void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir);
  		/// Binds a null deque.
  
  	void bind(std::size_t pos, const std::list<NullData>& val, Direction dir);
  		/// Binds a null list.
  
  	void setDataBinding(ParameterBinding binding);
  		/// Set data binding type.
  
  	ParameterBinding getDataBinding() const;
  		/// Return data binding type.
  
  	std::size_t parameterSize(SQLPOINTER pAddr) const;
  		/// Returns bound data size for parameter at specified position.
  
  	void synchronize();
  		/// Transfers the results of non-POD outbound parameters from internal 
  		/// holders back into the externally supplied buffers.
  
  	void reset();
  		/// Clears the cached storage.
  
  private:
  	typedef std::vector<SQLLEN*>                             LengthPtrVec;
  	typedef std::vector<SQLLEN>                              LengthVec;
  	typedef std::vector<LengthVec*>                          LengthVecVec;
  	typedef std::vector<char*>                               CharPtrVec;
  	typedef std::vector<UTF16Char*>                          UTF16CharPtrVec;
  	typedef std::vector<bool*>                               BoolPtrVec;
  	typedef std::vector<SQL_DATE_STRUCT>                     DateVec;
  	typedef std::vector<DateVec*>                            DateVecVec;
  	typedef std::vector<SQL_TIME_STRUCT>                     TimeVec;
  	typedef std::vector<TimeVec*>                            TimeVecVec;
  	typedef std::vector<SQL_TIMESTAMP_STRUCT>                DateTimeVec;
  	typedef std::vector<DateTimeVec*>                        DateTimeVecVec;
  	typedef std::vector<Poco::Any>                           AnyVec;
  	typedef std::vector<AnyVec>                              AnyVecVec;
  	typedef std::map<char*, std::string*>                    StringMap;
  	typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
  	typedef std::map<SQL_DATE_STRUCT*, Date*>                DateMap;
  	typedef std::map<SQL_TIME_STRUCT*, Time*>                TimeMap;
  	typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*>       TimestampMap;
  
  	void describeParameter(std::size_t pos);
  		/// Sets the description field for the parameter, if needed.
  
  	void bind(std::size_t pos, const char* const& pVal, Direction dir);
  		/// Binds a const char ptr. 
  		/// This is a private no-op in this implementation
  		/// due to security risk.
  
  	SQLSMALLINT toODBCDirection(Direction dir) const;
  		/// Returns ODBC parameter direction based on the parameter binding direction
  		/// specified by user.
  
  	template <typename T>
  	void bindImpl(std::size_t pos, T& val, SQLSMALLINT cDataType, Direction dir)
  	{
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
  
  		_lengthIndicator.push_back(0);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			cDataType, 
  			Utility::sqlDataType(cDataType), 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &val, 0, 0)))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter()");
  		}
  	}
  
  	template <typename L>
  	void bindImplLOB(std::size_t pos, const L& val, Direction dir)
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("LOB parameter type can only be inbound.");
  
  		SQLPOINTER pVal = (SQLPOINTER) val.rawContent();
  		SQLINTEGER size = (SQLINTEGER) val.size();
  			
  		_inParams.insert(ParamMap::value_type(pVal, size));
  
  		SQLLEN* pLenIn = new SQLLEN;
  		*pLenIn  = size;
  
  		if (PB_AT_EXEC == _paramBinding)
  			*pLenIn  = SQL_LEN_DATA_AT_EXEC(size);
  
  		_lengthIndicator.push_back(pLenIn);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			SQL_PARAM_INPUT, 
  			SQL_C_BINARY, 
  			SQL_LONGVARBINARY, 
  			(SQLUINTEGER) size,
  			0,
  			pVal,
  			(SQLINTEGER) size, 
  			_lengthIndicator.back())))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(LOB)");
  		}
  	}
  
  	template <typename T>
  	void bindImplVec(std::size_t pos, const std::vector<T>& val, SQLSMALLINT cDataType, Direction dir)
  	{
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("std::vector can only be bound immediately.");
  
  		std::size_t length = val.size();
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
  		setParamSetSize(length);
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length);
  		}
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			cDataType, 
  			Utility::sqlDataType(cDataType), 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &val[0], 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter()");
  		}
  	}
  
  	template <typename C>
  	void bindImplContainer(std::size_t pos, const C& val, SQLSMALLINT cDataType, Direction dir)
  		/// Utility function - a "stand-in" for non-vector containers.
  		/// Creates, fills and stores the reference to the replacement std::vector container
  		/// for std::deque and std::list. Calls std::vector binding.
  	{
  		typedef typename C::value_type Type;
  
  		if (_containers.size() <= pos)
  			_containers.resize(pos + 1);
  
  		_containers[pos].push_back(std::vector<Type>());
  
  		std::vector<Type>& cont = RefAnyCast<std::vector<Type> >(_containers[pos].back());
  		cont.assign(val.begin(), val.end());
  		bindImplVec(pos, cont, cDataType, dir);
  	}
  
  	template <typename C>
  	void bindImplContainerBool(std::size_t pos, const C& val, SQLSMALLINT cDataType, Direction dir)
  	{
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("std::vector can only be bound immediately.");
  
  		std::size_t length = val.size();
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
  
  		setParamSetSize(val.size());
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length);
  		}
  
  		if (_boolPtrs.size() <= pos)
  			_boolPtrs.resize(pos + 1);
  
  		_boolPtrs[pos] = new bool[val.size()];
  
  		typename C::const_iterator it = val.begin();
  		typename C::const_iterator end = val.end();
  		for (int i = 0; it != end; ++it, ++i) _boolPtrs[pos][i] = *it;
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			cDataType, 
  			Utility::sqlDataType(cDataType), 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &_boolPtrs[pos][0], 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter()");
  		}
  	}
  
  	template <typename C>
  	void bindImplContainerString(std::size_t pos, const C& val, Direction dir)
  		/// Utility function to bind containers of strings.
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("String container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Containers can only be bound immediately.");
  
  		std::size_t length = val.size();
  
  		if (0 == length)
  			throw InvalidArgumentException("Empty container not allowed.");
  
  		setParamSetSize(length);
  
  		SQLINTEGER size = 0;
  		getColumnOrParameterSize(pos, size);
  		poco_assert (size > 0);
  
  		if (size == _maxFieldSize)
  		{
  			getMinValueSize(val, size);
  			// accomodate for terminating zero
  			if (size != _maxFieldSize) ++size;
  		}
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1, SQL_NTS);
  		}
  
  		if (_charPtrs.size() <= pos)
  			_charPtrs.resize(pos + 1, 0);
  
  		_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
  		
  		std::size_t strSize;
  		std::size_t offset = 0;
  		typename C::const_iterator it = val.begin();
  		typename C::const_iterator end = val.end();
  		for (; it != end; ++it)
  		{
  			strSize = it->size();
  			if (strSize > size)	
  				throw LengthExceededException("SQLBindParameter(std::vector<std::string>)");
  			std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
  			offset += size;
  		}
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			SQL_C_CHAR, 
  			SQL_LONGVARCHAR, 
  			(SQLUINTEGER) size - 1,
  			0,
  			_charPtrs[pos], 
  			(SQLINTEGER) size, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(std::vector<std::string>)");
  		}
  	}
  
  	template <typename C>
  	void bindImplContainerUTF16String(std::size_t pos, const C& val, Direction dir)
  		/// Utility function to bind containers of strings.
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("String container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Containers can only be bound immediately.");
  
  		std::size_t length = val.size();
  		if (0 == length)
  			throw InvalidArgumentException("Empty container not allowed.");
  
  		setParamSetSize(val.size());
  
  		SQLINTEGER size = 0;
  		getColumnOrParameterSize(pos, size);
  		poco_assert(size > 0);
  
  		if (size == _maxFieldSize)
  		{
  			getMinValueSize(val, size);
  			// accomodate for terminating zero
  			if (size != _maxFieldSize) size += sizeof(UTF16Char);
  		}
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1, SQL_NTS);
  		}
  
  		if (_utf16CharPtrs.size() <= pos)
  			_utf16CharPtrs.resize(pos + 1, 0);
  
  		_utf16CharPtrs[pos] = (UTF16Char*)std::calloc(val.size() * size, sizeof(UTF16Char));
  
  		std::size_t strSize;
  		std::size_t offset = 0;
  		char* pBuf = (char*)_utf16CharPtrs[pos];
  		typename C::const_iterator it = val.begin();
  		typename C::const_iterator end = val.end();
  		for (; it != end; ++it)
  		{
  			strSize = it->size() * sizeof(UTF16Char);
  			if (strSize > size)
  				throw LengthExceededException("SQLBindParameter(std::vector<UTF16String>)");
  			std::memcpy(pBuf + offset, it->data(), strSize);
  			offset += size;
  		}
  
  		if (Utility::isError(SQLBindParameter(_rStmt,
  			(SQLUSMALLINT)pos + 1,
  			toODBCDirection(dir),
  			SQL_C_WCHAR,
  			SQL_WLONGVARCHAR,
  			(SQLUINTEGER)size - 1,
  			0,
  			_utf16CharPtrs[pos],
  			(SQLINTEGER)size,
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(std::vector<UTF16String>)");
  		}
  	}
  
  	template <typename C>
  	void bindImplContainerLOB(std::size_t pos, const C& val, Direction dir)
  	{
  		typedef typename C::value_type LOBType;
  		typedef typename LOBType::ValueType CharType;
  
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("BLOB container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Containers can only be bound immediately.");
  
  		std::size_t length = val.size();
  		if (0 == length)
  			throw InvalidArgumentException("Empty container not allowed.");
  
  		setParamSetSize(length);
  
  		SQLINTEGER size = 0;
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
  		}
  
  		std::vector<SQLLEN>::iterator lIt = _vecLengthIndicator[pos]->begin();
  		std::vector<SQLLEN>::iterator lEnd = _vecLengthIndicator[pos]->end();
  		typename C::const_iterator cIt = val.begin();
  		for (; lIt != lEnd; ++lIt, ++cIt) 
  		{
  			SQLLEN sz = static_cast<SQLLEN>(cIt->size());
  			if (sz > size) size = static_cast<SQLINTEGER>(sz);
  			*lIt = sz;
  		}
  
  		if (_charPtrs.size() <= pos)
  			_charPtrs.resize(pos + 1, 0);
  
  		_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(CharType));
  		poco_check_ptr (_charPtrs[pos]);
  
  		std::size_t blobSize;
  		std::size_t offset = 0;
  		cIt = val.begin();
  		typename C::const_iterator cEnd = val.end();
  		for (; cIt != cEnd; ++cIt)
  		{
  			blobSize = cIt->size();
  			if (blobSize > size)	
  				throw LengthExceededException("SQLBindParameter(std::vector<BLOB>)");
  			std::memcpy(_charPtrs[pos] + offset, cIt->rawContent(), blobSize * sizeof(CharType));
  			offset += size;
  		}
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			SQL_PARAM_INPUT, 
  			SQL_C_BINARY, 
  			SQL_LONGVARBINARY, 
  			(SQLUINTEGER) size,
  			0,
  			_charPtrs[pos], 
  			(SQLINTEGER) size, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(std::vector<BLOB>)");
  		}
  	}
  
  	template<typename C>
  	void bindImplContainerDate(std::size_t pos, const C& val, Direction dir)
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("Date vector parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("std::vector can only be bound immediately.");
  
  		std::size_t length = val.size();
  
  		if (0 == length)
  			throw InvalidArgumentException("Empty vector not allowed.");
  
  		setParamSetSize(length);
  
  		SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
  		}
  
  		if (_dateVecVec.size() <= pos)
  		{
  			_dateVecVec.resize(pos + 1, 0);
  			_dateVecVec[pos] = new DateVec(length ? length : 1);
  		}
  
  		Utility::dateSync(*_dateVecVec[pos], val);
  
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, SQL_TYPE_DATE, colSize, decDigits);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			SQL_C_TYPE_DATE, 
  			SQL_TYPE_DATE, 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &(*_dateVecVec[pos])[0], 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(Date[])");
  		}
  	}
  
  	template<typename C>
  	void bindImplContainerTime(std::size_t pos, const C& val, Direction dir)
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("Time container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Containers can only be bound immediately.");
  
  		std::size_t length = val.size();
  		if (0 == length)
  			throw InvalidArgumentException("Empty container not allowed.");
  
  		setParamSetSize(val.size());
  
  		SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIME_STRUCT);
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
  		}
  
  		if (_timeVecVec.size() <= pos)
  		{
  			_timeVecVec.resize(pos + 1, 0);
  			_timeVecVec[pos] = new TimeVec(length ? length : 1);
  		}
  
  		Utility::timeSync(*_timeVecVec[pos], val);
  
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, SQL_TYPE_TIME, colSize, decDigits);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			SQL_C_TYPE_TIME, 
  			SQL_TYPE_TIME, 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &(*_timeVecVec[pos])[0], 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(Time[])");
  		}
  	}
  
  	template<typename C>
  	void bindImplContainerDateTime(std::size_t pos, const C& val, Direction dir)
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("DateTime container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Containers can only be bound immediately.");
  
  		std::size_t length = val.size();
  
  		if (0 == length)
  			throw InvalidArgumentException("Empty Containers not allowed.");
  
  		setParamSetSize(length);
  
  		SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIMESTAMP_STRUCT);
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
  		}
  
  		if (_dateTimeVecVec.size() <= pos)
  		{
  			_dateTimeVecVec.resize(pos + 1, 0);
  			_dateTimeVecVec[pos] = new DateTimeVec(length ? length : 1);
  		}
  
  		Utility::dateTimeSync(*_dateTimeVecVec[pos], val);
  
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, SQL_TYPE_TIMESTAMP, colSize, decDigits);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			toODBCDirection(dir), 
  			SQL_C_TYPE_TIMESTAMP, 
  			SQL_TYPE_TIMESTAMP, 
  			colSize,
  			decDigits,
  			(SQLPOINTER) &(*_dateTimeVecVec[pos])[0], 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter(Time[])");
  		}
  	}
  
  	template<typename C>
  	void bindImplNullContainer(std::size_t pos, const C& val, Direction dir)
  	{
  		if (isOutBound(dir) || !isInBound(dir))
  			throw NotImplementedException("Null container parameter type can only be inbound.");
  
  		if (PB_IMMEDIATE != _paramBinding)
  			throw InvalidAccessException("Container can only be bound immediately.");
  
  		std::size_t length = val.size();
  
  		if (0 == length)
  			throw InvalidArgumentException("Empty container not allowed.");
  
  		setParamSetSize(length);
  
  		SQLINTEGER size = SQL_NULL_DATA;
  
  		if (_vecLengthIndicator.size() <= pos)
  		{
  			_vecLengthIndicator.resize(pos + 1, 0);
  			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
  		}
  
  		SQLINTEGER colSize = 0;
  		SQLSMALLINT decDigits = 0;
  		getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
  
  		if (Utility::isError(SQLBindParameter(_rStmt, 
  			(SQLUSMALLINT) pos + 1, 
  			SQL_PARAM_INPUT, 
  			SQL_C_STINYINT, 
  			Utility::sqlDataType(SQL_C_STINYINT), 
  			colSize,
  			decDigits,
  			0, 
  			0, 
  			&(*_vecLengthIndicator[pos])[0])))
  		{
  			throw StatementException(_rStmt, "SQLBindParameter()");
  		}
  	}
  
  	void getColSizeAndPrecision(std::size_t pos, 
  		SQLSMALLINT cDataType, 
  		SQLINTEGER& colSize, 
  		SQLSMALLINT& decDigits,
  		std::size_t actualSize = 0);
  		/// Used to retrieve column size and precision.
  		/// Not all drivers cooperate with this inquiry under all circumstances
  		/// This function runs for query and stored procedure parameters (in and 
  		/// out-bound). Some drivers, however, do not care about knowing this 
  		/// information to start with. For that reason, after all the attempts 
  		/// to discover the required values are unsuccesfully exhausted, the values 
  		/// are both set to zero and no exception is thrown.
  		/// However, if the colSize is succesfully retrieved and it is greater than
  		/// session-wide maximum allowed field size, LengthExceededException is thrown.
  
  	void setParamSetSize(std::size_t length);
  		/// Sets the parameter set size. Used for column-wise binding.
  
  	void getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size);
  		/// Fills the column or parameter size into the 'size' argument.
  		/// Does nothing if neither can be obtained from the driver, so
  		/// size should be set to some default value prior to calling this 
  		/// function in order to avoid undefined size value.
  
  	void freeMemory();
  		/// Frees all dynamically allocated memory resources.
  
  	template<typename T>
  	void getMinValueSize(T& val, SQLINTEGER& size)
  		/// Some ODBC drivers return DB-wide maximum allowed size for variable size columns,
  		/// rather than the allowed size for the actual column. In such cases, the length is 
  		/// automatically resized to the maximum field size allowed by the session.
  		/// This function, in order to prevent unnecessary memory allocation, does further 
  		/// optimization, looking for the maximum length within supplied data container and
  		/// uses the smaller of maximum found and maximum predefined data length.
  	{
  		typedef typename T::value_type ContainedValType;
  		typedef typename ContainedValType::value_type BaseValType;
  		std::size_t typeSize = sizeof(BaseValType);
  		std::size_t maxSize = 0;
  		typename T::const_iterator it = val.begin();
  		typename T::const_iterator end = val.end();
  		for (; it != end; ++it)
  		{
  			std::size_t sz = it->size() * typeSize;
  			if (sz > _maxFieldSize)
  				throw LengthExceededException();
  
  			if (sz == _maxFieldSize)
  			{
  				maxSize = 0;
  				break;
  			}
  
  			if (sz < _maxFieldSize && sz > maxSize)
  				maxSize = sz;
  		}
  		if (maxSize) size = static_cast<SQLINTEGER>(maxSize);
  	}
  
  	const StatementHandle& _rStmt;
  
  	LengthPtrVec     _lengthIndicator;
  	LengthVecVec     _vecLengthIndicator;
  
  	ParamMap         _inParams;
  	ParamMap         _outParams;
  	ParameterBinding _paramBinding;
  	
  	DateMap          _dates;
  	TimeMap          _times;
  	TimestampMap     _timestamps;
  	StringMap        _strings;
  	UTF16StringMap   _utf16Strings;
  
  	DateVecVec       _dateVecVec;
  	TimeVecVec       _timeVecVec;
  	DateTimeVecVec   _dateTimeVecVec;
  	CharPtrVec       _charPtrs;
  	UTF16CharPtrVec  _utf16CharPtrs;
  	BoolPtrVec       _boolPtrs;
  	const TypeInfo*  _pTypeInfo;
  	SQLINTEGER       _paramSetSize;
  	std::size_t      _maxFieldSize;
  	AnyVecVec        _containers;
  };
  
  
  //
  // inlines
  //
  inline void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_UTINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_UTINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_UTINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_UTINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_SSHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_SSHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SSHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SSHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_USHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_USHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_USHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_USHORT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_ULONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_ULONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_ULONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_ULONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_SBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_SBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_UBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_UBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_UBIGINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_UBIGINT, dir);
  }
  
  
  #ifndef POCO_INT64_IS_LONG
  inline void Binder::bind(std::size_t pos, const long& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<long>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<long>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SLONG, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<long>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_SLONG, dir);
  }
  #endif
  
  
  inline void Binder::bind(std::size_t pos, const float& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_FLOAT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_FLOAT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<float>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_FLOAT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<float>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_FLOAT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const double& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_DOUBLE, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_DOUBLE, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<double>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_DOUBLE, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<double>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_DOUBLE, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const bool& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_BIT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
  {
  	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<bool>& val, Direction dir)
  {
  	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<bool>& val, Direction dir)
  {
  	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const char& val, Direction dir)
  {
  	bindImpl(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
  {
  	bindImplVec(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<char>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<char>& val, Direction dir)
  {
  	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
  {
  	bindImplContainerString(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<std::string>& val, Direction dir)
  {
  	bindImplContainerString(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<std::string>& val, Direction dir)
  {
  	bindImplContainerString(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir)
  {
  	bindImplContainerUTF16String(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<UTF16String>& val, Direction dir)
  {
  	bindImplContainerUTF16String(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir)
  {
  	bindImplContainerUTF16String(pos, val, dir);
  }
  
  inline void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
  {
  	bindImplLOB<BLOB>(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const CLOB& val, Direction dir)
  {
  	bindImplLOB<CLOB>(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<BLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<CLOB>& val, Direction dir)
  {
  	bindImplContainerLOB(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Date>& val, Direction dir)
  {
  	bindImplContainerDate(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Date>& val, Direction dir)
  {
  	bindImplContainerDate(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Date>& val, Direction dir)
  {
  	bindImplContainerDate(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<Time>& val, Direction dir)
  {
  	bindImplContainerTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<Time>& val, Direction dir)
  {
  	bindImplContainerTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<Time>& val, Direction dir)
  {
  	bindImplContainerTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir)
  {
  	bindImplContainerDateTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir)
  {
  	bindImplContainerDateTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<DateTime>& val, Direction dir)
  {
  	bindImplContainerDateTime(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
  {
  	bindImplNullContainer(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir)
  {
  	bindImplNullContainer(pos, val, dir);
  }
  
  
  inline void Binder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir)
  {
  	bindImplNullContainer(pos, val, dir);
  }
  
  
  inline void Binder::setDataBinding(Binder::ParameterBinding binding)
  {
  	_paramBinding = binding;
  }
  
  
  inline Binder::ParameterBinding Binder::getDataBinding() const
  {
  	return _paramBinding;
  }
  
  
  } } } // namespace Poco::Data::ODBC
  
  
  #endif // Data_ODBC_Binder_INCLUDED
  