+ All Categories
Home > Documents > Using Node.js with Cach© - InterSystems Documentation

Using Node.js with Cach© - InterSystems Documentation

Date post: 11-Feb-2022
Category:
Upload: others
View: 21 times
Download: 0 times
Share this document with a friend
44
Using Node.js with Caché Version 2012.2 13 September 2017 InterSystems Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com
Transcript

Using Node.js with Caché

Version 2012.213 September 2017

InterSystems Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com

Using Node.js with CachéCaché Version 2012.2 13 September 2017 Copyright © 2017 InterSystems CorporationAll rights reserved.

InterSystems, InterSystems Caché, InterSystems Ensemble, InterSystems HealthShare, HealthShare, InterSystems TrakCare, TrakCare,InterSystems DeepSee, and DeepSee are registered trademarks of InterSystems Corporation.

InterSystems iKnow, Zen, and Caché Server Pages are trademarks of InterSystems Corporation.

All other brand or product names used herein are trademarks or registered trademarks of their respective companies or organizations.

This document contains trade secret and confidential information which is the property of InterSystems Corporation, One Memorial Drive,Cambridge, MA 02142, or its affiliates, and is furnished for the sole purpose of the operation and maintenance of the products of InterSystemsCorporation. No part of this publication is to be used for any other purpose, and this publication is not to be reproduced, copied, disclosed,transmitted, stored in a retrieval system or translated into any human or computer language, in any form, by any means, in whole or in part,without the express prior written consent of InterSystems Corporation.

The copying, use and disposition of this document and the software programs described herein is prohibited except to the limited extentset forth in the standard software license agreement(s) of InterSystems Corporation covering such programs and related documentation.InterSystems Corporation makes no representations and warranties concerning such software programs other than those set forth in suchstandard software license agreement(s). In addition, the liability of InterSystems Corporation for any losses or damages relating to or arisingout of the use of such software programs is limited in the manner set forth in such standard software license agreement(s).

THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BY INTERSYSTEMSCORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTER SOFTWARE. FOR COMPLETE INFORMATIONREFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARE LICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION,COPIES OF WHICH WILL BE MADE AVAILABLE UPON REQUEST.

InterSystems Corporation disclaims responsibility for errors which may appear in this document, and it reserves the right, in its sole discretionand without notice, to make substitutions and modifications in the products and practices described in this document.

For Support questions about any InterSystems products, contact:

InterSystems Worldwide Response Center (WRC)+1-617-621-0700Tel:+44 (0) 844 854 2917Tel:[email protected]:

Table of Contents

About This Book .................................................................................................................................... 1

1 Introduction ........................................................................................................................................ 3

2 Installation ........................................................................................................................................... 52.1 UNIX .......................................................................................................................................... 52.2 Windows ..................................................................................................................................... 6

3 Accessing Caché from Node.js ........................................................................................................... 73.1 JSON Objects and Caché Globals .............................................................................................. 73.2 Synchronous vs. Asynchronous cache.node Methods ................................................................ 83.3 Overview of cache.node Methods .............................................................................................. 93.4 Opening and Closing the Caché Database ............................................................................... 103.5 Advanced Data Access with retrieve() and update() ................................................................ 11

3.5.1 Using retrieve() .............................................................................................................. 113.5.2 Using update() ................................................................................................................ 15

3.6 Towards an Object Oriented Development Methodology ........................................................ 16

4 Reference for cache.node Methods ................................................................................................. 174.1 Example Data ........................................................................................................................... 184.2 close() ....................................................................................................................................... 184.3 data() ......................................................................................................................................... 184.4 function() .................................................................................................................................. 194.5 get() .......................................................................................................................................... 204.6 global_directory() ..................................................................................................................... 214.7 increment() ............................................................................................................................... 224.8 kill() .......................................................................................................................................... 224.9 lock() ........................................................................................................................................ 234.10 merge() ................................................................................................................................... 234.11 next() or order() ...................................................................................................................... 244.12 next_node() ............................................................................................................................. 254.13 open() ..................................................................................................................................... 274.14 previous() ................................................................................................................................ 274.15 previous_node() ...................................................................................................................... 284.16 retrieve() ................................................................................................................................. 304.17 set() ......................................................................................................................................... 324.18 unlock() .................................................................................................................................. 324.19 update() ................................................................................................................................... 334.20 version() and about() .............................................................................................................. 34

Appendix A: Building cache.node from Source ................................................................................ 37A.1 Using the Node.js Build Procedure ......................................................................................... 37

A.1.1 Creating the Build Script (wscript) ............................................................................... 37A.1.2 Build the cache.node Module ........................................................................................ 38

A.2 Building Directly from Source ................................................................................................ 38

Using Node.js with Caché                                                                                                                                                      iii

About This Book

This book describes how to install and use the cache.node module, which provides access to Caché from a Node.js appli-cation.

This book contains the following sections:

• Introduction

• Installation

• Accessing Caché from Node.js

• Reference for cache.node Methods

• Building cache.node from Source

There is also a detailed Table of Contents.

For general information, see Using InterSystems Documentation.

Using Node.js with Caché                                                                                                                                                       1

1Introduction

This document describes cache.node, an add-on module for the Node.js environment that implements high performanceaccess to data held in Caché.

Node.js provides a means through which high performance and highly scalable network infrastructure can be easily created.It is different from conventional thread based networking software (such as web servers) because it provides a non-blockingevent based architecture.

Most modern web servers are implemented using a hybrid multi-process/multithreaded server architecture where a threadis dedicated to serving each request. All resources associated with that thread remain allocated until the request is satisfiedand a response dispatched to the client. In the Node.js architecture, a single process is used per instance (of node) andthreads are only used as a means through which operations and system calls that would otherwise block can be calledasynchronously with respect to the primary thread of execution. Everything happens asynchronously, and a primary designfeature is that no function should block, but rather accept a callback function that Node.js will use to notify the initiatingprogram that the operation has completed.

A consequence of the event based server architecture is that system resources (such as heap memory) are never tied-upwhile waiting for some other operation to complete. Because of this, network programs developed using Node.js occupya very small footprint in terms of system resource and memory usage and a high level of scalability.

The cache.node module allows Caché to be leveraged as a high performance persistence storage engine that perfectlycomplements the high performance Node.js environment. Caché multidimensional storage provides a very fast, flexiblestorage model that can be used to implement a wide variety of data structures. The Caché cache.node module allows directaccess to globals, the basis of the multidimensional storage model (see Using Caché Globals for a formal description).

Caché can be regarded as a NoSQL database providing B-Tree based storage but with one important difference. Whereasmost B-Tree databases implement one-dimensional key/value storage, Caché provides a multi-dimensional multiple key/valuestorage model. This provides the basis for a highly structured NoSQL data repository. In Caché terminology, each entry isknown as a "global node".

Examples:

One-dimensional Global Storage:

MyGlobal(“key1”)=”value1” MyGlobal(“key2”)=”value2” MyGlobal(“key3”)=”value3”

Multi-dimensional Global Storage:

Using Node.js with Caché                                                                                                                                                       3

MyGlobal(“key1”)=”value1” MyGlobal(“key1”, “key1a”)=”value1a” MyGlobal(“key1”, “key1a, “key1b”)=”value1b” MyGlobal(“key2”)=”value2” MyGlobal(“key2”, 1)=”value21” MyGlobal(“key2”, 2)=”value22” MyGlobal(“key3”)=”value3” MyGlobal(“key3”, 1, 2, 3)=”value3123” MyGlobal(“key3”, 1, 3)=”value313”

4                                                                                                                                                       Using Node.js with Caché

Introduction

2Installation

This section describes the procedure for installing a pre-built cache.node module.

The following components are required:

• Caché installation.

• Node.js version 0.4.2 (or later).

Node.js is available for a number of UNIX platforms. Native support for Windows was added in version 0.6.

The cache.node file is named using the Node.js .node extension for both UNIX and Windows. In the kits supplied byInterSystems, the module to be used with Node.js version 0.6 (and later) is named cache061.node. This may be renamedas the more usual cache.node name before deployment to avoid having to modify the require statement in existingNode.js software.

• Node.js version 0.4.x: cache.node

• Node.js version 0.6.x: cache061.node

2.1 UNIXThe module cache.node is actually a standard UNIX shared object (i.e. cache.so) but with an unusual Node.js-specific fileextension.

Copy cache.node to the following location in the node file system:

.../node/lib/node/

For example:

/opt/local/node/lib/node/cache.node

Placing the module in the recognized library path will remove the need to specify the full path in the JavaScript files. Forexample, in JavaScript, it will be possible to write:

var globals = require(‘cache');

Instead of (for example):

var globals = require('/opt/local/build/default/cache');

Using Node.js with Caché                                                                                                                                                       5

2.2 WindowsThe module cache.node is actually a standard Windows DLL (i.e. cache.dll) but with an unusual Node.js-specific fileextension.

The standard Windows installer (provided by the Node.js Group) usually places the Node.js software in the followinglocation:

C:\Program Files\nodejs

The installation mechanism usually adds this location to the Windows PATH environment variable. If this is not the case,then add it manually. Also, the NODE_PATH environment variable should be set and it, too, should be set to the Node.jsinstallation directory. For example:

NODE_PATH=C:\Program Files\nodejs

Copy cache.node to the location specified in the NODE_PATH environment variable:

C:\Program Files\nodejs

Placing the module in the recognized Node.js path will remove the need to specify the full path in the JavaScript files. Forexample, in JavaScript, it will be possible to write:

var globals = require(‘cache');

Instead of (for example):

var globals = require('/nodejs/lib/cache');

or:

var globals = require('c:/nodejs/lib/cache');

6                                                                                                                                                       Using Node.js with Caché

Installation

3Accessing Caché from Node.js

The cache.node module provides the basic NoSQL-style methods, and also has more advanced methods that can be usedto implement a higher-level view of the Caché database which can, in turn, form the basis of an object oriented approachto development. This chapter provides an overview of the available methods and the concepts behind them.

The following topics are discussed:

• JSON Objects and Caché Globals — describes the basic relationship between the globals in the Caché database andJSON objects in the Node.js environment.

• Synchronous vs. Asynchronous cache.node Methods — describes how to use cache.node calls both synchronouslyand asynchronously.

• Overview of cache.node Methods — provides a quick overview of the basic NoSQL-style cache.node database methods.

• Opening and Closing the Caché Database — describes how to load the cache.node module, create an instance of thecache.node object, and open or close the target Caché database.

• Advanced Data Access with retrieve() and update() — describes advanced cache.node methods that perform certainoperations more efficiently than the basic NoSQL-style methods.

• Towards an Object Oriented Development Methodology — illustrates how the cache.node methods and JSON notationcan be used for object orientated development.

3.1 JSON Objects and Caché GlobalsIn this section we will look at the basic relationship between JSON objects in the Node.js environment and globals in theCaché database.

Consider the following global node:

^Customer(1)="Chris Munt"

Note: By convention, global names are prefixed with the ‘^’ character in Caché. However, this convention should notbe followed in the corresponding JSON representation.

The equivalent JSON construct will be:

{global: "Customer", subscripts: [1], data: "Chris Munt"}

Adding further nodes to this data construct:

Using Node.js with Caché                                                                                                                                                       7

Globals:

^Customer(1)="Chris Munt" ^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010"

JSON:

{ global: "Customer", subscripts: [1], data: "Chris Munt" } { global: "Customer", subscripts: [1, "Address", 1], data: "London" } { global: "Customer", subscripts: [1, "Address", 2], data: "UK" } { global: "Customer", subscripts: [1, "DateOfRegistration"], data: "1 May 2010" }

3.2 Synchronous vs. Asynchronous cache.node MethodsAll methods provided by cache.node can be run either synchronously or asynchronously. While synchronous operation isconceptually easier to grasp and can be useful for debugging, the expectation in the Node.js environment is that all operationsshould be implemented asynchronously with a completion event raised by means of a callback function. For this reason,most of the examples given in this guide are coded to run asynchronously. To run them synchronously simply omit thecallback function from the arguments list.

• Synchronous operation — Method does not return until the operation is complete.

• Asynchronous operation — Method returns immediately and your program is notified when the operation is complete.In order to accept notification, you must pass a callback function as an argument to the original method call. By con-vention, the callback will always be the last argument in the list.

Consider the method to determine the version of the cache.node module in use:

Synchronous operation:

var result = mydata.version();

Asynchronous operation:

mydata.version( function(error, result) { if (error) { // error } else { // success } } );

The standard convention for reporting errors in Node.js is implemented in cache.node. If an operation is successful, errorwill be false. If an error occurs then error will be true and the result object will contain the details according to the followingJSON construct:

8                                                                                                                                                       Using Node.js with Caché

Accessing Caché from Node.js

{ "ErrorMessage": [error message text], "ErrorCode": [error code], "ok": [true|false] }

For synchronous operation, you should check for the existence of these properties in the result object to determine whetheror not an error has occurred.

3.3 Overview of cache.node MethodsThe individual cache.node methods are described in detail in the reference section. Here is a brief summary of the availablemethods and their uses, with links to the reference section entries:

Opening and closing the database

See “Opening and Closing the Caché Database” for basic information on using these methods:

• open() — opens the specified Caché database.

• close() — closes a previously opened database.

Operations on individual nodes

• set() — sets the value of a global node.

• get() — retrieves a global node.

• kill() — deletes a global node.

• increment() — adds 1 to the value of an integer in a global node.

• merge() — copies all or part of a global to another global.

Iteration over global nodes

• data() — tests for the existence of a global node.

• next() and previous() — gets the next or previous global node subscript on the current level.

• next_node() and previous_node() — gets the next or previous global node in collation order regardless oflevel.

• lock() and unlock() — locks global nodes for exclusive use, and unlocks nodes previously locked by yourprogram.

Advanced data access

These methods perform batch read and write operations that are frequently more efficient than access with thebasic NoSQL-style methods:

• retrieve() — recursively retrieves all global nodes defined beneath a specified level and returns them as asingle JSON object.

• update() — uses information in a JSON object to write a set of globals to the database.

See “Advanced Data Access with retrieve() and update()” for a detailed discussion of usage.

Using Node.js with Caché                                                                                                                                                       9

Overview of cache.node Methods

Caché-specific methods

These methods provide access to Caché information and functions:

• function() — invokes a Caché function.

• global_directory() — returns a list of globals held in the Caché database.

• version() — returns version information about the cache.node module in use and the associated Caché database(if open).

3.4 Opening and Closing the Caché DatabaseBefore any other methods can be called, the cache.node module must be loaded, an instance of the Caché object createdand the target Caché database must be opened before any data can be accessed.

Loading the Cache.node moduleIf the cache.node module has been installed in the correct location for your Node.js installation, the following line willsuccessfully load it from the default location:

var globals = require('cache');

If the module is installed in some other location the full path should be specified. For example:

var globals = require('/opt/cm/node042/build/default/cache');

Creating an instanceThe next task is to create an instance of the cache.node object.

var mydata = new globals.Cache();

Opening the DatabaseFinally, the Caché database can be opened:

mydata.open(parameters[, function(error, result){}]);

where:

• parameters.path — Path to the mgr directory of the target Caché installation.

• parameters.username — User name for access.

• parameters.password — Password for access.

• parameters.namespace — Target Caché namespace.

For example:

mydata.open( { path:"/cache20102/mgr", username: "_SYSTEM", password: "SYS", namespace: "USER" }, function(error, result){} );

Closing the DatabaseThe following method will gracefully close a previously opened database.

10                                                                                                                                                     Using Node.js with Caché

Accessing Caché from Node.js

mydata.close([function(error, result){}]);

3.5 Advanced Data Access with retrieve() and update()This section describes advanced methods that perform operations that could otherwise be achieved by combining severalof the basic NoSQL-style methods.

The following topics are discussed:

• Using retrieve() — describes retrieving groups of global nodes as a single JSON object

• Using update() — describes writing a single JSON object to update groups of global nodes.

The following Caché data will be used to illustrate the higher level methods.

^Customer(1)="Chris Munt" ^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010" ^Customer(2)="Rob Tweed" ^Customer(2, "Address", 1)="Reigate" ^Customer(2, "Address", 2)="UK" ^Customer(2, "DateOfRegistration")="7 May 2010" ^Customer(3)="Jane Smith" ^Customer(3, "Address", 1)="Oxford" ^Customer(3, "Address", 2)="UK" ^Customer(3, "DateOfRegistration")="9 June 2010"

3.5.1 Using retrieve()

The following topics are discussed:

• Retrieve a list of global nodes (retrieve("list"))

• Retrieve a list of global nodes recursively (retrieve("array"))

• Retrieve a structured data object (retrieve("object"))

• Controlling the amount of data returned by retrieve operations

3.5.1.1 Retrieve a list of global nodes (retrieve("list"))

This method will return a list of subscript values that are defined directly beneath a given level in the global.

Example 1: Retrieve a list of customer numbers

mydata.retrieve( {global: "Customer"}, "list", function(error, result) { // callback code } );

Result:

Three Customer records:

[1, 2, 3]

Using Node.js with Caché                                                                                                                                                     11

Advanced Data Access with retrieve() and update()

Example 2: Retrieve a list of address lines for a specific customer

mydata.retrieve( {global: "Customer", subscripts: [1, "address"]}, "list", function(error, result) { // callback code } );

Result:

Two lines in the address for customer number 1:

[1, 2]

3.5.1.2 Retrieve a list of global nodes recursively (retrieve("array"))

This method will return a list of subscript values together with their associated data values that are defined beneath a givenlevel in the global. The method is recursive and will retrieve all global nodes defined beneath a chosen level.

The result will be expressed as an array of global nodes: each global node expressed as a single JSON object.

Example 1: Retrieve all data for a customer

mydata.retrieve( {global: "Customer", subscripts: [1]}, "array", function(error, result) { // callback code } );

Result:

[ { global: "Customer", subscripts: [1], data: "Chris Munt" } { global: "Customer", subscripts: [1, "Address", 1], data: "London" } { global: "Customer", subscripts: [1, "Address", 2], data: "UK" } { global: "Customer", subscripts: [1, "DateOfRegistration], data: "1 May 2010" } ]

3.5.1.3 Retrieve a structured data object (retrieve("object"))

This method will retrieve a structured data object defined beneath a given level in a global. This method provides a structuredalternative to the array of global nodes described previously.

The result will be expressed as a single JSON object.

Example: Retrieve all data for a customer

Consider the following structured Caché global:

^Customer(1, "Name")="Chris Munt" ^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010"

In Node.js:

12                                                                                                                                                     Using Node.js with Caché

Accessing Caché from Node.js

mydata.retrieve( {global: "Customer", subscripts: [1]}, "object", function(error, result) { // callback code } );

Result:

{ node: { global: "Customer", subscripts: [1] } object: { Name: "Chris Munt", Address: {"1": "London", "2": "UK"}, DateOfRegistration: "1 May 2010" } }

3.5.1.4 Controlling the amount of data returned by retrieve operations

The retrieve operations are capable, depending on the underlying global structure, of returning enormous volumes of datato the Node.js environment. The following properties can be added to the requesting JSON object (i.e. the object definingthe root global node) to limit the amount of data returned.

• max — The maximum number of global nodes to return.

• lo — The lowest global subscript to return.

• hi — The highest global subscript to return.

If all three properties are defined, the retrieve operation will terminate when the max number of global nodes have beenreturned, even if the global subscript defined in hi has not been reached.

Consider the following Caché global:

^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010" ^Customer(1, "Name")="Chris Munt" ^Customer(1, "Orders", 20100501, "Reference")="Order001" ^Customer(1, "Orders", 20100503, "Reference")="Order002" ^Customer(1, "Orders", 20100507, "Reference")="Order003" ^Customer(1, "Orders", 20100509, "Reference")="Order004" ^Customer(1, "Orders", 20100510, "Reference")="Order005" ^Customer(1, "Orders", 20100520, "Reference")="Order006" ^Customer(1, "Orders", 20100527, "Reference")="Order007" ^Customer(1, "Orders", 20100906, "Reference")="Order008" ^Customer(1, "Orders", 20110104, "Reference")="Order011" ^Customer(1, "Orders", 20110203, "Reference")="Order012" ^Customer(2, "Address", 1)="Reigate" ^Customer(2, "Address", 2)="UK" ^Customer(2, "DateOfRegistration")="7 May 2010" ^Customer(2, "Name")="Rob Tweed" ^Customer(2, "Orders", 20101204, "Reference")="Order009" ^Customer(2, "Orders", 20101206, "Reference")="Order010" ^Customer(3, "Address", 1)="Oxford" ^Customer(3, "Address", 2)="UK" ^Customer(3, "DateOfRegistration")="9 June 2010" ^Customer(3, "Name")="Jane Smith" ^Customer(4, "Name")="Jim Cooper" ^Customer(5, "Name")="Eve Simpson" ^Customer(6, "Name")="John Cotton" ^Customer(7, "Name")="Alison Clarke" ^Customer(8, "Name")="Paul Francis" ^Customer(9, "Name")="Susan Reed" ^Customer(10, "Name")="Mary Dodds"

Note: The third subscript in the "Orders" section is the date in YYYYMMDD format.

The following examples demonstrate how to use the max, lo, and hi properties:

Using Node.js with Caché                                                                                                                                                     13

Advanced Data Access with retrieve() and update()

Example 1: List the registered Customer numbers between 2 and 7 (inclusive)

mydata.retrieve( {global: "Customer", lo: 2, hi: 7}, "list", function(error, result) { // callback code } );

Result:

Six Customer records:

[2, 3, 4, 5, 6, 7]

Example 2: List the Orders placed by Customer number 1 between 7 May 2010 and 24 December 2010(inclusive)

mydata.retrieve( { global: "Customer", subscripts [1, "Orders"], lo: 20100507, hi: 20101224 }, "list", function(error, result) { // callback code } );

Result:

Six Customer Order records:

[20100507, 20100509, 20100510, 20100520, 20100527, 20100906]

Example 3: List the full details for Orders placed by Customer number 1 in September 2010

mydata.retrieve( { global: "Customer", subscripts [1, "Orders"], lo: 20100901, hi: 20100930 }, "array", function(error, result) { // callback code } );

Result:

One Customer Order record:

[{ global: "Customer", subscripts: [1, "Orders", 20100906, "Reference"], data: "Order008" }]

Example 4: List first three Customers registered (by Customer number) in the database

mydata.retrieve( {global: "Customer", max: 3}, "list", function(error, result) { // callback code } );

Result:

Three Customer records:

[1, 2, 3]

14                                                                                                                                                     Using Node.js with Caché

Accessing Caché from Node.js

3.5.2 Using update()

The update() method allows an application to save a group of global nodes by passing information saved in a single JSONobject. The nodes can represent either an array or an object:

• Save a list of global nodes (update("array"))

• Save a structured data object (update("object"))

3.5.2.1 Save a list of global nodes (update("array"))

This method performs the opposite task to that performed by the retrieve method. In other words the update method takesan array of global nodes, each expressed as a single JSON object and writes them back to the Caché database.

Example 1: Create or update a record for a customer

mydata.update( [ { global: "Customer", subscripts: [1], data: "Chris Munt" } { global: "Customer", subscripts: [1, "Address", 1], data: "London" } { global: "Customer", subscripts: [1, "Address", 2], data: "UK" } { global: "Customer", subscripts: [1, "DateOfRegistration"], data: "1 May 2010" } ], "array", function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

3.5.2.2 Save a structured data object (update("object"))

This method performs the opposite task to that performed by the retrieve method. In other words it writes the contents ofa structured JSON object back to the Caché database.

Example 1: Create or update a record for a customer

mydata.update( node: { global: "Customer", subscripts: [1] }, Object: { Name: "Chris Munt", DateOfRegistration: "1 May 2010", Address: {"1": "London", "2": "UK"} }, "object", function(error, result) { // callback code } );

Result:

Using Node.js with Caché                                                                                                                                                     15

Advanced Data Access with retrieve() and update()

Operation successful if no error reported. If successful, the following set of global nodes will be created for thisexample:

^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010" ^Customer(1, "Name")="Chris Munt"

3.6 Towards an Object Oriented DevelopmentMethodologyThe examples shown so far have illustrated the use of the Caché database as a raw NoSQL engine. The following codeillustrates how the cache.node methods together with the JSON notation in JavaScript can be used to create a more ObjectOrientated development methodology.

var globals = require('cache'); var user = new globals.Cache(); user.open({ path:"/cache20102/mgr", username: "_SYSTEM", password: "SYS", namespace: "USER" }); var customers = new Customers(); var customer = customers.getCustomer(1); console.log("customer number 1 is " + customer.data); customers.setCustomer(9, "Tom Smith"); user.close();

function Customers() { this.global = "Customer"; this.subscripts = new Array(); this.getCustomer = function(id) { this.subscripts[0] = id; var person = user.get(this); return person; } this.setCustomer = function(id, name) { this.subscripts[0] = id; this.data = name; var person = user.set(this); return; } }

16                                                                                                                                                     Using Node.js with Caché

Accessing Caché from Node.js

4Reference for cache.node Methods

This section provides detailed documentation for each of the functions supported by the Caché cache.node module. Seethe “Example Data” section for a listing of the data sets used by many of the examples in this section.

The following functions are supported:

• about() — see version().

• close() — closes a previously opened database.

• data() — tests for the existence of a global node.

• function() — invokes a Caché function.

• get() — retrieves a global node.

• global_directory() — returns a list of globals held in the Caché database.

• increment() — adds 1 to the value of an integer in a global node.

• kill() — deletes a global node.

• lock() — locks global nodes for exclusive use.

• merge() — copies all or part of a global to another global.

• next() — gets the next Global subscript on the current level.

• next_node() — gets the next global node in collation order regardless of level.

• open() — opens the specified Caché database.

• order() — see next()

• previous() — gets the previous Global subscript on the current level.

• previous_node() — gets the previous global node in collation order regardless of level.

• retrieve() — recursively retrieves all global nodes defined beneath a specified level.

• set() — sets the value of a global node.

• update() — writes the contents of a JSON object to the Caché database.

• unlock() — unlocks global nodes previously locked by your program.

• version() — returns basic version information about the cache.node module in use and the associated Caché database(if open).

Using Node.js with Caché                                                                                                                                                     17

4.1 Example DataMost examples in this reference section will be based on the following simple Caché data set:

^Customer(1)="Chris Munt" ^Customer(1, "address")="Banstead" ^Customer(2)="Rob Tweed" ^Customer(3)="Jane Smith"

The following Caché data will be used to illustrate the retrieve() and update() methods:

^Customer(1)="Chris Munt" ^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010"

^Customer(2)="Rob Tweed" ^Customer(2, "Address", 1)="Reigate" ^Customer(2, "Address", 2)="UK" ^Customer(2, "DateOfRegistration")="7 May 2010"

^Customer(3)="Jane Smith" ^Customer(3, "Address", 1)="Oxford" ^Customer(3, "Address", 2)="UK" ^Customer(3, "DateOfRegistration")="9 June 2010"

4.2 close()The close() method will gracefully close a previously opened database. See “Opening and Closing the Caché Database”for a detailed description of how to open and close the database.

Synchronous

mydata.close();

Asynchronous

mydata.close(callback_function);

Parameters

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.close( function(error, result) { // callback code } );

4.3 data()The data() method tests for the existence of a global node.

This method will return one of the following numeric values:

• 0 — Node does not exist.

18                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

• 1 — Node has data but no subnodes.

• 10 — Node does not have data but has subnodes.

• 11 — Node has data and has subnodes.

Synchronous

var result = mydata.data(node);

Asynchronous

mydata.data(node, callback_function);

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.data( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{defined: 11}

4.4 function()The function() method provides a way to invoke a Caché function directly.

Synchronous

var result = mydata.function( Cache_Function_Name, Arguments ... );

Asynchronous

var result = mydata.function( { Cache_Function_Name, Arguments ... }, callback_function );

Parameters

• Cache_Function_Name

• Arguments

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Using Node.js with Caché                                                                                                                                                     19

function()

The following examples will be based on calls to the following Caché function:

Math ; Math Functions ; Add(X,Y) ; Add two numbers Quit (X * Y) ; Multiply(X,Y) ; Add two numbers Quit (X * Y) ;

This is a simple Caché ‘routine’ file called ‘Math" containing functions to perform basic mathematical functions ("Add"and "Multiply").

Example 1 (Synchronous/Non-JSON)

result = mydata.function("Add^Math", 3, 4);

Result:

7

Example 2: (Synchronous/JSON)

result = mydata.function({function: "Add^Math", arguments: [3, 4]});

Result:

{ "function": "Add^Math", "arguments": [3, 4], "result": 7 }

Example 3: (Asynchronous/JSON)

mydata.function( {function: "Add^Math", arguments: [3, 4]}, function(error, result) { // callback code } );

Result:

{ "ok": 1, "function": " Add^Math ", "arguments": [3, 4], "result": 7 }

4.5 get()The get() method retrieves a global node.

Synchronous

var result = mydata.get(node);

Asynchronous

mydata.get(node, callback_function);

20                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (Synchronous)

result = mydata.get({global: "Customer", subscripts: [9]});

Result:

{global: "Customer", subscripts: [9], data: "", defined: 0}

Example 2 (Asynchronous)

mydata.get( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{global: "Customer", subscripts: [1], data: "Chris Munt", defined: 1}

Note that the ‘defined’ property is set to 1 if the global node is actually defined and set to 0 if it is not.

4.6 global_directory()The global_directory() method returns a list of globals held in the directory. The number of names returned can be controlledusing the range limiting properties ‘lo’, ‘hi’ and ‘max’ (see “Controlling the amount of data returned by retrieve operations”).

Synchronous

var result = mydata.global_directory(range);

Asynchronous

mydata.global_directory (range, callback_function);

Parameters

• range

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1: Obtain a list of all globals in the directory

mydata.global_directory( {}, function(error, result) { // callback code } );

Result:

If successful, an array containing all global names found will be returned.

Using Node.js with Caché                                                                                                                                                     21

global_directory()

Example 2: Obtain a list of all globals whose name begins with "Cust"

mydata. global_directory( {lo: "Cust", hi: "Cust~"}, function(error, result) { // callback code } );

Result:

If successful, an array containing all global names beginning with "Cust" will be returned.

4.7 increment()The increment() method adds 1 to the value of an integer in a global node.

This method provides an efficient way of uniquely assigning an (incremented) integer to a process without using locking.When called, the integer value held in the global is incremented and the new value returned to the calling program. Cachéwill guarantee that a unique number is assigned to multiple processes that may be accessing this function simultaneously.

Synchronous

var result = mydata.increment(node);

Asynchronous

mydata.increment (node, callback_function);

Parameters

• node — the global node that holds the value to be incremented.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.increment( {global: "Counter"}, function(error, result) { // callback code } );

Result:

If successful the integer value held in global "Counter" will be incremented and the new value returned as theresult.

4.8 kill()The kill() method deletes a global node.

Synchronous

var result = mydata.kill(node);

Asynchronous

mydata.kill(node, callback_function);

22                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.kill( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

4.9 lock()The lock() method locks global nodes for exclusive use by your program. The method can lock either an entire Global (forexample, ^Customer) or sub-sections of a Global (for example, ^Customer(1)).

To prevent deadlock situations, all global nodes that your code has locked should be unlocked before your program terminates(see unlock()).

Synchronous

var result = mydata.lock(node);

Asynchronous

mydata.lock(node, callback_function);

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.lock( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

4.10 merge()The merge method copies all or part of a global to another global.

Using Node.js with Caché                                                                                                                                                     23

lock()

Synchronous

var result = mydata.merge(to: {destination_node}, from: {source_node}};

Asynchronous

mydata.merge({to: {destination_node}, from: {source_node}}, callback_function);

Parameters

• source_node

• destination_node

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1: Copy a whole global

mydata.get( {to: {global: "CopyOfCustomer"}, from: {global: "Customer"}}, function(error, result) { // callback code } );

Result:

If successful, the whole of global "Customer" will be copied to "CopyOfCustomer".

Example 2: Copy a section of global

mydata.get( {to: {global: "Customer", subscripts: [7, "address"]}, from: {global: "Customer", subscripts: [1, "address"]}}, function(error, result) { // callback code } );

Result:

If successful, the subsection of global contained under "Customer(1,’address’)" will be copied to "Cus-tomer(7,’address’)".

4.11 next() or order()The next() method gets the next Global subscript.

Get the next value in the collating sequence for a particular level of subscript.

Synchronous

var result = mydata.order(node);

Asynchronous

mydata.order(node, callback_function);

Parameters

• node — the global node to be accessed.

24                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (Synchronous)

result = mydata.order({global: "Customer", subscripts: [""]},

Result:

{global: "Customer", subscripts: [1], result: "1"}}

Example 2 (Synchronous)

result = mydata.next({global: "Customer", subscripts: [3]},

Result:

{global: "Customer", subscripts: [""], result: ""}}

Example 3 (Asynchronous)

mydata.next( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{global: "Customer", subscripts: [2], result: "2"}}

Example 4 (Parse at the first level)

key = {global: "Customer", subscripts: [""]}; while ((key = user.next(key)).result != "") { console.log(JSON.stringify(key, null, '\t')) }

Result:

{global: "Customer", subscripts: [1], result: "1"}} {global: "Customer", subscripts: [2], result: "2"}} {global: "Customer", subscripts: [3], result: "3"}}

If there is no further subscript defined in the sequence then the result property will be returned as empty string("").

4.12 next_node()The next_node() method gets the next global node in the collating sequence regardless of the level of subscript.

Synchronous

var result = mydata.next_node(node);

Asynchronous

mydata.next_node(node, callback_function);

Parameters

• node — the global node to be accessed.

Using Node.js with Caché                                                                                                                                                     25

next_node()

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (Synchronous)

result = mydata.next_node({global: "Customer"},

Result:

{global: "Customer", subscripts: [1], data: "Chris Munt, defined: 1}}

Example 2 (Synchronous)

result = mydata.next_node({global: "Customer", subscripts: [3]},

Result:

{global: "Customer", defined: 0}}

Example 3 (Asynchronous)

mydata.next_node( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{ global: "Customer", subscripts: [1, "address"], data: "Banstead", defined: 1 }

Example 4 (Parse Global)

key = {global: "Customer"}; while ((key = user.next_node(key)).defined) { console.log(JSON.stringify(key, null, '\t')); }

Result:

{ global: "Customer", subscripts: [1], data: "Chris Munt", defined: 1 } { global: "Customer", subscripts: [1, "address"], data: "Banstead", defined: 1 } { global: "Customer", subscripts: [2], data: "Rob Tweed", defined: 1 } { global: "Customer", subscripts: [3], data: "Jane Smith", defined: 1 }

If there is no further node defined in the sequence then the defined property will be set to zero.

26                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

4.13 open()The open() method opens the specified Caché database. See “Opening and Closing the Caché Database” for a detaileddescription of how to open and close the database.

Synchronous

mydata.open(parameters);

Asynchronous

mydata.open(parameters, callback_function);

Parameters

• parameters — specifies the Caché database to be opened:

– parameters.path — Path to the ‘mgr’ directory of the target Caché installation.

– parameters.username — User name for access.

– parameters.password — Password for access.

– parameters.namespace — Target Caché namespace.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.open( { path:"/cache20102/mgr", username: "_SYSTEM", password: "SYS", namespace: "USER" }, function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

4.14 previous()The previous() method gets the previous Global subscript

Get the previous value in the collating sequence for a particular level of subscript.

Synchronous

var result = mydata.previous(node);

Asynchronous

mydata.previous(node, callback_function);

Using Node.js with Caché                                                                                                                                                     27

open()

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (Synchronous)

result = mydata.previous({global: "Customer", subscripts: [""]},

Result:

{global: "Customer", subscripts: [3], result: "3"}}

Example 2 (Synchronous)

result = mydata.previous({global: "Customer", subscripts: [2]},

Result:

{global: "Customer", subscripts: ["1"], result: "1"}}

Example 3 (Asynchronous)

mydata.previous( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{global: "Customer", subscripts: [""], result: ""}}

Example 4 (Parse at the first level)

key = {global: "Customer", subscripts: [""]}; while ((key = user.previous(key)).result != "") { console.log(JSON.stringify(key, null, '\t')) }

Result:

{global: "Customer", subscripts: [3], result: "3"}} {global: "Customer", subscripts: [2], result: "2"}} {global: "Customer", subscripts: [1], result: "1"}}

If there is no further subscript defined in the sequence then the result property will be returned as empty string("").

4.15 previous_node()The previous_node() method gets the previous global node

Get the previous whole global node in the collating sequence regardless of the level of subscript.

Synchronous

var result = mydata.previous(node);

28                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Asynchronous

mydata.previous(node, callback_function);

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (Synchronous)

result = mydata.previous_node({global: "Customer", subscripts: ["z"]},

Result:

{global: "Customer", subscripts: [3], data: "Jane Smith", defined: 1}}

Example 2 (Synchronous)

result = mydata.next_node({global: "Customer", subscripts: [2]},

Result:

{ global: "Customer", subscripts: [1, "address"], data: "Banstead", defined: 1 }

Example 3 (Asynchronous)

mydata.previous_node( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

{global: "Customer", defined: 0}}

Example 4 (Parse Global)

key = {global: "Customer", subscripts: ["z"]}; while ((key = user.previous_node(key)).defined) { console.log(JSON.stringify(key, null, '\t')); }

Result:

{ global: "Customer", subscripts: [3], data: "Jane Smith", defined: 1 } { global: "Customer", subscripts: [2], data: "Rob Tweed", defined: 1 } { global: "Customer", subscripts: [1, "address"], data: "Banstead", defined: 1 } {

Using Node.js with Caché                                                                                                                                                     29

previous_node()

global: "Customer", subscripts: [1], data: "Chris Munt", defined: 1 }

If there is no further node defined in the sequence then the defined property will be set to zero.

4.16 retrieve()• The retrieve(node, "list") method will return a list of subscript values that are defined directly beneath a

given level in the global.

• The retrieve(node, "array") method will return a list of subscript values together with their associated datavalues that are defined beneath a given level in the global. The method is recursive and will retrieve all global nodesdefined beneath a chosen level.

The result will be expressed as an array of global nodes, with each global node expressed as a single JSON object.

• The retrieve(node, "object") method will retrieve a structured data object defined beneath a given level ina global. This method provides a structured alternative to an array of global nodes.

The result will be expressed as a single JSON object.

Synchronous

var result = mydata.retrieve(node, type);

Asynchronous

mydata.retrieve(node, type, callback_function);

Parameters

• node — the global node to be accessed.

• type — a literal string specifying the type of data to be accessed. Options are:

– "list"

– "array"

– "object"

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (type = “list”): Retrieve a list of customer numbers

mydata.retrieve( {global: "Customer"}, "list", function(error, result) { // callback code } );

Result:

Three Customer records:

[1, 2, 3]

30                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Example 2 (type = “list”): Retrieve a list of address lines for a specific customer

mydata.retrieve( {global: "Customer", subscripts: [1, "address"]}, "list", function(error, result) { // callback code } );

Result:

Two lines in the address for customer number 1:

[1, 2]

Example 3 (type = “array”): Retrieve all data for a customer

mydata.retrieve( {global: "Customer", subscripts: [1]}, "array", function(error, result) { // callback code } );

Result:

[ { global: "Customer", subscripts: [1], data: "Chris Munt" } { global: "Customer", subscripts: [1, "Address", 1], data: "London" } { global: "Customer", subscripts: [1, "Address", 2], data: "UK" } { global: "Customer", subscripts: [1, "DateOfRegistration], data: "1 May 2010" } ]

Example 4 (type = “object”): Retrieve all data for a customer

Consider the following structured Caché global:

^Customer(1, "Name")="Chris Munt" ^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010"

In Node.js:

mydata.retrieve( {global: "Customer", subscripts: [1]}, "object", function(error, result) { // callback code } );

Result:

{ node: { global: "Customer", subscripts: [1] } object: { Name: "Chris Munt", Address: {"1": "London", "2": "UK"}, DateOfRegistration: "1 May 2010" } }

Using Node.js with Caché                                                                                                                                                     31

retrieve()

4.17 set()The set() method saves a global node.

Synchronous

var result = mydata.set(node);

Asynchronous

mydata.set(node, callback_function);

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example

mydata.set( {global: "Customer", subscripts: [1], data: "Chris Munt"}, function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

4.18 unlock()The unlock() method unlocks global nodes previously locked by your program (see lock()). The method can unlock eitheran entire Global (for example, ^Customer) or sub-sections of a Global (for example, ^Customer(1)).

To release all locks held by your program, call the unlock() method with no node argument. All locks held by a Node.jsprocess will be released when the process terminates normally.

Synchronous

var result = mydata.unlock(node); var result = mydata.unlock();

Asynchronous

mydata.unlock(node, callback_function); mydata.unlock(callback_function);

Parameters

• node — the global node to be accessed.

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

32                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Example 1: Unlock one node

mydata.unlock( {global: "Customer", subscripts: [1]}, function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

Example 2: Unlock all locked nodes

mydata.unlock( function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

4.19 update()The update() method writes the contents of a JSON object to the Caché database.

• The update("array") method performs the opposite task to that performed by the retrieve method. In other wordsthe update method takes an array of global nodes, each expressed as a single JSON object and writes them back to theCaché database.

• The update("object") method performs the opposite task to that performed by the retrieve method. In other wordsit writes the contents of a structured JSON object back to the Caché database.

Synchronous

var result = mydata.update(node, type);

Asynchronous

mydata.update(node, type, callback_function);

Parameters

• node — the global node to be accessed.

• type — a literal string specifying the type of data to be accessed. Options are:

– "array"

– "object"

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

Example 1 (type = “array”): Create or update a record for a customer

mydata.update( [ { global: "Customer", subscripts: [1], data: "Chris Munt" }

Using Node.js with Caché                                                                                                                                                     33

update()

{ global: "Customer", subscripts: [1, "Address", 1], data: "London" } { global: "Customer", subscripts: [1, "Address", 2], data: "UK" } { global: "Customer", subscripts: [1, "DateOfRegistration"], data: "1 May 2010" } ], "array", function(error, result) { // callback code } );

Result:

Operation successful if no error reported.

Example 2 (type = “object”): Create or update a record for a customer

mydata.update( node: { global: "Customer", subscripts: [1] }, Object: { Name: "Chris Munt", DateOfRegistration: "1 May 2010", Address: {"1": "London", "2": "UK"} }, "object", function(error, result) { // callback code } );

Result:

Operation successful if no error reported. If successful, the following set of global nodes will be created for thisexample:

^Customer(1, "Address", 1)="London" ^Customer(1, "Address", 2)="UK" ^Customer(1, "DateOfRegistration")="1 May 2010" ^Customer(1, "Name")="Chris Munt"

4.20 version() and about()The version() and about() methods return basic version information about the cache.node module in use and the associatedCaché database (if open).

Synchronous

var result = mydata.version(); var result = mydata.about();

Asynchronous

mydata.version(callback_function); mydata.about(callback_function);

Parameters

• callback_function — a function of the form function(error, result){} used to return resultsasynchronously (see “Synchronous vs. Asynchronous cache.node Methods” ).

34                                                                                                                                                     Using Node.js with Caché

Reference for cache.node Methods

Example

mydata.version( function(error, result) { // callback code } );

Result:

If the Caché database is not open:

Node.js Adaptor for Cache: Version: 1.0.17 (CM)

If the Caché database is open:

Node.js Adaptor for Cache: Version: 1.0.17 (CM); Caché Version: 2012 build 100

Using Node.js with Caché                                                                                                                                                     35

version() and about()

ABuilding cache.node from Source

The following development tools should be installed:

• C and C++ build environment.

• For Ubuntu:

– sudo apt-get install gcc

– sudo apt-get install g++

There are two methods for building the cache.node module from source:

• Using the Node.js Build Procedure — using the scripts provided by the Node.js community.

• Building Directly from Source — directly from the C++ source (cache.cpp).

A.1 Using the Node.js Build ProcedureThe cache.node module is built using the script provided by node-waf script provided by the Node.js group. The node-waf

scripts builds the cache.node module in accordance with instructions contained in a file called wscript.

.../build/default/

A.1.1 Creating the Build Script (wscript)

The script provided is as follows:

def set_options(opt): opt.tool_options("compiler_cxx")

def configure(conf): conf.check_tool("compiler_cxx") conf.check_tool("node_addon")

def build(bld): obj = bld.new_task_gen("cxx", "shlib", "node_addon") obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-I/cache20102/dev/cpp/include"] obj.linkflags = ["-Wl", "-lpthread", "-lrt", "-ldl", "-lc", "-lm"] obj.target = "cache" obj.source = "cache.cpp"

Using Node.js with Caché                                                                                                                                                     37

Create this text file and modify it to suite your own environment. There is just one path that will require modifying for yourlocal environment

• The compiler options line (obj.cxxflags):

"-I/cache20102/dev/cpp/include"

This must be the directory where the Caché C header files reside (For example: callin.h)

A.1.2 Build the cache.node Module

In the directory containing both the wscript file created previously and the source code (cache.cpp) use the node-wafcommand to build the module:

node-waf configure build

If successful, the output will look something like the following:

Setting srcdir to : /opt/cm/node042 Setting blddir to : /opt/cm/node042/build Checking for program g++ or c++ : /usr/bin/g++ Checking for program cpp : /usr/bin/cpp Checking for program ar : /usr/bin/ar Checking for program ranlib : /usr/bin/ranlib Checking for g++ : ok Checking for node path : not found Checking for node prefix : ok /opt/cm/node042 'configure' finished successfully (0.974s) Waf: Entering directory `/opt/cm/node042/build' [1/2] cxx: cache.cpp -> build/default/cache_1.o [2/2] cxx_link: build/default/cache_1.o -> build/default/cache.node Waf: Leaving directory `/opt/cm/node042/build' 'build' finished successfully (2.904s) root@ubuntu:/opt/cm/node042#

The Caché module will be created: cache.node

This module will, by default, be created in the following subdirectory:

.../build/default/

A.2 Building Directly from SourceAs an alternative to using the scripted infrastructure provided by the Node.js Group, the Caché module (cache.node) canbe built directly from the C++ source code as follows:

Linux:

g++ -c -g -fPIC -DPIC -DEV_MULTIPLICITY=0 –DLINUX \ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wall \ -I/opt/local/node/include/node -I/cache20102/dev/cpp/include \ -o cache.o cache.cpp

g++ -shared -L/opt/local/node/lib -Wl -lpthread -lrt -ldl -lc -lm \ -o cache.node cache.o

Note the three paths that will require modifying to suit your local environment.

• Path to the Node.js C/C++ header files. For example:

/opt/local/node/include/node

• Path to the Caché C/C++ header files. For example:

/cache20102/dev/cpp/include

38                                                                                                                                                     Using Node.js with Caché

Building cache.node from Source

• Path to the Node.js library files. For example:

/opt/local/node/lib

Using Node.js with Caché                                                                                                                                                     39

Building Directly from Source


Recommended