Hi together,

first of all, thanks for soci, it's great stuff and eases our database 
tasks quite a lot.

Recently, we have implemented a type conversion for our variant class, 
which enables us to store even multi-hierarchical data into a soci 
connection.

To give an example:

void masterclient(soci::session &sql) {
     variant master;
     master["cost"] = 1234.56f;
     master["name"] = "test";
     master["details"] = 2;

     for (size_t i = 0; i < master["details"].asSize(); ++i) {
         variant detail;
         detail["master_idx"] = "%PARENT%";
detail["id"] = i;
detail["data"] = "xyz";

         master["{details}"].push_back(std::move(detail));
     };

     vdb::storeTables(sql, "master", master);
}

Remarks:
%PARENT% is a placeholder for the last_insert_id, which maps the 
relationship between master and detail here
{}-field names indicate sub-table objects to avoid name clashes with the 
same name

Instead of using variant classes here, we could of course use any 
tree-like data structure, like xml.

Whatever... in the end, we have to convert the variant (the data) to 
something that soci understands. So we have implemented the 
type_conversion specialization:


namespace soci {
template<> struct type_conversion<variant> {
     typedef values base_type;

     static void from_base(values const &v, indicator ind, variant &out) {
     ...


At this point, we have to map fields from 'values' into our variant 
'out'. However, there's no way in iterating the values here, nor is 
there a way to figure out the size of values. Ouch.

To enable our implementation, we have changed values.h around line 221:

+    inline row * GetRow() const {
+        return row_;
+    }

This enables us (somehow) to iterate the values, and retrieve type 
information for each row:

         soci::row *row = v.GetRow();

         for (size_t x = 0; x < row->size(); ++x) {
             const column_properties &props = v.get_properties(x);
             const char *colname = props.get_name().c_str();
             if (v.get_indicator(x) == i_null) {
                 out[colname] = nullptr;
             } else {

                 switch (props.get_data_type()) {
                     case dt_string:
                         // store into variant as string
                     ...


However, I have no evidence that the row and the values are 'the same 
thing', and I don't feel to happy about this solution. Now here's my 
question: could you guys provide an iterator for the values class, or 
expose (e.g. a const row) accessor inside values?
Or is there any other method you recommand to get this particular job done?

Any hints appreciated!

Thanks and cheers,
   Roman








------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
Soci-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/soci-users

Reply via email to