/******************************************************************************/ /* File : bdeschema.h */ /* Schema : bdeschema.sch */ /* GENCPP Version : Chgen V 12 - Sathya */ /* Chgen keysize : 8 characters */ /******************************************************************************/ #ifndef __SCHEMA_LOADED #define __SCHEMA_LOADED 1 #include #include #ifdef USE_STL #include #include using namespace std ; #endif /* USE_STL */ #include #define TRUE 1 #define FALSE 0 /******************************************************************************/ /* These macros indicate which version of CHGEN was used to produce this */ /* code, and the command-line qualifiers used as well. */ /******************************************************************************/ #define CHGEN_VERSION "Chgen V 12 - Sathya" #define CHGEN_RELEASE_DATE "Thu Feb 21 19:43:51 GMT 2002" #define CHGEN_QUALIFIERS " -ansi" /******************************************************************************/ /* NOTE: The symbol ## found throughout this include file is called the */ /* identifier concatenation symbol. This symbol is ansi 'C' specific, */ /* and its equivalent in K&R 'C' is the empty comment (which cannot */ /* be typed here, to avoid nested comments). By using this symbol, */ /* macros are able to construct larger identifier names out of smaller */ /* ones. For example, given a table name AA, the AAcurr variable can */ /* be 'referenced' by concatenating AA with curr. This concept is */ /* exploited throughout the macros in this system. */ /******************************************************************************/ /******************************************************************************/ /* This macro will either declare or define the table variables for each */ /* table in the schema. This general approach (#ifdef MAIN) is used often */ /* to distinguish between a main module and a non-main module. In a main, */ /* a definition can occur, and variable initialization can occur. In a non- */ /* main, only a declaration can occur, so the word extern is used. Although */ /* VAX 'C' can handle redundant definitions, several versions of 'C' for UNIX */ /* cannot. */ /******************************************************************************/ #ifndef USE_STL #ifdef MAIN #define hcg_declare(tbl) *tbl##begin = NULL , *tbl##curr = NULL , *tbl##temp = NULL , *tbl##end = NULL , *tbl##elt = NULL,\ *tbl##curr2 = NULL , *tbl##temp2 = NULL; #else #define hcg_declare(tbl) *tbl##begin, *tbl##curr, *tbl##temp, *tbl##end, *tbl##elt, *tbl##curr2, *tbl##temp2; #endif #endif /* USE_STL */ /******************************************************************************/ /* This macro allows the optional insertion of the word 'extern' in various */ /* structures and variables. */ /******************************************************************************/ #ifndef MAIN #define hcg_extern extern #else #define hcg_extern #endif /******************************************************************************/ /* These macros are constants, which are copys of the same constants embedded */ /* in CHGEN. */ /******************************************************************************/ #define SCHEMA_TEXT_FILE_NAME "bdeschema.sch" #define SCHEMA_HEADER_FILE_NAME "bdeschema.h" #define SCHEMA_HEADER_FILE_NAME_LENGTH 100 #define BUFSIZE 256 #define NAMELENGTH 30 #define MAXVIEWS 10 #define MAXVIEWNAMELEN 30 #define ABBREV_NAME_LENGTH 5 #define MAXVERSIONS 99 /******************************************************************************/ /* These macros are based on the schema itself. */ /******************************************************************************/ #define HCG_NUM_TABLES 15 /*----------------------------------------------------------- * * Source File : lut.h * *----------------------------------------------------------- */ #define bool unsigned char #ifndef ERROR #define ERROR -1 #endif #ifndef TRUE #define TRUE (bool) 1 #define FALSE (bool) 0 #endif #define ABBR_SIZE_BIG 4 /* num char in abbr name */ #define VER_SIZE 3 /* num char in version name */ #define ABBR_SIZE_SMALL 2 /* num char in abbr name */ #define ARR_SIZE ABBR_SIZE_BIG #ifdef MAXTABLES #define LUT_NUM_ELEMENTS MAXTABLES #else #define LUT_NUM_ELEMENTS 256 /* max num elements in lut */ #endif #define MAX_VER_ELEMENTS 100 /* max allowed elements in version lut */ #define MAX_VER_NUMBER 999 /* Highest version number allowed... */ typedef struct btree_node_st btree_node_st; /*****************************************************************/ /* the following structure is used as a binary tree node element */ /*****************************************************************/ struct btree_node_st { char name[ARR_SIZE+1]; unsigned char num; int weight; btree_node_st *p_right; /* ptr to right child */ btree_node_st *p_left; /* ptr to left child */ btree_node_st *p_parent; /* ptr to parent */ }; /***********************************/ /* the following structure is used */ /* as a look up table structure */ /***********************************/ typedef char C_TABLE[ARR_SIZE + 1]; typedef enum { ABBR_TBL_TYPE = 777, /* abbreviation table type */ VER_TBL_TYPE /* version number type */ } lut_type; typedef struct { int num_elements; /* num elements currently in lut. */ lut_type type; btree_node_st *p_btree_root; /* ptr to root of btree */ C_TABLE names[LUT_NUM_ELEMENTS]; /* look up table */ }lut_st; /****************************************************/ /* The following decls are for key manipulation. */ /* The key type is defined here as well. */ /****************************************************/ typedef unsigned long hcg_key; #ifndef __cplusplus int encode(); int decode(); void pr_find_bt(char *, hcg_key *); char* decode_retstr(); int key_compare(); char* get_abbr(); int get_version(); int get_row(); int set_abbr(); int set_version(); int set_row(); hcg_key* null_key(); int is_null_key(); int set_external_key_length(); #endif /*__cplusplus*/ /******** End of key manipulation decls ****************/ /******************************************************************************/ /* The following define the btree structures and relative variables for each */ /* table which defines btree search in schema file. */ /******************************************************************************/ #define BTREESEARCH 1 #define SEQUENCESEARCH 0 #define LEFT 2 #define RIGHT 3 extern int SVbtidx; extern int TTbtidx; extern int TAbtidx; extern int VVbtidx; extern int TSbtidx; extern int FObtidx; extern int GDbtidx; extern int HGbtidx; extern int HNbtidx; extern int HAbtidx; extern int HLbtidx; extern int HPbtidx; extern int HIbtidx; extern int CGbtidx; extern int GXbtidx; #ifdef USE_STL extern class SVtable *SVtab; class SV; extern list::iterator SVcurr, SVtemp, SVelt, SVcurr2, SVtemp2; #else extern class SV *SVbegin, *SVcurr, *SVtemp, *SVend, *SVelt, *SVcurr2, *SVtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class TTtable *TTtab; class TT; extern list::iterator TTcurr, TTtemp, TTelt, TTcurr2, TTtemp2; #else extern class TT *TTbegin, *TTcurr, *TTtemp, *TTend, *TTelt, *TTcurr2, *TTtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class TAtable *TAtab; class TA; extern list::iterator TAcurr, TAtemp, TAelt, TAcurr2, TAtemp2; #else extern class TA *TAbegin, *TAcurr, *TAtemp, *TAend, *TAelt, *TAcurr2, *TAtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class VVtable *VVtab; class VV; extern list::iterator VVcurr, VVtemp, VVelt, VVcurr2, VVtemp2; #else extern class VV *VVbegin, *VVcurr, *VVtemp, *VVend, *VVelt, *VVcurr2, *VVtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class TStable *TStab; class TS; extern list::iterator TScurr, TStemp, TSelt, TScurr2, TStemp2; #else extern class TS *TSbegin, *TScurr, *TStemp, *TSend, *TSelt, *TScurr2, *TStemp2; #endif /* USE_STL */ #ifdef USE_STL extern class FOtable *FOtab; class FO; extern list::iterator FOcurr, FOtemp, FOelt, FOcurr2, FOtemp2; #else extern class FO *FObegin, *FOcurr, *FOtemp, *FOend, *FOelt, *FOcurr2, *FOtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class GDtable *GDtab; class GD; extern list::iterator GDcurr, GDtemp, GDelt, GDcurr2, GDtemp2; #else extern class GD *GDbegin, *GDcurr, *GDtemp, *GDend, *GDelt, *GDcurr2, *GDtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HGtable *HGtab; class HG; extern list::iterator HGcurr, HGtemp, HGelt, HGcurr2, HGtemp2; #else extern class HG *HGbegin, *HGcurr, *HGtemp, *HGend, *HGelt, *HGcurr2, *HGtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HNtable *HNtab; class HN; extern list::iterator HNcurr, HNtemp, HNelt, HNcurr2, HNtemp2; #else extern class HN *HNbegin, *HNcurr, *HNtemp, *HNend, *HNelt, *HNcurr2, *HNtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HAtable *HAtab; class HA; extern list::iterator HAcurr, HAtemp, HAelt, HAcurr2, HAtemp2; #else extern class HA *HAbegin, *HAcurr, *HAtemp, *HAend, *HAelt, *HAcurr2, *HAtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HLtable *HLtab; class HL; extern list::iterator HLcurr, HLtemp, HLelt, HLcurr2, HLtemp2; #else extern class HL *HLbegin, *HLcurr, *HLtemp, *HLend, *HLelt, *HLcurr2, *HLtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HPtable *HPtab; class HP; extern list::iterator HPcurr, HPtemp, HPelt, HPcurr2, HPtemp2; #else extern class HP *HPbegin, *HPcurr, *HPtemp, *HPend, *HPelt, *HPcurr2, *HPtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class HItable *HItab; class HI; extern list::iterator HIcurr, HItemp, HIelt, HIcurr2, HItemp2; #else extern class HI *HIbegin, *HIcurr, *HItemp, *HIend, *HIelt, *HIcurr2, *HItemp2; #endif /* USE_STL */ #ifdef USE_STL extern class CGtable *CGtab; class CG; extern list::iterator CGcurr, CGtemp, CGelt, CGcurr2, CGtemp2; #else extern class CG *CGbegin, *CGcurr, *CGtemp, *CGend, *CGelt, *CGcurr2, *CGtemp2; #endif /* USE_STL */ #ifdef USE_STL extern class GXtable *GXtab; class GX; extern list::iterator GXcurr, GXtemp, GXelt, GXcurr2, GXtemp2; #else extern class GX *GXbegin, *GXcurr, *GXtemp, *GXend, *GXelt, *GXcurr2, *GXtemp2; #endif /* USE_STL */ extern hcg_key key1, key2; hcg_extern char tempbtree[BUFSIZE]; hcg_extern hcg_key btfinish,btresult; /******************************************************************************/ /* This structure holds all information about a single view. Version list */ /* is really a list of numbers, but since version numbers are in the range */ /* 01->99, they can be stored in a single byte. This was done to minimize */ /* the storage requirements of internal structures. In the future, even if */ /* the 2-character version number embedded inside key fields becomes a 2-digit*/ /* hexadecimal value, it can still be stored in a single byte. */ /******************************************************************************/ struct view_elt_type { char view_name[MAXVIEWNAMELEN]; char mode; char version_list[HCG_NUM_TABLES]; } ; /******************************************************************************/ /* This structure variable holds all information about all views that have */ /* been defined (by calling pr_init). */ /******************************************************************************/ hcg_extern struct hcg_view_list_type { int num_views; struct view_elt_type view_list[MAXVIEWS]; } hcg_view_list; /******************************************************************************/ /* This structure holds all table-statistics maintained for a single table */ /* at a single version. Currently, only rcount (number of rows in this table */ /* at this version), and maxrow (highest embedded row-number for this table/ */ /* version). While the code depends heavily on max-row (specifically, for */ /* generating pkeys), the rcount value is maintained for users who may need */ /* it (via the pr_rcount() macro). */ /******************************************************************************/ struct ts_list_elt_type { int maxrow; int rcount; }; /******************************************************************************/ /* This structure holds all table-statistics structs (see above) for each */ /* version that could exist for a single table. The value 100 would have */ /* to be changed if hexadecimal version numbers were introduced. */ /******************************************************************************/ struct ts_list_type { struct ts_list_elt_type ts_list[MAXVERSIONS]; }; /******************************************************************************/ /* This structure variable holds all table-statistics information for all */ /* tables, and for each possible version of them. */ /******************************************************************************/ hcg_extern struct ts_list_type hcg_ts_list[HCG_NUM_TABLES]; /******************************************************************************/ /* This structure is used to simplify type casting pointers within table */ /* rows. */ /******************************************************************************/ struct dummy_type { int dummy ; } ; /******************************************************************************/ /* This following is a type definition for generic porinters */ /******************************************************************************/ #ifdef __STDC__ typedef void * hcg_ptr; #else typedef char * hcg_ptr; #endif extern hcg_ptr pr_gen_create(); //#define pr_create(tbl_abbr) \ // (struct tbl_abbr *) pr_gen_create( sizeof( struct tbl_abbr)) /******************************************************************************/ /* This following macros are used to get/set table fields. */ /******************************************************************************/ /* BEGIN MODIFICATION, ctwang, 12/20/97 */ #define pr_set_int(tbl,fld,value) \ do{\ if((tbl)->get_##RFLAG()==1 && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_INT %s %s %d\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ }\ (tbl)->set_##fld(value); \ }while(0) #define pr_set_flt(tbl,fld,value) \ do{\ if((tbl)->get_##RFLAG()==1 && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_FLT %s %s %f\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ }\ (tbl)->set_##fld(value); \ }while(0) #define pr_set_key(tbl,fld,value) \ do{\ if((tbl)->get_##RFLAG()==1 && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_KEY %s %s %s\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", decode_retstr(value) );\ }\ (tbl)->set_##fld(value); \ }while(0) #define pr_set_str(tbl,fld,value) \ do{\ if ( strlen(value) >= sizeof((tbl)->fld) ) \ fprintf(stderr, \ "Warning: field %s in table %s is too long- truncated\n", "fld", "tbl");\ if((tbl)->get_##RFLAG()==1 && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_STR %s %s %s\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ } \ (tbl)->set_##fld(value); \ }while(0) /* END MODIFICATION, ctwang, 12/20/97 */ #ifndef USE_STL #define pr_get_int(tbl,fld) (tbl)->fld #define pr_get_flt(tbl,fld) (tbl)->fld #define pr_get_str(tbl,fld) (tbl)->fld #define pr_get_key(tbl,fld) (tbl)->fld #endif /* USE_STL */ #define pr_set_default(val) hcg_default_fkey = (val) #define pr_get_default(val) hcg_default_fkey /******************************************************************************/ /* This following variables are for internal use only. Users should never */ /* modify them, and should never have a need to use them. Again, either */ /* a definition or a declaration will actually be compiled. */ /******************************************************************************/ #define HCG_KEY_SIZE 8 #define HCG_ABBR_SIZE 2 #ifdef MAIN hcg_key hcg_k; /* Temp var to hold integer version of character keys */ lut_st hcg_table_abbrev_lut;/* Holds lookup table of table abbrev's and indexes */ int hcg_initialized = 0; /* Has pr_init been called yet ? */ int hcg_default_fkey = 0; /* default pkey assignment flag */ int hcg_version = 0; /* Temp var to hold version number of key in question */ int hcg_row = 0; /* Temp var to hold row number of key in question */ int hcg_tbl_idx = 0; /* Integer mapping of table abbrev, used extensively */ int hcg_view_idx = 0; /* Integer mapping of view name, used extensively */ int hcg_log; /* Integer indicating log on (1) off (0) replay (2) */ char hcg_buffer[BUFSIZE]; /* File read buffer (holds one line) */ char hcg_t[BUFSIZE]; /* Holds a parsed key value. */ char hcg_logfile[NAMELENGTH]; /* File name of log file */ char hcg_viewname[NAMELENGTH] = "\0"; /* Last viewname used by pr_add */ FILE *hcg_ascii_fp; /* File variable for any data file or viewdef file */ FILE *hcg_dump_fp; /* File variable for output data files */ FILE *hcg_logfileptr; /* File variable for hcg_logfile */ FILE *hcg_stats_fp; /* File variable for output statistics files */ #else extern hcg_key hcg_k; extern lut_st hcg_table_abbrev_lut; extern int hcg_initialized; extern int hcg_default_fkey; extern int hcg_version; extern int hcg_row; extern int hcg_tbl_idx; extern int hcg_view_idx; extern int hcg_log; extern char hcg_buffer[BUFSIZE]; extern char hcg_t[BUFSIZE]; extern char hcg_logfile[NAMELENGTH]; extern char hcg_viewname[NAMELENGTH]; extern FILE *hcg_ascii_fp; extern FILE *hcg_dump_fp; extern FILE *hcg_logfileptr; extern FILE *hcg_stats_fp; #endif /******************************************************************************/ /* This structure variable holds all general information and global statistics*/ /* for each table in the schema. It also populates the structure with the */ /* table abbrevs. */ /******************************************************************************/ hcg_extern struct hcg_table_seq_list_type { char ttabbrev[ABBREV_NAME_LENGTH] ; int rcount ; int maxver ; } hcg_table_seq_list[15] #ifdef MAIN = { "SV",0,0, "TT",0,0, "TA",0,0, "VV",0,0, "TS",0,0, "FO",0,0, "GD",0,0, "HG",0,0, "HN",0,0, "HA",0,0, "HL",0,0, "HP",0,0, "HI",0,0, "CG",0,0, "GX",0,0 } #endif ; /******************************************************************************/ /* This set of macros defines an integer mapping for each table. This value */ /* is used as an array index in various structures. */ /* The table hcg_table_abbrev_lut contains the index values for each table */ /******************************************************************************/ #define SV_idx 0 #define TT_idx 1 #define TA_idx 2 #define VV_idx 3 #define TS_idx 4 #define FO_idx 5 #define GD_idx 6 #define HG_idx 7 #define HN_idx 8 #define HA_idx 9 #define HL_idx 10 #define HP_idx 11 #define HI_idx 12 #define CG_idx 13 #define GX_idx 14 /******************************************************************************/ /* This macro will delete the 'current' row from the specified table. It */ /* also helps ensure data integrity by going out and null-ing any pointers to */ /* this row in any parent and child tables. The actual work, however, is */ /* done in pr_del (see pr_delete.c), which also calls del_row and the */ /* unlink_xxx macros. */ /* */ /* NOTE: The 'current' row (AAcurr for example) is left undefined after this */ /* call. */ /* */ /******************************************************************************/ #ifndef USE_STL #define pr_delete(tbl) pr_del(tbl##_idx) #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used to generate a unique number based on the 2-char */ /* table abbreviation. It also converts the characters to upper-case if not */ /* already. The number mapping is a base-26 system, (A=0, Z=25). For example,*/ /* AA maps to 0, while BB maps to 27 ((1*26) + 1). */ /******************************************************************************/ #define encoding(s) (lut_insert_element(&hcg_table_abbrev_lut, s)) /******************************************************************************/ /* This macro is used to determine the highest embedded row number (last 4 */ /* digits in a key value), for the specified table, under the specified view. */ /******************************************************************************/ #define pr_maxkey(viewname,tbl) \ (find_view_idx(viewname) ? \ hcg_ts_list[tbl##_idx].ts_list[hcg_view_list.view_list[hcg_view_idx].version_list[tbl##_idx]].maxrow : \ 0) /******************************************************************************/ /* This macro is used to determine the number of rows currently loaded in the */ /* entire specified table. This includes all versions. */ /******************************************************************************/ #define pr_rcount_all(tbl) hcg_table_seq_list[tbl##_idx].rcount /******************************************************************************/ /* This macro is used to determine the number of rows currently loaded in the */ /* specified table, using the specified view (ie, only one version). */ /******************************************************************************/ #define pr_rcount(viewname,tbl) \ (find_view_idx(viewname) ? \ hcg_ts_list[tbl##_idx].ts_list[hcg_view_list.view_list[hcg_view_idx].version_list[tbl##_idx]].rcount : \ 0) /******************************************************************************/ /* This macro is used to determine if the specified child exists under the */ /* specified parent. */ /******************************************************************************/ #ifndef USE_STL #define child_exists(parent,child) ((child##curr != NULL) && ((struct parent *) child##curr) != (parent##curr)) #endif /* USE_STL */ /******************************************************************************/ /* This macro is used to begin a traversal of the specified child chain under */ /* the specified parent. The actual chain followed is indicated by the fkey. */ /******************************************************************************/ #ifndef USE_STL #define start_child_chain(parent,child,fkey) child##curr = parent##curr->fkey##_fcp #endif /* USE_STL */ /******************************************************************************/ /* This macro is used to continue a child traversal started by start_child_ */ /* chain (see above). */ /******************************************************************************/ #ifndef USE_STL #define next_child(child,fkey) child##curr = (struct child *) child##curr->fkey##_fpp #endif /* USE_STL */ /******************************************************************************/ /* This macro will determine if any rows exist for the specified table. */ /* This should always be equivalent to (pr_rcount_all(tbl) != 0) if integrity */ /* is maintained. */ /******************************************************************************/ #ifndef USE_STL #define exists(tbl) (tbl##curr) #endif /* USE_STL */ /******************************************************************************/ /* This macro is used to begin a traversal of the specified entire table. */ /* This includes all versions. */ /******************************************************************************/ #ifndef USE_STL #define start_chain_all(tbl) tbl##curr = tbl##begin #endif /* USE_STL */ /******************************************************************************/ /* This macro is used to continue a full table traversal, started by start_ */ /* chain_all (see above). */ /******************************************************************************/ #ifndef USE_STL #define next_all(tbl) tbl##curr = tbl##curr->next_ptr #endif /* USE_STL */ /******************************************************************************/ /* This macro will determine if the specified child is the first in the child */ /* chain under the specified parent. */ /******************************************************************************/ #ifndef USE_STL #define first_child(parent,child,pkey) (parent##curr->pkey##_fcp == child##curr) #endif /* USE_STL */ /******************************************************************************/ /* This macro will determine if the specified child is the last in the child */ /* chain under the specified parent. */ /******************************************************************************/ #ifndef USE_STL #define last_child(parent,child,ckey) ((class parent *) child##curr->ckey##_fpp == parent##curr) #endif /* USE_STL */ /******************************************************************************/ /* The macro defines pr_dump_row() as dump_row(). */ /******************************************************************************/ #ifndef USE_STL #define pr_dump_row(tbl,viewname,file_name,new_version,modestr) dump_row(#tbl,viewname,file_name,new_version,modestr) #endif /* USE_STL */ extern int open_file; /******************************************************************************/ /* This macro is used to add the row into a binary tree. It is for internal */ /* use to build a binary tree. */ /******************************************************************************/ #define btree_add_row(tbl) \ tbl##btelt = (struct tbl##btree *)malloc( sizeof(struct tbl##btree) ); \ tbl##btelt->ptr = tbl##elt; \ tbl##btelt->key = tbl##elt->get_pkid(); \ tbl##btelt->parent = NULL; \ tbl##btelt->left = NULL; \ tbl##btelt->right = NULL; \ btfinish = FALSE; \ btresult = -1; \ tbl##bttemp = tbl##btroot; \ while( tbl##bttemp != NULL && btfinish == FALSE) \ { \ btresult = key_compare(&tbl##btelt->key,&tbl##bttemp->key); \ if( btresult == 0 ) \ { \ printf("Error: duplicate pkey in building pr_find btree.\n"); \ exit(3); \ } \ else if ( btresult < 0 ) \ { \ if( tbl##bttemp->left == NULL ) \ btfinish = LEFT ; \ else \ tbl##bttemp = tbl##bttemp->left; \ } \ else \ { \ if( tbl##bttemp->right == NULL ) \ btfinish = RIGHT ; \ else \ tbl##bttemp = tbl##bttemp->right; \ } \ } \ if ( btfinish == FALSE ) \ tbl##btroot = tbl##btelt; \ else if( btfinish == LEFT ) \ { \ tbl##bttemp->left = tbl##btelt; \ tbl##btelt->parent = tbl##bttemp; \ } \ else \ { \ tbl##bttemp->right = tbl##btelt; \ tbl##btelt->parent = tbl##bttemp; \ } /******************************************************************************/ /* This macro is used to locate the row in the specified table whose primary */ /* key is the one specified. */ /******************************************************************************/ #ifndef USE_STL #define pr_find(tbl,pkey,value) \ if( tbl##btidx == BTREESEARCH ) \ { \ sprintf(tempbtree, #tbl); \ tempbtree[HCG_ABBR_SIZE]='\0'; \ pr_find_bt(tempbtree,&value); \ } \ else \ for (tbl##curr = tbl##begin; (tbl##curr != NULL) && (key_compare1(tbl##curr->get_pkid(),value) < 0); tbl##curr = tbl##curr->next_ptr); \ if ((tbl##curr != NULL) && (key_compare1(tbl##curr->get_pkid(),value) != 0)) \ tbl##curr = NULL #endif /* USE_STL */ /******************************************************************************/ /* This looping macro will traverse the entire table (ie, all versions), */ /* stopping at each row whose specified string field equals the specified */ /* string value. */ /******************************************************************************/ #ifndef USE_STL #define find_str_loop_all(tbl,field,value) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (strcmp(trim(tbl##curr->get_##field()),value) == 0) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro is the same as find_str_loop_all, but uses a view. */ /******************************************************************************/ #ifndef USE_STL #define find_str_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->get_pkid())) &&\ (strcmp(trim(tbl##curr->get_##field()),value) == 0)) #endif /* USE_STL */ /******************************************************************************/ #ifndef USE_STL #define find_key_loop_all(tbl,field,value) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (key_compare1(tbl##curr->get_pkid(), value) == 0) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro is the same as find_key_loop_all, but uses a view. */ /******************************************************************************/ #ifndef USE_STL #define find_key_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->get_pkid())) &&\ (key_compare1(tbl##curr->get_pkid(),value) == 0)) #endif /* USE_STL */ /******************************************************************************/ #ifndef USE_STL #define find_fkey_loop_all(tbl,field,value) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (key_compare1(tbl##curr->get_##field(), value) == 0) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro is the same as find_fkey_loop_all, but uses a view. */ /******************************************************************************/ #ifndef USE_STL #define find_fkey_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->get_pkid())) &&\ (key_compare1(tbl##curr->get_##field(),value) == 0)) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro is identical to find_str_loop_all, except that integer */ /* fields and values are used. */ /******************************************************************************/ #ifndef USE_STL #define find_int_loop_all(tbl,field,value) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (tbl##curr->get_##field() == value) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro is identical to find_int_loop_all, but uses a view. */ /******************************************************************************/ #ifndef USE_STL #define find_int_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->get_pkid())) &&\ (tbl##curr->get_##field() == value)) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro will traverse all children of a parent, stopping at */ /* each child row. */ /******************************************************************************/ #ifndef USE_STL #define child_loop(parent,child,pkey,ckey) \ for (child##curr = parent##curr->pkey##_fcp; \ ((child##curr != NULL) && ((parent *) child##curr) != (parent##curr)); \ child##curr = (child *) child##curr->ckey##_fpp) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro will traverse the entire specified table (ie, all */ /* versions), stopping at every row. */ /******************************************************************************/ #ifndef USE_STL #define table_loop_all(tbl) for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) #endif /* USE_STL */ /******************************************************************************/ /* This looping macro will traverse the specified table, stopping at every */ /* row that that meets the view (based on version number). */ /******************************************************************************/ #ifndef USE_STL #define table_loop(viewname,tbl) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##begin; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if (meets_view(tbl##_idx,hcg_view_idx,tbl##curr->get_pkid())) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to pr_find, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define pr_var_find(tbl,tblvar,pkey,value) \ for (tblvar = tbl##begin; (tblvar != NULL) && (key_compare1(tblvar->get_pkid(),value) < 0); tblvar = tblvar->next_ptr); \ if ((tblvar != NULL) && (key_compare1(tblvar->get_pkid(),value) != 0)) \ tblvar = NULL #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to find_str_loop_all, except that the user can */ /* specify his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_find_str_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr)\ if (strcmp(trim(tblvar->get_##field()),value) == 0) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to find_str_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_find_str_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tblvar->get_pkid())) &&\ (strcmp(trim(tblvar->get_##field()),value) == 0)) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to find_int_loop_all, except that the user can */ /* specify his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_find_int_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr) \ if (tblvar->get##field() == value) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to var_find_int_loop_all, but uses a view. */ /* specify his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_find_int_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tblvar->get_pkid())) &&\ (tblvar->get_##field() == value)) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to child_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_child_loop(tbl,parent,pkey,tbl2,child,ckey) \ for (child = parent->pkey##_fcp; \ ((child != NULL) && ((tbl *) child) != (parent)); \ child = (tbl2 *) child->ckey##_fpp) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to table_loop_all, except that the user can specify*/ /* his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_table_loop_all(tbl,tblvar) for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to table_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #ifndef USE_STL #define var_table_loop(viewname,tbl,tblvar) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##begin; tblvar != NULL; tblvar = tblvar->next_ptr)\ if (meets_view(tbl##_idx,hcg_view_idx,tblvar->get_pkid())) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to first_child, except that the user can specify */ /* his/her own parent and child pointer variables. */ /******************************************************************************/ #ifndef USE_STL #define var_first_child(tbl,parent,child,pkey) (parent->pkey##_fcp == child) #endif /* USE_STL */ /******************************************************************************/ /* This macro is identical to last_child, except that the user can specify */ /* his/her own parent and child pointer variables. */ /******************************************************************************/ #ifndef USE_STL #define var_last_child(tbl,parent,child,ckey) ((tbl *) child->ckey##_fpp == parent) #endif /* USE_STL */ /******************************************************************************/ /* Macro for checking error in file writes */ /******************************************************************************/ #define PrintCheck(x) if((x) == -1) { printf("Error in outputing file. Exiting\n"); exit(1);} #ifdef USE_STL #undef link_parent_bp_m /* We use 'this' ptr in place of ca##curr */ #define link_parent_bp_m(ca,pa,cf,pk,p,c) \ for (pa##curr2 = pa##tab->getFirstRow(); pa##curr2 != pa##tab->Terminator() && (key_compare1((*pa##curr2)->get_pkid(),this->get_##cf()) < 0); pa##curr2++); \ if ((pa##curr2 != pa##tab->Terminator()) && (key_compare1(this->get_##cf(),(*pa##curr2)->get_pkid()) == 0)) \ { \ this->setParent_##p((*pa##curr2)); \ (*pa##curr2)->insertChild_##c(this); \ } #undef link_parent_nobp_m #define link_parent_nobp_m(ca,pa,cf,pk,p,c) \ link_parent_bp_m(ca,pa,cf,pk,p,c) #undef link_parent_1 #define link_parent_1(ca,pa,cf,pk,p,c) \ link_parent_bp_m(ca,pa,cf,pk,p,c) #undef unlink_parent_bp_m /* ca##curr is an iterator that is set in ca::delete_row */ #define unlink_parent_bp_m(ca,pa,p,c) \ if(getParent_##p() != NULL) \ (getParent_##p())->removeChild_##c(ca##curr); #undef unlink_parent_nobp_m #define unlink_parent_nobp_m(ca,pa,p,c) \ unlink_parent_bp_m(ca,pa,p,c) #undef unlink_parent_1 #define unlink_parent_1(ca,pa,p,c) \ unlink_parent_bp_m(ca,pa,p,c) #undef start_child_chain #define start_child_chain(parent,child,fkey) \ child##curr = (*parent##curr)->getFirstChild_##fkey() #undef next_child #define next_child(child,fkey) \ child##curr++ #undef child_loop #define child_loop(parent,child,pkey,ckey) \ for(start_child_chain(parent,child,pkey); child##curr != (*parent##curr)->pkey##_Terminator(); \ next_child(child,pkey)) #undef first_child #define first_child(parent,child,pkey) \ ((*(*parent##curr)->getFirstChild_##pkey()) == (*child##curr)) #undef last_child #define last_child(parent,child,pkey) \ ((*(((*parent##curr)->getLastChild_##pkey()))) == (*child##curr)) #undef var_child_loop #define var_child_loop(tbl,parent,pkey,tbl2,child,ckey) \ for ( child = (*parent)->getFirstChild_##pkey(); \ child != (*parent)->pkey##_Terminator(); \ child++) #undef var_first_child #define var_first_child(tbl,parent,child,pkey) \ ((*(*parent)->getFirstChild_##pkey()) == (*child)) #undef var_last_child #define var_last_child(tbl,parent,child,ckey) \ ((*(((*parent)->getLastChild_##pkey()))) == (*child)) #undef unlink_child_bp_m #define unlink_child_bp_m(ca,pa,p,c) \ while(this->getFirstChild_##c() != this->c##_Terminator()) \ { \ (*getFirstChild_##c())->setParent_##p##(NULL); \ removeChild_##c( getFirstChild_##c() ) ; \ } #undef unlink_child_nobp_m #define unlink_child_nobp_m(ca,pa,p,c) \ unlink_child_bp_m(ca,pa,p,c) #undef unlink_child_1 #define unlink_child_1(ca,pa,p,c) \ unlink_child_bp_m(ca,pa,p,c) #undef link_child_bp_m /* we use 'this' ptr in place of pa##curr */ #define link_child_bp_m(ca,pa,cf,pk,p,c) \ ca##curr2 = ca##tab->getFirstRow(); \ while(ca##curr2 != ca##tab->Terminator()) \ { \ if (key_compare1((*ca##curr2)->get_##cf(),this->get_pkid()) == 0) \ { \ (*ca##curr2)->setParent_##p(this);\ insertChild_##c((*ca##curr2)); \ } \ ca##curr2++; \ } #undef link_child_nobp_m #define link_child_nobp_m(ca,pa,cf,pk,p,c) \ link_child_bp_m(ca,pa,cf,pk,p,c) #undef link_child_1 #define link_child_1(ca,pa,cf,pk,p,c) \ link_child_bp_m(ca,pa,cf,pk,p,c) #undef insert_element #undef del_row #undef free_table #undef start_chain_all #define start_chain_all(tbl) tbl##curr = tbl##tab->getFirstRow() #undef next_all #define next_all(tbl) tbl##curr++ #undef pr_find #define pr_find(tbl,pkey,value) \ if( tbl##btidx == BTREESEARCH ) \ { \ sprintf(tempbtree, #tbl); \ tempbtree[HCG_ABBR_SIZE]='\0'; \ pr_find_bt(tempbtree,&value); \ } \ else \ for (tbl##curr = tbl##tab->getFirstRow(); (tbl##curr != tbl##tab->Terminator()) && (key_compare1((*tbl##curr)->get_pkid(),value) < 0); tbl##curr++); \ if ((tbl##curr != tbl##tab->Terminator()) && (key_compare1((*tbl##curr)->get_pkid(),value) != 0)) \ tbl##curr = tbl##tab->Terminator() #undef find_str_loop_all #define find_str_loop_all(tbl,field,value) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if (strcmp(trim((*tbl##curr)->get_##field()),value) == 0) #undef find_str_loop #define find_str_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); (tbl##curr != tbl##tab->Terminator()) ? tbl##curr++ : tbl##curr) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tbl##curr)->get_pkid())) &&\ (strcmp(trim((*tbl##curr)->get_##field()),value) == 0)) #undef find_key_loop_all #define find_key_loop_all(tbl,field,value) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if (key_compare1((*tbl##curr)->get_pkid(), value) == 0) #undef find_key_loop #define find_key_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tbl##curr)->get_pkid())) &&\ (key_compare1((*tbl##curr)->get_pkid(),value) == 0)) #undef find_fkey_loop_all #define find_fkey_loop_all(tbl,field,value) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if (key_compare1((*tbl##curr)->get_##field(), value) == 0) #undef find_fkey_loop #define find_fkey_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tbl##curr)->get_pkid())) &&\ (key_compare1((*tbl##curr)->get_##field(),value) == 0)) #undef find_int_loop_all #define find_int_loop_all(tbl,field,value) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if ((*tbl##curr)->get_##field() == value) #undef find_int_loop #define find_int_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tbl##curr)->get_pkid())) &&\ ((*tbl##curr)->get_##field() == value)) #undef table_loop_all #define table_loop_all(tbl) for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) #undef table_loop #define table_loop(viewname,tbl) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl##tab->getFirstRow(); tbl##curr != tbl##tab->Terminator(); tbl##curr++) \ if (meets_view(tbl##_idx,hcg_view_idx,(*tbl##curr)->get_pkid())) #undef pr_var_find #define pr_var_find(tbl,tblvar,pkey,value) \ for (tblvar = tbl##tab->getFirstRow(); (tblvar != tbl##tab->Terminator()) && (key_compare1((*tblvar)->get_pkid(),value) < 0); tblvar++); \ if ((tblvar != tbl##tab->Terminator()) && (key_compare1((*tblvar)->get_pkid(),value) != 0)) \ tblvar = tbl##tab->Terminator() #undef var_find_str_loop_all #define var_find_str_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) \ if (strcmp(trim((*tblvar)->get_##field()),value) == 0) #undef var_find_str_loop #define var_find_str_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tblvar)->get_pkid())) &&\ (strcmp(trim((*tblvar)->get_##field()),value) == 0)) #undef var_find_int_loop_all #define var_find_int_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) \ if ((*tblvar)->get##field() == value) #undef var_find_int_loop #define var_find_int_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) \ if ((meets_view(tbl##_idx,hcg_view_idx,(*tblvar)->get_pkid())) &&\ ((*tblvar)->get_##field() == value)) #undef var_table_loop_all #define var_table_loop_all(tbl,tblvar) for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) #undef var_table_loop #define var_table_loop(viewname,tbl,tblvar) \ if (find_view_idx(viewname)) \ for (tblvar = tbl##tab->getFirstRow(); tblvar != tbl##tab->Terminator(); tblvar++) \ if (meets_view(tbl##_idx,hcg_view_idx,(*tblvar)->get_pkid())) #undef pr_check_fkey /* ctbl_ptr is a row pointer not an iterator */ #define pr_check_fkey(ctbl_abbr,ctbl_ptr,ckey,ptbl_abbr,pkey,ptbl_ptr) \ ptbl_ptr = ptbl_abbr##tab->getFirstRow(); \ key1 = ctbl_ptr->get_##ckey(); \ key2 = (*ptbl_ptr)->get_pkid(); \ if ( is_null_key(&key1) || key1 == 0 ) {\ if (!hcg_default_fkey) {\ printf("Warning: foreign key %s is not set for table %s element 0x%8.8x\n", \ #ckey, #ctbl_abbr, ctbl_ptr );\ pr_gen_key( ckey,#ptbl_abbr, 0, 0);\ }\ else if ((ptbl_ptr != ptbl_abbr##tab->Terminator()) && ( !is_null_key(&key2) ) && ( key2 != 0) ) {\ ctbl_ptr->set_##ckey (key2);\ }\ else {\ pr_gen_key( ckey, #ptbl_abbr, 0, 0);\ }\ } #undef pr_check_str #define pr_check_str(tbl_abbr,not_used,fld,length) \ if ( fld[0] == '\0' ) \ {\ int i = sizeof(fld) - 2;\ printf("Warning: string field %s is not set for table %s element 0x%8.8x\n", \ #fld, #tbl_abbr, this);\ for(fld[i] = '\0'; i>=0; fld[i--] = '?');\ } #undef child_exists #undef exists #define exists(tbl) (tbl##tab->getRowCount()) #endif /* USE_STL */ /* C function prototypes for the C++ compiler */ #ifdef __cplusplus extern "C" { extern int find_tbl_idx(char *); extern int find_view_idx(char *); /* extern int encode(hcg_key *, char *); */ extern int encode( char *, hcg_key * ); extern void pr_find_bt(char *, hcg_key *); extern char *decode_retstr(hcg_key *); extern int decode(char *, hcg_key *); extern int key_compare(hcg_key *, hcg_key *); extern int key_compare1(hcg_key, hcg_key); extern char *get_abbr(hcg_key *, char *); extern int get_version(hcg_key *); extern int get_row(hcg_key *); extern int set_abbr(hcg_key *, char *); extern int set_version(hcg_key *, int); extern int set_row(hcg_key *, int); extern hcg_key *null_key(void); extern int is_null_key(hcg_key *); extern void pr_init (char *, char *); extern hcg_ptr pr_gen_create(int); extern void pr_load(char *, char *); extern void pr_del(int); extern void pr_free(void); extern void pr_stats(char *, char *); extern void pr_dump(char *, char *, int, char *); extern int btree_does_node_exist(btree_node_st *, char *); extern void btree_initialized() ; extern int btree_create(lut_st *); extern int btree_insert_node(btree_node_st **, char *, int ); extern int btree_destroy(btree_node_st *, btree_node_st *); extern int btree_wt(btree_node_st *); extern int get_version (hcg_key *); extern void pr_parse (char *, char *, int , int , hcg_key ); extern int meets_view(int , int , hcg_key ) ; extern int lut_insert_element(lut_st *, char *); extern void hcg_update_version(hcg_key *, int , int ); extern void pr_del_bt(char *, hcg_key ) ; extern void logwait(); extern void logstr(char *); extern void hcg_read_next() ; extern void hcg_parse(char *, char *, int *); extern void mystrcpy(char *, char *, int , int ); extern int pr_startlog (char *, char *); extern int pr_stoplog (char *, int dump_flag); extern int pr_replay(char *, char *logfile, int , int ); extern void dup_row_warning(hcg_key pkey) ; extern void pr_link (int ) ; extern void strncpy_null(char *, char *, int); extern int find_tbl_idx(char *); extern int decode( char *, hcg_key *); extern void pr_init ( char *, char *); extern void pr_free(); extern int log_sleep(int); extern int pr_startlog (char *, char *); extern void del_tempfiles(char *); /* extern void log_pr_add (char *, char *, hcg_ptr ); ntansala */ extern void logstr(char *); extern void logwait(); extern char* trim(char *); extern void forward_ref_warning(hcg_key ,hcg_key ); } #endif /******************************************************************************/ /* The following comment is simply a listing of the parent<-->child pairs */ /* found by CHGEN for the schema. The format is : */ /* */ /* parent:child has-bp singleton */ /* */ /* Where parent is the foreign key to the parent, as stored in the child */ /* and child is the implied foreign key to the child, as stored in the parent */ /* and has-bp indicates whether back-pointers along this relationship are */ /* maintained. The singleton falg indicates if this child is supposed to be */ /* the only-child under this parent (ie, no chain, usually occurs with an */ /* is-a relation). Having this flag set minimizes the code generated to */ /* link and manage children of this type. */ /* */ /******************************************************************************/ /* CGid:GXid 1 0 HGid:CGid 1 0 HGid:HNid 1 0 HLid:HIid 1 0 HLid:HPid 1 0 HNid:HAid 1 0 HNid1:HLid1 1 0 HNid2:HLid2 1 0 SVid:VVid 1 0 SVid:TTid 1 0 TTid:TSid 1 0 TTid:TAid 1 0 VVid:TSid 1 0 */ /******************************************************************************/ /* The following comment is simply a listing of the child<-->parent pairs */ /* found by CHGEN for the schema. The format is the same as the parent<--> */ /* child listing, and is simply the reverse of that listings content. */ /******************************************************************************/ /* CGid:HGid 1 0 GXid:CGid 1 0 HAid:HNid 1 0 HIid:HLid 1 0 HLid1:HNid1 1 0 HLid2:HNid2 1 0 HNid:HGid 1 0 HPid:HLid 1 0 TAid:TTid 1 0 TSid:TTid 1 0 TSid:VVid 1 0 TTid:SVid 1 0 VVid:SVid 1 0 */ /******************************************************************************/ /* The following macros are called access macros. Each macro represents */ /* a path upwards through the schema from the first listed table (the child) */ /* to the second listed table (the parent). Actually, the parent could be */ /* an ancestor (grandparent, etc...). The macro itself is designed to be */ /* used in code where the user would normally type in a potentially long */ /* structure access statement, up along xxid_pp pointers. The macros not only*/ /* minimize typing and chances of error, they also give the user a very small */ /* degree of data independence. For example, if a new table is developed and */ /* is placed between two tables in the original schema, the macros will */ /* reflect the change, and the user does not have to change any code. */ /* One major restriction is that a macro will only be generated if the path */ /* is unique. However, access macros can be compounded together, letting */ /* the user specify what to do to get around a point of ambiguity in the */ /* parent chain. */ /******************************************************************************/ #ifndef USE_STL #define TT__SV SVid_pp #define TA__SV TTid_pp->SVid_pp #define TA__TT TTid_pp #define VV__SV SVid_pp #define TS__TT TTid_pp #define TS__VV VVid_pp #define HN__HG HGid_pp #define HA__HG HNid_pp->HGid_pp #define HA__HN HNid_pp #define HP__HL HLid_pp #define HI__HL HLid_pp #define CG__HG HGid_pp #define GX__HG CGid_pp->HGid_pp #define GX__CG CGid_pp /* Not implemented for USE_STL yet */ #endif /* USE_STL */ /******************************************************************************/ /* This macro is used to generate the next available primary key value for the*/ /* specified table, using the specified view. */ /******************************************************************************/ #define pr_gen_key(key,tbl_abbrv,version_id,entry_id) \ (key) = *null_key();\ set_abbr(&(key), (tbl_abbrv));\ set_version(&(key), (version_id));\ set_row(&(key), (entry_id)) #define pr_gen_pkey(viewname,tbl,pkey) \ if (find_view_idx(viewname)) \ pr_gen_key(pkey,hcg_table_seq_list[tbl##_idx].ttabbrev, \ (char) hcg_view_list.view_list[hcg_view_idx].version_list[tbl##_idx], \ hcg_ts_list[tbl##_idx].ts_list[hcg_view_list.view_list[hcg_view_idx].version_list[tbl##_idx]].maxrow+1) #ifndef USE_STL #define pr_check_fkey(ctbl_abbr,ctbl_ptr,ckey,ptbl_abbr,pkey,ptbl_ptr) \ key1 = ctbl_ptr->get_##ckey(); \ key2 = ptbl_ptr->get_pkid(); \ if ( is_null_key(&key1) || key1 == 0 ) {\ if (!hcg_default_fkey) {\ printf("Warning: foreign key %s is not set for table %s element 0x%8.8x\n", \ #ckey, #ctbl_abbr, ctbl_ptr );\ pr_gen_key( ckey,#ptbl_abbr, 0, 0);\ }\ else if ( (ptbl_ptr) && ( !is_null_key(&key2) ) && ( key2 != 0) ) {\ ctbl_ptr->set_##ckey (key2);\ }\ else {\ pr_gen_key( ckey, #ptbl_abbr, 0, 0);\ }\ } #endif /* USE_STL */ /******************************************************************************/ /* This macro is used set the default value of non-key fields of type cX or tX*/ /******************************************************************************/ #ifndef USE_STL #define pr_check_str(tbl_abbr,tbl_ptr,fld,length) \ if ( (tbl_ptr)->fld[0] == '\0' ) \ {\ int i = sizeof((tbl_ptr)->fld) - 2;\ printf("Warning: string field %s is not set for table %s element 0x%8.8x\n", \ #fld, #tbl_abbr, tbl_ptr);\ for((tbl_ptr)->fld[i] = '\0'; i>=0; (tbl_ptr)->fld[i--] = '?');\ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro will allocate a block of memory large enough to hold the*/ /* specified table type. It also flushes the block to binary 0 (zero), so */ /* that pointer fields are pre-nulled. */ /******************************************************************************/ #ifndef USE_STL #define alloc_element(tbl) \ tbl##elt = (tbl *)malloc( sizeof(tbl) ); \ clear_mem(tbl##elt,sizeof(tbl)) #endif /* USE_STL */ /******************************************************************************/ /* This private macro will insert a row into a table. The pkey parameter is */ /* the name of the primary key field for the table in question. The row is */ /* linked into the tables row chain at the alphabetically correct location, */ /* sorted by primary key. */ /******************************************************************************/ #ifndef USE_STL #define insert_element(tbl) \ if (tbl##begin == NULL) \ { \ tbl##begin = tbl##elt; \ tbl##end = tbl##elt; \ } \ else \ if (key_compare1(tbl##end->get_pkid(),tbl##elt->get_pkid()) < 0) \ { \ tbl##end->next_ptr = tbl##elt; \ tbl##elt->prev_ptr = tbl##end; \ tbl##end = tbl##elt; \ } \ else \ { \ tbl##temp = tbl##begin; \ tbl##curr = tbl##begin; \ while ((tbl##curr != NULL) && (key_compare1(tbl##curr->get_pkid(),tbl##elt->get_pkid()) < 0)) \ { \ tbl##temp = tbl##curr; \ tbl##curr = tbl##curr->next_ptr; \ } \ if ((tbl##curr != NULL) && (key_compare1(tbl##curr->get_pkid(),tbl##elt->get_pkid()) == 0)) \ { \ dup_row_warning(tbl##elt->get_pkid()); \ free(tbl##elt); \ } \ if (tbl##curr == tbl##begin) \ { \ tbl##elt->next_ptr = tbl##begin; \ tbl##begin->prev_ptr = tbl##elt; \ tbl##begin = tbl##elt; \ } \ else \ { \ tbl##elt->next_ptr = tbl##curr; \ tbl##elt->prev_ptr = tbl##temp; \ tbl##temp->next_ptr = tbl##elt; \ if (tbl##curr != NULL) \ tbl##curr->prev_ptr = tbl##elt; \ } \ } \ tbl##curr = tbl##elt #endif /* USE_STL */ /******************************************************************************/ /* This private macro will loop over the specified child table, linking the */ /* first child it finds for this parent row. This is acceptable since it is */ /* supposed to be a singleton relationship. */ /* The assert macro aborts if more than one child is linked in - RJL 94/12/6 */ /* assert (loosely) allows NULL or self-pointer in the current parent */ /******************************************************************************/ #ifndef USE_STL #define link_child_1(ca,pa,cf,pk,p,c) \ assert(pa##curr->c##_fcp == NULL || pa##curr->c##_fcp == pa##curr);\ pa##curr = pa##elt; \ ca##curr2 = ca##begin; \ while(ca##curr2) \ { \ if (key_compare1(ca##curr2->get_##cf(),pa##curr->get_pkid()) == 0) \ { \ ca##curr2->p##_pp = pa##curr; \ pa##curr->c##_fcp = ca##curr2; \ break; \ } \ ca##curr2 = ca##curr2->next_ptr; \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro will loop over the specified child table, linking any */ /* children of this parent row. It is identical to link_child_nobp except */ /* that back pointers are also filled in. */ /******************************************************************************/ #ifndef USE_STL #define link_child_bp_m(ca,pa,cf,pk,p,c) \ pa##curr = pa##elt; \ ca##curr2 = ca##begin; \ while(ca##curr2) \ { \ if (key_compare1(ca##curr2->get_##cf(),pa##curr->get_pkid()) == 0) \ { \ ca##curr2->p##_pp = pa##curr; \ ca##temp2 = pa##curr->c##_bcp; \ pa##curr->c##_bcp = ca##curr2; \ (pa *) ca##curr2->p##_fpp = pa##curr; \ if (pa##curr->c##_fcp == NULL) \ { \ pa##curr->c##_fcp = ca##curr2; \ (pa *) ca##curr2->p##_bpp = pa##curr; \ } \ else \ { \ (ca *) ca##curr2->p##_bpp = ca##temp2; \ (ca *) ca##temp2->p##_fpp = ca##curr2; \ } \ } \ ca##curr2 = ca##curr2->next_ptr; \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro will loop over the specified parent table, linking any */ /* parents of this child row. It is identical to link_parent_nobp except */ /* that it is assumed to be a singleton child. */ /******************************************************************************/ #ifndef USE_STL #define link_parent_1(ca,pa,cf,pk,p,c) \ for (pa##curr2 = pa##begin; (pa##curr2 != NULL) && (key_compare1(pa##curr2->get_pkid(),ca##curr->get_##cf()) < 0); pa##curr2 = pa##curr2->next_ptr); \ if ((pa##curr2 != NULL) && (key_compare1(ca##curr->get_##cf(),pa##curr2->get_pkid()) == 0)) \ { \ ca##curr->p##_pp = pa##curr2; \ pa##curr2->c##_fcp = ca##curr; \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro will loop over the specified parent table, linking any */ /* parents of this child row. It is identical to link_parent_nobp except */ /* that back pointers are also filled in. */ /* */ /* NOTE: Since the -noforward command-line qualifier was NOT used to generate */ /* this code, no check is included to ensure that a parent row was */ /* actually found. Performance and code size are sacrificed here, since*/ /* calls to link_child_{no}bp are included in the caller (pr_add). */ /* Link child is only needed when there is a risk of forward references */ /* in the data file. */ /* */ /******************************************************************************/ #ifndef USE_STL #define link_parent_bp_m(ca,pa,cf,pk,p,c) \ for (pa##curr2 = pa##begin; (pa##curr2 != NULL) && (key_compare1(pa##curr2->get_pkid(),ca##curr->get_##cf()) < 0); pa##curr2 = pa##curr2->next_ptr); \ if ((pa##curr2 != NULL) && (key_compare1(ca##curr->get_##cf(),pa##curr2->get_pkid()) == 0)) \ { \ ca##curr->p##_pp = pa##curr2; \ ca##temp = pa##curr2->c##_bcp; \ pa##curr2->c##_bcp = ca##curr; \ (pa *) ca##curr->p##_fpp = pa##curr2; \ if (pa##curr2->c##_fcp == NULL) \ { \ pa##curr2->c##_fcp = ca##curr; \ (pa *) ca##curr->p##_bpp = pa##curr2; \ } \ else \ { \ (ca *) ca##curr->p##_bpp = ca##temp; \ (ca *) ca##temp->p##_fpp = ca##curr; \ } \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used by pr_delete to physically delete a row. It */ /* also unlinks the row from its table's row chain. */ /******************************************************************************/ /* New version of del_row - 93/2/8 by RJL and CMurphy: */ /* tbl == tbl*//*end != NULL (and rcount = 1) means a single-row table */ /* tbl == tbl*//*end == NULL (and rcount = 0) means an empty table -RJL */ #ifndef USE_STL #define del_row(tbl) \ if (tbl##end == NULL) \ printf("del_row error: empty table");\ else \ if (tbl##curr == NULL) \ printf("del_row error: NULL curr row ptr");\ else\ {\ if( tbl##btidx == BTREESEARCH ) \ { \ sprintf(tempbtree,#tbl); \ tempbtree[HCG_ABBR_SIZE]='\0'; \ pr_del_bt(tempbtree,tbl##curr->get_pkid()); \ } \ if (tbl##end == tbl##curr) /*last row: next_ptr = NULL - RJL 93/2/8 */\ tbl##end = tbl##curr->prev_ptr; /* = NULL iff curr row = first row */\ if (tbl##begin == tbl##curr) /* first row: prev_ptr = NULL - RJL 93/2/8 */\ tbl##begin = tbl##curr->next_ptr; /* = NULL iff curr row = last row */\ if (tbl##curr->prev_ptr != NULL) \ { \ tbl##curr->prev_ptr->next_ptr = tbl##curr->next_ptr; \ } \ if (tbl##curr->next_ptr != NULL) \ { \ tbl##curr->next_ptr->prev_ptr = tbl##curr->prev_ptr; \ } \ key1 = tbl##curr->get_pkid(); \ hcg_ts_list[tbl##_idx].ts_list[get_version(&key1)].rcount--; \ hcg_table_seq_list[tbl##_idx].rcount--;\ free(tbl##curr);\ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used by pr_del to unlink a row from the specified */ /* parent table. It is identical to unlink_parent_nobp except that its is */ /* for a singleton child. */ /******************************************************************************/ #ifndef USE_STL #define unlink_parent_1(ca,pa,p,c) \ pa##temp = ca##curr->p##_pp; \ if (pa##temp != NULL) \ pa##temp->c##_fcp = NULL #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used by pr_del to unlink a row from the specified */ /* parent table. It is identical to unlink_parent_nobp except that back */ /* pointers are also unlinked. */ /******************************************************************************/ #ifndef USE_STL #define unlink_parent_bp_m(ca,pa,p,c) \ pa##temp = ca##curr->p##_pp; \ ca##temp = ca##curr; /* Change CEM & RJL 20 APR 93*/ \ if (pa##temp != NULL) \ { \ if (( pa##temp->c##_fcp == ca##temp) && \ ( (pa *) ca##curr->p##_fpp == pa##temp)) /* only child case */ \ { \ pa##temp->c##_fcp = NULL; \ pa##temp->c##_bcp = NULL; \ } \ else \ if ( pa##temp->c##_fcp == ca##temp ) /* first child case */ \ { \ pa##temp->c##_fcp = (ca *)ca##curr->p##_fpp; \ ca##curr2 = (ca *)ca##curr->p##_fpp; \ (pa *) ca##curr2->p##_bpp = pa##temp; \ } \ else \ if ( (pa *) ca##curr->p##_fpp == pa##temp) /* last child case */ \ { \ pa##temp->c##_bcp = (ca *)ca##curr->p##_bpp; \ ca##curr2 = (ca *)ca##curr->p##_bpp; \ (pa *) ca##curr2->p##_fpp = pa##temp; \ } \ else /* middle of child chain case */ \ { \ ca##curr2 = (ca *)ca##curr->p##_bpp; \ ca##curr2->p##_fpp = ca##curr->p##_fpp; \ ca##curr2 = (ca *)ca##curr->p##_fpp; \ ca##curr2->p##_bpp = ca##curr->p##_bpp; \ } \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used by pr_del to unlink a row from the specified */ /* child table. It is identical to link_child_nobp except that it is for a */ /* singleton child. */ /******************************************************************************/ #ifndef USE_STL #define unlink_child_1(ca,pa,p,c) \ ca##temp = (ca *) pa##curr->c##_fcp; \ if (ca##temp != NULL) \ ca##temp->p##_pp = NULL #endif /* USE_STL */ /******************************************************************************/ /* This private macro is used by pr_del to unlink a row from the specified */ /* child table. It is identical to link_child_nobp except that back pointers */ /* are also unlinked. */ /******************************************************************************/ #ifndef USE_STL #define unlink_child_bp_m(ca,pa,p,c) \ ca##temp = (ca *) pa##curr->c##_fcp; \ while ((ca##temp != NULL) && \ ((pa *) ca##temp != pa##curr)) \ { \ ca##temp2 = (ca *)ca##temp->p##_fpp; \ ca##temp->p##_bpp = ca##temp->p##_fpp = ca##temp->p##_pp = NULL; \ ca##temp = ca##temp2; \ } #endif /* USE_STL */ /******************************************************************************/ /* This private macro will loop over the specified table, freeing the memory */ /* allocated to each row. It should not be used by users, since it does not */ /* go out to parents and children, nulling out pointers to the deleted rows. */ /******************************************************************************/ #ifndef USE_STL #define free_table(tbl) \ tbl##curr = tbl##begin;\ while(tbl##curr)\ {\ tbl##temp = tbl##curr; \ tbl##curr = tbl##curr->next_ptr; \ free(tbl##temp); \ }\ tbl##begin = tbl##temp = tbl##elt = NULL /* curr already nulled by loop */ #endif /* USE_STL */ /******************************************************************************/ /* The remainder of this file holds the 'C' structure definitions for each */ /* table in the schema. */ /******************************************************************************/ static char *hcg_tbl_abbr[] = { "SV", "TT", "TA", "VV", "TS", "FO", "GD", "HG", "HN", "HA", "HL", "HP", "HI", "CG", "GX" }; /******************************************************************************/ /* Class: RC (Root Class) */ /******************************************************************************/ class RC { private : hcg_key pkid; int RFLAG; /* for pr_utility macro log */ public : void set_pkid (hcg_key id) { pkid = id; } void set_RFLAG (int flag) { RFLAG = flag; } hcg_key get_pkid () { return pkid; } int get_RFLAG () { return RFLAG; } } ; #endif