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>();
|
||