src/hg/instinct/hgGeneset/hgGenesets.c 1.12
1.12 2010/01/31 01:17:07 jsanborn
added search
Index: src/hg/instinct/hgGeneset/hgGenesets.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/hgGeneset/hgGenesets.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -b -B -U 4 -r1.11 -r1.12
--- src/hg/instinct/hgGeneset/hgGenesets.c 29 Jan 2010 23:47:20 -0000 1.11
+++ src/hg/instinct/hgGeneset/hgGenesets.c 31 Jan 2010 01:17:07 -0000 1.12
@@ -120,8 +120,19 @@
return analysisFeaturesLoadByQuery(conn, query);
}
+struct analysisFeatures *getAnalysisFeaturesByNameType(struct sqlConnection *conn,
+ char *name, char *type)
+{
+char query[256];
+safef(query, sizeof(query),
+ "select * from %s where feature_name = \"%s\" and type = \"%s\"",
+ AF_TABLE, name, type);
+
+return analysisFeaturesLoadByQuery(conn, query);
+}
+
struct analysisFeatures *getAnalysisFeaturesById(struct sqlConnection *conn,
int id)
{
char query[256];
@@ -207,8 +218,19 @@
return genesetsLoadByQuery(conn, query);
}
+struct slInt *getGenesInGeneset(struct sqlConnection *conn, int id)
+{
+char query[256];
+safef(query, sizeof(query),
+ "select DISTINCT gene_id from %s where id = %d",
+ GG_TABLE, id);
+
+return sqlQuickNumList(conn, query);
+}
+
+
char *getDataTypeById(struct sqlConnection *conn, int id)
{
char query[256];
safef(query, sizeof(query),
@@ -467,14 +489,8 @@
hFreeConn(&conn);
}
-void sendNoMatch(struct json *js)
-{
-return;
-}
-
-
void sendRawFeatureData(struct sqlConnection *conn, struct json *js,
struct datasets *da, struct samples *saList,
struct analysisFeatures *af)
{
@@ -1041,8 +1057,141 @@
if (js)
hPrintf("%s\n", js->print(js));
}
+
+struct searchResults {
+ struct searchResults *next;
+ int id;
+ char *name;
+ char *type;
+ double val;
+};
+
+int searchResultsCmp(const void *va, const void *vb)
+/* Compare function to sort array of ints. */
+{
+const struct searchResults *a = *((struct searchResults **)va);
+const struct searchResults *b = *((struct searchResults **)vb);
+double diff = a->val - b->val;
+if (diff < 0)
+ return -1;
+else if (diff > 0)
+ return 1;
+else
+ return 0;
+}
+
+struct searchResults *searchForFeatures(struct sqlConnection *conn, char *feature_name)
+{
+int maxResponse = 10;
+/* Check analysis features */
+char query[256];
+safef(query, sizeof(query),
+ "select id,feature_name,type from %s where feature_name like \"%%%s%%\" "
+ "order by length(feature_name);",
+ AF_TABLE, feature_name);
+
+int count = 0;
+struct searchResults *sp, *spList = NULL;
+struct sqlResult *sr = sqlGetResult(conn, query);
+char **row = NULL;
+while ((row = sqlNextRow(sr)) != NULL)
+ {
+ int id = atoi(row[0]);
+ char *name = row[1];
+ char *type = row[2];
+ AllocVar(sp);
+ sp->id = id;
+ sp->name = cloneString(name);
+ sp->type = cloneString(type);
+ sp->val = strlen(sp->name);
+ slAddHead(&spList, sp);
+ if (count > maxResponse)
+ break;
+ count++;
+ }
+sqlFreeResult(&sr);
+
+slSort(&spList, searchResultsCmp);
+return spList;
+}
+
+void sendNoMatch(struct json *js)
+{
+return;
+}
+
+void sendAmbiguities(struct json *js, struct searchResults *spList)
+{
+struct searchResults *sp;
+for (sp = spList; sp; sp = sp->next)
+ {
+ struct json *new = jsonAddContainer(js, sp->name);
+ jsonAddInt(new, "id", sp->id);
+ jsonAddString(new, "type", sp->type);
+ }
+}
+
+void getMatching()
+{
+struct sqlConnection *conn = hAllocConnProfile(localDb, db);
+
+char *term = cartOptionalString(cart, hghSearchTerm);
+struct json *js = newJson();
+
+if (sameString(term, "")) // blank was sent, return no match
+ sendNoMatch(js);
+else
+ {
+ struct searchResults *spList = searchForFeatures(conn, term);
+ int numMatched = slCount(spList);
+ if (numMatched == 0)
+ sendNoMatch(js);
+ else
+ sendAmbiguities(js, spList);
+ }
+
+if (js)
+ hPrintf("%s\n", js->print(js));
+
+cartRemovePrefix(cart, hghSearchTerm);
+}
+
+void getInfo()
+{
+struct sqlConnection *conn = hAllocConnProfile(localDb, db);
+
+int id = cartUsualInt(cart, hghInfoId, -1);
+char *name = cartOptionalString(cart, hghInfoName);
+char *type = cartOptionalString(cart, hghInfoType);
+
+if (id == -1 && (!name || !type))
+ errAbort("Insufficient input for getInfo().\n");
+
+struct analysisFeatures *af;
+if (id > 0)
+ af = getAnalysisFeaturesById(conn, id);
+else
+ af = getAnalysisFeaturesByNameType(conn, name, type);
+
+if (!sameString(af->type, "geneset"))
+ errAbort("getInfo only supports retrieving geneset information.\n");
+
+
+struct json *js = newJson();
+
+struct slInt *geneIds = getGenesInGeneset(conn, af->id);
+struct json *new = jsonAddContainer(js, af->feature_name);
+jsonAddSlInt(new, "ids", geneIds);
+
+if (js)
+ hPrintf("%s\n", js->print(js));
+
+cartRemovePrefix(cart, hghInfoPrefix);
+}
+
+
void dispatchRoutines()
/* Look at command variables in cart and figure out which
* page to draw. */
{
@@ -1052,16 +1201,22 @@
errAbort("%s is required.", hghMode);
if (sameString(mode, "drawHeatmap"))
drawHeatmap();
+else if (sameString(mode, "getInfo"))
+ getInfo();
+else if (sameString(mode, "getMatching"))
+ getMatching();
else if (sameString(mode, "getCohorts"))
getCohorts();
else if (sameString(mode, "getSamples"))
getSamples();
+else if (sameString(mode, "resetState"))
+ cartRemovePrefix(cart, hghPrefix);
else
errAbort("Incorrect mode = %s", mode);
-cartRemovePrefix(cart, hghPrefix);
+//cartRemovePrefix(cart, hghPrefix);
}
void hghDoUsualHttp()
/* Wrap html page dispatcher with code that writes out