RE: Support for composite primary keys in dbo ยป composite-key-load.patch
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>();
|