Generating table dependencies using templates

Don Clugston dac at nospam.com.au
Tue Apr 4 12:45:50 PDT 2006


Aarti wrote:
> Hello!
> 
> In my program I need to generate dependencies between database tables, 
> so I will always get information about below mentioned relations for 
> every specific table:
> 1. parent tables
> 2. child tables
> 3. ancestor tables
> 4. descendant tables
> 
> To generate such a dependencies I have following matrix (table is much 
> bigger in real program):
> 
> //tbl_vc,  tbl_ad,   tbl_dc, tbl_ic,  tbl_ct, tbl_root, tbl_end
> const ubyte tablerel[tbl_end][tbl_end] = {
>     {0,       1,        0,       1,      1,        0}, //tbl_vc
>     {0,       0,        1,       0,      0,        0}, //tbl_ad
>     {0,       0,        0,       0,      0,        0}, //tbl_dc
>     {0,       0,        0,       0,      0,        0}, //tbl_ic
>     {0,       0,        0,       0,      0,        0}, //tbl_ct
>     {1,       0,        0,       0,      0,        0}, //tbl_root
> };                            //tbl_end
> 
> Let's assume I want to find dependencies for table x:
> - parents --> search x column and add to result every table from row 
> label which on crossing with x column has 1 - e.g. parent of tbl_vc is 
> tbl_root, parent for tbl_dc is tbl_ad
> - children --> search x row and add to result every table from column 
> label which on crossing with x row has 1 - e.g. children of tbl_vc are 
> tbl_ad,  tbl_dt,  tbl_rlp,  tblrlo, tbl_ic,  tbl_ct,  tbl_dp,  tbl_ph, 
> tbl_sn; for tbl_root the child is tbl_vc
> - ancestor -> search for parents, add them to result and add also their 
> parents
> - descendants --> search for children, add them to result and add also 
> their children
> 
> Now in C++ code I have two (at least these two I know) possibilities:
> 1. I can hardcode every relation in vector for every table, so I have:
> int[] childrentables[tbl_end];
> 
> childrentables[tbl_vc][0]=tbl_ad; childrentables[tbl_vc][1]=tbl_ic; 
> childrentables[tbl_vc][2]=tbl_ct;
> 
> childrentables[tbl_ad][0]=tbl_dc;
> ... much more definitions for every table ...
> 
> Now I make it with simple code generator, but this solution is very 
> uncomfortable to use and difficult to modify when relations change.
> 
> 2. I can generate these dependencies on runtime using recurence. This 
> solution has runtime overhead and is more than I need as relations will 
> never change on runtime.
> 
> I would be happy to find solution with D templates. Is it possible? How 
> it should be implemented? Maybe you have some other suggestions?
> I will appreciate your suggestions.

It's hard without array literals, but you could do it with a const 
string. Untested, but I've done this sort of thing before...

const int numTables = 6;
const char [] tableDependencies
   = "010110"
     "001000"
     "000000"
     ...;

static assert(tableDependencies.length == numTables*numTables);

// true if dependencies[x][y] is '1'.
template dependsOn(int x, int y)
{
   const bool dependsOn = (tableDependencies[x*numTables+y]=='1';
}

// Returns an array of all the parents of table x.
// A bit of a hack -- we can concat char [] at compile time,
// but not const int[].
// int [] parentsOf!(x).

template parentsOf(int x, int row=0, dchar [] sofar="")
{
    static if (row==numTables)
	const int [] parentsOf = cast(int [])(sofar);
    else static if (dependsOn(x, row))
	const int [] parentsOf = parentsOf(x,
		row+1, sofar~cast(dchar)(row));
    else const int [] parentsOf = parentsOf(x,
		row+1, sofar);
}

// Usage:
const int tbl_vc = 1;
... etc.

int [] p  = parentsOf!(tbl_vc);



More information about the Digitalmars-d mailing list