src/hg/instinct/hgHeatmap2/hgGenesets.c 1.10

1.10 2009/06/04 03:50:37 jsanborn
added copyright notices, removed cluster library
Index: src/hg/instinct/hgHeatmap2/hgGenesets.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/hgHeatmap2/hgGenesets.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -b -B -U 1000000 -r1.9 -r1.10
--- src/hg/instinct/hgHeatmap2/hgGenesets.c	24 Jan 2009 00:34:58 -0000	1.9
+++ src/hg/instinct/hgHeatmap2/hgGenesets.c	4 Jun 2009 03:50:37 -0000	1.10
@@ -1,456 +1,459 @@
-/* hgSessions.c 
- *   These routines handle the storing and retrieving of JSON objects stored in a local
- * mysql database "sessionTrash".
+/********************************************************************************/
+/* Copyright 2007-2009 -- The Regents of the University of California           */
+/********************************************************************************/
+
+/* hgGenesets.c 
+ *   These routines handle the custom genesets.
  */
 
 #include "common.h"
 #include "cart.h"
 #include "hCommon.h"
 #include "hdb.h"
 #include "hgHeatmap2.h"
 #include "heatmapUtility.h"
 
 #define GENESETS_TABLE "genesets" 
 #define DESCRIPTIONS_TABLE "descriptions"
 #define USERGENESETS_TABLE "userGenesets" 
 #define USERPREFIX "user_"
 
 static char const rcsid[] = "$Id$";
 
 static char *heatMapDbProfile = "localDb";  // database profile to use
 
 
 char *getDescriptionOfGeneset(char *geneset)
 {
 if (!geneset)
     return NULL;
 
 struct sqlConnection *conn = getPathwayDbConn();
 if (!sqlTableExists(conn, DESCRIPTIONS_TABLE))
     {
     hFreeConn(&conn);
     return NULL;
     }
 
 char query[256];
 safef(query, sizeof(query),
       "select description from %s where name = \"%s\"",
       DESCRIPTIONS_TABLE, geneset);
 
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 row = sqlNextRow(sr);
 char *desc = NULL;
 if (row)
     desc = cloneString(*(row));
 
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 
 return desc;
 }
 
 char *getGenesInMatchingGeneset(char *table, char *geneset, unsigned int userId, int checkUser)
 {
 if (!geneset || !table)
     return NULL;
 struct sqlConnection *conn = getPathwayDbConn();
 
 char query[256];
 if (checkUser)
     safef(query, sizeof(query),
 	  "select members from %s where user=%u and name = \"%s\"",
 	  table, userId, geneset);
 else
     safef(query, sizeof(query),
 	  "select members from %s where name = \"%s\"",
 	  table, geneset);
 
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 row = sqlNextRow(sr);
 char *genes = NULL;
 if (row)
     genes = cloneString(*(row));
 
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 
 return genes;
 }
 
 struct slName *getGenesInGeneset(struct cart *cart, char *geneset)
 {
 unsigned int userId = cartUserId(cart);
 char *genes = getGenesInMatchingGeneset(USERGENESETS_TABLE, geneset, userId, 1);
 if (!genes)  // if nothing found, check normal db
     genes = getGenesInMatchingGeneset("genesets", geneset, 0, 0);
 
 if (!genes)
     return NULL;
 
 struct slName *slList = slNameListFromComma(genes);
 
 return slList;
 }
 
 
 struct geneSet *getAllPathways(struct cart *cart, char *db, char *pathwayNames)
 {
 if (!pathwayNames)
     return NULL;
 
 unsigned int userId = cartUserId(cart);
 struct slName *sl, *slList = slNameListFromComma(pathwayNames);
 
 struct geneSet *geneSets = NULL;
 struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, db);
 for (sl = slList; sl; sl = sl->next)
     {
     char query[512];
     safef(query, sizeof(query), 
 	  "select DISTINCT name, members from %s where user=%u and name=\"%s\"",
 	  USERGENESETS_TABLE, userId, sl->name);
 
     char *name = NULL;
     char *members = NULL;
     char *displayName = NULL;
 
     char **row = NULL;
     struct sqlResult *sr = sqlGetResult(conn, query);
     row = sqlNextRow(sr);
     if (row)
 	{
 	name = cloneString(row[0]);
 	members = cloneString(row[1]);
 	displayName = NULL;
 	}
     else
 	{
 	sqlFreeResult(&sr);
 	/* Check normal db */
 	safef(query, sizeof(query),
 	      "select DISTINCT name, members from genesets where name=\"%s\"",
 	      sl->name);
 
 	sr = sqlGetResult(conn, query);
 	row = sqlNextRow(sr);
 	if (!row)
 	    continue;
 	
 	name = cloneString(row[0]);
 	members = cloneString(row[1]);
 	displayName = cloneString(row[2]);
 	}
     sqlFreeResult(&sr);
 
     if (!name || !members)
 	continue;
 
     struct slName *geneList = slNameListFromComma(members);
     struct geneSet *gs = AllocA(struct geneSet);
     gs->genes = geneList;
     gs->name = name;
     gs->displayName = displayName;
     gs->numGenes = slCount(geneList);
     gs->numGenesActive = 0;
     gs->x = 0;
     gs->y = 0;
     gs->width = 0;
     gs->pixelsPerGene = 0;
     slAddHead(&geneSets, gs);
     }
 
 slReverse(&geneSets);
 
 hFreeConn(&conn);
 
 return geneSets; 
 }
 
 struct slName *hashAddMatchingInDb(struct sqlConnection *conn, struct hash *genesetHash,
 				   char *searchTerms, char *table, char *returnField,
 				   char *searchField, boolean ignoreCase, boolean perfectMatch)
 {
 if (!conn || !searchTerms || !searchField || !returnField || !table || !genesetHash)
     return NULL;
 
 struct slName *notMatching = NULL;
 
 /* Remove any double quotes to prevent sql injection attack */
 searchTerms = replaceChars(searchTerms, "\"", "");
 
 struct slName *sl, *slList = slNameListFromComma(searchTerms);
 for (sl = slList; sl; sl = sl->next)
     {
     char query[256];
     if (ignoreCase && perfectMatch)
         safef(query, sizeof(query),
               "select %s from %s where %s like UCASE(\"%s\");",
               returnField, table, searchField, sl->name);
     else if (perfectMatch)
         safef(query, sizeof(query),
               "select %s from %s where %s like \"%s\";",
               returnField, table, searchField, sl->name);
     else if (ignoreCase)
         safef(query, sizeof(query),
               "select %s from %s where %s like UCASE(\"%%%s%%\");",
               returnField, table, searchField, sl->name);
     else
         safef(query, sizeof(query),
               "select %s from %s where %s like \"%%%s%%\";",
               returnField, table, searchField, sl->name);
 
     if (!sqlExists(conn, query))
 	{
 	struct slName *nm = slNameNew(sl->name);
 	slAddHead(&notMatching, nm);
 	continue;
 	}
 
     struct sqlResult *sr = sqlGetResult(conn, query);
     char **row = NULL;
     while ((row = sqlNextRow(sr)) != NULL)
         {
         char *name = *(row);
         hashStoreName(genesetHash, name);
         }
     sqlFreeResult(&sr);
     }
 
 slReverse(&notMatching);
 return notMatching;
 }
 
 void hashAddMatchingInDbUser(struct sqlConnection *conn, struct hash *genesetHash,
 			     unsigned int userId, char *searchTerms, char *table, 
 			     char *returnField, char *searchField, 
 			     boolean ignoreCase, boolean perfectMatch)
 {
 if (!conn || !searchTerms || !searchField || !returnField || !table || !genesetHash)
     return;
 
 struct slName *sl, *slList = slNameListFromComma(searchTerms);
 for (sl = slList; sl; sl = sl->next)
     {
     char query[256];
     if (ignoreCase && perfectMatch)
         safef(query, sizeof(query),
               "select %s from %s where user=%u AND %s like UCASE(\"%s\");",
               returnField, table, userId, searchField, sl->name);
     else if (perfectMatch)
         safef(query, sizeof(query),
               "select %s from %s where user=%u and %s like \"%s\";",
               returnField, table, userId, searchField, sl->name);
     else if (ignoreCase)
         safef(query, sizeof(query),
               "select %s from %s where user=%u AND %s like UCASE(\"%%%s%%\");",
               returnField, table, userId, searchField, sl->name);
     else
         safef(query, sizeof(query),
               "select %s from %s where user=%u and %s like \"%%%s%%\";",
               returnField, table, userId, searchField, sl->name);
 
     struct sqlResult *sr = sqlGetResult(conn, query);
     char **row = NULL;
 
     while ((row = sqlNextRow(sr)) != NULL)
         {
         char *name = *(row);
         hashStoreName(genesetHash, name);
         }
     sqlFreeResult(&sr);
     }
 }
 
 struct hash *findMatching(char *searchGenes, boolean perfectMatch)
 /* Search genesets with a query for geneset name or containing gene */
 {
 if (!searchGenes)
     return NULL;
 /* remove any white space in search terms */
 searchGenes = replaceChars(searchGenes, " ", "");
 
 /* make connection to remote hg18, where refGene/refLink is stored */
 struct sqlConnection *conn = hAllocConn("hg18");
 
 struct hash *genes = hashNew(0);
 hashAddMatchingInDb(conn, genes, searchGenes, 
 		    "refGene", "name2", "name2", FALSE, perfectMatch);
 hFreeConn(&conn);
 
 /* Preserve order of original list, skipping genes that don't exist in db, 
  * and allowing duplicates (user may desire duplicates, who knows?)
  */
 
 return genes;
 }
 
 struct slName *getGenesMatchingList(char *searchGenes)
 {
 struct slName *sl, *sl2, *slList = NULL;
 struct slName *origList = slNameListFromComma(searchGenes);
 
 /* Get genes in list, perfect matches */
 struct hash *genes = findMatching(searchGenes, TRUE);
 
 char *name;
 struct slName *dbList = NULL;
 struct hashCookie hc = hashFirst(genes);
 while((name = hashNextName(&hc)) != NULL)
     slNameAddHead(&dbList, name);
 
 /* Match order of input list */
 for (sl = origList; sl; sl = sl->next)
     {
     /* If found in db, add to gene list sent in response, ignoring case
      * for search, but returning string from db */
     sl2 = slNameFind(dbList, sl->name);
     if (!sl2)
 	continue;
     slNameAddHead(&slList, sl2->name);
     }
 slReverse(&slList); 
 
 return slList;
 }  
 
 struct slName *getGenesMatching(char *searchGenes)
 /* Search genesets with a query for geneset name or containing gene */
 {
 /* Get genes in list, perfect matches */
 struct hash *genes = findMatching(searchGenes, FALSE);
 
 char *name;
 struct slName *slList = NULL;
 struct hashCookie hc = hashFirst(genes);
 while((name = hashNextName(&hc)) != NULL)
     slNameAddHead(&slList, name);
 slReverse(&slList); 
 
 return slList;
 }  
 
 struct slName *getGenesNotMatching(char *searchGenes)
 /* Search genesets with a query for geneset name or containing gene */
 {
 if (!searchGenes)
     return NULL;
 /* remove any white space in search terms */
 searchGenes = replaceChars(searchGenes, " ", "");
 
 /* make connection to remote hg18, where refGene/refLink is stored */
 struct sqlConnection *conn = hAllocConn("hg18");
 
 struct hash *genes = hashNew(0);
 struct slName *notMatching = hashAddMatchingInDb(conn, genes, searchGenes, 
 						 "refGene", "name2", "name2", FALSE, TRUE);
 hFreeConn(&conn);
 
 return notMatching;
 }  
 
 struct slName *getGenesetsMatching(struct cart *cart, char *searchGenes, char *searchGenesets)
 /* Search genesets with a query for geneset name or containing gene */
 {
 if (!searchGenes && !searchGenesets)
     return NULL;
 
 /* remove any white space in search terms */
 if (searchGenes)
     searchGenes = replaceChars(searchGenes, " ", "");
 
 if (searchGenesets)
     searchGenesets = replaceChars(searchGenesets, " ", "");
 
 struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, getPathwayDb());
 if (!conn)
     return NULL;
 
 struct hash *genesets = hashNew(0);
 hashAddMatchingInDb(conn, genesets, searchGenes, 
 		    GENESETS_TABLE, "name", "members", TRUE, FALSE);
 hashAddMatchingInDb(conn, genesets, searchGenesets, 
 		    GENESETS_TABLE, "name", "name", FALSE, FALSE);
 
 /* check user genesets for add'l matches */
 if (sqlTableExists(conn, USERGENESETS_TABLE))
     {
     unsigned int userId = cartUserId(cart);
     hashAddMatchingInDbUser(conn, genesets, userId, searchGenes, 
 			    USERGENESETS_TABLE, "name", "members", TRUE, FALSE);
     hashAddMatchingInDbUser(conn, genesets, userId, searchGenesets, 
 			    USERGENESETS_TABLE, "name", "name", FALSE, FALSE);
     }
 hFreeConn(&conn);
 
 char *name;
 struct slName *sl, *slList = NULL;
 struct hashCookie hc = hashFirst(genesets);
 while((name = hashNextName(&hc)) != NULL)
     {
     sl = slNameNew(name);
     slAddHead(&slList, sl);
     }
 slReverse(&slList);
 
 return slList;
 }
   
 void createUserGenesetsTable(struct sqlConnection *conn)
 {
 struct dyString *dy = newDyString(1024);
 dyStringPrintf(dy, "CREATE TABLE %s (\n", USERGENESETS_TABLE);
 dyStringPrintf(dy, "user int not null,\n");
 dyStringPrintf(dy, "name varchar(255) not null,\n");
 dyStringPrintf(dy, "members longblob not null,\n");
 dyStringPrintf(dy, "PRIMARY KEY(user, name)\n");
 dyStringPrintf(dy, ")\n");
 sqlUpdate(conn,dy->string);
 dyStringFree(&dy);
 }
 
 char *storeUserGeneset(struct cart *cart, char *inputName, char *inputMembers)
 {
 if (!cart || !inputName || !inputMembers)
     return NULL;
 
 char tmp[1024];
 safef(tmp, sizeof(tmp), "%s%s", USERPREFIX, inputName);
 char *name = cloneString(tmp);
 
 /* replace " with single quote, hurts MySQL */
 char *members = replaceChars(inputMembers, "\"", "'");  
 
 struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, getPathwayDb());
 if (!conn)
     errAbort("Couldn't connect to pathway database");
 
 if (!sqlTableExists(conn, USERGENESETS_TABLE))
     createUserGenesetsTable(conn);
 
 char query[1024];
 struct sqlResult *sr = NULL;
 char **row = NULL;
 
 unsigned int userId = cartUserId(cart);
 
 safef(query, sizeof(query), "SELECT name FROM %s WHERE user=%u AND name=\"%s\"",
       USERGENESETS_TABLE, userId, name);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 
 struct dyString *dy = newDyString(1024);
 if (row)
     dyStringPrintf(dy, "UPDATE %s SET members=\"%s\" WHERE user=%u AND name=\"%s\"",
                    USERGENESETS_TABLE, members, userId, name);
 else
     dyStringPrintf(dy, "INSERT %s VALUES(%u,\"%s\",\"%s\")",
                    USERGENESETS_TABLE, userId, name, members);
 
 sqlFreeResult(&sr);
 sqlUpdate(conn,dy->string);
 
 hFreeConn(&conn);
 return name;
 }