__OBJECT-ORIENTED DATABASE MANAGEMENT SYSTEMS_ by Al Stevens [LISTING ONE] // ----------- school.hcd // School Database Design for POET #include #include persistent class Teacher { PtString name; public: Teacher(char *nm) { name = nm; } ~Teacher() {} void Display() { cout << (char *) name; } }; persistent class Subject { PtString name; Teacher *teacher; public: Subject(char *nm) { name = nm; teacher = NULL; } ~Subject() {} void AddTeacher( Teacher &tch ) { teacher = &tch; } void Display() { cout << (char *) name; } Teacher *Tchr() { return teacher; } }; typedef cset TeacherSet; typedef cset SubjectSet; [LISTING TWO] // -------- schoolp.cpp // School Application for POET #include #include #include "school.hxx" PtBase objbase; // ------- build a new Subject object void NewSubject() { char nm[50]; cout << "\n--- New Subject --- "; cout << "\nEnter Subject name: "; cin >> nm; Subject subj(nm); subj.Assign(&objbase); // assign object to database subj.Store(); // store object in database } // ------- build a new Teacher object void NewTeacher() { char nm[50]; cout << "\n--- New Teacher --- "; cout << "\nEnter Teacher name: "; cin >> nm; Teacher tch(nm); tch.Assign(&objbase); // assign object to database tch.Store(); // store object in database } // ----------- assign a Teacher object to a Subject object void Assignment() { char nm[50]; cout << "\n--- Assignment --- "; cout << "\nEnter Subject name: "; cin >> nm; // ----- build sets to query for Subjects SubjectAllSet *allSubjects = new SubjectAllSet(&objbase); SubjectSet *SubjectResult = new SubjectSet; SubjectQuery SubjQuery; // ----- build the query SubjQuery.Setname(nm, PtEQ); // ----- run the query allSubjects->Query( &SubjQuery, SubjectResult ); // ---- get the first SubjectResult int n = SubjectResult->GetNum(); if (n == 0) cout << "\nNo such subject"; else if (n > 1) { // ----- more than one result, query used wild cards? cout << "\nEnter specific subject"; cout << '\n'; cout << "n = " << n; } else { // ------- found a Subject object Subject *subj; SubjectResult->Seek(0, PtSTART); SubjectResult->Get(subj); cout << "\nFound "; subj->Display(); // ------- get a Teacher object to assign to Subject char tnm[50]; cout << "\nEnter Teacher name: "; cin >> tnm; // ----- build sets to query for Teachers TeacherAllSet *allTeachers = new TeacherAllSet(&objbase); TeacherSet *TeacherResult = new TeacherSet; TeacherQuery TchQuery; // ----- build the query TchQuery.Setname(tnm, PtEQ); // ----- run the query allTeachers->Query( &TchQuery, TeacherResult ); // ----- get the first TeacherResult int n = TeacherResult->GetNum(); if (n == 0) cout << "\nNo such teacher"; else if (n > 1) cout << "\nEnter specific teacher"; else { // ------- found a Teacher object Teacher *tch; TeacherResult->Seek(0, PtSTART); TeacherResult->Get(tch); cout << "\nFound "; tch->Display(); // ---------- add the Teacher to the Subject subj->AddTeacher(*tch); // ------- store the Subject object in the database subj->Store(); TeacherResult->Unget(tch); } delete allTeachers; delete TeacherResult; SubjectResult->Unget(subj); } delete allSubjects; delete SubjectResult; } // ---------- list the Subjects (with assigned Teachers) // and the Teachers (regardless of assignment) void List() { cout << "\nSubjects"; cout << "\n--------"; // --------- build set to get all Subjects SubjectAllSet *allSubjects = new SubjectAllSet(&objbase); Subject *thisSubject; allSubjects->Seek(0, PtSTART); while (allSubjects->Seek(1, PtCURRENT) == 0) { // ----- get each Subject in turn allSubjects->Get(thisSubject); // ------ display the Subject cout << '\n'; thisSubject->Display(); // ----- if there is a Teacher assigned, display it Teacher *t = thisSubject->Tchr(); if (t != NULL) { cout << " taught by "; t->Display(); } allSubjects->Unget(thisSubject); } cout << "\n\nTeachers"; cout << "\n--------"; // --------- build set to get all Teachers TeacherAllSet *allTeachers = new TeacherAllSet(&objbase); Teacher *thisTeacher; allTeachers->Seek(0, PtSTART); while (allTeachers->Seek(1, PtCURRENT) == 0) { // ----- get each Teacher in turn allTeachers->Get(thisTeacher); cout << '\n'; thisTeacher->Display(); allTeachers->Unget(thisTeacher); } } // -------- menu to select processes void SchoolMenu() { int sel = 0; while (sel != 5) { cout << '\n'; cout << '\t' << "1. New Subject" << '\n'; cout << '\t' << "2. New Teacher" << '\n'; cout << '\t' << "3. Assignment" << '\n'; cout << '\t' << "4. List" << '\n'; cout << '\t' << "5. Quit" << '\n'; cout << '\t' << " Select: "; cin >> sel; switch (sel) { case 1: NewSubject(); break; case 2: NewTeacher(); break; case 3: Assignment(); break; case 4: List(); break; default: break; } } } void main() { // ------- connect to server if (objbase.Connect("LOCAL") != 0) cout << "Cannot connect"; else { // ----- open database if (objbase.Open("..\\base") != 0) cout << "Cannot open database"; else { // --------- run the application SchoolMenu(); // ------- close the database objbase.Close(); } // ------ disconnect from the server objbase.DisConnect(); } } [LISTING THREE] // -------- schoolc.cpp // School application for Code Farms Libraries #include #include #include #define ZZmain #include "zzincl.h" // generated by ZZPREP // ------ Root class to control entry to others class Root { ZZ_EXT_Root }; // ---------- persistent Teacher class class Teacher { ZZ_EXT_Teacher public: Teacher(char *name); Teacher() {} void Display(); }; // ---------- persistent Subject class class Subject { ZZ_EXT_Subject public: Subject(char *name); Subject() {} void Display(); }; // -------- the Organizations ZZ_HYPER_SINGLE_COLLECT(subject,Root,Subject); ZZ_HYPER_NAME(subjname, Subject); ZZ_HYPER_SINGLE_COLLECT(teacher,Root,Teacher); ZZ_HYPER_NAME(tchname, Teacher); ZZ_HYPER_DOUBLE_LINK(assignment,Subject,Teacher); ZZ_HYPER_UTILITIES(util); // ---------- Teacher constructor Teacher::Teacher(char *name) { char *nm = util.strAlloc(name); tchname.add(this, nm); } // -------- display a Teacher object void Teacher::Display() { // --- get the NAME linked with this Teacher char *nm = tchname.fwd(this); cout << nm; } // ---------- Subject constructor Subject::Subject(char *name) { char *nm = util.strAlloc(name); subjname.add(this, nm); } // -------- display a Subject object void Subject::Display() { // --- get the NAME linked with this Subject char *nm = subjname.fwd(this); cout << nm; } static Root *rt; // ------- build a new Subject object void NewSubject() { char name[50]; cout << "\n--- New Subject --- "; cout << "\nEnter Subject name: "; cin >> name; Subject *sb = new Subject(name); subject.add(rt, sb); } // ------- build a new Teacher object void NewTeacher() { char name[50]; cout << "\n--- New Teacher --- "; cout << "\nEnter Teacher name: "; cin >> name; Teacher *tc = new Teacher(name); teacher.add(rt, tc); } // ----------- assign a Teacher object to a Subject object void Assignment() { char nm[50]; cout << "\n--- Assignment --- "; cout << "\nEnter Subject name: "; cin >> nm; // ---- iterate through the Subject objects subject_iterator sIter(rt); Subject *sb; while ((sb = sIter++) != NULL) { char *snm = subjname.fwd(sb); if (strcmp(nm, snm) == 0) { // ---- get a Teacher object to assign to Subject cout << "\nEnter Teacher name: "; cin >> nm; // ---- iterate through the Teacher objects teacher_iterator tIter(rt); Teacher *tc; while ((tc = tIter++) != NULL) { char *tnm = tchname.fwd(tc); if (strcmp(nm, tnm) == 0) { // --- associate the two assignment.add(sb, tc); return; } } cout << "\nNo such teacher"; return; } } cout << "\nNo such subject"; } // ---------- list the Subjects and the Teachers void List() { static char *ln = "\n----------------------"; cout << ln; cout << "\nSubjects"; cout << ln; // ---- iterate through the Subject objects subject_iterator sIter(rt); Subject *sb; while ((sb = sIter++) != NULL) { cout << '\n'; sb->Display(); // -- get Teacher object associated with this Subject Teacher *tch = assignment.fwd(sb); if (tch != NULL) { cout << " taught by "; tch->Display(); } } cout << ln; cout << "\nTeachers"; cout << ln; // ---- iterate through the Teacher objects teacher_iterator tIter(rt); Teacher *tc; while ((tc = tIter++) != NULL) { cout << '\n'; tc->Display(); // -- get Subject object associated with this Teacher Subject *sbj = assignment.bwd(tc); if (sbj != NULL) { cout << " teaches "; sbj->Display(); } } cout << ln; } // -------- menu to select processes void SchoolMenu(void) { int sel = 0; while (sel != 5) { cout << '\n'; cout << '\t' << "1. New Subject" << '\n'; cout << '\t' << "2. New Teacher" << '\n'; cout << '\t' << "3. Assignment" << '\n'; cout << '\t' << "4. List" << '\n'; cout << '\t' << "5. Quit" << '\n'; cout << '\t' << " Select: "; cin >> sel; switch (sel) { case 1: NewSubject(); break; case 2: NewTeacher(); break; case 3: Assignment(); break; case 4: List(); break; default: break; } } } static char dbname[] = "school"; void main() { char *v, *t; // --------- open the database and load the organizations if (access(dbname, 0) == 0) { util.open(dbname, 1, &v, &t); rt = (Root *) v; } else { // ----- the database has never been built rt = new Root; v = (char *) rt; t = "Root"; } // --------- run the application SchoolMenu(); // --------- save the objects to the database util.save(dbname, 1, &v, &t); } #include "zzfunc.c" // generated by ZZPREP [LISTING FOUR] /* ----------------------------------------------------------------------- school.ddl -- the Raima Object Manager schema for the School database ---------------------------------------------------------------------- */ database school[512] { data file "school.dat" contains teacher, subject; key file "school.k01" contains teacher.name; key file "school.k02" contains subject.name; record teacher { key char name[30]; db_addr subj; } record subject { key char name[30]; db_addr tch; } } [LISTING FIVE] // -------- schoolr.cpp // School Application for Raima Object Manager #include #include #include #include #include #include "school.h" // ------ define the database class School : public StoreDb { public: School(); DEFINE_DB_LOCATOR; }; class Subject; // ------ Teacher class class Teacher : public StoreObj, public teacher { int RecType() { return TEACHER; } public: Teacher() : StoreObj(KeyObj(TEACHER_NAME)) { subj = 0; } Teacher(char *nm) : StoreObj(KeyObj(TEACHER_NAME)) { subj = 0; strncpy(name, nm, 30); } STOREDIN(School); DIRECTREF(Subject, subj); void Display() { cout << name; } }; // ------ Subject class class Subject : public StoreObj, public subject { int RecType() { return SUBJECT; } public: Subject() : StoreObj(KeyObj(SUBJECT_NAME)) { tch = 0; } Subject(char *nm) : StoreObj(KeyObj(SUBJECT_NAME)) { tch = 0; strncpy(name, nm, 30); } STOREDIN(School); DIRECTREF(Teacher, tch); void Display() { cout << name; } }; // ------- define the task class SchoolTask : public StoreTask { School SchoolDB; // this is the database int sel; // menu selection void NewSubject(); void NewTeacher(); void Assignment(); void List(); public: SchoolTask(); }; DB_INIT(School); // Initialize DB_LOCATOR // ------ constructor for the database School::School() : StoreDb("School", PDB_LOCATOR) { if (Open() != True) // --- database probably has not been initialized cout << "\nCannot open database"; } // ------- build a new Subject object void SchoolTask::NewSubject() { char nm[50]; cout << "\n--- New Subject --- "; cout << "\nEnter Subject name: "; cin >> nm; Subject sbj(nm); // construct the Subject sbj.NewObj(); // add it to the database } // ------- build a new Teacher object void SchoolTask::NewTeacher() { char nm[50]; cout << "\n--- New Teacher --- "; cout << "\nEnter Teacher name: "; cin >> nm; Teacher tchr(nm); // construct the Teacher tchr.NewObj(); // add it to the database } // ----------- assign a Teacher object to a Subject object void SchoolTask::Assignment() { char nm[50]; cout << "\n--- Assignment --- "; cout << "\nEnter Subject name: "; cin >> nm; Subject sbj; KeyObj sky(SUBJECT_NAME, nm); // build a Subject key sbj[sky]; // retrieve Subject if (sbj.Okay()) { // ------- get a Teacher object to assign to Subject char tnm[50]; cout << "\nEnter Teacher name: "; cin >> tnm; Teacher tchr; KeyObj tky(TEACHER_NAME, tnm); // build a Teacher key tchr[tky]; // retrieve Teacher if (tchr.Okay()) { tchr.Ref(sbj); // direct reference to Subject sbj.Ref(tchr); // direct reference to Teacher } else cout << "\nNo such teacher"; } else cout << "\nNo such subject"; } // ---------- list the Subjects (with assigned Teachers) // and the Teachers (with assigned Subjects) void SchoolTask::List() { Subject sbj; Teacher tchr; cout << "\nSubjects"; cout << "\n--------"; // ------- step through Subjects for (sbj[FIRST]; sbj.Okay(); sbj++) { cout << '\n'; sbj.Display(); sbj >> tchr; // direct reference link if (tchr.Okay()) { cout << " taught by "; tchr.Display(); } } cout << "\n\nTeachers"; cout << "\n--------"; // ------- step through Teachers for (tchr[FIRST]; tchr.Okay(); tchr++) { cout << '\n'; tchr.Display(); tchr >> sbj; // direct reference link if (sbj.Okay()) { cout << " teaches "; sbj.Display(); } } } // -------- task constructor has menu to select processes SchoolTask::SchoolTask() { sel = 0; while (sel != 5) { cout << '\n'; cout << '\t' << "1. New Subject" << '\n'; cout << '\t' << "2. New Teacher" << '\n'; cout << '\t' << "3. Assignment" << '\n'; cout << '\t' << "4. List" << '\n'; cout << '\t' << "5. Quit" << '\n'; cout << '\t' << " Select: "; cin >> sel; switch (sel) { case 1: NewSubject(); break; case 2: NewTeacher(); break; case 3: Assignment(); break; case 4: List(); break; default: break; } } } void main() { SchoolTask st; }