Boost logo

Boost :

From: Nicola Musatti (Nicola.Musatti_at_[hidden])
Date: 2006-10-04 17:39:12


Jeff Garland wrote:
> Nicola Musatti wrote:
>> Hallo,
>> a few months ago there was a discussion on how a database interface library
>> would be a welcome addition to TR2 and the SOCI developers suggested that SOCI
>> could be a valid candidate for that role
>> (http://article.gmane.org/gmane.comp.lib.boost.devel/140816). They also
>> mentioned their intention to make SOCI ready for submission to Boost.
>>
>> Was any progress made on this issue? Is there any interest in reopening the
>> discussion on such a library, SOCI submission notwithstanding?
>
> I'm not sure what there is to discuss. It didn't happen :-( And TR2
> submission time is over. I still want to see SOCI or the equivalent in Boost,
> but the authors have to bring it forward. Last I knew they were waiting to
> have an ODBC driver first. I didn't see the need for that, but they thought
> it was essential...

Missing the TR2 deadline was unfortunate, but probably putting together
a valid proposal deserved more time than was available, even with such
an impressive starting point such as SOCI.

Lately I've been trying to put together a few ideas on how I think such
a library should look like and I'd be happy to discuss them with anybody
who is interested. To get the ball rolling, here is an example of how a
program using my hypothetical Boost.Dbi (for DataBase Interface) library
might look like:

#include <iostream>
#include <ostream>

#include <boost/optional.hpp>
#include <boost/none.hpp>

#include <boost/dbi.hpp>

int main()
{
     try
     {

// Connect to a database, specifying the underlying technology. Unless
// specific SQL syntax is used, this should be the only place where the
// actual DBMS product / technology is evident

         boost::dbi::connection conn("ODBC");
         conn.connect("PVAL", "dba", "sql");

// Execute a couple of simple queries

         boost::dbi::statement st(conn);
         try
         {
             st.exec("drop table t");
             conn.commit();
         }
         catch ( boost::dbi::error & e )
         {
             std::cerr << e.what() << '\n';
         }
         st.exec("create table t ( a int, b varchar(10), c double, "
                "d int )");

// Execute a parameterized query

         long a;
         std::string b;
         boost::optional<double> c; // a value that may be null
         boost::dbi::null_value<long> d; // a value that is always null

         // prepare the statement and bind input parameters, so as to
        // be able to execute it in a loop with different values

         st.prepare("insert into t ( a, b, c, d ) values ( ?, ?, ?, ? )",
                 a, b, c, d);

         char * nums[] = { "zero", "one", "two", "three", "four", "five",
                "six", "seven", "eight", "nine" };
         for ( a = 0; a < 10; ++a )
         {
             b = nums[a];
             if ( a % 2 )
                 c = a * 1.1;
             else
                 c = boost::none;
             st.exec();
         }
         conn.commit();

// Execute a query that returns a result set

         st.exec("select * from t");
         boost::dbi::result_set rs(st);

         // Explore the structure of the result set

         std::cout << "No. of columns: " << rs.column_count() << '\n';
         for ( int i = 0; i < rs.column_count(); ++i )
         {
             std::cout << rs[i].name() << "\t " <<
                    rs[i].type().name() << '(' << rs[i].size() <<
                    ", " << rs[i].precision() << ')';
             if ( rs[i].nullable() )
                 std::cout << "\t null";
             std::cout << '\n';
         }

         // Print the actual results

         std::cout << "\nRows:\n";
         for ( boost::dbi::result_set::iterator i = rs.begin();
                i != rs.end(); ++i )
         {
             boost::dbi::row const & r = *i;

             // Columns may be accessed by position...

             std::cout << r[0].as<long>() << "\t ";

             // ...or by name

             std::cout << r["b"].as<std::string>() << "\t ";
             boost::optional<double> c =
                    r[2].as<boost::optional<double> >();
             if ( ! c )
                 std::cout << "(null)\t ";
             else
                 std::cout << *c << "\t ";
             boost::optional<long> d =
                    r["d"].as<boost::optional<long> >();
             if ( ! d )
                 std::cout << "(null)\n";
             else
                 std::cout << *d << '\n';
         }
         conn.disconnect();
     }
     catch ( boost::dbi::error & e )
     {
         std::cerr << e.what() << '\n';
         std::cout << "Failure!\n";
         return 1;
     }
     std::cout << "Success!\n";
}

Cheers,
Nicola Musatti


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