Merge pull request #17 from krisdaniels/master

Added Postgres Node
This commit is contained in:
Nick O'Leary 2014-02-08 14:48:44 +00:00
commit e5af41ba2b
3 changed files with 269 additions and 0 deletions

View File

@ -0,0 +1,146 @@
<!--
Copyright 2013 Kris Daniels.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="postgresdb">
<div class="form-row">
<label for="node-config-input-hostname"><i class="icon-bookmark"></i> Host</label>
<input class="input-append-left" type="text" id="node-config-input-hostname" placeholder="localhost" style="width: 40%;" >
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
<input type="text" id="node-config-input-port" placeholder="5432" style="width:45px">
</div>
<div class="form-row">
<label for="node-config-input-db"><i class="icon-briefcase"></i> Database</label>
<input type="text" id="node-config-input-db" placeholder="test">
</div>
<div class="form-row">
<label for="node-config-input-name"><i class="icon-user"></i> Username</label>
<input type="text" id="node-config-input-user" placeholder="postgres">
<label for="node-config-input-password"><i class="icon-lock"></i> Password</label>
<input type="password" id="node-config-input-password" placeholder="postgres">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('postgresdb',{
category: 'config',
color:"rgb(218, 196, 180)",
defaults: {
hostname: { value:"localhost",required:true},
port: { value: 5432,required:true},
db: { value:"postgres",required:true}
},
label: function() {
return this.name||this.hostname+":"+this.port+"/"+this.db;
},
oneditprepare: function() {
$.getJSON('postgresdb/'+this.id,function(data) {
if (data.user) {
$('#node-config-input-user').val(data.user);
}
if (data.hasPassword) {
$('#node-config-input-password').val('__PWRD__');
} else {
$('#node-config-input-password').val('');
}
});
},
oneditsave: function() {
var newUser = $('#node-config-input-user').val();
var newPass = $('#node-config-input-password').val();
var credentials = {};
credentials.user = newUser;
if (newPass != '__PWRD__') {
credentials.password = newPass;
}
$.ajax({
url: 'postgresdb/'+this.id,
type: 'POST',
data: credentials,
success:function(result){}
});
},
ondelete: function() {
$.ajax({
url: 'postgresdb/'+this.id,
type: 'DELETE',
success: function(result) {}
});
}
});
</script>
<script type="text/x-red" data-template-name="postgres">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-postgresdb"><i class="icon-tag"></i> Server</label>
<input type="text" id="node-input-postgresdb">
</div>
<div class="form-row">
<label>&nbsp;</label>
<input type="checkbox" id="node-input-output" placeholder="once" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-output" style="width: 70%;">Receive query output ?</label>
</div>
</script>
<script type="text/x-red" data-help-name="postgres">
<p>A PostgreSql I/O node. </p>
<p>Executes the query specified in msg.payload with optional query parameters in msg.queryParameters</p>
<p>The queryParameters in the query must be specified as $propertyname</p>
<p>See the node-postgres-named package for more info</p>
<p>When receiving data from the query, the msg.payload on the output will be a json array of the returned records</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('postgres',{
category: 'storage-output',
color:"rgb(148, 226, 252)",
defaults: {
postgresdb: { type:"postgresdb",required:true},
name: {value:""},
output: {value:false},
outputs: {value:0}
},
inputs: 1,
outputs: 0,
icon: "postgres.png",
align: "right",
label: function() {
return this.name||(this.sqlquery?this.sqlquery:"postgres");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
$( "#node-input-output" ).prop( "checked", this.output );
$("#node-input-name").focus();
},
oneditsave: function() {
var hasOutput = $( "#node-input-output" ).prop( "checked" );
this.outputs = hasOutput ? 1:0;
}
});
</script>

View File

@ -0,0 +1,123 @@
/**
* Copyright 2013 Kris Daniels.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var RED = require(process.env.NODE_RED_HOME+"/red/red");
var pg=require('pg');
var named=require('node-postgres-named');
var querystring = require('querystring');
RED.app.get('/postgresdb/:id',function(req,res) {
var credentials = RED.nodes.getCredentials(req.params.id);
if (credentials) {
res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")}));
} else {
res.send(JSON.stringify({}));
}
});
RED.app.delete('/postgresdb/:id',function(req,res) {
RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
RED.app.post('/postgresdb/:id',function(req,res) {
var body = "";
req.on('data', function(chunk) {
body+=chunk;
});
req.on('end', function(){
var newCreds = querystring.parse(body);
var credentials = RED.nodes.getCredentials(req.params.id)||{};
if (newCreds.user == null || newCreds.user == "") {
delete credentials.user;
} else {
credentials.user = newCreds.user;
}
if (newCreds.password == "") {
delete credentials.password;
} else {
credentials.password = newCreds.password||credentials.password;
}
RED.nodes.addCredentials(req.params.id,credentials);
res.send(200);
});
});
function PostgresDatabaseNode(n) {
RED.nodes.createNode(this,n);
this.hostname = n.hostname;
this.port = n.port;
this.db = n.db;
var credentials = RED.nodes.getCredentials(n.id);
if (credentials) {
this.user = credentials.user;
this.password = credentials.password;
}
}
RED.nodes.registerType("postgresdb",PostgresDatabaseNode);
function PostgresNode(n) {
RED.nodes.createNode(this,n);
this.topic = n.topic;
this.postgresdb = n.postgresdb;
this.postgresConfig = RED.nodes.getNode(this.postgresdb);
this.sqlquery = n.sqlquery;
this.output = n.output;
var node = this;
if(this.postgresConfig)
{
var conString = 'postgres://'+this.postgresConfig.user +':' + this.postgresConfig.password + '@' + this.postgresConfig.hostname + ':' + this.postgresConfig.port + '/' + this.postgresConfig.db;
node.clientdb = new pg.Client(conString);
named.patch(node.clientdb);
node.clientdb.connect(function(err){
if(err) { node.error(err); }
else {
node.on('input',
function(msg){
if(!msg.queryParameters) msg.queryParameters={};
node.clientdb.query(msg.payload,
msg.queryParameters,
function (err, results) {
if(err) { node.error(err); }
else {
if(node.output)
{
msg.payload = results.rows;
node.send(msg);
}
}
});
});
}
});
} else {
this.error("missing postgres configuration");
}
this.on("close", function() {
if(node.clientdb) node.clientdb.end();
});
}
RED.nodes.registerType("postgres",PostgresNode);

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B