// file : mssql/types/traits.cxx // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include "traits.hxx" using namespace std; namespace odb { namespace mssql { void value_traits<variant, id_long_string>:: param_callback (const void* context, size_t*, const void** buffer, size_t* size, chunk_type* chunk, void* tmp_buf, size_t tmp_capacity) { const variant& v (*static_cast<const variant*> (context)); string str; switch (v.val_type) { case variant::type_int: { ostringstream os; os << v.int_val; str = "bigint "; str += os.str (); break; } case variant::type_str: { str = "varchar "; str += v.str_val; break; } } // Here we assume that the temoprary buffer is large enough to fit // the whole string in one go. If that were not the case, then we // would have had to chunk it. // assert (tmp_capacity >= str.size ()); memcpy (tmp_buf, str.c_str (), str.size ()); *buffer = tmp_buf; *size = str.size (); *chunk = chunk_one; } void value_traits<variant, id_long_string>:: result_callback (void* context, size_t*, void** buffer, size_t* size, chunk_type chunk, size_t, void* tmp_buf, size_t tmp_capacity) { variant& v (*static_cast<variant*> (context)); switch (chunk) { case chunk_null: case chunk_one: { assert (false); // The value cannot be NULL or empty. break; } case chunk_first: { // Use the variant's string value as a temporary buffer. If this // were not possible, we could have allocated one as part of // context. // v.str_val.clear (); *buffer = tmp_buf; *size = tmp_capacity; break; } case chunk_next: { v.str_val.append (static_cast<char*> (tmp_buf), *size); *buffer = tmp_buf; *size = tmp_capacity; break; } case chunk_last: { v.str_val.append (static_cast<char*> (tmp_buf), *size); // Figure out what we've got. // string::size_type p (v.str_val.find (' ')); assert (p != string::npos); // Must have type followed by value. string type (v.str_val, 0, p); string text (v.str_val, p + 1, string::npos); if (type == "tinyint" || type == "smallint" || type == "int" || type == "bigint") { istringstream is (text); is >> v.int_val; v.val_type = variant::type_int; } else if (type == "char" || type == "varchar") { v.str_val = text; v.val_type = variant::type_str; } else assert (false); // Unknown type. break; } } } } }