Skip to content

Instantly share code, notes, and snippets.

@m1sta
Created May 24, 2014 23:35
Show Gist options
  • Save m1sta/f0bf0dfff3b34722ba4d to your computer and use it in GitHub Desktop.
Save m1sta/f0bf0dfff3b34722ba4d to your computer and use it in GitHub Desktop.
function example(){
var plv8 = require('./plv8')
var options = {
user: 'postgres',
password: 'password',
database: 'data',
host: '127.0.0.1',
port: 9999
};
plv8.connect(options, function(err, plv8){
plv8.configure(function(err, result){
plv8.set("first", {a:2}, function(){
plv8.get("first", function(err, result){
console.log("get result:", result);
})
});
var queryFunction1 = function (input){
return {happy:"day", text:input.a};
};
var queryFunction2 = function (input){
plv8.setSync("second", {hello:"world"});
return plv8.getSync("second");
};
var displayResult = function(err, result){
if(err) console.dir(err)
console.log("call result:", JSON.stringify(result));
};
plv8.define(queryFunction1, function(){
plv8.call(queryFunction1, {a:12345}, displayResult);
});
plv8.define(queryFunction2, function(){
plv8.call(queryFunction2, null, displayResult);
});
});
})
}
example();
var plv8 = module.exports = {
connect : function (options, connectionCallback){
var pg = require('pg');
pg.connect(new pg.Client(options), function(err, client, done) {
var plv8Connection = {
client:client,
prefix:options.prefix || "plv8_",
dataName:options.dataName || "jsonData",
generatedNames:[[],[]],
configure: function(callback){
//todo: consider enabling coffeescript support with CREATE EXTENSION plcoffee;?
var queryString = "CREATE EXTENSION plv8; CREATE TABLE IF NOT EXISTS " + plv8Connection.dataName + " ( id text UNIQUE, data json );"
var result = plv8Connection.client.query(queryString, [], function (err, result){
done();
callback(err, result);
})
},
get: function(key, callback){
var queryString = "select * from " + plv8Connection.dataName + " where id = '" + key.toString() + "'";
var result = plv8Connection.client.query(queryString, [], function (err, result){
done();
var deepResult = err ? undefined : result.rows.length > 0 && result.rows[0].data;
callback(err, deepResult);
})
},
set: function(key, value, callback){
var valueJson = JSON.stringify(value)
var queryString = "UPDATE " + plv8Connection.dataName + " SET data='" + valueJson + "' WHERE id='" + key + "'; \n"
+ "insert into " + plv8Connection.dataName + " (id, data) select '" + key + "', '" + valueJson + "'\n"
+ "WHERE NOT EXISTS (SELECT 1 FROM " + plv8Connection.dataName + " WHERE id='" + key + "');"
var result = plv8Connection.client.query(queryString, [], function (err, result){
done();
callback(err, result);
})
},
define: function(queryFn, callback){
var fnString = queryFn.toString();
var fnBody = fnString.substring(fnString.indexOf("{") + 1, fnString.lastIndexOf("}"));
var fnName = plv8Connection.prefix;
if(queryFn.name.length > 0) fnName += queryFn.name;
else {
plv8Connection.generatedNames[0].push(queryFn);
plv8Connection.generatedNames[1].push(fnName += "Generated_" + Math.random().toString().replace(/\./,""));
}
var isv = "STABLE"; //todo: calculate based on function contents or have it passed via args
var helperFn = function(){
var plv8Connection = {dataName: "jsonData"};
var console = {log: function(message){plv8.elog(INFO, '', JSON.stringify(arguments))}};
plv8.getSync = function(key){return plv8.execute("select * from " + plv8Connection.dataName + " where id='" + key + "'")};
plv8.setSync = function(key, value){
var valueJson = JSON.stringify(value)
var queryString = "UPDATE " + plv8Connection.dataName + " SET data='" + valueJson + "' WHERE id='" + key + "'; \n"
+ "insert into " + plv8Connection.dataName + " (id, data) select '" + key + "', '" + valueJson + "'\n"
+ "WHERE NOT EXISTS (SELECT 1 FROM " + plv8Connection.dataName + " WHERE id='" + key + "');"
return plv8.execute(queryString);
}
plv8.get = function(key, callback){var result = plv8.getSync(key); callback && callback(undefined, result); return result;}
plv8.set = function(key, value, callback){var result = plv8.setSync(key, value); callback && callback(undefined, result); return result;}
plv8.query = function(query, args, callback){var result = plv8.execute(query, args); callback && callback(undefined, result); return result;}
}
var helperFnString = helperFn.toString();
var helperFnBody = helperFnString.substring(helperFnString.indexOf("{") + 1, helperFnString.lastIndexOf("}"));
var queryString = " create or replace function " + fnName + " (input json )"
+ " RETURNS json LANGUAGE plv8 " + isv
+ " AS $javascript$\n" + helperFnBody + ";\n" + fnBody + "\n$javascript$";
var result = plv8Connection.client.query(queryString, [], function (err, result){
done();
callback(err, result);
})
},
call: function(queryFn, input, callback){
if(!input) input = null;
var fnName = "";
if(queryFn.name.length > 0) fnName = plv8Connection.prefix + queryFn.name;
else {
var index = plv8Connection.generatedNames[0].indexOf(queryFn);
fnName += plv8Connection.generatedNames[1][index];
}
var queryString = "select " + fnName + "('" + JSON.stringify(input) + "')";
var result = plv8Connection.client.query(queryString, [], function (err, result){
done();
var deepResult = err ? undefined : result.rows.length > 0 && result.rows[0][Object.keys(result.rows[0])[0]];
callback(err, deepResult);
})
},
query: function(query, args, callback){
return plv8Connection.client.query(query, args, callback)
}
}
connectionCallback(err, plv8Connection)
});
//todo: provide a sql injection attack protection layer and improved error handling for when the module is used by novices
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment