Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copied empty backend skeleton to db2 backend Added DB2 detection and building Implemented session backend calls
- Loading branch information
Denis Chapligin
committed
Feb 20, 2013
1 parent
d121e93
commit c5135ee
Showing
8 changed files
with
546 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
soci_backend(DB2 | ||
DEPENDS DB2 | ||
HEADERS soci-db2.h | ||
DESCRIPTION "SOCI backend for DB2 Ubiversal Database" | ||
AUTHORS "Denis Chapligin" | ||
MAINTAINERS "Denis Chapligin") | ||
|
||
add_subdirectory(test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// | ||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton | ||
// Copyright (C) 2011 Denis Chapligin | ||
// Distributed under the Boost Software License, Version 1.0. | ||
// (See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
|
||
#define SOCI_DB2_SOURCE | ||
#include "soci-db2.h" | ||
|
||
#ifdef _MSC_VER | ||
#pragma warning(disable:4355) | ||
#endif | ||
|
||
using namespace soci; | ||
using namespace soci::details; | ||
|
||
|
||
db2_session_backend::db2_session_backend( | ||
std::string const & connectString /* DSN=SAMPLE;Uid=db2inst1;Pwd=db2inst1;AutoCommit=off */) | ||
{ | ||
SQLRETURN cliRC = SQL_SUCCESS; | ||
|
||
/* Prepare handles */ | ||
cliRC = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&hEnv); | ||
if (cliRC != SQL_SUCCESS) { | ||
throw db2_soci_error("Error while allocating the enironment handle",cliRC); | ||
} | ||
|
||
cliRC = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); | ||
if (cliRC != SQL_SUCCESS) { | ||
SQLFreeHandle(SQL_HANDLE_ENV,hEnv); | ||
throw db2_soci_error("Error while allocating the connection handle",cliRC); | ||
} | ||
|
||
/* Set autocommit */ | ||
cliRC = SQLSetConnectAttr(hDbc,SQL_ATTR_AUTOCOMMIT, this->autocommit ? (SQLPOINTER)SQL_AUTOCOMMIT_ON : (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS); | ||
if (cliRC != SQL_SUCCESS) { | ||
SQLFreeHandle(SQL_HANDLE_DBC,hDbc); | ||
SQLFreeHandle(SQL_HANDLE_ENV,hEnv); | ||
throw db2_soci_error("Error while setting autocommit attribute",cliRC); | ||
} | ||
|
||
/* Connect to database */ | ||
cliRC = SQLConnect(hDbc,(SQLCHAR*)connectString.c_str(),SQL_NTS,(SQLCHAR*)username.c_str(),SQL_NTS,(SQLCHAR*)password.c_str(),SQL_NTS); | ||
if (cliRC != SQL_SUCCESS) { | ||
SQLFreeHandle(SQL_HANDLE_DBC,hDbc); | ||
SQLFreeHandle(SQL_HANDLE_ENV,hEnv); | ||
throw db2_soci_error("Error connecting to database",cliRC); | ||
} | ||
} | ||
|
||
db2_session_backend::~db2_session_backend() | ||
{ | ||
clean_up(); | ||
} | ||
|
||
void db2_session_backend::begin() | ||
{ | ||
//Transations begin implicitly | ||
} | ||
|
||
void db2_session_backend::commit() | ||
{ | ||
if (!autocommit) { | ||
SQLRETURN cliRC = SQLEndTran(SQL_HANDLE_DBC,hDbc,SQL_COMMIT); | ||
if (cliRC != SQL_SUCCESS) { | ||
throw db2_soci_error("Commit failed",cliRC); | ||
} | ||
} | ||
} | ||
|
||
void db2_session_backend::rollback() | ||
{ | ||
if (!autocommit) { | ||
SQLRETURN cliRC = SQLEndTran(SQL_HANDLE_DBC,hDbc,SQL_ROLLBACK); | ||
if (cliRC != SQL_SUCCESS) { | ||
throw db2_soci_error("Rollback failed",cliRC); | ||
} | ||
} | ||
} | ||
|
||
void db2_session_backend::clean_up() | ||
{ | ||
SQLDisconnect(hDbc); | ||
SQLFreeHandle(SQL_HANDLE_DBC,hDbc); | ||
SQLFreeHandle(SQL_HANDLE_ENV,hEnv); | ||
} | ||
|
||
db2_statement_backend * db2_session_backend::make_statement_backend() | ||
{ | ||
return new db2_statement_backend(*this); | ||
} | ||
|
||
db2_rowid_backend * db2_session_backend::make_rowid_backend() | ||
{ | ||
return new db2_rowid_backend(*this); | ||
} | ||
|
||
db2_blob_backend * db2_session_backend::make_blob_backend() | ||
{ | ||
return new db2_blob_backend(*this); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
// | ||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton | ||
// Copyright (C) 2011 Denis Chapligin | ||
// Distributed under the Boost Software License, Version 1.0. | ||
// (See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
|
||
#ifndef SOCI_DB2_H_INCLUDED | ||
#define SOCI_DB2_H_INCLUDED | ||
|
||
#ifdef _WIN32 | ||
# ifdef SOCI_DLL | ||
# ifdef SOCI_DB2_SOURCE | ||
# define SOCI_DB2_DECL __declspec(dllexport) | ||
# else | ||
# define SOCI_DB2_DECL __declspec(dllimport) | ||
# endif // SOCI_DB2_SOURCE | ||
# endif // SOCI_DLL | ||
#endif // _WIN32 | ||
// | ||
// If SOCI_DB2_DECL isn't defined yet define it now | ||
#ifndef SOCI_DB2_DECL | ||
# define SOCI_DB2_DECL | ||
#endif | ||
|
||
#include "soci-backend.h" | ||
|
||
#include <cstddef> | ||
#include <string> | ||
|
||
#include <sqlcli1.h> | ||
|
||
namespace soci | ||
{ | ||
|
||
class db2_soci_error : public soci_error { | ||
public: | ||
db2_soci_error(std::string const & msg, SQLRETURN rc) : soci_error(msg),errorCode(rc) {}; | ||
|
||
SQLRETURN errorCode; | ||
}; | ||
|
||
struct db2_statement_backend; | ||
|
||
struct SOCI_DB2_DECL db2_standard_into_type_backend : details::standard_into_type_backend | ||
{ | ||
db2_standard_into_type_backend(db2_statement_backend &st) | ||
: statement_(st) | ||
{} | ||
|
||
void define_by_pos(int& position, void* data, details::exchange_type type); | ||
|
||
void pre_fetch(); | ||
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind); | ||
|
||
void clean_up(); | ||
|
||
db2_statement_backend& statement_; | ||
}; | ||
|
||
struct SOCI_DB2_DECL db2_vector_into_type_backend : details::vector_into_type_backend | ||
{ | ||
db2_vector_into_type_backend(db2_statement_backend &st) | ||
: statement_(st) | ||
{} | ||
|
||
void define_by_pos(int& position, void* data, details::exchange_type type); | ||
|
||
void pre_fetch(); | ||
void post_fetch(bool gotData, indicator* ind); | ||
|
||
void resize(std::size_t sz); | ||
std::size_t size(); | ||
|
||
void clean_up(); | ||
|
||
db2_statement_backend& statement_; | ||
}; | ||
|
||
struct SOCI_DB2_DECL db2_standard_use_type_backend : details::standard_use_type_backend | ||
{ | ||
db2_standard_use_type_backend(db2_statement_backend &st) | ||
: statement_(st) | ||
{} | ||
|
||
void bind_by_pos(int& position, void* data, details::exchange_type type, bool readOnly); | ||
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly); | ||
|
||
void pre_use(indicator const* ind); | ||
void post_use(bool gotData, indicator* ind); | ||
|
||
void clean_up(); | ||
|
||
db2_statement_backend& statement_; | ||
}; | ||
|
||
struct SOCI_DB2_DECL db2_vector_use_type_backend : details::vector_use_type_backend | ||
{ | ||
db2_vector_use_type_backend(db2_statement_backend &st) | ||
: statement_(st) {} | ||
|
||
void bind_by_pos(int& position, void* data, details::exchange_type type); | ||
void bind_by_name(std::string const& name, void* data, details::exchange_type type); | ||
|
||
void pre_use(indicator const* ind); | ||
|
||
std::size_t size(); | ||
|
||
void clean_up(); | ||
|
||
db2_statement_backend& statement_; | ||
}; | ||
|
||
struct db2_session_backend; | ||
struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend | ||
{ | ||
db2_statement_backend(db2_session_backend &session); | ||
|
||
void alloc(); | ||
void clean_up(); | ||
void prepare(std::string const& query, details::statement_type eType); | ||
|
||
exec_fetch_result execute(int number); | ||
exec_fetch_result fetch(int number); | ||
|
||
long long get_affected_rows(); | ||
int get_number_of_rows(); | ||
|
||
std::string rewrite_for_procedure_call(std::string const& query); | ||
|
||
int prepare_for_describe(); | ||
void describe_column(int colNum, data_type& dtype, std::string& columnName); | ||
|
||
db2_standard_into_type_backend* make_into_type_backend(); | ||
db2_standard_use_type_backend* make_use_type_backend(); | ||
db2_vector_into_type_backend* make_vector_into_type_backend(); | ||
db2_vector_use_type_backend* make_vector_use_type_backend(); | ||
|
||
db2_session_backend& session_; | ||
}; | ||
|
||
struct db2_rowid_backend : details::rowid_backend | ||
{ | ||
db2_rowid_backend(db2_session_backend &session); | ||
|
||
~db2_rowid_backend(); | ||
}; | ||
|
||
struct db2_blob_backend : details::blob_backend | ||
{ | ||
db2_blob_backend(db2_session_backend& session); | ||
|
||
~db2_blob_backend(); | ||
|
||
std::size_t get_len(); | ||
std::size_t read(std::size_t offset, char* buf, std::size_t toRead); | ||
std::size_t write(std::size_t offset, char const* buf, std::size_t toWrite); | ||
std::size_t append(char const* buf, std::size_t toWrite); | ||
void trim(std::size_t newLen); | ||
|
||
db2_session_backend& session_; | ||
}; | ||
|
||
struct db2_session_backend : details::session_backend | ||
{ | ||
db2_session_backend(std::string const& connectString); | ||
|
||
~db2_session_backend(); | ||
|
||
void begin(); | ||
void commit(); | ||
void rollback(); | ||
|
||
std::string get_backend_name() const { return "DB2"; } | ||
|
||
void clean_up(); | ||
|
||
db2_statement_backend* make_statement_backend(); | ||
db2_rowid_backend* make_rowid_backend(); | ||
db2_blob_backend* make_blob_backend(); | ||
|
||
std::string dsn; | ||
std::string username; | ||
std::string password; | ||
bool autocommit; | ||
|
||
SQLHANDLE hEnv; /* Environment handle */ | ||
SQLHANDLE hDbc; /* Connection handle */ | ||
}; | ||
|
||
struct SOCI_DB2_DECL db2_backend_factory : backend_factory | ||
{ | ||
db2_backend_factory() {} | ||
db2_session_backend* make_session(std::string const& connectString) const; | ||
}; | ||
|
||
extern SOCI_DB2_DECL db2_backend_factory const db2; | ||
|
||
extern "C" | ||
{ | ||
|
||
// for dynamic backend loading | ||
SOCI_DB2_DECL backend_factory const* factory_db2(); | ||
SOCI_DB2_DECL void register_factory_db2(); | ||
|
||
} // extern "C" | ||
|
||
} // namespace soci | ||
|
||
#endif // SOCI_DB2_H_INCLUDED |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
soci_backend_test( | ||
BACKEND DB2 | ||
SOURCE test-db2.cpp | ||
CONNSTR "dummy") |
Oops, something went wrong.