UNPKG

@comake/skl-js-engine

Version:

Standard Knowledge Language Javascript Engine

204 lines 9.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SparqlQueryAdapter = void 0; const SparqlUtil_1 = require("../../../util/SparqlUtil"); const TripleUtil_1 = require("../../../util/TripleUtil"); const InMemorySparqlQueryExecutor_1 = require("./query-executor/InMemorySparqlQueryExecutor"); const SparqlEndpointQueryExecutor_1 = require("./query-executor/SparqlEndpointQueryExecutor"); const SparqlQueryBuilder_1 = require("./SparqlQueryBuilder"); const SparqlUpdateBuilder_1 = require("./SparqlUpdateBuilder"); /** * A {@link QueryAdapter} that stores data in a database through a sparql endpoint. */ class SparqlQueryAdapter { constructor(options) { this.setTimestamps = options.setTimestamps ?? false; switch (options.type) { case 'memory': this.queryExecutor = new InMemorySparqlQueryExecutor_1.InMemorySparqlQueryExecutor(); break; case 'sparql': this.queryExecutor = new SparqlEndpointQueryExecutor_1.SparqlEndpointQueryExecutor(options); break; default: throw new Error('No schema source found in setSchema args.'); } } async executeRawQuery(query) { const response = await this.queryExecutor.executeSparqlSelectAndGetDataRaw(query); if (response.length === 0) { return []; } return (0, SparqlUtil_1.selectQueryResultsAsJSValues)(response); } async executeRawConstructQuery(query, frame) { const response = await this.queryExecutor.executeSparqlConstructAndGetDataRaw(query); if (response.length === 0) { return { '@graph': [] }; } return await (0, TripleUtil_1.triplesToJsonldWithFrame)(response, frame); } async executeRawUpdate(query) { await this.queryExecutor.executeRawSparqlUpdate(query); } async find(options) { const jsonld = await this.findAllAsJsonLd({ ...options, limit: 1 }); if (Array.isArray(jsonld) && !options?.skipFraming) { if (jsonld.length === 0) { return null; } if (jsonld.length === 1) { return jsonld[0]; } } return jsonld; } async findBy(where) { return this.find({ where }); } async findAll(options) { const jsonld = await this.findAllAsJsonLd(options); if (Array.isArray(jsonld)) { return jsonld; } return [jsonld]; } async findAllAsJsonLd(options) { const queryBuilder = new SparqlQueryBuilder_1.SparqlQueryBuilder(); const { where, selectionTriples, entityOrder } = await this.buildFindAllQueryData(queryBuilder, options); if (entityOrder && entityOrder.length === 0) { return []; } const queryData = queryBuilder.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, options); const query = queryBuilder.buildConstructFromEntitySelectQuery(where, selectionTriples, options?.select, queryData.selectVariables); return await this.executeEntitySelectQuery(query, options, entityOrder); } async buildFindAllQueryData(queryBuilder, options) { const queryData = queryBuilder.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, options); const entitySelectQuery = queryData.where.length > 0 ? (0, SparqlUtil_1.createSparqlSelectQuery)([ options?.entitySelectVariable ?? SparqlUtil_1.entityVariable, ...(queryData.selectVariables?.map(({ variable, expression }) => ({ variable, expression, })) ?? []), ], queryData.where, queryData.orders, queryData.group ?? options?.group, options?.limit, options?.offset) : undefined; let entityOrder; if (queryData.orders.length > 0 && options?.limit !== 1 && entitySelectQuery) { const entitySelectResponse = await this.queryExecutor.executeSparqlSelectAndGetData(entitySelectQuery); const valuesByVariable = (0, SparqlUtil_1.groupSelectQueryResultsByKey)(entitySelectResponse); entityOrder = (0, SparqlUtil_1.getEntityVariableValuesFromVariables)(valuesByVariable); if (entityOrder.length === 0) { return { where: queryData.where, selectionTriples: queryData.graphSelectionTriples, entityOrder: [], }; } const variableValueFilters = (0, SparqlUtil_1.createValuesPatternsForVariables)(valuesByVariable); queryData.graphWhere = [...variableValueFilters, ...queryData.graphWhere]; } else if (entitySelectQuery) { const entitySelectGroupQuery = (0, SparqlUtil_1.createSparqlSelectGroup)([entitySelectQuery]); queryData.graphWhere.unshift(entitySelectGroupQuery); } return { where: queryData.graphWhere, selectionTriples: queryData.graphSelectionTriples, entityOrder, }; } async executeEntitySelectQuery(query, options, entityOrder) { const responseTriples = await this.queryExecutor.executeSparqlSelectAndGetData(query); return await (0, TripleUtil_1.triplesToJsonld)(responseTriples, options?.skipFraming, options?.relations, options?.where, entityOrder); } async findAllBy(where) { return this.findAll({ where }); } async exists(options) { const queryBuilder = new SparqlQueryBuilder_1.SparqlQueryBuilder(); const queryData = queryBuilder.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, options); const values = queryData.graphWhere.filter((pattern) => pattern.type === 'values'); const query = (0, SparqlUtil_1.creteSparqlAskQuery)([...values, ...queryData.where]); return await this.queryExecutor.executeAskQueryAndGetResponse(query); } async count(options) { const queryBuilder = new SparqlQueryBuilder_1.SparqlQueryBuilder(); const queryData = queryBuilder.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, options); const values = queryData.graphWhere.filter((pattern) => pattern.type === 'values'); const query = (0, SparqlUtil_1.createSparqlCountSelectQuery)(SparqlUtil_1.entityVariable, [...values, ...queryData.where], queryData.orders, options?.offset); return await this.queryExecutor.executeSelectCountAndGetResponse(query); } async save(entityOrEntities) { const queryBuilder = new SparqlUpdateBuilder_1.SparqlUpdateBuilder({ setTimestamps: this.setTimestamps }); const query = queryBuilder.buildUpdate(entityOrEntities); await this.queryExecutor.executeSparqlUpdate(query); return entityOrEntities; } async groupBy(options) { const queryBuilder = new SparqlQueryBuilder_1.SparqlQueryBuilder(); const { query: selectQuery, variableMapping } = await queryBuilder.buildGroupByQuery(options); const results = await this.queryExecutor.executeSparqlSelectAndGetData(selectQuery); // Create reverse mapping from path to variable name const reverseMapping = Object.entries(variableMapping).reduce((acc, [varName, path]) => { acc[path] = varName; return acc; }, {}); // Transform results const groupResults = results.map((result) => { const group = {}; options.groupBy?.forEach((path) => { const varName = reverseMapping[path]; if (!varName) { throw new Error(`No variable mapping found for path: ${path}`); } const value = result[varName].value; // Try to convert to number if possible group[path] = isNaN(Number(value)) ? value : Number(value); }); if (options.dateGrouping) { const dateGroupVarName = reverseMapping['dateGroup']; group.dateGroup = result[dateGroupVarName].value; } const countVarName = reverseMapping['count']; const entityIdsVarName = reverseMapping['entityIds']; return { group, count: parseInt(result[countVarName].value, 10), entityIds: result[entityIdsVarName].value.split(" "), }; }); return { results: groupResults, meta: { totalCount: groupResults.reduce((sum, curr) => sum + curr.count, 0), dateRange: options.dateRange, groupings: options.groupBy || [], }, }; } async update(idOrIds, attributes) { const queryBuilder = new SparqlUpdateBuilder_1.SparqlUpdateBuilder({ setTimestamps: this.setTimestamps }); const query = queryBuilder.buildPartialUpdate(idOrIds, attributes); await this.queryExecutor.executeSparqlUpdate(query); } async delete(idOrIds) { const queryBuilder = new SparqlUpdateBuilder_1.SparqlUpdateBuilder(); const query = queryBuilder.buildDeleteById(idOrIds); await this.queryExecutor.executeSparqlUpdate(query); } async destroy(entityOrEntities) { const queryBuilder = new SparqlUpdateBuilder_1.SparqlUpdateBuilder(); const query = queryBuilder.buildDelete(entityOrEntities); await this.queryExecutor.executeSparqlUpdate(query); return entityOrEntities; } async destroyAll() { const queryBuilder = new SparqlUpdateBuilder_1.SparqlUpdateBuilder(); const query = queryBuilder.buildDeleteAll(); await this.queryExecutor.executeSparqlUpdate(query); } } exports.SparqlQueryAdapter = SparqlQueryAdapter; //# sourceMappingURL=SparqlQueryAdapter.js.map