Reputation: 1750
(please throw any concern for security or anything out the window, as its a internal application)
basically What i want to do is store a javascript function in a db:
function x(name) {
return name + 1;
}
and then at a later time fetch the DB row
(pseudo code here)
x = db.get('function').where('id').equals(1);
console.log(x('bob'));
//should print "bob +1 "
so here is the scenario i am envisioning:
basically, i am getting a JSON object, and depending on certain criteria, i want to do some transformation to that json, and output the new transformed json. for the sake of the "main" app, i dont want to hard code the transformation logic, instead it will be dynamic (dynamic in the sense that a different developer will provide it at run time)
so a DB might contain:
ID | javascript
====================
1 | (some js code)
2 | (same func, different code)
what i want to do is execute that JS code stored in the DB, with an input of my choosing.
if it makes it easier, the function name will be standard.. i.e we can assume that the javascript saved in the DB will all follow:
function transform(input) {
/* below this line logic will change
* end diff logic/
return output
}
Upvotes: 3
Views: 9509
Reputation: 346
eval()
not so good decision to make persistence for active objects:
for example, let's look at a simple frame object:
o = {
type:'obj',
value:'o',
dump: function() { return "<"+this.type+":"+this.value+">" }
}
> {type: "obj", value: "o", dump: ƒ}
And now we want to do eval()
uable representation:
o.toString()
"[object Object]"
JSON.stringify(o)
"{"type":"obj","value":"o"}"
Very informative!
Upvotes: 0
Reputation: 4659
Matthias Brantner with Oracle Labs recently demonstrated an experimental feature, Multilingual Engine (MLE), that allows JavaScript to be executed in Oracle Database:
https://www.youtube.com/playlist?list=PL_lVOJzXeE_8UwipLqfu6vKnOYDF3ITaI
The demos there include:
Visit this page to get more info, download a VM that includes a DB + MLE, and provide feedback via the MLE Community: http://www.oracle.com/technetwork/database/multilingual-engine/overview/index.html
Upvotes: 2
Reputation: 150040
You can execute any arbitrary string of JS using the eval()
function, which will return the result of whatever was evaluated.
So for your purposes, where you want to assign a variable to hold the (eval'ed) function that was in a string, you can do this:
// retrieve string from DB somehow
var functionString = "(function whatever(name) { return name + 1; })";
var x = eval(functionString);
console.log(x("bob")); // logs "bob1"
Note that I've wrapped the function in the string in parentheses, because that makes it a function expression which can then be assigned to the variable x
.
I dont want to hard code the transformation logic, instead it will be dynamic (dynamic in the sense that a different developer will provide it at run time)
Another approach, in my opinion a better approach, is to put all of your transformation functions into a separate JavaScript module that you then require()
as per the standard Node.js module loading system. That way the transformation logic is kept separate in another file that can be maintained separately by a different developer as needed, without mucking around with DB operations and eval()
:
// transforms.js
module.exports = {
"1" : function plus1(name) { return name + 1; },
"2" : function square(x) { return x * x; },
"3" : function half(x) { return x / 2; }
// etc.
};
// in main JS file
var transforms = require("./transforms.js");
var a = transforms["2"];
var b = transforms["3"];
console.log(a(b(20))); // 100
console.log(transforms["1"]("bob")); // "bob1"
As you can see above, each of the "dynamic" transformation functions has been defined as a property of the object where the property names are the keys that you were going to use in your database.
StackOverflow code snippets don't seem to handle modules, but if you expand the following snippet you can see an equivalent of the above code working:
// in "transform.js"
var transforms = {
"1" : function plus1(name) { return name + 1; },
"2" : function square(x) { return x * x; },
"3" : function half(x) { return x / 2; }
// etc.
};
// in main JS file
var a = transforms ["2"];
var b = transforms ["3"];
console.log(a(b(20))); // 100
console.log(transforms ["1"]("bob")); // "bob1"
Upvotes: 11
Reputation: 8139
You can do that in JavaScript. Here is an example.
var f = "function(x) {return x * 2}"
var x = 4;
eval("("+f+")("+x+")");
But this is very unsafe since you have no way to ensure that the function you are executing doesn't contain dangerous code. Instead you could use an interpreter. Either use an existing one like this https://github.com/NeilFraser/JS-Interpreter
Or write your own. It doesn't have to be JS. If the language is very simple you can write an interpreter for it in an afternoon.
Upvotes: 3
Reputation: 6720
You can use eval
to execute a String of JS. I don't know what you're doing nor what this is for, but this is highly discouraged.
Try running this in your web console:
eval('alert(\'hello\')')
Upvotes: 3