[odb-users] Creating BLOBs out of vector/array of doubles?
Szumowski, Thomas
thomas.szumowski at lmco.com
Tue Jan 31 13:07:52 EST 2012
Thanks Boris!
You code works just as expected. I understand the mapping concept better now.
I understand the risk in portability. For our application, we don't expect to require it to be portable in this particular case.
-Tom
-----Original Message-----
From: Boris Kolpackov [mailto:boris at codesynthesis.com]
Sent: Tuesday, January 31, 2012 12:02 PM
To: Szumowski, Thomas
Cc: odb-users at codesynthesis.com
Subject: EXTERNAL: Re: [odb-users] Creating BLOBs out of vector/array of doubles?
Hi Thomas,
Szumowski, Thomas <thomas.szumowski at lmco.com> writes:
> I have a large array of doubles (10000+ elements) that I'd like to
> store in the database using ODB. The array does not need to be queried
> on, just associated as a single element in a table.
>
> So ideally I'd like to BLOB the array (or vector) of doubles as a
> single entry of data.
The danger of this kind of operation is that the binary representation of the resulting array will not be portable (e.g., one applications is big-endian while another is little-endian; and in case of doubles, even ABIs with the same endian-ness can have different representations).
But if you want to do this then it is just a matter of providing a value_traits specialization. Here are the steps for SQLite that will allow you to save a vector of anything as a BLOB.
1. Save the following specialization in the blob-traits.hxx file or
similar:
#ifndef BLOB_TRAITS_HXX
#define BLOB_TRAITS_HXX
#include <vector>
#include <cstring> // std::memcpy
#include <odb/sqlite/traits.hxx>
namespace odb
{
namespace sqlite
{
template <typename T>
struct value_traits<std::vector<T>, id_blob>
{
public:
typedef std::vector<T> value_type;
typedef std::vector<T> query_type;
typedef details::buffer image_type;
static void
set_value (value_type& v,
const details::buffer& b,
std::size_t n,
bool is_null)
{
if (!is_null)
{
const T* p = reinterpret_cast<const T*> (b.data ());
v.assign (p, p + n / sizeof (T));
}
else
v.clear ();
}
static void
set_image (details::buffer& b,
std::size_t& n,
bool& is_null,
const value_type& v)
{
is_null = false;
n = v.size () * sizeof (T);
if (n > b.capacity ())
b.capacity (n);
if (n != 0)
std::memcpy (b.data (), &v.front (), n);
}
};
}
}
#endif // BLOB_TRAITS_HXX
2. When compiling your headers with the ODB compiler, add the following
option:
--hxx-prologue "#include \"blob-traits.hxx\""
The 'mapping' example in the odb-examples package has more information on customizing the mapping between C++ types and database types.
Boris
More information about the odb-users
mailing list