Skip to content

Commit c9de920

Browse files
author
Benjamin Forster
committed
add prefixes to keys on put, and decode them on get
1 parent a39a660 commit c9de920

5 files changed

Lines changed: 61 additions & 49 deletions

File tree

index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const events = require('events')
66
const SparqlIterator = require('sparql-iterator')
77

88
const utils = require('./lib/utils')
9+
const prefixes = require('./lib/prefixes')
910
const Variable = require('./lib/Variable')
1011
const HyperdbReadTransform = require('./lib/HyperdbReadTransform')
1112
const JoinStream = require('./lib/JoinStream')
@@ -37,6 +38,24 @@ inherits(Graph, events.EventEmitter)
3738

3839
Graph.prototype.v = (name) => new Variable(name)
3940

41+
Graph.prototype.prefixes = function (callback) {
42+
// should cache this somehow
43+
const prefixStream = this.db.createReadStream(prefixes.PREFIX_KEY)
44+
utils.collect(prefixStream, (err, data) => {
45+
if (err) return callback(err)
46+
var names = data.reduce((p, nodes) => {
47+
var data = prefixes.fromNodes(nodes)
48+
p[data.prefix] = data.uri
49+
return p
50+
}, {})
51+
callback(null, names)
52+
})
53+
}
54+
55+
Graph.prototype.addPrefix = function (prefix, uri, cb) {
56+
this.db.put(prefixes.toKey(prefix), uri, cb)
57+
}
58+
4059
Graph.prototype.getStream = function (triple, opts) {
4160
const stream = this.db.createReadStream(utils.createQuery(triple))
4261
return stream.pipe(new HyperdbReadTransform(this.db, opts))

lib/utils.js

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const Variable = require('./Variable')
2+
const prefixes = require('./prefixes')
23

34
const defs = {
45
spo: ['subject', 'predicate', 'object'],
@@ -22,15 +23,6 @@ function collect (stream, cb) {
2223
stream.once('end', cb.bind(null, null, res))
2324
}
2425

25-
function namespaceBlankVariables (triple) {
26-
Object.keys(triple).forEach((key) => {
27-
if (triple[key].startsWith && triple[key].startsWith('_:')) {
28-
triple[key] = triple[key].replace(/^_:/, 'hg:')
29-
}
30-
})
31-
return triple
32-
}
33-
3426
function filterTriple (triple) {
3527
const filtered = {}
3628
defs.spo.forEach((key) => {
@@ -43,13 +35,13 @@ function filterTriple (triple) {
4335

4436
function escapeKeyValue (value) {
4537
if (typeof value === 'string' || value instanceof String) {
46-
return value.replace(/(\/)/g, '%2F')
38+
return prefixes.toPrefixed(value, prefixes.DEFAULT_PREFIXES).replace(/(\/)/g, '%2F')
4739
}
4840
return value
4941
}
5042

5143
function unescapeKeyValue (value) {
52-
return value.replace(/%2F/g, '/')
44+
return prefixes.fromPrefixed(value.replace(/%2F/g, '/'), prefixes.DEFAULT_PREFIXES)
5345
}
5446

5547
function decodeKey (key) {
@@ -86,13 +78,12 @@ function encodeKeys (triple) {
8678
}
8779

8880
function generateBatch (triple, action) {
89-
const namespacedTriple = namespaceBlankVariables(triple)
9081
if (!action) action = 'put'
9182
var data = null
9283
if (action === 'put') {
9384
data = JSON.stringify(extraDataMask(triple))
9485
}
95-
return encodeKeys(namespacedTriple).map(key => ({
86+
return encodeKeys(triple).map(key => ({
9687
type: 'put', // no delete in hyperdb so just putting nulls
9788
key: key,
9889
value: data

test/fixture/foaf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ module.exports = [{
3838
subject: 'davide',
3939
predicate: 'age',
4040
object: 70
41-
}];
41+
}]

test/sparql.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('hypergraph.queryStream', () => {
4545
it('performs CONSTRUCT query type with UNION operator', (done) => {
4646
console.time('query')
4747
var expected = [
48-
{ subject: 'hg:b0_b',
48+
{ subject: 'hg://b0_b',
4949
predicate: 'http://www.w3.org/2001/vcard-rdf/3.0#N',
5050
object: '_:b0' },
5151
{ subject: '_:b0',
@@ -54,7 +54,7 @@ describe('hypergraph.queryStream', () => {
5454
{ subject: '_:b0',
5555
predicate: 'http://www.w3.org/2001/vcard-rdf/3.0#familyName',
5656
object: '"Hacker"' },
57-
{ subject: 'hg:b0_a',
57+
{ subject: 'hg://b0_a',
5858
predicate: 'http://www.w3.org/2001/vcard-rdf/3.0#N',
5959
object: '_:b1' },
6060
{ subject: '_:b1',

test/utils.spec.js

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,44 @@
22
const expect = require('chai').expect
33
const utils = require('../lib/utils')
44

5-
describe('encodeKey', () => {
6-
it('generates a unique index key for a triple (spo)', () => {
7-
var key = utils.encodeKey('spo', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
8-
expect(key).to.eql('spo/a-subject/a-predicate/a-object')
9-
})
10-
it('generates a unique index key for a triple (spo)', () => {
11-
var key = utils.encodeKey('sop', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
12-
expect(key).to.eql('sop/a-subject/a-object/a-predicate')
13-
})
14-
it('generates a unique index key for a triple (osp)', () => {
15-
var key = utils.encodeKey('osp', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
16-
expect(key).to.eql('osp/a-object/a-subject/a-predicate')
17-
})
5+
describe('util functions', () => {
6+
describe('encodeKey', () => {
7+
it('generates a unique index key for a triple (spo)', () => {
8+
var key = utils.encodeKey('spo', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
9+
expect(key).to.eql('spo/a-subject/a-predicate/a-object')
10+
})
11+
it('generates a unique index key for a triple (spo)', () => {
12+
var key = utils.encodeKey('sop', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
13+
expect(key).to.eql('sop/a-subject/a-object/a-predicate')
14+
})
15+
it('generates a unique index key for a triple (osp)', () => {
16+
var key = utils.encodeKey('osp', { subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
17+
expect(key).to.eql('osp/a-object/a-subject/a-predicate')
18+
})
1819

19-
it('escapes forward slashes in the triple', () => {
20-
var key = utils.encodeKey('spo', { subject: 'a/subject' })
21-
expect(key).to.eql('spo/a%2Fsubject/')
20+
it('escapes forward slashes in the triple', () => {
21+
var key = utils.encodeKey('spo', { subject: 'a/subject' })
22+
expect(key).to.eql('spo/a%2Fsubject/')
23+
})
2224
})
23-
})
2425

25-
describe('decodeKey', () => {
26-
it('generates a triple from a index key (spo)', () => {
27-
var triple = utils.decodeKey('spo/a-subject/a-predicate/a-object')
28-
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
29-
})
30-
it('generates a triple from a index key (spo)', () => {
31-
var triple = utils.decodeKey('sop/a-subject/a-object/a-predicate')
32-
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
33-
})
34-
it('generates a triple from a index key (osp)', () => {
35-
var triple = utils.decodeKey('osp/a-object/a-subject/a-predicate')
36-
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
37-
})
26+
describe('decodeKey', () => {
27+
it('generates a triple from a index key (spo)', () => {
28+
var triple = utils.decodeKey('spo/a-subject/a-predicate/a-object')
29+
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
30+
})
31+
it('generates a triple from a index key (spo)', () => {
32+
var triple = utils.decodeKey('sop/a-subject/a-object/a-predicate')
33+
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
34+
})
35+
it('generates a triple from a index key (osp)', () => {
36+
var triple = utils.decodeKey('osp/a-object/a-subject/a-predicate')
37+
expect(triple).to.eql({ subject: 'a-subject', object: 'a-object', predicate: 'a-predicate' })
38+
})
3839

39-
it('unescapes escaped /‘s from index key (spo)', () => {
40-
var triple = utils.decodeKey('spo/a%2Fsubject/a%2Fpredicate/a%2Fobject')
41-
expect(triple).to.eql({ subject: 'a/subject', object: 'a/object', predicate: 'a/predicate' })
40+
it('unescapes escaped /‘s from index key (spo)', () => {
41+
var triple = utils.decodeKey('spo/a%2Fsubject/a%2Fpredicate/a%2Fobject')
42+
expect(triple).to.eql({ subject: 'a/subject', object: 'a/object', predicate: 'a/predicate' })
43+
})
4244
})
4345
})

0 commit comments

Comments
 (0)