-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for text/turtle format for quad queries (#55)
Resolves #54.
- Loading branch information
1 parent
d0b7003
commit 028981c
Showing
9 changed files
with
167 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"deno.enable": true, | ||
"deno.importMap": ".vscode/import_map.json", | ||
"deno.documentPreloadLimit": 0, | ||
"editor.defaultFormatter": "denoland.vscode-deno" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { BindingsFactory, N3, QuadFactory, type RDF, RDFJSON } from "../rdf.ts"; | ||
import { | ||
ArrayIterator, | ||
MappingIterator, | ||
TreeIterator, | ||
} from "../asynciterator.ts"; | ||
|
||
type ResolveFormat = { | ||
"boolean": boolean; | ||
"bindings": RDF.ResultStream<RDF.Bindings>; | ||
"quads": RDF.ResultStream<RDF.Quad>; | ||
}; | ||
|
||
export type ResolverType = keyof ResolveFormat; | ||
|
||
abstract class QueryResolver< | ||
T extends ResolverType, | ||
O = Promise<ResolveFormat[T]>, | ||
> { | ||
abstract resolve(response: Response): O; | ||
} | ||
|
||
class BooleanJsonResolver extends QueryResolver<"boolean"> { | ||
async resolve(response: Response) { | ||
const json = await response.json(); | ||
if ("boolean" in json) { | ||
return Boolean(json.boolean); | ||
} | ||
throw new Error("Boolean SPARQL query result not found"); | ||
} | ||
} | ||
|
||
class BindingsJsonResolver extends QueryResolver<"bindings"> { | ||
async resolve(response: Response) { | ||
const json = await response.json(); | ||
|
||
if (!Array.isArray(json.results?.bindings)) { | ||
throw new Error("Bindings SPARQL query result not found"); | ||
} | ||
|
||
const bindingsFactory = new BindingsFactory(); | ||
|
||
const bindingsIterator = new ArrayIterator<RDFJSON.Bindings>( | ||
json.results!.bindings, | ||
); | ||
|
||
// TODO: review the unknown type cast | ||
return new MappingIterator( | ||
bindingsIterator, | ||
(i) => bindingsFactory.fromJson(i), | ||
) as unknown as RDF.ResultStream<RDF.Bindings>; | ||
} | ||
} | ||
|
||
class QuadsJsonResolver extends QueryResolver<"quads"> { | ||
async resolve(response: Response) { | ||
const json = await response.json(); | ||
|
||
if (!(json?.constructor === Object)) { | ||
throw new Error("Quads SPARQL query result not found"); | ||
} | ||
|
||
const quadFactory = new QuadFactory(); | ||
|
||
const treeIterator = new TreeIterator<RDFJSON.Term>(json); | ||
|
||
// TODO: review the unknown type cast | ||
return new MappingIterator( | ||
treeIterator, | ||
(i) => quadFactory.fromJson(i as [string, string, RDFJSON.Term]), | ||
) as unknown as RDF.ResultStream<RDF.Quad>; | ||
} | ||
} | ||
|
||
class QuadsTurtleResolver extends QueryResolver<"quads"> { | ||
async resolve(response: Response) { | ||
const text = await response.text(); | ||
|
||
const quads = new N3.Parser({ format: "turtle" }).parse(text); | ||
return new ArrayIterator(quads); | ||
} | ||
} | ||
|
||
type ResolversMap = { | ||
[K in ResolverType]: Record<string, QueryResolver<K>>; | ||
}; | ||
|
||
const resolvers: ResolversMap = { | ||
"boolean": { | ||
"application/sparql-results+json": new BooleanJsonResolver(), | ||
}, | ||
"bindings": { | ||
"application/sparql-results+json": new BindingsJsonResolver(), | ||
}, | ||
"quads": { | ||
"application/rdf+json": new QuadsJsonResolver(), | ||
"text/turtle": new QuadsTurtleResolver(), | ||
}, | ||
}; | ||
|
||
export const getResponseTypes = (resolverType: ResolverType) => | ||
Object.keys(resolvers[resolverType]); | ||
|
||
export const resolve = <T extends ResolverType>( | ||
resolverType: T, | ||
response: Response, | ||
) => { | ||
const contentType = response.headers.get("Content-type"); | ||
if (!contentType) { | ||
throw new Error(`Content-type header was not found in response`); | ||
} | ||
const separatorPosition = contentType.indexOf(";"); | ||
const mime = separatorPosition > 0 | ||
? contentType.substring(0, separatorPosition) | ||
: contentType; | ||
|
||
const resolver = resolvers[resolverType][mime]; | ||
|
||
if (!resolver) { | ||
throw new Error(`No resolver exists for response type '${mime}'`); | ||
} | ||
|
||
return resolver.resolve(response); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,9 @@ export { fromRdf, toRdf } from "npm:[email protected]"; | |
import { DataFactory, DefaultGraph } from "npm:[email protected]"; | ||
export { DataFactory, DefaultGraph }; | ||
|
||
// @deno-types="npm:@types/n3" | ||
export * as N3 from "npm:[email protected]"; | ||
|
||
import type { | ||
IDataSource, | ||
IQueryContextCommon, | ||
|
@@ -52,7 +55,7 @@ export declare namespace RDFJSON { | |
type Term = { | ||
type: "uri" | "literal" | "bnode"; | ||
value: string; | ||
"xml:lang"?: string; | ||
lang?: string; | ||
datatype?: string; | ||
}; | ||
type Bindings = Record<string, Term>; | ||
|
@@ -91,8 +94,8 @@ export class TermFactory implements RDFJSON.TermFactory { | |
if (jsonTerm.type === "bnode") { | ||
return this.dataFactory.blankNode(jsonTerm.value); | ||
} | ||
if ("xml:lang" in jsonTerm) { | ||
return this.dataFactory.literal(jsonTerm.value, jsonTerm["xml:lang"]); | ||
if ("lang" in jsonTerm) { | ||
return this.dataFactory.literal(jsonTerm.value, jsonTerm["lang"]); | ||
} | ||
if ("datatype" in jsonTerm) { | ||
return this.dataFactory.literal( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,3 @@ export { | |
export { assert as assertTypeSafe } from "npm:[email protected]"; | ||
|
||
export { QueryEngine as Comunica } from "npm:@comunica/[email protected]"; | ||
|
||
// @deno-types="npm:@types/n3" | ||
export * as N3 from "npm:[email protected]"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters