Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cmake_minimum_required (VERSION 2.8.11)
project (dbccpp)

set( CMAKE_VERBOSE_MAKEFILE on )

file(GLOB SOURCES_DBCCPP include/dbccpp/*.h src/*.cpp src/*.h src/mysql/*.cpp src/mysql/*.h src/sqlite/*.cpp src/sqlite/*.h )
file(GLOB SOURCES_TEST test/src/*.cpp test/testcpp/src/*.cpp )

include_directories(include test/testcpp/include )

link_directories(lib)

add_library (libdbccpp STATIC ${SOURCES_DBCCPP})

add_executable(dbccpp-test ${SOURCES_TEST} )

target_link_libraries(dbccpp-test libdbccpp.a)

10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ TARGET = lib/lib$(LIBNAME).a
# For building with clang++ 3.1 in Ubuntu 12.04, install system clang and
# add -I/usr/include/clang/3.0/include to compile flags

OPTIMIZE = -O2 # -g -std=c++0x | -std=c++11
OPTIMIZE = -g -std=c++0x
COMPILER = clang++ # g++

CXX = $(COMPILER)
CXXFLAGS = -pipe $(OPTIMIZE) -fPIC -Wall -Wextra -Werror -D_REENTRANT
CXXFLAGS = -pipe $(OPTIMIZE) -fPIC -Wall -Wextra -D_REENTRANT
INCPATH = -Iinclude

TEST = dbccpp-test
Expand All @@ -21,7 +21,7 @@ TESTINCPATH = $(INCPATH) -I$(TESTCPPDIR)/include

LINK = $(COMPILER)
LFLAGS = -Wl,-O1
LIBS = -Llib -l$(LIBNAME) -L$(TESTCPPDIR)/lib -ltestcpp -lsqlite3
LIBS = -Llib -l$(LIBNAME) -L$(TESTCPPDIR)/lib -ltestcpp -lsqlite3 -lmysqlclient

AR = ar cqs

Expand All @@ -30,7 +30,8 @@ DEP = Makefile.dep
# Generic source file lists

SRC = $(wildcard src/*.cpp) \
$(wildcard src/sqlite/*.cpp)
$(wildcard src/sqlite/*.cpp) \
$(wildcard src/mysql/*.cpp)

OBJS = $(patsubst src/%.cpp, obj/%.o, $(SRC))

Expand All @@ -41,6 +42,7 @@ TESTOBJS = $(patsubst test/src/%.cpp, test/obj/%.o, $(TESTSRC))

obj/%.o: src/%.cpp
mkdir -p obj/sqlite
mkdir -p obj/mysql
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<

$(TARGET): $(OBJS)
Expand Down
10 changes: 8 additions & 2 deletions include/dbccpp/DbConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ namespace dbc
*/
class DbConnection
{
UTILCPP_DECLARE_INTERFACE(DbConnection)

public:
virtual ~DbConnection() {};
/** Creates the singleton instance of the driver-specific database
* connection.
*
* @param driver Driver name in lowercase, e.g. "sqlite"
* @param params Parameters for the driver, e.g. file name for SQLite.
*/
static void connect(const std::string& driver, const std::string& params);
static void disconnect();

/** Access the singleton instance of the database connection.
* The connection instance needs to be created with connect() before this
Expand All @@ -37,7 +37,13 @@ class DbConnection
virtual const CountProxy& executeUpdate(const std::string& sql) = 0;
virtual ResultSet::ptr executeQuery(const std::string& sql) = 0;

protected:
DbConnection() {}
private:

DbConnection(const DbConnection&);
DbConnection& operator=(const DbConnection&);

static std::string _driver;
static std::string _params;
};
Expand Down
2 changes: 1 addition & 1 deletion include/dbccpp/PreparedStatement.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class PreparedStatement
*/
// FIXME: this should be a 64-bit type really
// FIXME: information is SQLite-specific
virtual int getLastInsertId() = 0;
virtual u_int64_t getLastInsertId() = 0;

/** Get the underlying SQL statement. */
virtual const char* getSQL() const = 0;
Expand Down
58 changes: 31 additions & 27 deletions src/DbConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,49 @@
#include "DbConnectionFactory.h"

#if !(defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus > 199711L))
#include <utilcpp/scoped_ptr.h>
#include <utilcpp/scoped_ptr.h>
#endif

namespace dbc
{

std::string DbConnection::_driver;
std::string DbConnection::_params;
namespace dbc {

#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus > 199711L)
typedef std::unique_ptr<DbConnection> dbconnection_scoped_ptr;
typedef std::unique_ptr<DbConnection> dbconnection_scoped_ptr;
#else
typedef utilcpp::scoped_ptr<DbConnection> dbconnection_scoped_ptr;
typedef utilcpp::scoped_ptr<DbConnection> dbconnection_scoped_ptr;
#endif

void DbConnection::connect(const std::string& driver, const std::string& params)
{
if (!_driver.empty())
throw DbErrorBase("Already connected, disconnect() has to be called before reconnect");
std::string DbConnection::_driver;
std::string DbConnection::_params;

_driver = driver;
_params = params;
}
static dbconnection_scoped_ptr instanceObj;

void DbConnection::connect(const std::string &driver,
const std::string &params) {
if (!_driver.empty())
throw DbErrorBase(
"Already connected, disconnect() has to be called before reconnect");

DbConnection& DbConnection::instance()
{
static dbconnection_scoped_ptr instance;
_driver = driver;
_params = params;
}

if (!instance)
{
if (_driver.empty())
throw DbErrorBase("connect() has to be called before instance()");
DbConnection &DbConnection::instance() {
if (!instanceObj) {
if (_driver.empty())
throw DbErrorBase("connect() has to be called before instance()");

instance = DbConnectionFactory::instance().createDbConnection(_driver, _params);
if (!instance)
throw DbErrorBase("Null instance returned from driver factory");
}
instanceObj =
DbConnectionFactory::instance().createDbConnection(_driver, _params);
if (!instanceObj)
throw DbErrorBase("Null instance returned from driver factory");
}

return *instance;
return *instanceObj;
}

void DbConnection::disconnect() {
instanceObj.reset();
_driver = "";
_params = "";
}
}
47 changes: 24 additions & 23 deletions src/DbConnectionFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
#include "DbConnectionFactory.h"
#include <dbccpp/DbExceptions.h>
#include "mysql/MySQLConnection.h"
#include "sqlite/SQLiteConnection.h"
#include <dbccpp/DbExceptions.h>

namespace dbc
{
namespace dbc {

dbconnection_transferable_ptr createSQLiteConnection(const std::string& params)
{
return dbconnection_transferable_ptr(new SQLiteConnection(params));
dbconnection_transferable_ptr
createSQLiteConnection(const std::string &params) {
return dbconnection_transferable_ptr(new SQLiteConnection(params));
}

DbConnectionFactory::DbConnectionFactory() :
_callbacks_registry()
{
// see doc/README-factory.rst why this unneccessary coupling is needed
_callbacks_registry["sqlite"] = createSQLiteConnection;
dbconnection_transferable_ptr createMySQLConnection(const std::string &params) {
return dbconnection_transferable_ptr(new MySQLConnection(params));
}

dbconnection_transferable_ptr DbConnectionFactory::createDbConnection(const std::string& driverName,
const std::string& params)
{
CallbackMap::const_iterator it = _callbacks_registry.find(driverName);
if (it == _callbacks_registry.end())
throw DbErrorBase(driverName + ": database driver not found");

return (it->second)(params);
DbConnectionFactory::DbConnectionFactory() : _callbacks_registry() {
// see doc/README-factory.rst why this unneccessary coupling is needed
_callbacks_registry["sqlite"] = createSQLiteConnection;
_callbacks_registry["mysql"] = createMySQLConnection;
}

DbConnectionFactory& DbConnectionFactory::instance()
{
static DbConnectionFactory factory;
return factory;
dbconnection_transferable_ptr
DbConnectionFactory::createDbConnection(const std::string &driverName,
const std::string &params) {
CallbackMap::const_iterator it = _callbacks_registry.find(driverName);
if (it == _callbacks_registry.end())
throw DbErrorBase(driverName + ": database driver not found");

return (it->second)(params);
}

DbConnectionFactory &DbConnectionFactory::instance() {
static DbConnectionFactory factory;
return factory;
}
}
28 changes: 13 additions & 15 deletions src/DbConnectionFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,33 @@
#include <map>
#include <memory>

namespace dbc
{
namespace dbc {

#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus > 199711L)
typedef std::unique_ptr<DbConnection> dbconnection_transferable_ptr;
typedef std::unique_ptr<DbConnection> dbconnection_transferable_ptr;
#else
typedef std::auto_ptr<DbConnection> dbconnection_transferable_ptr;
typedef std::auto_ptr<DbConnection> dbconnection_transferable_ptr;
#endif

// Abstract factory that creates database-specific DbFactories.
// Based on "Modern C++ Design" scalable factory idiom.
class DbConnectionFactory
{
UTILCPP_DECLARE_SINGLETON(DbConnectionFactory)
class DbConnectionFactory {
UTILCPP_DECLARE_SINGLETON(DbConnectionFactory)

public:
typedef dbconnection_transferable_ptr (*CreateDbConnectionCallback)(const std::string&);
typedef std::map<std::string, CreateDbConnectionCallback> CallbackMap;
typedef dbconnection_transferable_ptr (*CreateDbConnectionCallback)(
const std::string &);
typedef std::map<std::string, CreateDbConnectionCallback> CallbackMap;

bool registerDbConnectionCreator(const std::string& driverName,
CreateDbConnectionCallback creator);
bool registerDbConnectionCreator(const std::string &driverName,
CreateDbConnectionCallback creator);

dbconnection_transferable_ptr createDbConnection(const std::string& driverName,
const std::string& params);
dbconnection_transferable_ptr
createDbConnection(const std::string &driverName, const std::string &params);

private:
CallbackMap _callbacks_registry;
CallbackMap _callbacks_registry;
};

}

#endif /* DBCONNECTIONFACTORY_H */
40 changes: 22 additions & 18 deletions src/PreparedStatement.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
#include <dbccpp/PreparedStatement.h>

namespace dbc
{
namespace dbc {

template<>
void PreparedStatement::set<int>(const int parameterIndex, const int val)
{ setInt(parameterIndex, val); }
template <>
void PreparedStatement::set<int>(const int parameterIndex, const int val) {
setInt(parameterIndex, val);
}

template<>
void PreparedStatement::set<bool>(const int parameterIndex, const bool val)
{ setBool(parameterIndex, val); }
template <>
void PreparedStatement::set<bool>(const int parameterIndex, const bool val) {
setBool(parameterIndex, val);
}

template<>
void PreparedStatement::set<double>(const int parameterIndex, const double val)
{ setDouble(parameterIndex, val); }
template <>
void PreparedStatement::set<double>(const int parameterIndex,
const double val) {
setDouble(parameterIndex, val);
}

template<>
void PreparedStatement::set(const int parameterIndex, const char* val)
{ setString(parameterIndex, val); }
template <>
void PreparedStatement::set(const int parameterIndex, const char *val) {
setString(parameterIndex, val);
}

template<>
template <>
void PreparedStatement::set<std::string>(const int parameterIndex,
const std::string& val)
{ setString(parameterIndex, val); }

const std::string &val) {
setString(parameterIndex, val);
}
}
39 changes: 13 additions & 26 deletions src/ResultSet.cpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
#include <dbccpp/ResultSet.h>
#include <dbccpp/SubscriptProxy.h>

namespace dbc
{
namespace dbc {

template <>
int ResultSet::get(const int columnIndex) const
{
return getInt(columnIndex);
template <> int ResultSet::get(const int columnIndex) const {
return getInt(columnIndex);
}

template <>
double ResultSet::get(const int columnIndex) const
{
return getDouble(columnIndex);
template <> double ResultSet::get(const int columnIndex) const {
return getDouble(columnIndex);
}

template <>
bool ResultSet::get(const int columnIndex) const
{
return getBool(columnIndex);
template <> bool ResultSet::get(const int columnIndex) const {
return getBool(columnIndex);
}

template <>
std::string ResultSet::get(const int columnIndex) const
{
return getString(columnIndex);
template <> std::string ResultSet::get(const int columnIndex) const {
return getString(columnIndex);
}

template <>
void ResultSet::get(const int columnIndex, std::string& out) const
{
return getString(columnIndex, out);
template <> void ResultSet::get(const int columnIndex, std::string &out) const {
return getString(columnIndex, out);
}

const SubscriptProxy ResultSet::operator[] (const int index) const
{
return SubscriptProxy(*this, index);
const SubscriptProxy ResultSet::operator[](const int index) const {
return SubscriptProxy(*this, index);
}

}
Loading