Safir SDK Core
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Statement.h
Go to the documentation of this file.
1 /******************************************************************************
2 *
3 * Copyright Saab AB, 2005-2013 (http://safir.sourceforge.net)
4 *
5 * Created by: Jörgen Johansson / stjrjo
6 *
7 *******************************************************************************
8 *
9 * This file is part of Safir SDK Core.
10 *
11 * Safir SDK Core is free software: you can redistribute it and/or modify
12 * it under the terms of version 3 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * Safir SDK Core is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Safir SDK Core. If not, see <http://www.gnu.org/licenses/>.
22 *
23 ******************************************************************************/
24 #ifndef Safir_Databases_Statement_h
25 #define Safir_Databases_Statement_h
26 
28 #include "Safir/Databases/Odbc/Internal/InternalDefs.h"
29 #include "Safir/Databases/Odbc/Internal/Parameter.h"
30 #include "Safir/Databases/Odbc/Internal/Column.h"
31 #include "Safir/Databases/Odbc/Internal/BufferedWideStringParameter.h"
32 #include "Safir/Databases/Odbc/Internal/NonBufferedWideStringParameter.h"
33 #include "Safir/Databases/Odbc/Internal/BufferedBinaryParameter.h"
34 #include "Safir/Databases/Odbc/Internal/NonBufferedBinaryParameter.h"
35 #include "Safir/Databases/Odbc/Internal/BinaryColumn.h"
36 #include "Safir/Databases/Odbc/Internal/WideStringColumn.h"
37 
38 #include <boost/noncopyable.hpp>
40 
41 namespace Safir
42 {
43 namespace Databases
44 {
45 namespace Odbc
46 {
47  class Connection;
48 
49 #ifdef _MSC_VER
50 #pragma warning(push)
51 #pragma warning(disable: 4275)
52 #endif
53 
59 class OLIB_API Statement : private boost::noncopyable
60 {
61 public:
64  Statement();
65 
68  ~Statement();
69 
77  void Alloc(Connection & pConnection);
78 
86  void Free();
87 
94  void CloseCursor();
95 
106  void Execute();
107 
116  void Prepare(const std::wstring & wszSqlCommand);
117 
127  void ExecDirect(const std::wstring & wszSqlCommand);
128 
138  bool Fetch();
139 
148  bool MoreResults();
149 
159  int GetNumberOfColumns() const;
160 
169  void SetStmtAttr(long lAttribute, long lValue);
170 
179  void SetStmtAttr(long lAttribute, const std::wstring & wszValue);
180 
189  void GetStmtAttr(long lAttribute, long & lValue) const;
190 
200  void GetStmtAttr(long lAttribute, wchar_t * wszValue, unsigned long ulLength) const;
201 
211  bool ParamData(unsigned short & lParameter) const;
212 
224  template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
225  void BindParameter( unsigned short usParameterNumber,
226  Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param );
227  template<short sSqlType, short sInputOutputType>
228  void BindParameter( unsigned short usParameterNumber,
229  Internal::NonBufferedWideStringParameter<sSqlType, sInputOutputType> & param );
230 
231 
243  template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
244  void BindLongParameter( unsigned short usParameterNumber,
245  Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param );
246 
257  template<short sValueType, class Type>
258  void BindColumn(unsigned short usColumnNumber,
259  Internal::Column<sValueType, Type> & column );
260 
271  template<short sValueType, class Type>
272  bool GetData( unsigned short usColumnNumber,
273  Internal::Column<sValueType, Type> & column );
274 
283  template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
284  void PutData(Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param );
285 
296  bool GetDiagRec(short sRecNumber,
297  std::wstring & SqlState,
298  boost::int32_t & NativeError,
299  std::wstring & MessageText,
300  bool & bDataRead) const;
301 
306  bool IsValid() const;
307 
312  SQLHDBC Handle() const;
313 private:
314  SQLHSTMT m_hStatement;
315  Connection * m_pConnection;
316 
317  void SetNotValid();
318  void ThrowException(const std::wstring & fileName,
319  const Safir::Dob::Typesystem::Int64 lineNumber,
320  SQLRETURN original_returncode) const;
321  void ThrowException(SQLSMALLINT HandleType,
322  SQLHANDLE Handle,
323  const std::wstring & fileName,
324  const Safir::Dob::Typesystem::Int64 lineNumber,
325  SQLRETURN original_returncode) const;
326 
328 };
329 
330 #ifdef _MSC_VER
331 #pragma warning(pop)
332 #endif
333 
334 inline
335 SQLHDBC Statement::Handle() const
336 {
337  return m_hStatement;
338 }
339 
340 inline
341 bool Statement::IsValid() const
342 {
343  return m_hStatement != SQL_NULL_HSTMT;
344 }
345 
346 inline
347 void Statement::SetNotValid()
348 {
349  m_hStatement = SQL_NULL_HSTMT;
350 }
351 
352 template<short sValueType, class Type>
353 bool Statement::GetData(unsigned short usColumnNumber,
354  Internal::Column<sValueType, Type> & column )
355 {
356  SQLRETURN ret;
357  bool bDataFound = true;
358 
359  if (!IsValid())
360  throw Safir::Dob::Typesystem::SoftwareViolationException(L"Using an invalid statement",__WFILE__,__LINE__);
361 
362  ret = ::SQLGetData( m_hStatement, // StatementHandle
363  usColumnNumber, // ColumnNumber,
364  column.m_csValueType, // TargetType,
365  column.GetValuePtr(), // TargetValuePtr,
366  column.GetSize(), // BufferLength,
367  column.GetLengthOrIndPtr()); // StrLen_or_Ind
368  if (ret==SQL_NO_DATA_FOUND)
369  bDataFound = false;
370  else if (!SQL_SUCCEEDED(ret))
371  {
372  ThrowException(__WFILE__,__LINE__, ret);
373  }
374 
375  return bDataFound;
376 }
377 
378 template<short sValueType, class Type>
379 void Statement::BindColumn( unsigned short usColumnNumber,
380  Internal::Column<sValueType, Type> & column )
381 {
382  SQLRETURN ret;
383 
384  if (!IsValid())
385  throw Safir::Dob::Typesystem::SoftwareViolationException(L"Using an invalid statement",__WFILE__,__LINE__);
386 
387  ret = ::SQLBindCol( m_hStatement, // StatementHandle
388  usColumnNumber, // ColumnNumber,
389  column.m_csValueType, // TargetType,
390  column.GetValuePtr(), // TargetValuePtr,
391  column.GetSize(), // BufferLength,
392  column.GetLengthOrIndPtr()); // StrLen_or_Ind
393  if (!SQL_SUCCEEDED(ret))
394  {
395  ThrowException(__WFILE__,__LINE__, ret);
396  }
397 }
398 
399 template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
400 void Statement::BindParameter( unsigned short usParameterNumber,
401  Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param )
402 {
403  SQLRETURN ret;
404 
405  if (!IsValid())
406  throw Safir::Dob::Typesystem::SoftwareViolationException(L"Using an invalid statement",__WFILE__,__LINE__);
407 
408  ret = ::SQLBindParameter( m_hStatement, // StatementHandle
409  usParameterNumber, // ParameterNumber,
410  param.m_csInputOutputType, // InputOutputType
411  param.m_csCType, // ValueType
412  param.m_csSqlType, // ParameterType
413  param.GetColumnSize(), // ColumnSize
414  param.GetDecimal(), // DecimalDigits
415  param.GetValuePtr(), // ParameterValuePtr
416  param.GetSize(), // BufferLength
417  param.GetLengthOrIndPtr() ); // StrLen_or_Ind
418  if (!SQL_SUCCEEDED(ret))
419  {
420  ThrowException(__WFILE__,__LINE__, ret);
421  }
422 }
423 
424 template<short sSqlType, short sInputOutputType>
425 void Statement::BindParameter( unsigned short /*usParameterNumber*/,
426  Internal::NonBufferedWideStringParameter<sSqlType, sInputOutputType> & /*param*/ )
427 {
428  throw Safir::Dob::Typesystem::SoftwareViolationException(L"This parameter can only be used with PutData",__WFILE__,__LINE__);
429 }
430 
431 
432 template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
433 void Statement::BindLongParameter( unsigned short usParameterNumber,
434  Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param )
435 {
436  SQLRETURN ret;
437 
438  if (!IsValid())
439  throw Safir::Dob::Typesystem::SoftwareViolationException(L"Using an invalid statement",__WFILE__,__LINE__);
440 
441  ret = ::SQLBindParameter( m_hStatement, // StatementHandle
442  usParameterNumber, // ParameterNumber,
443  param.m_csInputOutputType, // InputOutputType
444  param.m_csCType, // ValueType
445  param.m_csSqlType, // ParameterType
446  param.GetColumnSize(), // ColumnSize
447  param.GetDecimal(), // DecimalDigits
448  reinterpret_cast<SQLPOINTER>(usParameterNumber), // ParameterValuePtr
449  param.GetSize(), // BufferLength
450  param.GetLengthOrIndPtr() ); // StrLen_or_Ind
451  if (!SQL_SUCCEEDED(ret))
452  {
453  ThrowException(__WFILE__,__LINE__, ret);
454  }
455 }
456 
457 template<short sCType, short sSqlType, class Type, short sInputOutputType, unsigned long lColumnSize>
458 void Statement::PutData(Internal::Parameter<sCType, sSqlType, Type, sInputOutputType,lColumnSize> & param )
459 {
460  SQLRETURN ret;
461 
462  if (!IsValid())
463  throw Safir::Dob::Typesystem::SoftwareViolationException(L"Using an invalid statement",__WFILE__,__LINE__);
464 
465  ret = ::SQLPutData( m_hStatement, // StatementHandle
466  param.GetValuePtr(), // ParameterValuePtr
467  param.GetSize() ); // StrLen_or_Ind
468 
469  if (!SQL_SUCCEEDED(ret))
470  {
471  ThrowException(__WFILE__,__LINE__, ret);
472  }
473 }
474 
475 } // End namespace Odbc
476 
477 } // End namespace Databases
478 
479 } // End namespace Safir
480 
481 #endif // Safir_Databases_Statement_h
Meant to be used when something goes very wrong.
Definition: Exceptions.h:360
SQLHDBC Handle() const
Returns the ODBC Handle of the statement.
Definition: Statement.h:335
DotsC_Int64 Int64
64 bit integer type.
Definition: Defs.h:70
#define __WFILE__
Definition: Exceptions.h:31
void BindParameter(unsigned short usParameterNumber, Internal::Parameter< sCType, sSqlType, Type, sInputOutputType, lColumnSize > &param)
Binds a parameter to a statement.
Definition: Statement.h:400
bool IsValid() const
Checks if this statement is a valid allocated statement.
Definition: Statement.h:341
void PutData(Internal::Parameter< sCType, sSqlType, Type, sInputOutputType, lColumnSize > &param)
Put data into a parameter.
Definition: Statement.h:458
The Statement class models a statement made to the database engine and one statement object should be...
Definition: Statement.h:59
bool GetData(unsigned short usColumnNumber, Internal::Column< sValueType, Type > &column)
Get data from a column.
Definition: Statement.h:353
void BindColumn(unsigned short usColumnNumber, Internal::Column< sValueType, Type > &column)
Binds a column to a statement.
Definition: Statement.h:379
The Connection class models a connection made to the database engine.
Definition: Connection.h:53
void BindLongParameter(unsigned short usParameterNumber, Internal::Parameter< sCType, sSqlType, Type, sInputOutputType, lColumnSize > &param)
Binds a long parameter to a statement.
Definition: Statement.h:433