[odb-users] Re: Recommended way of persisting objects that contain struct timeval?

Boris Kolpackov boris at codesynthesis.com
Wed Aug 10 14:06:35 EDT 2011


Hi Thomas,

[CC'ed odb-users to my reply.]

Szumowski, Thomas <thomas.szumowski at lmco.com> writes:

> We have a legacy object I'd like to persist using ODB. One of the fields is
> time, in the form of a timeval
> structure. (http://www.gnu.org/s/hello/manual/libc/Elapsed-Time.html). The
> timeval structure is defined in sys/time.h (linux).
> 
> Is there a recommended way of persisting timeval structures without having 
> to edit sys/time.h with ODB markings?

There are actually two ways a struct like timeval can be stored in the
database: as a simple value or as a composite value. Sections 3.1,
"Concepts and Terminology" in the ODB manual gives a good overview of
the differences between the two, but, essentially, a simple value would
be stored in a single column and a composite value will occupy several
columns. The desired way normally depends on the application requirements.

To store timeval as a simple value (for example, as a number of 
milliseconds stored in a single 64-bit integer) we would need to map
it to a suitable database type using the type pragma. For the SQLite
database, we can do something like this:

#pragma db value(timeval) type("INTEGER")

Then we will need to provide the value_traits specialization for this
type that implements the conversion between the struct value and a
single integer. The 'mapping' example in the odb-example package shows
how to do this.

Storing timeval as a composite value is a bit trickier because it is
defined in a system header and, as you mentioned, we don't want to
modify it by adding a pragma that tells the ODB compiler it is a
composite value type. What we can do is add this pragma into the
ODB compilation process using the --odb-epilogue option. We will
also need to use the --include-regex option (added in ODB 1.5.0)
to fix up some of the includes. Here are step-by-step instructions
for a test header I created (test.hxx):

#include <sys/time.h>

#pragma db object
class person
{
public:
  #pragma db id
  unsigned long id_;

  timeval time_;
};

1. First, I created the "mapping file" for sys/time.h, I called it
   time-mapping.h, it contains just this line:

#pragma db value(timeval)

2. Now if I try to compile /usr/include/sys/time.h, I get empty
   generated files. As it turns out, timeval is defined in the
   bits/time.h header which is included by sys/time.h. So the
   ODB compiler command line I used is this:

odb -d sqlite --odb-epilogue-file time-mapping.h \
--include-regex '%time.h%<sys/time.h>%' -D __need_timeval \
/usr/include/bits/time.h

  The __need_timeval define is needed in order to make bits/time.h
  to define struct timeval.

  This step will product a set of C++ source file (time-odb.?xx) that
  contain the persistence code for struct timeval.

3. To compile test.hxx, I used this command line:

odb -d sqlite --odb-epilogue-file time-mapping.h \
--include-regex '%bits/time-odb.hxx%"time-odb.hxx"%' test.hxx

To tidy this up, you may want to place some of the options into an
options file, e.g., time.options:

--odb-epilogue-file time-mapping.h
--include-regex '%bits/time-odb.hxx%"time-odb.hxx"%'

Then the command lines become:

odb -d sqlite --include-regex '%time.h%<sys/time.h>%' -D __need_timeval \
--options-file time.options /usr/include/bits/time.h

odb -d sqlite --options-file time.options test.hxx

Boris



More information about the odb-users mailing list