# [START runtime]
runtime: nodejs
env: flex
# [END runtime]
# Temporary setting to keep gcloud from uploading node_modules
skip_files:
- ^node_modules$
app.get('/', function (req, res) {
sql_command = "SELECT TO_VARCHAR(ROUND((FREE_PHYSICAL_MEMORY) /1024/1024/1024, 2)) AS FREEMEM FROM PUBLIC.M_HOST_RESOURCE_UTILIZATION";
async.waterfall([connect, executeSQL, disconnect], function (err, rows) {
client.end();
if (err) {
return console.error(err);
}
lv_freemem = rows[0].FREEMEM;
res.render('index', {
version: lv_version,
app_version: lv_appversion,
freemem: lv_freemem,
diskvol: lv_disk,
cpu: lv_cpu,
alerts: lv_alerts,
users: lv_users
});
});
})
<!DOCTYPE HTML>
<html lang="en">
<head>
<link rel="apple-touch-icon" sizes="57x57" href="https://blogs.sap.com/images/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="https://blogs.sap.com/images/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="https://blogs.sap.com/images/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="https://blogs.sap.com/images/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="https://blogs.sap.com/images/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="https://blogs.sap.com/images/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="https://blogs.sap.com/images/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="https://blogs.sap.com/images/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://blogs.sap.com/images/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="https://blogs.sap.com/images/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://blogs.sap.com/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="https://blogs.sap.com/images/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://blogs.sap.com/images/favicon-16x16.png">
<link rel="manifest" href="https://blogs.sap.com/images/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/images/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="/js/jquery-3.1.1.min.js"></script>
<link rel="stylesheet" href="https://blogs.sap.com/css/bootstrap.min.css">
<script src="/js/bootstrap.min.js"></script>
</head>
<body>
<div>
<div>
<nav class="navbar navbar-inverse" role="navigation" style="padding-left:130px;">
<img src="/images/logo.png" class="pull-left" style="display: inline-block; width: 50px">
<ul class="nav navbar-nav">
<li class="active"><a href="https://blogs.sap.com/">Home<span class="sr-only">(current)</span></a></li>
<li><a href="https://blogs.sap.com/fuzzy">Fuzzy Search</a></li>
<li><a href="https://blogs.sap.com/map">Maps</a></li>
<li><a href="https://www.sap.com/cmp/nl/sap-developer-news/index.html">Subscribe</a></li>
</ul>
</nav>
</div>
<br/>
<div class="jumbotron">
<div class="container">
<p>
<img src="/images/hana.png" class="pull-left" style="display: inline-block;">
<a href="https://www.sap.com/developer/topics/sap-hana-express.html">SAP HANA</a> is a data platform that provides everything you need to build real-time
data-driven applications. Learn about the different features and components, how
to use them and how to program your applications.<br>
<br>
</p>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-4">
<h2>SAP Developers</h2>
<p>The following is a Node JS demo connecting to SAP HANA, express edition running within the Google Cloud Platform. </p>
<img src="/images/landscape.png">
</div>
<div class="col-md-4">
<h2>Components</h2>
<ul>
<li>Node Library: express</li>
<li>Node Library: ejs</li>
<li>Node Library: util</li>
<li>Node Library: async</li>
<li>Node Library: hdb</li>
<li>JS Library: JQuery</li>
<li>JS Library: JQuery UI</li>
<li>Layout Library: Bootstrap</li>
<li>SAP HANA, express edition</li>
</ul>
</div>
<div class="col-md-4">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Server Information</h3>
</div>
<div class="panel-body">
<p class="text-muted">HANA v<%= version %></p>
<p class="text-muted">Application v<%= app_version %></p>
<p class="text-muted">Active Users <span class="label label-info"><%= users %></span></p>
<p class="text-muted">Free Memory <span class="label label-info"><%= freemem %></span> GB</p>
<p class="text-muted">CPUs <span class="label label-info"><%= cpu %></span></p>
<p class="text-muted">Free Disk Space <span class="label label-info"><%= diskvol %></span> GB</p>
<p class="text-muted">Alerts <span class="label label-danger"><%= alerts %></span><p>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<p class="text-muted">HANA v<%= version %></p>
<p class="text-muted">Application v<%= app_version %></p>
res.render('index', {
version: lv_version,
app_version: lv_appversion,
...
}
<form id="form1" method="GET" action="/fuzzy_get">
<label for="txtFieldSearch">Mispelled keyword to search the <span class="label label-success"><%= sql_count %></span> reviews for:</label>
<input id="txtFieldSearch" name="txtFieldSearch" type="text" size="30" value="<%= search_field %>" />
<input id="txtfuzzyweight" name="txtfuzzyweight" type="hidden" />
<p></p>
<p></p>
<div align="center">
<input class="ui-button ui-widget ui-corner-all" type="button" value="View SQL" onclick="display()">
<input class="ui-button ui-widget ui-corner-all" type="button" value="Submit SQL" onclick="submitDetailsForm()">
</div>
<p></p>
<div id="txtSearch"><%= search_sql %></div>
<p></p>
</form>
app.get('/fuzzy_get', function (req, res) {
var lv_res = {
txtFieldSearch: req.query.txtFieldSearch,
txtfuzzyweight: req.query.txtfuzzyweight
};
sql_command = "SELECT SCORE() AS score, RTEXT FROM \"FSM\".\"sap.devs.demo.fuzzymovie.data::movies.Review\" WHERE CONTAINS(RTEXT,'" + req.query.txtFieldSearch + "', FUZZY(0." + req.query.txtfuzzyweight + ") ) ORDER BY score DESC limit 15";
async.waterfall([connect, executeSQL, disconnect], function (err, rows) {
client.end();
if (err) {
return console.error(err);
}
res.render('fuzzy', {
data: rows,
version: lv_version,
app_version: lv_appversion,
search_field: req.query.txtFieldSearch,
search_sql: sql_command,
sql_count: lv_count
});
});
})
<table padding="2">
<tr>
<th>Score</th><th>Review</th>
</tr>
<% for (var i = 0; i < data.length; i++) { %>
<tr>
<td align="left" valign="top"><%= data[i].SCORE %> </td>
<td><%= data[i].RTEXT %></td>
</tr>
<% } %>
</table>
// Insert to HANA
var timeStamp = new Date().getTime();
var data = {
"ID": 1,
"PDATE": "/Date(" + timeStamp + ")/",
"PLAT": "" + position.coords.latitude + "",
"PLON": "" + position.coords.longitude + "",
"PDESC": " "
};
console.log("Data: " + JSON.stringify(data));
var aUrl =
'/sap/devs/demo/mylocation/services/location_input.xsodata/locs';
jQuery.ajax({
url: aHost + aUrl,
method: 'POST',
crossDomain: true,
contentType: "application/json",
data: JSON.stringify(data),
success: function (data) {
console.log('Posted to SAP HANA');
console.log(data);
},
failure: function (errMsg) {
console.log(errMsg);
},
error: function (errMsg) {
console.log(errMsg);
},
xhrFields: {
withCredentials: true
},
crossDomain: true
});
app.get('/map', function (req, res) {
sql_command = "SELECT * FROM \"HGL\".\"sap.devs.demo.mylocation.data::hanalocations_details.locations\"";
async.waterfall([connect, executeSQL, disconnect], function (err, rows) {
client.end();
if (err) {
return console.error(err);
}
var result = JSON.stringify({
Items: rows
});
sql_command = "SELECT * FROM \"HGL\".\"sap.devs.demo.mylocation.data::hanalocations_details.offices\"";
async.waterfall([connect, executeSQL, disconnect], function (err, rows) {
client.end();
if (err) {
return console.error(err);
}
var office_result = JSON.stringify({
Items: rows
});
res.render('map', {
api_key: API_KEY,
version: lv_version,
app_version: lv_appversion,
data: result,
offices: office_result
});
});
});
})
// Marker Locations
var result = "<%= data %>"
var map_data = replaceAll(result);
map_data = JSON.parse(map_data);
// Offce locations
var office_result = "<%= offices %>"
var map_officedata = replaceAll(office_result);
map_officedata = JSON.parse(map_officedata);
function replaceAll(str) {
return str.replace(new RegExp('"', 'g'), '"');
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
29 | |
13 | |
12 | |
10 | |
9 | |
9 | |
9 | |
7 | |
7 | |
6 |