SQL database support

Metadata

Last edited 01/14/11. Matthew O'Meara (mattjomeara@gmail.com).

Overview of Relational Databases

Relational Databases are standard datastructures for persistent management of large quantities of data. Compared with flat file formats, relational databases offer the following advantages:

Database Support In Rosetta

While standard implementations such as SQLite, PostgreSQ, MySQL and Oracle are in many ways quite similar, they each have unique details. To be useful in different contexts, Rosetta uses an abstraction library, cppdb, to present a common interface within the code supporting multiple databases backends.

Why the cppdb library?

When choosing to use cppdb as the database abstraction layer we evaluated several approaches and projects. The general strategy of an abstraction layer is to have backend drivers that each connect with a different library–in this case database engine–and frontend drivers that present an interface for a different programming environment. Effective abstraction layers should simplfy software design by avoiding having to implement interfaces for all combinations of programming environments and libraries.

Usage of Databases

Usage Overview

The general process of using a database involves the following three basic tasks steps:

Session Management

Currently only SQLite3 databases are supported, though if adding more database types will be doable. To establish a session, resquest a session from the DatabaseSessionManager.

#include <utility/sql_database/DatabaseSessionManager.hh>

//...

using utility::sql_database::DatabaseSessionManager;
  using utility::sql_database::sessionOP;

DatabaseSessionManager * dsm = DatatabaseSessionManager::get_instance();
  sessionOP db_session = dsm->get_session(database_filename);

The DatabaseSessionManager is singleton mananaged on non-mpi builds and boost::auto_ptr managed for mpi builds. One thing to note: In order use owning pointers with a session object use the utility::sql_database::session. It derives from both cppdb::session and utility::pointer::ReferenceCount .

Usually your application will want to use the database filename the user specifies in the option system:

-inout:database_filename

by looking it up like this:

#include <basic/options/option.hh>
#include <basic/options/keys/inout.OptionKeys.gen.hh>
  #include <string>

// ...

using namespace basic::options;
using OptionKeys::inout;

  std::string database_filename(option[database_filename].value());

Once a database session has been established. One of the main tasks it to execute statements. For example to create a table:

#include <cppdb/frontend.h> // for 'statement' and 'result' classes

  // ...

  using cppdb::statement;

statement create_table_stmt = (*db_session) <<
      "CREATE TABLE table1 ("
      "   column1 INTEGER PRIMARY KEY,"
      "   value1 TEXT);";
  create_table_stmt.exec();

  statement insert_row_stmt = (*db_session) <<
      "INSERT INTO table1 (null,?)" << "hi";
  insert_row_stmt.exec();

Another main task is to execute queries over a database. For example:

#include <cppdb/frontend.h> // for 'statement' and 'result' classes

  // ...

  using cppdb::statement;

result res = (*db_session) <<
      "SELECT * FROM table1;";
  while(res.next()){
    int col1;
      string val;
    res >> col1 >> val;
      // use col1 and val
  }

For a working expanded example see test/utility/sql_database/DatabaseSessionManagerTests.cxxtest.hh

For more documentation on the cppdb API see the CppDB Online Documentation and external/dbio/cppdb/frontend.h.