[odb-users] Re: 2-table query

MM finjulhich at gmail.com
Wed Sep 16 17:22:11 EDT 2015


On 16 September 2015 at 16:10, Boris Kolpackov <boris at codesynthesis.com>
wrote:

> MM <finjulhich at gmail.com> writes:
>
> > Is the join-condition limited to data members?
>
> Just think a little: how would a C++ member function be mapped to
> a relational model?
>
> In ODB views, the JOIN condition can be specified as either a data
> member, which should be a pointer to object, or you can spell the
> condition literally, as a comparison of the relevant columns. In
> other words, the JOIN condition in ODB views is a very thin
> abstraction of the SQL JOIN condition. So next time when you are
> try to "stick" something in there, find out it doesn't work, and
> start writing another email to the mailing list, pause and think
> how would something like this be mapped to SQL..?
>
> Boris
>
>
Yes indeed it makes sense now. I suppose I assumed odb could magically make
the association given the member function  (and the fact that it returns
the associated object pointer)... But  that doesn't make sense.

Is it possible to add a little paragraph to clarify this part for the
join-condition in the case of?
 JOIN ON ( F::mid = M::id )
I could write something up and send a "pull request", I suppose, if that is
how you merge things in.

Thanks, I have made the changes, and the generated code compiles correctly.
Runtime works as well, except that I have object ownership issues that
cause a crash on exit,
which I am trying to understand.

Here is the types and pragmas again:

struct M {
...
  std::uint32_t id;
...
};

struct F {
... const M* m;   /// gets stored/loaded as a mid in the table, setting m
searchs for the right M object
  std::uint32_t  id;
...
};

#pragma db view object(F = fctrct) object(M = fmkt: fctrct::mid==fmkt::id)\
  query( fctrct::month==fmkt::activemonth || fctrct::month==fmkt::nextmonth
)
struct F_current {
  std::shared_ptr<F> fctrct;
};

and the query code is:

odb::transaction t{ db.begin() };
odb::session s;  /// as required mentioned in the manual
auto res = db.query<F_current>();
for (const auto& fc: res) {
  /// I would like to use the F* (take ownership of it)
  fc.fctrct.get();  ///this is probably wrong to take ownership of this
pointer
}

As it happens, the M objects have manually been loaded prior to this query.

After the crash, I printed the object F's address. It's the same address
for each iteration of the loop. So, odb allocates a single F_current
instance, and a single F instance with this code above, and populates it
with the result of the query for each iteration.  Is this correct?

When does the F instance get deallocated? Obviously when the last
shared_ptr pointing to it is destroyed, but when is that? Ie, in the code
above, what is the scope of the fctrct shared pointer?
When does the F_current instance get destroyed?

This is similar to the employee/employer examples... But I manually load
all the employers ahead of time, then load either all or some of the
employees later. And the employed_by_ is not a shared pointer but a raw
pointer in my case. The employers are stored in a boost ptr container, so
are the employees.

Can I get odb to allocate a new instance of F for each result from the
query?
I could just clone the F instance atevery iteration in the for loop, and
take ownership of that instead.

I appreciate all the help I can get. It is a difficult problem.

Rds,


More information about the odb-users mailing list