[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.


-----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


#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>
      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));
          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);


2. When compiling your headers with the ODB compiler, add the following

   --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.


More information about the odb-users mailing list