diff --git a/js/common/tests/shell-aqlfunctions.js b/js/common/tests/shell-aqlfunctions.js index 707fe0b4a9..c6c818b9a0 100644 --- a/js/common/tests/shell-aqlfunctions.js +++ b/js/common/tests/shell-aqlfunctions.js @@ -60,6 +60,7 @@ function AqlFunctionsSuite () { //////////////////////////////////////////////////////////////////////////////// setUp : function () { + db._useDatabase("_system"); aqlfunctions.unregisterGroup("UnitTests::"); }, @@ -71,6 +72,102 @@ function AqlFunctionsSuite () { aqlfunctions.unregisterGroup("UnitTests::"); }, +//////////////////////////////////////////////////////////////////////////////// +/// @brief multiple databases +//////////////////////////////////////////////////////////////////////////////// + + testDatabases1 : function () { + aqlfunctions.register("UnitTests::tryme::foo", function (what) { return what * 2; }, true); + + try { + db._dropDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + + try { + db._createDatabase("UnitTestsAhuacatl"); + db._useDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + + var actual; + + aqlfunctions.register("UnitTests::tryme::foo", function (what) { return what * 4; }, true); + assertEqual("function (what) { return what * 4; }", aqlfunctions.toArray("UnitTests")[0].code); + + actual = db._createStatement({ query: "RETURN UnitTests::tryme::foo(4)" }).execute().toArray(); + assertEqual([ 16 ], actual); + + db._useDatabase("_system"); + assertEqual("function (what) { return what * 2; }", aqlfunctions.toArray("UnitTests")[0].code); + actual = db._createStatement({ query: "RETURN UnitTests::tryme::foo(4)" }).execute().toArray(); + assertEqual([ 8 ], actual); + + try { + db._useDatabase("_system"); + db._dropDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief multiple databases +//////////////////////////////////////////////////////////////////////////////// + + testDatabases2 : function () { + try { + unregister("UnitTests::tryme"); + } + catch (err) { + } + + try { + db._dropDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + + try { + db._createDatabase("UnitTestsAhuacatl"); + db._useDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + + var actual; + + aqlfunctions.register("UnitTests::tryme", function (what) { return what * 3; }, true); + assertEqual("function (what) { return what * 3; }", aqlfunctions.toArray("UnitTests")[0].code); + + actual = db._createStatement({ query: "RETURN UnitTests::tryme(3)" }).execute().toArray(); + assertEqual([ 9 ], actual); + + aqlfunctions.register("UnitTests::tryme", function (what) { return what * 4; }, true); + assertEqual("function (what) { return what * 4; }", aqlfunctions.toArray("UnitTests")[0].code); + actual = db._createStatement({ query: "RETURN UnitTests::tryme(3)" }).execute().toArray(); + assertEqual([ 12 ], actual); + + db._useDatabase("_system"); + assertEqual(0, aqlfunctions.toArray("UnitTests").length); + try { + db._createStatement({ query: "RETURN UnitTests::tryme(4)" }).execute().toArray(); + fail(); + } + catch (err) { + assertEqual(ERRORS.ERROR_QUERY_FUNCTION_NOT_FOUND.code, err.errorNum); + } + + try { + db._useDatabase("_system"); + db._dropDatabase("UnitTestsAhuacatl"); + } + catch (err) { + } + }, + //////////////////////////////////////////////////////////////////////////////// /// @brief toArray //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/modules/org/arangodb/ahuacatl.js b/js/server/modules/org/arangodb/ahuacatl.js index be450f4580..3192ea0130 100644 --- a/js/server/modules/org/arangodb/ahuacatl.js +++ b/js/server/modules/org/arangodb/ahuacatl.js @@ -78,6 +78,14 @@ var TYPEWEIGHT_DOCUMENT = 16; /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief return a database-specific function prefix +//////////////////////////////////////////////////////////////////////////////// + +function DB_PREFIX () { + return INTERNAL.db._name(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief normalise a function name //////////////////////////////////////////////////////////////////////////////// @@ -401,8 +409,13 @@ function FCALL (name, parameters) { function FCALL_USER (name, parameters) { "use strict"; - if (UserFunctions.hasOwnProperty(name)) { - var result = UserFunctions[name].func.apply(null, parameters); + var prefix = DB_PREFIX(); + if (! UserFunctions.hasOwnProperty(prefix)) { + THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, NORMALIZE_FNAME(name)); + } + + if (UserFunctions[prefix].hasOwnProperty(name)) { + var result = UserFunctions[prefix][name].func.apply(null, parameters); return FIX_VALUE(result); } @@ -3908,8 +3921,6 @@ function reloadUserFunctions () { var c; - UserFunctions = { }; - c = INTERNAL.db._collection("_aqlfunctions"); if (c === null) { @@ -3917,6 +3928,9 @@ function reloadUserFunctions () { } var foundError = false; + var prefix = DB_PREFIX(); + + UserFunctions[prefix] = { }; c.toArray().forEach(function (f) { var code = "(function() { var callback = " + f.code + "; return callback; })();"; @@ -3925,7 +3939,7 @@ function reloadUserFunctions () { try { var res = INTERNAL.executeScript(code, undefined, "(user function " + key + ")"); - UserFunctions[key.toUpperCase()] = { + UserFunctions[prefix][key.toUpperCase()] = { name: key, func: res, isDeterministic: f.isDeterministic || false