Boost logo

Boost :

From: Steve Hutton (shutton_at_[hidden])
Date: 2006-04-16 15:58:03


On 2006-04-15, Reece Dunn <msclrhd_at_[hidden]> wrote:
> Steve Hutton wrote:
>>
>> const int BATCH_SIZE = 30;
>> std::vector<int> valsOut(BATCH_SIZE);
>> Statement st = (sql.prepare << "select value from numbers",
>> into(valsOut));
>> st.execute();
>> while (st.fetch())
>> {
>> std::vector<int>::iterator pos;
>> for(; pos != valsOut.end(); ++pos)
>> {
>> cout << *pos << '\n';
>> }
>> }
>
> How abouit something like:
>
> sql::statement query;
> query << "select value from numbers";
>
> sql::rowset< int > rows(query);
> cout << "found = " << rows.size() << endl;
>
> std::vector< int > values;
> std::copy( rows.begin(), rows.end(), values );
>
> Multi-item row searches could use tuple:
>
> sql::rowset< int, std::wstring, int > rows( query );
> std::tr1::tuple< int, std::wstring, int > value = rows.begin();

The tuple idea is interesting. SOCI supports selecting
into a generic Row object, which can iterated over, or
interrogated by column name:

Session sql("oracle", "service=db1", "user=scott", "password=tiger");
Row r;
sql << "select * from Parts", into(r);

cout << "first column: " << r.get<string>(0);
cout << "column named 'PART_NUMBER': " << r.get<int>("PART_NUMBER");

(Note that you can also interrogate the row to get the names and types
of the columns, e.g. to write generic app that dumps a table to xml)

SOCI extends this further to provide object relational mapping:

struct Part
{
int num;
string description;
};

// define O/R mapping via specialization of SOCI::TypeConversion
template<> struct TypeConversion<Part>
{
        typedef Values base_type;
        static Part from(Values const &v)
        {
                Parts p;
                p.num = v.get<int>("PART_NUMBER");
                p.description = v.get<string>("DESCRIPTION");
        }
        static Values to(Part &p)
        {
                Values v;
                v.set("PART_NUMBER", p.num);
                v.set("DESCRIPTION", pdescription);
        }
};

Part p;
sql << "select * from Parts", into(p);
cout << "got part # " << p.num << "(" << p.description << ")";

So, back to your tuple suggestion - I could see that perhaps
being supported in this fashion:

tuple t<int, string>;
sql << "select * from Parts", into(t);

Your suggestion of the use of a RowSet class is interesting.
SOCI supports selecting to/from vector<int>, vector<string>, etc.
The context in which we added support for these features was to
support high performance bulk operations...the fetch() mechanism
was already in place as the default way to iterate over a rowset.

But we haven't yet added support for vector<Row> or vector<MyType>.
So in these cases there's just the one way to interate over rows
in a result set - the fetch() function.

I was planning on adding support for vector<Row> and vector<MyType>,
as a performance optimization for bulk operations.

But now I can see that having these two means of iterating over
result sets might be a little confusing to users.

Steve


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk