src/hg/instinct/bioInt2/bioIntDb.c 1.1

1.1 2009/03/20 06:06:31 jsanborn
initial commit
Index: src/hg/instinct/bioInt2/bioIntDb.c
===================================================================
RCS file: src/hg/instinct/bioInt2/bioIntDb.c
diff -N src/hg/instinct/bioInt2/bioIntDb.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/hg/instinct/bioInt2/bioIntDb.c	20 Mar 2009 06:06:31 -0000	1.1
@@ -0,0 +1,2828 @@
+/* bioIntDb.c was originally generated by the autoSql program, which also 
+ * generated bioIntDb.h and bioIntDb.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 "bioIntDb.h"
+
+static char const rcsid[] = "$Id$";
+
+void sqlFloatDynamicArrayFixedSize(char *s, float **retArray, int size)
+/* Convert comma separated list of numbers to an dynamically allocated
+ * array, which should be freeMem()'d when done. */
+{
+float *array = NULL;
+unsigned count = 0;
+
+AllocArray(array, size);
+for (;;)
+    {
+    char *e;
+    if (s == NULL || s[0] == 0 || count == size)
+	break;
+    e = strchr(s, ',');
+    if (e != NULL)
+	*e++ = 0;
+
+    array[count++] = atof(s);
+    s = e;
+    }
+*retArray = array;
+} 
+
+void pathwaysStaticLoad(char **row, struct pathways *ret)
+/* Load a row from pathways table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->name = row[1];
+ret->source = row[2];
+}
+
+struct pathways *pathwaysLoad(char **row)
+/* Load a pathways from row fetched with select * from pathways
+ * from database.  Dispose of this with pathwaysFree(). */
+{
+struct pathways *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->name = cloneString(row[1]);
+ret->source = cloneString(row[2]);
+return ret;
+}
+
+struct pathways *pathwaysLoadAll(char *fileName) 
+/* Load all pathways from a whitespace-separated file.
+ * Dispose of this with pathwaysFreeList(). */
+{
+struct pathways *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileRow(lf, row))
+    {
+    el = pathwaysLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathways *pathwaysLoadAllByChar(char *fileName, char chopper) 
+/* Load all pathways from a chopper separated file.
+ * Dispose of this with pathwaysFreeList(). */
+{
+struct pathways *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = pathwaysLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathways *pathwaysLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all pathways 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 pathwaysFreeList(). */
+{
+struct pathways *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = pathwaysLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void pathwaysSaveToDb(struct sqlConnection *conn, struct pathways *el, char *tableName, int updateSize)
+/* Save pathways 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use pathwaysSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s')", 
+	tableName,  el->id,  el->name,  el->source);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void pathwaysSaveToDbEscaped(struct sqlConnection *conn, struct pathways *el, char *tableName, int updateSize)
+/* Save pathways 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than pathwaysSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *name, *source;
+name = sqlEscapeString(el->name);
+source = sqlEscapeString(el->source);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s')", 
+	tableName,  el->id,  name,  source);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&name);
+freez(&source);
+}
+
+struct pathways *pathwaysCommaIn(char **pS, struct pathways *ret)
+/* Create a pathways out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new pathways */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+ret->source = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void pathwaysFree(struct pathways **pEl)
+/* Free a single dynamically allocated pathways such as created
+ * with pathwaysLoad(). */
+{
+struct pathways *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->name);
+freeMem(el->source);
+freez(pEl);
+}
+
+void pathwaysFreeList(struct pathways **pList)
+/* Free a list of dynamically allocated pathways's */
+{
+struct pathways *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    pathwaysFree(&el);
+    }
+*pList = NULL;
+}
+
+void pathwaysOutput(struct pathways *el, FILE *f, char sep, char lastSep) 
+/* Print out pathways.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->source);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void pathwayGenesStaticLoad(char **row, struct pathwayGenes *ret)
+/* Load a row from pathwayGenes table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->gene_id = sqlUnsigned(row[1]);
+}
+
+struct pathwayGenes *pathwayGenesLoad(char **row)
+/* Load a pathwayGenes from row fetched with select * from pathwayGenes
+ * from database.  Dispose of this with pathwayGenesFree(). */
+{
+struct pathwayGenes *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->gene_id = sqlUnsigned(row[1]);
+return ret;
+}
+
+struct pathwayGenes *pathwayGenesLoadAll(char *fileName) 
+/* Load all pathwayGenes from a whitespace-separated file.
+ * Dispose of this with pathwayGenesFreeList(). */
+{
+struct pathwayGenes *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = pathwayGenesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathwayGenes *pathwayGenesLoadAllByChar(char *fileName, char chopper) 
+/* Load all pathwayGenes from a chopper separated file.
+ * Dispose of this with pathwayGenesFreeList(). */
+{
+struct pathwayGenes *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = pathwayGenesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathwayGenes *pathwayGenesLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all pathwayGenes 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 pathwayGenesFreeList(). */
+{
+struct pathwayGenes *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = pathwayGenesLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void pathwayGenesSaveToDb(struct sqlConnection *conn, struct pathwayGenes *el, char *tableName, int updateSize)
+/* Save pathwayGenes 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use pathwayGenesSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u)", 
+	tableName,  el->id,  el->gene_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void pathwayGenesSaveToDbEscaped(struct sqlConnection *conn, struct pathwayGenes *el, char *tableName, int updateSize)
+/* Save pathwayGenes 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than pathwayGenesSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u)", 
+	tableName,  el->id,  el->gene_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+struct pathwayGenes *pathwayGenesCommaIn(char **pS, struct pathwayGenes *ret)
+/* Create a pathwayGenes out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new pathwayGenes */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->gene_id = sqlUnsignedComma(&s);
+*pS = s;
+return ret;
+}
+
+void pathwayGenesFree(struct pathwayGenes **pEl)
+/* Free a single dynamically allocated pathwayGenes such as created
+ * with pathwayGenesLoad(). */
+{
+struct pathwayGenes *el;
+
+if ((el = *pEl) == NULL) return;
+freez(pEl);
+}
+
+void pathwayGenesFreeList(struct pathwayGenes **pList)
+/* Free a list of dynamically allocated pathwayGenes's */
+{
+struct pathwayGenes *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    pathwayGenesFree(&el);
+    }
+*pList = NULL;
+}
+
+void pathwayGenesOutput(struct pathwayGenes *el, FILE *f, char sep, char lastSep) 
+/* Print out pathwayGenes.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+fprintf(f, "%u", el->gene_id);
+fputc(lastSep,f);
+}
+
+void pathwayInfoStaticLoad(char **row, struct pathwayInfo *ret)
+/* Load a row from pathwayInfo table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->description = row[1];
+}
+
+struct pathwayInfo *pathwayInfoLoad(char **row)
+/* Load a pathwayInfo from row fetched with select * from pathwayInfo
+ * from database.  Dispose of this with pathwayInfoFree(). */
+{
+struct pathwayInfo *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->description = cloneString(row[1]);
+return ret;
+}
+
+struct pathwayInfo *pathwayInfoLoadAll(char *fileName) 
+/* Load all pathwayInfo from a whitespace-separated file.
+ * Dispose of this with pathwayInfoFreeList(). */
+{
+struct pathwayInfo *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = pathwayInfoLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathwayInfo *pathwayInfoLoadAllByChar(char *fileName, char chopper) 
+/* Load all pathwayInfo from a chopper separated file.
+ * Dispose of this with pathwayInfoFreeList(). */
+{
+struct pathwayInfo *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = pathwayInfoLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct pathwayInfo *pathwayInfoLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all pathwayInfo 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 pathwayInfoFreeList(). */
+{
+struct pathwayInfo *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = pathwayInfoLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void pathwayInfoSaveToDb(struct sqlConnection *conn, struct pathwayInfo *el, char *tableName, int updateSize)
+/* Save pathwayInfo 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use pathwayInfoSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%s)", 
+	tableName,  el->id,  el->description);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void pathwayInfoSaveToDbEscaped(struct sqlConnection *conn, struct pathwayInfo *el, char *tableName, int updateSize)
+/* Save pathwayInfo 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than pathwayInfoSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *description;
+description = sqlEscapeString(el->description);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->id,  description);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&description);
+}
+
+struct pathwayInfo *pathwayInfoCommaIn(char **pS, struct pathwayInfo *ret)
+/* Create a pathwayInfo out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new pathwayInfo */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->description = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void pathwayInfoFree(struct pathwayInfo **pEl)
+/* Free a single dynamically allocated pathwayInfo such as created
+ * with pathwayInfoLoad(). */
+{
+struct pathwayInfo *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->description);
+freez(pEl);
+}
+
+void pathwayInfoFreeList(struct pathwayInfo **pList)
+/* Free a list of dynamically allocated pathwayInfo's */
+{
+struct pathwayInfo *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    pathwayInfoFree(&el);
+    }
+*pList = NULL;
+}
+
+void pathwayInfoOutput(struct pathwayInfo *el, FILE *f, char sep, char lastSep) 
+/* Print out pathwayInfo.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->description);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void tissuesStaticLoad(char **row, struct tissues *ret)
+/* Load a row from tissues table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->name = row[1];
+}
+
+struct tissues *tissuesLoad(char **row)
+/* Load a tissues from row fetched with select * from tissues
+ * from database.  Dispose of this with tissuesFree(). */
+{
+struct tissues *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->name = cloneString(row[1]);
+return ret;
+}
+
+struct tissues *tissuesLoadAll(char *fileName) 
+/* Load all tissues from a whitespace-separated file.
+ * Dispose of this with tissuesFreeList(). */
+{
+struct tissues *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = tissuesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct tissues *tissuesLoadAllByChar(char *fileName, char chopper) 
+/* Load all tissues from a chopper separated file.
+ * Dispose of this with tissuesFreeList(). */
+{
+struct tissues *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = tissuesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct tissues *tissuesLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all tissues 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 tissuesFreeList(). */
+{
+struct tissues *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = tissuesLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void tissuesSaveToDb(struct sqlConnection *conn, struct tissues *el, char *tableName, int updateSize)
+/* Save tissues 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use tissuesSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->id,  el->name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void tissuesSaveToDbEscaped(struct sqlConnection *conn, struct tissues *el, char *tableName, int updateSize)
+/* Save tissues 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than tissuesSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *name;
+name = sqlEscapeString(el->name);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->id,  name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&name);
+}
+
+struct tissues *tissuesCommaIn(char **pS, struct tissues *ret)
+/* Create a tissues out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new tissues */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void tissuesFree(struct tissues **pEl)
+/* Free a single dynamically allocated tissues such as created
+ * with tissuesLoad(). */
+{
+struct tissues *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->name);
+freez(pEl);
+}
+
+void tissuesFreeList(struct tissues **pList)
+/* Free a list of dynamically allocated tissues's */
+{
+struct tissues *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    tissuesFree(&el);
+    }
+*pList = NULL;
+}
+
+void tissuesOutput(struct tissues *el, FILE *f, char sep, char lastSep) 
+/* Print out tissues.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void dataTypesStaticLoad(char **row, struct dataTypes *ret)
+/* Load a row from dataTypes table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->format = row[1];
+ret->name = row[2];
+}
+
+struct dataTypes *dataTypesLoad(char **row)
+/* Load a dataTypes from row fetched with select * from dataTypes
+ * from database.  Dispose of this with dataTypesFree(). */
+{
+struct dataTypes *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->format = cloneString(row[1]);
+ret->name = cloneString(row[2]);
+return ret;
+}
+
+struct dataTypes *dataTypesLoadAll(char *fileName) 
+/* Load all dataTypes from a whitespace-separated file.
+ * Dispose of this with dataTypesFreeList(). */
+{
+struct dataTypes *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileRow(lf, row))
+    {
+    el = dataTypesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct dataTypes *dataTypesLoadAllByChar(char *fileName, char chopper) 
+/* Load all dataTypes from a chopper separated file.
+ * Dispose of this with dataTypesFreeList(). */
+{
+struct dataTypes *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = dataTypesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct dataTypes *dataTypesLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all dataTypes 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 dataTypesFreeList(). */
+{
+struct dataTypes *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = dataTypesLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void dataTypesSaveToDb(struct sqlConnection *conn, struct dataTypes *el, char *tableName, int updateSize)
+/* Save dataTypes 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use dataTypesSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s')", 
+	tableName,  el->id,  el->format,  el->name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void dataTypesSaveToDbEscaped(struct sqlConnection *conn, struct dataTypes *el, char *tableName, int updateSize)
+/* Save dataTypes 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than dataTypesSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *format, *name;
+format = sqlEscapeString(el->format);
+name = sqlEscapeString(el->name);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s')", 
+	tableName,  el->id,  format,  name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&format);
+freez(&name);
+}
+
+struct dataTypes *dataTypesCommaIn(char **pS, struct dataTypes *ret)
+/* Create a dataTypes out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new dataTypes */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->format = sqlStringComma(&s);
+ret->name = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void dataTypesFree(struct dataTypes **pEl)
+/* Free a single dynamically allocated dataTypes such as created
+ * with dataTypesLoad(). */
+{
+struct dataTypes *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->format);
+freeMem(el->name);
+freez(pEl);
+}
+
+void dataTypesFreeList(struct dataTypes **pList)
+/* Free a list of dynamically allocated dataTypes's */
+{
+struct dataTypes *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    dataTypesFree(&el);
+    }
+*pList = NULL;
+}
+
+void dataTypesOutput(struct dataTypes *el, FILE *f, char sep, char lastSep) 
+/* Print out dataTypes.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->format);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void datasetsStaticLoad(char **row, struct datasets *ret)
+/* Load a row from datasets table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->tissue_id = sqlUnsigned(row[1]);
+ret->type_id = sqlUnsigned(row[2]);
+ret->num_samples = sqlUnsigned(row[3]);
+ret->name = row[4];
+ret->data_table = row[5];
+ret->probe_table = row[6];
+ret->probe_to_gene_table = row[7];
+}
+
+struct datasets *datasetsLoad(char **row)
+/* Load a datasets from row fetched with select * from datasets
+ * from database.  Dispose of this with datasetsFree(). */
+{
+struct datasets *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->tissue_id = sqlUnsigned(row[1]);
+ret->type_id = sqlUnsigned(row[2]);
+ret->num_samples = sqlUnsigned(row[3]);
+ret->name = cloneString(row[4]);
+ret->data_table = cloneString(row[5]);
+ret->probe_table = cloneString(row[6]);
+ret->probe_to_gene_table = cloneString(row[7]);
+return ret;
+}
+
+struct datasets *datasetsLoadAll(char *fileName) 
+/* Load all datasets from a whitespace-separated file.
+ * Dispose of this with datasetsFreeList(). */
+{
+struct datasets *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[8];
+
+while (lineFileRow(lf, row))
+    {
+    el = datasetsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct datasets *datasetsLoadAllByChar(char *fileName, char chopper) 
+/* Load all datasets from a chopper separated file.
+ * Dispose of this with datasetsFreeList(). */
+{
+struct datasets *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[8];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = datasetsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct datasets *datasetsLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all datasets 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 datasetsFreeList(). */
+{
+struct datasets *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = datasetsLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void datasetsSaveToDb(struct sqlConnection *conn, struct datasets *el, char *tableName, int updateSize)
+/* Save datasets 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use datasetsSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%u,%u,'%s','%s','%s','%s')", 
+	tableName,  el->id,  el->tissue_id,  el->type_id,  el->num_samples,  el->name,  el->data_table,  el->probe_table,  el->probe_to_gene_table);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void datasetsSaveToDbEscaped(struct sqlConnection *conn, struct datasets *el, char *tableName, int updateSize)
+/* Save datasets 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than datasetsSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *name, *data_table, *probe_table, *probe_to_gene_table;
+name = sqlEscapeString(el->name);
+data_table = sqlEscapeString(el->data_table);
+probe_table = sqlEscapeString(el->probe_table);
+probe_to_gene_table = sqlEscapeString(el->probe_to_gene_table);
+
+dyStringPrintf(update, "insert into %s values ( %u,%u,%u,%u,'%s','%s','%s','%s')", 
+	tableName,  el->id,  el->tissue_id,  el->type_id,  el->num_samples,  name,  data_table,  probe_table,  probe_to_gene_table);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&name);
+freez(&data_table);
+freez(&probe_table);
+freez(&probe_to_gene_table);
+}
+
+struct datasets *datasetsCommaIn(char **pS, struct datasets *ret)
+/* Create a datasets out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new datasets */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->tissue_id = sqlUnsignedComma(&s);
+ret->type_id = sqlUnsignedComma(&s);
+ret->num_samples = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+ret->data_table = sqlStringComma(&s);
+ret->probe_table = sqlStringComma(&s);
+ret->probe_to_gene_table = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void datasetsFree(struct datasets **pEl)
+/* Free a single dynamically allocated datasets such as created
+ * with datasetsLoad(). */
+{
+struct datasets *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->name);
+freeMem(el->data_table);
+freeMem(el->probe_table);
+freeMem(el->probe_to_gene_table);
+freez(pEl);
+}
+
+void datasetsFreeList(struct datasets **pList)
+/* Free a list of dynamically allocated datasets's */
+{
+struct datasets *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    datasetsFree(&el);
+    }
+*pList = NULL;
+}
+
+void datasetsOutput(struct datasets *el, FILE *f, char sep, char lastSep) 
+/* Print out datasets.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+fprintf(f, "%u", el->tissue_id);
+fputc(sep,f);
+fprintf(f, "%u", el->type_id);
+fputc(sep,f);
+fprintf(f, "%u", el->num_samples);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->data_table);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->probe_table);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->probe_to_gene_table);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void geneLookupStaticLoad(char **row, struct geneLookup *ret)
+/* Load a row from geneLookup table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->kgId = row[1];
+}
+
+struct geneLookup *geneLookupLoad(char **row)
+/* Load a geneLookup from row fetched with select * from geneLookup
+ * from database.  Dispose of this with geneLookupFree(). */
+{
+struct geneLookup *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->kgId = cloneString(row[1]);
+return ret;
+}
+
+struct geneLookup *geneLookupLoadAll(char *fileName) 
+/* Load all geneLookup from a whitespace-separated file.
+ * Dispose of this with geneLookupFreeList(). */
+{
+struct geneLookup *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = geneLookupLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct geneLookup *geneLookupLoadAllByChar(char *fileName, char chopper) 
+/* Load all geneLookup from a chopper separated file.
+ * Dispose of this with geneLookupFreeList(). */
+{
+struct geneLookup *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = geneLookupLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct geneLookup *geneLookupLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all geneLookup 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 geneLookupFreeList(). */
+{
+struct geneLookup *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = geneLookupLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void geneLookupSaveToDb(struct sqlConnection *conn, struct geneLookup *el, char *tableName, int updateSize)
+/* Save geneLookup 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use geneLookupSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->id,  el->kgId);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void geneLookupSaveToDbEscaped(struct sqlConnection *conn, struct geneLookup *el, char *tableName, int updateSize)
+/* Save geneLookup 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than geneLookupSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *kgId;
+kgId = sqlEscapeString(el->kgId);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->id,  kgId);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&kgId);
+}
+
+struct geneLookup *geneLookupCommaIn(char **pS, struct geneLookup *ret)
+/* Create a geneLookup out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new geneLookup */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->kgId = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void geneLookupFree(struct geneLookup **pEl)
+/* Free a single dynamically allocated geneLookup such as created
+ * with geneLookupLoad(). */
+{
+struct geneLookup *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->kgId);
+freez(pEl);
+}
+
+void geneLookupFreeList(struct geneLookup **pList)
+/* Free a list of dynamically allocated geneLookup's */
+{
+struct geneLookup *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    geneLookupFree(&el);
+    }
+*pList = NULL;
+}
+
+void geneLookupOutput(struct geneLookup *el, FILE *f, char sep, char lastSep) 
+/* Print out geneLookup.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->kgId);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void probeInfoStaticLoad(char **row, struct probeInfo *ret)
+/* Load a row from probeInfo table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->chrom = row[1];
+ret->start = sqlUnsigned(row[2]);
+ret->stop = sqlUnsigned(row[3]);
+ret->name = row[4];
+}
+
+struct probeInfo *probeInfoLoad(char **row)
+/* Load a probeInfo from row fetched with select * from probeInfo
+ * from database.  Dispose of this with probeInfoFree(). */
+{
+struct probeInfo *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->chrom = cloneString(row[1]);
+ret->start = sqlUnsigned(row[2]);
+ret->stop = sqlUnsigned(row[3]);
+ret->name = cloneString(row[4]);
+return ret;
+}
+
+struct probeInfo *probeInfoLoadAll(char *fileName) 
+/* Load all probeInfo from a whitespace-separated file.
+ * Dispose of this with probeInfoFreeList(). */
+{
+struct probeInfo *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[5];
+
+while (lineFileRow(lf, row))
+    {
+    el = probeInfoLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeInfo *probeInfoLoadAllByChar(char *fileName, char chopper) 
+/* Load all probeInfo from a chopper separated file.
+ * Dispose of this with probeInfoFreeList(). */
+{
+struct probeInfo *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[5];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = probeInfoLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeInfo *probeInfoLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all probeInfo 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 probeInfoFreeList(). */
+{
+struct probeInfo *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = probeInfoLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void probeInfoSaveToDb(struct sqlConnection *conn, struct probeInfo *el, char *tableName, int updateSize)
+/* Save probeInfo 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use probeInfoSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s')", 
+	tableName,  el->id,  el->chrom,  el->start,  el->stop,  el->name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void probeInfoSaveToDbEscaped(struct sqlConnection *conn, struct probeInfo *el, char *tableName, int updateSize)
+/* Save probeInfo 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than probeInfoSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *chrom, *name;
+chrom = sqlEscapeString(el->chrom);
+name = sqlEscapeString(el->name);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s')", 
+	tableName,  el->id,  chrom,  el->start,  el->stop,  name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&chrom);
+freez(&name);
+}
+
+struct probeInfo *probeInfoCommaIn(char **pS, struct probeInfo *ret)
+/* Create a probeInfo out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new probeInfo */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->chrom = sqlStringComma(&s);
+ret->start = sqlUnsignedComma(&s);
+ret->stop = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void probeInfoFree(struct probeInfo **pEl)
+/* Free a single dynamically allocated probeInfo such as created
+ * with probeInfoLoad(). */
+{
+struct probeInfo *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->chrom);
+freeMem(el->name);
+freez(pEl);
+}
+
+void probeInfoFreeList(struct probeInfo **pList)
+/* Free a list of dynamically allocated probeInfo's */
+{
+struct probeInfo *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    probeInfoFree(&el);
+    }
+*pList = NULL;
+}
+
+void probeInfoOutput(struct probeInfo *el, FILE *f, char sep, char lastSep) 
+/* Print out probeInfo.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->chrom);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+fprintf(f, "%u", el->start);
+fputc(sep,f);
+fprintf(f, "%u", el->stop);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void probeToGeneStaticLoad(char **row, struct probeToGene *ret)
+/* Load a row from probeToGene table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->probe_id = sqlUnsigned(row[0]);
+ret->gene_id = sqlUnsigned(row[1]);
+}
+
+struct probeToGene *probeToGeneLoad(char **row)
+/* Load a probeToGene from row fetched with select * from probeToGene
+ * from database.  Dispose of this with probeToGeneFree(). */
+{
+struct probeToGene *ret;
+
+AllocVar(ret);
+ret->probe_id = sqlUnsigned(row[0]);
+ret->gene_id = sqlUnsigned(row[1]);
+return ret;
+}
+
+struct probeToGene *probeToGeneLoadAll(char *fileName) 
+/* Load all probeToGene from a whitespace-separated file.
+ * Dispose of this with probeToGeneFreeList(). */
+{
+struct probeToGene *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = probeToGeneLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeToGene *probeToGeneLoadAllByChar(char *fileName, char chopper) 
+/* Load all probeToGene from a chopper separated file.
+ * Dispose of this with probeToGeneFreeList(). */
+{
+struct probeToGene *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = probeToGeneLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeToGene *probeToGeneLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all probeToGene 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 probeToGeneFreeList(). */
+{
+struct probeToGene *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = probeToGeneLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void probeToGeneSaveToDb(struct sqlConnection *conn, struct probeToGene *el, char *tableName, int updateSize)
+/* Save probeToGene 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use probeToGeneSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u)", 
+	tableName,  el->probe_id,  el->gene_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void probeToGeneSaveToDbEscaped(struct sqlConnection *conn, struct probeToGene *el, char *tableName, int updateSize)
+/* Save probeToGene 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than probeToGeneSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u)", 
+	tableName,  el->probe_id,  el->gene_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+struct probeToGene *probeToGeneCommaIn(char **pS, struct probeToGene *ret)
+/* Create a probeToGene out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new probeToGene */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->probe_id = sqlUnsignedComma(&s);
+ret->gene_id = sqlUnsignedComma(&s);
+*pS = s;
+return ret;
+}
+
+void probeToGeneFree(struct probeToGene **pEl)
+/* Free a single dynamically allocated probeToGene such as created
+ * with probeToGeneLoad(). */
+{
+struct probeToGene *el;
+
+if ((el = *pEl) == NULL) return;
+freez(pEl);
+}
+
+void probeToGeneFreeList(struct probeToGene **pList)
+/* Free a list of dynamically allocated probeToGene's */
+{
+struct probeToGene *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    probeToGeneFree(&el);
+    }
+*pList = NULL;
+}
+
+void probeToGeneOutput(struct probeToGene *el, FILE *f, char sep, char lastSep) 
+/* Print out probeToGene.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->probe_id);
+fputc(sep,f);
+fprintf(f, "%u", el->gene_id);
+fputc(lastSep,f);
+}
+
+void probeSampleValStaticLoad(char **row, struct probeSampleVal *ret)
+/* Load a row from probeSampleVal table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->probe_id = sqlUnsigned(row[0]);
+ret->sample_id = sqlUnsigned(row[1]);
+ret->val = sqlFloat(row[2]);
+}
+
+struct probeSampleVal *probeSampleValLoad(char **row)
+/* Load a probeSampleVal from row fetched with select * from probeSampleVal
+ * from database.  Dispose of this with probeSampleValFree(). */
+{
+struct probeSampleVal *ret;
+
+AllocVar(ret);
+ret->probe_id = sqlUnsigned(row[0]);
+ret->sample_id = sqlUnsigned(row[1]);
+ret->val = sqlFloat(row[2]);
+return ret;
+}
+
+struct probeSampleVal *probeSampleValLoadAll(char *fileName) 
+/* Load all probeSampleVal from a whitespace-separated file.
+ * Dispose of this with probeSampleValFreeList(). */
+{
+struct probeSampleVal *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileRow(lf, row))
+    {
+    el = probeSampleValLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeSampleVal *probeSampleValLoadAllByChar(char *fileName, char chopper) 
+/* Load all probeSampleVal from a chopper separated file.
+ * Dispose of this with probeSampleValFreeList(). */
+{
+struct probeSampleVal *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = probeSampleValLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeSampleVal *probeSampleValLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all probeSampleVal 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 probeSampleValFreeList(). */
+{
+struct probeSampleVal *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = probeSampleValLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void probeSampleValSaveToDb(struct sqlConnection *conn, struct probeSampleVal *el, char *tableName, int updateSize)
+/* Save probeSampleVal 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use probeSampleValSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g)", 
+	tableName,  el->probe_id,  el->sample_id,  el->val);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void probeSampleValSaveToDbEscaped(struct sqlConnection *conn, struct probeSampleVal *el, char *tableName, int updateSize)
+/* Save probeSampleVal 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than probeSampleValSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g)", 
+	tableName,  el->probe_id,  el->sample_id,  el->val);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+struct probeSampleVal *probeSampleValCommaIn(char **pS, struct probeSampleVal *ret)
+/* Create a probeSampleVal out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new probeSampleVal */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->probe_id = sqlUnsignedComma(&s);
+ret->sample_id = sqlUnsignedComma(&s);
+ret->val = sqlFloatComma(&s);
+*pS = s;
+return ret;
+}
+
+void probeSampleValFree(struct probeSampleVal **pEl)
+/* Free a single dynamically allocated probeSampleVal such as created
+ * with probeSampleValLoad(). */
+{
+struct probeSampleVal *el;
+
+if ((el = *pEl) == NULL) return;
+freez(pEl);
+}
+
+void probeSampleValFreeList(struct probeSampleVal **pList)
+/* Free a list of dynamically allocated probeSampleVal's */
+{
+struct probeSampleVal *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    probeSampleValFree(&el);
+    }
+*pList = NULL;
+}
+
+void probeSampleValOutput(struct probeSampleVal *el, FILE *f, char sep, char lastSep) 
+/* Print out probeSampleVal.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->probe_id);
+fputc(sep,f);
+fprintf(f, "%u", el->sample_id);
+fputc(sep,f);
+fprintf(f, "%g", el->val);
+fputc(lastSep,f);
+}
+
+struct probeVals *probeValsLoad(char **row)
+/* Load a probeVals from row fetched with select * from probeVals
+ * from database.  Dispose of this with probeValsFree(). */
+{
+struct probeVals *ret;
+
+AllocVar(ret);
+ret->sample_count = sqlUnsigned(row[1]);
+ret->probe_id = sqlUnsigned(row[0]);
+{
+sqlFloatDynamicArrayFixedSize(row[2], &ret->sample_data, ret->sample_count); 
+//int sizeOne;
+//sqlFloatDynamicArray(row[2], &ret->sample_data, &sizeOne);
+//assert(sizeOne == ret->sample_count);
+}
+return ret;
+}
+
+struct probeVals *probeValsLoadAll(char *fileName) 
+/* Load all probeVals from a whitespace-separated file.
+ * Dispose of this with probeValsFreeList(). */
+{
+struct probeVals *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileRow(lf, row))
+    {
+    el = probeValsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeVals *probeValsLoadAllByChar(char *fileName, char chopper) 
+/* Load all probeVals from a chopper separated file.
+ * Dispose of this with probeValsFreeList(). */
+{
+struct probeVals *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[3];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = probeValsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct probeVals *probeValsLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all probeVals 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 probeValsFreeList(). */
+{
+struct probeVals *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = probeValsLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void probeValsSaveToDb(struct sqlConnection *conn, struct probeVals *el, char *tableName, int updateSize)
+/* Save probeVals 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use probeValsSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+char  *sample_dataArray;
+sample_dataArray = sqlFloatArrayToString(el->sample_data, el->sample_count);
+dyStringPrintf(update, "insert into %s values ( %u,%u,'%s')", 
+	tableName,  el->probe_id,  el->sample_count,  sample_dataArray );
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&sample_dataArray);
+}
+
+void probeValsSaveToDbEscaped(struct sqlConnection *conn, struct probeVals *el, char *tableName, int updateSize)
+/* Save probeVals 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than probeValsSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *sample_dataArray;
+
+sample_dataArray = sqlFloatArrayToString(el->sample_data, el->sample_count);
+dyStringPrintf(update, "insert into %s values ( %u,%u,'%s')", 
+	tableName,  el->probe_id,  el->sample_count,  sample_dataArray );
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+struct probeVals *probeValsCommaIn(char **pS, struct probeVals *ret)
+/* Create a probeVals out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new probeVals */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->probe_id = sqlUnsignedComma(&s);
+ret->sample_count = sqlUnsignedComma(&s);
+{
+int i;
+s = sqlEatChar(s, '{');
+AllocArray(ret->sample_data, ret->sample_count);
+for (i=0; i<ret->sample_count; ++i)
+    {
+    ret->sample_data[i] = sqlFloatComma(&s);
+    }
+s = sqlEatChar(s, '}');
+s = sqlEatChar(s, ',');
+}
+*pS = s;
+return ret;
+}
+
+void probeValsFree(struct probeVals **pEl)
+/* Free a single dynamically allocated probeVals such as created
+ * with probeValsLoad(). */
+{
+struct probeVals *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->sample_data);
+freez(pEl);
+}
+
+void probeValsFreeList(struct probeVals **pList)
+/* Free a list of dynamically allocated probeVals's */
+{
+struct probeVals *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    probeValsFree(&el);
+    }
+*pList = NULL;
+}
+
+void probeValsOutput(struct probeVals *el, FILE *f, char sep, char lastSep) 
+/* Print out probeVals.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->probe_id);
+fputc(sep,f);
+fprintf(f, "%u", el->sample_count);
+fputc(sep,f);
+{
+int i;
+if (sep == ',') fputc('{',f);
+for (i=0; i<el->sample_count; ++i)
+    {
+    fprintf(f, "%g", el->sample_data[i]);
+    fputc(',', f);
+    }
+if (sep == ',') fputc('}',f);
+}
+fputc(lastSep,f);
+}
+
+void samplesStaticLoad(char **row, struct samples *ret)
+/* Load a row from samples table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->name = row[1];
+ret->patient_id = sqlUnsigned(row[2]);
+ret->patient_name = row[3];
+ret->dataset_id = sqlUnsigned(row[4]);
+ret->exp_id = sqlUnsigned(row[5]);
+ret->tissue_id = sqlUnsigned(row[6]);
+}
+
+struct samples *samplesLoad(char **row)
+/* Load a samples from row fetched with select * from samples
+ * from database.  Dispose of this with samplesFree(). */
+{
+struct samples *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->name = cloneString(row[1]);
+ret->patient_id = sqlUnsigned(row[2]);
+ret->patient_name = cloneString(row[3]);
+ret->dataset_id = sqlUnsigned(row[4]);
+ret->exp_id = sqlUnsigned(row[5]);
+ret->tissue_id = sqlUnsigned(row[6]);
+return ret;
+}
+
+struct samples *samplesLoadAll(char *fileName) 
+/* Load all samples from a whitespace-separated file.
+ * Dispose of this with samplesFreeList(). */
+{
+struct samples *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[7];
+
+while (lineFileRow(lf, row))
+    {
+    el = samplesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct samples *samplesLoadAllByChar(char *fileName, char chopper) 
+/* Load all samples from a chopper separated file.
+ * Dispose of this with samplesFreeList(). */
+{
+struct samples *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[7];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = samplesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct samples *samplesLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all samples 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 samplesFreeList(). */
+{
+struct samples *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = samplesLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void samplesSaveToDb(struct sqlConnection *conn, struct samples *el, char *tableName, int updateSize)
+/* Save samples 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use samplesSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,'%s',%u,%u,%u)", 
+	tableName,  el->id,  el->name,  el->patient_id,  el->patient_name,  el->dataset_id,  el->exp_id,  el->tissue_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void samplesSaveToDbEscaped(struct sqlConnection *conn, struct samples *el, char *tableName, int updateSize)
+/* Save samples 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than samplesSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *name, *patient_name;
+name = sqlEscapeString(el->name);
+patient_name = sqlEscapeString(el->patient_name);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,'%s',%u,%u,%u)", 
+	tableName,  el->id,  name,  el->patient_id,  patient_name,  el->dataset_id,  el->exp_id,  el->tissue_id);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&name);
+freez(&patient_name);
+}
+
+struct samples *samplesCommaIn(char **pS, struct samples *ret)
+/* Create a samples out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new samples */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+ret->patient_id = sqlUnsignedComma(&s);
+ret->patient_name = sqlStringComma(&s);
+ret->dataset_id = sqlUnsignedComma(&s);
+ret->exp_id = sqlUnsignedComma(&s);
+ret->tissue_id = sqlUnsignedComma(&s);
+*pS = s;
+return ret;
+}
+
+void samplesFree(struct samples **pEl)
+/* Free a single dynamically allocated samples such as created
+ * with samplesLoad(). */
+{
+struct samples *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->name);
+freeMem(el->patient_name);
+freez(pEl);
+}
+
+void samplesFreeList(struct samples **pList)
+/* Free a list of dynamically allocated samples's */
+{
+struct samples *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    samplesFree(&el);
+    }
+*pList = NULL;
+}
+
+void samplesOutput(struct samples *el, FILE *f, char sep, char lastSep) 
+/* Print out samples.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+fprintf(f, "%u", el->patient_id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->patient_name);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+fprintf(f, "%u", el->dataset_id);
+fputc(sep,f);
+fprintf(f, "%u", el->exp_id);
+fputc(sep,f);
+fprintf(f, "%u", el->tissue_id);
+fputc(lastSep,f);
+}
+
+void featuresStaticLoad(char **row, struct features *ret)
+/* Load a row from features table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->id = sqlUnsigned(row[0]);
+ret->name = row[1];
+ret->shortLabel = row[2];
+ret->longLabel = row[3];
+}
+
+struct features *featuresLoad(char **row)
+/* Load a features from row fetched with select * from features
+ * from database.  Dispose of this with featuresFree(). */
+{
+struct features *ret;
+
+AllocVar(ret);
+ret->id = sqlUnsigned(row[0]);
+ret->name = cloneString(row[1]);
+ret->shortLabel = cloneString(row[2]);
+ret->longLabel = cloneString(row[3]);
+return ret;
+}
+
+struct features *featuresLoadAll(char *fileName) 
+/* Load all features from a whitespace-separated file.
+ * Dispose of this with featuresFreeList(). */
+{
+struct features *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileRow(lf, row))
+    {
+    el = featuresLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct features *featuresLoadAllByChar(char *fileName, char chopper) 
+/* Load all features from a chopper separated file.
+ * Dispose of this with featuresFreeList(). */
+{
+struct features *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = featuresLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct features *featuresLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all features 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 featuresFreeList(). */
+{
+struct features *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = featuresLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void featuresSaveToDb(struct sqlConnection *conn, struct features *el, char *tableName, int updateSize)
+/* Save features 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use featuresSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s','%s')", 
+	tableName,  el->id,  el->name,  el->shortLabel,  el->longLabel);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void featuresSaveToDbEscaped(struct sqlConnection *conn, struct features *el, char *tableName, int updateSize)
+/* Save features 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than featuresSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *name, *shortLabel, *longLabel;
+name = sqlEscapeString(el->name);
+shortLabel = sqlEscapeString(el->shortLabel);
+longLabel = sqlEscapeString(el->longLabel);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s','%s','%s')", 
+	tableName,  el->id,  name,  shortLabel,  longLabel);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&name);
+freez(&shortLabel);
+freez(&longLabel);
+}
+
+struct features *featuresCommaIn(char **pS, struct features *ret)
+/* Create a features out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new features */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->id = sqlUnsignedComma(&s);
+ret->name = sqlStringComma(&s);
+ret->shortLabel = sqlStringComma(&s);
+ret->longLabel = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void featuresFree(struct features **pEl)
+/* Free a single dynamically allocated features such as created
+ * with featuresLoad(). */
+{
+struct features *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->name);
+freeMem(el->shortLabel);
+freeMem(el->longLabel);
+freez(pEl);
+}
+
+void featuresFreeList(struct features **pList)
+/* Free a list of dynamically allocated features's */
+{
+struct features *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    featuresFree(&el);
+    }
+*pList = NULL;
+}
+
+void featuresOutput(struct features *el, FILE *f, char sep, char lastSep) 
+/* Print out features.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->name);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->shortLabel);
+if (sep == ',') fputc('"',f);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->longLabel);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void clinicalDataStaticLoad(char **row, struct clinicalData *ret)
+/* Load a row from clinicalData table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->sample_id = sqlUnsigned(row[0]);
+ret->feature_id = sqlUnsigned(row[1]);
+ret->val = sqlDouble(row[2]);
+ret->code = row[3];
+}
+
+struct clinicalData *clinicalDataLoad(char **row)
+/* Load a clinicalData from row fetched with select * from clinicalData
+ * from database.  Dispose of this with clinicalDataFree(). */
+{
+struct clinicalData *ret;
+
+AllocVar(ret);
+ret->sample_id = sqlUnsigned(row[0]);
+ret->feature_id = sqlUnsigned(row[1]);
+ret->val = sqlDouble(row[2]);
+ret->code = cloneString(row[3]);
+return ret;
+}
+
+struct clinicalData *clinicalDataLoadAll(char *fileName) 
+/* Load all clinicalData from a whitespace-separated file.
+ * Dispose of this with clinicalDataFreeList(). */
+{
+struct clinicalData *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileRow(lf, row))
+    {
+    el = clinicalDataLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct clinicalData *clinicalDataLoadAllByChar(char *fileName, char chopper) 
+/* Load all clinicalData from a chopper separated file.
+ * Dispose of this with clinicalDataFreeList(). */
+{
+struct clinicalData *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = clinicalDataLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct clinicalData *clinicalDataLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all clinicalData 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 clinicalDataFreeList(). */
+{
+struct clinicalData *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = clinicalDataLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void clinicalDataSaveToDb(struct sqlConnection *conn, struct clinicalData *el, char *tableName, int updateSize)
+/* Save clinicalData 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use clinicalDataSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g,'%s')", 
+	tableName,  el->sample_id,  el->feature_id,  el->val,  el->code);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void clinicalDataSaveToDbEscaped(struct sqlConnection *conn, struct clinicalData *el, char *tableName, int updateSize)
+/* Save clinicalData 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than clinicalDataSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *code;
+code = sqlEscapeString(el->code);
+
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g,'%s')", 
+	tableName,  el->sample_id,  el->feature_id,  el->val,  code);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&code);
+}
+
+struct clinicalData *clinicalDataCommaIn(char **pS, struct clinicalData *ret)
+/* Create a clinicalData out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new clinicalData */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->sample_id = sqlUnsignedComma(&s);
+ret->feature_id = sqlUnsignedComma(&s);
+ret->val = sqlDoubleComma(&s);
+ret->code = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void clinicalDataFree(struct clinicalData **pEl)
+/* Free a single dynamically allocated clinicalData such as created
+ * with clinicalDataLoad(). */
+{
+struct clinicalData *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->code);
+freez(pEl);
+}
+
+void clinicalDataFreeList(struct clinicalData **pList)
+/* Free a list of dynamically allocated clinicalData's */
+{
+struct clinicalData *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    clinicalDataFree(&el);
+    }
+*pList = NULL;
+}
+
+void clinicalDataOutput(struct clinicalData *el, FILE *f, char sep, char lastSep) 
+/* Print out clinicalData.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->sample_id);
+fputc(sep,f);
+fprintf(f, "%u", el->feature_id);
+fputc(sep,f);
+fprintf(f, "%g", el->val);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->code);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void analysisFeaturesStaticLoad(char **row, struct analysisFeatures *ret)
+/* Load a row from analysisFeatures table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->feature_id = sqlUnsigned(row[0]);
+ret->feature_name = row[1];
+}
+
+struct analysisFeatures *analysisFeaturesLoad(char **row)
+/* Load a analysisFeatures from row fetched with select * from analysisFeatures
+ * from database.  Dispose of this with analysisFeaturesFree(). */
+{
+struct analysisFeatures *ret;
+
+AllocVar(ret);
+ret->feature_id = sqlUnsigned(row[0]);
+ret->feature_name = cloneString(row[1]);
+return ret;
+}
+
+struct analysisFeatures *analysisFeaturesLoadAll(char *fileName) 
+/* Load all analysisFeatures from a whitespace-separated file.
+ * Dispose of this with analysisFeaturesFreeList(). */
+{
+struct analysisFeatures *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileRow(lf, row))
+    {
+    el = analysisFeaturesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct analysisFeatures *analysisFeaturesLoadAllByChar(char *fileName, char chopper) 
+/* Load all analysisFeatures from a chopper separated file.
+ * Dispose of this with analysisFeaturesFreeList(). */
+{
+struct analysisFeatures *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[2];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = analysisFeaturesLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct analysisFeatures *analysisFeaturesLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all analysisFeatures 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 analysisFeaturesFreeList(). */
+{
+struct analysisFeatures *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = analysisFeaturesLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void analysisFeaturesSaveToDb(struct sqlConnection *conn, struct analysisFeatures *el, char *tableName, int updateSize)
+/* Save analysisFeatures 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use analysisFeaturesSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->feature_id,  el->feature_name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void analysisFeaturesSaveToDbEscaped(struct sqlConnection *conn, struct analysisFeatures *el, char *tableName, int updateSize)
+/* Save analysisFeatures 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than analysisFeaturesSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+char  *feature_name;
+feature_name = sqlEscapeString(el->feature_name);
+
+dyStringPrintf(update, "insert into %s values ( %u,'%s')", 
+	tableName,  el->feature_id,  feature_name);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+freez(&feature_name);
+}
+
+struct analysisFeatures *analysisFeaturesCommaIn(char **pS, struct analysisFeatures *ret)
+/* Create a analysisFeatures out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new analysisFeatures */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->feature_id = sqlUnsignedComma(&s);
+ret->feature_name = sqlStringComma(&s);
+*pS = s;
+return ret;
+}
+
+void analysisFeaturesFree(struct analysisFeatures **pEl)
+/* Free a single dynamically allocated analysisFeatures such as created
+ * with analysisFeaturesLoad(). */
+{
+struct analysisFeatures *el;
+
+if ((el = *pEl) == NULL) return;
+freeMem(el->feature_name);
+freez(pEl);
+}
+
+void analysisFeaturesFreeList(struct analysisFeatures **pList)
+/* Free a list of dynamically allocated analysisFeatures's */
+{
+struct analysisFeatures *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    analysisFeaturesFree(&el);
+    }
+*pList = NULL;
+}
+
+void analysisFeaturesOutput(struct analysisFeatures *el, FILE *f, char sep, char lastSep) 
+/* Print out analysisFeatures.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->feature_id);
+fputc(sep,f);
+if (sep == ',') fputc('"',f);
+fprintf(f, "%s", el->feature_name);
+if (sep == ',') fputc('"',f);
+fputc(lastSep,f);
+}
+
+void analysisValsStaticLoad(char **row, struct analysisVals *ret)
+/* Load a row from analysisVals table into ret.  The contents of ret will
+ * be replaced at the next call to this function. */
+{
+
+ret->sample_id = sqlUnsigned(row[0]);
+ret->feature_id = sqlUnsigned(row[1]);
+ret->val = sqlFloat(row[2]);
+ret->conf = sqlFloat(row[3]);
+}
+
+struct analysisVals *analysisValsLoad(char **row)
+/* Load a analysisVals from row fetched with select * from analysisVals
+ * from database.  Dispose of this with analysisValsFree(). */
+{
+struct analysisVals *ret;
+
+AllocVar(ret);
+ret->sample_id = sqlUnsigned(row[0]);
+ret->feature_id = sqlUnsigned(row[1]);
+ret->val = sqlFloat(row[2]);
+ret->conf = sqlFloat(row[3]);
+return ret;
+}
+
+struct analysisVals *analysisValsLoadAll(char *fileName) 
+/* Load all analysisVals from a whitespace-separated file.
+ * Dispose of this with analysisValsFreeList(). */
+{
+struct analysisVals *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileRow(lf, row))
+    {
+    el = analysisValsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct analysisVals *analysisValsLoadAllByChar(char *fileName, char chopper) 
+/* Load all analysisVals from a chopper separated file.
+ * Dispose of this with analysisValsFreeList(). */
+{
+struct analysisVals *list = NULL, *el;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *row[4];
+
+while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
+    {
+    el = analysisValsLoad(row);
+    slAddHead(&list, el);
+    }
+lineFileClose(&lf);
+slReverse(&list);
+return list;
+}
+
+struct analysisVals *analysisValsLoadByQuery(struct sqlConnection *conn, char *query)
+/* Load all analysisVals 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 analysisValsFreeList(). */
+{
+struct analysisVals *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+
+sr = sqlGetResult(conn, query);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = analysisValsLoad(row);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+return list;
+}
+
+void analysisValsSaveToDb(struct sqlConnection *conn, struct analysisVals *el, char *tableName, int updateSize)
+/* Save analysisVals 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. Note that strings must be escaped to allow insertion into the database.
+ * For example "autosql's features include" --> "autosql\'s features include" 
+ * If worried about this use analysisValsSaveToDbEscaped() */
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g,%g)", 
+	tableName,  el->sample_id,  el->feature_id,  el->val,  el->conf);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+void analysisValsSaveToDbEscaped(struct sqlConnection *conn, struct analysisVals *el, char *tableName, int updateSize)
+/* Save analysisVals 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. Automatically 
+ * escapes all simple strings (not arrays of string) but may be slower than analysisValsSaveToDb().
+ * For example automatically copies and converts: 
+ * "autosql's features include" --> "autosql\'s features include" 
+ * before inserting into database. */ 
+{
+struct dyString *update = newDyString(updateSize);
+dyStringPrintf(update, "insert into %s values ( %u,%u,%g,%g)", 
+	tableName,  el->sample_id,  el->feature_id,  el->val,  el->conf);
+sqlUpdate(conn, update->string);
+freeDyString(&update);
+}
+
+struct analysisVals *analysisValsCommaIn(char **pS, struct analysisVals *ret)
+/* Create a analysisVals out of a comma separated string. 
+ * This will fill in ret if non-null, otherwise will
+ * return a new analysisVals */
+{
+char *s = *pS;
+
+if (ret == NULL)
+    AllocVar(ret);
+ret->sample_id = sqlUnsignedComma(&s);
+ret->feature_id = sqlUnsignedComma(&s);
+ret->val = sqlFloatComma(&s);
+ret->conf = sqlFloatComma(&s);
+*pS = s;
+return ret;
+}
+
+void analysisValsFree(struct analysisVals **pEl)
+/* Free a single dynamically allocated analysisVals such as created
+ * with analysisValsLoad(). */
+{
+struct analysisVals *el;
+
+if ((el = *pEl) == NULL) return;
+freez(pEl);
+}
+
+void analysisValsFreeList(struct analysisVals **pList)
+/* Free a list of dynamically allocated analysisVals's */
+{
+struct analysisVals *el, *next;
+
+for (el = *pList; el != NULL; el = next)
+    {
+    next = el->next;
+    analysisValsFree(&el);
+    }
+*pList = NULL;
+}
+
+void analysisValsOutput(struct analysisVals *el, FILE *f, char sep, char lastSep) 
+/* Print out analysisVals.  Separate fields with sep. Follow last field with lastSep. */
+{
+fprintf(f, "%u", el->sample_id);
+fputc(sep,f);
+fprintf(f, "%u", el->feature_id);
+fputc(sep,f);
+fprintf(f, "%g", el->val);
+fputc(sep,f);
+fprintf(f, "%g", el->conf);
+fputc(lastSep,f);
+}
+
+/* -------------------------------- End autoSql Generated Code -------------------------------- */
+