Skip to content

Commit

Permalink
Merge pull request #119 from doowb/exact-matches
Browse files Browse the repository at this point in the history
Exact matches
  • Loading branch information
mcollina committed Apr 28, 2015
2 parents 599cbce + 9b92c00 commit 55beefc
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -660,6 +660,7 @@ LevelGraph is only possible due to the excellent work of the following contribut
href="https://github.com/jez0990">GitHub/jez0990</a></td></tr>
<tr><th align="left">Elf Pavlik</th><td><a href="https://github.com/elf-pavlik">GitHub/elf-pavlik</a></td><td><a href="https://twitter.com/elfpavlik">Twitter/@elfpavlik</a></td></tr>
<tr><th align="left">Riceball LEE</th><td><a href="https://github.com/snowyu">GitHub/snowyu</a></td><td></td></tr>
<tr><th align="left">Brian Woodward</th><td><a href="https://github.com/doowb">GitHub/doowb</a></td><td><a href="https://twitter.com/doowb">Twitter/@doowb</a></td></tr>
</tbody></table>

## LICENSE - "MIT License"
Expand Down
10 changes: 8 additions & 2 deletions lib/utilities.js
Expand Up @@ -138,15 +138,21 @@ function typesFromPattern(pattern) {
});
}

function applyUpperBoundChar(key) {
var parts = key.split('::');
var len = parts.length;
return len === 4 && parts[len-1] !== '' ? key : key + upperBoundChar;
}

function createQuery(pattern, options) {
var types = typesFromPattern(pattern)
, preferiteIndex = options && options.index
, index = findIndex(types, preferiteIndex)
, key = genKey(index, pattern, '')
, limit = pattern.limit
, reverse = pattern.reverse || false
, start = reverse ? key + upperBoundChar : key
, end = reverse ? key : key + upperBoundChar
, start = reverse ? applyUpperBoundChar(key) : key
, end = reverse ? key : applyUpperBoundChar(key)
, query = {
start: start
, end: end
Expand Down
145 changes: 145 additions & 0 deletions test/triple_store_spec.js
Expand Up @@ -301,6 +301,151 @@ describe('a basic triple store', function() {
});
});

describe('with two triple inserted with the same predicate and same object', function() {

var triple1
, triple2;

beforeEach(function(done) {
triple1 = { subject: 'a', predicate: 'b', object: 'c' };
triple2 = { subject: 'a2', predicate: 'b', object: 'c' };
db.put([triple1, triple2], done);
});

it('should get one by specifiying the subject', function(done) {
db.get({ subject: 'a' }, function(err, list) {
expect(list).to.eql([triple1]);
done();
});
});

it('should get one by specifiying the exact triple', function(done) {
db.get({ subject: 'a', predicate: 'b', object: 'c'}, function(err, list) {
expect(list).to.eql([triple1]);
done();
});
});

it('should get one by specifiying the subject and a falsy predicate', function(done) {
db.get({ subject: 'a', predicate: null }, function(err, list) {
expect(list).to.eql([triple1]);
done();
});
});

it('should get two by specifiying the predicate', function(done) {
db.get({ predicate: 'b' }, function(err, list) {
expect(list).to.eql([triple1, triple2]);
done();
});
});

it('should get two by specifiying the predicate and a falsy subject', function(done) {
db.get({ subject: null, predicate: 'b' }, function(err, list) {
expect(list).to.eql([triple1, triple2]);
done();
});
});

it('should remove one and still return the other', function(done) {
db.del(triple2, function() {
db.get({ predicate: 'b' }, function(err, list) {
expect(list).to.eql([triple1]);
done();
});
});
});

it('should return both triples through the getStream interface', function(done) {
var triples = [triple1, triple2]
, stream = db.getStream({ predicate: 'b' });
stream.on('data', function(data) {
expect(data).to.eql(triples.shift());
});

stream.on('end', done);
});

it('should return only one triple with limit 1', function(done) {
db.get({ predicate: 'b', limit: 1 }, function(err, list) {
expect(list).to.eql([triple1]);
done();
});
});

it('should return two triples with limit 2', function(done) {
db.get({ predicate: 'b', limit: 2 }, function(err, list) {
expect(list).to.eql([triple1, triple2]);
done();
});
});

it('should return three triples with limit 3', function(done) {
db.get({ predicate: 'b', limit: 3 }, function(err, list) {
expect(list).to.eql([triple1, triple2]);
done();
});
});

it('should support limit over streams', function(done) {
var triples = [triple1]
, stream = db.getStream({ predicate: 'b', limit: 1 });
stream.on('data', function(data) {
expect(data).to.eql(triples.shift());
});

stream.on('end', done);
});

it('should return only one triple with offset 1', function(done) {
db.get({ predicate: 'b', offset: 1 }, function(err, list) {
expect(list).to.eql([triple2]);
done();
});
});

it('should return only no triples with offset 2', function(done) {
db.get({ predicate: 'b', offset: 2 }, function(err, list) {
expect(list).to.eql([]);
done();
});
});

it('should support offset over streams', function(done) {
var triples = [triple2]
, stream = db.getStream({ predicate: 'b', offset: 1 });
stream.on('data', function(data) {
expect(data).to.eql(triples.shift());
});

stream.on('end', done);
});

it('should return the triples in reverse order with reverse true', function(done) {
db.get({ predicate: 'b', reverse: true }, function(err, list) {
expect(list).to.eql([triple2, triple1]);
done();
});
});

it('should return the last triple with reverse true and limit 1', function(done) {
db.get({ predicate: 'b', reverse: true, limit: 1 }, function(err, list) {
expect(list).to.eql([triple2]);
done();
});
});

it('should support reverse over streams', function(done) {
var triples = [triple2, triple1]
, stream = db.getStream({ predicate: 'b', reverse: true });
stream.on('data', function(data) {
expect(data).to.eql(triples.shift());
});

stream.on('end', done);
});
});

describe('with 10 triples inserted', function() {
beforeEach(function (done) {
var triples = [];
Expand Down

0 comments on commit 55beefc

Please sign in to comment.