Logo Search packages:      
Sourcecode: poco version File versions  Download package

Preparation.h
//
// Preparation.h
//
// $Id: //poco/1.3/Data/ODBC/include/Poco/Data/ODBC/Preparation.h#6 $
//
// Library: Data/ODBC
// Package: ODBC
// Module:  Preparation
//
// Definition of the Preparation class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//


#ifndef DataConnectors_ODBC_Preparation_INCLUDED
#define DataConnectors_ODBC_Preparation_INCLUDED


#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/ODBCColumn.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/AbstractPreparation.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Any.h"
#include "Poco/SharedPtr.h"
#include <vector>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>


namespace Poco {
namespace Data {
namespace ODBC {


class BLOB;


00066 class ODBC_API Preparation : public AbstractPreparation
      /// Class used for database preparation where we first have to register all data types 
      /// with respective memory output locations before extracting data. 
      /// Extraction works in two-phases: first prepare is called once, then extract n-times.
      /// In ODBC, SQLBindCol/SQLFetch is the preferred method of data retrieval (SQLGetData is available, 
      /// however with numerous driver implementation dependent limitations). In order to fit this functionality 
      /// into Poco DataConnectors framework, every ODBC SQL statement instantiates its own Preparation object. 
      /// This is done once per statement execution (from StatementImpl::bindImpl()).
      ///
      /// Preparation object is used to :
      ///
      ///         1) Prepare SQL statement.
      ///         2) Provide and contain the memory locations where retrieved values are placed during recordset iteration.
      ///         3) Keep count of returned number of columns with their respective datatypes and sizes.
      ///
      /// Notes:
      ///
      /// - Value datatypes in this interface prepare() calls serve only for the purpose of type distinction.
      /// - Preparation keeps its own std::vector<Any> buffer for fetched data to be later retrieved by Extractor.
      /// - prepare() methods should not be called when extraction mode is DE_MANUAL
      /// 
{
public:
      enum DataExtraction
      {
            DE_MANUAL,
            DE_BOUND
      };

      Preparation(const StatementHandle& rStmt, 
            const std::string& statement, 
            std::size_t maxFieldSize,
            DataExtraction dataExtraction = DE_BOUND);
            /// Creates the Preparation.

      ~Preparation();
            /// Destroys the Preparation.

      void prepare(std::size_t pos, Poco::Int8);
            /// Prepares an Int8.

      void prepare(std::size_t pos, Poco::UInt8);
            /// Prepares an UInt8.

      void prepare(std::size_t pos, Poco::Int16);
            /// Prepares an Int16.

      void prepare(std::size_t pos, Poco::UInt16);
            /// Prepares an UInt16.

      void prepare(std::size_t pos, Poco::Int32);
            /// Prepares an Int32.

      void prepare(std::size_t pos, Poco::UInt32);
            /// Prepares an UInt32.

      void prepare(std::size_t pos, Poco::Int64);
            /// Prepares an Int64.

      void prepare(std::size_t pos, Poco::UInt64);
            /// Prepares an UInt64.

      void prepare(std::size_t pos, bool);
            /// Prepares a boolean.

      void prepare(std::size_t pos, float);
            /// Prepares a float.

      void prepare(std::size_t pos, double);
            /// Prepares a double.

      void prepare(std::size_t pos, char);
            /// Prepares a single character.

      void prepare(std::size_t pos, const std::string&);
            /// Prepares a string.

      void prepare(std::size_t pos, const Poco::Data::BLOB&);
            /// Prepares a BLOB.

      void prepare(std::size_t pos, const Poco::Any&);
            /// Prepares an Any.

      std::size_t columns() const;
            /// Returns the number of columns.

      Poco::Any& operator [] (std::size_t pos);
            /// Returns reference to column data.

      void setMaxFieldSize(std::size_t size);
            /// Sets maximum supported field size.

      std::size_t getMaxFieldSize() const;
            // Returns maximum supported field size.

      std::size_t maxDataSize(std::size_t pos) const;
            /// Returns max supported size for column at position pos.
            /// Returned length for variable length fields is the one 
            /// supported by this implementation, not the underlying DB.

      std::size_t actualDataSize(std::size_t pos) const;
            /// Returns the returned length. This is usually
            /// equal to the column size, except for variable length fields
            /// (BLOB and variable length strings).

      void setDataExtraction(DataExtraction ext);
            /// Set data extraction mode.

      DataExtraction getDataExtraction() const;
            /// Returns data extraction mode.

private:
      template <typename T>
00179       void preparePOD(std::size_t pos, SQLSMALLINT valueType)
      {
            poco_assert (DE_BOUND == _dataExtraction);
            poco_assert (pos >= 0 && pos < _pValues.size());

            std::size_t dataSize = sizeof(T);

            _pValues[pos] = new Poco::Any(T());
            _pLengths[pos] = new SQLLEN;
            *_pLengths[pos] = 0;

            T* pVal = AnyCast<T>(_pValues[pos]);

            poco_assert_dbg (pVal);

            if (Utility::isError(SQLBindCol(_rStmt, 
                  (SQLUSMALLINT) pos + 1, 
                  valueType, 
                  (SQLPOINTER) pVal, 
                  (SQLINTEGER) dataSize, 
                  _pLengths[pos])))
            {
                  throw StatementException(_rStmt, "SQLBindCol()");
            }
      }

      void prepareRaw(std::size_t pos, SQLSMALLINT valueType, std::size_t size);

      const StatementHandle& _rStmt;
      std::vector<Poco::Any*> _pValues;
      std::vector<SQLLEN*> _pLengths;
      std::size_t _maxFieldSize;
      DataExtraction _dataExtraction;
      std::vector<char*> _charPtrs;
};


//
// inlines
//
00219 inline void Preparation::prepare(std::size_t pos, Poco::Int8)
{
      preparePOD<Poco::Int8>(pos, SQL_C_STINYINT);
}


00225 inline void Preparation::prepare(std::size_t pos, Poco::UInt8)
{
      preparePOD<Poco::UInt8>(pos, SQL_C_UTINYINT);
}


00231 inline void Preparation::prepare(std::size_t pos, Poco::Int16)
{
      preparePOD<Poco::Int16>(pos, SQL_C_SSHORT);
}


00237 inline void Preparation::prepare(std::size_t pos, Poco::UInt16)
{
      preparePOD<Poco::UInt16>(pos, SQL_C_USHORT);
}


00243 inline void Preparation::prepare(std::size_t pos, Poco::Int32)
{
      preparePOD<Poco::Int32>(pos, SQL_C_SLONG);
}


00249 inline void Preparation::prepare(std::size_t pos, Poco::UInt32)
{
      preparePOD<Poco::UInt32>(pos, SQL_C_ULONG);
}


00255 inline void Preparation::prepare(std::size_t pos, Poco::Int64)
{
      preparePOD<Poco::Int64>(pos, SQL_C_SBIGINT);
}


00261 inline void Preparation::prepare(std::size_t pos, Poco::UInt64)
{
      preparePOD<Poco::UInt64>(pos, SQL_C_UBIGINT);
}


00267 inline void Preparation::prepare(std::size_t pos, bool)
{
      preparePOD<bool>(pos, SQL_C_BIT);
}


00273 inline void Preparation::prepare(std::size_t pos, float)
{
      preparePOD<float>(pos, SQL_C_FLOAT);
}


00279 inline void Preparation::prepare(std::size_t pos, double)
{
      preparePOD<double>(pos, SQL_C_DOUBLE);
}


00285 inline void Preparation::prepare(std::size_t pos, char)
{
      preparePOD<char>(pos, SQL_C_STINYINT);
}


00291 inline void Preparation::prepare(std::size_t pos, const std::string&)
{
      prepareRaw(pos, SQL_C_CHAR, maxDataSize(pos));
}


00297 inline void Preparation::prepare(std::size_t pos, const Poco::Data::BLOB&)
{
      prepareRaw(pos, SQL_C_BINARY, maxDataSize(pos));
}


00303 inline std::size_t Preparation::columns() const
{
      return _pValues.size();
}


00309 inline std::size_t Preparation::actualDataSize(std::size_t pos) const
{
      poco_assert (pos >= 0 && pos < _pValues.size());
      poco_assert (_pLengths[pos]);

      return *_pLengths[pos];
}


00318 inline void Preparation::setMaxFieldSize(std::size_t size)
{
      _maxFieldSize = size;
}


00324 inline std::size_t Preparation::getMaxFieldSize() const
{
      return _maxFieldSize;
}


00330 inline void Preparation::setDataExtraction(Preparation::DataExtraction ext)
{
      _dataExtraction = ext;
}


00336 inline Preparation::DataExtraction Preparation::getDataExtraction() const
{
      return _dataExtraction;
}


} } } // namespace Poco::Data::ODBC


#endif // DataConnectors_ODBC_Preparation_INCLUDED

Generated by  Doxygen 1.6.0   Back to index