LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Public Member Functions | Private Types | Private Member Functions | Private Attributes | Friends | List of all members
lsst::daf::persistence::DbStorageImpl Class Reference

Class for implementation of database storage. More...

#include <DbStorageImpl.h>

Inheritance diagram for lsst::daf::persistence::DbStorageImpl:
lsst::daf::base::Citizen

Public Member Functions

virtual ~DbStorageImpl (void)
 
template<>
void setColumn (std::string const &columnName, std::string const &value)
 
template<>
void setColumn (std::string const &columnName, dafBase::DateTime const &value)
 
template<>
void outParam (std::string const &columnName, std::string *location, bool isExpr)
 
template<>
void outParam (std::string const &columnName, dafBase::DateTime *location, bool isExpr)
 
template<>
std::string const & getColumnByPos (int pos)
 
template<>
dafBase::DateTime const & getColumnByPos (int pos)
 
- Public Member Functions inherited from lsst::daf::base::Citizen
 Citizen (const std::type_info &)
 
 Citizen (Citizen const &)
 
 ~Citizen ()
 
Citizenoperator= (Citizen const &)
 
std::string repr () const
 Return a string representation of a Citizen. More...
 
void markPersistent (void)
 Mark a Citizen as persistent and not destroyed until process end. More...
 
memId getId () const
 Return the Citizen's ID. More...
 

Private Types

typedef
std::tr1::unordered_map
< std::string, BoundVar
BoundVarMap
 

Private Member Functions

 DbStorageImpl (void)
 
virtual void setPolicy (pexPolicy::Policy::Ptr policy)
 
virtual void setPersistLocation (LogicalLocation const &location)
 
virtual void setRetrieveLocation (LogicalLocation const &location)
 
virtual void startTransaction (void)
 
virtual void endTransaction (void)
 
virtual void startSession (std::string const &location)
 
virtual void createTableFromTemplate (std::string const &tableName, std::string const &templateName, bool mayAlreadyExist)
 
virtual void dropTable (std::string const &tableName)
 
virtual void truncateTable (std::string const &tableName)
 
virtual void executeSql (std::string const &sqlStatement)
 
virtual void setTableForInsert (std::string const &tableName)
 
template<typename T >
void setColumn (std::string const &columnName, T const &value)
 
virtual void setColumnToNull (std::string const &columnName)
 
virtual void insertRow (void)
 
virtual void setTableForQuery (std::string const &tableName, bool isExpr)
 
virtual void setTableListForQuery (std::vector< std::string > const &tableNameList)
 
virtual void outColumn (std::string const &columnName, bool isExpr)
 
template<typename T >
void outParam (std::string const &columnName, T *location, bool isExpr)
 
template<typename T >
void condParam (std::string const &paramName, T const &value)
 
virtual void orderBy (std::string const &expression)
 
virtual void groupBy (std::string const &expression)
 
virtual void setQueryWhere (std::string const &whereClause)
 
virtual void query (void)
 
virtual bool next (void)
 
template<typename T >
T const & getColumnByPos (int pos)
 
bool columnIsNull (int pos)
 
virtual void finishQuery (void)
 
void executeQuery (std::string const &query)
 
std::string quote (std::string const &name)
 
void stError (std::string const &text)
 
void error (std::string const &text, bool mysqlCaused=true)
 
void * allocateMemory (size_t size)
 

Private Attributes

bool _readonly
 Remember if we are supposed to be read-only. More...
 
std::string _location
 Database location string saved for use by raw MySQL interface. More...
 
MYSQL * _db
 MySQL database connection pointer. More...
 
std::string _insertTable
 Name of table into which to insert. More...
 
std::vector< std::string > _queryTables
 Names of tables to select from. More...
 
BoundVarMap _inputVars
 Input variable bindings. More...
 
BoundVarMap _outputVars
 Output variable bindings. More...
 
std::vector
< boost::shared_array< char > > 
_bindingMemory
 Memory for bound variables. More...
 
std::vector< std::string > _outColumns
 
std::string _whereClause
 
std::string _groupBy
 
std::string _orderBy
 
MYSQL_STMT * _statement
 Prepared query statement. More...
 
MYSQL_FIELD * _resultFields
 Query result field metadata. More...
 
int _numResultFields
 Number of result fields. More...
 
boost::shared_array< unsigned
long > 
_fieldLengths
 Space for lengths of result fields. More...
 
boost::shared_array< my_bool > _fieldNulls
 Space for null flags of result fields. More...
 

Friends

class DbStorage
 

Additional Inherited Members

- Public Types inherited from lsst::daf::base::Citizen
enum  { magicSentinel = 0xdeadbeef }
 
typedef unsigned long memId
 Type of the block's ID. More...
 
typedef memId(* memNewCallback )(const memId cid)
 A function used to register a callback. More...
 
typedef memId(* memCallback )(const Citizen *ptr)
 
- Static Public Member Functions inherited from lsst::daf::base::Citizen
static bool hasBeenCorrupted ()
 Check all allocated blocks for corruption. More...
 
static memId getNextMemId ()
 Return the memId of the next object to be allocated. More...
 
static int init ()
 Called once when the memory system is being initialised. More...
 
static int census (int, memId startingMemId=0)
 How many active Citizens are there? More...
 
static void census (std::ostream &stream, memId startingMemId=0)
 Print a list of all active Citizens to stream, sorted by ID. More...
 
static const std::vector
< const Citizen * > * 
census ()
 Return a (newly allocated) std::vector of active Citizens sorted by ID. More...
 
static memId setNewCallbackId (memId id)
 Call the NewCallback when block is allocated. More...
 
static memId setDeleteCallbackId (memId id)
 Call the current DeleteCallback when block is deleted. More...
 
static memNewCallback setNewCallback (memNewCallback func)
 Set the NewCallback function. More...
 
static memCallback setDeleteCallback (memCallback func)
 Set the DeleteCallback function. More...
 
static memCallback setCorruptionCallback (memCallback func)
 Set the CorruptionCallback function. More...
 

Detailed Description

Class for implementation of database storage.

Use via DbStorage class only.

Definition at line 79 of file DbStorageImpl.h.

Member Typedef Documentation

typedef std::tr1::unordered_map<std::string, BoundVar> lsst::daf::persistence::DbStorageImpl::BoundVarMap
private

Definition at line 149 of file DbStorageImpl.h.

Constructor & Destructor Documentation

lsst::daf::persistence::DbStorageImpl::~DbStorageImpl ( void  )
virtual

Destructor. End session if present.

Definition at line 168 of file DbStorageImpl.cc.

168  {
169  if (_db) {
170  mysql_close(_db);
171  _db = 0;
172  }
173 }
MYSQL * _db
MySQL database connection pointer.
lsst::daf::persistence::DbStorageImpl::DbStorageImpl ( void  )
private

Default constructor.

Definition at line 161 of file DbStorageImpl.cc.

161  :
162  lsst::daf::base::Citizen(typeid(*this)), _db(0) {
163 }
MYSQL * _db
MySQL database connection pointer.
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...
Definition: Citizen.h:56

Member Function Documentation

void * lsst::daf::persistence::DbStorageImpl::allocateMemory ( size_t  size)
private

Definition at line 283 of file DbStorageImpl.cc.

283  {
284  boost::shared_array<char> mem(new char[size]);
285  _bindingMemory.push_back(mem);
286  return mem.get();
287 }
std::vector< boost::shared_array< char > > _bindingMemory
Memory for bound variables.
bool lsst::daf::persistence::DbStorageImpl::columnIsNull ( int  pos)
private

Determine if the value of a column is NULL.

Parameters
[in]posPosition of the column (starts at 0)
Returns
true if value is NULL

Definition at line 979 of file DbStorageImpl.cc.

979  {
980  if (pos > _numResultFields) {
981  std::ostringstream os;
982  os << "Nonexistent column: " << pos;
983  error(os.str(), false);
984  }
985  return _fieldNulls[pos];
986 }
int _numResultFields
Number of result fields.
void error(std::string const &text, bool mysqlCaused=true)
boost::shared_array< my_bool > _fieldNulls
Space for null flags of result fields.
template<typename T >
void lsst::daf::persistence::DbStorageImpl::condParam ( std::string const &  paramName,
T const &  value 
)
private

Bind a value to a WHERE condition parameter.

Parameters
[in]paramNameName of the parameter (prefixed by ":" in the WHERE clause)
[in]valueValue to be bound to the parameter.

Definition at line 627 of file DbStorageImpl.cc.

627  {
628  setColumn<T>(paramName, value);
629 }
void lsst::daf::persistence::DbStorageImpl::createTableFromTemplate ( std::string const &  tableName,
std::string const &  templateName,
bool  mayAlreadyExist 
)
privatevirtual

Create a new table from an existing template table.

Parameters
[in]tableNameName of the new table
[in]templateNameName of the existing template table
[in]mayAlreadyExistFalse (default) if the table must not be present

Definition at line 298 of file DbStorageImpl.cc.

300  {
301  std::string query = "CREATE TABLE ";
302  if (mayAlreadyExist) query += "IF NOT EXISTS ";
303  query += quote(tableName) + " LIKE " + quote(templateName);
304  executeQuery(query);
305 }
std::string quote(std::string const &name)
void executeQuery(std::string const &query)
void lsst::daf::persistence::DbStorageImpl::dropTable ( std::string const &  tableName)
privatevirtual

Drop a table.

Parameters
[in]tableNameName of the table to drop

Definition at line 310 of file DbStorageImpl.cc.

310  {
311  executeQuery("DROP TABLE " + quote(tableName));
312 }
std::string quote(std::string const &name)
void executeQuery(std::string const &query)
void lsst::daf::persistence::DbStorageImpl::endTransaction ( void  )
privatevirtual

End a transaction.

Definition at line 237 of file DbStorageImpl.cc.

237  {
238  if (_db == 0) error("Database session not initialized "
239  "in DbStorage::endTransaction()", false);
240  if (mysql_commit(_db)) error("Unable to commit transaction");
241  if (mysql_autocommit(_db, true)) error("Unable to turn on autocommit");
242 }
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
void lsst::daf::persistence::DbStorageImpl::error ( std::string const &  text,
bool  mysqlCaused = true 
)
private

Definition at line 274 of file DbStorageImpl.cc.

274  {
275  if (mysqlCause) {
276  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, text + " - * " + mysql_error(_db));
277  }
278  else {
279  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, text);
280  }
281 }
MYSQL * _db
MySQL database connection pointer.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
void lsst::daf::persistence::DbStorageImpl::executeQuery ( std::string const &  query)
private

Execute a query string.

Definition at line 250 of file DbStorageImpl.cc.

250  {
251  if (_db == 0) {
252  error("No DB connection for query: " + query, false);
253  }
254  lsst::pex::logging::TTrace<5>("daf.persistence.DbStorage",
255  "Query: " + query);
256  if (mysql_query(_db, query.c_str()) != 0) {
257  error("Unable to execute query: " + query);
258  }
259 }
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
void lsst::daf::persistence::DbStorageImpl::executeSql ( std::string const &  sqlStatement)
privatevirtual

Execute an arbitrary SQL statement. Use primarily to perform server-side computations or complex DDL.

Parameters
[in]sqlStatementSQL statement to be executed. Must not end in ";".

Definition at line 325 of file DbStorageImpl.cc.

325  {
326  executeQuery(sqlStatement);
327 }
void executeQuery(std::string const &query)
void lsst::daf::persistence::DbStorageImpl::finishQuery ( void  )
privatevirtual

Indicate that query processing is finished.

Definition at line 990 of file DbStorageImpl.cc.

990  {
991  mysql_stmt_close(_statement);
992  _statement = 0;
993 }
MYSQL_STMT * _statement
Prepared query statement.
template<typename T >
T const & lsst::daf::persistence::DbStorageImpl::getColumnByPos ( int  pos)
private

Get the value of a column of the query result row by position.

Parameters
[in]posPosition of the column (starts at 0)
Returns
Reference to the value of the column

Definition at line 890 of file DbStorageImpl.cc.

890  {
891  if (pos > _numResultFields) {
892  std::ostringstream os;
893  os << "Nonexistent column: " << pos;
894  error(os.str(), false);
895  }
896  MYSQL_BIND bind;
897  memset(&bind, 0, sizeof(MYSQL_BIND));
898  static T t;
899  bind.buffer_type = BoundVarTraits<T>::mysqlType;
900  bind.is_unsigned = BoundVarTraits<T>::isUnsigned;
901  bind.buffer = &t;
902  bind.buffer_length = sizeof(T);
903  bind.length = &(_fieldLengths[pos]);
904  bind.is_null = &(_fieldNulls[pos]);
905  if (mysql_stmt_fetch_column(_statement, &bind, pos, 0)) {
906  std::ostringstream os;
907  os << "Error fetching column: " << pos;
908  error(os.str(), false);
909  }
910  return t;
911 }
boost::shared_array< unsigned long > _fieldLengths
Space for lengths of result fields.
int _numResultFields
Number of result fields.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
boost::shared_array< my_bool > _fieldNulls
Space for null flags of result fields.
template<>
std::string const& lsst::daf::persistence::DbStorageImpl::getColumnByPos ( int  pos)

Definition at line 914 of file DbStorageImpl.cc.

914  {
915  if (pos > _numResultFields) {
916  std::ostringstream os;
917  os << "Nonexistent column: " << pos;
918  error(os.str(), false);
919  }
920  MYSQL_BIND bind;
921  memset(&bind, 0, sizeof(MYSQL_BIND));
922  if (_resultFields[pos].type == MYSQL_TYPE_BIT) {
923  error("Invalid type for string retrieval", false);
924  }
925  boost::scoped_array<char> t(new char[_fieldLengths[pos]]);
926  bind.buffer_type = BoundVarTraits<std::string>::mysqlType;
927  bind.is_unsigned = BoundVarTraits<std::string>::isUnsigned;
928  bind.buffer = t.get();
929  bind.buffer_length = _fieldLengths[pos];
930  bind.length = &(_fieldLengths[pos]);
931  bind.is_null = &(_fieldNulls[pos]);
932  if (mysql_stmt_fetch_column(_statement, &bind, pos, 0)) {
933  std::ostringstream os;
934  os << "Error fetching string column: " << pos;
935  stError(os.str());
936  }
937  static std::string s;
938  s = std::string(t.get(), _fieldLengths[pos]);
939  return s;
940 }
boost::shared_array< unsigned long > _fieldLengths
Space for lengths of result fields.
int _numResultFields
Number of result fields.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
boost::shared_array< my_bool > _fieldNulls
Space for null flags of result fields.
MYSQL_FIELD * _resultFields
Query result field metadata.
void stError(std::string const &text)
template<>
dafBase::DateTime const& lsst::daf::persistence::DbStorageImpl::getColumnByPos ( int  pos)

Definition at line 943 of file DbStorageImpl.cc.

943  {
944  if (pos > _numResultFields) {
945  std::ostringstream os;
946  os << "Nonexistent column: " << pos;
947  error(os.str(), false);
948  }
949  MYSQL_BIND bind;
950  memset(&bind, 0, sizeof(MYSQL_BIND));
951  if (_resultFields[pos].type != MYSQL_TYPE_TIME &&
952  _resultFields[pos].type != MYSQL_TYPE_DATE &&
953  _resultFields[pos].type != MYSQL_TYPE_DATETIME &&
954  _resultFields[pos].type != MYSQL_TYPE_TIMESTAMP) {
955  error("Invalid type for DateTime retrieval", false);
956  }
957  static MYSQL_TIME t;
958  bind.buffer_type = BoundVarTraits<dafBase::DateTime>::mysqlType;
959  bind.is_unsigned = BoundVarTraits<dafBase::DateTime>::isUnsigned;
960  bind.buffer = &t;
961  bind.buffer_length = sizeof(MYSQL_TIME);
962  bind.length = &(_fieldLengths[pos]);
963  bind.is_null = &(_fieldNulls[pos]);
964  if (mysql_stmt_fetch_column(_statement, &bind, pos, 0)) {
965  std::ostringstream os;
966  os << "Error fetching DateTime column: " << pos;
967  stError(os.str());
968  }
969  static dafBase::DateTime v;
970  v = dafBase::DateTime(t.year, t.month, t.day, t.hour, t.minute, t.second,
972  return v;
973 }
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:58
boost::shared_array< unsigned long > _fieldLengths
Space for lengths of result fields.
int _numResultFields
Number of result fields.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
boost::shared_array< my_bool > _fieldNulls
Space for null flags of result fields.
MYSQL_FIELD * _resultFields
Query result field metadata.
void stError(std::string const &text)
void lsst::daf::persistence::DbStorageImpl::groupBy ( std::string const &  expression)
privatevirtual

Request that the query output be grouped by an expression.

Parameters
[in]expressionText of the SQL expression

Definition at line 645 of file DbStorageImpl.cc.

645  {
646  if (!_groupBy.empty()) {
647  _groupBy += ", ";
648  }
649  _groupBy += expression;
650 }
void lsst::daf::persistence::DbStorageImpl::insertRow ( void  )
privatevirtual

Insert the row. Row values must have been set with setColumn() calls.

Definition at line 435 of file DbStorageImpl.cc.

435  {
436  if (_readonly) {
437  error("Attempt to insert into read-only database", false);
438  }
439  if (_insertTable.empty()) error("Insert table not initialized in DbStorage::insertRow()", false);
440  if (_inputVars.empty()) error("No values to insert", false);
441 
442  std::string query = "INSERT INTO " + quote(_insertTable) + " (";
443 
444  boost::scoped_array<MYSQL_BIND> binder(new MYSQL_BIND[_inputVars.size()]);
445  memset(binder.get(), 0, _inputVars.size() * sizeof(MYSQL_BIND));
446 
447  int i = 0;
448  for (BoundVarMap::iterator it = _inputVars.begin();
449  it != _inputVars.end(); ++it) {
450  if (it != _inputVars.begin()) {
451  query += ", ";
452  }
453  query += quote(it->first);
454 
455  // Bind variables
456  MYSQL_BIND& bind(binder[i]);
457  BoundVar& bv(it->second);
458  if (bv._isNull) {
459  bind.buffer_type = MYSQL_TYPE_NULL;
460  }
461  else {
462  bind.buffer_type = bv._type;
463  bind.buffer = bv._data;
464  bind.buffer_length = bv._length;
465  bind.length = &(bv._length);
466  bind.is_null = 0;
467  bind.is_unsigned = bv._isUnsigned;
468  bind.error = 0;
469  }
470  ++i;
471  }
472  query += ") VALUES (";
473  for (size_t i = 0; i < _inputVars.size(); ++i) {
474  if (i != 0) {
475  query += ", ";
476  }
477  query += "?";
478  }
479  query += ")";
480 
481  // Execute statement
482  // Guard statement with mysql_stmt_close()
483  _statement = mysql_stmt_init(_db);
484  if (_statement == 0) {
485  error("Unable to initialize statement: " + query);
486  }
487  if (mysql_stmt_prepare(_statement, query.c_str(), query.length()) != 0) {
488  stError("Unable to prepare statement: " + query);
489  }
490  if (mysql_stmt_bind_param(_statement, binder.get())) {
491  stError("Unable to bind variables in: " + query);
492  }
493  if (mysql_stmt_execute(_statement) != 0) {
494  stError("Unable to execute statement: " + query);
495  }
496  mysql_stmt_close(_statement);
497  _statement = 0;
498 }
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
std::string quote(std::string const &name)
void stError(std::string const &text)
BoundVarMap _inputVars
Input variable bindings.
bool _readonly
Remember if we are supposed to be read-only.
std::string _insertTable
Name of table into which to insert.
bool lsst::daf::persistence::DbStorageImpl::next ( void  )
privatevirtual

Move to the next (first) row of the query result.

Returns
false if no more rows

Definition at line 845 of file DbStorageImpl.cc.

845  {
846  if (_statement == 0) {
847  error("Statement not initialized in DbStorage::next()", false);
848  }
849  int ret = mysql_stmt_fetch(_statement);
850  if (ret == 0) {
851  // Fix up strings and DateTimes
852  if (!_outputVars.empty()) {
853  for (size_t i = 0; i < _outColumns.size(); ++i) {
854  BoundVarMap::iterator bvit = _outputVars.find(_outColumns[i]);
855  if (bvit == _outputVars.end()) {
856  error("Unbound variable in SELECT clause: " +
857  _outColumns[i], false);
858  }
859  BoundVar& bv = bvit->second;
860  if (bv._type == BoundVarTraits<std::string>::mysqlType) {
861  **reinterpret_cast<std::string**>(bv._data) =
862  std::string(reinterpret_cast<char*>(bv._data) +
863  sizeof(std::string*), _fieldLengths[i]);
864  }
865  else if (bv._type ==
866  BoundVarTraits<dafBase::DateTime>::mysqlType) {
867  char* cp = reinterpret_cast<char*>(bv._data) +
868  sizeof(dafBase::DateTime*);
869  MYSQL_TIME* t = reinterpret_cast<MYSQL_TIME*>(cp);
870  **reinterpret_cast<dafBase::DateTime**>(bv._data) =
871  dafBase::DateTime(t->year, t->month, t->day,
872  t->hour, t->minute, t->second,
874  }
875  }
876  }
877  return true;
878  }
879  if (ret == MYSQL_NO_DATA) return false;
880  if (ret == MYSQL_DATA_TRUNCATED && _outputVars.empty()) return true;
881  stError("Error fetching next row");
882  return false;
883 }
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:58
boost::shared_array< unsigned long > _fieldLengths
Space for lengths of result fields.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
void stError(std::string const &text)
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
void lsst::daf::persistence::DbStorageImpl::orderBy ( std::string const &  expression)
privatevirtual

Request that the query output be sorted by an expression. Multiple expressions may be specified, in order.

Parameters
[in]expressionText of the SQL expression

Definition at line 635 of file DbStorageImpl.cc.

635  {
636  if (!_orderBy.empty()) {
637  _orderBy += ", ";
638  }
639  _orderBy += expression;
640 }
void lsst::daf::persistence::DbStorageImpl::outColumn ( std::string const &  columnName,
bool  isExpr 
)
privatevirtual

Request a column in the query output.

Parameters
[in]columnNameName of the column
[in]isExprTrue if the name is actually an expression

The order of outColumn() calls is the order of appearance in the output row. Use either outColumn() or outParam() but not both.

Definition at line 548 of file DbStorageImpl.cc.

549  {
550  std::string col = isExpr ? columnName : quote(columnName);
551  _outColumns.push_back(col);
552 }
std::string quote(std::string const &name)
std::vector< std::string > _outColumns
int col
Definition: CR.cc:152
template<typename T >
void lsst::daf::persistence::DbStorageImpl::outParam ( std::string const &  columnName,
T *  location,
bool  isExpr 
)
private

Request a column in the query output and bind a destination location.

Parameters
[in]columnNameName of the column
[in]locationPointer to the destination
[in]isExprTrue if the name is actually an expression

The order of outParam() calls is the order of appearance in the output row. Use either outColumn() or outParam() but not both.

Definition at line 563 of file DbStorageImpl.cc.

564  {
565  std::string col = isExpr ? columnName : quote(columnName);
566  _outColumns.push_back(col);
567  size_t size = sizeof(T);
568  std::pair<BoundVarMap::iterator, bool> pair = _outputVars.insert(
569  BoundVarMap::value_type(col, BoundVar(location)));
570  if (!pair.second) {
571  error("Duplicate column name requested: " + columnName, false);
572  }
573  BoundVar& bv = pair.first->second;
574  bv._type = BoundVarTraits<T>::mysqlType;
575  bv._isNull = false;
576  bv._isUnsigned = BoundVarTraits<T>::isUnsigned;
577  bv._length = size;
578 }
void error(std::string const &text, bool mysqlCaused=true)
std::string quote(std::string const &name)
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
int col
Definition: CR.cc:152
template<>
void lsst::daf::persistence::DbStorageImpl::outParam ( std::string const &  columnName,
std::string *  location,
bool  isExpr 
)

Definition at line 581 of file DbStorageImpl.cc.

582  {
583  std::string col = isExpr ? columnName : quote(columnName);
584  _outColumns.push_back(col);
585  size_t size = 4096;
586  std::pair<BoundVarMap::iterator, bool> pair = _outputVars.insert(
587  BoundVarMap::value_type(
588  col, BoundVar(allocateMemory(size + sizeof(std::string*)))));
589  if (!pair.second) {
590  error("Duplicate column name requested: " + columnName, false);
591  }
592  BoundVar& bv = pair.first->second;
593  *reinterpret_cast<std::string**>(bv._data) = location;
594  bv._type = BoundVarTraits<std::string>::mysqlType;
595  bv._isNull = false;
596  bv._isUnsigned = BoundVarTraits<std::string>::isUnsigned;
597  bv._length = size;
598 }
void error(std::string const &text, bool mysqlCaused=true)
std::string quote(std::string const &name)
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
int col
Definition: CR.cc:152
template<>
void lsst::daf::persistence::DbStorageImpl::outParam ( std::string const &  columnName,
dafBase::DateTime location,
bool  isExpr 
)

Definition at line 601 of file DbStorageImpl.cc.

603  {
604  std::string col = isExpr ? columnName : quote(columnName);
605  _outColumns.push_back(col);
606  size_t size = sizeof(MYSQL_TIME);
607  std::pair<BoundVarMap::iterator, bool> pair = _outputVars.insert(
608  BoundVarMap::value_type(
609  col, BoundVar(allocateMemory(size + sizeof(dafBase::DateTime*)))));
610  if (!pair.second) {
611  error("Duplicate column name requested: " + columnName, false);
612  }
613  BoundVar& bv = pair.first->second;
614  *reinterpret_cast<dafBase::DateTime**>(bv._data) = location;
615  bv._type = BoundVarTraits<dafBase::DateTime>::mysqlType;
616  bv._isNull = false;
617  bv._isUnsigned = BoundVarTraits<dafBase::DateTime>::isUnsigned;
618  bv._length = size;
619 }
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:58
void error(std::string const &text, bool mysqlCaused=true)
std::string quote(std::string const &name)
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
int col
Definition: CR.cc:152
void lsst::daf::persistence::DbStorageImpl::query ( void  )
privatevirtual

Execute the query.

Definition at line 663 of file DbStorageImpl.cc.

663  {
664  if (_outColumns.empty()) error("No output columns for query", false);
665 
666  // SELECT outVars FROM queryTables WHERE whereClause GROUP BY groupBy
667  // ORDER BY orderBy
668 
669  // SELECT clause
670  std::string query = "SELECT ";
671  for (std::vector<std::string>::const_iterator it = _outColumns.begin();
672  it != _outColumns.end(); ++it) {
673  if (it != _outColumns.begin()) {
674  query += ", ";
675  }
676  query += *it;
677  }
678 
679  // FROM clause
680  query += " FROM ";
681  for (std::vector<std::string>::const_iterator it = _queryTables.begin();
682  it != _queryTables.end(); ++it) {
683  if (it != _queryTables.begin()) {
684  query += ", ";
685  }
686  query += *it;
687  }
688 
689  // WHERE clause
690  std::vector<std::string> whereBindings;
691  if (!_whereClause.empty()) {
692  boost::regex re(":([A-Za-z_]+)");
693  std::string result;
694  std::back_insert_iterator<std::string> out(result);
695  boost::regex_iterator<std::string::iterator> m;
696  for (boost::regex_iterator<std::string::iterator> i(
697  _whereClause.begin(), _whereClause.end(), re);
698  i != boost::regex_iterator<std::string::iterator>(); ++i) {
699  m = i;
700  std::copy(m->prefix().first, m->prefix().second, out);
701  *out++ = '?';
702  assert(m->size() == 2);
703  whereBindings.push_back(m->str(1));
704  }
705  if (m != boost::regex_iterator<std::string::iterator>()) {
706  std::copy(m->suffix().first, m->suffix().second, out);
707  }
708  else {
709  std::copy(_whereClause.begin(), _whereClause.end(), out);
710  }
711  query += " WHERE " + result;
712  }
713 
714  // GROUP BY clause
715  if (!_groupBy.empty()) query += " GROUP BY " + _groupBy;
716 
717  // ORDER BY clause
718  if (!_orderBy.empty()) query += " ORDER BY " + _orderBy;
719 
720 
721  // Create bindings for input WHERE clause variables, if any
722 
723  boost::scoped_array<MYSQL_BIND> inBinder(
724  new MYSQL_BIND[whereBindings.size()]);
725  memset(inBinder.get(), 0, whereBindings.size() * sizeof(MYSQL_BIND));
726  for (size_t i = 0; i < whereBindings.size(); ++i) {
727  MYSQL_BIND& bind(inBinder[i]);
728  BoundVarMap::iterator it = _inputVars.find(whereBindings[i]);
729  if (it == _inputVars.end()) {
730  error("Unbound variable in WHERE clause: " + whereBindings[i],
731  false);
732  }
733  BoundVar& bv = it->second;
734  bind.buffer_type = bv._type;
735  bind.buffer = bv._data;
736  bind.buffer_length = bv._length;
737  bind.is_null = 0;
738  bind.is_unsigned = bv._isUnsigned;
739  bind.error = 0;
740  }
741 
742 
743  // Initialize and prepare statement
744 
745  _statement = mysql_stmt_init(_db);
746  if (!_statement) {
747  error("Unable to initialize prepared statement");
748  }
749 
750  if (mysql_stmt_prepare(_statement, query.c_str(), query.length()) != 0) {
751  stError("Unable to prepare statement: " + query);
752  }
753 
754 
755  // Check number of input parameters and bind them
756  unsigned int params = mysql_stmt_param_count(_statement);
757  if (_whereClause.empty()) {
758  if (params != 0) {
759  error("Unbound WHERE clause parameters: " + query, false);
760  }
761  }
762  else {
763  if (params != whereBindings.size()) {
764  error("Mismatch in number of WHERE clause parameters: " + query,
765  false);
766  }
767  if (mysql_stmt_bind_param(_statement, inBinder.get())) {
768  stError("Unable to bind WHERE parameters: " + query);
769  }
770  }
771 
772  // Check number of result columns
773  MYSQL_RES* queryMetadata = mysql_stmt_result_metadata(_statement);
774  if (!queryMetadata) {
775  stError("No query metadata: " + query);
776  }
777  _numResultFields = mysql_num_fields(queryMetadata);
778  if (static_cast<unsigned int>(_numResultFields) != _outColumns.size()) {
779  error("Mismatch in number of SELECT items: " + query, false);
780  }
781 
782 
783  // Execute query
784 
785  if (mysql_stmt_execute(_statement) != 0) {
786  stError("MySQL query failed: " + query);
787  }
788 
789 
790  // Create bindings for output variables
791 
792  _resultFields = mysql_fetch_fields(queryMetadata);
793 
794  boost::scoped_array<MYSQL_BIND> outBinder(new MYSQL_BIND[_numResultFields]);
795  memset(outBinder.get(), 0, _numResultFields * sizeof(MYSQL_BIND));
796  _fieldLengths.reset(new unsigned long[_numResultFields]);
797  _fieldNulls.reset(new my_bool[_numResultFields]);
798 
799  for (int i = 0; i < _numResultFields; ++i) {
800  MYSQL_BIND& bind(outBinder[i]);
801  if (_outputVars.empty()) {
802  bind.buffer_type = MYSQL_TYPE_STRING;
803  bind.buffer = 0;
804  bind.buffer_length = 0;
805  bind.length = &(_fieldLengths[i]);
806  bind.is_null = &(_fieldNulls[i]);
807  bind.is_unsigned = (_resultFields[i].flags & UNSIGNED_FLAG) != 0;
808  bind.error = 0;
809  }
810  else {
811  BoundVarMap::iterator it = _outputVars.find(_outColumns[i]);
812  if (it == _outputVars.end()) {
813  error("Unbound variable in SELECT clause: " + _outColumns[i],
814  false);
815  }
816  BoundVar& bv = it->second;
817 
818  bind.buffer_type = bv._type;
819  if (bv._type == BoundVarTraits<std::string>::mysqlType) {
820  bind.buffer = reinterpret_cast<char*>(bv._data) +
821  sizeof(std::string*);
822  }
823  else if (bv._type == BoundVarTraits<dafBase::DateTime>::mysqlType) {
824  bind.buffer = reinterpret_cast<char*>(bv._data) +
825  sizeof(std::string*);
826  }
827  else {
828  bind.buffer = bv._data;
829  }
830  bind.buffer_length = bv._length;
831  bind.length = &(_fieldLengths[i]);
832  bind.is_null = &(_fieldNulls[i]);
833  bind.is_unsigned = bv._isUnsigned;
834  bind.error = 0;
835  }
836  }
837  if (mysql_stmt_bind_result(_statement, outBinder.get())) {
838  stError("Unable to bind results: " + query);
839  }
840 }
std::vector< std::string > _queryTables
Names of tables to select from.
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
Definition: eigen.h:390
boost::shared_array< unsigned long > _fieldLengths
Space for lengths of result fields.
int _numResultFields
Number of result fields.
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
boost::shared_array< my_bool > _fieldNulls
Space for null flags of result fields.
MYSQL_FIELD * _resultFields
Query result field metadata.
tuple m
Definition: lsstimport.py:48
void stError(std::string const &text)
BoundVarMap _inputVars
Input variable bindings.
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
std::string lsst::daf::persistence::DbStorageImpl::quote ( std::string const &  name)
private

Quote a name in ANSI-standard fashion.

Definition at line 263 of file DbStorageImpl.cc.

263  {
264  std::string::size_type pos = name.find('.');
265  if (pos == std::string::npos) return '`' + name + '`';
266  return '`' + std::string(name, 0, pos) + "`.`" +
267  std::string(name, pos + 1) + '`';
268 }
table::Key< std::string > name
Definition: ApCorrMap.cc:71
template<typename T >
void lsst::daf::persistence::DbStorageImpl::setColumn ( std::string const &  columnName,
T const &  value 
)
private

Set the value to insert in a given column.

Parameters
[in]columnNameName of the column
[in]valueValue to set in the column

Definition at line 349 of file DbStorageImpl.cc.

350  {
351  BoundVarMap::iterator bv = _inputVars.find(columnName);
352  size_t size = sizeof(T);
353  if (bv == _inputVars.end()) {
354  bv = _inputVars.insert(
355  BoundVarMap::value_type(columnName,
356  BoundVar(allocateMemory(size)))).first;
357  }
358  else if (bv->second._length != size) {
359  bv->second._data = allocateMemory(size);
360  }
361  bv->second._type = BoundVarTraits<T>::mysqlType;
362  bv->second._isNull = false;
363  bv->second._isUnsigned = BoundVarTraits<T>::isUnsigned;
364  bv->second._length = size;
365  memcpy(bv->second._data, &value, size);
366 }
BoundVarMap _inputVars
Input variable bindings.
template<>
void lsst::daf::persistence::DbStorageImpl::setColumn ( std::string const &  columnName,
std::string const &  value 
)

Definition at line 369 of file DbStorageImpl.cc.

370  {
371  BoundVarMap::iterator bv = _inputVars.find(columnName);
372  size_t size = value.length();
373  if (bv == _inputVars.end()) {
374  bv = _inputVars.insert(
375  BoundVarMap::value_type(columnName,
376  BoundVar(allocateMemory(size)))).first;
377  }
378  else if (bv->second._length != size) {
379  bv->second._data = allocateMemory(size);
380  }
381  bv->second._type = BoundVarTraits<std::string>::mysqlType;
382  bv->second._isNull = false;
383  bv->second._isUnsigned = BoundVarTraits<std::string>::isUnsigned;
384  bv->second._length = size;
385  memcpy(bv->second._data, value.data(), size);
386 }
BoundVarMap _inputVars
Input variable bindings.
template<>
void lsst::daf::persistence::DbStorageImpl::setColumn ( std::string const &  columnName,
dafBase::DateTime const &  value 
)

Definition at line 389 of file DbStorageImpl.cc.

390  {
391  BoundVarMap::iterator bv = _inputVars.find(columnName);
392  size_t size = sizeof(MYSQL_TIME);
393  if (bv == _inputVars.end()) {
394  bv = _inputVars.insert(
395  BoundVarMap::value_type(columnName,
396  BoundVar(allocateMemory(size)))).first;
397  }
398  else if (bv->second._length != size) {
399  bv->second._data = allocateMemory(size);
400  }
401  bv->second._type = BoundVarTraits<dafBase::DateTime>::mysqlType;
402  bv->second._isNull = false;
403  bv->second._isUnsigned = BoundVarTraits<dafBase::DateTime>::isUnsigned;
404  bv->second._length = size;
405  struct tm v = value.gmtime();
406  MYSQL_TIME* t = reinterpret_cast<MYSQL_TIME*>(bv->second._data);
407  t->year = v.tm_year + 1900;
408  t->month = v.tm_mon + 1;
409  t->day = v.tm_mday;
410  t->hour = v.tm_hour;
411  t->minute = v.tm_min;
412  t->second = v.tm_sec;
413  t->neg = false;
414  t->second_part =
415  static_cast<unsigned long>((value.nsecs() % 1000000000LL) / 1000);
416 }
BoundVarMap _inputVars
Input variable bindings.
void lsst::daf::persistence::DbStorageImpl::setColumnToNull ( std::string const &  columnName)
privatevirtual

Set a given column to NULL.

Parameters
[in]columnNameName of the column

Definition at line 421 of file DbStorageImpl.cc.

421  {
422  BoundVarMap::iterator bv = _inputVars.find(columnName);
423  if (bv == _inputVars.end()) {
424  bv = _inputVars.insert(
425  BoundVarMap::value_type(columnName,
426  BoundVar(allocateMemory(1)))).first;
427  }
428  bv->second._isNull = true;
429  bv->second._length = 1;
430 }
BoundVarMap _inputVars
Input variable bindings.
void lsst::daf::persistence::DbStorageImpl::setPersistLocation ( LogicalLocation const &  location)
privatevirtual

Set the database location to persist to.

Parameters
[in]locationDatabase connection string to insert into

Definition at line 214 of file DbStorageImpl.cc.

214  {
215  startSession(location.locString());
216  _readonly = false;
217 }
virtual void startSession(std::string const &location)
bool _readonly
Remember if we are supposed to be read-only.
void lsst::daf::persistence::DbStorageImpl::setPolicy ( pexPolicy::Policy::Ptr  policy)
privatevirtual

Allow a Policy to be used to configure the DbStorage.

Parameters
[in]policy

Definition at line 178 of file DbStorageImpl.cc.

178  {
179 }
void lsst::daf::persistence::DbStorageImpl::setQueryWhere ( std::string const &  whereClause)
privatevirtual

Set the condition for the WHERE clause of the query.

Parameters
[in]whereClauseSQL text of the WHERE clause

May include join conditions.

Definition at line 657 of file DbStorageImpl.cc.

657  {
658  _whereClause = whereClause;
659 }
void lsst::daf::persistence::DbStorageImpl::setRetrieveLocation ( LogicalLocation const &  location)
privatevirtual

Set the database location to retrieve from.

Parameters
[in]locationDatabase connection string to query

Definition at line 222 of file DbStorageImpl.cc.

222  {
223  startSession(location.locString());
224  _readonly = true;
225 }
virtual void startSession(std::string const &location)
bool _readonly
Remember if we are supposed to be read-only.
void lsst::daf::persistence::DbStorageImpl::setTableForInsert ( std::string const &  tableName)
privatevirtual

Set the table to insert rows into.

Parameters
[in]tableNameName of the table

Definition at line 336 of file DbStorageImpl.cc.

336  {
337  if (_readonly) {
338  error("Attempt to insert into read-only database", false);
339  }
340  _insertTable = tableName;
341  _inputVars.clear();
342 }
void error(std::string const &text, bool mysqlCaused=true)
BoundVarMap _inputVars
Input variable bindings.
bool _readonly
Remember if we are supposed to be read-only.
std::string _insertTable
Name of table into which to insert.
void lsst::daf::persistence::DbStorageImpl::setTableForQuery ( std::string const &  tableName,
bool  isExpr 
)
privatevirtual

Set the table to query (single-table queries only).

Parameters
[in]tableNameName of the table
[in]isExprTrue if the name is actually a table expression

Definition at line 508 of file DbStorageImpl.cc.

509  {
510  if (_db == 0) error("Database session not initialized in DbStorage::setTableForQuery()", false);
511  _queryTables.clear();
512  _queryTables.push_back(isExpr ? tableName : quote(tableName));
513  _inputVars.clear();
514  _outputVars.clear();
515  _outColumns.clear();
516  _whereClause.clear();
517  _groupBy.clear();
518  _orderBy.clear();
519  _statement = 0;
520 }
std::vector< std::string > _queryTables
Names of tables to select from.
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
std::string quote(std::string const &name)
BoundVarMap _inputVars
Input variable bindings.
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
void lsst::daf::persistence::DbStorageImpl::setTableListForQuery ( std::vector< std::string > const &  tableNameList)
privatevirtual

Set a list of tables to query (multiple-table queries).

Parameters
[in]tableNameListVector of names of tables

Definition at line 525 of file DbStorageImpl.cc.

526  {
527  if (_db == 0) error("Database session not initialized in DbStorage::setTableListForQuery()", false);
528  for (std::vector<std::string>::const_iterator it = tableNameList.begin();
529  it != tableNameList.end(); ++it) {
530  _queryTables.push_back(quote(*it));
531  }
532  _inputVars.clear();
533  _outputVars.clear();
534  _outColumns.clear();
535  _whereClause.clear();
536  _groupBy.clear();
537  _orderBy.clear();
538  _statement = 0;
539 }
std::vector< std::string > _queryTables
Names of tables to select from.
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
std::string quote(std::string const &name)
BoundVarMap _inputVars
Input variable bindings.
BoundVarMap _outputVars
Output variable bindings.
std::vector< std::string > _outColumns
void lsst::daf::persistence::DbStorageImpl::startSession ( std::string const &  location)
privatevirtual

Start a database session.

Parameters
[in]locationPhysical database location
[in]amAccess mode for the database (ReadOnly or Update)

Definition at line 189 of file DbStorageImpl.cc.

189  {
190  // Set the timezone for any DATE/TIME/TIMESTAMP fields.
191  setenv("TZ", "UTC", 1);
192 
193  DbStorageLocation dbloc(location);
194 
195  if (_db) {
196  mysql_close(_db);
197  }
198  _db = mysql_init(0);
199 
200  unsigned int port = strtoul(dbloc.getPort().c_str(), 0, 10);
201  if (mysql_real_connect(_db,
202  dbloc.getHostname().c_str(),
203  dbloc.getUsername().c_str(),
204  dbloc.getPassword().c_str(),
205  dbloc.getDbName().c_str(),
206  port, 0, 0) == 0) {
207  error("Unable to connect to MySQL database: " + _location);
208  }
209 }
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
std::string _location
Database location string saved for use by raw MySQL interface.
void lsst::daf::persistence::DbStorageImpl::startTransaction ( void  )
privatevirtual

Start a transaction.

Definition at line 229 of file DbStorageImpl.cc.

229  {
230  if (_db == 0) error("Database session not initialized "
231  "in DbStorage::startTransaction()", false);
232  if (mysql_autocommit(_db, false)) error("Unable to turn off autocommit");
233 }
MYSQL * _db
MySQL database connection pointer.
void error(std::string const &text, bool mysqlCaused=true)
void lsst::daf::persistence::DbStorageImpl::stError ( std::string const &  text)
private

Definition at line 270 of file DbStorageImpl.cc.

270  {
271  error(text + " - * " + mysql_stmt_error(_statement), false);
272 }
void error(std::string const &text, bool mysqlCaused=true)
MYSQL_STMT * _statement
Prepared query statement.
void lsst::daf::persistence::DbStorageImpl::truncateTable ( std::string const &  tableName)
privatevirtual

Truncate a table.

Parameters
[in]tableNameName of the table to truncate

Definition at line 317 of file DbStorageImpl.cc.

317  {
318  executeQuery("TRUNCATE TABLE " + quote(tableName));
319 }
std::string quote(std::string const &name)
void executeQuery(std::string const &query)

Friends And Related Function Documentation

friend class DbStorage
friend

Definition at line 85 of file DbStorageImpl.h.

Member Data Documentation

std::vector< boost::shared_array<char> > lsst::daf::persistence::DbStorageImpl::_bindingMemory
private

Memory for bound variables.

Definition at line 154 of file DbStorageImpl.h.

MYSQL* lsst::daf::persistence::DbStorageImpl::_db
private

MySQL database connection pointer.

Definition at line 141 of file DbStorageImpl.h.

boost::shared_array<unsigned long> lsst::daf::persistence::DbStorageImpl::_fieldLengths
private

Space for lengths of result fields.

Definition at line 169 of file DbStorageImpl.h.

boost::shared_array<my_bool> lsst::daf::persistence::DbStorageImpl::_fieldNulls
private

Space for null flags of result fields.

Definition at line 171 of file DbStorageImpl.h.

std::string lsst::daf::persistence::DbStorageImpl::_groupBy
private

Definition at line 160 of file DbStorageImpl.h.

BoundVarMap lsst::daf::persistence::DbStorageImpl::_inputVars
private

Input variable bindings.

Definition at line 150 of file DbStorageImpl.h.

std::string lsst::daf::persistence::DbStorageImpl::_insertTable
private

Name of table into which to insert.

Definition at line 144 of file DbStorageImpl.h.

std::string lsst::daf::persistence::DbStorageImpl::_location
private

Database location string saved for use by raw MySQL interface.

Definition at line 139 of file DbStorageImpl.h.

int lsst::daf::persistence::DbStorageImpl::_numResultFields
private

Number of result fields.

Definition at line 167 of file DbStorageImpl.h.

std::string lsst::daf::persistence::DbStorageImpl::_orderBy
private

Definition at line 161 of file DbStorageImpl.h.

std::vector<std::string> lsst::daf::persistence::DbStorageImpl::_outColumns
private

Definition at line 158 of file DbStorageImpl.h.

BoundVarMap lsst::daf::persistence::DbStorageImpl::_outputVars
private

Output variable bindings.

Definition at line 152 of file DbStorageImpl.h.

std::vector<std::string> lsst::daf::persistence::DbStorageImpl::_queryTables
private

Names of tables to select from.

Definition at line 146 of file DbStorageImpl.h.

bool lsst::daf::persistence::DbStorageImpl::_readonly
private

Remember if we are supposed to be read-only.

Definition at line 137 of file DbStorageImpl.h.

MYSQL_FIELD* lsst::daf::persistence::DbStorageImpl::_resultFields
private

Query result field metadata.

Definition at line 165 of file DbStorageImpl.h.

MYSQL_STMT* lsst::daf::persistence::DbStorageImpl::_statement
private

Prepared query statement.

Definition at line 163 of file DbStorageImpl.h.

std::string lsst::daf::persistence::DbStorageImpl::_whereClause
private

Definition at line 159 of file DbStorageImpl.h.


The documentation for this class was generated from the following files: