Defining PixDbInterface

This page contains information for discussion by people working with PixDbInterface. This is not official documentation.

What is PixDbInterface, and what is it for?

PixDbInterface is a C++ interface to connectivity and configuration information about ATLAS Pixel detector. The information should be versioned. Implementations of the current version of PixDbInterface, RootDb (and TurboDAQ?), handle connectivity and configuration data, but no existing implementation provides version control. The promise of a Coral-based implementation is to provide version control for connectivity and configuration data, and to be able to scale up to the whole Pixel detector.

Connectivity

Connectivity part of the database describes "connections" between "objects". An object (e.g. a module) has a class name (MODULE), and a unique geographical ID (D2A-S01-M3). A connection is made between named slots of objects, and can be represented by a pair of pairs of strings:

   ((srcObjID,srcSlotName), (dstObjID, dstSlotName))
Each (ID,slotName) pair must be unique. A connection is directed, and navigating from src to dst in a connectivity DB may be more efficient than navigating back from dst to src. This is the accepted connectivity model that has been discussed many times in PixelDBTaskForce meetings. The content of Marian's connectivity spreadsheet, and of CoralDB relational tables, follows this model. We want to provide access to such connectivity DB through PixDbInterface to make it usable by existing software, and want to minimize modifications to the existing code.

The first goal is to demonstrate that the technology (Coral) is suitable to serve the needs of Pixel DAQ software. Performance of a DB application is a strong function of DB schema. So we should do the demonstration with the schema that we are going to use in the long term. It does not make sense to sacrifice functionality and/or performance of CoralDB implementation by modifying its schema and relaxing constraints (like the uniqueness of ID+slotName pairs) just to accommodate the current use of PixDbInterface. Instead PixDbInterface and/or the client code may need to be modified.

A connection in PixDbInterface is represented by one DbRecord being a subrecord of another DbRecord (a hard link), or being linked from another DbRecord via a soft link. Thus a DbRecord corresponds to an object in the database sense, and must have both its class name and unique geographical ID defined. Geographical IDs were not explicitly supported by RootDb, and they were stored instead in subfields called "name". Moreover, in some cases DbRecords are used for purposes other than to represent physical objects and connections between them, and in such cases a DbRecord might have had no ID defined. To maintain compatibility with the existing code and existing ROOT files to the largest possible extent, at a meeting on 2006-12-12 we agreed that:

  • Geographical IDs should still be accessible via the "name" field.

  • DbRecord::addRecord(className,slotName,ID) now takes ID as its third argument.

  • DbRecord::addRecord(className,slotName) with two arguments sets ID to the value of slotName.

  • However if an ID for a DbRecord is still not defined or not valid (e.g. not unique) at the point where it is needed (for example, when storing information in a database), a PixDbInterface implementation must throw an exception. The application code should then be fixed to provide a unique IDs for the DbRecord.

Configuration data

In PixDbInterface one can attach DbFields, which are named pieces of extra data, to a DbRecord. A DbField can contain either a single value or an array of some fundamental types (bool, float,...), or a Histogram. In the present PixDbInterface, a field should be linked to one parent. To associate a piece of data with several DbRecords, an auxiliary DbRecord owning the data of interest is created, and that DbRecord is soft linked from the several DbRecords.

Code excerpts.

Please read the comments and see if we agree on the meaning of the interface methods. Some of unused methods and parameters were removed to simplify the interface. PixLib and ConfigEx code compiles with the shown version of PixDbInterface code (using the andr-pixdb-test CVS branch). Please also provide feedback on

  • Questions in my comments (look for question marks).

  • Comments about decorated names for fields and records.

  • Deprecation of some methods: we will support them for the sake of the old code, but new code should not use them.

DbField

 class DbField{ // this class is an interface to the actual field of a record
  public:
    // Accessors
    virtual PixDbInterface* getDb() const = 0; // get the DataBase of this field
    virtual enum DbDataType getDataType() const = 0; // read the data type.
    virtual void dump(std::ostream& os) const = 0; // Dump - debugging purpose

    virtual string getName() const = 0 ; // read the field name

    // Decorated name is an implementation dependent string that 
    // can  be obtained by a call to DbField::getDecName(), and later
    // used to find the field in the context of a database by calling 
    // PixDbInterface::DbFindFieldByName(decName). 
    // There is no other meaning to it.
    virtual string getDecName() const = 0 ;

    virtual ~DbField(){};
  };

DbRecord

  class DbRecord{ // this class is an interface to the actual record used by an actual database
  public:
    // Accessors
    virtual PixDbInterface* getDb() const = 0; // get the DataBase of this record;
    virtual dbRecordIterator recordBegin() = 0; // the iterator to the depending records
    virtual dbFieldIterator fieldBegin() = 0; // the iterator to the record data fields
    virtual dbRecordIterator recordEnd() = 0; // the end iterator to the depending records
    virtual dbFieldIterator fieldEnd() = 0; // the end iterator to the record data fields
    virtual dbRecordIterator findRecord(const string& recordName) = 0; // find a subrecord by the name of its slot
    virtual dbFieldIterator findField(const string& fieldName) = 0; // find a field by its name
    virtual void dump(std::ostream& os) const = 0; // Dump - debugging purpose

    // get the record class name - the base class name of the object
    // the record refers to (e.g. PixController)
    virtual string getClassName() const = 0;

    // This function returns the name of the slot this record is
    // attached to in the parent. If no parent, returns ID.
    virtual string getName() const = 0;

    // Decorated name is an implementation dependent string that
    // uniquely identifies a record in the context of a database.
    // It can be obtained by a call to DbRecord::getDecName(),
    // and then used as an argument for
    // PixDbInterface::DbFindRecordByName(decName).
    // There is no other meaning to it.
    virtual string getDecName() const = 0;

    virtual dbFieldIterator addField(const string& name) = 0; // NEW: Create a new field attached to this record.
    virtual void eraseField(dbFieldIterator it) = 0; // Erase a field.

    // Creates a hard link to a new DbRecord.  The slot name for the
    // link is srcSlotName, and className and ID are the attributes of
    // the new record.  Empty ID means use srcSlotName as ID.
    virtual DbRecord* addRecord(const string& className, const string& srcSlotName, const string& ID="") = 0;

    // Creates a soft link to an existing record.
    virtual dbRecordIterator linkRecord(DbRecord* in, const string& srcSlotName, const string& dstSlotName) = 0;

    // Erase a hard or soft link.  The pointed to record is NOT
    // deleted, but in the case of a hard link, its parent is set to 0.
    virtual void eraseRecord(dbRecordIterator it) = 0;

    // Virtual destructor
    virtual ~DbRecord() {};

    //################################################################
    // \deprecated Use rec->addField(name) instead of 
    //     rec->pushField(db->makeField(name)) 
    // and avoid creating orphan fields even temporarily.
    virtual dbFieldIterator pushField(DbField* in) = 0;

    // \deprecated Add a record to the record list and return the corresponding iterator.
    // Use rec->addRecord(...) instead of a combination of makeRecord() and pushRecord().
    virtual dbRecordIterator pushRecord(DbRecord* in) = 0; 
  };

PixDbInterface

  class PixDbInterface{ // this class is an interface to the actual Db used by the library
  public:
    // Accessors
    virtual DbRecord* readRootRecord() = 0;

    // \deprecated Use DbRecord::addField() instead.
    virtual DbField* makeField(const string& name) = 0;

    // Deprecated in most cases: use DbRecord::addRecord() instead.
    // The non-deprecated use is when you want to have a parentless DbRecord.
    virtual DbRecord* makeRecord(const string& name, const string& ID) = 0;

    // Modifiers
    virtual void setTag(std::string tagName) = 0; // set the date of object to be read from Db to t1

    // What is this for???
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode)= 0;

    // A call to one of this functions with
    //
    // DbAccessType==DBCOMMIT
    //   - defines the type and value of the field, and
    //   - commits the field to the database.
    //
    // DbAccessType==DBREAD
    //   - sets the variable passed by the third argument to the value of the field.
    //     If field value is not set, it throws an exception.
    //
    // DbAccessType==DBCOMMITTREE
    //   - this option does not make sense.  Throws an exception.
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, bool&) = 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, vector<bool>&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, int&) = 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, vector<int>&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, unsigned int &) = 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, float&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, vector<float>&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, double&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, vector<double>&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, Histo&)= 0;
    virtual dbFieldIterator DbProcess(DbField* theField, enum DbAccessType mode, string&)= 0;

    // DbAccessType==DBCOMMIT means write out:
    //    - The connectivity DB object it represents (class name, ID)
    //    - All subfields of the record
    //    - The connections represented by all hard and soft links of this record. Writing out the connections may
    //      requre writing out additional connectivity DB objects for the linked records, but their fields are not
    //      committed.
    //
    // DbAccessType==DBCOMMITTREE means do DBCOMMIT recursively following all hard and soft links of the record.
    //      Soft links may form loops, an implementation should take care to write them out without going into
    //      an infinite loop.
    //
    // DbAccessType==DBREAD. What is DBREAD meant to do here?
    virtual dbRecordIterator DbProcess(DbRecord* theRecord, enum DbAccessType mode) = 0;

    // \deprecated This bunch of functions is an unnecessary duplication of functions described above.
    // Kept to avoid modifications to the existing code.
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, bool&) = 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, vector<bool>&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, int&) = 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, vector<int>&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, unsigned int &) = 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, float&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, vector<float>&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, double&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, vector<double>&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, Histo&)= 0;
    virtual dbFieldIterator DbProcess(dbFieldIterator theField, enum DbAccessType mode, string&)= 0;
    virtual dbRecordIterator DbProcess(dbRecordIterator theRecord, enum DbAccessType mode) = 0;

    // These functions return an object identified by the decorated name, or 0.
    virtual DbRecord* DbFindRecordByName(const string& decName) = 0; // find a record by its name
    virtual DbField* DbFindFieldByName(const string& decName) = 0; // find a data field by its name
    // Virtual destructor
    virtual ~PixDbInterface(){};
  };

Setting up to work with updated PixDbInterface

Here is how you can prepare to work with the updated version of PixDbInterface (andr-pixdb-test CVS branch of PixDbInterface). The instructions are for a SR1 machine. (I used atlpix01.)

  1. Check out the right set of tags from CVS. The easiest way to do so is to run the script
    /afs/cern.ch/user/a/andr/public/ccdb/andr-pixdb-test/checkout.sh
  2. Set up symbolic link $HOME/daq pointing to $HOME/daq.andr-pixdb-test
  3. Set environment variables for Coral. The source command needs to be executed in each new shell session.
    • csh-like shells
      source $HOME/daq.andr-pixdb-test/Applications/Pixel/CoralDB/setup.csh
    • sh-like shells
      cd $HOME/daq.andr-pixdb-test/Applications/Pixel/CoralDB/
      ./csh2sh setup.csh > setup.sh
      source ./setup.sh
  4. Compile. To do it for the first time you can run
    /afs/cern.ch/user/a/andr/public/ccdb/andr-pixdb-test/compile.sh
    Then it will probably be enough to run make in PixLib and in PixLib/Examples.

If the compilation was successful, you'll get executables PixLib/PixDbCoralDB/mytest and PixLib/Examples/ConfigEx. Running

   ./mytest sqlite_file:/afs/cern.ch/user/a/andr/public/ccdb/andr-pixdb-test/connectivity_table_v9.db
will dump the current version of the endcap connectivity. The command
   ./ConfigEx -w SR1connectivity.cfg -o connectivity.crl
will run to completion, and produce some output. (However the output database connectivity.crl will be empty at the moment.)

Major updates:
-- Main.AndreiGaponenko - 14 Dec 2006 -- Main.AndreiGaponenko - 19 Dec 2006

Edit | Attach | Watch | Print version | History: r6 < r5 < r4 < r3 < r2 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r6 - 2007-01-31 - StefanoAntonelli
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Main All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback