Skip to content

Commit

Permalink
Merge pull request #62 from KeithKelleher/master
Browse files Browse the repository at this point in the history
redirect to old pharos renderererer
  • Loading branch information
tsheils authored Mar 10, 2021
2 parents 081d6d3 + 158a0d4 commit de4fb4b
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pharos graphql server
=====================

###To run
### To run

Run `npm install` to get all dependencies, then

Expand Down
8 changes: 7 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ const app = express();

app.get("/render", (req, res) => {
const parsedUrl = url.parse(req.url);
res.redirect("https://tripod.nih.gov/servlet/renderServletv13?" + parsedUrl.query);
const pieces = parsedUrl.query.split('&');
const paramMap = {};
pieces.forEach(piece => {
const chunks = piece.split('=');
paramMap[chunks[0]] = chunks[1];
});
res.redirect(`https://tripod.nih.gov/idg/api/v1/render/${paramMap.structure}?size=${paramMap.size}`);
});

server.applyMiddleware({
Expand Down
42 changes: 34 additions & 8 deletions src/models/DataModelList.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import now from "performance-now";
import {FacetInfo} from "./FacetInfo";
import {FacetFactory} from "./FacetFactory";
import {Config, ConfigKeys, QueryDefinition, SqlTable} from "./config";
import {Config, ConfigKeys, QueryDefinition, RequestedData, SqlTable} from "./config";
import {DatabaseConfig} from "./databaseConfig";
// @ts-ignore
import * as CONSTANTS from "../constants";
Expand All @@ -17,6 +17,7 @@ export abstract class DataModelList {

facetFactory: FacetFactory;
term: string = "";
fields: string[] = [];
rootTable: string;
keyColumn: string;
filteringFacets: FacetInfo[] = [];
Expand All @@ -39,13 +40,13 @@ export abstract class DataModelList {

get AllFacets(): string[] {
const modelInfo = this.databaseConfig.modelList.get(this.rootTable);
const facetInfo = this.databaseConfig.fieldLists.get(`${modelInfo?.name} Facets - All`);
const facetInfo = this.databaseConfig.fieldLists.get(`${modelInfo?.name} Facet - All`);
return facetInfo?.map(facet => facet.type) || [];
}

get DefaultFacets() {
const modelInfo = this.databaseConfig.modelList.get(this.rootTable);
const facetInfo = this.databaseConfig.fieldLists.get(`${modelInfo?.name} Facets - Default`);
const facetInfo = this.databaseConfig.fieldLists.get(`${modelInfo?.name} Facet - Default`);
return facetInfo?.sort((a,b) => a.order - b.order).map(a => a.type) || [];
};

Expand All @@ -64,6 +65,9 @@ export abstract class DataModelList {
if (json.top) {
this.top = json.top;
}
if (json.fields) {
this.fields = json.fields;
}
}

if (json && json.filter) {
Expand Down Expand Up @@ -138,16 +142,28 @@ export abstract class DataModelList {

getListQuery() {
const that = this;
let dataFields = Config.GetDataFields(this.listQueryKey(), this.sortTable, this.sortColumn);
let dataFields: RequestedData[];
if (this.fields && this.fields.length > 0) {
dataFields = Config.GetDataFields(this.rootTable, this.fields, this.databaseConfig);
}
else {
dataFields = Config.GetDataFieldsFromKey(this.listQueryKey(), this.sortTable, this.sortColumn);
}
const queryDefinition = QueryDefinition.GenerateQueryDefinition(this.rootTable, dataFields);
let rootTableObject = queryDefinition.getRootTable();
let rootTableObject = queryDefinition.getRootTable();
if (rootTableObject == undefined) {
return;
}
let aggregateAll = (this.databaseConfig.getPrimaryKey(this.rootTable) != this.keyColumn);

let leftJoins = queryDefinition.getLeftJoinTables();
let innerJoins = queryDefinition.getInnerJoinTables();
if(this.associatedDisease && this.rootTable != 'disease'){
const hasDiseaseAlready = innerJoins.find(table => table.tableName === 'disease');
if(!hasDiseaseAlready){
innerJoins.push(new SqlTable('disease'));
}
}

let query = this.database(queryDefinition.getTablesAsObjectArray(innerJoins))
.select(queryDefinition.getColumnList(this.database));
Expand All @@ -164,6 +180,11 @@ export abstract class DataModelList {
if (leftJoins[i].joinConstraint) {
this.andOn(that.database.raw(leftJoins[i].joinConstraint));
}
leftJoins[i].columns.forEach(col => {
if(col.where_clause){
this.andOn(that.database.raw(col.where_clause));
}
});
});
}
if (this.associatedDisease){
Expand All @@ -189,20 +210,25 @@ export abstract class DataModelList {
if (additionalWhereClause) {
query.andWhere(this.database.raw(additionalWhereClause));
}
innerJoins[i].columns.forEach(col => {
if(col.where_clause){
query.andWhere(that.database.raw(col.where_clause));
}
});
}
}
this.addModelSpecificFiltering(query, true);

query.groupBy(this.keyString());

if(this.fields.length === 0) {
query.groupBy(this.keyString());
}
this.addSort(query, queryDefinition);
if (this.skip) {
query.offset(this.skip);
}
if (this.top) {
query.limit(this.top);
}
//console.log(query.toString());
this.captureQueryPerformance(query, "list count");
return query;
}
Expand Down
19 changes: 19 additions & 0 deletions src/models/DataModelListFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {DiseaseList} from "./disease/diseaseList";
import {LigandList} from "./ligand/ligandList";
import {TargetList} from "./target/targetList";
import {DataModelList} from "./DataModelList";

export class DataModelListFactory {
static getListObject(modelName: string, tcrd: any, json: any): DataModelList {
if (modelName === "Diseases") {
return new DiseaseList(tcrd, json);
}
if (modelName === "Ligands") {
return new LigandList(tcrd, json);
}
if (modelName === "Targets") {
return new TargetList(tcrd, json);
}
throw new Error('Unknown Data Model: Expecting Diseases, Ligands, or Targets');
}
}
75 changes: 53 additions & 22 deletions src/models/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
import {DatabaseTable} from "./databaseTable";
import {DatabaseConfig} from "./databaseConfig";

/**
* Class for gathering tables and columns to use for standard queries
*/
export class Config {
static GetDataFields(fieldKey: ConfigKeys, sortTable: string = "", sortColumn: string = ""): RequestedData[] {
static GetDataFields(rootTable: string, fields: string[], dbConfig: DatabaseConfig): RequestedData[] {
const dataFields: RequestedData[] = [];

// TODO : get primary key better
dataFields.push({table: "protein", data: "id", alias: 'id'});

fields.forEach(field => {
const facetInfo = dbConfig.getFacetConfig(rootTable, field);
dataFields.push({table: facetInfo.dataTable, data: facetInfo.dataColumn, alias: field, where_clause: facetInfo.whereClause, group_method: facetInfo.group_method});
});
return dataFields;
}

/**
* TODO : get rid of this when the normal list pages are using the pharos_config.fieldList
* @param fieldKey
* @param sortTable
* @param sortColumn
* @constructor
*/
static GetDataFieldsFromKey(fieldKey: ConfigKeys, sortTable: string = "", sortColumn: string = ""): RequestedData[] {
const dataFields: RequestedData[] = [];
switch (fieldKey) {
case ConfigKeys.Target_List_Default:
Expand Down Expand Up @@ -113,6 +134,7 @@ export class RequestedData {
data: string = "";
alias?: string = "";
group_method?: string = "";
where_clause?: string = "";
subQuery?: boolean = false;
}

Expand Down Expand Up @@ -151,34 +173,38 @@ export class QueryDefinition {
}

addRequestedDataToNewTable(reqData: RequestedData) {
const table = reqData.table;
const data = reqData.data;
const alias = reqData.alias;
const subq = reqData.subQuery;
let links: string[] = [];
const tableCount = this.tables.filter(t => {
return t.tableName == table;
return t.tableName == reqData.table;
}).length;

if (DatabaseTable.sparseTables.includes(table)) {
this.tables.push(SqlTable.getSparseTableData(table, data, alias, table + tableCount));
if (DatabaseTable.sparseTables.includes(reqData.table)) {
this.tables.push(SqlTable.getSparseTableData(reqData.table, reqData.data, reqData.alias, reqData.table + tableCount, reqData.group_method, reqData.where_clause));
return;
}

if (DatabaseTable.typeTables.includes(table)) {
const typeColumn = DatabaseTable.typeTableColumns.get(table);
if (!typeColumn) throw new Error(`bad table configuration - ${table} has no type column configuration`);
const dataColumn = DatabaseTable.typeTableColumnMapping.get(table + "-" + data);
this.tables.push(SqlTable.getTypeTableData(table, data, typeColumn, (dataColumn || data), alias, table + tableCount));
if (DatabaseTable.typeTables.includes(reqData.table)) {
const typeColumn = DatabaseTable.typeTableColumns.get(reqData.table);
if (!typeColumn) throw new Error(`bad table configuration - ${reqData.table} has no type column configuration`);
const dataColumn = DatabaseTable.typeTableColumnMapping.get(reqData.table + "-" + reqData.data);
this.tables.push(
SqlTable.getTypeTableData(
reqData.table,
reqData.data,
typeColumn,
(dataColumn || reqData.data),
reqData.alias,
reqData.table + tableCount)
);
return;
}

if (table != this.rootTable) {
links = DatabaseTable.getRequiredLinks(table, this.rootTable) || [];
if (reqData.table != this.rootTable) {
links = DatabaseTable.getRequiredLinks(reqData.table, this.rootTable) || [];
}

const newTable = new SqlTable(table, {}, links, subq);
newTable.columns.push(new SqlColumns(reqData.data, reqData.alias, reqData.group_method));
const newTable = new SqlTable(reqData.table, {}, links, reqData.subQuery);
newTable.columns.push(new SqlColumns(reqData.data, reqData.alias, reqData.group_method, reqData.where_clause));
this.tables.push(newTable);
}

Expand Down Expand Up @@ -273,19 +299,22 @@ export class SqlTable {
}
}

static getTypeTableData(tableName: string, typeName: string, typeColumn: string, dataColumn: string, columnAlias?: string, tableAlias?: string) {
static getTypeTableData(tableName: string, typeName: string, typeColumn: string, dataColumn: string, columnAlias?: string, tableAlias?: string, group_method?: string, where_clause?: string) {
const typeTable = new SqlTable(tableName, {
allowUnmatchedRows: true,
joinConstraint: `${tableAlias || tableName}.${typeColumn} = '${typeName}'`,
alias: tableAlias
});
typeTable.columns.push(new SqlColumns(dataColumn, columnAlias || dataColumn));
typeTable.columns.push(new SqlColumns(dataColumn, columnAlias || dataColumn, group_method, where_clause));
return typeTable;
}

static getSparseTableData(tableName: string, dataColumn: string, columnAlias?: string, tableAlias?: string) {
static getSparseTableData(tableName: string, dataColumn: string, columnAlias?: string, tableAlias?: string, group_method?: string, where_clause?: string) {
const sparseTable = new SqlTable(tableName, {allowUnmatchedRows: true, alias: tableAlias});
sparseTable.columns.push(new SqlColumns(dataColumn, columnAlias || dataColumn));
if(where_clause && tableAlias) {
where_clause = where_clause.replace(tableName, tableAlias);
}
sparseTable.columns.push(new SqlColumns(dataColumn, columnAlias || dataColumn, group_method, where_clause));
return sparseTable;
}
}
Expand All @@ -294,15 +323,17 @@ export class SqlColumns {
column: string;
private _alias?: string = "";
group_method?: string = "";
where_clause?: string = "";

get alias(): string {
if (this._alias) return this._alias;
return this.column;
}

constructor(column: string, alias: string = "", group_method: string = "") {
constructor(column: string, alias: string = "", group_method: string = "", where_clause: string = "") {
this.column = column;
this.group_method = group_method;
this.where_clause = where_clause;
if (alias) {
this._alias = alias;
}
Expand Down
14 changes: 8 additions & 6 deletions src/models/databaseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ export class DatabaseConfig {
}

fieldListColumns = {
listName: `fieldList.name`,
listType: `fieldList.type`,
listName: `fieldList.listName`,
field_id: `fieldList.field_id`,
order: 'fieldList.order'
};
fieldColumns = {
Expand Down Expand Up @@ -105,21 +107,21 @@ export class DatabaseConfig {
.whereRaw(this.linkFieldToModel);
listQuery.then((rows: any[]) => {
rows.forEach(row => {
if (this.fieldLists.has(row.listName)) {
const list = this.fieldLists.get(row.listName);
const listNameString = row.modelName + ' ' + row.listType + ' - ' + row.listName;
if (this.fieldLists.has(listNameString)) {
const list = this.fieldLists.get(listNameString);
list?.push(row);
} else {
this.fieldLists.set(row.listName, [row]);
this.fieldLists.set(listNameString, [row]);
}
});
});
const allFieldsQuery = this.database({...this.fieldTable, ...this.modelTable})
.select({...this.fieldColumns, ...this.modelColumns})
.whereRaw(this.linkFieldToModel);
// console.log(allFieldsQuery.toString());
allFieldsQuery.then((rows: any[]) => {
rows.forEach(row => {
const keyName = `${row.modelName} Facets - All`;
const keyName = `${row.modelName} Facet - All`;
if(row.isGoodForFacet) {
if (this.fieldLists.has(keyName)) {
const list = this.fieldLists.get(keyName);
Expand Down
7 changes: 5 additions & 2 deletions src/models/databaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,17 @@ export class DatabaseTable {

static requiredLinks: Map<string, string[]> = new Map(
[
["protein-target", ["t2tc"]],
["protein-viral_protein", ["viral_ppi", "virus"]],
["protein-virus", ["viral_ppi", "viral_protein"]],
["protein-dto", ["p2dto"]],
["protein-panther_class", ["p2pc"]],
["protein-virus", ["viral_protein", "viral_ppi"]],
["protein-viral_protein", ["virus", "viral_ppi"]],
["protein-ncats_ligands", ["ncats_ligand_activity", "target", "t2tc"]]

// checked
["protein-target", ["t2tc"]],
["protein-ncats_ligands", ["t2tc", "target", "ncats_ligand_activity"]],
["protein-ncats_ligand_activity", ["t2tc", "target"]]
]);

static getRequiredLinks(table1: string, table2: string): string[] | undefined {
Expand Down
2 changes: 1 addition & 1 deletion src/models/disease/diseaseList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class DiseaseList extends DataModelList {

get DefaultFacetsWithTarget() {
return this.databaseConfig.fieldLists
.get('Disease Facets - Associated Target')?.sort((a,b) => a.order - b.order)
.get('Disease Facet - Associated Target')?.sort((a,b) => a.order - b.order)
.map(a => a.type) || [];
};
defaultSortParameters(): {column: string; order: string}[]
Expand Down
14 changes: 13 additions & 1 deletion src/models/ligand/ligandList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@ export class LigandList extends DataModelList{

constructor(tcrd: any, json: any) {
super(tcrd, "ncats_ligands" , "id", new LigandFacetFactory(), json);
let facetList: string[];
if (this.associatedTarget) {
facetList = this.DefaultFacetsWithTarget;
} else {
facetList = this.DefaultFacets;
}
this.facetsToFetch = FacetInfo.deduplicate(
this.facetsToFetch.concat(this.facetFactory.getFacetsFromList(this, this.DefaultFacets)));
this.facetsToFetch.concat(this.facetFactory.getFacetsFromList(this, facetList)));
}

get DefaultFacetsWithTarget() {
return this.databaseConfig.fieldLists
.get('Ligand Facet - Associated Target')?.sort((a,b) => a.order - b.order)
.map(a => a.type) || [];
};

defaultSortParameters(): {column: string; order: string}[]
{
return [{column: 'actcnt', order: 'desc'}];
Expand Down
Loading

0 comments on commit de4fb4b

Please sign in to comment.