Más contenido relacionado La actualidad más candente (20) Similar a EWD 3 Training Course Part 19: The cache.node APIs (20) EWD 3 Training Course Part 19: The cache.node APIs1. Copyright © 2016 M/Gateway Developments Ltd
EWD 3 Training Course
Part 19
Accessing a Global Storage
Database from JavaScript: the
cache.node APIs
Rob Tweed
Director, M/Gateway Developments Ltd
Twitter: @rtweed
2. Copyright © 2016 M/Gateway Developments Ltd
cache.node
• The cache.node interface module allows
you to access a Caché database from
JavaScript
3. Copyright © 2016 M/Gateway Developments Ltd
NodeM
• The NodeM module is an Open Source
emulation of cache.node, allowing the
GT.M database to be accessed identically
from JavaScript
– https://github.com/dlwicksell/nodem
4. Copyright © 2016 M/Gateway Developments Ltd
ewd-redis-globals
• The Redis-based ewd-redis-globals
implementation of Global Storage includes
an implementation of the cache.node
APIs, allowing the database to be
accessed identically from JavaScript
– https://github.com/robtweed/ewd-redis-globals
5. Copyright © 2016 M/Gateway Developments Ltd
cache.node, NodeM &
ewd-redis-globals APIs
When accessed in a QEWD
application:
this.db.{{someFunctioName}}()
6. Copyright © 2016 M/Gateway Developments Ltd
Loading and Initialising the
Interface Modules
These steps are done for you
automatically by QEWD
Here’s how to do it manually, eg
if you're creating a standalone
test-harness…
7. Copyright © 2016 M/Gateway Developments Ltd
cache.node APIs
Loading cache.node:
var interface = require('cache');
var db = new interface.Cache();
8. Copyright © 2016 M/Gateway Developments Ltd
cache.node APIs
Opening connection to Caché :
db.open({
path: '/opt/cache/mgr',
username: '_SYSTEM',
password: 'SYS',
namespace: 'USER',
charset: 'UTF-8',
lock: 0
});
9. Copyright © 2016 M/Gateway Developments Ltd
cache.node APIs
Closing connection to Caché:
var ok = db.close();
10. Copyright © 2016 M/Gateway Developments Ltd
NodeM (GT.M) APIs
Loading NodeM:
var interface = require('nodem');
var db = new interface.Gtm();
11. Copyright © 2016 M/Gateway Developments Ltd
NodeM APIs
Opening connection to GT.M:
db.open();
12. Copyright © 2016 M/Gateway Developments Ltd
NodeM APIs
Opening connection to GT.M:
db.open();
Thereafter, all APIs are identical to those used with cache.node
13. Copyright © 2016 M/Gateway Developments Ltd
NodeM APIs
Closing connection to GT.M:
var ok = db.close();
ie: Identical to cache.node
14. Copyright © 2016 M/Gateway Developments Ltd
ewd-redis-globals APIs
Loading ewd-redis-globals:
var interface = require('ewd-redis-globals');
var db = new interface();
15. Copyright © 2016 M/Gateway Developments Ltd
Opening connection to Redis / ewd-redis-globals:
db.open();
ewd-redis-globals APIs
16. Copyright © 2016 M/Gateway Developments Ltd
Thereafter, all APIs are identical to those used with cache.node
Opening connection to Redis / ewd-redis-globals:
db.open();
ewd-redis-globals APIs
17. Copyright © 2016 M/Gateway Developments Ltd
Closing connection to Redis / ewd-redis-globals:
var ok = db.close();
ie: Identical to cache.node
ewd-redis-globals APIs
18. Copyright © 2016 M/Gateway Developments Ltd
Setting up a test harness
• Ready to use example for Caché in
QEWD:
– C:qewdnode_modulesqewdexampletest.js
– Needs editing to match your Caché (or other
database) configuration
• Use previous slides for GT.M and Redis
19. Copyright © 2016 M/Gateway Developments Ltd
Edit test.js
var interface = require('cache');
var db = new interface.Cache();
console.log('db: ' + JSON.stringify(db));
// Change these parameters to match your GlobalsDB or Cache system:
var ok = db.open({
path: '/opt/cache/mgr',
username: '_SYSTEM',
password: 'SYS',
namespace: 'USER'
});
console.log('ok: ' + JSON.stringify(ok));
console.log(db.version());
var node = {
global: 'rob',
subscripts: [1],
data: 'hello'
};
db.set(node);
var result = db.get(node);
console.log(JSON.stringify(result));
db.close();
20. Copyright © 2016 M/Gateway Developments Ltd
Edit test.js
var interface = require('cache');
var db = new interface.Cache();
console.log('db: ' + JSON.stringify(db));
// Change these parameters to match your GlobalsDB or Cache system:
var ok = db.open({
path: 'C:InterSystemsCache2015-2mgr',
username: '_SYSTEM',
password: 'SYS',
namespace: 'USER'
});
console.log('ok: ' + JSON.stringify(ok));
console.log(db.version());
var node = {
global: 'rob',
subscripts: [1],
data: 'hello'
};
db.set(node);
var result = db.get(node);
console.log(JSON.stringify(result));
db.close();
21. Copyright © 2016 M/Gateway Developments Ltd
Save as C:qewdtest.js
var interface = require('cache');
var db = new interface.Cache();
console.log('db: ' + JSON.stringify(db));
// Change these parameters to match your GlobalsDB or Cache system:
var ok = db.open({
path: 'C:InterSystemsCache2015-2mgr',
username: '_SYSTEM',
password: 'SYS',
namespace: 'USER'
});
console.log('ok: ' + JSON.stringify(ok));
console.log(db.version());
var node = {
global: 'rob',
subscripts: [1],
data: 'hello'
};
db.set(node);
var result = db.get(node);
console.log(JSON.stringify(result));
db.close();
22. Copyright © 2016 M/Gateway Developments Ltd
Run it
cd qewd (or on Linux / Raspberry Pi: cd /qewd )
node test
23. Copyright © 2016 M/Gateway Developments Ltd
Run it
cd qewd
node test
db: {}
ok: {"ok":1,"result":1,"cache_pid":2960}
Node.js Adaptor for Cache: Version: 1.1.113 (CM); Cache Version: 2015.2 build 66
4
{"global":"rob","subscripts":[1],"data":"hello","ok":1,"defined":1}
24. Copyright © 2016 M/Gateway Developments Ltd
One difference between test harness
and QEWD
• Test harness: invoke cache.node APIs
using:
– db.xxx()
• In QEWD worker module, they are
accessed using:
– this.db.xxx()
25. Copyright © 2016 M/Gateway Developments Ltd
One difference between test harness
and QEWD
• Test harness: invoke cache.node APIs
using:
– db.xxx()
db.set(node);
var result = db.get(node);
console.log(JSON.stringify(result));
db.close();
26. Copyright © 2016 M/Gateway Developments Ltd
One difference between test harness
and QEWD
• In QEWD worker module:
– this.db.xxx()
• Note: QEWD opens the database automatically when a worker is
started, and closes it automatically when the worker is stopped
this.db.set(node);
var result = this.db.get(node);
console.log(JSON.stringify(result));
28. Copyright © 2016 M/Gateway Developments Ltd
Global Storage handling APIs
Accessing global nodes:
- set
- get
- delete (kill)
29. Copyright © 2016 M/Gateway Developments Ltd
Defining a Global Node:
var node = {
global: 'employee',
subscripts: [123456, 'name']
};
Global Storage handling APIs
30. Copyright © 2016 M/Gateway Developments Ltd
Defining a Global Node:
var node = {
global: 'employee',
subscripts: [123456, 'name']
};
employee(123456,"name")
Global Storage handling APIs
31. Copyright © 2016 M/Gateway Developments Ltd
Accessing global nodes:
- set
node.data = 'Rob Tweed';
this.db.set(node);
Global Storage handling APIs
32. Copyright © 2016 M/Gateway Developments Ltd
Accessing global nodes:
- get
var value = this.db.get(node).data;
Global Storage handling APIs
33. Copyright © 2016 M/Gateway Developments Ltd
Accessing global nodes:
- kill
this.db.kill(node);
Global Storage handling APIs
35. Copyright © 2016 M/Gateway Developments Ltd
Traversing global nodes:
- Iterate through subscripts
Global Storage handling APIs
36. Copyright © 2016 M/Gateway Developments Ltd
Traversing global nodes:
- Iterate through subscripts at a particular hierarchy level
myGlobal("a")=123
myGlobal("b","c1")="foo"
myGlobal("b","c2")="foo2"
myGlobal("d","e1","f1")="bar1"
myGlobal("d","e1","f2")="bar2"
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
myGlobal
"a" 123
"b"
"c2" "foo2"
"d"
"c1" "foo"
"e2"
"e1"
"f2" "bar2"
"f1" "bar1"
"f2" "bar2"
"f1" "bar1"
"f3" "bar3"
"a", "b", "d"
Global Storage handling APIs
37. Copyright © 2016 M/Gateway Developments Ltd
Traversing global nodes:
- Iterate through subscripts at a particular hierarchy level
myGlobal("a")=123
myGlobal("b","c1")="foo"
myGlobal("b","c2")="foo2"
myGlobal("d","e1","f1")="bar1"
myGlobal("d","e1","f2")="bar2"
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
myGlobal
"a" 123
"b"
"c2" "foo2"
"d"
"c1" "foo"
"e2"
"e1"
"f2" "bar2"
"f1" "bar1"
"f2" "bar2"
"f1" "bar1"
"f3" "bar3"
"e1", "e2"
Global Storage handling APIs
38. Copyright © 2016 M/Gateway Developments Ltd
Traversing global nodes:
- Iterate through subscripts at a particular hierarchy level
myGlobal("a")=123
myGlobal("b","c1")="foo"
myGlobal("b","c2")="foo2"
myGlobal("d","e1","f1")="bar1"
myGlobal("d","e1","f2")="bar2"
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
myGlobal
"a" 123
"b"
"c2" "foo2"
"d"
"c1" "foo"
"e2"
"e1"
"f2" "bar2"
"f1" "bar1"
"f2" "bar2"
"f1" "bar1"
"f3" "bar3"
"f1", "f2", "f3"
Global Storage handling APIs
39. Copyright © 2016 M/Gateway Developments Ltd
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
To achieve the following traversal:
40. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
41. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
"seed" value to start iterator
Empty string
Global Storage handling APIs
42. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
var subscript = this.db.order(node).result;
// 'f1'
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
43. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
var subscript = this.db.order(node).result;
// 'f1'
subscript = this.db.order(node).result;
// 'f2' myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
44. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
var subscript = this.db.order(node).result;
// 'f1'
subscript = this.db.order(node).result;
// 'f2'
subscript = this.db.order(node).result;
// 'f3'
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
45. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
var subscript = this.db.order(node).result;
// 'f1'
subscript = this.db.order(node).result;
// 'f2'
subscript = this.db.order(node).result;
// 'f3'
subscript = this.db.order(node).result;
// ''
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
46. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', 'f2' ]
};
var subscript = this.db.order(node).result;
// 'f3'
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f3"
"seed" value to start iterator
Start from f2
Global Storage handling APIs
47. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var subscript = this.db.order(node).result;
// 'f3'
node is now:
{
global: 'myGlobal',
subscripts: ['d', 'e2', 'f3' ]
};
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
Global Storage handling APIs
48. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', 'f2' ]
};
var subscript = this.db.order(node).result;
// 'f3'
subscript = this.db.order(node).result;
// '' myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
""
Global Storage handling APIs
Empty string means no further subscripts, so traversal is complete
49. Copyright © 2016 M/Gateway Developments Ltd
Traversing Global Node – generic loop:
var node = {
global: 'myGlobal',
subscripts: ['d', 'e2', '' ]
};
var subscript;
do {
subscript = this.db.order(node).result;
if (subscript !== '') console.log(subscript);
}
while (subscript !== '');
myGlobal("d","e2","f1")="bar1"
myGlobal("d","e2","f2")="bar2"
myGlobal("d","e2","f3")="bar3"
"f1", "f2", "f3"
Global Storage handling APIs
50. Copyright © 2016 M/Gateway Developments Ltd
The APIs are low-level
• Deliberately designed to provide the basic
means of access to Global Storage and nothing
more
• They assume you understand the mechanics of
Global Storage
• Too low-level for JavaScript development
– Traversal, in particular, requires a lot of code
• However, they can be abstracted to a more
JavaScript-centric point of view
– Which is the subject of the next part of this course