[odb-users] Creating BLOBs out of vector/array of doubles?

Boris Kolpackov boris at codesynthesis.com
Tue Jan 31 12:02:11 EST 2012


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