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 = {};
// init memory plugin
externalContexts["_"] = require("./memory");
externalContexts["_"].init();
var memory = require("./memory");
externalContexts["_"] = memory();
globalContext = createContext("global",settings.functionGlobalContext || {});
}
@ -61,8 +61,7 @@ function load() {
} else {
plugin = plugins[pluginName].module;
}
plugin.init(config);
externalContexts[pluginName] = plugin;
externalContexts[pluginName] = plugin(config);
}else{
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 path = require("path");
var configs;
var storageBaseDir;
var storages;
function createStorage(scope) {
function createStorage(storageBaseDir, scope) {
var i = scope.indexOf(":")
if(i === -1){
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
storages[scope] = new JsonDB(path.join(storageBaseDir,scope,"flow"), true, true);
return new JsonDB(path.join(storageBaseDir,scope,"flow"), true, true);
}
}else{ // scope:local
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 = {
init: function(_configs) {
configs = _configs;
storages = {};
if (!configs.dir) {
if(configs.settings && configs.settings.userDir){
storageBaseDir = path.join(configs.settings.userDir,"contexts");
}else{
function getStoragePath(config) {
var base = config.base || "contexts";
var storageBaseDir;
if (!config.dir) {
if(config.settings && config.settings.userDir){
storageBaseDir = path.join(config.settings.userDir, base);
}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 {
fs.statSync(path.join(process.env.NODE_RED_HOME,".config.json"));
storageBaseDir = path.join(process.env.NODE_RED_HOME,"contexts");
// Consider compatibility for older versions
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) {
try {
// Consider compatibility for older versions
if (process.env.HOMEPATH) {
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");
}
}
if (!storageBaseDir) {
storageBaseDir = path.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH || process.env.NODE_RED_HOME,".node-red", base);
}
}
}else{
storageBaseDir = configs.dir;
}
},
get: function (scope, key) {
if(!storages[scope]){
createStorage(scope);
}
try{
storages[scope].reload();
return storages[scope].getData("/" + key.replace(/\./g,"/"));
}catch(err){
if(err.name === "DataError"){
return undefined;
}else{
throw err;
}
}
},
}else{
storageBaseDir = path.join(config.dir, base);
}
return storageBaseDir;
}
set: function (scope, key, value) {
if(!storages[scope]){
createStorage(scope);
}
if(value){
storages[scope].push("/" + key.replace(/\./g,"/"), value);
function LocalFileSystem(config){
this.config = config;
this.storageBaseDir = getStoragePath(this.config);
this.storages = {};
}
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{
storages[scope].delete("/" + key.replace(/\./g,"/"));
}
},
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];
throw err;
}
}
}
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 data;
function Memory(config){
this.data = {};
}
var memory = {
init: function(config) {
data = {};
},
get: function(scope, key) {
if(!data[scope]){
data[scope] = {};
}
return util.getMessageProperty(data[scope],key);
},
set: function(scope, key, value) {
if(!data[scope]){
data[scope] = {};
}
util.setMessageProperty(data[scope],key,value);
},
keys: function(scope){
if(!data[scope]){
data[scope] = {};
}
var keysData = Object.keys(data[scope]);
if (scope !== "global") {
return keysData;
} 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;
Memory.prototype.get = function(scope, key) {
if(!this.data[scope]){
return undefined;
}
return util.getMessageProperty(this.data[scope],key);
};
Memory.prototype.set =function(scope, key, value) {
if(!this.data[scope]){
this.data[scope] = {};
}
util.setMessageProperty(this.data[scope],key,value);
};
Memory.prototype.keys = function(scope){
if(!this.data[scope]){
return [];
}
if (scope !== "global") {
return Object.keys(this.data[scope]);
} else {
return Object.keys(this.data[scope]).filter(function (key) {
return key !== "set" && key !== "get" && key !== "keys";
});
}
};
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 contextStorage={
test:{
module: {
init: function() {
return true;
},
get: stubGet,
set: stubSet,
keys: stubKeys,
delete: stubDelete
module: function(config){
function Test(){}
Test.prototype.get = stubGet;
Test.prototype.set = stubSet;
Test.prototype.keys = stubKeys;
Test.prototype.delete = stubDelete;
return new Test(config);
},
config:{}
}
@ -228,14 +227,13 @@ describe('context', function() {
var contextDefaultStorage={
default: "test",
test:{
module: {
init: function() {
return true;
},
get: stubGet,
set: stubSet,
keys: stubKeys,
delete: stubDelete
module: function(config){
function Test(){}
Test.prototype.get = stubGet;
Test.prototype.set = stubSet;
Test.prototype.keys = stubKeys;
Test.prototype.delete = stubDelete;
return new Test(config);
},
config:{}
}

View File

@ -17,23 +17,21 @@
var should = require('should');
var fs = require('fs-extra');
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"));
describe('localfilesystem',function() {
var context;
beforeEach(function() {
context.init({dir: resourcesDir});
context = LocalFileSystem({dir: resourcesDir});
});
afterEach(function() {
context.delete("nodeX");
context.delete("nodeY");
});
after(function() {
fs.removeSync(resourcesDir);
afterEach(function(done) {
fs.remove(resourcesDir).then(function(result){
return done(result);
});
});
describe('#get/set',function() {

View File

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