[odb-users] Trouble with lazy_ptr

Miguel Revilla Rodríguez yo at miguelrevilla.com
Sat Aug 18 20:06:16 EDT 2012


I'm completely lost on this. Examples compile fine, so it's not an
environment problem. Basically I use this files (sorry if it is a bit
long, but I'm really, really lost):

node.h:

#ifndef NODE_H
#define NODE_H

#include <string>
#include <vector>
#include <odb/core.hxx>
#include <odb/lazy-ptr.hxx>

#include "activity.h"
#include "userProfile.h"
#include "avatar.h"

class group ;

#pragma db object polymorphic
class node {
public:
        node(   const std::string &hash,
                unsigned long creationTime) :
                hash_(hash), creationTime_(creationTime) {}
        virtual ~node() = 0 ;

        void nodeavatar(const odb::lazy_shared_ptr<avatar> &n) ;
        const odb::lazy_shared_ptr<avatar> nodeavatar() ;
        const std::string nodeHash() ;


protected:
        friend class odb::access ;
        node() {}

        #pragma db id auto
        unsigned long id_ ;
        std::string hash_ ;
        unsigned long creationTime_ ;
        #pragma db value_not_null
        odb::lazy_shared_ptr<avatar> nodeavatar_ ;
        #pragma db value_not_null
        std::vector<odb::lazy_shared_ptr<activity> > activities_ ;
        #pragma db value_not_null inverse(nodes_)
        std::vector<odb::lazy_weak_ptr<group> > groups_ ;
} ;

#pragma db object
class user : public node {
typedef std::vector<odb::lazy_weak_ptr<user>> friends_type ;
public:
        user(   const std::string &hash,
                unsigned long creationTime,
                const std::string &username,
                const std::string &password,
                const std::string &email,
                const std::string &creationIP) :
                node(hash,creationTime),
                username_(username),
                password_(password),
                email_(email),
                creationIP_(creationIP) {}

        const unsigned long id() ;
        const bool verified() ;
        const bool locked() ;
        const std::string username() ;
        const std::string email() ;
        void verified(const bool &v) ;
        void locked(const bool &l) ;
        void email(const std::string &e) ;
        const std::shared_ptr<userProfile> profile() ;
        void profile(const std::shared_ptr<userProfile> &p) ;
        friends_type& friends() ;
        const friends_type& friends() const ;
        void addFriend(const std::shared_ptr<user> &u) ;

private:
        friend class odb::access ;
        user() {}

        std::string username_ ;
        std::string password_ ;
        std::string email_ ;
        #pragma db default(false)
        bool verified_ ;
        #pragma db default(false)
        bool locked_ ;
        std::string creationIP_ ;
        #pragma db not_null
        std::shared_ptr<userProfile> userProfile_ ;
        #pragma db value_not_null
        friends_type friends_ ;
} ;

#endif // NODE_H

----------------------------------------------------------------
node.cpp:

#include "node.h"

node::~node() {}

void node::nodeavatar(const odb::lazy_shared_ptr<avatar> &n) {
        nodeavatar_ = n ;
}

const odb::lazy_shared_ptr<avatar> node::nodeavatar() {
        return nodeavatar_ ;
}

const std::string node::nodeHash() {
        return hash_ ;
}

const unsigned long user::id() {
        return id_ ;
}

const bool user::verified() {
        return verified_ ;
}

const bool user::locked() {
        return locked_ ;
}

const std::string user::username() {
        return username_ ;
}

const std::string user::email() {
        return email_ ;
}

void user::email(const std::string &e) {
        email_ = e ;
}

void user::verified(const bool &v) {
        verified_ = v ;
}

void user::locked(const bool &l) {
        locked_ = l ;
}

const std::shared_ptr<userProfile> user::profile() {
        return userProfile_ ;
}

void user::profile(const std::shared_ptr<userProfile> &p) {
        userProfile_ = p ;
}

typedef std::vector<odb::lazy_weak_ptr<user>> friends_type ;

friends_type& user::friends() {
        return friends_ ;
}

const friends_type& user::friends() const {
        return friends_ ;
}

void user::addFriend(const std::shared_ptr<user> &u) {
//      friends_.insert(u) ;
}

------------------------------------
apiUserFriends.cpp:


#include <odb/database.hxx>
#include <odb/pgsql/database.hxx>
#include <odb/transaction.hxx>
#include <Wt/Utils>
#include <vector>
#include <sstream>
#include <string>
#include "apiUserFriends.h"
#include "odbClasses/node.h"
#include "odbClasses/node-odb.h"
#include "odbClasses/session.h"
#include "odbClasses/session-odb.h"

apiUserFriends::apiUserFriends(serviceTools *serviceT, WObject
*parent) : WResource(parent), serviceT_(serviceT) {

}

apiUserFriends::~apiUserFriends() {
        beingDeleted() ;
}

void apiUserFriends::handleRequest(const Http::Request& request,
Http::Response& response) {

        response.setMimeType("application/json") ;

        if(
serviceT_->checkClientAuth(Utils::urlDecode(*request.getParameter("token")),permissions::permFrontend)
&&

serviceT_->checkSessionAuth(Utils::urlDecode(*request.getParameter("sessionid")),Utils::hexEncode(Utils::md5(request.clientAddress()))))
{

                typedef odb::query<session> query ;
                typedef odb::result<session> result ;

                odb::database *db_ = serviceT_->database() ;

                {
                        typedef std::vector<odb::lazy_weak_ptr<user>>
friends_type ;
                        odb::transaction t (db_->begin()) ;
                        result g(db_->query<session> ( query::token ==
Utils::urlDecode(*request.getParameter("sessionid")))) ;

                        if(g.size()==1) {
                                for(session& s: g) {
                                        std::shared_ptr<user>
u(s.sessionUser()) ;
                                        std::stringstream friendsStr ;
                                        friends_type& f (u->friends()) ;
                                        friends_type::iterator it ;
                                        for(auto it (f.begin()); it !=
f.end() ; it++) {

odb::lazy_weak_ptr<user>& tmpPtr (*it) ;
                                                tmpPtr.load() ;
                                        }
                                        response.out() <<
"{\"result\":\"true\",\"friends\":[" ;
                                        response.out() <<
friendsStr.str().substr(0,friendsStr.str().size()-1) ;
                                        response.out() << "]}\n" ;
                                }
                        } else {
                                response.out() <<
"{\"result\":\"error\",\"data\":{\"errormsg\":\"bad_session\"}}\n" ;
                        }

                        t.commit() ;
                }
        } else {
                response.out()  << "{\"result\":\"false\"}\n" ;
        }
}


When I try to compile I get:

[  2%] Building CXX object CMakeFiles/yajpws.dir/apiUserFriends.cpp.o
In file included from /usr/include/odb/lazy-ptr.hxx:643:0,
                 from /home/mine/bettercodes/yajp-backend/odbClasses/node.h:7,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:9:
/usr/include/odb/lazy-ptr.ixx: In instantiation of
'std::shared_ptr<_Tp> odb::lazy_weak_ptr<T>::load() const [with T =
user]':
/home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:48:19:
required from here
/usr/include/odb/lazy-ptr.ixx:1511:5: error: no match for 'operator='
in 'r = ((const
odb::lazy_weak_ptr<user>*)this)->odb::lazy_weak_ptr<user>::i_.odb::lazy_ptr_impl<T>::load<user>(0)'
/usr/include/odb/lazy-ptr.ixx:1511:5: note: candidates are:
In file included from
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/memory:87:0,
                 from /usr/include/odb/pointer-traits.hxx:11,
                 from /usr/include/odb/traits.hxx:11,
                 from /usr/include/odb/database.hxx:13,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:1:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:269:19:
note: std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(const
std::shared_ptr<_Tp>&) [with _Tp = user; std::shared_ptr<_Tp> =
std::shared_ptr<user>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:269:19:
note:   no known conversion for argument 1 from
'odb::object_traits<user>::pointer_type {aka user*}' to 'const
std::shared_ptr<user>&'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:273:2:
note: template<class _Tp1> std::shared_ptr&
std::shared_ptr::operator=(const std::shared_ptr<_Tp1>&) [with _Tp1 =
_Tp1; _Tp = user]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:273:2:
note:   template argument deduction/substitution failed:
In file included from /usr/include/odb/lazy-ptr.hxx:643:0,
                 from /home/mine/bettercodes/yajp-backend/odbClasses/node.h:7,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:9:
/usr/include/odb/lazy-ptr.ixx:1511:5: note:   mismatched types 'const
std::shared_ptr<_Tp>' and 'odb::object_traits<user>::pointer_type {aka
user*}'
In file included from
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/memory:87:0,
                 from /usr/include/odb/pointer-traits.hxx:11,
                 from /usr/include/odb/traits.hxx:11,
                 from /usr/include/odb/database.hxx:13,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:1:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:282:2:
note: template<class _Tp1> std::shared_ptr&
std::shared_ptr::operator=(std::auto_ptr<_Tp1>&&) [with _Tp1 = _Tp1;
_Tp = user]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:282:2:
note:   template argument deduction/substitution failed:
In file included from /usr/include/odb/lazy-ptr.hxx:643:0,
                 from /home/mine/bettercodes/yajp-backend/odbClasses/node.h:7,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:9:
/usr/include/odb/lazy-ptr.ixx:1511:5: note:   mismatched types
'std::auto_ptr<T>' and 'odb::object_traits<user>::pointer_type {aka
user*}'
In file included from
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/memory:87:0,
                 from /usr/include/odb/pointer-traits.hxx:11,
                 from /usr/include/odb/traits.hxx:11,
                 from /usr/include/odb/database.hxx:13,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:1:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:290:7:
note: std::shared_ptr<_Tp>&
std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp>&&) [with _Tp =
user; std::shared_ptr<_Tp> = std::shared_ptr<user>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:290:7:
note:   no known conversion for argument 1 from
'odb::object_traits<user>::pointer_type {aka user*}' to
'std::shared_ptr<user>&&'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:298:2:
note: template<class _Tp1> std::shared_ptr&
std::shared_ptr::operator=(std::shared_ptr<_Tp1>&&) [with _Tp1 = _Tp1;
_Tp = user]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:298:2:
note:   template argument deduction/substitution failed:
In file included from /usr/include/odb/lazy-ptr.hxx:643:0,
                 from /home/mine/bettercodes/yajp-backend/odbClasses/node.h:7,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:9:
/usr/include/odb/lazy-ptr.ixx:1511:5: note:   mismatched types
'std::shared_ptr<_Tp>' and 'odb::object_traits<user>::pointer_type
{aka user*}'
In file included from
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/memory:87:0,
                 from /usr/include/odb/pointer-traits.hxx:11,
                 from /usr/include/odb/traits.hxx:11,
                 from /usr/include/odb/database.hxx:13,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:1:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:306:2:
note: template<class _Tp1, class _Del> std::shared_ptr&
std::shared_ptr::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Tp1 =
_Tp1; _Del = _Del; _Tp = user]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/shared_ptr.h:306:2:
note:   template argument deduction/substitution failed:
In file included from /usr/include/odb/lazy-ptr.hxx:643:0,
                 from /home/mine/bettercodes/yajp-backend/odbClasses/node.h:7,
                 from /home/mine/bettercodes/yajp-backend/apiUserFriends.cpp:9:
/usr/include/odb/lazy-ptr.ixx:1511:5: note:   mismatched types
'std::unique_ptr<_Tp, _Dp>' and
'odb::object_traits<user>::pointer_type {aka user*}'
make[2]: *** [CMakeFiles/yajpws.dir/apiUserFriends.cpp.o] Error 1
make[1]: *** [CMakeFiles/yajpws.dir/all] Error 2
make: *** [all] Error 2


odb files are compiled with:

/usr/bin/odb --std c++11 --database pgsql --hxx-suffix .h --ixx-suffix
.i --cxx-suffix .cpp --output-dir
${CMAKE_CURRENT_SOURCE_DIR}/odbClasses --generate-query
--generate-schema --schema-format sql

and C++:

g++ -O2 -std=c++11 (4.7.1)

I really don't understand those errors. As a clue, if I comment out
the line tmpPtr.load(), everything compiles fine; and, if instead of
load() I use object_id(), the lazy_ptr returns the correct object ID,
so the lazy_ptr looks well formed and well instantiated. Another
things is that if I use std::weak_ptr (or shared_ptr for the matter)
everything works as expected, except that in some cases it gets on a
recursive loop that causes a crash (that's why I need to use lazy
pointers).

Thanks in advance if you help me out of this :) :) :)

Miguel



More information about the odb-users mailing list