Allow multiple instances of a given storage module to exist

This commit is contained in:
HirokiUchikawa 2018-05-24 21:42:40 +09:00
parent 7fafa21a1b
commit 28d05e2449
6 changed files with 157 additions and 144 deletions

View File

@ -29,8 +29,8 @@ function init(_settings) {
externalContexts = {}; externalContexts = {};
// init memory plugin // init memory plugin
externalContexts["_"] = require("./memory"); var memory = require("./memory");
externalContexts["_"].init(); externalContexts["_"] = memory();
globalContext = createContext("global",settings.functionGlobalContext || {}); globalContext = createContext("global",settings.functionGlobalContext || {});
} }
@ -61,8 +61,7 @@ function load() {
} else { } else {
plugin = plugins[pluginName].module; plugin = plugins[pluginName].module;
} }
plugin.init(config); externalContexts[pluginName] = plugin(config);
externalContexts[pluginName] = plugin;
}else{ }else{
throw new Error(log._("context.error-module-not-defined", {storage:pluginName})); throw new Error(log._("context.error-module-not-defined", {storage:pluginName}));
} }

View File

@ -18,102 +18,109 @@ var JsonDB = require('node-json-db');
var fs = require('fs-extra'); var fs = require('fs-extra');
var path = require("path"); var path = require("path");
var configs; function createStorage(storageBaseDir, scope) {
var storageBaseDir;
var storages;
function createStorage(scope) {
var i = scope.indexOf(":") var i = scope.indexOf(":")
if(i === -1){ if(i === -1){
if(scope === "global"){ if(scope === "global"){
storages[scope] = new JsonDB(path.join(storageBaseDir,"global",scope), true, true); return new JsonDB(path.join(storageBaseDir,"global",scope), true, true);
}else{ // scope:flow }else{ // scope:flow
storages[scope] = new JsonDB(path.join(storageBaseDir,scope,"flow"), true, true); return new JsonDB(path.join(storageBaseDir,scope,"flow"), true, true);
} }
}else{ // scope:local }else{ // scope:local
var ids = scope.split(":") var ids = scope.split(":")
storages[scope] = new JsonDB(path.join(storageBaseDir,ids[1],ids[0]), true, true); return new JsonDB(path.join(storageBaseDir,ids[1],ids[0]), true, true);
} }
} }
var localfilesystem = { function getStoragePath(config) {
init: function(_configs) { var base = config.base || "contexts";
configs = _configs; var storageBaseDir;
storages = {}; if (!config.dir) {
if (!configs.dir) { if(config.settings && config.settings.userDir){
if(configs.settings && configs.settings.userDir){ storageBaseDir = path.join(config.settings.userDir, base);
storageBaseDir = path.join(configs.settings.userDir,"contexts"); }else{
}else{ try {
fs.statSync(path.join(process.env.NODE_RED_HOME,".config.json"));
storageBaseDir = path.join(process.env.NODE_RED_HOME, base);
} catch(err) {
try { try {
fs.statSync(path.join(process.env.NODE_RED_HOME,".config.json")); // Consider compatibility for older versions
storageBaseDir = path.join(process.env.NODE_RED_HOME,"contexts"); if (process.env.HOMEPATH) {
fs.statSync(path.join(process.env.HOMEPATH,".node-red",".config.json"));
storageBaseDir = path.join(process.env.HOMEPATH, ".node-red", base);
}
} catch(err) { } catch(err) {
try { }
// Consider compatibility for older versions if (!storageBaseDir) {
if (process.env.HOMEPATH) { storageBaseDir = path.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH || process.env.NODE_RED_HOME,".node-red", base);
fs.statSync(path.join(process.env.HOMEPATH,".node-red",".config.json"));
storageBaseDir = path.join(process.env.HOMEPATH,".node-red","contexts");
}
} catch(err) {
}
if (!storageBaseDir) {
storageBaseDir = path.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH || process.env.NODE_RED_HOME,".node-red","contexts");
}
} }
} }
}else{
storageBaseDir = configs.dir;
} }
}, }else{
get: function (scope, key) { storageBaseDir = path.join(config.dir, base);
if(!storages[scope]){ }
createStorage(scope); return storageBaseDir;
} }
try{
storages[scope].reload();
return storages[scope].getData("/" + key.replace(/\./g,"/"));
}catch(err){
if(err.name === "DataError"){
return undefined;
}else{
throw err;
}
}
},
set: function (scope, key, value) { function LocalFileSystem(config){
if(!storages[scope]){ this.config = config;
createStorage(scope); this.storageBaseDir = getStoragePath(this.config);
} this.storages = {};
if(value){ }
storages[scope].push("/" + key.replace(/\./g,"/"), value);
LocalFileSystem.prototype.get = function (scope, key) {
if(!this.storages[scope]){
return undefined;
}
try{
this.storages[scope].reload();
return this.storages[scope].getData("/" + key.replace(/\./g,"/"));
}catch(err){
if(err.name === "DataError"){
return undefined;
}else{ }else{
storages[scope].delete("/" + key.replace(/\./g,"/")); throw err;
}
},
keys: function (scope) {
if(!storages[scope]){
return [];
}
return Object.keys(storages[scope].getData("/"));
},
delete: function(scope){
if(storages[scope]){
storages[scope].delete("/");
if(scope.indexOf(":") === -1){
fs.removeSync(path.dirname(storages[scope].filename));
}else{
try{
fs.statSync(storages[scope].filename);
fs.unlinkSync(storages[scope].filename);
}catch(err){
console.log("deleted");
}
}
delete storages[scope];
} }
} }
}
LocalFileSystem.prototype.set = function(scope, key, value) {
if(!this.storages[scope]){
this.storages[scope] = createStorage(this.storageBaseDir ,scope);
}
if(value){
this.storages[scope].push("/" + key.replace(/\./g,"/"), value);
}else{
this.storages[scope].delete("/" + key.replace(/\./g,"/"));
}
}
LocalFileSystem.prototype.keys = function(scope) {
if(!this.storages[scope]){
return [];
}
return Object.keys(this.storages[scope].getData("/"));
}
LocalFileSystem.prototype.delete = function(scope){
if(this.storages[scope]){
this.storages[scope].delete("/");
if(scope.indexOf(":") === -1){
fs.removeSync(path.dirname(this.storages[scope].filename));
}else{
try{
fs.statSync(this.storages[scope].filename);
fs.unlinkSync(this.storages[scope].filename);
}catch(err){
console.log("deleted");
}
}
delete this.storages[scope];
}
}
module.exports = function(config){
return new LocalFileSystem(config);
}; };
module.exports = localfilesystem;

View File

@ -16,43 +16,53 @@
var util = require("../../util"); var util = require("../../util");
var data; function Memory(config){
this.data = {};
}
var memory = { Memory.prototype.get = function(scope, key) {
init: function(config) { if(!this.data[scope]){
data = {}; return undefined;
}, }
get: function(scope, key) { return util.getMessageProperty(this.data[scope],key);
if(!data[scope]){ };
data[scope] = {};
} Memory.prototype.set =function(scope, key, value) {
return util.getMessageProperty(data[scope],key); if(!this.data[scope]){
}, this.data[scope] = {};
set: function(scope, key, value) { }
if(!data[scope]){ util.setMessageProperty(this.data[scope],key,value);
data[scope] = {}; };
}
util.setMessageProperty(data[scope],key,value); Memory.prototype.keys = function(scope){
}, if(!this.data[scope]){
keys: function(scope){ return [];
if(!data[scope]){ }
data[scope] = {}; if (scope !== "global") {
} return Object.keys(this.data[scope]);
var keysData = Object.keys(data[scope]); } else {
if (scope !== "global") { return Object.keys(this.data[scope]).filter(function (key) {
return keysData; return key !== "set" && key !== "get" && key !== "keys";
} else { });
return keysData.filter(function (key) {
return key !== "set" && key !== "get" && key !== "keys";
});
}
},
delete: function(scope){
delete data[scope];
},
setGlobalContext: function(seed){
data["global"] = seed;
} }
}; };
module.exports = memory; Memory.prototype.delete = function(scope){
delete this.data[scope];
};
Memory.prototype.open = function(){
return true;
};
Memory.prototype.close = function(){
delete this.data;
};
Memory.prototype.setGlobalContext= function(seed){
this.data["global"] = seed;
};
module.exports = function(config){
return new Memory(config);
};

View File

@ -151,14 +151,13 @@ describe('context', function() {
var stubDelete = sinon.stub(); var stubDelete = sinon.stub();
var contextStorage={ var contextStorage={
test:{ test:{
module: { module: function(config){
init: function() { function Test(){}
return true; Test.prototype.get = stubGet;
}, Test.prototype.set = stubSet;
get: stubGet, Test.prototype.keys = stubKeys;
set: stubSet, Test.prototype.delete = stubDelete;
keys: stubKeys, return new Test(config);
delete: stubDelete
}, },
config:{} config:{}
} }
@ -228,14 +227,13 @@ describe('context', function() {
var contextDefaultStorage={ var contextDefaultStorage={
default: "test", default: "test",
test:{ test:{
module: { module: function(config){
init: function() { function Test(){}
return true; Test.prototype.get = stubGet;
}, Test.prototype.set = stubSet;
get: stubGet, Test.prototype.keys = stubKeys;
set: stubSet, Test.prototype.delete = stubDelete;
keys: stubKeys, return new Test(config);
delete: stubDelete
}, },
config:{} config:{}
} }

View File

@ -17,23 +17,21 @@
var should = require('should'); var should = require('should');
var fs = require('fs-extra'); var fs = require('fs-extra');
var path = require("path"); var path = require("path");
var context = require('../../../../../red/runtime/nodes/context/localfilesystem'); var LocalFileSystem = require('../../../../../red/runtime/nodes/context/localfilesystem');
var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context")); var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context"));
describe('localfilesystem',function() { describe('localfilesystem',function() {
var context;
beforeEach(function() { beforeEach(function() {
context.init({dir: resourcesDir}); context = LocalFileSystem({dir: resourcesDir});
}); });
afterEach(function() { afterEach(function(done) {
context.delete("nodeX"); fs.remove(resourcesDir).then(function(result){
context.delete("nodeY"); return done(result);
}); });
after(function() {
fs.removeSync(resourcesDir);
}); });
describe('#get/set',function() { describe('#get/set',function() {

View File

@ -15,12 +15,13 @@
**/ **/
var should = require('should'); var should = require('should');
var context = require('../../../../../red/runtime/nodes/context/memory'); var Memory = require('../../../../../red/runtime/nodes/context/memory');
describe('memory',function() { describe('memory',function() {
var context;
beforeEach(function() { beforeEach(function() {
context.init({}); context = Memory({});
}); });
describe('#get/set',function() { describe('#get/set',function() {