src/hg/utils/tdbQuery/tdbQuery.c 1.26
1.26 2010/01/04 19:12:40 kent
Merging viewInTheMiddle branch.
Index: src/hg/utils/tdbQuery/tdbQuery.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/utils/tdbQuery/tdbQuery.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -b -B -U 4 -r1.25 -r1.26
--- src/hg/utils/tdbQuery/tdbQuery.c 10 Dec 2009 07:13:56 -0000 1.25
+++ src/hg/utils/tdbQuery/tdbQuery.c 4 Jan 2010 19:12:40 -0000 1.26
@@ -20,8 +20,11 @@
static boolean clStrict = FALSE; /* If set only return tracks with actual tables. */
static boolean clAlpha = FALSE; /* If set include release alphas, exclude release beta. */
static boolean clNoBlank = FALSE; /* If set suppress blank lines in output. */
static char *clRewrite = NULL; /* Rewrite to given directory. */
+static boolean clNoCompSub = FALSE; /* If set don't do subtrack inheritence of fields. */
+
+boolean uglyOne;
void usage()
/* Explain usage and exit. */
{
@@ -50,12 +53,11 @@
"Check that trackDb is internally consistent. Prints diagnostic output to stderr and aborts if \n"
"there's problems.\n"
" -strict\n"
"Mimic -strict option on hgTrackDb. Suppresses tracks where corresponding table does not exist.\n"
-" -alpha\n"
-"Do checking on release alpha (and not release beta) tracks\n"
-" -noBlank\n"
-"Don't print out blank lines separating records"
+" -alpha Do checking on release alpha (and not release beta) tracks\n"
+" -noBlank Don't print out blank lines separating records"
+" -noCompSub Subtracks don't inherit fields from parents\n"
);
}
@@ -65,8 +67,9 @@
{"strict", OPTION_BOOLEAN},
{"alpha", OPTION_BOOLEAN},
{"noBlank", OPTION_BOOLEAN},
{"rewrite", OPTION_STRING},
+ {"noCompSub", OPTION_BOOLEAN},
{NULL, 0},
};
#define glKeyField "track" /* The field that has the record ID */
@@ -567,8 +570,10 @@
/* Find parent record if possible. This is a bit complicated by wanting to
* match parents and children from the same release if possible. Our
* strategy is to just ignore records from the wrond release. */
{
+if (clNoCompSub)
+ return NULL;
struct tdbField *parentField = tdbRecordField(rec, parentFieldName);
if (parentField == NULL)
return NULL;
char *parentLine = parentField->val;
@@ -745,8 +750,10 @@
break;
}
}
}
+ if (!clNoCompSub)
+ {
if (view != NULL)
{
struct slPair *setting;
for (setting = view->val; setting != NULL; setting = setting->next)
@@ -766,13 +773,15 @@
{
verbose(3, "view %s not in parent settingsByView of %s\n", viewName, rec->key);
}
}
+ }
/* Then inherit from parents. */
struct tdbRecord *parent;
for (parent = rec->parent; parent != NULL; parent = parent->parent)
{
+ if (!clNoCompSub)
mergeParentRecord(rec, parent, lm);
}
}
}
@@ -859,18 +868,28 @@
}
return FALSE;
}
-static struct tdbRecord *closestParentInFile(struct slRef *allParentRefs,
- struct tdbFilePos *childPos)
-/* Find parent that comes closest to (but before) childPos. */
+static int countAncestors(struct tdbRecord *r)
+/* Return 0 if has no parent, 1 if has a parent, 2 if it has a grandparent, etc. */
{
-struct slRef *parentRef;
-struct tdbRecord *closestParent = NULL;
+int count = 0;
+struct tdbRecord *p;
+for (p = r->parent; p != NULL; p = p->parent)
+ count += 1;
+return count;
+}
+
+static struct tdbRecord *closestTdbAboveLevel(struct tdbRecord *tdbList,
+ struct tdbFilePos *childPos, int parentDepth)
+/* Find parent at given depth that comes closest to (but before) childPos. */
+{
+struct tdbRecord *parent, *closestParent = NULL;
int closestDistance = BIGNUM;
-for (parentRef = allParentRefs; parentRef != NULL; parentRef = parentRef->next)
+for (parent = tdbList; parent != NULL; parent = parent->next)
+ {
+ if (countAncestors(parent) <= parentDepth)
{
- struct tdbRecord *parent = parentRef->val;
struct tdbFilePos *pos;
for (pos = parent->posList; pos != NULL; pos = pos->next)
{
if (sameString(pos->fileName, childPos->fileName))
@@ -886,16 +905,19 @@
}
}
}
}
+ }
return closestParent;
}
-static void checkChildUnderNearestParent(struct slRef *allParentRefs,
- struct tdbRecord *parent, struct tdbRecord *child)
+static void checkChildUnderNearestParent(struct tdbRecord *recordList, struct tdbRecord *child)
/* Make sure that parent record occurs before child, and that indeed it is the
* closest parent before the child. */
{
+struct tdbRecord *parent = child->parent;
+int parentDepth = countAncestors(parent);
+
/* We do the check for each file the child is in */
struct tdbFilePos *childFp, *parentFp;
for (childFp = child->posList; childFp != NULL; childFp = childFp->next)
{
@@ -908,9 +930,10 @@
errAbort("Child before parent in %s\n"
"Child (%s) at line %d, parent (%s) at line %d",
childFp->fileName, child->key, childFp->startLineIx,
parent->key, parentFp->startLineIx);
- struct tdbRecord *closestParent = closestParentInFile(allParentRefs, childFp);
+ struct tdbRecord *closestParent = closestTdbAboveLevel(recordList, childFp,
+ parentDepth);
assert(closestParent != NULL);
if (closestParent != parent)
errAbort("%s comes between parent (%s) and child (%s) in %s\n"
"Parent at line %d, child at line %d.",
@@ -951,21 +974,13 @@
}
}
}
-/* Create parent list, which we'll use for various child/parent checks. */
-struct slRef *parentRefList = NULL;
-for (record = recordList; record != NULL; record = record->next)
- {
- if (record->children != NULL)
- refAdd(&parentRefList, record);
- }
-
/* Additional child/parent checks. */
for (record = recordList; record != NULL; record = record->next)
{
if (record->parent != NULL)
- checkChildUnderNearestParent(parentRefList, record->parent, record);
+ checkChildUnderNearestParent(recordList, record);
}
}
void tdbQuery(char *sql)
@@ -1274,8 +1289,9 @@
clStrict = optionExists("strict");
clAlpha = optionExists("alpha");
clNoBlank = optionExists("noBlank");
clRewrite = optionVal("rewrite", clRewrite);
+clNoCompSub = optionExists("noCompSub");
if (clRewrite)
{
doRewrite(clRewrite, clRoot, "trackDb.ra", "visibility.ra", "priority.ra");
}