Project

General

Profile

RE: Support for composite primary keys in dbo ยป composite-key-load.patch

Patch for loading with composite keys - Koen Deforche, 09/23/2010 12:31 AM

View differences:

src/Wt/Dbo/Session
namespace Dbo {
namespace Impl {
extern WTDBO_API std::string quoteSchemaDot(const std::string& table);
template <class C, typename T> struct LoadHelper;
}
struct NullType {
......
template <class C> ptr<C> loadLazy(const typename dbo_traits<C>::IdType& id);
template <class C> ptr<C> load(SqlStatement *statement, int& column);
template <class C>
ptr<C> loadWithNaturalId(SqlStatement *statement, int& column);
template <class C>
ptr<C> loadWithLongLongId(SqlStatement *statement, int& column);
void prune(MetaDboBase *obj);
template <class C> void prune(MetaDbo<C> *obj);
......
friend class DropSchema;
friend class ToAnysAction;
friend class FromAnyAction;
template <class C, typename T> friend class Impl::LoadHelper;
};
}
src/Wt/Dbo/Session_impl.h
namespace Wt {
namespace Dbo {
namespace Impl {
template <class C, typename T>
struct LoadHelper
{
static ptr<C> load(Session *session, SqlStatement *statement,
int& column)
{
return session->loadWithNaturalId<C>(statement, column);
};
};
template <class C>
struct LoadHelper<C, long long>
{
static ptr<C> load(Session *session, SqlStatement *statement,
int& column)
{
return session->loadWithLongLongId<C>(statement, column);
}
};
}
template <class C>
void Session::mapClass(const char *tableName)
......
template <class C>
ptr<C> Session::load(SqlStatement *statement, int& column)
{
return Impl::LoadHelper<C, typename dbo_traits<C>::IdType>
::load(this, statement, column);
}
template <class C>
ptr<C> Session::loadWithNaturalId(SqlStatement *statement, int& column)
{
Mapping<C> *mapping = getMapping<C>();
typedef typename dbo_traits<C>::IdType IdType;
IdType id;
/* Natural id is possibly multiple fields anywhere */
MetaDbo<C> *dbo = new MetaDbo<C>(dbo_traits<C>::invalidId(), -1,
MetaDboBase::Persisted, *this, 0);
implLoad<C>(*dbo, statement, column);
typename Mapping<C>::Registry::iterator i
= mapping->registry_.find(dbo->id());
if (i == mapping->registry_.end()) {
mapping->registry_[id] = dbo;
return ptr<C>(dbo);
} else {
delete dbo;
return ptr<C>(i->second);
}
}
template <class C>
ptr<C> Session::loadWithLongLongId(SqlStatement *statement, int& column)
{
Mapping<C> *mapping = getMapping<C>();
/*
* If mapping uses surrogate keys, then we can first read the id and decide
* if we already have it.
* If mapping uses surrogate keys, then we can first read the id and
* decide if we already have it.
*
* If not, then we need to first read the object, get the id, and if we already
* had it, delete the redundant copy.
* If not, then we need to first read the object, get the id, and if
* we already had it, delete the redundant copy.
*/
typedef typename dbo_traits<C>::IdType IdType;
IdType id;
long long id;
if (mapping->surrogateIdFieldName) {
/* Auto-generated surrogate key is first field */
......
}
} else {
/* Natural id is possibly multiple fields anywhere */
MetaDbo<C> *dbo = new MetaDbo<C>(dbo_traits<C>::invalidId(), -1,
MetaDboBase::Persisted, *this, 0);
implLoad<C>(*dbo, statement, column);
test/dbo/DboTest.C
As asManyToOne;
Cs csManyToMany;
D() { }
D(const Coordinate& anId, const std::string& aName)
: id(anId),
name(aName)
{ }
template <class Action>
void persist(Action& a)
{
......
{
dbo::Transaction t(*session_);
session_->add(new D(Coordinate(5, 6), "yes"));
dbo::ptr<D> d1 = session_->find<D>();
BOOST_REQUIRE(d1->name == "yes");
BOOST_REQUIRE(d1->id == Coordinate(5, 6));
session_->add(new C("c1"));
dbo::Query< dbo::ptr<C> > query = session_->find<C>();
    (1-1/1)