Skip to content

Develop Chrome Apps for SAP HANA

Holger Koser edited this page Mar 17, 2016 · 16 revisions

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.

Prerequisites

On Windows it is recommended to use GIT BASH as shell to run git, node, npm, browserify from the command line.

Bundle up node-hdb for use on the Chrome Platform

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.

Create your first SAP HANA Chrome App

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.

Settings...

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 the manifest

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.

Create the background script

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.

Create a window page

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.

Create the stylesheet

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.

Create the main application script

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);
    }
  });
};

Create the hdb bundle script

Move the previously created hdb.js bundle script file from the node-hdb folder into root folder of the Chrome App project.

Create the App icons

Download these images and copy them to the assets subfolder:

Install the App

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.

Launch the App

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.

icon_128.png

Display the query results as table

In order to display the resulting rows as table we use a simple javascript table control called Dable.

Download 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.

Change the window page

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>

Change the main application script

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.

Reload the Chrome App

Right click somewhere in the Chrome App window and select Reload app.

Debug the Chrome 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.

Download the final Chrome App

Unzip, adjust the HANA connection data in main.js and install the unpacked Chrome App in Developer Mode.