static struct joinerField *findJoinerField(struct joinerSet *js, struct joinerDtf *dtf) /* Find field in set if any that matches dtf */ { struct slRef *chain = joinerSetInheritanceChain(js), *link; struct joinerField *jf, *ret = NULL; for (link = chain; link != NULL; link = link->next) { js = link->val; for (jf = js->fieldList; jf != NULL; jf = jf->next) { if (sameString(dtf->table, jf->table) && sameString(dtf->field, jf->field)) { if (slNameInList(jf->dbList, dtf->database)) { ret = jf; break; } } } if (ret != NULL) break; } slFreeList(&chain); return ret; }
struct joinerPair *joinerRelate(struct joiner *joiner, char *database, char *table) /* Get list of all ways to link table in given database to other tables, * possibly in other databases. */ { struct joinerSet *js, *jsChain; struct joinerField *jf, *jfBase; struct joinerPair *jpList = NULL, *jp; struct slRef *chainList, *chainEl; /* Return list of self, children, and parents (but not siblings) */ #ifdef SCREWS_UP_SPLITS if (!tableExists(database, table, NULL)) errAbort("%s.%s - table doesn't exist", database, table); #endif for (js = joiner->jsList; js != NULL; js = js->next) { if ((jfBase = joinerSetIncludesTable(js, database, table)) != NULL) { chainList = joinerSetInheritanceChain(js); for (chainEl = chainList; chainEl != NULL; chainEl = chainEl->next) { jsChain = chainEl->val; for (jf = jsChain->fieldList; jf != NULL; jf = jf->next) { struct slName *db; for (db = jf->dbList; db != NULL; db = db->next) { if (joinerExclusiveCheck(joiner, database, db->name)) { if (!sameString(database, db->name) || !sameString(table, jf->table)) { if (tableExists(db->name, jf->table, jf->splitPrefix)) { jp = joinerToField(database, jfBase, db->name, jf, jsChain); slAddHead(&jpList, jp); } } } } } } slFreeList(&chainList); } } slReverse(&jpList); return jpList; }