Skip to content

Commit

Permalink
Merge 073b4dd into f24aae3
Browse files Browse the repository at this point in the history
  • Loading branch information
vhf committed Oct 30, 2019
2 parents f24aae3 + 073b4dd commit 6c3984e
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 40 deletions.
19 changes: 14 additions & 5 deletions __tests__/filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ import { Dimension } from "../src/components";
import { DataCube } from "../src/datacube";
import { fetch } from "./utils/fetch-mock";

export function extractFilter(sparql: string) {
return sparql
export function extractKeyword(sparql: string, keyword: string): string {
const lastMatchingLine = sparql
.split("\n")
.filter((line: string) => line.trim().startsWith("FILTER"))
.slice(-1)[0]
.trim();
.filter((line: string) => line.trim().startsWith(keyword))
.slice(-1)[0];
if (lastMatchingLine) {
return lastMatchingLine.trim();
}
return "";
}
export function extractFilter(sparql: string) {
return extractKeyword(sparql, "FILTER");
}
export function extractLimit(sparql: string) {
return extractKeyword(sparql, "LIMIT");
}

const dataCube: DataCube = new DataCube("https://ld.stadt-zuerich.ch/query", {
Expand Down
105 changes: 75 additions & 30 deletions __tests__/query.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { literal, namedNode } from "@rdfjs/data-model";
import { Attribute, Dimension, Measure } from "../src/components";
import { DataCube} from "../src/datacube";
import { DataCube } from "../src/datacube";
import { DataCubeEntryPoint } from "../src/entrypoint";
import { extractFilter } from "./filter.test";
import { extractFilter, extractLimit } from "./filter.test";
import { fetch } from "./utils/fetch-mock";

const betriebsartDimension = new Dimension({
Expand Down Expand Up @@ -106,7 +106,8 @@ describe("select", () => {
});

test("distinct", async () => {
const query = dataCube.query()
const query = dataCube
.query()
.select({
raum: raumDimension,
})
Expand All @@ -121,6 +122,37 @@ test("empty select", async () => {
expect(sparql).toMatchSnapshot();
});

describe("limit", () => {
test("defaults to 10 when not set", async () => {
const query = dataCube.query().select({
raum: raumDimension,
bep: beschaeftigteMeasure.avg(),
});
const sparql = await query.toSparql();
expect(extractLimit(sparql)).toMatchInlineSnapshot(`"LIMIT 10"`);
});

test("uses provided value", async () => {
const query = dataCube.query().select({
raum: raumDimension,
bep: beschaeftigteMeasure.avg(),
})
.limit(12377);
const sparql = await query.toSparql();
expect(extractLimit(sparql)).toMatchInlineSnapshot(`"LIMIT 12377"`);
});

test("can be explicitly removed using null", async () => {
const query = dataCube.query().select({
raum: raumDimension,
bep: beschaeftigteMeasure.avg(),
})
.limit(null);
const sparql = await query.toSparql();
expect(extractLimit(sparql)).toBe("");
});
});

describe("avg", () => {
test("avg", async () => {
const query = dataCube.query().select({
Expand Down Expand Up @@ -165,21 +197,24 @@ describe("avg", () => {
});

test("avg distinct", async () => {
const query = dataCube.query().select({
betriebsart: betriebsartDimension,
geschlecht: geschlechtDimension,
raum: raumDimension,
zeit: zeitDimension,
const query = dataCube
.query()
.select({
betriebsart: betriebsartDimension,
geschlecht: geschlechtDimension,
raum: raumDimension,
zeit: zeitDimension,

bep: beschaeftigteMeasure.avg().distinct(),
bep: beschaeftigteMeasure.avg().distinct(),

quelle: quelleAttribute,
glossar: glossarAttribute,
fussnote: fussnoteAttribute,
datenstand: datenstandAttribute,
erwarteteAktualisierung: erwarteteAktualisierungAttribute,
korrektur: korrekturAttribute,
}).distinct();
quelle: quelleAttribute,
glossar: glossarAttribute,
fussnote: fussnoteAttribute,
datenstand: datenstandAttribute,
erwarteteAktualisierung: erwarteteAktualisierungAttribute,
korrektur: korrekturAttribute,
})
.distinct();
const sparql = await query.toSparql();
expect(sparql).toMatchSnapshot();
});
Expand Down Expand Up @@ -441,9 +476,11 @@ describe("filter", () => {
.filter(beschaeftigteMeasure.gte(literal(filters[2])))
.filter(beschaeftigteMeasure.lt(literal(filters[3])));
const sparql = await query.toSparql();
extractFilter(sparql).split("&&").forEach((part, index) => {
expect(part).toContain(filters[index]);
});
extractFilter(sparql)
.split("&&")
.forEach((part, index) => {
expect(part).toContain(filters[index]);
});
});
});

Expand All @@ -457,7 +494,9 @@ describe("auto names variables", () => {
test("doesn't generate name conflicts", async () => {
// create a cube with a bunch of dimensions with the same label "time" but different IRI,
// we want to make sure they get bound to different names instead of all becoming `?time`
const cube = DataCube.fromJSON('{"endpoint":"https://ld.stadt-zuerich.ch/query","iri":"https://ld.stadt-zuerich.ch/statistics/dataset/BES-RAUM-ZEIT-BTA-SEX","graphIri":"https://linked.opendata.swiss/graph/zh/statistics","labels":[{"value":"Beschäftigte nach Betriebsart, Raum, Geschlecht, Zeit","language":"de"}],"languages":[],"components":{"dimensions":[{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT-c","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT-d","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/RAUM","labels":[{"value":"","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/BTA","labels":[{"value":"something fön","language":""}]}],"measures":[],"attributes":[]}}');
const cube = DataCube.fromJSON(
'{"endpoint":"https://ld.stadt-zuerich.ch/query","iri":"https://ld.stadt-zuerich.ch/statistics/dataset/BES-RAUM-ZEIT-BTA-SEX","graphIri":"https://linked.opendata.swiss/graph/zh/statistics","labels":[{"value":"Beschäftigte nach Betriebsart, Raum, Geschlecht, Zeit","language":"de"}],"languages":[],"components":{"dimensions":[{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT-c","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/ZEIT-d","labels":[{"value":"time","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/RAUM","labels":[{"value":"","language":""}]},{"componentType":"dimension","iri":"https://ld.stadt-zuerich.ch/statistics/property/BTA","labels":[{"value":"something fön","language":""}]}],"measures":[],"attributes":[]}}',
);

const query = cube.query().select({});
const sparql = await query.toSparql();
Expand All @@ -468,12 +507,15 @@ describe("auto names variables", () => {

describe("execute", () => {
it("returns results in a language", async () => {
const entryPoint = new DataCubeEntryPoint("https://trifid-lindas.test.cluster.ldbar.ch/query", {
languages: ["fr", "de"],
fetcher: {
fetch,
const entryPoint = new DataCubeEntryPoint(
"https://trifid-lindas.test.cluster.ldbar.ch/query",
{
languages: ["fr", "de"],
fetcher: {
fetch,
},
},
});
);
const dataCubes = await entryPoint.dataCubes();
const ds = dataCubes[0];

Expand All @@ -499,12 +541,15 @@ describe("execute", () => {
it("returns different results in different languages", async () => {
const results = [];
for (const languages of [[], ["fr"]]) {
const entryPoint = new DataCubeEntryPoint("https://trifid-lindas.test.cluster.ldbar.ch/query", {
languages,
fetcher: {
fetch,
const entryPoint = new DataCubeEntryPoint(
"https://trifid-lindas.test.cluster.ldbar.ch/query",
{
languages,
fetcher: {
fetch,
},
},
});
);
const dataCubes = await entryPoint.dataCubes();
const ds = dataCubes[0];

Expand Down
11 changes: 6 additions & 5 deletions src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface QueryState {
groupBys: Array<PredicateFunction | string>;
havings: PredicateFunction[];
offset: number;
limit: number;
limit: number | null;
distinct: boolean;
order: Component[];
}
Expand Down Expand Up @@ -194,11 +194,12 @@ export class Query {
}

/**
* Limit the number of results to return. Defaults to `10`.
* Limit the number of results to return. Defaults to `10`, even when `.limit()` is not used.
* Use `.limit(null)` to remove the default limit and get all results.
*
* @param {number} How many results to return.
* @param {number|null} How many results to return. `null` removes the limit.
*/
public limit(limit: number) {
public limit(limit: number | null) {
const self = this.clone();
self.state.limit = limit;
return self;
Expand Down Expand Up @@ -271,7 +272,7 @@ export class Query {
public async execute(): Promise<any[]> {
const query = await this.toSparql();
const results = await this.fetcher.select(query);
if (results.every((obj) => obj.key && obj.value)) {
if (results.length && results.every((obj) => obj.key && obj.value)) {
const error = results.reduce((obj, {key, value}) => {
obj[key] = value;
return obj;
Expand Down

0 comments on commit 6c3984e

Please sign in to comment.