UNPKG

medicaid

Version:

Software Development Kit (SDK) to interact with the data.gov Medicaid API

107 lines (100 loc) 3.46 kB
import {getItems} from "./httpMethods.js"; async function getDatastoreQuerySql(sqlQuery) { //handles all sql query GET requests let result; let limit= parseLimit(sqlQuery) if (!limit){ result = await sqlNoLimit(sqlQuery); } else if (limit <= 10000){ result = await getItems(`datastore/sql?query=${sqlQuery}&show_db_columns=false`); } else { result = await sqlHighLimit(sqlQuery); } if (result === undefined){ throw new Error("The SQL query could not be executed.") } return result; } function parseOffset(query) { if (query.includes("OFFSET")) { let offset = query.split("OFFSET")[1].trimStart().split("]")[0] return parseInt(offset); } return null; } function parseLimit(query){ if (query.includes("LIMIT")) { let limit = (query.split("LIMIT")[1].trimStart().split(" ")[0]).split("]")[0] return parseInt(limit) } return null; } async function fetchChunk(offset, limit, sqlQuery) { let adjustedQuery; let parsedOffset = parseOffset(sqlQuery); let parsedLimit = parseLimit(sqlQuery); if (parsedOffset){ if (parsedLimit){ const splitQuery = sqlQuery.split(`[LIMIT ${parsedLimit} OFFSET ${parsedOffset}]`); adjustedQuery = `${splitQuery[0]}[LIMIT ${limit} OFFSET ${offset}]` } else { const splitQuery = sqlQuery.split(`[OFFSET ${parsedOffset}]`); adjustedQuery = `${splitQuery[0]}[LIMIT ${limit} OFFSET ${offset}]` } } else { if (parsedLimit){ const splitQuery = sqlQuery.split(`[LIMIT`) adjustedQuery = `${splitQuery[0]}[LIMIT ${limit} OFFSET ${offset}]`; } else { adjustedQuery = `${sqlQuery}[LIMIT ${limit} OFFSET ${offset}]` } } const baseEndpoint = `datastore/sql?query=${adjustedQuery}&show_db_columns=false`; return getItems(baseEndpoint); } async function sqlHighLimit(sqlQuery){ let promises = []; let limit = parseLimit(sqlQuery); let offset = parseOffset(sqlQuery) || 0; const firstRequestCheck = await fetchChunk(offset, 10000, sqlQuery); if (firstRequestCheck.length < 10000){ return firstRequestCheck; } while (limit > 0) { const currentLimit = Math.min(limit, 10000); promises.push(fetchChunk(offset, currentLimit, sqlQuery)); offset += 10000; limit -= currentLimit; } const responses = await Promise.all(promises); return responses.flat(); } async function sqlNoLimit(sqlQuery) { let allData = []; let offset = parseOffset(sqlQuery) || 0; let condition = true let responses = []; let count = 0; const firstRequestCheck = await fetchChunk(offset, 1000, sqlQuery); if (firstRequestCheck.length < 1000){ return firstRequestCheck; } while (condition){ const promises = []; for (let i = 0; i < 3; i++) { promises.push(fetchChunk(offset, 10000, sqlQuery)); offset += 10000; } responses = await Promise.all(promises); count += promises.length; allData.push(...responses.flat()) if (responses.some(response => response.length !== 10000)){ condition = false; } } return allData; } export{ getDatastoreQuerySql }