UNPKG

ndn-js-contrib

Version:

Reusable 'Classes' for Named Data Networking: NameTree, PIT, FIB, ContentStore, Interfaces, and Transports

144 lines (143 loc) 5.24 kB
var leveldown = require("leveldown"), levelup = require("levelup"), Name = require("ndn-js/js/name.js").Name, crypto = require("ndn-js/js/crypto.js"), Data = require("ndn-js/js/data.js").Data, NameTree = require("./NameTree.js"), ContentStore = require("./ContentStore.js"); function Repository(path) { var self = this; this._dataPath = path; this._contentStore = new ContentStore(); this._contentStore.setEntryClass(Repository.Entry); return new Promise(function Repository_Constructor_Promise(resolve, reject) { levelup(self._dataPath, { db: leveldown, valueEncoding: "json" }, function Repository_Contstructor_Promise_levelup(err, db) { if (err) return reject(err); self._dataDB = db; self.populateContentStoreNodes().then(function() { resolve(self); }).catch(reject); }); }); } Repository.Open = function Repository_Open(path) { return new Repository(path); }; Repository.Entry = function Repository_Entry(data, repository) { var self = this; this._repository = repository; this.prefix = data.name; return this; }; function Repository_getNameWithDigest(name, packet) { var name = new Name(name); name.append("sha256digest=" + crypto.createHash('sha256').update(packet).digest().toString('hex')); return name; } Repository.Entry.prototype.getData = function Repository_Entry_getData() { var self = this; return new Promise(function Repository_Entry_getData_Promise(resolve, reject) { self._repository._dataDB.get(self.prefix.toUri(), function(err, packet) { if (err) return reject(err); var data = new Data(); data.wireDecode(new Buffer(packet)); resolve(data); }); }); }; Repository.Entry.prototype.delete = function Repository_Entry_delete() { var self = this; return new Promise(function Repository_Entry_delete_Promise(resolve, reject) { self._repository._dataDB.del(self.prefix.toUri(), function(err) { if (err) return reject(err); resolve(self); }); }); }; Repository.Entry.prototype.fulfillsInterest = function Repository_Entry_fulfillsInterest(interest) { return (!!this.prefix && interest.matchesName(this.prefix)); }; Repository.prototype.createNode = function Repository_createNode(data, repository) { var self = this; return new Promise(function Repository_createNode_Promise(resolve, reject) { var entry = new Repository.Entry(data, repository); entry._repository = self; if (!data.content) { if (data.name.get(-1).toEscapedString().substr(0, 12) !== "sha256digest") reject(new Error("new Repository.Entry(data, contentStore) : no content to digest or digest component on name" + data.name.toUri())); resolve(new NameTree.Node(data.name, entry)); } else { var packet = data.wireEncode().buffer, nameWithDigest = Repository_getNameWithDigest(data.name, packet); entry._repository._dataDB.put(nameWithDigest.toUri(), data.wireEncode().buffer, function(err) { if (err) reject(err); else { entry.prefix = nameWithDigest; resolve(new NameTree.Node(entry.prefix, entry)); } }); } }); }; Repository.prototype.insert = function Repository_insert(data) { return this._contentStore.insert(data, this); }; Repository.prototype.remove = function Repository_remove(entry) { var self = this; return new Promise(function Repository_remove_Promise(resolve, reject) { self._contentStore.nameTree.remove(entry.prefix); entry.delete().then(resolve).catch(reject); }); }; Repository.prototype.lookup = function Repository_lookup(interest) { return this._contentStore.lookup(interest); }; Repository.prototype.populateContentStoreNodes = function Repository_populateContentStoreNodes() { var self = this; return new Promise(function Repository_populateContentStoreNodes_Promise(resolve, reject) { var proms = []; self._dataDB.createKeyStream().on("data", function(key) { proms.push(self.createNode({name: new Name(key)}, self).then(function(node) { return self._contentStore._nameTree.insert(node); })); }).on("error", function(err) { reject(err); }).on("close", function() {}).on("end", function() { Promise.all(proms).then(resolve).catch(function(err) { self.close().then(function() { reject(err); }); }); }); }); }; Repository.prototype.close = function Repository_close() { var self = this; return new Promise(function Repository_close_Promise(resolve, reject) { self._dataDB.close(function Repository_close_Promise_level(err) { if (err) return reject(err); resolve(self); }); }); }; Repository.prototype.destroy = function Repository_destroy() { var self = this; return new Promise(function Repository_destroy_Promise(resolve, reject) { if (self._dataDB.isOpen()) return reject(new Error("Repository.destroy(): Repository must call Repository.close() prior to destruction")); leveldown.destroy(self._dataPath, function Repository_destroy_level(err) { if (!err) return resolve(); reject(err); }); }); }; module.exports = Repository;