1.94k likes | 2.25k Views
Objectivity/DB Course for C++ Developers. G. Organtini and L. Silvestris. Course Objectives. This course’s aim is to provide you with enough knowledge to: manage Objectivity components write a C++ application to: store data retrieve them process transactions. Daily Schedule. Monday
E N D
Objectivity/DB Course for C++ Developers G. Organtini and L. Silvestris G. Organtini & L. Silvestris
Course Objectives • This course’s aim is to provide you with enough knowledge to: • manage Objectivity components • write a C++ application to: • store data • retrieve them • process transactions G. Organtini & L. Silvestris
Daily Schedule • Monday • Objectivity main concepts • Developing applications • Data modelling • Exercise 1 • Objectivity programming • Exercise 2 • Tuesday • Varrays and Strings • Exercise 3 • Hash Tables & Naming Objects • Exercise 4 • Wednesday • Associations • Exercise 5 • Iterators • Exercise 6 • Indexes • Exercise 7 • Thursday • Objectivity tools • Exercise 8 • HepODBMS • Exercise 9-10-11-12 G. Organtini & L. Silvestris
Exercise 1 G. Organtini & L. Silvestris
Exercise 1 - Objectives • In this exercise you will learn: • the storage structure of Objectivity/DB • how to create a Federated Database • how to register a Schema into the Database • how to use of the Data Browser G. Organtini & L. Silvestris
Federate Database Federated Database (ooFDObj) Database A (ooDBObj) Database B (ooDBObj) Default Container (ooDefaultContObj) Container B (ooContObj) Basic Object (ooObj) Container A (ooContObj) Default Container (ooDefaultContObj) G. Organtini & L. Silvestris
ooDefaultContObj ooFDObj ooDBObj ooObj ooContObj Objectivity/DB Storage Classes • There are four logical storage classes provided by Objectivity to create DB Objects: • Federated Database (ooFDObj) • Database (ooDBObj) • Container (ooContObj, ooDefaultContainer) • Basic Object (ooObj) G. Organtini & L. Silvestris
Federated Database • A Federated Database logically contains one or more user-defined Databases and • the schema(data model that describes all visible class definitions) • the boot file information (lockserver host, etc) • the catalog of databases • It is physically represented by a single file on disk • Access Concurrency is managed by a lock server G. Organtini & L. Silvestris
Databases • A Database is a collection of Containers • Each Database contains at least one default Container that holds Basic Objects not explicitly clustered in a user-defined container. • It is physically represented by a single file on disk • Each Database belong to a single Federate Database G. Organtini & L. Silvestris
Containers • Containers is a collection of Basic Objects • Basic Objects belonging to a Container are physically clustered into memory pages and on disk • accessing objects belonging to the same container is more efficient • Opening a Container in update mode will lock it • Each container belongs to one and only one Database G. Organtini & L. Silvestris
Basic Object • Basic Objects are the elementary storage unit • Basic Objects may contain • scalar types (int, float, char) • structures and class instance • non-persistent C++ objects (string) • aggregates (fixed size and variable size arrays) • associations to other objects • Each Object belongs to one (and only one) Container G. Organtini & L. Silvestris
Object Persistency • Objects of the four Objectivity/DB classes, unlike C++ objects, are persistent. • Instances of each class continue to exist after your application terminates. • Persistent objects can be shared among applications, with locking manages by Objectivity/DB. • All types of persistent objects (except for the Federate DataBase) can be created and deleted dynamically by an application. G. Organtini & L. Silvestris
32 0 16 48 DATABASE Identifier CONTAINER Identifier PAGE Identifier SLOT Identifier Object Identifiers • Any object (Basic Objects, Container, Database and Federated Database) has a unique Object Identifier (OID) that allows Objectivity to find the Object anywhere in the Federation • The OID is a 64 bits word made as follows G. Organtini & L. Silvestris
Objectivity/DB Storage Summary • Persistent data are stored into a Federated Database • A Federation is composed of several Databases that may be resident on several hosts • Databases are divided into Containers • Containers are the minimum unit for locking • Containers contains Basic Objects • Access rights are managed by a process called the lock server G. Organtini & L. Silvestris
Database Database Database defaultContainer Container Basic Object Basic Object Basic Object Objectivity/DB Storage Summary Federated Database G. Organtini & L. Silvestris
The Boot File • The BOOT FILE contains information about the Federation structure • It includes the following: • the lock server host • the federation unique identifier used by the lockserver • the location of the federated database (.FDDB) file • The BOOT FILE name is the only one you should know in your application • The BOOT FILE is created and managed using Objectivity tools (oonewfd , oochange) G. Organtini & L. Silvestris
Create a Federation • To create a Federation use the command: oonewfd-fdfilehost infn-corsi98.corsi.infn.it -fdfilepath $HOME/Exercise/work/EPool.FDDB -lockserverhost infn-corsi98.corsi.infn.it -fdnumber 98 EPool fdhost: The host name that holds the federated database file fdfilepath: The complete filename of the federated database file lockserverhost: The machine running the lockserver fdnumber: A unique ID EPool: The BOOT FILE name G. Organtini & L. Silvestris
Development Flow • Develop the Logical Model of your application • Identify persistent objects and define your database structure • Define the Schema • Create the Federation • Register the Schema and generate source code • Write your C++ application • Build using Objectivity libraries G. Organtini & L. Silvestris
2 oonewfd 1 Boot File Application DDL Schema File (C++) 3 DDL Processor Application Code C++ 4 Schema Header File (C++) Schema Source Code C++ 5 Compiler/Linker C++ RunTime Library Application Program 6 Federate DataBase DataBase Schema Development Flow G. Organtini & L. Silvestris
Example Application (Logical Model) • An Electronic Pool Management System • Research Institutes maintains Electronic Pools: services who loan electronic devices to physicists to do experiments • Several Electronic Pools may exist within a single Institute • Electronic Pools need to store data about • Electronic Modules belonging to it • Physicists using them G. Organtini & L. Silvestris
EPool (a Federate Database = set of Pools within a Research Institute) ElectronicPool (a Database) ElectronicPool (a Database) Members Container Pool Container User Objets Module Objects Example Application (Logical Model) G. Organtini & L. Silvestris
Define a Schema • Identify Persistent Classes • Define data members and methods • Use Data Definition Language(DDL) to describe the object • Example - define a Module belonging to an Electronic Pool: • must store its type (ADC, TDC, I/O register,…), its standard (CAMAC, VME, PCI,…) and its serial number. • must record who is using the module (if any) and who used it in the past (for accounting) G. Organtini & L. Silvestris
class Module { private: char *type; char *standard; char *serialNumber; loan *activeLoan; loan **previousLoans; } Define a Schema Module.h G. Organtini & L. Silvestris
class Module : public ooObj { private: ooVString type; ooVString standard; ooVString serialNumber; ooRef(loan) activeLoan <-> activeModule; ooRef(loan) previousLoans[] <-> previousModule; } Define a Schema Module.ddl G. Organtini & L. Silvestris
Persistence by inheritance • Persistence in Objectivity/DB is obtained by inheriting from the ooObj class • The persistence of associations (links) is obtained using ooRef • The persistence of variable size arrays is obtained using Objectivity classes G. Organtini & L. Silvestris
DDL Processing • DDL files must be processed by an Objectivity tool to produce source files to be used in C++ programs and to register the Schema into the Federation • Running ooddlxproduces three output files: • schema.h: the header file to be used in your C++ program • schema_ddl.C: the class implementation needed to build your program • schema_ref.h: the header file to be used to handle references in your application • Syntax: ooddlxschema.ddl bootfilename G. Organtini & L. Silvestris
BOOT FILE .h OODDLX _ddl.C DDL FILE _ref.h DDL Processing G. Organtini & L. Silvestris
Browing the Database • To browse the federated database use the Objectivity tool ootoolmgr bootfilename • You may omit the bootfilename parameter if you define the environment variable OO_FD_BOOT • setenv OO_FD_BOOT bootfilename • The Tool Manager has two distinct functionalities: • the DATA BROWSER allows you to navigate into the database • the TYPE BROWSER allows you to browse classes, data members and associations between them G. Organtini & L. Silvestris
Container Region Types Region DataBase Region Browser Output Type Buttons Object Region Object Content Region Association G. Organtini & L. Silvestris
Exercise 1 • Run oonewfd to create your own Federation • check file structure on your disk • check Federation structure using the Objectivity browser • Define a Module DDL and run ooddlx to produce the Schema • look at the files created on your disk • look at the Schema registered into the Federation • navigate into the Federation G. Organtini & L. Silvestris
Exercise 1 • Use the tcshell using the comman tcsh • mkdir Exercise/work • cd Exercise/work • cp -R/home/lucia/INFNTraining/Exercise/proto/Exercise1/* . • source env.sh • Read and understand the provided DDL schema file for the persistent Module class. (Module.ddl) • Read the method source file Module.cpp • Create the Federated database oonewfd • Build the schema using ooddlx • Make changes in the Makefile • use ootoolmgr G. Organtini & L. Silvestris
Transactions • A TRANSACTION is a unit of work applied to the Database • In a transaction you can specify a set of database operations as an atomic unit • A transaction can consists of • a simple modification of a single field into a Basic Object • a complex set of changes on many Objects on several Databases G. Organtini & L. Silvestris
Beginning and Committing a Transaction • Objectivity provide a transaction class: ooTrans • To start a transaction calls the start() method of an object of type ooTrans • ooTrans transaction; • transaction.start(); • After the changes you may commit a transaction. You can use one of the following method: • transaction.commit(); • transaction.commitAndHold(); Declare Transaction Object Begin Transaction End Transaction End Transaction and Begin NewTransaction G. Organtini & L. Silvestris
Committing a Transaction • commit()terminates the transaction, commits the changes and closes the communication with the database • commitAndHold()terminates the transaction, commits the changes and start a new transaction • WARNING!! After commitment a transaction cannot be undone! G. Organtini & L. Silvestris
Aborting a Transaction • To abort a transaction already started (before committing it) use the abort() method: • transaction.start(); • … • transaction.abort(); • Aborting a transaction leaves the database in the state it was before starting the transaction • Transactions automatically abort if a process terminates before transaction is committed • Aborting a transaction causes you to lose your cache. G. Organtini & L. Silvestris
Writing an Application • Write a C++ program including the header files produced by ooddlx • Use ooHandle to declare pointers to persistent objects • Call ooInit() once to initialize • Start a transaction • Use the open() method to access a database • Commit the transaction G. Organtini & L. Silvestris
Writing an Application Module.h: the header file generated by ooddlx from Module.ddl #include “Module.h” main() { ooHandle(ooFDObj) fdbH; ooInit(); ooTrans transaction; transaction.start(); fdbH.open(“EPool”,oocUpdate); … transaction.commit(); } ooHandle(ooFDObj): fdbH is a “pointer” to a Federated Database. It is called an handle ooInit(): Initialize Objy ooTrans: declare an ooTrans Object start(): initialize a transaction open(): open in update mode the Federation using the BOOT FILE ...: make your changes to the database (i.e., add Objects, modify them, etc.) commit(): commit changes G. Organtini & L. Silvestris
Associations Objects Containers Example: Data Model User Loan User Loans[] previousModule activeModule Members previousLoans[] ActiveLoan Module ElectronicPool G. Organtini & L. Silvestris
Example: Makefile CXX=c++ OPTCXXFLAGS:= -O3 LD=c++ -Wl,-noinhibit-exec LD_FLAGS = -ldl -lm SL_FLAGS = -fPIC MKSHLIB:= c++ -shared CXXFLAGS+= -m486 -Df2cFortran OPTCXXFLAGS+= -felide-constructors -fomit-frame-pointer CXXFLAGS+=$(OPTCXXFLAGS) ALLLIBS = -L${BOOT_LIB_DIR} -L${OO_LIB_DIR} -loo #-------------------------------------------------------------------- ARCH = linux OO_LS_HOST = ${HOST} OO_PAGESIZE = 8192 OO_FDID = 99 OO_DB_PATH = /tmp/lucia/db OO_DB_JOU = /tmp/lucia/db OO_INC_DIR = ${OBJY_DIR}/include OO_LIB_DIR = ${OBJY_DIR}/lib OO_BIN_DIR = ${OBJY_DIR}/bin OODDL = $(OO_BIN_DIR)/ooddlx OONEWFD = $(OO_BIN_DIR)/oonewfd OODELETEFD = $(OO_BIN_DIR)/oodeletefd Lockserver Host Page Size Unique FD Number DataBase Path DataBase Journal File G. Organtini & L. Silvestris
Example: Makefile CCINCLUDE = TOPINC = $(CCINCLUDE) -I$(OO_INC_DIR) DEPEND = makedepend TOPLIB = -lm INCLUDES = -I. $(TOPINC) LIBS = $(TOPLIB) SOURCES := $(wildcard *.cpp) OBJECTS := $(SOURCES:.cpp=.o) SHLIB = libEPMS.so SCHEMA_DDL := $(wildcard *.ddl) SCHEMA_SRCS = $(SCHEMA_DDL:.ddl=_ddl.cpp) SCHEMA_OBJS = $(SCHEMA_DDL:.ddl=_ddl.o) SCHEMA_METHOD_SRCS = $(SCHEMA_DDL:.ddl=.cpp) SCHEMA_METHOD_OBJS = $(SCHEMA_DDL:.ddl=.o) SCHEMA_HDRS_REF = $(SCHEMA_DDL:.ddl=_ref.h) SCHEMA_HDRS_NOREF = $(SCHEMA_DDL:.ddl=.h) SCHEMA_HDRS = $(SCHEMA_HDRS_REF) $(SCHEMA_HDRS_NOREF) ALL_SRCS = $(SRCS) $(SCHEMA_DDL:.ddl=.cpp) $(SCHEMA_METHOD_SRCS) HS = $(filter-out $(SCHEMA_HDRS), $(wildcard *.h)) .PHONY : all clean all: $(SCHEMA_HDRS_NOREF) $ (SCHEMA_OBJS) $(OBJECTS) $(SHLIB) boot: $(OO_FD_BOOT) Processing all .cpp files Shared Library Name Processing all .ddl files Processing all .h files Creation of the New Federation G. Organtini & L. Silvestris
Example: Makefile %.exe : %.cc libEPMS.so $(LD) $(LD_FLAGS) $(C_FLAGS) $(INCLUDES) -o $@ \ $*.cc \ $(ALLLIBS) -lEPMS \ $(LIBS) chmod 755 $@; $(SHLIB) : $(OBJECTS) $(MKSHLIB) $(C_FLAGS) -o $(SHLIB) $(OBJECTS) $(SCHEMA_HDRS_NOREF): %.h : %.ddl $(OO_FD_BOOT) $(DEPEND) $(INCLUDES) $*.ddl $(OODDL) -c++_suffix _ddl.cpp $(INCLUDES) $< $(OO_FD_BOOT) touch $*_ddl.d $(DEPEND) $(INCLUDES) $*_ddl.cpp %.o : %.cpp $(CXX) $(C_FLAGS) $(SL_FLAGS) $(INCLUDES) -c $< -o $@ %.o : %.cc $(CXX) $(C_FLAGS) $(INCLUDES) -c $< -o $@ %.d : %.cpp touch $@ $(DEPEND) -f $@ $(INCLUDES) $< %.d : %.cc touch $@ $(DEPEND) -f $@ $(INCLUDES) $< %.o : %.f $(F77) $(F_FLAGS) -c $< -o $@ Rules for the executable Rules for the Shared Memory Usage of the ooddlx G. Organtini & L. Silvestris
Example: Makefile clean: rm -f $(SCHEMA_HDRS) $(SCHEMA_OBJS) $(OBJECTS) rm -f *_ddl.* rm -f *.so cleanall: clean $(OODELETEFD) $(OO_FD_BOOT) $(OO_FD_BOOT): $(OONEWFD) -fdfilehost $(OO_LS_HOST) -fdfilepath $(OO_DB_PATH)/$(OO_BOOT).FDDB \ -jnldirpath $(OO_DB_JOU) -pagesize $(OO_PAGESIZE) \ -lockserverhost $(OO_LS_HOST) \ -fdnumber $(OO_FDID) $(OO_FD_BOOT) Rules for clean the directory Rules for delete also the federate database Usage of oonewfd Objectivity Tool G. Organtini & L. Silvestris
Example: Application • We will write an application from which we can • add new Pools, new Users and new Modules in the database • loan Modules to Users • inquire the status of Modules and Users • Check Module’s and User’s characteristics • Our application will be MENU based, but not graphical (graphics is beyond the aims of this course) G. Organtini & L. Silvestris
Exercise 1 Continuation • Read and understand the source files for the provided application • In EPMS::AddModule(), note the sequence of starting a transaction, opening the federate database, opening a database specified by the OO_DB_NAME, creating the Module using the overloaded new operator and committing the transaction • Use the modified Makefile • Build the shared library • Read and understand the provided the epms.cc application • Build the application epms.exe • Use epms.exe • Use ootoolmgr G. Organtini & L. Silvestris
Exercise 2 G. Organtini & L. Silvestris
Exercise 2 - Objectives • In this section basic coding rules will be presented to be able to: • create and access persistent Objects in databases using handles • use handles member functions • use databases System Names • create Basic Objects in the database • encapsulate your code to simplify the program G. Organtini & L. Silvestris
Accessing Persistent Objects • Objectivity provides two classes to access Objects: • object references (ooRef) • object handles (ooHandle) • Handles and references are also called smart pointers. They are used to access persistent Objects in the databases • ooHandle(className) classH; • ooRef(className) classR; This is the class Name... …and this is the Object of class ooHandle... …while this is an Object of class ooRef G. Organtini & L. Silvestris
Handles vs. References • References points Objects in the cache for the current operation • the Objects may be removed from the cache if space is needed • Handles points Objects in memory • the Objects stays in memory as long as the handle exists • How to choose: • References are used as data members within a persistent object to store a reference to another persistent objects • Handles are used to maintain the state information of an Object, which makes accessing multiple fields on the same object more efficient than ooRef G. Organtini & L. Silvestris
Object Handles • Once you create a new object, you use a handle as reference point: • ModuleH = new(databaseH) Module(“ADC”,”VME”,”1”); The new operator create a new instance of a Module in the database pointed by databaseH This is a handle to ooDBObj, declared as: ooHandle(ooDBObj) databaseH Arguments passed to new Module Object This is a Handle to a Module class, declared as: ooHandle(Module) ModuleH This is the Object class G. Organtini & L. Silvestris
Handle Member Functions • You can use member functions and operators defined on the handle to access database operations for the object. • Some handle member functions are: • containedIn() returns object handle to container in which the basic object is contained • nameObj() assigns a name to the object associated to the handle • lookupObj() is used to access the object by its name G. Organtini & L. Silvestris