Skip to content

Commit c70428e

Browse files
committed
Added blank node get support.
1 parent 0d30fce commit c70428e

7 files changed

Lines changed: 161 additions & 162 deletions

File tree

index.js

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

22
var jsonld = require("jsonld")
33
, uuid = require("uuid")
4-
, IRI = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i;
4+
, IRI = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i
5+
, RDFTYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
6+
, async = require("async");
57

68
function levelgraphJSONLD(db, jsonldOpts) {
79

@@ -43,59 +45,108 @@ function levelgraphJSONLD(db, jsonldOpts) {
4345
callback(null, obj);
4446
});
4547

46-
expanded.forEach(function(triples) {
48+
var writeTriples = function(triples) {
4749
var subject = triples["@id"];
4850
delete triples["@id"];
4951

5052
if (!subject) {
51-
subject = (options.base || graphdb.jsond.options.base) + uuid.v1();
53+
subject = "_:" + uuid.v1();
5254
}
5355

5456
Object.keys(triples).forEach(function(predicate) {
57+
if (predicate === "@type") {
58+
if (!triples[predicate].forEach) {
59+
triples[predicate] = [triples[predicate]];
60+
}
61+
62+
triples[RDFTYPE] = triples[predicate];
63+
delete triples[predicate];
64+
predicate = RDFTYPE;
65+
}
66+
5567
triples[predicate].forEach(function(object) {
5668
var triple = {
5769
subject: subject
5870
, predicate: predicate
59-
, object: object["@id"] || object["@value"]
71+
, object: (typeof object === 'string') ? object : object["@id"] || object["@value"]
6072
};
73+
74+
if (!triple.object) {
75+
// the object should be a blank node that points
76+
// to a another triple
77+
writeTriples(object);
78+
triple.object = object["@id"];
79+
}
80+
6181
stream.write(triple);
6282
});
6383
});
64-
});
84+
85+
triples["@id"] = subject;
86+
};
87+
88+
expanded.forEach(writeTriples);
6589

6690
stream.end();
6791
});
6892
};
6993

70-
graphdb.jsonld.get = function(iri, context, options, callback) {
71-
72-
if (typeof options === 'function') {
73-
callback = options;
74-
options = {};
94+
var fetchExpandedTriples = function(iri, memo, callback) {
95+
if (typeof memo === "function") {
96+
callback = memo;
97+
memo = {};
7598
}
7699

77100
graphdb.get({ subject: iri }, function(err, triples) {
78101
if (err || triples.length === 0) {
79102
return callback(err, null);
80103
}
81104

82-
var triples = triples.reduce(function(acc, triple) {
83-
var key;
105+
async.reduce(triples, memo, function(acc, triple, cb) {
106+
var key;
84107

85-
if (!acc[triple.subject]) {
86-
acc[triple.subject] = { "@id": triple.subject };
87-
}
88-
acc[triple.subject][triple.predicate] = {};
89-
key = triple.object.match(IRI) ? "@id" : "@value";
90-
acc[triple.subject][triple.predicate][key] = triple.object;
108+
if (!acc[triple.subject]) {
109+
acc[triple.subject] = { "@id": triple.subject };
110+
}
111+
112+
if (triple.predicate === RDFTYPE) {
113+
if (acc[triple.subject]["@type"]) {
114+
acc[triple.subject]["@type"] = [acc[triple.subject]["@type"]];
115+
acc[triple.subject]["@type"].push(triple.object);
116+
} else {
117+
acc[triple.subject]["@type"] = triple.object;
118+
}
119+
cb(null, acc);
120+
} else if (triple.object.indexOf("_:") !== 0) {
121+
acc[triple.subject][triple.predicate] = {};
122+
key = (triple.object.match(IRI) || triple.object.indexOf("_:") === 0) ? "@id" : "@value";
123+
acc[triple.subject][triple.predicate][key] = triple.object;
124+
cb(null, acc);
125+
} else {
126+
fetchExpandedTriples(triple.object, function(err, expanded) {
127+
acc[triple.subject][triple.predicate] = expanded[triple.object];
128+
cb(err, acc);
129+
});
130+
}
131+
}, callback);
132+
});
133+
};
91134

92-
return acc;
93-
}, {})
135+
graphdb.jsonld.get = function(iri, context, options, callback) {
94136

95-
, expanded = Object.keys(triples).reduce(function(acc, key) {
96-
acc.push(triples[key]);
97-
return acc;
98-
}, []);
137+
if (typeof options === 'function') {
138+
callback = options;
139+
options = {};
140+
}
141+
142+
fetchExpandedTriples(iri, function(err, expanded) {
143+
if (err || expanded === null) {
144+
return callback(err, expanded);
145+
}
146+
expanded = Object.keys(expanded).reduce(function(acc, key) {
147+
acc.push(expanded[key]);
148+
return acc;
149+
}, []);
99150

100151
jsonld.compact(expanded, context, options, callback);
101152
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"license": "MIT",
2525
"dependencies": {
2626
"jsonld": "0.0.62",
27-
"uuid": "~1.4.1"
27+
"uuid": "~1.4.1",
28+
"async": "~0.2.9"
2829
},
2930
"peerDependencies": {
3031
"levelgraph": "~0.6.1"

test/common.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,13 @@
22

33
global.chai = require("chai");
44
global.expect = require("chai").expect;
5+
6+
var fs = require("fs")
7+
, fixtures = {};
8+
9+
global.fixture = function(name) {
10+
if (!fixtures[name]) {
11+
fixtures[name] = fs.readFileSync(__dirname + "/fixture/" + name);
12+
}
13+
return JSON.parse(fixtures[name]);
14+
};

test/fixture/john.jsonld

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/fixture/person.jsonld

Lines changed: 0 additions & 86 deletions
This file was deleted.

test/get_spec.js

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,16 @@
11

2-
var level = require("level-test")()
3-
, graph = require("levelgraph")
2+
var level = require("level-test")()
3+
, graph = require("levelgraph")
44
, jsonld = require("../")
5+
, fs = require("fs")
6+
, JSONLD = require("jsonld");
57

68
describe("jsonld.get", function() {
79

8-
var db
9-
, manu = {
10-
"@context": {
11-
"name": "http://xmlns.com/foaf/0.1/name"
12-
, "homepage": {
13-
"@id": "http://xmlns.com/foaf/0.1/homepage"
14-
, "@type": "@id"
15-
}
16-
}
17-
, "@id": "http://manu.sporny.org#person"
18-
, "name": "Manu Sporny"
19-
, "homepage": "http://manu.sporny.org/"
20-
};
10+
var db, manu = fixture("manu.json");
2111

2212
beforeEach(function() {
23-
db = jsonld(graph(level()));
13+
db = jsonld(graph(level()), { base: "http://levelgraph.io/get" } );
2414
});
2515

2616
afterEach(function(done) {
@@ -46,4 +36,22 @@ describe("jsonld.get", function() {
4636
});
4737
});
4838
});
39+
40+
describe("with an object with blank nodes", function() {
41+
var tesla;
42+
43+
beforeEach(function(done) {
44+
tesla = fixture("tesla.json")
45+
db.jsonld.put(tesla, done);
46+
});
47+
48+
it("should load it properly", function(done) {
49+
db.jsonld.get(tesla["@id"], { "@context": tesla["@context"] }, function(err, obj) {
50+
tesla["gr:hasPriceSpecification"]["@id"] = obj["gr:hasPriceSpecification"]["@id"];
51+
tesla["gr:includes"]["@id"] = obj["gr:includes"]["@id"];
52+
expect(obj).to.eql(tesla);
53+
done();
54+
});
55+
});
56+
});
4957
});

0 commit comments

Comments
 (0)