[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