24992e962e50a3ba5ab93e1af502fde3a0b99893
hiram
  Mon Apr 8 14:31:37 2019 -0700
now supporting psl types refs #18869

diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c
index 933027c..363e1c0 100644
--- src/hg/hubApi/getData.c
+++ src/hg/hubApi/getData.c
@@ -31,94 +31,121 @@
 }
 
 static void jsonDatumOut(struct jsonWrite *jw, char *name, char *val,
     int jsonType)
 /* output a json item, determine type, appropriate output */
 {
 if (JSON_DOUBLE == jsonType)
     jsonWriteDouble(jw, name, sqlDouble(val));
 else if (JSON_NUMBER == jsonType)
     jsonWriteNumber(jw, name, sqlLongLong(val));
 else
     jsonWriteString(jw, name, val);
 }
 
 static void tableDataOutput(char *db, struct trackDb *tdb,
-    struct sqlConnection *conn, struct jsonWrite *jw, char *table,
+    struct sqlConnection *conn, struct jsonWrite *jw, char *track,
     char *chrom, unsigned start, unsigned end)
-/* output the SQL table data */
+/* output the SQL table data for given track */
 {
 char query[4096];
+/* might have a specific table defined instead of the track name */
+char *sqlTable = cloneString(track);
+char *tableName = trackDbSetting(tdb, "table");
+if (isNotEmpty(tableName))
+    {
+    freeMem(sqlTable);
+    sqlTable = cloneString(tableName);
+    jsonWriteString(jw, "sqlTable", sqlTable);
+    }
+
 /* no chrom specified, return entire table */
 if (isEmpty(chrom))
-    sqlSafef(query, sizeof(query), "select * from %s", table);
+    sqlSafef(query, sizeof(query), "select * from %s", sqlTable);
 else if (0 == (start + end))	/* have chrom, no start,end == full chr */
     {
+    boolean useTname = FALSE;
     /* need to extend the chrom column check to allow tName also */
-    if (! sqlColumnExists(conn, table, "chrom"))
-	apiErrAbort("track '%s' is not a position track, request track without chrom specification, genome: '%s'", table, db);
+    if (! sqlColumnExists(conn, sqlTable, "chrom"))
+	{
+        if (sqlColumnExists(conn, sqlTable, "tName"))	// track type psl
+	    useTname = TRUE;
+	else
+	    apiErrAbort("track '%s' is not a position track, request track without chrom specification, genome: '%s'", track, db);
+	}
     jsonWriteString(jw, "chrom", chrom);
     struct chromInfo *ci = hGetChromInfo(db, chrom);
     jsonWriteNumber(jw, "start", (long long)0);
     jsonWriteNumber(jw, "end", (long long)ci->size);
-    sqlSafef(query, sizeof(query), "select * from %s where chrom='%s'", table, chrom);
+    if (useTname)
+	sqlSafef(query, sizeof(query), "select * from %s where tName='%s'", sqlTable, chrom);
+    else
+	sqlSafef(query, sizeof(query), "select * from %s where chrom='%s'", sqlTable, chrom);
     }
 else	/* fully specified chrom:start-end */
     {
     boolean useTxStartEnd = FALSE;
-    if (! sqlColumnExists(conn, table, "chrom"))
-	apiErrAbort("track '%s' is not a position track, request track without chrom specification, genome: '%s'", table, db);
-    if (! sqlColumnExists(conn, table, "chromStart"))
+    boolean useTnameStartEnd = FALSE;
+    if (! sqlColumnExists(conn, sqlTable, "chrom"))
 	{
-        if (sqlColumnExists(conn, table, "txStart"))
+        if (sqlColumnExists(conn, sqlTable, "tName"))	// track type psl
+	    useTnameStartEnd = TRUE;
+	else
+	    apiErrAbort("track '%s' is not a position track, request track without chrom specification, genome: '%s'", track, db);
+        }
+    if (useTnameStartEnd || ! sqlColumnExists(conn, sqlTable, "chromStart"))
+	{
+        if (sqlColumnExists(conn, sqlTable, "txStart"))	// track type genePred
 	    useTxStartEnd = TRUE;
 	}
     jsonWriteString(jw, "chrom", chrom);
     jsonWriteNumber(jw, "start", (long long)start);
     jsonWriteNumber(jw, "end", (long long)end);
     if (startsWith("wig", tdb->type))
 	{
-        wigTableDataOutput(jw, db, table, chrom, start, end);
+        wigTableDataOutput(jw, db, sqlTable, chrom, start, end);
         return;	/* DONE */
 	}
     else
 	{
-	if (useTxStartEnd)
-	    sqlSafef(query, sizeof(query), "select * from %s where chrom='%s' AND txEnd > %u AND txStart < %u", table, chrom, start, end);
+	if (useTnameStartEnd)
+	    sqlSafef(query, sizeof(query), "select * from %s where tName='%s' AND tEnd > %u AND tEnd < %u", sqlTable, chrom, start, end);
+	else if (useTxStartEnd)
+	    sqlSafef(query, sizeof(query), "select * from %s where chrom='%s' AND txEnd > %u AND txStart < %u", sqlTable, chrom, start, end);
 	else
-	    sqlSafef(query, sizeof(query), "select * from %s where chrom='%s' AND chromEnd > %u AND chromStart < %u", table, chrom, start, end);
+	    sqlSafef(query, sizeof(query), "select * from %s where chrom='%s' AND chromEnd > %u AND chromStart < %u", sqlTable, chrom, start, end);
 	}
     }
 
 /* continuing, not a wiggle output */
 char **columnNames = NULL;
 char **columnTypes = NULL;
 int *jsonTypes = NULL;
-int columnCount = tableColumns(conn, jw, table, &columnNames, &columnTypes, &jsonTypes);
+int columnCount = tableColumns(conn, jw, sqlTable, &columnNames, &columnTypes, &jsonTypes);
 if (debug)
     {
     jsonWriteObjectStart(jw, "columnTypes");
     int i = 0;
     for (i = 0; i < columnCount; ++i)
 	{
 	char bothTypes[1024];
 	safef(bothTypes, sizeof(bothTypes), "%s - %s", columnTypes[i], jsonTypeStrings[jsonTypes[i]]);
 	jsonWriteString(jw, columnNames[i], bothTypes);
 	}
     jsonWriteObjectEnd(jw);
     }
-jsonWriteListStart(jw, table);
+jsonWriteListStart(jw, track);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 unsigned itemCount = 0;
 while (itemCount < maxItemsOutput && (row = sqlNextRow(sr)) != NULL)
     {
     jsonWriteObjectStart(jw, NULL);
     int i = 0;
     for (i = 0; i < columnCount; ++i)
 	{
 	jsonDatumOut(jw, columnNames[i], row[i], jsonTypes[i]);
 	}
     jsonWriteObjectEnd(jw);
     ++itemCount;
     }
 sqlFreeResult(&sr);