text: //! \file SQLAPI.h
  //! General SQLAPI++ include file.
  
  #if !defined(__SQLAPI_H__)
  #define __SQLAPI_H__
  
  #ifdef SQLAPI_EXPORTS
  #define SQLAPI_API __declspec(dllexport)
  #else
  #define SQLAPI_API
  #endif
  
  #ifdef SQLAPI_DECL_THROW
  #define SQLAPI_THROW(x) throw(x)
  #else
  #define SQLAPI_THROW(x)
  #endif
  
  #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || defined(_WINDOWS) || defined(_WINDOWS_)
  #ifndef SQLAPI_WINDOWS 
  #define SQLAPI_WINDOWS
  #endif
  #include <windows.h>
  #endif
  
  #if !defined(SQLAPI_WINDOWS) || defined (CYGWIN)
  #include <wchar.h>
  #include <wctype.h>
  #endif
  
  #ifndef SQLAPI_WINDOWS
  #include <sys/time.h>
  #endif
  
  #ifdef UNDER_CE
  #include <types.h>
  #else
  #include <sys/types.h>
  #include <sys/timeb.h>
  #endif
  #include <time.h>
  #include <stdarg.h>
  #if (defined(_MSC_VER) &&  _MSC_VER >= 1600) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x0630) || defined(__GNUC__) || defined(__SUNPRO_C)
  #define SA_HAVE_STDINT_H
  #include <stdint.h>
  #endif
  #include <limits.h>
  
  #ifndef SIZE_MAX
  #define SIZE_MAX ULONG_MAX
  #endif
  
  #ifdef SQLAPI_WINDOWS
  // 64-bit integer
  typedef __int64 sa_int64_t;
  typedef unsigned __int64 sa_uint64_t;
  // SQLAPI callback naming
  #define SQLAPI_CALLBACK __cdecl
  #else
  // 64-bit integer
  typedef long long int sa_int64_t;
  typedef unsigned long long int sa_uint64_t;
  // SQLAPI callback naming
  #define SQLAPI_CALLBACK
  #endif // ! SQLAPI_WINDOWS
  
  //! DBMS client type. Describes a list of supported DBMS client types.
  typedef
  enum eSAClient
  {
  	SA_Client_NotSpecified, //!< DBMS client is not specified
  	SA_ODBC_Client, //!< ODBC client
  	SA_Oracle_Client, //!< Oracle client
  	SA_SQLServer_Client, //!< Microsoft SQL Server client
  	SA_InterBase_Client, //!< InterBase/Firebird client
  	SA_SQLBase_Client, //!< SQLBase client
  	SA_DB2_Client, //!< IBM DB2 client
  	SA_Informix_Client, //!< Informix client
  	SA_Sybase_Client, //!< Sybase ASE client
  	SA_MySQL_Client, //!< MySQL client
  	SA_PostgreSQL_Client, //!< PostgreSQL client
  	SA_SQLite_Client, //!< SQLite client
  	SA_SQLAnywhere_Client, //!< SQL Anywhere client
  	SA_CubeSQL_Client, //!< CubeSQL client
  	SA_DuckDB_Client, //!< DuckDB client
  	_SA_Client_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SAClient_t;
  
  //! Possible types of errors. Describes a set of possible types of a error.
  typedef
  enum eSAErrorClass
  {
  	SA_No_Error, //!< no error occurred
  	SA_UserGenerated_Error, //!< user-generated error
  	SA_Library_Error, //!< the Library-generated error
  	SA_DBMS_API_Error, //!< DBMS API error occurred
  	_SA_ErrorClass_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SAErrorClass_t;
  
  //! Possible types of the Library errors. Describes a set of possible types of a error generated by SQLAPI++.
  typedef
  enum eSALibraryErrorType
  {
  	SA_Library_Error_Nomem, //!< The memory allocation failed
  	SA_Library_Error_ClientNotSet, //!< The DBMS client type is not set for SQLAPI++ object
  	SA_Library_Error_ClientNotSupported, //!< Requested DBMS client is not supported
  	SA_Library_Error_LoadLibraryFails, //!< Loading of the DBMS client API library failed
  	SA_Library_Error_GetLibraryVersionFails, //!< Reading of the DBMS client API library version failed
  	SA_Library_Error_ClientVersionOld, //!< DBMS client API version is too old
  	SA_Library_Error_ClientInitFails, //!< DBMS client API initialization failed
  	SA_Library_Error_BindVarNotFound, //!< Requested parameter not found (unknown number or name)
  	SA_Library_Error_FieldNotFound, //!< Requested field not found (unknown number or name)
  	SA_Library_Error_UnknownDataType, //!<  Unknown value data type detected
  	SA_Library_Error_UnknownParameterType, //!< Unknown command parameter type detected
  	SA_Library_Error_UnknownColumnType, //!< Unknown result column type detected
  	SA_Library_Error_WrongConversion, //!< Wrong conversion direction requested
  	SA_Library_Error_WrongDatetime, //!< Wrong date/time data or format
  	_SA_Library_Error_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SALibraryErrorType_t;
  
  //! Possible transaction isolation levels. Describes a set of possible transaction isolation levels.
  typedef
  enum eSAIsolationLevel
  {
  	//! the default(unknown) isolation level
  	SA_LevelUnknown = -1, //!< the default(unknown) isolation level
  	SA_ANSILevel0, //!< standard ANSI isolation level 0
  	SA_ANSILevel1, //!< standard ANSI isolation level 1
  	SA_ANSILevel2, //!< standard ANSI isolation level 2
  	SA_ANSILevel3, //!< standard ANSI isolation level 3
  	SA_Snapshot, //!< isolation level 'Snapshot'
  	SA_ReadUncommitted = SA_ANSILevel0, //!< isolation level 'Read Uncommitted'
  	SA_ReadCommitted = SA_ANSILevel1, //!< isolation level 'Read Committed'
  	SA_RepeatableRead = SA_ANSILevel2, //!< isolation level 'Repeatable Read'
  	SA_Serializable = SA_ANSILevel3, //!< isolation level 'Serializable'
  	_SA_IsolationLevel_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SAIsolationLevel_t;
  
  //! Possible auto-commit modes. Describes a set of possible auto-commit modes.
  typedef
  enum eSAAutoCommit
  {
  	SA_AutoCommitUnknown = -1, //!< the default(unknown) auto-commit mode
  	SA_AutoCommitOff, //!< auto-commit mode is off
  	SA_AutoCommitOn, //!< auto-commit mode is on
  	_SA_AutoCommit_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SAAutoCommit_t;
  
  //! SQLAPI++ program data types. Describes a list of supported data types.
  typedef
  enum eSADataType
  {
  	SA_dtUnknown, //!< data type is unknown
  	SA_dtBool, //!< data type is C bool
  	SA_dtShort, //!< data type is C short
  	SA_dtUShort, //!< data type is C unsigned short
  	SA_dtLong, //!< data type is C long
  	SA_dtULong, //!< data type is C unsigned long
  	SA_dtInt64, //!< data type is 8-bit integer
  	SA_dtUInt64, //!< data type is 8-bit unsigned integer
  	SA_dtDouble, //!< data type is C double
  	SA_dtNumeric, //!< data type is SANumeric
  	SA_dtDateTime, //!< data type is SADateTime
  	SA_dtInterval, //!< data type is SAInterval (MySQL specific - for MySQL TIME data type)
  	SA_dtString, //!< data type is character string (SAString)
  	SA_dtBytes, //!< data type is binary array (SAString)
  	SA_dtLongBinary, //!< data type is long binary data (SAString) 
  	SA_dtLongChar, //!< data type is long character data (SAString)
  	SA_dtBLob, //!< data type is BLob data (SAString)
  	SA_dtCLob, //!< data type is CLob data (SAString)
  	SA_dtCursor, //!< data type is Oracle REF CURSOR (SACommand - for Oracle only)
  	SA_dtSpecificToDBMS,  //!< data type is server-specific and not interpreted by SQLAPI++
  	_SA_DataType_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SADataType_t;
  
  /*! SACommand type. Describes a set of possible types of SACommand.
  By default the Library tries to determine the SQL command type itself.It analyzes
  the query command, sets the command types and build the parameter list.
  \remarks
  For any supported DBMS SQLAPI++ interprets the ":<name>" or ":<number>"
  SQL command substrings as a bind parameter positions and builds the parameter list.
  */
  typedef
  enum eSACommandType
  {
  	SA_CmdUnknown, //!< command type is not defined
  	SA_CmdSQLStmt, //!< command is an SQL statement (with or without parameters)
  	SA_CmdSQLStmtRaw, //!< command is a raw SQL statement and not interpreted by SQLAPI++
  	SA_CmdStoredProc, //!< command is a stored procedure or a function
  	_SA_Cmd_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SACommandType_t;
  
  //! SAParam direction type. Describes types of a command parameter.
  typedef
  enum eSAParamDirType
  {
  	SA_ParamInput, //!< Input parameter
  	SA_ParamInputOutput, //!< Input/output parameter
  	SA_ParamOutput, //!< Output parameter
  	SA_ParamReturn, //!< Returning parameter (function or procedure returning value)
  	_SA_ParamDirType_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SAParamDirType_t;
  
  //! Long or Lob (CLob) data reading mode. Describes Long or Lob(CLob) data reading modes.
  typedef
  enum eSALongOrLobReaderModes
  {
  	SA_LongOrLobReaderDefault, //!< Long or Lob (CLob) data reading mode is default
  	SA_LongOrLobReaderManual, //!< Long or Lob (CLob) data reading mode is manual
  	_SA_LongOrLobReaderModes_Reserved = (int)(((unsigned int)(-1)) / 2)
  } SALongOrLobReaderModes_t;
  
  /*! Read piece of LONG or Lob (CLob) data description.
  Describes read piece of LONG or Lob (CLob) data description
  */
  typedef
  enum eSAPieceType
  {
  	SA_FirstPiece = 1, //!< The first (but not the last) piece of data
  	SA_NextPiece = 2, //!< The next (not the first and not the last) piece of data
  	SA_LastPiece = 3, //!< The last piece of data
  	SA_OnePiece = 4, //!< All required data is represented as one block
  	_SA_Reserved_PieceType = (int)(((unsigned int)(-1)) / 2)
  } SAPieceType_t;
  
  #if defined(SA_UNICODE)
  //! SQLAPI++  macros for character constants
  #define _TSA(x)      L ## x
  //! Default type for character symbol
  typedef wchar_t SAChar;
  #else
  //! SQLAPI++  macros for character constants
  #define _TSA(x)      x
  //! Default type for character symbol
  typedef char SAChar;
  #endif
  
  // SAConnection options (common for at least several DBMS-es)
  // Workstation ID
  #define SACON_OPTION_WSID		_TSA("WSID")
  // Application Name
  #define SACON_OPTION_APPNAME	_TSA("APPNAME")
  
  // SACommand options (common for at least several DBMS-es)
  //! Pre-fetching rows SACommand option.
  #define SACMD_PREFETCH_ROWS		_TSA("PreFetchRows")
  //! Using scrollable cursor SACommand option.
  #define SACMD_SCROLLABLE		_TSA("Scrollable")
  //! Option value
  #define SAOPT_TRUE		_TSA("1")
  
  
  #ifdef __cplusplus
  
  //! Long or LOB writer callback, use for parameter binding
  typedef size_t(SQLAPI_CALLBACK* saLongOrLobWriter_t)(SAPieceType_t& ePieceType, void* pBuf, size_t nLen, void* pAddlData);
  
  /*! Long or LOB data reader callback.
  
  Define own function and use use it for the field or output parameter data fetching.
  
  \see SAField::ReadLongOrLob SAParam::ReadLongOrLob
  */
  typedef void (SQLAPI_CALLBACK* saLongOrLobReader_t)(
  	SAPieceType_t ePieceType, //!<Passed to the function from SQLAPI++ Library mechanisms. It  defines which piece of data value was read.
  	void* pBuf, //!< Pointer to the buffer that contains the data block read from database.
  	size_t nLen, //!< The actual size of data in buffer pBuf.
  	size_t nBlobSize, //!< Maximum size of whole long or Lob field (if DBMS server allows to know it before whole field was read; otherwise 0).
  	void* pAddlData /*!< An additional data user want to pass to the function. */);
  
  #ifdef SA_USE_STL
  #include <string>
  #endif
  
  class ISAClient;
  class ISAConnection;
  class ISACursor;
  
  class SAMutex;
  
  class SAPI;
  class SAConnection;
  class SACommand;
  
  struct sa_Connections;
  struct sa_Commands;
  
  class saOptionsStorage;
  class SAOptions;
  
  class saParams;
  class SAParam;
  class SAField;
  
  class SAException;
  
  class saPlaceHolder;
  
  class SABytes;
  class SALongBinary;
  class SALongChar;
  class SABLob;
  class SACLob;
  class SAValueRead;
  class SADateTime;
  class SANumeric;
  class SAInterval;
  
  //! Base class for all DBMS API wrappers.
  class SQLAPI_API IsaAPI
  {
  protected:
  	IsaAPI();
  
  public:
  	virtual ~IsaAPI();
  
  	virtual void InitializeClient(const SAOptions* pOptions) = 0;
  	virtual void UnInitializeClient(const SAPI* pSAPI, const SAOptions* pOptions) = 0;
  
  	virtual long GetClientVersion() const = 0;
  
  	virtual ISAConnection* NewConnection(SAConnection* pConnection) = 0;
  };
  
  //! Base class for DBMS specific connection handle(s).
  class SQLAPI_API saConnectionHandles
  {
  protected:
  	saConnectionHandles();
  public:
  	virtual ~saConnectionHandles();
  };
  
  //! Base class for DBMS specific command handle(s).
  class SQLAPI_API saCommandHandles
  {
  protected:
  	saCommandHandles();
  public:
  	virtual ~saCommandHandles();
  };
  
  struct SAStringData;
  
  //! Provides support for manipulating character values.
  class SQLAPI_API SAString
  {
  public:
  	//! \name Constructors
  	//! Each of SAString constructors initializes a new SAString object with the specified data.
  	//! @{
  	SAString();
  	SAString(const SAString& stringSrc);
  	SAString(SAChar ch, size_t nRepeat);
  	SAString(const char* lpsz);
  	SAString(const wchar_t* lpsz);
  	SAString(const char* lpch, size_t nLength);
  	SAString(const wchar_t* lpch, size_t nLength);
  	SAString(const unsigned char* psz);
  	SAString(const void* pBuffer, size_t nLengthInBytes);
  #ifdef SA_USE_STL
  public:
  	SAString(const std::string& stringSrc);
  	SAString(const std::wstring& stringSrc);
  #endif
  	//! @}
  
  	//! \name Attributes & Operations
  	//! @{
  
  	//! Returns the data length (in characters).
  	size_t GetLength() const;
  	//! Tests whether a SAString object contains no characters.
  	bool IsEmpty() const;
  	//! Clears contents to empty.
  	void Empty();
  	//! Directly accesses characters stored in a SAString object as a C-style string.
  	operator const SAChar* () const;
  	//! Converts the object to uppercase.
  	void MakeUpper();
  	//! Converts the object to lowercase.
  	void MakeLower();
  	//! @}
  
  	//! \name Overloaded assignment
  	//! @{
  
  	//! Ref-counted copy from another SAString
  	const SAString& operator =(const SAString& sSrc);
  	//! Sets string content to single character
  	const SAString& operator=(SAChar ch);
  #ifdef SA_UNICODE
  	//! Sets string content to single character
  	const SAString& operator=(char ch);
  #endif
  	//! Copies string content from ANSI (multi-byte) string (converts to SAChar)
  	const SAString& operator=(const char* lpsz);
  	//! Copies string content from UNICODE string (converts to SAChar)
  	const SAString& operator=(const wchar_t* lpsz);
  	//! Copies string content from unsigned chars
  	const SAString& operator=(const unsigned char* psz);
  	//! @}
  
  	//! \name String concatenation
  	//! @{
  	
  	//! Concatenates from another SAString.
  	const SAString& operator+=(const SAString& string);
  	//! Concatenates a single character.
  	const SAString& operator+=(SAChar ch);
  #ifdef SA_UNICODE
  	//! Concatenates an ANSI character after converting it to SAChar.
  	const SAString& operator+=(char ch);
  #endif
  	//! Concatenates from a SAChar string.
  	const SAString& operator+=(const SAChar* lpsz);
  
  	friend SAString SQLAPI_API operator+(const SAString& string1, const SAString& string2);
  	friend SAString SQLAPI_API operator+(const SAString& string, SAChar ch);
  	friend SAString SQLAPI_API operator+(SAChar ch, const SAString& string);
  #ifdef SA_UNICODE
  	friend SAString SQLAPI_API operator+(const SAString& string, char ch);
  	friend SAString SQLAPI_API operator+(char ch, const SAString& string);
  #endif
  	friend SAString SQLAPI_API operator+(const SAString& string, const SAChar* lpsz);
  	friend SAString SQLAPI_API operator+(const SAChar* lpsz, const SAString& string);
  	//! @}
  
  	//! \name String comparison
  	//! @{
  
  	//! Compares two strings (case sensitive).
  	int Compare(const SAChar* lpsz) const;
  	//! Compares two strings (case insensitive).
  	int CompareNoCase(const SAChar* lpsz) const;
  #ifndef UNDER_CE
  	//! Compares two strings (case sensitive, uses locale-specific information).
  	int Collate(const SAChar* lpsz) const;
  #endif
  	//! @}
  
  	//! \name Simple sub-string extraction
  	//! @{
  	SAString Mid(size_t nFirst) const;
  	SAString Mid(size_t nFirst, size_t nCount) const;
  	//! Extracts the left part of a string.
  	SAString Left(size_t nCount) const;
  	//! Extracts the right part of a string.
  	SAString Right(size_t nCount) const;
  	//! Returns the character at the specified string position.
  	SAChar GetAt(size_t nPos) const;
  	//! @}
  
  	//! \name Trimming whitespace (either side)
  	//! @{
  
  	//! Removes whitespace starting from right edge.
  	void TrimRight();
  	//! Removes whitespace starting from left side.
  	void TrimLeft();
  	//! @}
  
  	//! \name Trimming anything (either side)
  	//! @{
  
  	//! Removes continuous occurrences of chTarget starting from right.
  	void TrimRight(SAChar chTarget);
  	//! Removes continuous occurrences of characters in passed string, starting from right.
  	void TrimRight(const SAChar* lpszTargets);
  	//! Removes continuous occurrences of chTarget starting from left.
  	void TrimLeft(SAChar chTarget);
  	//! Removes continuous occurrences of characters in passed string, starting from left.
  	void TrimLeft(const SAChar* lpszTargets);
  	//! @}
  
  	//! \name Advanced manipulation
  	//! @{
  
  	//! Replaces indicated characters with other characters.
  	size_t Replace(const SAChar* lpszOld, const SAChar* lpszNew);
  	//! Inserts a single character or a substring at the given index within the string.
  	size_t Insert(size_t nIndex, SAChar ch);
  	size_t Insert(size_t nIndex, const SAChar* pstr);
  	//! Deletes a character or characters from a string.
  	size_t Delete(size_t nIndex, size_t nCount = 1);
  	//! @}
  
  	//! \name Searching
  	//! @{
  
  	//! Finds a character or substring inside a larger string.
  	size_t Find(SAChar ch) const;
  	size_t Find(SAChar ch, size_t nStart) const;
  	size_t Find(const SAChar* lpszSub) const;
  	size_t Find(const SAChar* lpszSub, size_t nStart) const;
  	//! Finds a character inside a larger string; starts from the end.
  	size_t ReverseFind(SAChar ch) const;
  	//! Finds the first matching character from a set.
  	size_t FindOneOf(const SAChar* lpszCharSet) const;
  	//! @}
  
  	//! \name Simple formatting
  	//! @{
  
  	//! Printf-like formatting using passed string.
  	void Format(const SAChar* lpszFormat, ...);
  	//! Printf-like formatting using variable arguments parameter.
  	void FormatV(const SAChar*, va_list argList);
  	//! @}
  
  	//! \name Access to string implementation buffer as "C" character array
  	//! @{
  
  	//! Returns a pointer to the characters in the SAString.
  	SAChar* GetBuffer(size_t nMinBufLength);
  	//! Releases control of the buffer returned by GetBuffer.
  	void ReleaseBuffer(size_t nNewLength = SIZE_MAX);
  	//! @}
  
  	//! \name Use LockBuffer/UnlockBuffer to turn ref counting off
  	//! @{
  
  	//! Disables reference counting and protects the string in the buffer.
  	SAChar* LockBuffer();
  	//! Enables reference counting and releases the string in the buffer.
  	void UnlockBuffer();
  	//! @}
  
  	//! \name Special buffer access routines to manipulate binary data
  	//! @{
  
  	//! Returns a count of the bytes in the binary data buffer.
  	size_t GetBinaryLength() const;
  	//! Returns pointer to const binary data buffer.
  	operator const void* () const;
  	//! Returns pointer to const binary data buffer.
  	const void* GetBinaryData() const;
  	//! Gets pointer to modifiable binary data buffer.
  	void* GetBinaryBuffer(size_t nMinBufLengthInBytes);
  	//! Releases control of the buffer returned by GetBinaryBuffer.
  	void ReleaseBinaryBuffer(size_t nNewLengthInBytes);
  	//! @}
  
  	//! \name Special conversion functions (multi-byte <-> Unicode)
  	//! @{
  
  	//! Returns pointer to const Unicode string, converts the data if needed.
  	const wchar_t* GetWideChars() const;
  	//! Returns the string length (in Unicode characters).
  	size_t GetWideCharsLength() const;
  	//! Return pointer to const multi-byte string, converts the data if needed.
  	const char* GetMultiByteChars() const;
  	//! Returns the string length (in multi-byte characters).
  	size_t GetMultiByteCharsLength() const;
  
  #ifdef SA_UNICODE
  	//! Returns pointer to const UTF8 string.
  	const char* GetUTF8Chars() const;
  	//! Returns the string length (in UTF8 characters).
  	size_t GetUTF8CharsLength() const;
  	//! Assigns the UTF8 data into SAString object.
  	void SetUTF8Chars(const char* szSrc, size_t nSrcLen = SIZE_MAX);
  #endif	// SA_UNICODE
  	//! Returns pointer to const UTF16 string.
  	const void* GetUTF16Chars() const;
  	//! Returns the string length (in UTF16 characters).
  	size_t GetUTF16CharsLength() const;
  	//! Assigns the UTF16 data into SAString object.
  	void SetUTF16Chars(const void* szSrc, size_t nSrcLen = SIZE_MAX);
  	//! @}
  
  	// Implementation
  public:
  	~SAString();
  
  protected:
  	SAChar* m_pchData;	// pointer to ref counted string data
  
  	// implementation helpers
  	SAStringData* GetData() const;
  	void Init();
  	void AllocBuffer(size_t nLen);
  #ifdef SA_UNICODE
  	void AssignBinaryCopy(size_t nSrcLenInBytes, const void* pSrcData);
  	void ConcatBinaryCopy(size_t nSrc1LenInBytes, const void* pSrc1Data, size_t nSrc2LenInBytes, const void* pSrc2Data);
  	void ConcatBinaryInPlace(size_t nSrcLen, const void* pData);
  #endif	// SA_UNICODE
  	void AssignCopy(size_t nSrcLen, const SAChar* lpszSrcData);
  	void ConcatCopy(size_t nSrc1Len, const SAChar* lpszSrc1Data, size_t nSrc2Len, const SAChar* lpszSrc2Data);
  	void ConcatInPlace(size_t nSrcLen, const SAChar* lpszSrcData);
  
  	void CopyBeforeWrite();
  	void AllocBeforeWrite(size_t nLen);
  	void Release();
  	static void Release(SAStringData* pData);
  	static size_t SafeStrlen(const SAChar* lpsz);
  	static void FreeData(SAStringData* pData);
  };
  
  // Compare helpers
  bool SQLAPI_API operator==(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator==(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator==(const SAChar* s1, const SAString& s2);
  bool SQLAPI_API operator!=(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator!=(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator!=(const SAChar* s1, const SAString& s2);
  bool SQLAPI_API operator<(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator<(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator<(const SAChar* s1, const SAString& s2);
  bool SQLAPI_API operator>(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator>(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator>(const SAChar* s1, const SAString& s2);
  bool SQLAPI_API operator<=(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator<=(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator<=(const SAChar* s1, const SAString& s2);
  bool SQLAPI_API operator>=(const SAString& s1, const SAString& s2);
  bool SQLAPI_API operator>=(const SAString& s1, const SAChar* s2);
  bool SQLAPI_API operator>=(const SAChar* s1, const SAString& s2);
  
  //! Defines a specific empty/NULL data class for SACommand \<\< operator.
  class SQLAPI_API SANull
  {
  };
  
  #define SA_NUMERIC_MANTISSA_SIZE 32
  //! Provides support for manipulating NUMERIC values.
  class SQLAPI_API SANumeric
  {
  	void InitZero();
  	bool setFromPlainString(const SAChar* sVal);
  	bool setFromExpString(const SAString& sVal);
  
  public:
  	SANumeric(); //!< Default constructor, initializes to zero.
  	SANumeric(double dVal);	//!< Initializes from double.
  	SANumeric& operator=(double); //!< Re-initializes from double.
  	operator double() const; //!< Converts to double.
  
  	SANumeric(sa_int64_t iVal); //!< Initializes from 64-bit integer.
  	SANumeric(sa_uint64_t iVal); //!< Initializes from unsigned 64-bit integer.
  	SANumeric& operator=(sa_int64_t); //!< Re-initializes from 64-bit integer.
  	SANumeric& operator=(sa_uint64_t); //!< Re-initializes from unsigned 64-bit integer.
  	operator sa_int64_t() const; //!< Converts to 64-bit integer.
  	operator sa_uint64_t() const; //!< Converts to unsigned 64-bit integer.
  
  	SANumeric& operator=(const SAChar* sVal); //!< Re-initializes from string.
  	operator SAString() const; //!< Converts to string.
  
  public:
  	unsigned char precision; //!< The maximum number of digits in base 10.
  	unsigned char scale; //!< The number of digits to the right of the decimal point.
  	unsigned char sign;	//!< The sign: 1 for positive numbers, 0 for negative numbers.
  
  	//! A number stored as SA_NUMERIC_MANTISSA_SIZE-byte scaled integer, with the least-significant byte on the left.
  	unsigned char val[SA_NUMERIC_MANTISSA_SIZE];
  };
  
  //! This is MySQL specific class that is used to represent MySQL TIME data type.
  class SQLAPI_API SAInterval
  {
  public:
  	SAInterval(); //!< Default constructor, initializes to zero.
  	SAInterval(double dVal); //!< Initializes from double.
  	SAInterval(long nDays, int nHours, int nMins, int nSecs); //!< Initializes with defined days, hours, minutes and seconds.
  	SAInterval(long nDays, int nHours, int nMins, int nSecs, unsigned int nNanoSeconds); //!< Initializes with defined days, hours, minutes, seconds and nanoseconds
  
  	double GetTotalDays() const; //!< Returns total days in interval.
  	double GetTotalHours() const; //!< Returns total hours in interval.
  	double GetTotalMinutes() const; //!< Returns total minutes in interval.
  	double GetTotalSeconds() const; //!< Returns total seconds in interval.
  
  	long GetDays() const; //!< Returns interval days.
  	long GetHours() const; //!< Returns interval hours.
  	long GetMinutes() const; //!< Returns interval minutes.
  	long GetSeconds() const; //!< Returns interval seconds.
  	unsigned int Fraction() const; //!< Returns interval nanoseconds.
  
  	//! Interval type operator.
  	//!@{
  	SAInterval operator+(const SAInterval& interval) const;
  	SAInterval operator-(const SAInterval& interval) const;
  	SAInterval& operator+=(const SAInterval interval);
  	SAInterval& operator-=(const SAInterval interval);
  	SAInterval operator-() const;
  	//!@}
  
  	operator double() const; //!< Converts interval into double.	
  	operator SAString() const; //!< Converts interval into string (format is [-]HH:MM:SS[.ZZZZZZZZZ])
  
  	//! Re-initializes with defined days, hours, minutes, seconds and nanoseconds.
  	void SetInterval(long nDays, int nHours, int nMins, int nSecs, unsigned int nNanoSeconds);
  	SAInterval& operator=(double dVal); //!< Re-initializes from double.
  
  private:
  	double m_interval;
  };
  
  //! Provides support for manipulating date/time values.
  class SQLAPI_API SADateTime
  {
  	friend class SAValueRead;
  
  	static int m_saMonthDays[13];
  
  protected:
  	static bool DateFromTm(
  		unsigned short wYear, unsigned short wMonth, unsigned short wDay,
  		unsigned short wHour, unsigned short wMinute, unsigned short wSecond,
  		unsigned int nNanoSecond,
  		double& dtDest);
  	static bool TmFromDate(
  		double dtSrc,
  		struct tm& tmDest, unsigned int& nNanoSecond);
  
  protected:
  	void Init_Tm();
  	void Init(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, unsigned int nFraction, const SAChar* timezone);
  	struct tm m_tm;
  	unsigned int m_nFraction;	// 0..999999999
  	SAString m_timezone;
  	struct {
  		bool hasDate;
  		bool hasTime;
  	} m_parts;
  
  public:
  	//! Default constructor creates empty date/time value.
  	SADateTime();
  	//! Constructs a SADateTime object from the specified values.
  	//!@{
  	SADateTime(int nYear, int nMonth, int nDay);
  	SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec);
  	SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, unsigned int nFraction);
  	SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, const SAChar* timezone);
  	SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, unsigned int nFraction, const SAChar* timezone);
  	SADateTime(int nHour, int nMin, int nSec, unsigned int nFraction);
  	//!@}
  	//! Constructs new SADateTime object from standard C structure struct tm.
  	SADateTime(const struct tm& tmValue);
  	//! Constructs new object from double value (DATE data type in Windows).
  	SADateTime(double dt);
  	//! Constructs new SADateTime object and parses a value from date/time string (ISO format or decimal number).
  	SADateTime(const SAChar* szValue);
  #ifndef UNDER_CE
  	//! Constructs new SADateTime object from standard C structure struct timeb.
  	SADateTime(const struct timeb& tmbValue);
  	//! Constructs new SADateTime object from standard C structure struct timeval.
  	SADateTime(const struct timeval& tmvValue);
  #endif
  #ifdef SQLAPI_WINDOWS
  	//! Constructs new SADateTime object from Windows SYSTEMTIME value.
  	SADateTime(SYSTEMTIME& st);
  #endif
  	//! Copy constructor.
  	SADateTime(const SADateTime& other);
  
  	//! Returns true if stored date part is defined with one of SADateTime constructors.
  	bool hasDate() const;
  	//! Returns true if stored time part is defined with one of SADateTime constructors.
  	bool hasTime() const;
  
  	//! Returns a reference to the current value of SADateTime object as struct tm object. You can modify this structure directly.
  	operator struct tm& ();
  	//! Returns struct tm object which is copied from this SADateTime object.
  	operator struct tm() const;
  	//! Returns a double (DATE in Windows) value whose value is calculated from this SADateTime object.
  	operator double() const;
  	//! Returns a representation of the SADateTime object as a string (format is 'YYYY-MM-DDTHH:MI:SS').
  	operator SAString() const;
  
  	//! Parses the value from a date/time string (ISO format or decimal number).
  	bool ParseString(const SAChar* szValue);
  
  	//! Returns the year this SADateTime object represents.
  	int GetYear() const;		// year, f.ex., 1999, 2000
  	//! Returns the month this SADateTime object represents (1-12).
  	int GetMonth() const;		// 1..12
  	//! Returns the day this SADateTime object represents (1-31).
  	int GetDay() const;			// 1..31
  	//! Returns the hour this SADateTime object represents (0-23).
  	int GetHour() const;		// 0..23
  	//! Returns the minute this SADateTime object represents (0-59).
  	int GetMinute() const;		// 0..59
  	//! Returns the second this SADateTime object represents (0-59).
  	int GetSecond() const;		// 0..59
  	//! Returns the day of the week this SADateTime object represents (Sunday = 1).
  	int GetDayOfWeek() const;	// 1..7, 1=Sunday, 2=Monday, and so on
  	//! Returns the day of the year this SADateTime object represents (Jan 1 = 1).
  	int GetDayOfYear() const;	// 1..366, where January 1 = 1
  	//! Returns a reference to the fraction part of the second represented by the value of this SADateTime object.
  	unsigned int& Fraction();
  	//! Returns a value of the fraction part of the second which is copied from this SADateTime object. 
  	unsigned int Fraction() const;
  	//! Returns a reference to the timezone represented by the value of this SADateTime object. 
  	SAString& Timezone();
  	//! Returns a value of the timezone from this SADateTime object. 
  	const SAChar* Timezone() const;
  
  #ifndef UNDER_CE
  	//! Sets the standard C timeb structure to the value this SADateTime object represents.
  	void GetTimeValue(struct timeb& tmv);
  	//! Sets the standard C structure struct timeval to the value this SADateTime object represents.
  	void GetTimeValue(struct timeval& tmv);
  #endif
  #ifdef SQLAPI_WINDOWS
  	//! Sets the Windows SYSTEMTIME value to the value this SADateTime object represents.
  	void GetTimeValue(SYSTEMTIME& st);
  #endif
  
  	//! Creates a SADateTime object that represents the current time (static member function).
  	static SADateTime SQLAPI_CALLBACK currentDateTime();
  	//! Creates a SADateTime object that represents the current time with fraction (static member function).
  	static SADateTime SQLAPI_CALLBACK currentDateTimeWithFraction();
  
  	//! Arithmetic operators - accept ot return SAInterval object.
  	//!@{
  	SADateTime operator+(SAInterval interval) const;
  	SADateTime operator-(SAInterval interval) const;
  	SADateTime& operator+=(SAInterval interval);
  	SADateTime& operator-=(SAInterval interval);
  	SAInterval operator-(const SADateTime& dt) const;
  	//!@}
  	
  	SADateTime& operator=(const SADateTime& dtSrc);
  };
  
  //! A subsidiary class to specify a parameter position for SACommand << operator.
  class SQLAPI_API SAPos
  {
  	friend class SACommand;
  
  	SAString m_sName;
  
  public:
  	SAPos(int nByID);
  	SAPos(const SAString& sByName);
  };
  
  //! A subsidiary class to specify an object with options.
  class SQLAPI_API SAOptions
  {
  public:
  	//! Default constructor.
  	SAOptions();
  	virtual ~SAOptions();
  
  public:
  	//! Sets a string value of a specific option. 
  	virtual SAString& setOption(const SAString& sOptionName);
  	//! Returns a string value of a specific option.
  	virtual SAString Option(const SAString& sOptionName) const;
  	//! Returns the count of options.
  	virtual int TotalOptions() const;
  	//! Returns the string value of an option.
  	virtual SAString OptionName(int nIndex) const;
  
  	bool getOptionValue(const SAString& sOption, bool bDefault) const;
  	int getOptionValue(const SAString& sOption, int nDefault) const;
  	SAString getOptionValue(const SAString& sOption, const SAChar* szDefault) const;
  
  protected:
  	saOptionsStorage* m_pOptions;
  };
  
  //! Represents a database API. The point you have to start with.
  class SQLAPI_API SAPI : public SAOptions
  {
  	friend class SAConnection;
  
  private:
  	// disable copy constructor
  	SAPI(const SAPI&);
  	// disable assignment operator
  	SAPI& operator = (const SAPI&);
  
  	SAClient_t m_eSAClient;
  	IsaAPI* m_pISAPI;
  	SAMutex* m_pConnectionsMutex;
  	sa_Connections* m_pConnections;
  	bool m_unloadAPI;
  	bool m_autoUnset;
  
  protected:
  	void RegisterConnection(SAConnection* pConnection);
  	void UnRegisterConnection(SAConnection* pConnection);
  	ISAConnection* GetISAConnection(const SAConnection* pConnection);
  	void setClientWithOptions(SAClient_t eSAClient, SAOptions* pOptions);
  
  public:
  	//! Default constructor.
  	SAPI(bool unloadAPI = false);
  	//! Initializes the object with specific DBMS API type.
  	SAPI(SAClient_t eSAClient, bool unloadAPI = false) SQLAPI_THROW(SAException);
  	//! A destructor.
  	virtual ~SAPI();
  
  public:
  	//! Assigns an DBMS client for the API class. 
  	void setClient(SAClient_t eSAClient) SQLAPI_THROW(SAException);
  	//! Returns the current DBMS client assigned for the connection.
  	SAClient_t Client() const;
  	//! Returns the DBMS client API version number. 
  	long ClientVersion() const SQLAPI_THROW(SAException);
  
  	//! Returns a native DBMS client API object.
  	IsaAPI* NativeAPI() const SQLAPI_THROW(SAException);
  
  	//! Returns native API unload flag value
  	bool isUnloadAPI() const;
  	//! Set native API auto-uninitialize flag value
  	void setAutoUnInitialize(bool bVal);
  };
  
  /*! Describes types of a handle called for DBMS connection.
  The Library allows to define the DBMS connection process handler.
  */
  typedef
  enum eSAConnectionHandlerType
  {
  	//! The handles is called after DBMS connection structures is allocated
  	SA_PreConnectHandler,
  	//! The handles is called after DBMS connection is established
  	SA_PostConnectHandler
  } SAConnectionHandlerType_t;
  
  //! DBMS connection handling callback
  typedef void (SQLAPI_CALLBACK* saConnectionHandler_t)(SAConnection& con, SAConnectionHandlerType_t eHandlerType);
  
  typedef void (SQLAPI_CALLBACK* EnumCursors_t)(ISACursor*, void*);
  
  //! The DBMS connection class. Represents an unique session with a data source.
  class SQLAPI_API SAConnection : public SAOptions
  {
  	friend class SACommand;
  	friend class SAField;
  	friend class SAParam;
  	friend class ISAConnection;
  	friend class oraExternalConnection;
  
  private:
  	// disable copy constructor
  	SAConnection(const SAConnection&);
  	// disable assignment operator
  	SAConnection& operator = (const SAConnection&);
  
  	SAPI* m_pSAPI;
  	SAMutex* m_pCommandsMutex;
  	sa_Commands* m_pCommands;
  
  	SAIsolationLevel_t m_eIsolationLevel;
  	SAAutoCommit_t m_eAutoCommit;
  
  	int	nReserved;
  
  protected:
  	void EnumCursors(EnumCursors_t fn, void* pAddlData);
  	void RegisterCommand(SACommand* pCommand);
  	void UnRegisterCommand(SACommand* pCommand);
  	ISACursor* GetISACursor(SACommand* pCommand);
  	ISAConnection* GetISAConnection();
  
  public:
  	//! Initialize a new SAConnection object.
  	SAConnection();
  	//! Initialize a new SAConnection object associated with SAPI object.
  	SAConnection(SAPI* pAPI);
  	//! A destructor.
  	virtual ~SAConnection();
  
  	//! Returns SAPI object associated with current SAConnection one.
  	SAPI* API() const;
  	//! Associates SAPI object with SAConnection one.
  	void setAPI(SAPI* pAPI) SQLAPI_THROW(SAException);
  	//! Assigns an DBMS client for SAPI associated with this SAConnection.
  	void setClient(SAClient_t eSAClient) SQLAPI_THROW(SAException);
  	//! Returns the current DBMS SAPI object type associated with the connection.
  	SAClient_t Client() const;
  	//! Returns the DBMS client API version number.
  	long ClientVersion() const SQLAPI_THROW(SAException);
  	//! Returns the currently connected DBMS server version number.
  	long ServerVersion() const SQLAPI_THROW(SAException);
  	//! Returns the currently connected DBMS server version string.
  	SAString ServerVersionString() const SQLAPI_THROW(SAException);
  
  	//! Returns the connection state for a particular connection object.
  	bool isConnected() const;
  	//! Returns the database server connection status for a particular connection object.
  	bool isAlive() const;
  	//! Opens the connection to a data source.
  	void Connect(
  		const SAString& sDBString,
  		const SAString& sUserID,
  		const SAString& sPassword,
  		SAClient_t eSAClient = SA_Client_NotSpecified,
  		saConnectionHandler_t fHandler = NULL) SQLAPI_THROW(SAException);
  	//! Disconnects the connection from the database.
  	void Disconnect() SQLAPI_THROW(SAException);
  	//! Destroys a broken connection.
  	void Destroy();
  	//! Clears all DBMS related handles and structures but doesn't destroy them.
  	void Reset();
  
  	//! Sets the transaction isolation level.
  	void setIsolationLevel(SAIsolationLevel_t eIsolationLevel) SQLAPI_THROW(SAException);
  	//! Returns the transaction isolation level.
  	SAIsolationLevel_t IsolationLevel() const;
  	//! Sets the connection to be committed automatically.
  	void setAutoCommit(SAAutoCommit_t eAutoCommit) SQLAPI_THROW(SAException);
  	//! Returns the auto commit mode set.
  	SAAutoCommit_t AutoCommit() const;
  	//! Commits transactions.
  	void Commit() SQLAPI_THROW(SAException);
  	//! Roll's back to last commit.
  	void Rollback() SQLAPI_THROW(SAException);
  
  	//! Returns a string value of a specific command option.
  	virtual SAString Option(const SAString& sOptionName) const;
  
  	//! Returns a set of functions of native DBMS client API.
  	IsaAPI* NativeAPI() const SQLAPI_THROW(SAException);
  	//! Returns native DBMS client connection related handle(s).
  	saConnectionHandles* NativeHandles() SQLAPI_THROW(SAException);
  
  	//! Returns next SACommand instance associated with the current connection.
  	SACommand* GetNextCommand(sa_Commands*& pCmds);
  };
  
  //! Callback for exception pre-handling
  typedef bool (SQLAPI_CALLBACK* PreHandleException_t)(SAException& x, void* pAddlData);
  
  //! Defines a specific command that you intend to execute against a data source.
  class SQLAPI_API SACommand : public SAOptions
  {
  	friend class SAConnection;
  	friend class IasaCursor;
  	friend class IibCursor;
  	friend class IsybCursor;
  	friend class IssDBLibCursor;
  	friend class IsbCursor;
  	friend class ImyCursor;
  	friend class IpgCursor;
  	friend class IoraConnection;
  	friend class IoraCursor;
  
  	friend class saParams;
  
  private:
  	// disable copy constructor
  	SACommand(const SACommand&);
  	// disable assignment operator
  	SACommand& operator = (const SACommand&);
  
  	SAConnection* m_pConnection;
  
  	SACommandType_t	m_eCmdType;
  	SAString		m_sCmd;
  	bool			m_bPrepared;
  	bool			m_bExecuted;
  	bool			m_bFieldsDescribed;
  	bool			m_bSelectBuffersSet;
  
  	bool			m_bParamsKnown;
  	int				m_nPlaceHolderCount;
  	saPlaceHolder** m_ppPlaceHolders;
  	saParams* m_pParams;
  	int				m_nCurParamID;
  	SAString		m_sCurParamName;
  
  	int				m_nFieldCount;
  	SAField** m_ppFields;
  
  	int	nReserved;
  
  	void Init();
  
  	static int CompareIdentifier(
  		const SAString& sIdentifier1,
  		const SAString& sIdentifier2);
  	SAParam& CreateParam(
  		const SAString& sName,
  		SADataType_t eParamType,
  		int nNativeType,
  		size_t nParamSize,
  		int	nParamPrecision,
  		int	nParamScale,
  		SAParamDirType_t eDirType,
  		const SAString& sFullName,
  		size_t nStart,	// param position in SQL statement
  		size_t nEnd);	// param end position in SQL statement
  	void GetParamsSP();
  	void UnDescribeParams();
  	void ParseInputMarkers(
  		SAString& sCmd,
  		bool* pbSpacesInCmd);
  
  	void DescribeFields() SQLAPI_THROW(SAException);
  	void CreateField(
  		const SAString& sName,
  		SADataType_t eFieldType,
  		int nNativeType,
  		size_t nFieldSize,
  		int nFieldPrecision,
  		int nFieldScale,
  		bool bFieldRequired,
  		int nTotalFieldCount);
  	void DestroyFields();
  
  	// parses sql statement and create bind parameters array if any (In)
  	// also cancels previous statement if any
  	void ParseCmd(
  		const SAString& sSQL,
  		SACommandType_t eCmdType);
  
  	void UnSetCommandText();
  	void UnPrepare();
  	void UnExecute();
  
  public:
  	//! Construct command with no associated connection and SQL
  	SACommand();
  	//! Construct command based on the given connection and SQL
  	SACommand(
  		SAConnection* pConnection,
  		const SAString& sCmd = SAString(),
  		SACommandType_t eCmdType = SA_CmdUnknown);
  	//! A destructor.
  	virtual ~SACommand();
  
  	//! Returns a pointer to the current SAConnection object.
  	SAConnection* Connection() const;
  	//! Associates a command with an existing SAConnection object.
  	void setConnection(SAConnection* pConnection);
  
  	//! Opens the specified SACommand object.
  	virtual void Open() SQLAPI_THROW(SAException);
  	//! Tests whether the specified SACommand object is opened.
  	virtual bool isOpened();
  	//! Tests whether the specified SACommand object is executed.
  	virtual bool isExecuted();
  	//! Closes the specified SACommand object.
  	virtual void Close() SQLAPI_THROW(SAException);
  	//! Destroys the command.
  	virtual void Destroy();
  	//! Clears all DBMS related handles and structures.
  	virtual void Reset();
  
  	//! Sets the command text.
  	void setCommandText(
  		const SAString& sSQL, //!< A SAString object represents command text string (an SQL statement or a stored procedure name).
  		SACommandType_t eCmdType = SA_CmdUnknown);
  	//! Returns the command text associated with the SACommand object.
  	SAString CommandText() const;
  	//! Returns the command type currently associated with the SACommand object.
  	SACommandType_t CommandType() const;
  	//! Validates and prepares the current command for execution.
  	virtual void Prepare() SQLAPI_THROW(SAException);
  	//! Executes the current command.
  	virtual void Execute() SQLAPI_THROW(SAException);
  	//! Tests whether a result set exists after the command execution.
  	bool isResultSet() SQLAPI_THROW(SAException);
  	//! Returns number of rows affected by last DML operation.
  	long RowsAffected() SQLAPI_THROW(SAException);
  	//! Fetches next row from a result set.
  	bool FetchNext() SQLAPI_THROW(SAException);
  	//! Fetches the previous row from a result set.
  	bool FetchPrior() SQLAPI_THROW(SAException);
  	//! Fetches the first row from a result set.
  	bool FetchFirst() SQLAPI_THROW(SAException);
  	//! Fetches the last row from a result set.
  	bool FetchLast() SQLAPI_THROW(SAException);
  	//! Fetches the specified row from a result set.
  	bool FetchPos(int offset, bool Relative = false) SQLAPI_THROW(SAException);
  	//! Attempts to cancel the pending result set, or current statement execution.
  	void Cancel() SQLAPI_THROW(SAException);
  
  	//!@{
  	//! Creates parameter associated with the specified command.
  	SAParam& CreateParam(
  		const SAString& sName, //!< A string representing the name of parameter
  		SADataType_t eParamType, //!< Type of the parameter's value
  		SAParamDirType_t eDirType = SA_ParamInput); //!< Type of the parameter
  	SAParam& CreateParam(
  		const SAString& sName, //!< A string representing the name of parameter
  		SADataType_t eParamType, //!< Type of the parameter's value
  		int nNativeType, //!< An integer value representes a code of server-specific data type, if known. Otherwise, -1 
  		size_t nParamSize, //!< An integer value represents parameter's value size
  		int	nParamPrecision, //!< An integer value represents parameter's value precision
  		int	nParamScale, //!< An integer value represents parameter's value scale
  		SAParamDirType_t eDirType); //!< Type of the parameter
  	//!@}
  	//! Destroys all parameters associated with the specified command.
  	void DestroyParams();
  	//! Returns the number of parameters associated with the SACommand object.
  	int ParamCount();
  	//! Returns the SAParam object by index in the parameters array.
  	SAParam& ParamByIndex(int i);
  	//! Returns the command parameter specified by its position.
  	SAParam& Param(int nParamByID);
  	//! Returns the command parameter specified by its name.
  	SAParam& Param(const SAString& sParamByName);
  	//! Binds input variables.
  	//!@{
  	SACommand& operator << (const SAPos& pos);
  	SACommand& operator << (const SANull& null);
  	SACommand& operator << (bool Value);
  	SACommand& operator << (short Value);
  	SACommand& operator << (unsigned short Value);
  	SACommand& operator << (long Value);
  	SACommand& operator << (unsigned long Value);
  	SACommand& operator << (double Value);
  	SACommand& operator << (const SANumeric& Value);
  	SACommand& operator << (sa_int64_t Value);
  	SACommand& operator << (sa_uint64_t Value);
  	SACommand& operator << (const SADateTime& Value);
  	SACommand& operator << (const SAChar* Value);	// special overload for string constants
  	SACommand& operator << (const SAString& Value);
  	SACommand& operator << (const SABytes& Value);
  	SACommand& operator << (const SALongBinary& Value);
  	SACommand& operator << (const SALongChar& Value);
  	SACommand& operator << (const SABLob& Value);
  	SACommand& operator << (const SACLob& Value);
  	SACommand& operator << (const SAValueRead& Value);
  	//!@}
  
  	//! Returns the number of fields (columns) in a result set.
  	int FieldCount() SQLAPI_THROW(SAException);
  	//! Returns the column specified by its position in the result set. 
  	SAField& Field(int nField) SQLAPI_THROW(SAException);
  	//! Returns the column specified by its name in the result set.
  	SAField& Field(const SAString& sField) SQLAPI_THROW(SAException);
  	//! Returns the column specified by its position in the result set.
  	SAField& operator[](int nField) SQLAPI_THROW(SAException);
  	//! Returns the column specified by its name in the result set.
  	SAField& operator[](const SAString& sField) SQLAPI_THROW(SAException);
  
  	//! Returns the string value of an option
  	virtual SAString Option(const SAString& sOptionName) const;
  
  	//! Returns native DBMS client command related handle(s).
  	saCommandHandles* NativeHandles() SQLAPI_THROW(SAException);
  	void setBatchExceptionPreHandler(PreHandleException_t fnHandler, void* pAddlData);
  };
  
  //! Base DBMS values storage class.
  class SQLAPI_API SAValueRead
  {
  	friend class ISACursor;
  	friend class IibCursor;
  	friend class IoraCursor;
  	friend class IsbCursor;
  	friend class IodbcCursor;
  	friend class IssDBLibCursor;
  	friend class IssOleDbCursor;
  	friend class Idb2Cursor;
  	friend class IinfCursor;
  	friend class IsybCursor;
  	friend class ImyCursor;
  	friend class IpgCursor;
  	friend class Isl3Cursor;
  	friend class IssNCliCursor;
  	friend class IasaCursor;
  	friend class IcubeSqlCursor;
  	friend class IssOleDbSequentialStream;
  	friend class IduckdbCursor;
  
  protected:
  	SALongOrLobReaderModes_t m_eReaderMode;
  
  	saLongOrLobReader_t	m_fnReader;
  	size_t m_nReaderWantedPieceSize;
  	void* m_pReaderAddlData;
  
  	unsigned char* m_pReaderBuf;
  	size_t m_nReaderAlloc;
  	size_t m_nExpectedSizeMax;
  	size_t m_nReaderRead;
  	size_t m_nPieceSize;
  
  	size_t PrepareReader(
  		size_t nExpectedSizeMax,	// to optimize buf allocation for internal buffer, 0 = unknown
  		size_t nCallerMaxSize,	// max Piece that can be processed by API
  		unsigned char*& pBuf,
  		saLongOrLobReader_t fnReader,
  		size_t nReaderWantedPieceSize,
  		void* pReaderAddlData,
  		bool bAddSpaceForNull = false);
  	void InvokeReader(
  		SAPieceType_t ePieceType,
  		unsigned char*& pBuf,
  		size_t nPieceLen);
  	SAString asLongOrLob() const;
  
  protected:
  	SADataType_t	m_eDataType;
  
  	// null indicator
  	bool* m_pbNull;
  	// scalar types
  	void* m_pScalar;
  	// an exact numeric value with a fixed precision and scale
  	SANumeric* m_pNumeric;
  	// Date time
  	SADateTime* m_pDateTime;
  	// Time interval
  	SAInterval* m_pInterval;
  	// variable length types (string, bytes, Longs and Lobs)
  	SAString* m_pString;
  	// Cursor
  	SACommand* m_pCursor;
  private:
  	// null indicator
  	bool	m_bInternalNull;
  	// scalar types
  	union uScalars
  	{
  		bool m_Bool;
  		short m_Short;
  		unsigned short m_uShort;
  		long m_Long;
  		unsigned long m_uLong;
  		sa_int64_t m_Int8;
  		sa_uint64_t m_uInt8;
  		double m_Double;
  	} m_InternalScalar;
  	SANumeric	m_InternalNumeric;
  	SADateTime	m_InternalDateTime;
  	SAInterval	m_InternalInterval;
  	// variable length types (string, bytes, Longs and Lobs)
  	SAString	m_InternalString;
  	// Cursor
  	SACommand	m_InternalCursor;
  
  public:
  	//! Initializes the object with specified data type.
  	SAValueRead(SADataType_t eDataType);
  	//! Copy constructor.
  	SAValueRead(const SAValueRead& vr);
  	virtual ~SAValueRead();
  
  	//! Copy operator.
  	SAValueRead& operator =(const SAValueRead& vr);
  
  public:
  	//! Returns the object's data type. 
  	SADataType_t DataType() const;
  
  	//! Returns true if the value of current object is NULL; otherwise false.
  	bool isNull() const;
  
  	//! Returns the value of current object. Converts if needed.
  	//! \{
  	// scalar types
  	bool asBool() const;
  	short asShort() const;
  	unsigned short asUShort() const;
  	long asLong() const;
  	unsigned long asULong() const;
  	sa_int64_t asInt64() const;
  	sa_uint64_t asUInt64() const;
  	double asDouble() const;
  
  	// numeric
  	SANumeric asNumeric() const;
  
  	// date/time
  	SADateTime asDateTime() const;
  
  	// Interval
  	SAInterval asInterval() const;
  
  	// variable length types
  	SAString asString() const;
  	SAString asBytes() const;
  	SAString asLongBinary() const;
  	SAString asLongChar() const;
  	SAString asBLob() const;
  	SAString asCLob() const;
  
  	// cursor
  	SACommand* asCursor() const;
  	//! \}
  
  	//! Sets Long or Lob data reading mode. 
  	void setLongOrLobReaderMode(SALongOrLobReaderModes_t eMode);
  	//! Returns Long or Lob data reading mode.
  	SALongOrLobReaderModes_t LongOrLobReaderMode() const;
  
  	// operators for quick accessing values
  	// do not inline to prevent warnings
  	//! Returns the value of current object. Converts if needed.
  	//! \{
  	operator bool() const;
  	operator short() const;
  	operator unsigned short() const;
  	operator long() const;
  	operator unsigned long() const;
  	operator sa_int64_t() const;
  	operator sa_uint64_t() const;
  	operator double() const;
  	operator SANumeric() const;
  	operator SADateTime() const;
  	operator SAInterval() const;
  	operator SAString() const;
  	operator SACommand* () const;
  	//! \}
  
  	// data and indicator storage
  public:
  	void setIndicatorStorage(bool* pStorage);
  	void setDataStorage(void* pStorage, SADataType_t eDataType);
  };
  
  //! Subsidiary class.
  class SQLAPI_API SAValue : public SAValueRead
  {
  	friend class ISACursor;
  	friend class IibCursor;
  	friend class IssDBLibCursor;
  	friend class IoraCursor;
  	friend class IsbCursor;
  	friend class IodbcCursor;
  	friend class Idb2Cursor;
  	friend class IinfCursor;
  	friend class IsybCursor;
  	friend class ImyCursor;
  	friend class IpgCursor;
  	friend class Isl3Cursor;
  	friend class IssNCliCursor;
  	friend class IasaCursor;
  	friend class IcubeSqlCursor;
  	friend class IssOleDbSequentialStream;
  	friend class IduckdbCursor;
  
  private:
  	bool m_bInternalUseDefault;
  
  protected:
  	bool* m_pbUseDefault;
  
  	saLongOrLobWriter_t	m_fnWriter;
  	size_t m_nWriterSize;
  	void* m_pWriterAddlData;
  	void* m_pWriterBuf;
  	size_t m_nWriterAlloc;
  	size_t m_nWriterWritten;
  
  	size_t InvokeWriter(
  		SAPieceType_t& ePieceType,
  		size_t nCallerMaxSize,
  		void*& pBuf);
  
  private:
  	// disable copy constructor
  	SAValue(const SAValue&);
  	// disable assignment operator
  	SAValue& operator = (const SAValue&);
  
  public:
  	SAValue(SADataType_t eDataType);
  	virtual ~SAValue();
  
  	//! Sets value as null.
  	void setAsNull();
  	//! Sets a flag to use default value.
  	void setAsDefault();
  	//! Shows if "default value" flag is set.
  	bool isDefault() const;
  	//! Sets the value type as unknown.
  	void setAsUnknown();
  
  	// scalar types
  	//! Sets the value as bool data.
  	bool& setAsBool();
  	//! Sets the value as short integer data.
  	short& setAsShort();
  	//! Sets the value as unsigned short integer data.
  	unsigned short& setAsUShort();
  	//! Sets the value as long integer data.
  	long& setAsLong();
  	//! Sets the value as unsigned long integer data.
  	unsigned long& setAsULong();
  	//! Sets the value as 64-bit integer data.
  	sa_int64_t& setAsInt64();
  	//! Sets the value as unsigned 64-bit integer data.
  	sa_uint64_t& setAsUInt64();
  	//! Sets the value as double precision data.
  	double& setAsDouble();
  
  	//! Sets the value as SANumeric data.
  	SANumeric& setAsNumeric();
  
  	//! Sets the value as SADateTime data.
  	SADateTime& setAsDateTime();
  
  	//! Sets the value as SAInterval data.
  	SAInterval& setAsInterval();
  
  	//! Sets value as character string data (SAString).
  	SAString& setAsString();
  	//! Sets value as binary string data (SAString).
  	SAString& setAsBytes();
  	//! Sets value as long binary data (SAString).
  	SAString& setAsLongBinary(
  		saLongOrLobWriter_t fnWriter = NULL,
  		size_t nWriterSize = 0, void* pAddlData = NULL);
  	//! Sets value as long character data (SAString).
  	SAString& setAsLongChar(
  		saLongOrLobWriter_t fnWriter = NULL,
  		size_t nWriterSize = 0, void* pAddlData = NULL);
  	//! Sets parameter's value as BLob data (SAString).
  	SAString& setAsBLob(
  		saLongOrLobWriter_t fnWriter = NULL,
  		size_t nWriterSize = 0, void* pAddlData = NULL);
  	//! Sets parameter's value as CLob data (SAString).
  	SAString& setAsCLob(
  		saLongOrLobWriter_t fnWriter = NULL,
  		size_t nWriterSize = 0, void* pAddlData = NULL);
  
  	//! Sets value as a pointer to SACommand object.
  	SACommand*& setAsCursor();
  
  	// Sets value from SAValueRead objects 
  	SAValueRead& setAsValueRead();
  };
  
  //! Defines a specific command parameter that you assign and/or read the value.
  class SQLAPI_API SAParam : public SAValue, public SAOptions
  {
  	friend class SACommand;
  	friend class saPlaceHolder;
  	friend class saOptionsStorage;
  	friend class saParams;
  
  	SACommand* m_pCommand;
  
  	SAString m_sName;
  	SADataType_t m_eParamType;
  	int m_nNativeType;
  	size_t m_nParamSize;
  	int m_nParamPrecision;
  	int m_nParamScale;
  	SAParamDirType_t m_eDirType;
  
  private:
  	// disable copy constructor
  	SAParam(const SAParam&);
  	// disable assignment operator
  	SAParam& operator = (const SAParam&);
  
  protected:
  	SAParam(
  		SACommand* pCommand,
  		const SAString& sName,
  		SADataType_t eParamType,
  		int nNativeType,
  		size_t nParamSize,
  		int	nParamPrecision,
  		int	nParamScale,
  		SAParamDirType_t eDirType);
  	virtual ~SAParam();
  
  public:
  	const SAString& Name() const; //!< Returns the name of the parameter.
  	SADataType_t ParamType() const; //!< Returns parameter's data type.
  	void setParamType(SADataType_t eParamType); //!< Sets the parameter's data type.
  	int ParamNativeType() const; //!< Returns code of parameter's native data type.
  	void setParamNativeType(int nNativeType); //!< Sets parameter's native data type type.
  	size_t ParamSize() const; //!< Returns the parameter's data size.
  	void setParamSize(size_t nParamSize); //!< Sets parameter's data size.
  	SAParamDirType_t ParamDirType() const; //!< Returns direction type of parameter (input, output, etc.)
  	void setParamDirType(SAParamDirType_t eParamDirType); //!< Sets direction type of parameter (input, output, etc.)
  	int ParamPrecision() const; //!< Returns parameter's precision. 
  	void setParamPrecision(int nParamPrecision); //!< Sets precision of the parameter value.
  	int ParamScale() const; //!< Returns parameter's scale.
  	void setParamScale(int nParamScale); //!< Sets parameter's scale.
  
  	void ReadLongOrLob(
  		saLongOrLobReader_t fnReader,
  		size_t nReaderWantedSize,
  		void* pAddlData); //!< Starts reading of Long or BLob(CLob) value using user defined callback.
  
  	virtual SAString Option(const SAString& sOptionName) const;
  
  	bool isInput() const; //!< Returns true if SAParam::ParamDirType() is SA_ParamInput or SA_ParamInputOutput.
  	bool isOutput() const; //!< Returns true if SAParam::ParamDirType() is SA_ParamOutput or SA_ParamInputOutput.
  };
  
  //! A subsidiary class to bind a SA_dtBytes parameter with SACommand << operator.
  class SQLAPI_API SABytes : public SAString
  {
  public:
  	SABytes(const SAString& sData);
  };
  
  //! A subsidiary class to bind a long or LOB parameter with SACommand << operator.
  class SQLAPI_API SALongOrLob : public SAString
  {
  	friend class SACommand;
  
  protected:
  	saLongOrLobWriter_t	m_fnWriter;
  	size_t m_nWriterPieceSize;
  	void* m_pAddlData;
  
  	SALongOrLob(const SAString& sData);
  	SALongOrLob(
  		saLongOrLobWriter_t fnWriter,
  		size_t nWriterPieceSize,
  		void* pAddlData);
  };
  
  //! A subsidiary class to bind a SA_dtLongBinary parameter with SACommand << operator.
  class SQLAPI_API SALongBinary : public SALongOrLob
  {
  public:
  	SALongBinary(const SAString& sData);
  	SALongBinary(
  		saLongOrLobWriter_t fnWriter,
  		size_t nWriterPieceSize,
  		void* pAddlData);
  };
  
  //! A subsidiary class to bind a SA_dtLongChar parameter with SACommand << operator.
  class SQLAPI_API SALongChar : public SALongOrLob
  {
  public:
  	SALongChar(const SAString& sData);
  	SALongChar(
  		saLongOrLobWriter_t fnWriter,
  		size_t nWriterPieceSize,
  		void* pAddlData);
  };
  
  //! A subsidiary class to bind a SA_dtBLob parameter with SACommand << operator.
  class SQLAPI_API SABLob : public SALongOrLob
  {
  public:
  	SABLob(const SAString& sData);
  	SABLob(
  		saLongOrLobWriter_t fnWriter,
  		size_t nWriterPieceSize,
  		void* pAddlData);
  };
  
  //! A subsidiary class to bind a SA_dtCLob parameter with SACommand << operator.
  class SQLAPI_API SACLob : public SALongOrLob
  {
  public:
  	SACLob(const SAString& sData);
  	SACLob(
  		saLongOrLobWriter_t fnWriter,
  		unsigned int nWriterPieceSize,
  		void* pAddlData);
  };
  
  //! Defines a specific command result set field that you read the value.
  class SQLAPI_API SAField : public SAValueRead, public SAOptions
  {
  	friend class SACommand;
  
  	SACommand* m_pCommand;
  
  	// as reported by describe API
  	int					m_nPos;	// 1-based
  	SAString			m_sName;
  	SADataType_t		m_eFieldType;
  	int					m_nNativeType;
  	size_t				m_nFieldSize;
  	int					m_nFieldPrecision;
  	int					m_nFieldScale;
  	bool				m_bFieldRequired;
  
  private:
  	// disable copy constructor
  	SAField(const SAField&);
  	// disable assignment operator
  	SAField& operator = (const SAField&);
  
  protected:
  	SAField(
  		SACommand* pCommand,
  		int nPos,	// 1-based
  		const SAString& sName,
  		SADataType_t eFieldType,
  		int nNativeType,
  		size_t nFieldSize,
  		int nFieldPrecision,
  		int nFieldScale,
  		bool bFieldRequired);
  	virtual ~SAField();
  
  public:
  	int Pos() const; //!< Returns a one-based position of the field in a result set.
  	const SAString& Name() const; //!< Returns name of the field.
  	SADataType_t FieldType() const; //!< Returns field data type.
  	int FieldNativeType() const; //!< Returns native code of field data type.
  	size_t FieldSize() const; //!< Returns field data size.
  	int FieldPrecision() const; //!< Returns precision of the field value.
  	int FieldScale() const; //!< Returns scale of the field value.
  	bool isFieldRequired() const; //!< Shows if it is possible for the field value to be null.
  
  	void setFieldSize(int nSize); //!< Sets parameter's data size.
  	void setFieldType(SADataType_t eType); //!< Sets the fields's data type.
  
  	void ReadLongOrLob(
  		saLongOrLobReader_t fnReader,
  		size_t nReaderWantedSize,
  		void* pAddlData); //!< Starts reading of Long or BLob(CLob) value using user defined callback.
  
  	virtual SAString Option(const SAString& sOptionName) const;
  };
  
  //! Library error exception class.
  class SQLAPI_API SAException
  #ifdef SQLAPI_EXCEPTION_DELIVERED_FROM
  	: public SQLAPI_EXCEPTION_DELIVERED_FROM
  #endif
  {
  	friend class SAConnection;
  	friend class SACommand;
  
  public:
  	SAException(
  		SAException* pNested,
  		SAErrorClass_t eError,
  		int nNativeError,
  		int nErrPos,
  		const SAString& sMsg);
  	SAException(
  		SAException* pNested,
  		SAErrorClass_t eError,
  		int nNativeError,
  		const SAString& sCommandText,
  		int nErrPos,
  		const SAString& sMsg);
  	SAException(
  		SAException* pNested,
  		SAErrorClass_t eError,
  		int nNativeError,
  		int nErrPos,
  		const SAChar* lpszFormat, ...);
  
  	SAException(
  		SAErrorClass_t eError,
  		int nNativeError,
  		int nErrPos,
  		const SAString& sMsg);
  	SAException(
  		SAErrorClass_t eError,
  		int nNativeError,
  		const SAString& sCommandText,
  		int nErrPos,
  		const SAString& sMsg);
  	SAException(
  		SAErrorClass_t eError,
  		int nNativeError,
  		int nErrPos,
  		const SAChar* lpszFormat, ...);
  	SAException(
  		SAErrorClass_t eError,
  		int nNativeError,
  		const SAString& sCommandText,
  		int nErrPos,
  		const SAChar* lpszFormat, ...);
  
  	SAException(const SAException& other);
  
  public:
  	virtual ~SAException();
  
  	//! Throws an exception to stop an end-user operation.
  	static void SQLAPI_CALLBACK throwUserException(
  		int nUserCode, const SAChar* lpszFormat, ...);
  
  	SAErrorClass_t ErrClass() const; //!< Returns a class of error.
  	int ErrNativeCode() const; //!< Returns a native code associated with current error. 
  	int ErrPos() const; //!< Returns an error position in SQL statement.
  	SAString ErrMessage() const; //!< Returns an error message.
  	SAString ErrText() const; //!< Returns a full error text (with nested SAException error messages).
  	SAString CommandText() const;//!< Returns an error related command.
  	const SAException* NestedException() const; //!< Returns a nested SAException pointer.
  
  #ifdef SQLAPI_EXCEPTION_HAS_CUSTOM_MEMBERS
  	SQLAPI_EXCEPTION_HAS_CUSTOM_MEMBERS
  #endif
  
  public:
  	SAException& operator=(const SAException& other);
  
  protected:
  	SAErrorClass_t	m_eErrorClass;
  	int				m_nNativeError;
  	int				m_nErrPos;
  	SAString		m_sMsg;
  	SAString		m_sCommandText;
  	SAException* m_pNested;
  
  	int	nReserved;
  };
  
  class SQLAPI_API SAUserException : public SAException
  {
  	friend class SAException;
  
  protected:
  	SAUserException(int nUserCode, const SAString& sMsg);
  
  public:
  	virtual ~SAUserException();
  };
  
  //! The Library trace information type.
  typedef	enum eSATraceInfo
  {
  	SA_Trace_None = 0,
  	SA_Trace_QueryText = 1 //! trace real DBMS API query text SQLAPI++ sends
  } SATraceInfo_t;
  
  /*!
  Callback function for tracing.
  
  \see SAGlobals::SetTraceFunction
  */
  typedef void (SQLAPI_CALLBACK* SATraceFunction_t)(
  	SATraceInfo_t traceInfo, //!< Tracing into label.
  	SAConnection* pCon, //!< Related SAConnection or NULL.
  	SACommand* pCmd, //!< Related SACommand or NULL.
  	const SAChar* szTraceInfo, //!< Tracing text.
  	void* pData //!< User provided data.
  	);
  
  //! Global SQLAPI++ settings class
  class SQLAPI_API SAGlobals
  {
  public:
  	//! The wrapper for LIBC setlocale function.
  	static char* SQLAPI_CALLBACK setlocale(int category, const char* locale);
  
  	static void Initialize(); //!< Initialize SQLAPI++ library.
  	static void UnInitialize(); //!< Uninitialize SQLAPI++ library.
  
  	static int GetVersionMajor(); //!< Returns the Library major version number.
  	static int GetVersionMinor(); //!< Returns the Library minor version number.
  	static int GetVersionBuild(); //!< Returns the Library build version number.
  
  	static const SAChar* ClientToString(SAClient_t eSAClient); //!< Returns a name of a specified DBMS client type.
  	static SAClient_t StringToClient(const SAChar* szClientName); //!< Returns a DBMS client type of a specified client name.
  
  	//! Setups the Library tracing callback function.
  	static void SetTraceFunction(SATraceInfo_t traceInfo, SATraceFunction_t traceFunc, void* pData);
  
  	//! Can be used for the tuning the default double conversion precision.
  	static int & doubleConvertPrecision();
  };
  
  #endif // __cplusplus
  
  #ifdef __cplusplus
  extern "C" {
  #else
  // C declaration of C++ 'handles'
  typedef struct SAPI SAPI;
  typedef struct SAException SAException;
  typedef struct SAConnection SAConnection;
  typedef struct SACommand SACommand;
  typedef struct SAString SAString;
  typedef struct SAParam SAParam;
  typedef struct SAValueRead SAValueRead;
  typedef struct SAField SAField;
  typedef struct SANumeric SANumeric;
  typedef struct SADateTime SADateTime;
  #endif
  
  //! Enum describes possible result returned by the Library C function.
  typedef
  enum eSABool
  {
  	SA_ReturnError = -1, //!< Error occurred
  	SA_False, //!< TRUE value
  	SA_True //!< FALSE value
  } SABool_t;
  
  
  SQLAPI_API SAException* sqlapi_alloc_error();
  SQLAPI_API void sqlapi_free_error(SAException** perr);
  SQLAPI_API SAString* sqlapi_error_text(const SAException* error);
  SQLAPI_API const SAChar* sqlapi_error_message(const SAException* error);
  SQLAPI_API int sqlapi_error_native_code(const SAException* err);
  SQLAPI_API int sqlapi_error_pos(const SAException* err);
  SQLAPI_API SAErrorClass_t sqlapi_error_class(const SAException* err);
  SQLAPI_API const SAException* sqlapi_error_nested(const SAException* err);
  SQLAPI_API SABool_t sqlapi_has_error(const SAException* error);
  
  SQLAPI_API SAPI* sqlapi_alloc_api();
  SQLAPI_API void sqlapi_free_api(SAPI** papi);
  SQLAPI_API void sqlapi_set_api_option(SAPI* api, const SAChar* szOption, const SAChar *szValue);
  SQLAPI_API SAErrorClass_t sqlapi_init(SAPI* api, SAClient_t type, SAException* err);
  
  SQLAPI_API SAConnection* sqlapi_alloc_connection(SAPI* api);
  SQLAPI_API void sqlapi_free_connection(SAConnection** pcon);
  SQLAPI_API void sqlapi_set_connection_option(SAConnection* conn, const SAChar* szOption, const SAChar* szValue);
  SQLAPI_API SAErrorClass_t sqlapi_connect(SAConnection* conn, const SAChar* szConnectionStr, const SAChar* szUser, const SAChar* szPassword, SAException* err);
  SQLAPI_API SAErrorClass_t sqlapi_disconnect(SAConnection* conn, SAException* err);
  SQLAPI_API SABool_t sqlapi_is_connected(SAConnection* conn, SAException* err);
  SQLAPI_API SABool_t sqlapi_is_alive(SAConnection* conn, SAException* err);
  SQLAPI_API void sqlapi_reset_connection(SAConnection* conn);
  SQLAPI_API SAErrorClass_t sqlapi_commit(SAConnection* conn, SAException* err);
  SQLAPI_API SAErrorClass_t sqlapi_rollback(SAConnection* conn, SAException* err);
  SQLAPI_API SAErrorClass_t sqlapi_set_auto_commit(SAConnection* conn, SAAutoCommit_t mode, SAException* err);
  SQLAPI_API SAErrorClass_t sqlapi_set_isolation_level(SAConnection* conn, SAIsolationLevel_t level, SAException* err);
  
  SQLAPI_API SACommand* sqlapi_alloc_command(SAConnection* con);
  SQLAPI_API void sqlapi_free_command(SACommand** pcmd);
  SQLAPI_API void sqlapi_set_command_option(SACommand* cmd, const SAChar* szOption, const SAChar* szValue);
  SQLAPI_API SAErrorClass_t sqlapi_execute(SACommand* cmd, const SAChar* szQuery, SAException* err);
  SQLAPI_API void sqlapi_reset_command(SACommand* cmd);
  SQLAPI_API SABool_t sqlapi_is_result_set(SACommand* cmd, SAException* err);
  SQLAPI_API SABool_t sqlapi_fetch_next(SACommand* cmd, SAException* err);
  SQLAPI_API SABool_t sqlapi_fetch_prior(SACommand* cmd, SAException* err);
  SQLAPI_API SABool_t sqlapi_fetch_first(SACommand* cmd, SAException* err);
  SQLAPI_API SABool_t sqlapi_fetch_last(SACommand* cmd, SAException* err);
  SQLAPI_API SABool_t sqlapi_fetch_pos(SACommand* cmd, int offset, SABool_t relative, SAException* err);
  
  SQLAPI_API int sqlapi_param_count(SACommand* cmd, SAException* err);
  SQLAPI_API SAParam* sqlapi_param_by_index(SACommand* cmd, int nIndex, SAException* err);
  SQLAPI_API SAParam* sqlapi_param(SACommand* cmd, int nParamByID, SAException* err);
  SQLAPI_API SAParam* sqlapi_param_by_name(SACommand* cmd, const SAChar* szParamByName, SAException* err);
  SQLAPI_API SADataType_t sqlapi_param_type(const SAParam* par);
  SQLAPI_API int sqlapi_param_native_type(const SAParam* par);
  SQLAPI_API SAParamDirType_t sqlapi_param_direction(const SAParam* par);
  SQLAPI_API size_t sqlapi_param_size(const SAParam* par);
  SQLAPI_API int sqlapi_param_precision(const SAParam* par);
  SQLAPI_API int sqlapi_param_scale(const SAParam* par);
  SQLAPI_API const SAValueRead* sqlapi_param_value(SACommand* cmd, int nParamByID, SAException* err);
  SQLAPI_API const SAValueRead* sqlapi_param_value_by_name(SACommand* cmd, const SAChar* szParamByName, SAException* err);
  SQLAPI_API void sqlapi_param_set_short(SAParam* par, short val);
  SQLAPI_API void sqlapi_param_set_ushort(SAParam* par, unsigned short val);
  SQLAPI_API void sqlapi_param_set_int32(SAParam* par, long val);
  SQLAPI_API void sqlapi_param_set_uint32(SAParam* par, unsigned long val);
  SQLAPI_API void sqlapi_param_set_int64(SAParam* par, sa_int64_t val);
  SQLAPI_API void sqlapi_param_set_uint64(SAParam* par, sa_uint64_t val);
  SQLAPI_API void sqlapi_param_set_string(SAParam* par, const SAString* val);
  SQLAPI_API void sqlapi_param_set_numeric(SAParam* par, const SANumeric* val);
  SQLAPI_API void sqlapi_param_set_datetime(SAParam* par, const SADateTime* val);
  SQLAPI_API void sqlapi_param_set_double(SAParam* par, double val);
  SQLAPI_API void sqlapi_param_set_bytes(SAParam* par, const SAString* val);
  
  SQLAPI_API int sqlapi_field_count(SACommand* cmd, SAException* err);
  SQLAPI_API const SAField* sqlapi_field(SACommand* cmd, int nField, SAException* err);
  SQLAPI_API const SAValueRead* sqlapi_field_value(SACommand* cmd, int nField, SAException* err);
  SQLAPI_API const SAField* sqlapi_field_by_name(SACommand* cmd, const SAChar* szField, SAException* err);
  SQLAPI_API const SAValueRead* sqlapi_field_value_by_name(SACommand* cmd, const SAChar* szField, SAException* err);
  
  SQLAPI_API const SAChar* sqlapi_field_name(const SAField* field);
  SQLAPI_API SADataType_t sqlapi_field_type(const SAField* field);
  SQLAPI_API int sqlapi_field_native_type(const SAField* field);
  SQLAPI_API size_t sqlapi_field_data_size(const SAField* field);
  SQLAPI_API int sqlapi_field_precision(const SAField* field);
  SQLAPI_API int sqlapi_field_scale(const SAField* field);
  
  SQLAPI_API short sqlapi_value_as_short(const SAValueRead* val);
  SQLAPI_API unsigned short sqlapi_value_as_ushort(const SAValueRead* val);
  SQLAPI_API long sqlapi_value_as_int32(const SAValueRead* val);
  SQLAPI_API unsigned long sqlapi_value_as_uint32(const SAValueRead* val);
  SQLAPI_API sa_int64_t sqlapi_value_as_int64(const SAValueRead* val);
  SQLAPI_API sa_uint64_t sqlapi_value_as_uint64(const SAValueRead* val);
  SQLAPI_API SAString* sqlapi_value_as_string(const SAValueRead* val);
  SQLAPI_API SANumeric* sqlapi_value_as_numeric(const SAValueRead* val);
  SQLAPI_API SADateTime* sqlapi_value_as_datetime(const SAValueRead* val);
  SQLAPI_API double sqlapi_value_as_double(const SAValueRead* val);
  SQLAPI_API const SACommand* sqlapi_value_as_cursor(const SAValueRead* val);
  SQLAPI_API SAString* sqlapi_value_as_bytes(const SAValueRead* val);
  
  SQLAPI_API SAString* sqlapi_alloc_string(const SAString* src);
  SQLAPI_API void sqlapi_free_string(SAString** pstr);
  SQLAPI_API const char* sqlapi_string_mb(const SAString* str);
  SQLAPI_API size_t sqlapi_string_mb_length(const SAString* str);
  SQLAPI_API void sqlapi_string_set_mb_string(SAString* str, const char* src, size_t len);
  SQLAPI_API const wchar_t* sqlapi_string_wide(const SAString* str);
  SQLAPI_API size_t sqlapi_string_wide_length(const SAString* str);
  SQLAPI_API void sqlapi_string_set_wide_string(SAString* str, const wchar_t* src, size_t len);
  #ifdef SA_UNICODE
  SQLAPI_API const char* sqlapi_string_utf8(const SAString* str);
  SQLAPI_API size_t sqlapi_string_utf8_length(const SAString* str);
  SQLAPI_API void sqlapi_string_set_utf8_string(SAString* str, const char* src, size_t len);
  #endif
  SQLAPI_API const void* sqlapi_string_binary(const SAString* str);
  SQLAPI_API size_t sqlapi_string_binary_length(const SAString* str);
  SQLAPI_API void sqlapi_string_set_binary_string(SAString* str, const void* src, size_t len);
  
  SQLAPI_API SANumeric* sqlapi_alloc_numeric(const SANumeric* src);
  SQLAPI_API void sqlapi_free_numeric(SANumeric** pnum);
  SQLAPI_API SAString* sqlapi_numeric_string(const SANumeric* num);
  SQLAPI_API unsigned char sqlapi_numeric_precision(const SANumeric* num);
  SQLAPI_API unsigned char sqlapi_numeric_scale(const SANumeric* num);
  SQLAPI_API unsigned char sqlapi_numeric_sign(const SANumeric* num);
  SQLAPI_API double sqlapi_numeric_double(const SANumeric* num);
  SQLAPI_API sa_int64_t sqlapi_numeric_int64(const SANumeric* num);
  SQLAPI_API sa_uint64_t sqlapi_numeric_uint64(const SANumeric* num);
  SQLAPI_API void sqlapi_numeric_set_string(SANumeric* num, const SAChar* val);
  SQLAPI_API void sqlapi_numeric_set_double(SANumeric* num, double val);
  SQLAPI_API void sqlapi_numeric_set_int64(SANumeric* num, sa_int64_t val);
  SQLAPI_API void sqlapi_numeric_set_uint64(SANumeric* num, sa_uint64_t val);
  
  SQLAPI_API SADateTime* sqlapi_alloc_datetime(const SADateTime* src);
  SQLAPI_API void sqlapi_free_datetime(SADateTime** pdt);
  SQLAPI_API SAString* sqlapi_datetime_string(const SADateTime* dt);
  SQLAPI_API struct tm sqlapi_datetime_tm(const SADateTime* dt);
  SQLAPI_API double sqlapi_datetime_double(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_year(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_month(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_day(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_week_day(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_year_day(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_hour(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_min(const SADateTime* dt);
  SQLAPI_API int sqlapi_datetime_sec(const SADateTime* dt);
  SQLAPI_API const SAChar* sqlapi_datetime_timezone(const SADateTime* dt);
  SQLAPI_API unsigned int sqlapi_datetime_fraction(const SADateTime* dt);
  SQLAPI_API void sqlapi_datetime_set_tm(SADateTime* dt, struct tm val);
  SQLAPI_API void sqlapi_datetime_set_double(SADateTime* dt, double val);
  SQLAPI_API void sqlapi_datetime_set_datetime(SADateTime* dt, int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, unsigned int nFraction, const SAChar* timezone);
  SQLAPI_API void sqlapi_datetime_set_date(SADateTime* dt, int nYear, int nMonth, int nDay);
  SQLAPI_API void sqlapi_datetime_set_time(SADateTime* dt, int nHour, int nMin, int nSec, unsigned int nFraction);
  SQLAPI_API SABool_t sqlapi_datetime_has_date(const SADateTime* dt);
  SQLAPI_API SABool_t sqlapi_datetime_has_time(const SADateTime* dt);
  
  #ifdef __cplusplus  
  } // extern "C"  
  #endif
  
  #define SQLAPI_VER_MAJOR	5
  #define SQLAPI_VER_MINOR	1
  #define SQLAPI_VER_BUILD	4
  
  #endif // !defined(__SQLAPI_H__)
  
  