eb9622ef972f4e2b51d355a210d61defc2f64fcc
kate
  Tue Apr 24 20:25:04 2018 -0700
Fix table browser schema display for native track. refs #21109

diff --git src/hg/lib/interact.c src/hg/lib/interact.c
index 7bd2637..78bbbcc 100644
--- src/hg/lib/interact.c
+++ src/hg/lib/interact.c
@@ -1,375 +1,373 @@
 /* interact.c was originally generated by the autoSql program, which also 
  * generated interact.h and interact.sql.  This module links the database and
  * the RAM representation of objects. */
 
 #include "common.h"
 #include "linefile.h"
 #include "dystring.h"
 #include "jksql.h"
 #include "basicBed.h"
 #include "interact.h"
 
 
 
 char *interactCommaSepFieldNames = "chrom,chromStart,chromEnd,name,score,value,exp,color,sourceChrom,sourceStart,sourceEnd,sourceName,sourceStrand,targetChrom,targetStart,targetEnd,targetName,targetStrand";
 
 void interactStaticLoad(char **row, struct interact *ret)
 /* Load a row from interact table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->chrom = row[0];
 ret->chromStart = sqlUnsigned(row[1]);
 ret->chromEnd = sqlUnsigned(row[2]);
 ret->name = row[3];
 ret->score = sqlUnsigned(row[4]);
 ret->value = sqlDouble(row[5]);
 ret->exp = row[6];
 ret->color = sqlUnsigned(row[7]);
 ret->sourceChrom = row[8];
 ret->sourceStart = sqlUnsigned(row[9]);
 ret->sourceEnd = sqlUnsigned(row[10]);
 ret->sourceName = row[11];
 ret->sourceStrand = row[12];
 ret->targetChrom = row[13];
 ret->targetStart = sqlUnsigned(row[14]);
 ret->targetEnd = sqlUnsigned(row[15]);
 ret->targetName = row[16];
 ret->targetStrand = row[17];
 }
 
 struct interact *interactLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all interact from table that satisfy the query given.  
  * Where query is of the form 'select * from example where something=something'
  * or 'select example.* from example, anotherTable where example.something = 
  * anotherTable.something'.
  * Dispose of this with interactFreeList(). */
 {
 struct interact *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = interactLoad(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void interactSaveToDb(struct sqlConnection *conn, struct interact *el, char *tableName, int updateSize)
 /* Save interact as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. This function automatically escapes quoted strings for mysql. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s',%u,%u,'%s',%u,%g,'%s',%u,'%s',%u,%u,'%s','%s','%s',%u,%u,'%s','%s')", 
 	tableName,  el->chrom,  el->chromStart,  el->chromEnd,  el->name,  el->score,  el->value,  el->exp,  el->color,  el->sourceChrom,  el->sourceStart,  el->sourceEnd,  el->sourceName,  el->sourceStrand,  el->targetChrom,  el->targetStart,  el->targetEnd,  el->targetName,  el->targetStrand);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 struct interact *interactLoad(char **row)
 /* Load a interact from row fetched with select * from interact
  * from database.  Dispose of this with interactFree(). */
 {
 struct interact *ret;
 
 AllocVar(ret);
 ret->chrom = cloneString(row[0]);
 ret->chromStart = sqlUnsigned(row[1]);
 ret->chromEnd = sqlUnsigned(row[2]);
 ret->name = cloneString(row[3]);
 ret->score = sqlUnsigned(row[4]);
 ret->value = sqlDouble(row[5]);
 ret->exp = cloneString(row[6]);
 ret->color = sqlUnsigned(row[7]);
 ret->sourceChrom = cloneString(row[8]);
 ret->sourceStart = sqlUnsigned(row[9]);
 ret->sourceEnd = sqlUnsigned(row[10]);
 ret->sourceName = cloneString(row[11]);
 ret->sourceStrand = cloneString(row[12]);
 ret->targetChrom = cloneString(row[13]);
 ret->targetStart = sqlUnsigned(row[14]);
 ret->targetEnd = sqlUnsigned(row[15]);
 ret->targetName = cloneString(row[16]);
 ret->targetStrand = cloneString(row[17]);
 return ret;
 }
 
 struct interact *interactLoadAll(char *fileName) 
 /* Load all interact from a whitespace-separated file.
  * Dispose of this with interactFreeList(). */
 {
 struct interact *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[18];
 
 while (lineFileRow(lf, row))
     {
     el = interactLoad(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct interact *interactLoadAllByChar(char *fileName, char chopper) 
 /* Load all interact from a chopper separated file.
  * Dispose of this with interactFreeList(). */
 {
 struct interact *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[18];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = interactLoad(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct interact *interactCommaIn(char **pS, struct interact *ret)
 /* Create a interact out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new interact */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->chrom = sqlStringComma(&s);
 ret->chromStart = sqlUnsignedComma(&s);
 ret->chromEnd = sqlUnsignedComma(&s);
 ret->name = sqlStringComma(&s);
 ret->score = sqlUnsignedComma(&s);
 ret->value = sqlDoubleComma(&s);
 ret->exp = sqlStringComma(&s);
 ret->color = sqlUnsignedComma(&s);
 ret->sourceChrom = sqlStringComma(&s);
 ret->sourceStart = sqlUnsignedComma(&s);
 ret->sourceEnd = sqlUnsignedComma(&s);
 ret->sourceName = sqlStringComma(&s);
 ret->sourceStrand = sqlStringComma(&s);
 ret->targetChrom = sqlStringComma(&s);
 ret->targetStart = sqlUnsignedComma(&s);
 ret->targetEnd = sqlUnsignedComma(&s);
 ret->targetName = sqlStringComma(&s);
 ret->targetStrand = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void interactFree(struct interact **pEl)
 /* Free a single dynamically allocated interact such as created
  * with interactLoad(). */
 {
 struct interact *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->chrom);
 freeMem(el->name);
 freeMem(el->exp);
 freeMem(el->sourceChrom);
 freeMem(el->sourceName);
 freeMem(el->sourceStrand);
 freeMem(el->targetChrom);
 freeMem(el->targetName);
 freeMem(el->targetStrand);
 freez(pEl);
 }
 
 void interactFreeList(struct interact **pList)
 /* Free a list of dynamically allocated interact's */
 {
 struct interact *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     interactFree(&el);
     }
 *pList = NULL;
 }
 
 void interactOutput(struct interact *el, FILE *f, char sep, char lastSep) 
 /* Print out interact.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->chrom);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%u", el->chromStart);
 fputc(sep,f);
 fprintf(f, "%u", el->chromEnd);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->name);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%u", el->score);
 fputc(sep,f);
 fprintf(f, "%g", el->value);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->exp);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%u", el->color);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->sourceChrom);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%u", el->sourceStart);
 fputc(sep,f);
 fprintf(f, "%u", el->sourceEnd);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->sourceName);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->sourceStrand);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->targetChrom);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%u", el->targetStart);
 fputc(sep,f);
 fprintf(f, "%u", el->targetEnd);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->targetName);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->targetStrand);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 /* -------------------------------- End autoSql Generated Code -------------------------------- */
 
 static char *interactAutoSqlString =
 "table interact"
 "\"BED5+13 interaction between two regions\""
 "    ("
-"   string chrom;       \"Reference sequence chromosome or scaffold\""
-"   uint   chromStart;  \"Start position of lower region\""
-"   uint   chromEnd;    \"End position of upper region. For interchromsomal, set to chromStart+1.\""
+"   string chrom;       \"Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records\""
+"   uint   chromStart;  \"Start position of lower region. For chromosomal, set to chromStart of this region\""
+"   uint   chromEnd;    \"End position of upper region. For interchromsomal, set to chromEnd of this region\""
 "   string name;        \"Name or ID of item. Usually name1/name2 or name1/name2/exp or empty\""
 "   uint   score;       \"Score from 0-1000, typically derived from value\""
 "   double value;       \"Strength of interaction or other data value\""
-"   string exp;         \"Experiment name for filtering, or empty\""
+"   string exp;         \"Experiment name for filtering. Use . if not applicable\""
 "   uint   color;       \"Item color, as itemRgb in bed9.  Typically based on value or exp\""
-
-"   string sourceChrom; \"Chromosome of source region (directional) or lower region\""
-"   uint   sourceStart; \"Start position of source/lower region\""
-"   uint   sourceEnd;   \"End position of source/lower region\""
-"   string sourceName;  \"Identifier of source/lower region. Can be used as link to related table.\""
-"   string sourceStrand;\"Orientation of target/upper/other region: + or -.  Use . if not applicable.\""
-
-"   string targetChrom; \"Chromosome of target region (directional) or lower region\""
-"   uint   targetStart; \"Start position of target/lower region\""
-"   uint   targetEnd;   \"End position of target/lower region\""
-"   string targetName;  \"Identifier of target/lower region. Can be used as link to related table.\""
-"   string targetStrand;\"Orientation of target/lower/other region: + or -.  Use . if not applicable.\""
+"   string sourceChrom; \"Chromosome of source region (directional) or lower region. For non-directional interchromosomal, chrom of this region\""
+"   uint   sourceStart; \"Start position of source/lower/this region\""
+"   uint   sourceEnd;   \"End position of source/lower/this region\""
+"   string sourceName;  \"Identifier of source/lower/this region. Can be used as link to related table.\""
+"   string sourceStrand;\"Orientation of source/lower/this region: + or -.  Use . if not applicable.\""
+"   string targetChrom; \"Chromosome of target region (directional) or upper region. For non-directional interchromosomal, chrom of other region\""
+"   uint   targetStart; \"Start position of target/upper/this region\""
+"   uint   targetEnd;   \"End position of target/upper/this region\""
+"   string targetName;  \"Identifier of target/upper/this region. Can be used as link to related table.\""
+"   string targetStrand;\"Orientation of target/upper/this region: + or -.  Use . if not applicable.\""
 "   )"
 ;
 
 #include "asParse.h"
 
 struct asObject *interactAsObj()
 /* Return asObject describing fields of interact object */
 {   
 return asParseText(interactAutoSqlString);
 }   
 
 char *interactOtherChrom(struct interact *inter)
 /* Get other chromosome from an interaaction. Return NULL if same chromosome */
 {
 if (sameString(inter->sourceChrom, inter->targetChrom))
     return NULL;
 if (inter->chromStart == inter->sourceStart)
     return cloneString(inter->targetChrom);
 return cloneString(inter->sourceChrom);
 }
 
 int interactRegionCenter(int start, int end)
 /* Return genomic location of center of region */
 {
 return ((double)(end - start + .5) / 2) + start;
 }
 
 int interactRegionDistance(struct interact *inter)
 /* Return distance between region midpoints. Return -1 for other chromosome */
 {
 if (interactOtherChrom(inter))
     return -1;
 return abs(interactRegionCenter(inter->sourceStart, inter->sourceEnd) -
                 interactRegionCenter(inter->targetStart, inter->targetEnd));
 }
 
 int interactDistanceCmp(const void *va, const void *vb)
 /* Compare based on distance between region midpoints */
 {
 struct interact *a = *((struct interact **)va);
 struct interact *b = *((struct interact **)vb);
 
 int aDist = interactRegionDistance(a);
 int bDist = interactRegionDistance(b);
 
 // cross chromosome; always larger than same chrom
 if (aDist < 0)
     {
     if (bDist < 0)
         return 0;
     return 1;
     }
 if (bDist < 0)
     return -1;
 
 // same chromosome
 return aDist - bDist;
 }
 
 struct interact *interactLoadAndValidate(char **row)
 /* Load a interact from row fetched with select * from interact
  * from database, validating fields.  Dispose of this with interactFree(). */
 // TODO: more validating
 {
 struct interact *ret;
 
 AllocVar(ret);
 ret->chrom = cloneString(row[0]);
 ret->chromStart = sqlUnsigned(row[1]);
 ret->chromEnd = sqlUnsigned(row[2]);
 ret->name = cloneString(row[3]);
 ret->score = sqlUnsigned(row[4]);
 ret->value = sqlDouble(row[5]);
 ret->exp = cloneString(row[6]);
 ret->color = bedParseColor(row[7]);
 ret->sourceChrom = cloneString(row[8]);
 ret->sourceStart = sqlUnsigned(row[9]);
 ret->sourceEnd = sqlUnsigned(row[10]);
 ret->sourceName = cloneString(row[11]);
 ret->sourceStrand = cloneString(row[12]);
 ret->targetChrom = cloneString(row[13]);
 ret->targetStart = sqlUnsigned(row[14]);
 ret->targetEnd = sqlUnsigned(row[15]);
 ret->targetName = cloneString(row[16]);
 ret->targetStrand = cloneString(row[17]);
 return ret;
 }