(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
}
(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
}
Share
Improve this question
asked Jul 24, 2016 at 1:54
NateNate
1,7504 gold badges25 silver badges41 bronze badges
7
- Should be doable, but you will need to use code evaluation of some kind. – Alexander O'Mara Commented Jul 24, 2016 at 1:58
- Is that DB part of your JS program? – Oriol Commented Jul 24, 2016 at 1:59
-
Javascript is just text and you can certainly store text in a database. You can use
eval()
at any time to execute some Javascript text (with the associated risks of doing so). – jfriend00 Commented Jul 24, 2016 at 2:10 - I must add that usually one does not store and execute actual code this way, but rather some sort of meta data which a particular piece of code can then process to carry out the desired operations. This also allows you to control what the stored data is allowed to do, whereas that is much harder if you store actual Javascript. – jfriend00 Commented Jul 24, 2016 at 2:21
-
1
Just curious, why not have the web service method return the javascript code as
application/javascript
mime type and regular text? That way you could just link to it without eval. – Zachary Scott Commented Jul 24, 2016 at 2:58
5 Answers
Reset to default 11You 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"
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\')')
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./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.
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./playlist?list=PL_lVOJzXeE_8UwipLqfu6vKnOYDF3ITaI
The demos there include:
- JavaScript Module as UDF in SQL
- SQL Driver for JavaScript in Oracle Database
- Sequelize ORM in Oracle Database
- JavaScript Based Aggregate Function in SQL
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./technetwork/database/multilingual-engine/overview/index.html
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!