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

Support multiple graphs and named graphs in SPARQL builders #33

Merged
merged 3 commits into from
Oct 4, 2022
Merged
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
277 changes: 173 additions & 104 deletions library/sparql/sparql_query_builders.ts
Original file line number Diff line number Diff line change
@@ -1,114 +1,183 @@
import {
build,
createNumericBuilder,
createTemplateBuilder,
braces,
parentheses,
SparqlBuilder,
} from "./sparql_shared_builders.ts";

const OFFSET = createNumericBuilder(
(value) => `OFFSET ${value}\n`,
{ build },
);

const LIMIT = createNumericBuilder(
(value) => `LIMIT ${value}\n`,
{ build, OFFSET },
);

const ORDER_BY = createTemplateBuilder(
(value) => `ORDER BY ${value}\n`,
{ build, LIMIT },
);

const HAVING = createTemplateBuilder(
(value) => `HAVING(${value})\n`,
{ build, LIMIT },
);

const GROUP_BY = createTemplateBuilder(
(value) => `GROUP BY ${value}\n`,
{ build, HAVING, ORDER_BY, LIMIT },
);

const WHERE = createTemplateBuilder(
(value) => `WHERE {\n${value}\n}\n`,
{ build, GROUP_BY, ORDER_BY, LIMIT },
);

const FROM_NAMED = createTemplateBuilder(
(value) => `FROM NAMED ${value}\n`,
{ WHERE },
);

const FROM = createTemplateBuilder(
(value) => `FROM ${value}\n`,
{ FROM_NAMED, WHERE },
);

const _SELECT = createTemplateBuilder(
(value) => `SELECT ${value}\n`,
{ FROM, FROM_NAMED, WHERE },
);

const DISTINCT = createTemplateBuilder(
(value) => `SELECT DISTINCT ${value}\n`,
{ FROM, WHERE },
);

const REDUCED = createTemplateBuilder(
(value) => `SELECT REDUCED ${value}\n`,
{
FROM,
WHERE,
import { type RDF } from "../rdf.ts";
import { type SparqlValue } from "./sparql_tag.ts";

type Builders<T extends keyof SparqlQueryBuilder> = Pick<
SparqlQueryBuilder,
T
>;

class SparqlQueryBuilder extends SparqlBuilder {
public OFFSET(
number: number,
): Builders<"build"> {
return this.number(number, "OFFSET");
}

public LIMIT(
number: number,
): Builders<"build" | "OFFSET"> {
return this.number(number, "LIMIT");
}

public ORDER_BY(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "LIMIT"> {
return this.template(strings, values, "ORDER BY");
}

public HAVING(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "ORDER_BY" | "LIMIT"> {
return this.template(strings, values, "HAVING", parentheses);
}

public GROUP_BY(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "HAVING" | "ORDER_BY" | "LIMIT"> {
return this.template(strings, values, "GROUP BY");
}

public WHERE(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "GROUP_BY" | "ORDER_BY" | "LIMIT"> {
return this.template(strings, values, "WHERE", braces);
}

public FROM_NAMED(
stringOrNamedNode: string | RDF.NamedNode<string>,
): Builders<"FROM_NAMED" | "WHERE"> {
return this.namedNode(stringOrNamedNode, "FROM NAMED");
}

public FROM(
stringOrNamedNode: string | RDF.NamedNode<string>,
): Builders<"FROM" | "FROM_NAMED" | "WHERE"> {
return this.namedNode(stringOrNamedNode, "FROM");
}

public SELECT(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"FROM" | "FROM_NAMED" | "WHERE"> {
return this.template(strings, values, "SELECT");
}

public SELECT_DISTINCT(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"FROM" | "FROM_NAMED" | "WHERE"> {
return this.template(strings, values, "SELECT DISTINCT");
}

public SELECT_REDUCED(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"FROM" | "FROM_NAMED" | "WHERE"> {
return this.template(strings, values, "SELECT REDUCED");
}

public CONSTRUCT(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"WHERE"> {
return this.template(strings, values, "CONSTRUCT", braces);
}

public CONSTRUCT_WHERE(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "GROUP_BY" | "ORDER_BY" | "LIMIT"> {
return this.template(strings, values, "CONSTRUCT WHERE", braces);
}

public ASK(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build"> {
return this.template(strings, values, "ASK", braces);
}

public ASK_FROM(
stringOrNamedNode: string | RDF.NamedNode<string>,
): Builders<"FROM" | "FROM_NAMED" | "WHERE"> {
return this.namedNode(stringOrNamedNode, "ASK\nFROM");
}

public ASK_FROM_NAMED(
stringOrNamedNode: string | RDF.NamedNode<string>,
): Builders<"FROM_NAMED" | "WHERE"> {
return this.namedNode(stringOrNamedNode, "ASK\nFROM NAMED");
}

public ASK_WHERE(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "GROUP_BY" | "ORDER_BY" | "LIMIT"> {
return this.template(strings, values, "ASK\nWHERE", braces);
}

public DESCRIBE(
strings: TemplateStringsArray,
...values: SparqlValue[]
): Builders<"build" | "FROM" | "FROM_NAMED" | "WHERE"> {
return this.template(strings, values, "DESCRIBE");
}
}

export const SELECT = Object.assign((
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().SELECT(strings, ...values), {
DISTINCT: (
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().SELECT_DISTINCT(strings, ...values),
REDUCED: (
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().SELECT_REDUCED(strings, ...values),
get ALL() {
return new SparqlQueryBuilder().SELECT`*`;
},
);

export const SELECT = Object.assign(_SELECT, {
DISTINCT,
REDUCED,
ALL: _SELECT`*`,
});

const _CONSTRUCT = createTemplateBuilder(
(value) => `CONSTRUCT {\n${value}\n}\n`,
{ WHERE },
);

const _CONSTRUCT_WHERE = createTemplateBuilder(
(value) => `CONSTRUCT WHERE {\n${value}\n}\n`,
{ build, GROUP_BY, ORDER_BY, LIMIT },
);

export const CONSTRUCT = Object.assign(_CONSTRUCT, {
WHERE: _CONSTRUCT_WHERE,
export const CONSTRUCT = Object.assign((
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().CONSTRUCT(strings, ...values), {
WHERE: (
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().CONSTRUCT_WHERE(strings, ...values),
});

const _ASK = createTemplateBuilder(
(value) => `ASK {\n${value}\n}\n`,
{ build },
);

const _ASK_FROM = createTemplateBuilder(
(value) => `ASK\nFROM ${value}\n`,
{ FROM_NAMED, WHERE },
);

const _ASK_FROM_NAMED = createTemplateBuilder(
(value) => `ASK\nFROM NAMED ${value}\n`,
{ FROM_NAMED, WHERE },
);

const _ASK_WHERE = createTemplateBuilder(
(value) => `ASK\nWHERE {\n${value}\n}\n`,
{ build, GROUP_BY, ORDER_BY, LIMIT },
);

export const ASK = Object.assign(_ASK, {
FROM: _ASK_FROM,
FROM_NAMED: _ASK_FROM_NAMED,
WHERE: _ASK_WHERE,
export const ASK = Object.assign((
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().ASK(strings, ...values), {
FROM: (
stringOrNamedNode: string | RDF.NamedNode<string>,
) => new SparqlQueryBuilder().ASK_FROM(stringOrNamedNode),
FROM_NAMED: (
stringOrNamedNode: string | RDF.NamedNode<string>,
) => new SparqlQueryBuilder().ASK_FROM_NAMED(stringOrNamedNode),
WHERE: (
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().ASK_WHERE(strings, ...values),
});

export const DESCRIBE = createTemplateBuilder(
(value) => `DESCRIBE ${value}\n`,
{ build, FROM, FROM_NAMED, WHERE },
);
export const DESCRIBE = (
strings: TemplateStringsArray,
...values: SparqlValue[]
) => new SparqlQueryBuilder().DESCRIBE(strings, ...values);
Loading