Retrieving blobs

Contents of blobs are retrieved by constructing a x::sql::fetchblob<char_type> and passing it to fetch() or fetch_vectors().

std::string blob;

statement->fetch("memo_column",
                 x::sql::fetchblob<char>::create([&blob]
                     (size_t rownum)
                     {
                         return std::back_insert_iterator<std::string>(blob);
                     }));

std::string blobs[4];

statement->fetch_vectors(4, "memo_column",
                 x::sql::fetchblob<char>::create([&blob]
                     (size_t rownum)
                     {
                         return std::back_insert_iterator<std::string>(blobs[rownum]);
                     }));

Fetch an arbitrarily large blob column by passing an x::sql::fetchblob<char_type> instead of an lvalue to fetch(), or an lvalue to a vector to fetch_vectors().

The parameter to create() is an output iterator factory. This is a lambda or a functor that takes a single size_t parameter and returns an output iterator over char or unsigned char values, that matches fetchblob's template parameter.

Use x::sql::fetchblob<char> with text blobs, and x::sql::fetchblob<unsigned char> with binary blobs. The implementation semantics of text and binary blobs are database driver-specific. Support depends on the database driver. Some drivers may or may not support fetching more than one blob, or fetching a vector of blobs.

The fetched blob gets written to the output iterator that's returned from the lambda/functor. fetch() always invokes the lambda functor with the parameter of 0. fetch_vectors() invokes the lambda/functor for each row where the blob is not NULL, passing the 0-based row number as a parameter.


std::string blob;

std::pair<x::sql::fetchblob<char>, x::sql::bitflag> blob_fetch=
  std::make_pair(x::sql::fetchblob<char>::create([&blob]
                     (size_t rownum)
                     {
                         return std::back_insert_iterator<std::string>(blob);
                     }, 0);


statement->fetch("memo_column", blob_fetch);

std::pair<x::sql::fetchblob<char>, std::vector<x::sql::bitflag>> blob_vector_fetch=
  std::make_pair(x::sql::fetchblob<char>::create([&blob]
                     (size_t rownum)
                     {
                         return std::back_insert_iterator<std::string>(blob);
                     }, std::vector<x::sql::bitflag>());

statement->fetch_vectors(4, "memo_column", blob_vector_fetch);

Pair x::sql::fetchblob<char> with an x::sql::bitflag, for fetch(), and with a vector of them, for fetch_vectors(), in order to retrieve NULL indicator flags explicitly.

x::sql::fetchblob<char>::create([&blob]
    (size_t rownum)
    {
       return std::make_pair(std::back_insert_iterator<std::string>(blob),
           []
           (std::back_insert_iterator<std::string> iter)
           {
               *iter++='\n';
           });
    }

The lambda/functor can return a std::pair instead of a single iterator value. The first value in the pair is the output iterator factory. The second value in the pair is another lambda/functor, which takes an output iterator value for a parameter. This is the finish lambda/functor.

The finish lambda/functor gets invoked after the entire contents of the blob get written to the output iterator, and it receives the value of the output iterator, after iterating over the entire blob, as its parameter. This finish lambda/functor is the means of obtaining the final output iterator value after iterating over the entire contents of the blob.