Skip to content

Commit

Permalink
Merge 57a2c8e into 6af24a3
Browse files Browse the repository at this point in the history
  • Loading branch information
mcollina committed Dec 8, 2013
2 parents 6af24a3 + 57a2c8e commit 5f339e9
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 86 deletions.
39 changes: 2 additions & 37 deletions lib/joinstream.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ var Transform = require('./streamwrapper').Transform
, utilities = require('./utilities')
, queryMask = utilities.queryMask
, variablesMask = utilities.variablesMask
, maskUpdater
, matcher;
, maskUpdater = utilities.maskUpdater
, matcher = utilities.matcher;

function JoinStream(options) {
if (!(this instanceof JoinStream)) {
Expand Down Expand Up @@ -59,38 +59,3 @@ JoinStream.prototype._transform = function(solution, encoding, done) {
};

module.exports = JoinStream;

matcher = function(pattern) {
var variables = variablesMask(pattern);
return function(solution, triple) {
var bindable = Object.keys(variables).every(function(key) {
var variable = variables[key];
return variable.isBindable(solution, triple[key]);
});

if (!bindable) {
return false;
}

return Object.keys(variables).reduce(function(newsolution, key) {
var variable = variables[key];
return variable.bind(newsolution, triple[key]);
}, solution);
};
};

maskUpdater = function(pattern) {
var variables = variablesMask(pattern);
return function(solution, mask) {
return Object.keys(variables).reduce(function(newMask, key) {
var variable = variables[key];
if (variable.isBound(solution)) {
newMask[key] = solution[variable.name];
}
return newMask;
}, Object.keys(mask).reduce(function(acc, key) {
acc[key] = mask[key];
return acc;
}, {}));
};
};
8 changes: 6 additions & 2 deletions lib/keyfilterstream.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ function KeyFilterStream(options) {
that.source = source;
});

this.filter = options.filter;

this._destroyed = false;
}

Expand All @@ -28,10 +30,12 @@ KeyFilterStream.prototype = Object.create(

KeyFilterStream.prototype._transform = function(data, encoding, done) {

data.value = JSON.parse(data.value);

if (this._destroyed || data.key.indexOf(this.start) < 0) {
this.source.destroy();
} else {
this.push(JSON.parse(data.value));
} else if (!this.filter || this.filter(data.value)) {
this.push(data.value);
}

done();
Expand Down
52 changes: 9 additions & 43 deletions lib/sortjoinstream.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@

var Transform = require('./streamwrapper').Transform
, Variable = require('./variable')
, queryMask = require('./utilities').queryMask
, variablesMask = require('./utilities').variablesMask
, maskUpdater
, matcher
, materializer = require('./utilities').materializer
, createQuery = require('./utilities').createQuery
, genKey = require('./utilities').genKey
, genKeys = require('./utilities').genKeys;
, utilities = require('./utilities')
, queryMask = utilities.queryMask
, variablesMask = utilities.variablesMask
, matcher = utilities.matcher
, materializer = utilities.materializer
, createQuery = utilities.createQuery
, genKey = utilities.genKey
, genKeys = utilities.genKeys;

var counter = 0;

Expand All @@ -33,6 +33,7 @@ function SortJoinStream(options) {
});

this._queryMask = queryMask(options.triple);
this._queryMask.filter = options.triple.filter;

this.index = options.index;

Expand Down Expand Up @@ -159,38 +160,3 @@ SortJoinStream.prototype._transform = function(solution, encoding, done) {
};

module.exports = SortJoinStream;

matcher = function(pattern) {
var variables = variablesMask(pattern);
return function(solution, triple) {
var bindable = Object.keys(variables).every(function(key) {
var variable = variables[key];
return variable.isBindable(solution, triple[key]);
});

if (!bindable) {
return false;
}

return Object.keys(variables).reduce(function(newsolution, key) {
var variable = variables[key];
return variable.bind(newsolution, triple[key]);
}, solution);
};
};

maskUpdater = function(pattern) {
var variables = variablesMask(pattern);
return function(solution, mask) {
return Object.keys(variables).reduce(function(newMask, key) {
var variable = variables[key];
if (variable.isBound(solution)) {
newMask[key] = solution[variable.name];
}
return newMask;
}, Object.keys(mask).reduce(function(acc, key) {
acc[key] = mask[key];
return acc;
}, {}));
};
};
64 changes: 60 additions & 4 deletions lib/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,29 @@ function findIndex(types, preferiteIndex) {

module.exports.findIndex = findIndex;

function typesFromPattern(pattern) {
return Object.keys(pattern).filter(function(key) {
switch(key) {
case 'subject':
case 'predicate':
case 'object':
return true;
default:
return false;
}
});
}

function createQuery(pattern, options) {
var types = Object.keys(pattern)
var types = typesFromPattern(pattern)
, preferiteIndex = (options || {}).index
, index = findIndex(types, preferiteIndex)
, key = genKey(index, pattern)
, query = {
start: key,
end: key + '\xff',
fillCache: true
start: key
, end: key + '\xff'
, fillCache: true
, filter: pattern.filter
};

return query;
Expand Down Expand Up @@ -180,3 +194,45 @@ module.exports.materializer = materializer;
return objectMask(c, object);
};
})();

var variablesMask = module.exports.variablesMask;

function maskUpdater(pattern) {
var variables = variablesMask(pattern);
return function(solution, mask) {
return Object.keys(variables).reduce(function(newMask, key) {
var variable = variables[key];
if (variable.isBound(solution)) {
newMask[key] = solution[variable.name];
}
newMask.filter = pattern.filter;
return newMask;
}, Object.keys(mask).reduce(function(acc, key) {
acc[key] = mask[key];
return acc;
}, {}));
};
}

module.exports.maskUpdater = maskUpdater;

function matcher(pattern) {
var variables = variablesMask(pattern);
return function(solution, triple) {
var bindable = Object.keys(variables).every(function(key) {
var variable = variables[key];
return variable.isBindable(solution, triple[key]);
});

if (!bindable) {
return false;
}

return Object.keys(variables).reduce(function(newsolution, key) {
var variable = variables[key];
return variable.bind(newsolution, triple[key]);
}, solution);
};
}

module.exports.matcher = matcher;
33 changes: 33 additions & 0 deletions test/abstract_join_algorithm.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,4 +240,37 @@ module.exports = function(joinAlgorithm) {
done();
});
});

it('should support filtering inside a condition', function(done) {
db.search([{
subject: db.v('x'),
predicate: 'friend',
object: 'daniele',
filter: function(triple) { return triple.subject !== 'matteo'; }
}], function(err, results) {
expect(results).to.have.length(0);
done();
});
});

it('should support filtering inside a second-level condition', function(done) {
db.search([{
subject: 'matteo',
predicate: 'friend',
object: db.v('y'),
}, {
subject: db.v('y'),
predicate: 'friend',
object: db.v('x'),
filter: function(triple) {
return triple.object !== 'matteo';
}
}], function(err, results) {
expect(results).to.eql([{
'y': 'daniele',
'x': 'marco'
}]);
done();
});
});
};
16 changes: 16 additions & 0 deletions test/triple_store_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,20 @@ describe('a basic triple store', function() {
it('should alias search to join', function() {
expect(db.join).to.eql(db.search);
});

it('should support filtering', function(done) {
var triple1 = { subject: 'a', predicate: 'b', object: 'd' }
, triple2 = { subject: 'a', predicate: 'b', object: 'c' };

db.put([triple1, triple2], function() {
function filter(triple) {
return triple.object === 'd';
}

db.get({ subject: 'a', predicate: 'b', filter: filter }, function(err, results) {
expect(results).to.eql([triple1]);
done();
});
});
});
});

0 comments on commit 5f339e9

Please sign in to comment.