//-< BUGDB.H >------------------------------------------------------*--------* // GOODS Version 1.0 (c) 1997 GARRET * ? * // (Generic Object Oriented Database System) * /\| * // * / \ * // Created: 27-Mar-99 K.A. Knizhnik * / [] \ * // Last update: 4-Apr-99 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* // Example of database Web publishing: Bug Tracking Database //-------------------------------------------------------------------*--------* #ifndef __BUGDB_H__ #define __BUGDB_H__ #include #include #include "goods.h" #include "dbscls.h" USE_GOODS_NAMESPACE class SetMember : public object { public: virtual void print(void const*) const; virtual boolean select(void const*) const; struct select_args { void const* condition; void const* print_arg; size_t count; }; static void selectTrampoline(ref mbr, void const* arg); static void printTrampoline(ref mbr, void const* arg); SetMember(class_descriptor& desc) : object(desc) {} SetMember(class_descriptor& desc, size_t varyingSize) : object(desc, varyingSize) {} METACLASS_DECLARATIONS(SetMember, object); }; template class small_set { public: typedef void (T::*const_iterator)(void const* arg) const; typedef void (T::*iterator)(void const* arg); ref members; protected: struct invocation { iterator func; void const* arg; }; struct const_invocation { const_iterator func; void const* arg; }; static void const_trampoline(ref mbr, void const* arg) { ref obj = mbr->obj; const_invocation* ip = (const_invocation*)arg; (((obj.operator->()).operator->())->*ip->func)(ip->arg); } static void trampoline(ref mbr, void const* arg) { ref obj = mbr->obj; invocation* ip = (invocation*)arg; ((modify(obj).operator->())->*ip->func)(ip->arg); } public: size_t size() const { return members->n_members; } boolean empty() const { return members->empty(); } void apply(const_iterator iter, void const* arg = NULL) const { const_invocation inv; inv.arg = arg; inv.func = iter; members->iterate(const_trampoline, &inv); } void apply(iterator iter, void const* arg = NULL) const { invocation inv; inv.arg = arg; inv.func = iter; members->iterate(trampoline, &inv); } size_t print(void const* arg = NULL) const { return members->iterate(SetMember::printTrampoline, arg); } size_t select(void const* condition = NULL, void const* print_arg = NULL) const { SetMember::select_args args; args.condition = condition; args.print_arg = print_arg; args.count = 0; members->iterate(SetMember::selectTrampoline, &args); return args.count; } ref find(char const* key) const { ref mbr = members->find(key); if (mbr == NULL) { return NULL; } return mbr->obj; } ref erase(char const* key) const { ref mbr = members->find(key); if (mbr == NULL) { return NULL; } modify(members)->remove(mbr); return mbr->obj; } void insert(char const* key, ref obj) const { modify(members)->insert(key, obj); } boolean insertUnique(char const* key, ref obj) const { return modify(members)->insert_unique(key, obj); } field_descriptor& describe_components() { return FIELD(members); } inline friend field_descriptor& describe_field(small_set& s) { return s.describe_components(); } virtual ~small_set() {} virtual void initialize(object* owner) { members = set_owner::create(owner); } }; template class large_set : public small_set { public: virtual void initialize(object* owner) { members = B_tree::create(owner); } }; class Bug; class UserGroup; class Software; class Person : public SetMember { public: ref sName; ref sEmailAddress; ref sPassword; small_set setGroups; small_set setSoftware; small_set setReportedBugs; virtual boolean isUser() const; void changePassword(char const* password); void changeEmail(char const* e_mail); void print(void const*) const; struct SelectPattern { char const* name; char const* eMail; }; boolean select(void const* pattern) const; boolean checkPassword(char const* password) const { return sPassword->compare(password) == 0; } void unregister(void const* software) const; void exclude(void const* software) const; METACLASS_DECLARATIONS(Person, SetMember); Person(char const* name, char const* eMail, char const* password, class_descriptor &desc = self_class); }; class Engineer : public Person { public: small_set setAssignedBugs; virtual boolean isUser() const; void unregister(void const* software) const; Engineer(char const* name, char const* eMail, char const* password); METACLASS_DECLARATIONS(Engineer, Person); }; class UserGroup : public SetMember { public: ref sName; small_set setUsers; small_set setBugs; struct SelectPattern { char const* name; int minBugs; int maxBugs; }; void print(void const*) const; boolean select(void const* pattern) const; void removeUser(void const* arg) const; void removeBug(void const* arg) const; void addBug(void const* arg) const; boolean addUser(char const* group, char const* name, ref person) const; UserGroup(char const* name); METACLASS_DECLARATIONS(UserGroup, SetMember); }; class zDate { private: int4 timestamp; public: zDate() { timestamp = -1; } void setCurrentDate() { timestamp = time(0); } boolean isValid() const { return timestamp != -1; } char* asString(char* buf, size_t buf_size, const char* format = "%c") const { strftime(buf, buf_size, format, localtime((time_t*)×tamp)); return buf; } char* asString(const char* format = "%c") const { static char buf[64]; return asString(buf, sizeof buf, format); } int compare (zDate const& date) const { return timestamp - date.timestamp; } int operator >= (zDate const& date) const { return compare(date) >= 0; } int operator <= (zDate const& date) const { return compare(date) <= 0; } int operator > (zDate const& date) const { return compare(date) > 0; } int operator < (zDate const& date) const { return compare(date) < 0; } int operator == (zDate const& date) const { return compare(date) == 0; } int operator != (zDate const& date) const { return compare(date) == 0; } inline friend field_descriptor& describe_field(zDate& z) { return z.describe_components(); } field_descriptor& describe_components() { return FIELD(timestamp); } }; class Version : public SetMember { public: ref sLabel; nat1 majorVersionNumber; nat1 minorVersionNumber; zDate released; ref sComment; struct SelectPattern { char const* label; int minMajorVersionNumber; int maxMajorVersionNumber; int minMinorVersionNumber; int maxMinorVersionNumber; }; int getVersion() const; char* getVersionString() const; void print(void const*) const; boolean select(void const* pattern) const; Version(char const* label, int major, int minor, const char* comment); METACLASS_DECLARATIONS(Version, SetMember); }; class Software : public SetMember { public: ref sName; ref pManager; small_set setEngineers; small_set setUsers; small_set setVersions; small_set setBugs; struct SelectPattern { char const* name; int minEngineers; int maxEngineers; int minUsers; int maxUsers; int minBugs; int maxBugs; }; int getLastVersion() const; char* getLastVersionString() const; boolean attachEngineer(char const* name, ref engineer) const; boolean detachEngineer(char const* name) const; boolean registerUser(char const* name, ref user) const; boolean unregisterUser(char const* name) const; void detachEngineerCallback(void const*) const; void unregisterUserCallback(void const*) const; void print(void const*) const; boolean select(void const* pattern) const; Software(char const* name, ref version); METACLASS_DECLARATIONS(Software, SetMember); }; enum eCATEGORY { CATEGORY_NOT_SPECIFIED, CRASH, PROGRAM_HANGS, UI_DISPLAY, UI_BEHAVIOR, CALCULATION, ERROR_HANDLING, PERFORMANCE, LICENSING, INSTALLATION, DOCUMENTATION, ENHANCEMENT, HOW_TO_QUESTION }; extern char const* const eCATEGORY_STRING[]; enum eSTATUS { STATUS_NOT_SPECIFIED, STATUS_OPENED, STATUS_FIXED, STATUS_CLOSED, STATUS_PENDING_ENGINEER, STATUS_PENDING_USER, STATUS_POSTPONED, STATUS_IRREPRODUCIBLE, STATUS_WITHDRAWN, STATUS_AS_DESIGNED }; extern char const* const eSTATUS_STRING[]; enum eFIXING_PRIORITY { PRIORITY_NOT_SPECIFIED, FIX_IMMEDIATELY, FIX_BEFORE_NEXT_BUILD_RELEASE, FIX_BEFORE_NEXT_MINOR_RELEASE, FIX_BEFORE_NEXT_MAJOR_RELEASE, FIX_IF_POSSIBLE, OPTIONAL }; extern char const* const eFIXING_PRIORITY_STRING[]; enum eSEVERITY { SEVERITY_NOT_SPECIFIED, FATAL, SERIOUS, MINOR, LAST_SEVERITY }; extern char const* const eSEVERITY_STRING[]; class Report : public SetMember { public: ref sDescription; ref pAuthor; zDate creationDate; eSTATUS status; int4 index; struct SelectPattern { char const* author; zDate createdBefore; zDate createdAfter; eSTATUS status; }; void print(void const*) const; boolean select(void const* pattern) const; void update(char const* description, eSTATUS status); Report(int index, char const* description, ref author, eSTATUS status); METACLASS_DECLARATIONS(Report, SetMember); }; class Bug : public SetMember { public: int4 bugId; ref sOneLineSummary; eCATEGORY eCategory; eFIXING_PRIORITY eFixingPriority; eSEVERITY eSeverity; ref pReportedBy; ref pAssignedTo; ref sHardwarePlatform; ref sOperatingSystem; ref pSoftware; ref pVersion; small_set setReportHistory; small_set setWorkArounds; small_set setSimilarBugs; int4 nReports; struct SelectPattern { eCATEGORY eCategory; eFIXING_PRIORITY eFixingPriority; eSEVERITY eSeverity; char const* os; char const* platform; char const* software; char const* assignedTo; char const* reportedBy; char const* summary; int minMajorVersionNumber; int maxMajorVersionNumber; int minMinorVersionNumber; int maxMinorVersionNumber; }; boolean select(void const* pattern) const; void print(void const*) const; void addReport(ref report) const; void addWorkAround(ref report) const; void deassign(void const*) { pAssignedTo = NULL; } void update(char const* summary, eCATEGORY category, eFIXING_PRIORITY fixingPriority, eSEVERITY severity, char const* os, char const* platform, char const* similarBugId, ref similarBug); Bug(int4 bugId, char const* summary, eCATEGORY category, eFIXING_PRIORITY fixingPriority, eSEVERITY severity, char const* os, char const* platform, ref reportedByPerson, ref soft, ref vers); METACLASS_DECLARATIONS(Bug, SetMember); }; #define BUG_TRACKING_DB_VERSION 1 class BugTrackingDB : public object { public: int version; large_set setAllPeople; large_set setAllBugs; small_set setAllUserGroups; small_set setAllSoftware; BugTrackingDB(int vers); METACLASS_DECLARATIONS(BugTrackingDB, object); }; class RootObject : public object { public: ref db; int nBugs; void initialize() const; RootObject(int version) : object(self_class) { db = NEW BugTrackingDB(version); nBugs = 0; } boolean addBug(char* bugId, ref bug, ref user) const; void assignBug(char const* bugId, ref bug, ref engineer) const; void deassignBug(char const* bugId, ref bug, ref engineer) const; boolean removePerson(char const* name) const; boolean removeSoftware(char const* software) const; boolean removeGroup(char const* group) const; boolean removeBug(char const* bug) const; METACLASS_DECLARATIONS(RootObject, object); }; #endif