Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Custom Queries backend #133

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions query-connector/src/app/database-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
QueryInput,
generateQueryInsertionSql,
generateQueryToValueSetInsertionSql,
CustomUserQuery,
} from "./query-building";
import { UUID } from "crypto";
import {
Expand Down Expand Up @@ -606,6 +607,68 @@ export async function getConditionsData() {
} as const;
}

/**
* Fetches and structures custom user queries from the database.
* Executes a SQL query to join query information with related valueset and concept data,
* and then structures the result into a nested JSON format. The JSON format groups
* valuesets and their nested concepts under each query.
* @returns customUserQueriesArray - An array of objects where each object represents a query.
* Each query object includes:
* - query_id: The unique identifier for the query.
* - query_name: The name of the query.
* - valuesets: An array of CustomQueryValueSet objects, each containing:
* - valueSetId: The unique identifier for the valueset.
* - concepts: An array of CustomQueryConcept objects, each containing:
* - code: The unique code for the concept.
* - include: A boolean indicating whether the concept is included.
*/
export async function getCustomQueries(): Promise<CustomUserQuery[]> {
const query = `SELECT
q.id AS query_id,
q.query_name,
qtv.valueset_oid AS valueSetId,
qic.concept_id AS code,
qic.include
FROM
query q
LEFT JOIN query_to_valueset qtv ON q.id = qtv.query_id
LEFT JOIN query_included_concepts qic ON qic.query_by_valueset_id = qtv.id
WHERE q.author = 'DIBBs';`;
//TODO: this will eventually need to take into account user permissions and specific authors

const results = await dbClient.query(query);
const formattedData: { [key: string]: CustomUserQuery } = {};

results.rows.forEach((row) => {
const { query_id, query_name, valueSetId, code, include } = row;

// Initialize query structure if it doesn't exist
if (!formattedData[query_id]) {
formattedData[query_id] = {
query_id,
query_name,
valuesets: [],
};
}

// Check if the valueSetId already exists in the valuesets array
let valueset = formattedData[query_id].valuesets.find(
(v) => v.valueSetId === valueSetId,
);

// If valueSetId doesn't exist, add it
if (!valueset) {
valueset = { valueSetId, concepts: [] };
formattedData[query_id].valuesets.push(valueset);
}

// Add concept data to the concepts array
valueset.concepts.push({ code, include });
});
const customUserQueriesArray = Object.values(formattedData);
return customUserQueriesArray;
}

/**
* Checks the database to see if data has been loaded into the valuesets table by
* estmating the number of rows in the table. If the estimated count is greater than
Expand Down
17 changes: 17 additions & 0 deletions query-connector/src/app/query-building.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,20 @@ export function generateQueryToValueSetInsertionSql(
});
return joinInsertionSqlArray;
}

// Type definitions for CustomUserQueries
export interface CustomQueryConcept {
code: string;
include: boolean;
}

export interface CustomQueryValueSet {
valueSetId: string;
concepts: CustomQueryConcept[];
}

export interface CustomUserQuery {
query_id: string;
query_name: string;
valuesets: CustomQueryValueSet[];
}
Loading