To MLauzier pr_addCode.txt - RJL050315 - Marina, this is why we should have been looking at the actual pr_util code context: I did this after reconnecting my PC to the net. I believe I advised you to find out how pr_add calls link and pr_delete calls unlink a long time ago. My browsing shows that the pr_add macro does call a function do_pr_add #define pr_add(a,b,c) do_pr_add(a,#b,c) (very trivially - the macro's only purpose is to avoid quoting the ttabbr arg 2). and FUNCTION do_pr_add gets the string "b" and calls encoding(): tbl_encoding = encoding( hcg_table_seq_list[hcg_tbl_idx].ttabbrev ); then does a switch(tbl_encoding) // the int code for tabletype. Each switch case merely calls pr_link(tbl_encoding); which again must have a switch(tbl_encoding) (see below). do_pr_add only needs one tabletype (the child tbl_encoding) because it includes EVERY parent fkey in its link method calls. Your equivalent fucntion pr_set_fkey() [note the f] does need to extract two table types, but it only needs to make one call to pr_unlink and one to pr_link. pr_set_fkey will need adjustments on how it gets the tbl_encoding, and it only calls unlink and link macros ONCE, instead of linking for each fkey. Both parent and child ttabbr's are needed. From parent pkey you can get the int tbl_encoding directly from MostSignifByte of pkey, instead of calling decode then encode (;-). From child_ptr cp you can get cp->pkey (tblptr->AIid here). Then decode/encode the int AIid value or get its MSByte as above. [Caveat: I can't guarantee that the compressed 1-byte unsigned int table type ithat appears in a pkey or fkey value is the same as the one that encode returns from an ASCII key-string. The latter use hcg_structs (see the argument of encode( hcg_table_seq_list[hcg_tbl_idx].ttabbrev) in function do_pr_add()). I want to replace these by .msdat table TT data so I don't really mind if there is a conflict. (There should not be: Perhaps the string of ttbbr's that appears at the end of schema.h reflects this sequence - if not, then there are really three different encodings of ttabbr where there will eventually be one.) You can do similar things to do_pr_add inside a do_pr_set_fkey function CALLED in the pr_set_key macro body. R Lechner ========================================== saturn.cs.uml.edu(17)> pwd /nfs/earth/faculty/fac1/lechner/bde2alpha_rl/sandbox/bdecheckout/bde/pr_util saturn.cs.uml.edu(24)> echo $RL /usr/cs/fac1/lechner/bde2alpha_rl/sandbox/bdecheckout/bde saturn.cs.uml.edu(25)> alias grep egrep -n saturn.cs.uml.edu(16)> grep pr_add *.h 414: char hcg_viewname[NAMELENGTH] = "\0"; /* Last viewname used by pr_add */ 852:#define pr_add(a,b,c) do_pr_add(a,#b,c) 874: extern void do_pr_add(char *, char *, hcg_ptr); ... saturn.cs.uml.edu(19)> grep do_pr_add *.c pr_load.c:2337:/* its only client is do_pr_add(). */ pr_load.c:2510:void do_pr_add (char *viewname, char *tbl_abbrv, hcg_ptr tbl_ptr) pr_load.c:2543: printf("do_pr_add ignored; view %s not found.\n",viewname); pr_load.c:2678:} /* end do_pr_add */ pr_log.c:50:extern void do_pr_add( char *viewname, char *tbl_abbrv, hcg_ptr tbl_ptr); saturn.cs.uml.edu(20)> /******************************************************************************/ /* This routine is used to add a single row to a virtual database table. */ /* Validations for valid table-id, table is within view, and the version */ /* number is the right one for this table in this view. if all this passes, */ /* the row is added to the database, and linked in to its parents, etc... */ /******************************************************************************/ /* RJL040712: log_pr_add is a no-op unless hcg_log==1 */ void do_pr_add (char *viewname, char *tbl_abbrv, hcg_ptr tbl_ptr) { char error_table[HCG_ABBR_SIZE+1]; /*char tempkey[HCG_KEY_SIZE+1];*/ int tbl_encoding; char VNstring[NAMELENGTH] = "VN "; /* skip leading spaces (if any) from tbl_abbrv */ while( *tbl_abbrv == ' ') ++tbl_abbrv; if (hcg_log) { ... }; if (!hcg_initialized) { ... } DP; if (!find_view_idx(viewname)) { ... } if (!find_tbl_idx(tbl_abbrv)) { ... } hcg_version = hcg_view_list.view_list[hcg_view_idx].version_list[hcg_tbl_idx]; hcg_table_seq_list[hcg_tbl_idx].rcount++; hcg_ts_list[hcg_tbl_idx].ts_list[hcg_version].rcount++; tbl_encoding = encoding( hcg_table_seq_list[hcg_tbl_idx].ttabbrev ); switch( tbl_encoding ) { . . . case 3 : /* encoding of HN */ HNelt = (struct HN *) tbl_ptr; pr_gen_pkey(viewname,HN,HNelt->HNid); pr_check_fkey(HN,HNelt,HGid,HG,HGid,HGelt); pr_check_str (HN,HNelt,FSid,8); pr_check_str (HN,HNelt,shape,1); pr_check_str (HN,HNelt,txtfont,25); pr_check_str (HN,HNelt,nodename,20); log_pr_add ("HN", viewname, HNelt); pr_link(tbl_encoding); break; case 4 : /* encoding of HA */ HAelt = (struct HA *) tbl_ptr; pr_gen_pkey(viewname,HA,HAelt->HAid); pr_check_fkey(HA,HAelt,HNid,HN,HNid,HNelt); pr_check_str (HA,HAelt,DAid,8); pr_check_str (HA,HAelt,txtfont,25); pr_check_str (HA,HAelt,hlabel,60); log_pr_add ("HA", viewname, HAelt); pr_link(tbl_encoding); break; case 5 : /* encoding of HL */ HLelt = (struct HL *) tbl_ptr; pr_gen_pkey(viewname,HL,HLelt->HLid); pr_check_fkey(HL,HLelt,HNid1,HN,HNid,HNelt); pr_check_fkey(HL,HLelt,HNid2,HN,HNid,HNelt); log_pr_add ("HL", viewname, HLelt); pr_link(tbl_encoding); break; . . . }; hcg_ts_list[hcg_tbl_idx].ts_list[hcg_version].maxrow++; return; /* RJL 030811 */ } /* end do_pr_add */ /******************************************************************************/ /* This routine is used to link a single row to a virtual database table. */ /******************************************************************************/ void pr_link (tbl_encoding) int tbl_encoding; { switch( tbl_encoding ) { . . . . case 3 : /* encoding of HN */ insert_element(HN,HNid); link_child_nobp_m(HA,HN,HNid,HNid,HNid,HAid); link_child_nobp_m(HL,HN,HNid1,HNid,HNid1,HLid1); link_child_nobp_m(HL,HN,HNid2,HNid,HNid2,HLid2); link_parent_nobp_m(HN,HG,HGid,HGid,HGid,HNid); break; case 4 : /* encoding of HA */ insert_element(HA,HAid); link_parent_nobp_m(HA,HN,HNid,HNid,HNid,HAid); break; case 5 : /* encoding of HL */ insert_element(HL,HLid); link_child_nobp_m(HI,HL,HLid,HLid,HLid,HIid); link_child_nobp_m(HP,HL,HLid,HLid,HLid,HPid); link_parent_nobp_m(HL,HN,HNid1,HNid,HNid1,HLid1); link_parent_nobp_m(HL,HN,HNid2,HNid,HNid2,HLid2); break; . . . } } /* end pr_link */ saturn.cs.uml.edu(28)> grep pr_link *.c pr_load.c:2204:void pr_link (tbl_encoding) pr_load.c:2268:} /* end pr_link */ /******************************************************************************/ /* This routine is used to link a single row to a virtual database table. */ /******************************************************************************/ void pr_link (tbl_encoding) int tbl_encoding; { switch( tbl_encoding ) { . . . case 3 : /* encoding of HN */ insert_element(HN,HNid); link_child_nobp_m(HA,HN,HNid,HNid,HNid,HAid); link_child_nobp_m(HL,HN,HNid1,HNid,HNid1,HLid1); link_child_nobp_m(HL,HN,HNid2,HNid,HNid2,HLid2); link_parent_nobp_m(HN,HG,HGid,HGid,HGid,HNid); break; case 4 : /* encoding of HA */ insert_element(HA,HAid); link_parent_nobp_m(HA,HN,HNid,HNid,HNid,HAid); break; case 5 : /* encoding of HL */ insert_element(HL,HLid); link_child_nobp_m(HI,HL,HLid,HLid,HLid,HIid); link_child_nobp_m(HP,HL,HLid,HLid,HLid,HPid); link_parent_nobp_m(HL,HN,HNid1,HNid,HNid1,HLid1); link_parent_nobp_m(HL,HN,HNid2,HNid,HNid2,HLid2); break; . . . } } /* end pr_link */ This is the END of $RL/pr_util/94sbde_schema.h: The array definition defines the order of tbl_encodings (I think): The hasType(keyvalue,ttabbr) test was added for bde and is not yet auto-generated by chgen. It uses decode_retstr(&key) to decode the pkey to a string, then strstr to find out the position of this ttabbr in hcg_tbl_abbr[]. It only needs to return 0 or non-zero. But the index that is returned (dividedd by 2) yields a table type index.\ It would be interesting to see if the array order below matches tbl_encoding = encoding( hcg_table_seq_list[hcg_tbl_idx].ttabbrev ). [There is a third decoding sequence derived from a string of ttabbr's concatenated together, somewhere maybe chgen itself. These 3 should all be consistent.?] /* Client: pr_util/pr_load.c:1669: abbr_lut_create(...) */ static char *hcg_tbl_abbr[] = { "FO", "GD", "HG", "HN", "HA", "HL", "HP", "HI", "CG", "GX" }; ... #define hasType(key,ttabbr) (key?((strstr(decode_retstr(&key),#ttabbr)?1:0)):0) Here in 94sbde_schema.h is another code fragment that defines a ttabbr sequence: It is in fact the argument of tbl_encoding in do_pr-add above. tbl_encoding = encoding( hcg_table_seq_list[hcg_tbl_idx].ttabbrev ); SO the above and below orderings of ttabbr strings do in fact coincide. This order is PROBABLY the order of TT-rows in schema.msdat, which is the order in which tables are declared in schema.sch. I can't find the one-string ordering that I believe exists as the string "FOGDHGHNHAHLHPHICGGX" somewhere in $RL/pr_util/*. /******************************************************************************/ /* 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[10] #ifdef MAIN = { {"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 From lechner@cs.uml.edu Wed Mar 16 00:07:38 2005 Received: from saturn.cs.uml.edu (cs.uml.edu [129.63.8.2]) by earth.cs.uml.edu (8.11.6/8.11.6) with ESMTP id j2G57bw15893 for ; Wed, 16 Mar 2005 00:07:37 -0500 Received: from saturn.cs.uml.edu (localhost [127.0.0.1]) by saturn.cs.uml.edu (8.12.9/8.12.9) with ESMTP id j2G57bYn297669; Wed, 16 Mar 2005 00:07:37 -0500 (EST) Received: (from lechner@localhost) by saturn.cs.uml.edu (8.12.9/8.12.9/Submit) id j2G57b6M302740; Wed, 16 Mar 2005 00:07:37 -0500 (EST) From: Bob Lechner Message-Id: <200503160507.j2G57b6M302740@saturn.cs.uml.edu> Subject: Re: about pr_del - yes - see $RL/pr_util/pr_set_fkeyHelp050315.txt(next msg) To: marina@perlstar.com Date: Wed, 16 Mar 2005 00:07:37 -0500 (EST) Cc: lechner@cs.uml.edu (Bob Lechner) In-Reply-To: <4237B1E5.8090901@perlstar.com> from "M Lauzier" at Mar 15, 2005 11:11:17 PM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Status: X-Keywords: X-UID: 76 Status: RO > From marina@perlstar.com Tue Mar 15 23:12:24 2005 > To: Bob Lechner > Subject: about pr_del > > Professor, pr_del doesn't have to have table types because it has 12+ > cases switch statement and call unlink depend on table it deal with. > Do you want me to do "set_key" same way ? > > Marina. > > > void pr_del(tbl_idx) > > int tbl_idx; > > { > > static char rcsid[] = "$Id"; > > char temp_key[HCG_KEY_SIZE+1]; > > char log_text[BUFSIZE]; > > > > logwait(); > > > > switch( encoding(hcg_table_seq_list[tbl_idx].ttabbrev) ) > > { > > case 0 : /* encoding of SM */ > > unlink_child_nobp_m(ET,SM,SMid,ETid); > > unlink_child_nobp_m(ST,SM,SMid,STid); > > unlink_child_nobp_m(AC,SM,SMid,ACid); > > #ifdef DEBUG > > decode(temp_key, &SMcurr->SMid); > > printf("The primary key deleted is %s\n",temp_key); > > #endif > > del_row(SM); > > > > /* The following is to support logging */ > > decode(temp_key, &SMcurr->SMid); > > sprintf(log_text,"DL %s\n",temp_key); > > logstr(log_text); > > > > break; > > > > case 1 : /* encoding of AC */ > > unlink_child_nobp_m(AI,AC,ACid,AIid); > > unlink_parent_nobp_m(AC,SM,SMid,ACid); > > #ifdef DEBUG > > decode(temp_key, &ACcurr->ACid); > > printf("The primary key deleted is %s\n",temp_key); > > #endif > > del_row(AC); > > > > /* The following is to support logging */ > > decode(temp_key, &ACcurr->ACid); > > sprintf(log_text,"DL %s\n",temp_key); > > logstr(log_text); > > > > break; > > > > case 2 : /* encoding of ST */ > > unlink_child_nobp_m(TR,ST,STid1,TRid1); > > unlink_child_nobp_m(TR,ST,STid2,TRid2); > > unlink_parent_nobp_m(ST,SM,SMid,STid); > > #ifdef DEBUG > > decode(temp_key, &STcurr->STid); > > printf("The primary key deleted is %s\n",temp_key); > > #endif > > del_row(ST); > > > > /* The following is to support logging */ > > decode(temp_key, &STcurr->STid); > > sprintf(log_text,"DL %s\n",temp_key); > > logstr(log_text); > > > > break; > > > > case 3 : /* encoding of AI */ > > unlink_child_1(HO,AI,AIid,HOid); > > unlink_child_1(HD,AI,AIid,HDid); > > unlink_child_nobp_m(EI,AI,AIid1,EIid1); > > unlink_child_nobp_m(EI,AI,AIid2,EIid2); > > unlink_parent_nobp_m(AI,AC,ACid,AIid); > > #ifdef DEBUG > > decode(temp_key, &AIcurr->AIid); > > printf("The primary key deleted is %s\n",temp_key); > > #endif > > del_row(AI); > > ...................................................... > etc....... > > >