-
Notifications
You must be signed in to change notification settings - Fork 102
Develop Chrome Apps for SAP HANA
You can use node-hdb not only to build SAP HANA applications for Node.js but also for the Chrome Platform. This tutorial explains how to create your first Chrome App for SAP HANA.
If you are new to Chrome Apps you may first walk through the Create Your First App tutorial.
-
If you don't have git you can install it from http://git-scm.com/downloads.
-
If not already done install node from http://nodejs.org/download/. Node ships with npm.
-
Install browserify as a global npm package.
npm install -g browserify
With browserify you can use many node modules on NPM in the browser.
On Windows it is recommended to use GIT BASH as shell to run git, node, npm, browserify from the command line.
Browserify a tool that helps you to use many modules on NPM in the browser. In our case we will use browserify to bundle up node-hdb for use in Chrome Apps.
First we have to download or clone node-hdb from github and install all it's development dependencies.
git clone https://github.com/SAP/node-hdb.git
cd node-hdb
npm install
Now we use browserify to build a hdb.js
bundle file to be used in the Chrome App.
browserify -r buffer -r ./lib:hdb -o ./hdb.js
The hdb.js
file is now in the node-hdb
directory.
It is recommended to use the Chrome Dev Editor to create a new project for your first Chrome App. But you can also use your favorite Editor. If you use Chrome Dev Editor you should first set the Root directory for all your Chrome App projects in the Settings dialog.
Then create a new project named MyFirstHanaChromeApp
and select JavaScript Chrome App
as Project type.
From the Chrome Dev Editor you can install and launch the application by pressing the Run button.
Finally the project structure should look like:
MyFirstHanaChromeApp
|
+-- manifest.json
+-- background.js
+-- index.html
+-- styles.css
+-- main.js
+-- hdb.js
|
+-- assets
|
+-- icon_16.png
+-- icon_128.png
You can name the root folder as you like.
Create a new file named manifest.json
in the root directory of your project.
{
"manifest_version": 2,
"name": "MyFirstHanaChromeApp",
"short_name": "MyFirstHanaChromeApp",
"description": "My First SAP HANA Chrome App",
"version": "0.0.1",
"icons": {
"16": "assets/icon_16.png",
"128": "assets/icon_128.png"
},
"app": {
"background": {
"scripts": ["background.js"]
}
},
"sockets": {
"tcp": {
"connect": "*:*"
}
}
}
Allow TCP connections to any network address and port.
Now create a background.js
file:
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create("index.html", {
id: "mainWindow",
bounds: {
width: 640,
height: 800
}
});
});
The background script listens for the app launching, then creates the window.
For the window page you have to create a index.html
file with the following content:
<!DOCTYPE html>
<html>
<head>
<title>My First SAP HANA Chrome App</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<textarea cols="80" rows="4">select * from dummy</textarea><br>
<button>Execute</button>
<pre id="result"></pre>
<script src="hdb.js"></script>
<script src="main.js"></script>
</script>
</body>
</html>
This page will be displayed when your App is launched.
Now create a corresponding style.css
file as follows:
body {
margin: 10px;
padding: 0;
font-size: 14px;
font-family: monospace;
}
#result {
margin-top: 20px;
min-height: 480px;
max-height: 640px;
overflow-y: auto;
-webkit-user-select: text;
}
The -webkit-user-select
is important that the user is able to select and copy text in the result.
Now create the main.js
file:
window.onload = function () {
var hdb = require('hdb');
var client = hdb.createClient({
host: 'hostname',
port: 30015,
user: 'username',
password: 'secret'
});
var command = document.querySelector('textarea');
var button = document.querySelector('button');
function showMessage(msg) {
result.textContent = msg;
}
function showError(err) {
showMessage(err.message);
}
button.onclick = function execute(){
if (client.readyState !== 'connected') {
return showError(new Error('Not connected'));
}
client.exec(command.value, function done(err, rows) {
if (err) {
return showError(err);
}
var result = document.getElementById('result');
result.textContent = JSON.stringify(rows, null, 2);
});
};
client.connect(function (err) {
if (err) {
return showError(err);
}
});
};
Move the previously created hdb.js
bundle script file from the node-hdb
folder into root folder of the Chrome App project.
Download these images and copy them to the assets
subfolder:
Go to chrome://extensions and enable developer mode (checkbox in the upper right corner of the page). Now click the Load unpacked extension button and load your App from it's project root folder.
Go to chrome://apps and click the icon of your App. Or if you use the Chrome Dev Editor you can just press the Run button in the upper left corner. This also enables the developer mode.
In order to display the resulting rows as table we use a simple javascript table control called Dable.
Right click this link https://raw.githubusercontent.com/deltreey/Dable/master/dist/dable.js and select Save link as... dable.js
in the root directory of your Chrome App.
Open the index.html
window page and make the following changes:
<!DOCTYPE html>
<html>
<head>
<title>My First SAP HANA Chrome App</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<textarea cols="80" rows="4">select * from dummy</textarea><br>
<button>Execute</button>
- <pre id="result"></pre>
+ <div id="result"></div>
+ <script src="dable.js"></script>
<script src="hdb.js"></script>
<script src="main.js"></script>
</script>
</body>
</html>
Open the main.js
file and add the showResults
function, which creates the dable table control. Then change the onclick handler as you can see below:
window.onload = function () {
var hdb = require('hdb');
var client = hdb.createClient({
host: 'hostname',
port: 30015,
user: 'username',
password: 'secret'
});
var command = document.querySelector('textarea');
var button = document.querySelector('button');
function showMessage(msg) {
result.textContent = msg;
}
function showError(err) {
showMessage(err.message);
}
+ function showResult(metadata, rows) {
+ var columns = metadata.map(function(column){
+ return column.columnDisplayName;
+ });
+ var data = rows.map(function(row){
+ return columns.map(function(column){
+ return '' + row[column];
+ });
+ });
+ var dable = new Dable();
+ dable.SetDataAsRows(data);
+ dable.SetColumnNames(columns);
+ dable.BuildAll('result');
+ }
button.onclick = function execute(){
if (client.readyState !== 'connected') {
return showError(new Error('Not connected'));
}
- client.exec(command.value, function done(err, rows) {
+ client.execute(command.value, function done(err, rs) {
if (err) {
return showError(err);
}
- var result = document.getElementById('result');
- result.textContent = JSON.stringify(rows, null, 2);
+ rs.fetch(function(err, rows){
+ if (err) {
+ return showError(err);
+ }
+ showResult(rs.metadata, rows);
+ });
});
};
client.connect(function (err) {
if (err) {
return showError(err);
}
});
};
The table header is populated with ColumnDisplayName of the ResultSetMetadata. In order to be able to access the ResultSetMetadata we replace the exec
call, which returns an array with all rows, with an execute
call, which returns the resultSet object without fetching data. The resultSet object has an metadata property.
Right click somewhere in the Chrome App window and select Reload app.
Right click somewhere in the Chrome App window and select Inspect element or Inspect background page whether you like to debug the main application script or the background script.
Unzip, adjust the HANA connection data in main.js
and install the unpacked Chrome App in Developer Mode.