mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Allow multiple instances of a given storage module to exist
This commit is contained in:
		| @@ -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})); | ||||
|             } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
| }; | ||||
| @@ -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:{} | ||||
|                 } | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user