src/utils/raSqlQuery/raSqlQuery.c 1.12

1.12 2009/11/20 20:00:23 kent
Adding -addFile option.
Index: src/utils/raSqlQuery/raSqlQuery.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/utils/raSqlQuery/raSqlQuery.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -b -B -U 4 -r1.11 -r1.12
--- src/utils/raSqlQuery/raSqlQuery.c	20 Nov 2009 09:59:30 -0000	1.11
+++ src/utils/raSqlQuery/raSqlQuery.c	20 Nov 2009 20:00:23 -0000	1.12
@@ -20,8 +20,9 @@
 static char *clParentField = "subTrack";
 static char *clNoInheritField = "noInherit";
 static boolean clMerge = FALSE;
 static boolean clParent = FALSE;
+static boolean clAddFile = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
@@ -45,8 +46,9 @@
   "   -parentField=field - Use field as the one that tells us who is our parent. Default %s\n"
   "   -noInheritField=field - If field is present don't inherit fields from parent\n"
   "   -merge - If there are multiple raFiles, records with the same keyField will be\n"
   "          merged together with fields in later files overriding fields in earlier files\n"
+  "   -addFile - Add 'file' field to say where record is defined\n"
   "The output will be to stdout, in the form of a .ra file if the select command is used\n"
   "and just a simple number if the count command is used\n"
   , clKey, clParentField
   );
@@ -59,14 +61,12 @@
    {"key", OPTION_STRING},
    {"parent", OPTION_BOOLEAN},
    {"parentField", OPTION_STRING},
    {"noInheritField", OPTION_STRING},
+   {"addFile", OPTION_BOOLEAN},
    {NULL, 0},
 };
 
-struct rqlEval rqlEvalOnRecord(struct rqlParse *p, struct raRecord *ra);
-/* Evaluate self on ra. */
-
 static void mergeRecords(struct raRecord *old, struct raRecord *record, struct lm *lm)
 /* Merge record into old,  updating any old fields with new record values. */
 {
 struct raField *field;
@@ -82,8 +82,9 @@
 	oldField->val = field->val;
 	slAddTail(&old->fieldList, oldField);
 	}
     }
+old->posList = slCat(old->posList, record->posList);
 }
 
 static void mergeParentRecord(struct raRecord *record, struct raRecord *parent, struct lm *lm)
 /* Merge in parent record.  This only updates fields that are in parent but not record. */
@@ -103,9 +104,9 @@
     }
 }
 
 static struct raRecord *readRaRecords(int inCount, char *inNames[], 
-	char *mergeField, struct lm *lm)
+	char *mergeField, boolean addFile, struct lm *lm)
 /* Scan through files, merging records on mergeField if it is non-NULL. */
 {
 if (inCount <= 0)
     return NULL;
@@ -120,8 +121,10 @@
 	char *fileName = inNames[i];
 	struct lineFile *lf = lineFileOpen(fileName, TRUE);
 	while ((record = raRecordReadOne(lf, lm)) != NULL)
 	    {
+	    if (addFile)
+	        record->posList = raFilePosNew(lm, fileName, lf->lineIx);
 	    struct raField *keyField = raRecordField(record, mergeField);
 	    if (keyField != NULL)
 		{
 		struct raRecord *oldRecord = hashFindVal(recordHash, keyField->val);
@@ -152,8 +155,10 @@
 	struct lineFile *lf = lineFileOpen(fileName, TRUE);
 	struct raRecord *record;
 	while ((record = raRecordReadOne(lf, lm)) != NULL)
 	    {
+	    if (addFile)
+	        record->posList = raFilePosNew(lm, fileName, lf->lineIx);
 	    slAddHead(&recordList, record);
 	    }
 	lineFileClose(&lf);
 	}
@@ -175,10 +180,12 @@
     return res.val.b;
     }
 }
 
-void rqlStatementOutput(struct rqlStatement *rql, struct raRecord *ra, FILE *out)
-/* Output fields  from ra to file. */
+void rqlStatementOutput(struct rqlStatement *rql, struct raRecord *ra, 
+	char *addFileField, FILE *out)
+/* Output fields  from ra to file.  If addFileField is non-null add a new
+ * field with this name at end of output. */
 {
 struct slName *fieldList = rql->fieldList, *field;
 for (field = fieldList; field != NULL; field = field->next)
     {
@@ -193,8 +200,18 @@
 	    match = (strcmp(field->name, r->name) == 0);
 	if (match)
 	    fprintf(out, "%s %s\n", r->name, r->val);
 	}
+    if (addFileField != NULL)
+        {
+	fprintf(out, "%s", addFileField);
+	struct raFilePos *fp;
+	for (fp = ra->posList; fp != NULL; fp = fp->next)
+	    {
+	    fprintf(out, " %s %d", fp->fileName, fp->lineIx);
+	    }
+	fprintf(out, "\n");
+	}
     }
 fprintf(out, "\n");
 }
 
@@ -260,9 +277,9 @@
 void raSqlQuery(int inCount, char *inNames[], struct lineFile *query, char *mergeField, 
 	char *parentField, char *noInheritField, struct lm *lm, FILE *out)
 /* raSqlQuery - Do a SQL-like query on a RA file.. */
 {
-struct raRecord *raList = readRaRecords(inCount, inNames, mergeField, lm);
+struct raRecord *raList = readRaRecords(inCount, inNames, mergeField, clAddFile, lm);
 if (parentField != NULL)
     {
     addMissingKeys(raList, clKey);
     inheritFromParents(raList, parentField, noInheritField, lm);
@@ -280,9 +297,9 @@
         {
 	matchCount += 1;
 	if (doSelect)
 	    {
-	    rqlStatementOutput(rql, ra, out);
+	    rqlStatementOutput(rql, ra, (clAddFile ? "file" : NULL), out);
 	    }
 	}
     }
 if (!doSelect)
@@ -301,8 +318,9 @@
 clKey = optionVal("key", clKey);
 clQueryFile = optionVal("queryFile", NULL);
 clQuery = optionVal("query", NULL);
 clNoInheritField = optionVal("noInheritField", clNoInheritField);
+clAddFile = optionExists("addFile");
 if (clQueryFile == NULL && clQuery == NULL)
     errAbort("Please specify either the query or queryFile option.");
 if (clQueryFile != NULL && clQuery != NULL)
     errAbort("Please specify just one of the query or queryFile options.");