Skip to content

Rait changes #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ obj/
bin/
datamappercpp-test
test.sqlite
*.suo
*.sdf
*.opensdf
Debug
6 changes: 6 additions & 0 deletions include/datamappercpp/Field.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct Field
template <>
std::string Field<int>::getType() const { return "INT"; }

template <>
std::string Field<__int64>::getType() const { return "INT"; }

// TODO: add CHECK( in { 0, 1 } )
template <>
std::string Field<bool>::getType() const { return "INT"; }
Expand All @@ -57,6 +60,9 @@ std::string Field<const char*>::getType() const { return "TEXT"; }
template <>
std::string Field<std::string>::getType() const { return "TEXT"; }

template <>
std::string Field<std::wstring>::getType() const { return "TEXT"; }

}

#endif /* DATAMAPPERCPP_FIELD_H */
129 changes: 125 additions & 4 deletions include/datamappercpp/sql/Repository.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include <datamappercpp/sql/Transaction.h>
#include <datamappercpp/sql/db.h>
#include <datamappercpp/sql/exceptions.h>
Expand All @@ -17,13 +18,16 @@
namespace stdutil = std;
}
#else
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/function.hpp>
namespace dm
{
namespace stdutil = boost;
}
#endif


namespace dm {
namespace sql {

Expand Down Expand Up @@ -70,6 +74,7 @@ class ObjectFieldBinder
unsigned int _counter;
};


/**
* Repository transfers domain entities and their collections to and from
* the database.
Expand All @@ -82,6 +87,7 @@ class Repository
{
public:
typedef std::vector<Entity> Entities;
typedef std::vector<stdutil::shared_ptr<Entity> > EntitiesPtr;
typedef SqlStatementBuilder<Entity, Mapping> EntitySqlBuilder;

static void CreateTable(bool enableTransaction = true)
Expand Down Expand Up @@ -159,7 +165,7 @@ class Repository
entity.id = -1;
}

static void Delete(int id,
static void Delete(__int64 id,
bool enableTransaction = true,
bool checkOneDeleted = true)
{
Expand All @@ -181,6 +187,21 @@ class Repository
transaction.commit();
}

template <typename Value>
static void DeleteByField(std::string field,
const Value &value,
bool enableTransaction = true)
{
Statement statement = PrepareStatement(EntitySqlBuilder::DeleteByFieldStatement(field));
*statement << value;

Transaction transaction(enableTransaction);

statement->executeUpdate();

transaction.commit();
}

static void DeleteAll(bool enableTransaction = true)
{
Transaction transaction(enableTransaction);
Expand All @@ -190,7 +211,7 @@ class Repository
transaction.commit();
}

static Entity Get(int id)
static Entity Get(__int64 id)
{
// note that SELECTs are outside transactions and
// mixing them with ongoing transactions may cause problems
Expand Down Expand Up @@ -222,6 +243,13 @@ class Repository
return GetByQueryImpl(statement, allowMany, -1);
}

static Entity GetByQuery(const std::wstring& sql,
bool allowMany = false)
{
return GetByQuery(static_cast<const char*>(toMBStr(sql)), allowMany);
//toMBStr is included from SqlStatementBuilder.h
}

static Entity GetByQuery(Statement& statement,
bool allowMany = false)
{
Expand All @@ -236,6 +264,24 @@ class Repository
return GetManyByQuery(_getAllEntitiesStatement);
}

static EntitiesPtr GetAllPtr()
{
prepareStatement(_getAllEntitiesStatement,
&EntitySqlBuilder::SelectAllStatement);

return GetManyByQueryPtr(_getAllEntitiesStatement);
}

template <typename Value>
static EntitiesPtr GetManyByFieldPtr(const std::string& fieldname, Value value)
{
Statement statement = PrepareStatement(
EntitySqlBuilder::SelectByFieldStatement(fieldname));
*statement << value;

return GetManyByQueryPtr(statement);
}

template <typename Value>
static Entities GetManyByField(const std::string& fieldname, Value value)
{
Expand All @@ -246,12 +292,63 @@ class Repository
return GetManyByQuery(statement);
}

template <typename Value1, typename Value2>
static EntitiesPtr GetManyByFieldPtr(const std::string& fieldname1, Value1 value1,
const std::string& fieldname2, Value2 value2)
{
Statement statement = PrepareStatement(
EntitySqlBuilder::SelectByFieldStatement(fieldname1, fieldname2));
*statement << value1 << value2;

return GetManyByQueryPtr(statement);
}

template <typename Value1, typename Value2>
static Entities GetManyByField(const std::string& fieldname1, Value1 value1,
const std::string& fieldname2, Value2 value2)
{
Statement statement = PrepareStatement(
EntitySqlBuilder::SelectByFieldStatement(fieldname1, fieldname2));
*statement << value1 << value2;

return GetManyByQuery(statement);
}

template <typename Value1, typename Value2, typename Value3>
static EntitiesPtr GetManyByFieldPtr(const std::string& fieldname1, Value1 value1,
const std::string& fieldname2, Value2 value2, const std::string& fieldname3, Value3 value3)
{
Statement statement = PrepareStatement(
EntitySqlBuilder::SelectByFieldStatement(fieldname1, fieldname2, fieldname3));
*statement << value1 << value2 << value3;

return GetManyByQueryPtr(statement);
}

template <typename Value1, typename Value2, typename Value3>
static Entities GetManyByField(const std::string& fieldname1, Value1 value1,
const std::string& fieldname2, Value2 value2, const std::string& fieldname3, Value3 value3)
{
Statement statement = PrepareStatement(
EntitySqlBuilder::SelectByFieldStatement(fieldname1, fieldname2, fieldname3));
*statement << value1 << value2 << value3;

return GetManyByQuery(statement);
}

static Entities GetManyByQuery(const std::string& sql)
{
Statement statement = PrepareStatement(sql);
return GetManyByQuery(statement);
}

static Entities GetManyByQuery(const std::wstring& sql)
{
Statement statement = PrepareStatement(toMBStr(sql));
//toMBStr is included from SqlStatementBuilder.h
return GetManyByQuery(statement);
}

static Entities GetManyByQuery(Statement& statement)
{
Entities entities;
Expand All @@ -271,6 +368,30 @@ class Repository
return entities;
}

static EntitiesPtr GetManyByQueryPtr(Statement& statement)
{
EntitiesPtr entities;
dbc::ResultSet::ptr result(statement->executeQuery());

while (result->next())
{
stdutil::shared_ptr<Entity> entity(stdutil::make_shared<Entity>());
entity->id = (*result)[0];

ObjectFieldBinder fieldbinder(*result);
Mapping::accept(fieldbinder, *entity);

entities.push_back(entity);
}

return entities;
}

static dbc::ResultSet::ptr ExecuteQuery(std::string sql)
{
Statement statement;
}

static void ResetStatements()
{
// Free the resources associated with prepared statments.
Expand Down Expand Up @@ -307,7 +428,7 @@ class Repository
}

inline static Entity GetByQueryImpl(Statement& statement,
bool allowMany, int id)
bool allowMany, __int64 id)
{
Entity entity;

Expand All @@ -319,7 +440,7 @@ class Repository
// TODO: entity.id << *result;
entity.id = (*result)[0];
}
catch (const dbc::NoResultsError& e)
catch (const dbc::NoResultsError&)
{
std::ostringstream msg;
msg << "No " << Mapping::getLabel() << " exists for query '"
Expand Down
55 changes: 49 additions & 6 deletions include/datamappercpp/sql/detail/SqlStatementBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@
#include <datamappercpp/Field.h>
#include <datamappercpp/sql/detail/StatementBuilderFieldVisitors.h>

#include <utilcpp/release_assert.h>
#include <utilcpp/disable_copy.h>

#include <string>
#include <sstream>
#include <string>

// FIXME: ostringstream::exceptions(s.badbit | s.failbit);

namespace
{
#include <xstring>
std::string toMBStr(std::wstring const& str)
{
std::string mbstr( str.size(), 0 );
#pragma warning(disable:4996)//We are perfectly aware the wcstombs is not "safe" operation as the destination size is not given - fortunately our destination has dynamic size.
wcstombs(&mbstr[0], &str[0], str.size());
#pragma warning(default:4996)
return mbstr;
}
}

namespace dm {
namespace sql {

Expand All @@ -32,7 +42,7 @@ class SqlStatementBuilder
Mapping::accept(fieldBuilder, _dummy_entity);

// replace last comma with ')'
long pos = sql.tellp();
std::streamoff pos = sql.tellp();
sql.seekp(pos - 1);
sql << ")";

Expand Down Expand Up @@ -78,7 +88,7 @@ class SqlStatementBuilder
UpdateStatementFieldBuilder fieldBuilder(sql);
Mapping::accept(fieldBuilder, _dummy_entity);

long pos = sql.tellp();
std::streamoff pos = sql.tellp();
sql.seekp(pos - 1); // remove last comma

sql << " WHERE id=?";
Expand All @@ -105,6 +115,16 @@ class SqlStatementBuilder
return sql.str();
}

static std::string DeleteByFieldStatement(std::string &field)
{
std::ostringstream sql;

sql << "DELETE FROM " << Mapping::getLabel()
<< " WHERE " << field << "=?";

return sql.str();
}

static std::string SelectAllStatement()
{
std::ostringstream sql;
Expand All @@ -129,6 +149,29 @@ class SqlStatementBuilder
return sql.str();
}

// TODO: implement SelectByFieldStatement as variadic arguments template for C++11.
static std::string SelectByFieldStatement(const std::string field1, const std::string field2)
{
std::ostringstream sql;

sql << "SELECT * FROM " << Mapping::getLabel()
<< " WHERE " << field1 << "=? AND "
<< field2 << "=?";

return sql.str();
}

static std::string SelectByFieldStatement(const std::string field1, const std::string field2, const std::string field3)
{
std::ostringstream sql;

sql << "SELECT * FROM " << Mapping::getLabel()
<< " WHERE " << field1 << "=? AND "
<< field2 << "=? AND " << field3 << "=?";

return sql.str();
}

private:
// disable instantiation to assure the class is only used via it's static
// functions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include <datamappercpp/Field.h>

#include <utilcpp/disable_copy.h>
Expand Down
Loading