Skip to content

Commit

Permalink
Tweak queryable interfaces based on implementation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Feb 17, 2022
1 parent 4177d60 commit 013f500
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 49 deletions.
2 changes: 1 addition & 1 deletion query.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Dataset Interfaces */
/* Query Interfaces */
/* https://rdf.js.org/query-spec/ */

export * from './query/common';
Expand Down
45 changes: 16 additions & 29 deletions query/common.ts → query/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { EventEmitter } from "events";
import * as RDF from '../data-model';
import { Term } from '../data-model';

/**
* Helper union type for quad term names.
Expand Down Expand Up @@ -71,35 +70,30 @@ export interface QueryResultCardinality {

/**
* Indicates an estimated of the number of results in the stream if type = "estimate",
* or the exact number of quads in the stream if type = "exact".
* or the exact number of results in the stream if type = "exact".
*/
value: number;
}

/**
* A QueryResultMetadata is an object that contains metadata about a certain query result.
* BaseMetadataQuery is helper interface that provides a metadata callback.
*/
export interface QueryResultMetadata<OrderItemsType extends QuadTermName | RDF.Variable> {
interface BaseMetadataQuery<OrderItemsType extends QuadTermName | RDF.Variable, AdditionalMetadataType extends unknown> {
/**
* A callback field for obtaining the cardinality of the result stream.
* Asynchronously return metadata of the current result.
*/
cardinality(precision?: 'estimate' | 'exact'): Promise<QueryResultCardinality>;
metadata<M extends MetadataOpts>(opts?: M): Promise<ConditionalMetadataType<AdditionalMetadataType, M, OrderItemsType>>;
}

/**
* A callback for obtaining the current result ordering of the result stream.
*/
order(): Promise<QueryOperationOrder<OrderItemsType>[]>;
export type MetadataOpts = CardinalityMetadataOpts | OrderMetadataOpts | AvailableOrdersMetadataOpts;
export interface CardinalityMetadataOpts { cardinality: 'estimate' | 'exact'; }
export interface OrderMetadataOpts { order: true; }
export interface AvailableOrdersMetadataOpts { availableOrders: true; }

/**
* A callback for obtaining all available alternative result orderings for the current query.
*/
availableOrders(): Promise<QueryOperationOrder<OrderItemsType>[]>;

/**
* Custom properties
*/
[key: string]: any;
}
export type ConditionalMetadataType<AdditionalMetadataType, M, OrderItemsType extends QuadTermName | RDF.Variable> = AdditionalMetadataType
& (M extends CardinalityMetadataOpts ? { cardinality: QueryResultCardinality } : Record<string, unknown>)
& (M extends OrderMetadataOpts ? { order: QueryOperationOrder<OrderItemsType>['terms'] } : Record<string, unknown>)
& (M extends AvailableOrdersMetadataOpts ? { availableOrders: QueryOperationOrder<OrderItemsType>[] } : Record<string, unknown>);

/**
* Options that can be passed when executing a query.
Expand Down Expand Up @@ -130,29 +124,22 @@ export interface BaseQuery {
* a boolean or void depending on the semantics of the given query.
*/
execute(opts?: any): Promise<ResultStream<any> | boolean | void>;

/**
* Asynchronously metadata of the current result.
*/
metadata?: QueryResultMetadata<any>;
}

/**
* Query object that returns bindings.
*/
export interface QueryBindings extends BaseQuery {
export interface QueryBindings extends BaseQuery, BaseMetadataQuery<RDF.Variable, { variables: RDF.Variable[] }> {
resultType: 'bindings';
execute(opts?: QueryExecuteOptions<RDF.Variable>): Promise<ResultStream<Bindings>>;
metadata: QueryResultMetadata<RDF.Variable> & { variables(): Promise<RDF.Variable[]>; };
}

/**
* Query object that returns quads.
*/
export interface QueryQuads extends BaseQuery {
export interface QueryQuads extends BaseQuery, BaseMetadataQuery<QuadTermName, unknown> {
resultType: 'quads';
execute(opts?: QueryExecuteOptions<QuadTermName>): Promise<ResultStream<RDF.Quad>>;
metadata: QueryResultMetadata<QuadTermName>;
}

/**
Expand Down
File renamed without changes.
65 changes: 46 additions & 19 deletions query/queryable.ts → query/queryable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import * as RDF from '../data-model';
import { Bindings, Query, ResultStream } from './common';

// TODO: we may consider defining some standards, like 'string', RDF.Source, ...
/**
* Context objects provide a way to pass additional bits information to the query engine when executing a query.
*/
export interface QueryContext<SourceType> {
/**
* An array of data sources the query engine must use.
*/
sources: [SourceType, ...SourceType[]];
sources?: [SourceType, ...SourceType[]];
/**
* The date that should be used by SPARQL operations such as NOW().
*/
Expand All @@ -29,7 +28,7 @@ export interface QueryContext<SourceType> {
export interface QueryStringContext<SourceType> extends QueryContext<SourceType> {
/**
* The format in which the query string is defined.
* Defaults to { language: 'SPARQL', version: '1.1' }
* Defaults to { language: 'sparql', version: '1.1' }
*/
queryFormat?: QueryFormat;
/**
Expand All @@ -48,7 +47,7 @@ export type QueryAlgebraContext<SourceType> = QueryContext<SourceType>;
*/
export interface QueryFormat {
/**
* The query language, e.g. 'SPARQL'.
* The query language, e.g. 'sparql'.
*/
language: string;
/**
Expand Down Expand Up @@ -76,7 +75,13 @@ export type Algebra = any;
* @param SourceType The allowed sources over which queries can be executed.
* @param QueryType The allowed query types.
*/
export interface Queryable<QueryFormatType extends string | Algebra, SourceType, QueryType extends Query> {
export interface Queryable<
QueryFormatTypesAvailable extends string | Algebra,
SourceType,
QueryType extends Query,
QueryStringContextType extends QueryStringContext<SourceType>,
QueryAlgebraContextType extends QueryAlgebraContext<SourceType>,
> {
/**
* Initiate a given query.
*
Expand All @@ -86,30 +91,52 @@ export interface Queryable<QueryFormatType extends string | Algebra, SourceType,
*
* @see Query
*/
query(query: QueryFormatType, context?: QueryStringContext<SourceType>): Promise<QueryType>;
query<QueryFormatType extends QueryFormatTypesAvailable>(
query: QueryFormatType,
context?: QueryFormatType extends string ? QueryStringContextType : QueryAlgebraContextType,
): Promise<QueryType>;
}

/**
* SPARQL-constrainted query interface.
*
* This interface guarantees that result objects are of the expected type as defined by the SPARQL spec.
*/
export type SparqlQueryable<QueryFormatType extends string | Algebra, SourceType, SupportedResultType> = unknown
& (SupportedResultType extends BindingsResult ? {
queryBindings(query: QueryFormatType, context?: QueryStringContext<SourceType>): Promise<ResultStream<Bindings>>;
export type SparqlQueryable<
QueryFormatTypesAvailable extends string | Algebra,
SourceType,
QueryStringContextType extends QueryStringContext<SourceType>,
QueryAlgebraContextType extends QueryAlgebraContext<SourceType>,
SupportedResultType,
> = unknown
& (SupportedResultType extends BindingsResultSupport ? {
queryBindings<QueryFormatType extends QueryFormatTypesAvailable>(
query: QueryFormatType,
context?: QueryFormatType extends string ? QueryStringContextType : QueryAlgebraContextType,
): Promise<ResultStream<Bindings>>;
} : unknown)
& (SupportedResultType extends BooleanResult ? {
queryBoolean(query: QueryFormatType, context?: QueryStringContext<SourceType>): Promise<boolean>;
& (SupportedResultType extends BooleanResultSupport ? {
queryBoolean<QueryFormatType extends QueryFormatTypesAvailable>(
query: QueryFormatType,
context?: QueryFormatType extends string ? QueryStringContextType : QueryAlgebraContextType,
): Promise<boolean>;
} : unknown)
& (SupportedResultType extends QuadsResult ? {
queryQuads(query: QueryFormatType, context?: QueryStringContext<SourceType>): Promise<ResultStream<RDF.Quad>>;
& (SupportedResultType extends QuadsResultSupport ? {
queryQuads<QueryFormatType extends QueryFormatTypesAvailable>(
query: QueryFormatType,
context?: QueryFormatType extends string ? QueryStringContextType : QueryAlgebraContextType,
): Promise<ResultStream<RDF.Quad>>;
} : unknown)
& (SupportedResultType extends VoidResult ? {
queryVoid(query: QueryFormatType, context?: QueryStringContext<SourceType>): Promise<void>;
& (SupportedResultType extends VoidResultSupport ? {
queryVoid<QueryFormatType extends QueryFormatTypesAvailable>(
query: QueryFormatType,
context?: QueryFormatType extends string ? QueryStringContextType : QueryAlgebraContextType,
): Promise<void>;
} : unknown)
;

export type BindingsResult = { bindings: true };
export type VoidResult = { void: true };
export type QuadsResult = { quads: true };
export type BooleanResult = { boolean: true };
export type SparqlResultSupport = BindingsResultSupport & VoidResultSupport & QuadsResultSupport & BooleanResultSupport;
export type BindingsResultSupport = { bindings: true };
export type VoidResultSupport = { void: true };
export type QuadsResultSupport = { quads: true };
export type BooleanResultSupport = { boolean: true };

0 comments on commit 013f500

Please sign in to comment.