/******************************************************************************/ /* File : metaschema.h */ /* Schema : metaschema.sch */ /* Chgen Version : genMerge chgenv11-karner-spinney */ /* Chgen keysize : 8 characters */ /******************************************************************************/ #ifndef __SCHEMA_LOADED #define __SCHEMA_LOADED 1 #include #include #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. */ /******************************************************************************/ #ifdef MAIN #define hcg_declare(tbl) *tbl = 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, *tbl##curr, *tbl##temp, *tbl##end, *tbl##elt, *tbl##curr2, *tbl##temp2; #endif /******************************************************************************/ /* 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 "metaschema.sch" #define SCHEMA_HEADER_FILE_NAME "metaschema.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 5 /*----------------------------------------------------------- * * 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* 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; 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 */ hcg_key key_value; /* for pr_set_key() */ int PARSE; #define pr_set_int(tbl,fld,value) \ do{\ if((tbl)->RFLAG==1 && !PARSE && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_INT %s %s %d\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ }\ (tbl)->fld = (value); \ }while(0) #define pr_set_flt(tbl,fld,value) \ do{\ if((tbl)->RFLAG==1 && !PARSE && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_FLT %s %s %f\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ }\ (tbl)->fld = (value); \ }while(0) #define pr_set_key(tbl,fld,value) \ do{\ if((tbl)->RFLAG==1 && !PARSE && hcg_log ==1 )\ {\ key_value = ( value ); \ fprintf( hcg_logfileptr, "PR_SET_KEY %s %s %s\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", decode_retstr(value) );\ }\ (tbl)->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)->RFLAG==1 && !PARSE && hcg_log ==1 )\ {\ fprintf( hcg_logfileptr, "PR_SET_STR %s %s %s\n",\ decode_retstr( (hcg_key*)(tbl) ),"fld", (value) );\ } \ strncpy((tbl)->fld, (value), sizeof((tbl)->fld)-1); \ }while(0) /* END MODIFICATION, ctwang, 12/20/97 */ #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 #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[5] #ifdef MAIN = { "SV",0,0, "TT",0,0, "TA",0,0, "VV",0,0, "TS",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 /******************************************************************************/ /* 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. */ /* */ /******************************************************************************/ #define pr_delete(tbl) pr_del(tbl##_idx) /******************************************************************************/ /* 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. */ /******************************************************************************/ #define child_exists(parent,child) ((child##curr != NULL) && ((struct parent *) child##curr) != (parent##curr)) /******************************************************************************/ /* 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. */ /******************************************************************************/ #define start_child_chain(parent,child,fkey) child##curr = parent##curr->fkey##_fcp /******************************************************************************/ /* This macro is used to continue a child traversal started by start_child_ */ /* chain (see above). */ /******************************************************************************/ #define next_child(child,fkey) child##curr = (struct child *) child##curr->fkey##_fpp /******************************************************************************/ /* 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. */ /******************************************************************************/ #define exists(tbl) (tbl##curr) /******************************************************************************/ /* This macro is used to begin a traversal of the specified entire table. */ /* This includes all versions. */ /******************************************************************************/ #define start_chain_all(tbl) tbl##curr = tbl /******************************************************************************/ /* This macro is used to continue a full table traversal, started by start_ */ /* chain_all (see above). */ /******************************************************************************/ #define next_all(tbl) tbl##curr = tbl##curr->next_ptr /******************************************************************************/ /* This macro will determine if the specified child is the first in the child */ /* chain under the specified parent. */ /******************************************************************************/ #define first_child(parent,child,pkey) (parent##curr->pkey##_fcp == child##curr) /******************************************************************************/ /* This macro will determine if the specified child is the last in the child */ /* chain under the specified parent. */ /******************************************************************************/ #define last_child(parent,child,ckey) ((struct parent *) child##curr->ckey##_fpp == parent##curr) /******************************************************************************/ /* The macro defines pr_dump_row() as dump_row(). */ /******************************************************************************/ #define pr_dump_row(tbl,viewname,file_name,new_version,modestr) dump_row(#tbl,viewname,file_name,new_version,modestr) 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->tbl##id; \ 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. */ /******************************************************************************/ #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; (tbl##curr != NULL) && (key_compare(&tbl##curr->pkey,&value) < 0); tbl##curr = tbl##curr->next_ptr); \ if ((tbl##curr != NULL) && (key_compare(&tbl##curr->pkey,&value) != 0)) \ tbl##curr = NULL /******************************************************************************/ /* This looping macro will traverse the entire table (ie, all versions), */ /* stopping at each row whose specified string field equals the specified */ /* string value. */ /******************************************************************************/ #define find_str_loop_all(tbl,field,value) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (strcmp(tbl##curr->field,value) == 0) /******************************************************************************/ /* This looping macro is the same as find_str_loop_all, but uses a view. */ /******************************************************************************/ #define find_str_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->tbl##id)) &&\ (strcmp(tbl##curr->field,value) == 0)) /******************************************************************************/ #define find_key_loop_all(tbl,field,value) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (key_compare(&tbl##curr->field, &value) == 0) /******************************************************************************/ /* This looping macro is the same as find_key_loop_all, but uses a view. */ /******************************************************************************/ #define find_key_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->tbl##id)) &&\ (key_compare(&tbl##curr->field,&value) == 0)) /******************************************************************************/ /* This looping macro is identical to find_str_loop_all, except that integer */ /* fields and values are used. */ /******************************************************************************/ #define find_int_loop_all(tbl,field,value) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) \ if (tbl##curr->field == value) /******************************************************************************/ /* This looping macro is identical to find_int_loop_all, but uses a view. */ /******************************************************************************/ #define find_int_loop(viewname,tbl,field,value) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tbl##curr->tbl##id)) &&\ (tbl##curr->field == value)) /******************************************************************************/ /* This looping macro will traverse all children of a parent, stopping at */ /* each child row. */ /******************************************************************************/ #define child_loop(parent,child,pkey,ckey) \ for (child##curr = parent##curr->pkey##_fcp; \ ((child##curr != NULL) && ((struct parent *) child##curr) != (parent##curr)); \ child##curr = (struct child *) child##curr->ckey##_fpp) /******************************************************************************/ /* This looping macro will traverse the entire specified table (ie, all */ /* versions), stopping at every row. */ /******************************************************************************/ #define table_loop_all(tbl) for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr) /******************************************************************************/ /* This looping macro will traverse the specified table, stopping at every */ /* row that that meets the view (based on version number). */ /******************************************************************************/ #define table_loop(viewname,tbl) \ if (find_view_idx(viewname)) \ for (tbl##curr = tbl; tbl##curr != NULL; tbl##curr = tbl##curr->next_ptr)\ if (meets_view(tbl##_idx,hcg_view_idx,tbl##curr->tbl##id)) /******************************************************************************/ /* This macro is identical to pr_find, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #define pr_var_find(tbl,tblvar,pkey,value) \ for (tblvar = tbl; (tblvar != NULL) && (key_compare(&tblvar->pkey,&value) < 0); tblvar = tblvar->next_ptr); \ if ((tblvar != NULL) && (key_compare(&tblvar->pkey,&value) != 0)) \ tblvar = NULL /******************************************************************************/ /* This macro is identical to find_str_loop_all, except that the user can */ /* specify his/her own looping variable. */ /******************************************************************************/ #define var_find_str_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr)\ if (strcmp(tblvar->field,value) == 0) /******************************************************************************/ /* This macro is identical to find_str_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #define var_find_str_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tblvar->tbl##id)) &&\ (strcmp(tblvar->field,value) == 0)) /******************************************************************************/ /* This macro is identical to find_int_loop_all, except that the user can */ /* specify his/her own looping variable. */ /******************************************************************************/ #define var_find_int_loop_all(tbl,tblvar,field,value) \ for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr) \ if (tblvar->field == value) /******************************************************************************/ /* This macro is identical to var_find_int_loop_all, but uses a view. */ /* specify his/her own looping variable. */ /******************************************************************************/ #define var_find_int_loop(viewname,tbl,tblvar,field,value) \ if (find_view_idx(viewname)) \ for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr)\ if ((meets_view(tbl##_idx,hcg_view_idx,tblvar->tbl##id)) &&\ (tblvar->field == value)) /******************************************************************************/ /* This macro is identical to child_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #define var_child_loop(tbl,parent,pkey,tbl2,child,ckey) \ for (child = parent->pkey##_fcp; \ ((child != NULL) && ((struct tbl *) child) != (parent)); \ child = (struct tbl2 *) child->ckey##_fpp) /******************************************************************************/ /* This macro is identical to table_loop_all, except that the user can specify*/ /* his/her own looping variable. */ /******************************************************************************/ #define var_table_loop_all(tbl,tblvar) for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr) /******************************************************************************/ /* This macro is identical to table_loop, except that the user can specify */ /* his/her own looping variable. */ /******************************************************************************/ #define var_table_loop(viewname,tbl,tblvar) \ if (find_view_idx(viewname)) \ for (tblvar = tbl; tblvar != NULL; tblvar = tblvar->next_ptr)\ if (meets_view(tbl##_idx,hcg_view_idx,tblvar->tbl##id)) /******************************************************************************/ /* This macro is identical to first_child, except that the user can specify */ /* his/her own parent and child pointer variables. */ /******************************************************************************/ #define var_first_child(tbl,parent,child,pkey) (parent->pkey##_fcp == child) /******************************************************************************/ /* This macro is identical to last_child, except that the user can specify */ /* his/her own parent and child pointer variables. */ /******************************************************************************/ #define var_last_child(tbl,parent,child,ckey) ((struct tbl *) child->ckey##_fpp == parent) /******************************************************************************/ /* Macro for checking error in file writes */ /******************************************************************************/ #define PrintCheck(x) if((x) == -1) { printf("Error in outputing file. Exiting\n"); exit(1);} /* 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 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 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_add(char *, char *, hcg_ptr); 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 *); } #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. */ /* */ /******************************************************************************/ /* 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. */ /******************************************************************************/ /* 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. */ /******************************************************************************/ #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 /******************************************************************************/ /* The remainder of this file holds the 'C' structure definitions for each */ /* table in the schema. */ /******************************************************************************/ /******************************************************************************/ /* Table: SV */ /******************************************************************************/ hcg_extern struct SV /* sv_type - schema version, data, path, applications? */ { hcg_key SVid; /* primary key field */ char PVid[9]; /* Project Ref - non-key field for now */ char svname[31]; /* schema name [and version?] */ char sformat[7]; /* schema format: CHGEN or GENDB[?] */ char sversion[13]; /* schema tag or version (rev# i.j...? */ int lastMod; /* date of last mod: yymmdd */ char svpath[81]; /* full path prefix or $DEFINED-SYMBOL */ char descr[81]; /* e.g., list of schema applications? */ struct VV *VVid_fcp; struct VV *VVid_bcp; struct TT *TTid_fcp; struct TT *TTid_bcp; struct SV *prev_ptr; struct SV *next_ptr; int RFLAG; /* for pr_utility macro log */ } hcg_declare(SV); /******************************************************************************/ /* Table: TT */ /******************************************************************************/ hcg_extern struct TT /* tt_type - table description and child-set of attributes*/ { hcg_key TTid; /* primary key field */ hcg_key SVid; /* SVid is foreign key */ char ttabb[6]; /* 2 or 4 UCLetters */ char ttname[31]; /* table name */ char descr[81]; /* descriptive comment (table purpose) */ struct SV *SVid_pp; struct dummy_type *SVid_fpp; struct dummy_type *SVid_bpp; struct TS *TSid_fcp; struct TS *TSid_bcp; struct TA *TAid_fcp; struct TA *TAid_bcp; struct TT *prev_ptr; struct TT *next_ptr; int RFLAG; /* for pr_utility macro log */ } hcg_declare(TT); /******************************************************************************/ /* Table: TA */ /******************************************************************************/ hcg_extern struct TA /* ta_type - scalar or ref attribute of parent table */ { hcg_key TAid; /* primary key field */ hcg_key TTid; /* TTid is foreign key */ char fname[31]; /* field name (column header) */ char dfltVal[31]; /* default value (was altName) */ char ftype[11]; /* field type (I4/F4/c##,t###/k8/k12) */ char iskey[5]; /* 0:nonkey; 1/-1:pfkey; s:superClassRef */ char comment[133]; /* descriptive comment (units/range?) */ struct TT *TTid_pp; struct dummy_type *TTid_fpp; struct dummy_type *TTid_bpp; struct TA *prev_ptr; struct TA *next_ptr; int RFLAG; /* for pr_utility macro log */ } hcg_declare(TA); /******************************************************************************/ /* Table: VV */ /******************************************************************************/ hcg_extern struct VV /* vv_type - subset of tables in this view */ { hcg_key VVid; /* primary key field */ hcg_key SVid; /* SV foreign key field */ char vname[31]; /* view name (schema = all tables) */ char mode[3]; /* mode (r/w/u) */ int num_tables; /* number of tables in View */ struct SV *SVid_pp; struct dummy_type *SVid_fpp; struct dummy_type *SVid_bpp; struct TS *TSid_fcp; struct TS *TSid_bcp; struct VV *prev_ptr; struct VV *next_ptr; int RFLAG; /* for pr_utility macro log */ } hcg_declare(VV); /******************************************************************************/ /* Table: TS */ /******************************************************************************/ hcg_extern struct TS /* ts_type - statistics about this Table in View */ { hcg_key TSid; /* primary key field */ hcg_key VVid; /* fkey to ViewVersion for this TSrow */ hcg_key TTid; /* fkey to TTrow for this TSrow */ int verno; /* version number of TT in VV */ int maxrow; /* max row# in this table and VV */ int vvrowcnt; /* row-count of this TT in parent VV only*/ struct TT *TTid_pp; struct dummy_type *TTid_fpp; struct dummy_type *TTid_bpp; struct VV *VVid_pp; struct dummy_type *VVid_fpp; struct dummy_type *VVid_bpp; struct TS *prev_ptr; struct TS *next_ptr; int RFLAG; /* for pr_utility macro log */ } hcg_declare(TS); static char *hcg_tbl_abbr[] = { "SV", "TT", "TA", "VV", "TS" }; #endif /******************************************************************************/ /* 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 int SVbtidx; int TTbtidx; int TAbtidx; int VVbtidx; int TSbtidx; hcg_extern char tempbtree[BUFSIZE]; hcg_extern hcg_key btfinish,btresult; void pr_find_bt();