Commit c5135ee6 authored by Denis Chapligin's avatar Denis Chapligin

Ignored ide files

Copied empty backend skeleton to db2 backend

Added DB2 detection and building

Implemented session backend calls
parent d121e930
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)
//
// 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);
}
//
// 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
soci_backend_test(
BACKEND DB2
SOURCE test-db2.cpp
CONNSTR "dummy")
\ No newline at end of file
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
// 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)
//
#include "soci.h"
#include "soci-empty.h"
#include <iostream>
#include <string>
#include <cassert>
#include <cstdlib>
#include <ctime>
using namespace soci;
std::string connectString;
backend_factory const &backEnd = *soci::factory_empty();
// NOTE:
// This file is supposed to serve two purposes:
// 1. To be a starting point for implementing new tests (for new backends).
// 2. To exercise (at least some of) the syntax and try the SOCI library
// against different compilers, even in those environments where there
// is no database. SOCI uses advanced template techniques which are known
// to cause problems on different versions of popular compilers, and this
// test is handy to verify that the code is accepted by as many compilers
// as possible.
//
// Both of these purposes mean that the actual code here is meaningless
// from the database-development point of view. For new tests, you may wish
// to remove this code and keep only the general structure of this file.
struct Person
{
int id;
std::string firstName;
std::string lastName;
};
namespace soci
{
template<> struct type_conversion<Person>
{
typedef values base_type;
static void from_base(values & /* r */, indicator /* ind */,
Person & /* p */)
{
}
};
}
void test1()
{
{
session sql(backEnd, connectString);
sql << "Do what I want.";
sql << "Do what I want " << 123 << " times.";
std::string query = "some query";
sql << query;
int i = 7;
sql << "insert", use(i);
sql << "select", into(i);
#if defined (__LP64__) || ( __WORDSIZE == 64 )
long int li = 9;
sql << "insert", use(li);
sql << "select", into(li);
#endif
long long ll = 11;
sql << "insert", use(ll);
sql << "select", into(ll);
indicator ind = i_ok;
sql << "insert", use(i, ind);
sql << "select", into(i, ind);
std::vector<int> numbers(100);
sql << "insert", use(numbers);
sql << "select", into(numbers);
std::vector<indicator> inds(100);
sql << "insert", use(numbers, inds);
sql << "select", into(numbers, inds);
{
statement st = (sql.prepare << "select", into(i));
st.execute();
st.fetch();
}
{
statement st = (sql.prepare << "select", into(i, ind));
}
{
statement st = (sql.prepare << "select", into(numbers));
}
{
statement st = (sql.prepare << "select", into(numbers, inds));
}
{
statement st = (sql.prepare << "insert", use(i));
}
{
statement st = (sql.prepare << "insert", use(i, ind));
}
{
statement st = (sql.prepare << "insert", use(numbers));
}
{
statement st = (sql.prepare << "insert", use(numbers, inds));
}
{
Person p;
sql << "select person", into(p);
}
}
std::cout << "test 1 passed" << std::endl;
}
int main(int argc, char** argv)
{
#ifdef _MSC_VER
// Redirect errors, unrecoverable problems, and assert() failures to STDERR,
// instead of debug message window.
// This hack is required to run asser()-driven tests by Buildbot.
// NOTE: Comment this 2 lines for debugging with Visual C++ debugger to catch assertions inside.
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
#endif //_MSC_VER
if (argc == 2)
{
connectString = argv[1];
}
else
{
std::cout << "usage: " << argv[0]
<< " connectstring\n"
<< "example: " << argv[0]
<< " \'connect_string_for_empty_backend\'\n";
std::exit(1);
}
try
{
test1();
// test2();
// ...
std::cout << "\nOK, all tests passed.\n\n";
return EXIT_SUCCESS;
}
catch (std::exception const & e)
{
std::cout << e.what() << '\n';
}
return EXIT_FAILURE;
}
......@@ -25,7 +25,8 @@ set(SOCI_BACKENDS_DB_DEPENDENCIES
Oracle
PostgreSQL
SQLite3
Firebird)
Firebird
DB2)
set(SOCI_BACKENDS_ALL_DEPENDENCIES
Boost
......
set(DB2_FIND_QUIETLY TRUE)
find_package(DB2)
boost_external_report(DB2 INCLUDE_DIR LIBRARIES)
#TODO: Add detection on win32
find_path(DB2_INCLUDE_DIR sqlcli1.h
$ENV{DB2_INCLUDE_DIR}
$ENV{DB2_DIR}/include
/opt/ibm/db2/V9.7/include
/opt/ibm/db2/V9.5/include
/opt/ibm/db2/V9.1/include)
find_library(DB2_LIBRARY NAMES db2
PATHS
$ENV{DB2_LIB_DIR}
$ENV{DB2_DIR}/lib32
$ENV{DB2_DIR}/lib64
/opt/ibm/db2/V9.7/lib32
/opt/ibm/db2/V9.5/lib64
/opt/ibm/db2/V9.1/lib32
/opt/ibm/db2/V9.1/lib64)
if(DB2_LIBRARY)
get_filename_component(DB2_LIBRARY_DIR ${DB2_LIBRARY} PATH)
endif()
if(DB2_INCLUDE_DIR AND DB2_LIBRARY_DIR)
set(DB2_FOUND TRUE)
include_directories(${DB2_INCLUDE_DIR})
link_directories(${DB2_LIBRARY_DIR})
endif()
set(DB2_LIBRARIES ${DB2_LIBRARY})
# Handle the QUIETLY and REQUIRED arguments and set DB2_FOUND to TRUE
# if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DB2
DEFAULT_MSG
DB2_INCLUDE_DIR
DB2_LIBRARIES)
mark_as_advanced(DB2_INCLUDE_DIR DB2_LIBRARIES)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment