/*****************************************************************************/ /* File : GENDB.HPP */ /* */ /* Authors : Stephen C. Smith / Craig E. Smith */ /* University of Massachusetts - Lowell */ /* */ /* Created : Spring Semester, 1992 (Jan - May) */ /* */ /* Revisions : SCS/CES - 01/25/92 - Initial Version */ /* */ /* Purpose : This include file (header file) provides all the constants */ /* and class declarations used for the GENDB data-modeling tool. */ /* It must be included by any application that uses GENDB. */ /* For more information, see the module description in GENDB.CPP */ /* and the GENDB.DOC user's manual. */ /* */ /*****************************************************************************/ #ifndef __GENDB_LOADED #define __GENDB_LOADED 1 #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define BYTE unsigned char #define CondFree(x) if(x) free(x) #define DeclareFunc(x) static char *func = x #define table_loop(x) for (x.Reset(); !x.Done(); x.Next()) #define child_loop(x,y,fld) for (y.Reset(&x,fld); !y.Done(); y.Next()) #define dbinfo_loop(x) for (x.Reset(); !x.Done(); x.Next()) #define tableinfo_loop(x,y) for (x.Reset(y); !x.Done(); x.Next()) enum field_types { DATA_FIELD, TABLE_FIELD }; enum rel_types { PARENT, CHILD }; enum rel_cards { ONE_TO_ONE, ONE_TO_MANY }; enum data_types { INTEGER, FLOAT, STRING, USER }; enum iter_types { TABLE_ITER, CHILD_ITER }; #define MAX_TABLES 50 #define MAX_FIELDS 20 #define MAX_TBL_PATHS 5 #define FILELINE_LEN 132 #define ERRSTACK_MAX 5 #define USERTYPES_MAX 10 class table; class database; class iterator; class UserDefinedType; class UserTypes; #define ERR_FIELD_NOT_FOUND 1000 #define ERR_RELATION_NOT_FOUND 1002 #define ERR_NOT_A_PARENT_FIELD 1004 #define ERR_CHILD_NOT_A_PARENT 1006 #define ERR_PKEY_NOT_FOUND 1008 #define ERR_PARENT_NOT_CONNECTED 1010 #define ERR_BAD_TYPE 1012 #define ERR_PARENT_NOT_A_CHILD 1014 #define ERR_PKEY_ABBREV_MISMATCH 1016 #define ERR_BAD_PKEY 1018 #define ERR_FILE_NOT_FOUND 1020 #define ERR_NO_SUCH_TABLE 1022 #define ERR_CANT_OPEN_OUTPUT 1024 #define ERR_UNKNOWN_TYPE 1026 #define ERR_DUPLICATE_PKEY 1028 #define ERR_PARENT_CARD_1_OR_0 1030 #define ERR_CHILD_CARD_NOT_POSITIVE 1032 #define ERR_TOO_MANY_CHILDREN 1034 #define ERR_SCHEMA_SYNTAX 1036 #define ERR_SCHEMA_NOSUCHTABLE 1038 #define ERR_SCHEMA_EXPECT_OPEN 1040 #define ERR_SCHEMA_EXPECT_CLOSE 1042 #define ERR_SCHEMA_EXPECT_CREATE 1044 #define ERR_SCHEMA_EXPECT_FROM 1046 #define ERR_SCHEMA_EXPECT_VIA 1048 #define ERR_UNKNOWN_PATH 1050 struct errmsg_t { int err_num; char *routine; char *table; char *err_text; }; struct err_stack_t { int count; struct errmsg_t *body[ERRSTACK_MAX]; }; class UserDefinedType { protected: char *type_name; int type_name_len; int data_size; public: UserDefinedType(char *tname, int tsize); virtual void *Read(char *s); virtual char *Print(void *p); virtual void Free(void *p); friend class UserTypes; friend class database; friend class iterator; friend class dbinfo; friend class tableinfo; friend class table; }; // class UserDefinedType class UserTypes { protected: static int object_count; int num_types; UserDefinedType *types[USERTYPES_MAX]; public: UserTypes(); friend class UserDefinedType; friend class database; friend class iterator; friend class dbinfo; friend class tableinfo; friend class table; }; // class UserTypes extern UserTypes user_types; struct data_elt_t { int isnull; union { int ival; float fval; char cval; char *sval; void *pval; } u; }; struct tuple_t { char pkey[9]; struct data_elt_t *fields[MAX_FIELDS]; struct tuple_t *prev; struct tuple_t *next; struct tuple_t *pptr[MAX_FIELDS]; int num_children[MAX_FIELDS]; union { struct tuple_t *fcptr[MAX_FIELDS]; struct tuple_t *next_child[MAX_FIELDS]; }; union { struct tuple_t *lcptr[MAX_FIELDS]; struct tuple_t *prev_child[MAX_FIELDS]; }; }; struct index_list_t { struct tuple_t *data; struct index_list_t *next; }; struct index_elt_t { struct index_list_t *list; struct index_list_t *last; struct index_elt_t *left; struct index_elt_t *right; }; struct index_t { database *db; int fld_num; enum data_types type; struct index_elt_t *root; }; struct field_t { char *field_name; enum field_types type; union { struct { enum data_types data_type; UserDefinedType *user_routines; int data_size; struct index_t *index; } dfield; struct { enum rel_types rel_type; int rel_card; table *tbl; int fld_num; int num_rows; } tfield; } u; }; struct path_elt_t { int fld_num; struct path_elt_t *next; }; struct path_t { char *path_name; struct path_elt_t *head; }; class error { protected: struct err_stack_t err_stack; public: error(); void Reset(); void AddError(int fatal, int err, char *rtn, char *tbl, char *txt); int ErrNo() { return (err_stack.count >0 ? err_stack.body[err_stack.count-1]->err_num : 0); } int IsError() { return (err_stack.count > 0); } void Print(); ~error(); }; class table { protected: char *table_name; char table_abbrev[3]; int tbl_num; database *db; int num_fields; int last_data_field; int last_find_field; struct field_t *fields[MAX_FIELDS]; int waiting_children[MAX_TABLES]; int num_rows; struct tuple_t *first; struct tuple_t *last; iterator *iter; int num_paths; struct path_t *paths[MAX_TBL_PATHS]; public: table(database *db, char *tbl_name, char *tbl_abbrev); ~table(); int AddField(char *fld_name, char *data_type, int indexed = FALSE); int AddParent(table *parent, char *parent_fld_name, char *child_fld_name, int parent_card, int child_card); int FindField(char *fld_name, int *fld_num); int FindRel(char *fld_name, int *fld_num); int CreatePath(char *pname); int AddPathNode(int field_num); void Help(); int Print(FILE *fp = NULL); friend class database; friend class iterator; friend class dbinfo; friend class tableinfo; }; // class table class database { protected: char *dbname; int num_tables; table *tables[MAX_TABLES]; int strictly_topdown; error Error; public: database(char *name, char *schema_filename); ~database(); void Define(char *fil_name); void TopDownOnly() { strictly_topdown = TRUE; } int Print(FILE *fp = NULL); int Load(char *fil_name); int Dump(char *fil_name, char *mode = NULL); int Help(); friend class table; friend class iterator; friend class dbinfo; friend class tableinfo; }; // class database class iterator { protected: enum iter_types type; table *tbl; struct tuple_t *curr; int fld_num; public: iterator(table *t); iterator(database *db, char *tbl_name); int Reset(); int Reset(iterator *parent_iter, char *fld_name); int Next(); int Done(); int Append(char *pkey = NULL); int Delete(); int SetParent(char *fld_name, char *value); int Set(char *fld_name, char *value); int Set(char *fld_name, int value); int Set(char *fld_name, float value); int Set(char *fld_name, void *value); int InheritField(char *fld_name, table *tbl, struct tuple_t *curr, int path_num, table **tbl2, struct tuple_t **curr2, int *fld_num); char *PkeyVal(); char *StrVal(char *fld_name, char *path_name = NULL); char *ParentVal(char *fld_name); int IntVal(char *fld_name, char *path_name = NULL); float FloatVal(char *fld_name, char *path_name = NULL); void *UserVal(char *fld_name, char *path_name = NULL); int FindPkey(char *value); int Print(FILE *fp2 = NULL); int AddRow(char *line); void GenNextPkey(char *pkey); friend class database; friend class table; }; // class iterator class dbinfo { protected: database *db; int tbl_num; public: dbinfo(database *db_ptr); void Reset(); void Next(); int Done(); int table_num(); char *table_name(); char *table_abbrev(); int num_rows(); }; // class dbinfo class tableinfo { protected: database *db; int tbl_num; int fld_num; char temp_card[20]; public: tableinfo(database *db_ptr); void Reset(int table_num); int Done(); void Next(); int field_num(); char *field_name(); char field_type(); int data_size(); char data_type(); char *cardinality(); char *parent_table_name(); int parent_table_num(); }; // class tableinfo #endif