054cf0f3a8507c04aecde986ecee4f2979b8d4f3 chmalee Mon Nov 10 15:00:32 2025 -0800 Make listExisting endpoint to hubApi/liftOver respect fromGenome and toGenome arguments, taking precedence over the filter argument. If both fromGenome and toGenome arguments are present they are ANDed together diff --git src/hg/hubApi/liftOver.c src/hg/hubApi/liftOver.c index 8ce55f0346e..8592d415495 100644 --- src/hg/hubApi/liftOver.c +++ src/hg/hubApi/liftOver.c @@ -58,55 +58,67 @@ jsonWriteListStart(jw, NULL); jsonWriteString(jw, NULL, toDb); jsonWriteString(jw, NULL, position); jsonWriteString(jw, NULL, coverage); jsonWriteListEnd(jw); } jsonWriteListEnd(jw); apiFinishOutput(0, NULL, jw); } static void listExisting() /* output the fromDb,toDb from liftOverChain.hgcentral SQL table */ { long long itemCount = 0; char *filter = cgiOptionalString(argFilter); +char *fromDb = cgiOptionalString(argFromGenome); +char *toDb = cgiOptionalString(argToGenome); struct sqlConnection *conn = hConnectCentral(); char *tableName = cloneString(liftOverChainTable()); -char query[1024]; -sqlSafef(query, sizeof(query), "SELECT count(*) FROM %s", tableName); -long long totalRows = sqlQuickLongLong(conn, query); +struct dyString *query = newDyString(0); +sqlDyStringPrintf(query, "SELECT count(*) FROM %s", tableName); +long long totalRows = sqlQuickLongLong(conn, dyStringContents(query)); +dyStringClear(query); -if (isEmpty(filter)) +if (isNotEmpty(fromDb) || isNotEmpty(toDb)) { - sqlSafef(query, sizeof(query), "SELECT fromDb,toDb FROM %s LIMIT %d", tableName, maxItemsOutput); + sqlDyStringPrintf(query, "SELECT fromDb,toDb FROM %s WHERE ", tableName); + if (isNotEmpty(fromDb)) + sqlDyStringPrintf(query, "LOWER(fromDb) = LOWER('%s') %s ", fromDb, isNotEmpty(toDb) ? "AND" : ""); + if (isNotEmpty(toDb)) + sqlDyStringPrintf(query, "LOWER(toDb) = LOWER('%s') ", toDb); + sqlDyStringPrintf(query, "LIMIT %d;", maxItemsOutput); + } +else if (isNotEmpty(filter)) + { + sqlDyStringPrintf(query, "SELECT fromDb,toDb FROM %s WHERE LOWER(fromDb) = LOWER('%s') OR LOWER(toDb) = LOWER('%s') LIMIT %d;", tableName, filter, filter, maxItemsOutput); } else { - sqlSafef(query, sizeof(query), "SELECT fromDb,toDb FROM %s WHERE LOWER(fromDb) = LOWER('%s') OR LOWER(toDb) = LOWER('%s') LIMIT %d;", tableName, filter, filter, maxItemsOutput); + sqlDyStringPrintf(query, "SELECT fromDb,toDb FROM %s LIMIT %d", tableName, maxItemsOutput); } char *dataTime = sqlTableUpdate(conn, tableName); time_t dataTimeStamp = sqlDateToUnixTime(dataTime); replaceChar(dataTime, ' ', 'T'); /* ISO 8601 */ struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "dataTime", dataTime); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); jsonWriteListStart(jw, "existingLiftOvers"); -struct sqlResult *sr = sqlGetResult(conn, query); +struct sqlResult *sr = sqlGetResult(conn, dyStringCannibalize(&query)); char **row; while ((row = sqlNextRow(sr)) != NULL) { ++itemCount; jsonWriteListStart(jw, NULL); jsonWriteString(jw, NULL, row[0]); jsonWriteString(jw, NULL, row[1]); jsonWriteListEnd(jw); } jsonWriteListEnd(jw); jsonWriteNumber(jw, "totalLiftOvers", totalRows); jsonWriteNumber(jw, "itemsReturned", itemCount); apiFinishOutput(0, NULL, jw); hDisconnectCentral(&conn);