0e092ec31d4d48d6a85f4e68d081bd92d88a92b7 hiram Wed Apr 17 14:18:30 2019 -0700 correct array output better timing and column header information refs #18869 diff --git src/hg/hubApi/apiUtils.c src/hg/hubApi/apiUtils.c index 558d13a..001e46f 100644 --- src/hg/hubApi/apiUtils.c +++ src/hg/hubApi/apiUtils.c @@ -1,45 +1,61 @@ /* utility functions for data API business */ #include "dataApi.h" +/* when measureTiming is used */ +static long processingStart = 0; + +void startProcessTiming() +/* for measureTiming, beginning processing */ +{ +processingStart = clock1000(); +} + void apiFinishOutput(int errorCode, char *errorString, struct jsonWrite *jw) /* finish json output, potential output an error code other than 200 */ { /* this is the first time any output to stdout has taken place for * json output, therefore, start with the appropriate header. */ puts("Content-Type:application/json"); /* potentially with an error code return in the header */ if (errorCode) { char errString[2048]; safef(errString, sizeof(errString), "Status: %d %s",errorCode,errorString); puts(errString); if (err429 == errorCode) puts("Retry-After: 30"); } puts("\n"); if (debug) { char sizeString[64]; unsigned long long vmPeak = currentVmPeak(); sprintLongWithCommas(sizeString, vmPeak); jsonWriteString(jw, "vmPeak", sizeString); } +if (measureTiming) + { + long nowTime = clock1000(); + long long et = nowTime - processingStart; + jsonWriteNumber(jw, "totalTimeMs", et); + } + jsonWriteObjectEnd(jw); fputs(jw->dy->string,stdout); } /* void apiFinishOutput(int errorCode, char *errorString, ... ) */ void apiErrAbort(int errorCode, char *errString, char *format, ...) /* Issue an error message in json format, and exit(0) */ { char errMsg[2048]; va_list args; va_start(args, format); vsnprintf(errMsg, sizeof(errMsg), format, args); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "error", errMsg); jsonWriteNumber(jw, "statusCode", errorCode); jsonWriteString(jw, "statusMessage", errString); @@ -150,60 +166,96 @@ ) typeIndex = JSON_NUMBER; else if (startsWith("float", asType)) typeIndex = JSON_DOUBLE; else if (startsWith("char", asType) || startsWith("string", asType) || startsWith("lstring", asType) || startsWith("enum", asType) || startsWith("set", asType) ) typeIndex = JSON_STRING; return typeIndex; } /* int asToJsonType(char *asType) */ +/* temporarily from table browser until proven works, then move to library */ +struct asObject *asForTable(struct sqlConnection *conn, char *table, + struct trackDb *tdb) +/* Get autoSQL description if any associated with table. */ +/* Wrap some error catching around asForTable. */ +{ +if (tdb != NULL) + return asForTdb(conn,tdb); + +// Some cases are for tables with no tdb! +struct asObject *asObj = NULL; +if (sqlTableExists(conn, "tableDescriptions")) + { + struct errCatch *errCatch = errCatchNew(); + if (errCatchStart(errCatch)) + { + char query[256]; + + sqlSafef(query, sizeof(query), + "select autoSqlDef from tableDescriptions where tableName='%s'", table); + char *asText = asText = sqlQuickString(conn, query); + + // If no result try split table. (not likely) + if (asText == NULL) + { + sqlSafef(query, sizeof(query), + "select autoSqlDef from tableDescriptions where tableName='chrN_%s'", table); + asText = sqlQuickString(conn, query); + } + if (asText != NULL && asText[0] != 0) + { + asObj = asParseText(asText); + } + freez(&asText); + } + errCatchEnd(errCatch); + errCatchFree(&errCatch); + } +return asObj; +} + int tableColumns(struct sqlConnection *conn, struct jsonWrite *jw, char *table, - char ***nameReturn, char ***typeReturn, int **jsonType) + char ***nameReturn, char ***typeReturn, int **jsonTypes) /* return the column names, and their MySQL data type, for the given table * return number of columns (aka 'fields') */ { -// not needed jsonWriteListStart(jw, "columnNames"); struct sqlFieldInfo *fi, *fiList = sqlFieldInfoGet(conn, table); int columnCount = slCount(fiList); char **namesReturn = NULL; char **typesReturn = NULL; int *jsonReturn = NULL; AllocArray(namesReturn, columnCount); AllocArray(typesReturn, columnCount); AllocArray(jsonReturn, columnCount); int i = 0; for (fi = fiList; fi; fi = fi->next) { namesReturn[i] = cloneString(fi->field); typesReturn[i] = cloneString(fi->type); jsonReturn[i] = sqlTypeToJsonType(fi->type); i++; -// not needed jsonWriteObjectStart(jw, NULL); -// not needed jsonWriteString(jw, fi->field, fi->type); -// not needed jsonWriteObjectEnd(jw); } -// not needed jsonWriteListEnd(jw); *nameReturn = namesReturn; *typeReturn = typesReturn; -*jsonType = jsonReturn; +*jsonTypes = jsonReturn; return columnCount; } struct trackHub *errCatchTrackHubOpen(char *hubUrl) /* use errCatch around a trackHub open in case it fails */ { struct trackHub *hub = NULL; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { hub = trackHubOpen(hubUrl, ""); } errCatchEnd(errCatch); if (errCatch->gotError) {