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