├── .travis.yml ├── .gitignore ├── test ├── test.config.js ├── test.xecute.map ├── test.xecute.coffee ├── test.kill.coffee ├── test.kill.map ├── test.xecute.js ├── test.getObject.map ├── test.getObject.coffee ├── test.kill.js ├── test.order.coffee ├── test.zn.coffee ├── test.getObject.js ├── test.order.js ├── test.zn.map ├── test.order.map ├── test.zn.js ├── test.get.coffee ├── test.get.map ├── test.get.js ├── test.set.coffee ├── test.set.map └── test.set.js ├── package.json ├── docs ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── lang-css.js │ │ ├── Apache-License-2.0.txt │ │ └── prettify.js ├── index.html ├── styles │ ├── prettify-jsdoc.css │ ├── prettify-tomorrow.css │ └── jsdoc-default.css ├── global.html └── boobst.js.html ├── .jscs.json ├── boobst.m ├── Readme.md └── boobst.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.8" 5 | - "0.6" 6 | 7 | notifications: 8 | email: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .idea/* 3 | .idea/**/* 4 | 5 | node_modules 6 | test/test.config.js 7 | test/test.zn.coffee 8 | test/test.zn.js 9 | test/test.zn.map -------------------------------------------------------------------------------- /test/test.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Andrew D.Laptev 3 | */ 4 | 5 | module.exports = { 6 | host: '91.239.143.153' 7 | , port: 6666 8 | , ns: 'USER' 9 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boobst", 3 | "version": "0.9.3", 4 | "author": "Andrew D.Laptev ", 5 | "description": "Simple Node.js Caché driver", 6 | "main": "./boobst", 7 | "scripts": { 8 | "test": "mocha" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/agsh/boobst.git" 13 | }, 14 | "keywords": [ 15 | "M", 16 | "MUMPS", 17 | "database", 18 | "hierarchical database", 19 | "databases", 20 | "NoSQL", 21 | "intersystems", 22 | "cache", 23 | "cache'", 24 | "driver" 25 | ], 26 | "license": "MIT", 27 | "engines": { 28 | "node": ">=0.6" 29 | }, 30 | "devDependencies": { 31 | "mocha": "^2.0.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (function() { 3 | var source = document.getElementsByClassName('prettyprint source linenums'); 4 | var i = 0; 5 | var lineNumber = 0; 6 | var lineId; 7 | var lines; 8 | var totalLines; 9 | var anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = 'line' + lineNumber; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /test/test.xecute.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.xecute.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.xecute.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AAAA;;;CAAA;;CAIA;CAJA;CAAA;CAAA;CAAA,KAAA,sBAAA;;CAAA,CAMA,CAAS,GAAT,CAAS,CAAA;;CANT,CAOA,CAAS,GAAT,CAAS,IAAA;;CAPT,CAQA,CAAe,GAAM,MAArB;;CARA,CAUA,CAAmB,KAAnB,CAAmB;CACjB,CAAA,MAAA;CAAA,GAAA,CAAA,EAAA;CAAA,CACA,CAAS,CAAT,GAAsB,KAAb,GAAa;CADtB,EAKW,CAAX,KAAY,CAAZ;CACK,CAAD,CAAS,IAAX,EAAY,IAAZ;CACE,EAAA,CAAa,IAAb;CAAA,EAAA,aAAM;UAAN;CACA,GAAA,WAAA;CAFF,MAAW;CADb,IAAW;CALX,EAUU,CAAV,KAAA;CACK,CAAD,CAAY,MAAA,CAAd,GAAA;CACE,GAAA,WAAA;CADF,MAAc;CADhB,IAAU;CAID,CAAoB,CAAA,KAA7B,CAA6B,EAA7B,OAAA;CACK,CAAH,CAAkD,CAAA,KAAC,IAAnD,gCAAA;CACK,CAAD,CAAyB,CAAA,EAA3B,GAA4B,MAA5B;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,IAAN;CAAA,CACA,EAAW,CAAQ,CAAb,CAAK,GAAX,EAAA;CACA,GAAA,aAAA;CAHF,QAA2B;CAD7B,MAAkD;CADpD,IAA6B;CAf/B,EAAmB;CAVnB" 10 | } -------------------------------------------------------------------------------- /test/test.xecute.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | assert = require 'assert' 8 | boobst = require '../boobst' 9 | BoobstSocket = boobst.BoobstSocket 10 | 11 | describe 'xecute', () -> 12 | this.timeout 15000 13 | bs = new BoobstSocket(require './test.config') 14 | 15 | #bs.on('debug', console.log); # uncomment for debug messages 16 | 17 | beforeEach (done) -> 18 | bs.connect (err) -> 19 | throw err if err 20 | done() 21 | 22 | afterEach (done) -> 23 | bs.disconnect () -> 24 | done() 25 | 26 | describe '#run hello world', () -> 27 | it 'should properly gave us hello or disallowed', (done) -> 28 | bs.xecute 'write "hello"', (err, data) -> 29 | assert.equal err, null 30 | assert.ok (data == 'hello' || data == 'disallowed') 31 | done() -------------------------------------------------------------------------------- /.jscs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requireCurlyBraces": [ "if", "else", "for", "while", "do", "try", "catch" ], 3 | "requireSpaceAfterKeywords": [ 4 | "do", 5 | "for", 6 | "if", 7 | "else", 8 | "switch", 9 | "case", 10 | "try", 11 | "void", 12 | "while", 13 | "with", 14 | "return", 15 | "typeof" 16 | ], 17 | "requireSpacesInFunctionExpression": { 18 | "beforeOpeningCurlyBrace": true 19 | }, 20 | "disallowSpacesInFunctionExpression": { 21 | "beforeOpeningRoundBrace": true 22 | }, 23 | "disallowSpacesInCallExpression": true, 24 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 25 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-"], 26 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 27 | "disallowKeywords": [ "with" ], 28 | "disallowKeywordsOnNewLine": [ "else" ], 29 | "disallowSpaceAfterObjectKeys": true, 30 | "validateLineBreaks": "LF", 31 | "disallowMixedSpacesAndTabs": true, 32 | "requireSpacesInConditionalExpression": { 33 | "afterTest": true, 34 | "beforeConsequent": true, 35 | "afterConsequent": true, 36 | "beforeAlternate": true 37 | } 38 | } -------------------------------------------------------------------------------- /test/test.kill.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | assert = require 'assert' 8 | boobst = require '../boobst' 9 | BoobstSocket = boobst.BoobstSocket 10 | 11 | GLOBAL = '^testKILL'; 12 | 13 | describe 'kill', () -> 14 | this.timeout 15000 15 | bs = new BoobstSocket(require './test.config') 16 | 17 | #bs.on('debug', console.log); # uncomment for debug messages 18 | 19 | beforeEach (done) -> 20 | bs.connect (err) -> 21 | throw err if err 22 | done() 23 | 24 | afterEach (done) -> 25 | bs.disconnect () -> 26 | done() 27 | 28 | describe '#get-set-get-kill-get', () -> 29 | value = 'hello' 30 | it 'should properly switch between namespaces', (done) -> 31 | bs.get GLOBAL, (err, data) -> 32 | assert.notEqual err, null 33 | bs.set GLOBAL, value, (err) -> 34 | assert.equal err, null 35 | bs.get GLOBAL, (err, data) -> 36 | assert.equal err, null 37 | assert.equal data, value 38 | bs.kill GLOBAL, (err) -> 39 | assert.equal err, null 40 | bs.get GLOBAL, (err) -> 41 | assert.notEqual err, null 42 | done() -------------------------------------------------------------------------------- /test/test.kill.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.kill.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.kill.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AAAA;;;CAAA;;CAIA;CAJA;CAAA;CAAA;CAAA,KAAA,8BAAA;;CAAA,CAMA,CAAS,GAAT,CAAS,CAAA;;CANT,CAOA,CAAS,GAAT,CAAS,IAAA;;CAPT,CAQA,CAAe,GAAM,MAArB;;CARA,CAUA,CAAS,GAAT,KAVA;;CAAA,CAYA,CAAiB,GAAjB,EAAA,CAAiB;CACf,CAAA,MAAA;CAAA,GAAA,CAAA,EAAA;CAAA,CACA,CAAS,CAAT,GAAsB,KAAb,GAAa;CADtB,EAKW,CAAX,KAAY,CAAZ;CACK,CAAD,CAAS,IAAX,EAAY,IAAZ;CACE,EAAA,CAAa,IAAb;CAAA,EAAA,aAAM;UAAN;CACA,GAAA,WAAA;CAFF,MAAW;CADb,IAAW;CALX,EAUU,CAAV,KAAA;CACK,CAAD,CAAY,MAAA,CAAd,GAAA;CACE,GAAA,WAAA;CADF,MAAc;CADhB,IAAU;CAID,CAAyB,CAAA,KAAlC,CAAkC,EAAlC,YAAA;CACE,IAAA,KAAA;CAAA,EAAQ,EAAR,CAAA,CAAA;CACG,CAAH,CAAgD,CAAA,KAAC,IAAjD,8BAAA;CACK,CAAD,CAAF,CAAe,EAAf,GAAgB,MAAhB;CACE,CAAqB,CAArB,CAAA,EAAM,EAAN,EAAA;CACG,CAAD,CAAF,EAAA,CAAA,GAAuB,QAAvB;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,MAAN;CACG,CAAD,CAAF,CAAe,EAAf,GAAgB,UAAhB;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,QAAN;CAAA,CACmB,EAAnB,CAAA,CAAM,QAAN;CACG,CAAD,CAAc,CAAhB,EAAA,GAAiB,YAAjB;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,UAAN;CACG,CAAD,CAAF,GAAA,GAAgB,cAAhB;CACE,CAAqB,CAArB,CAAA,EAAM,EAAN,UAAA;CACA,GAAA,qBAAA;CAFF,gBAAe;CAFjB,cAAgB;CAHlB,YAAe;CAFjB,UAAsB;CAFxB,QAAe;CADjB,MAAgD;CAFlD,IAAkC;CAfpC,EAAiB;CAZjB" 10 | } -------------------------------------------------------------------------------- /test/test.xecute.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | /* 3 | * @author Andrew D.Laptev 4 | */ 5 | 6 | 7 | /*global describe, beforeEach, afterEach, it*/ 8 | 9 | 10 | (function() { 11 | var BoobstSocket, assert, boobst; 12 | 13 | assert = require('assert'); 14 | 15 | boobst = require('../boobst'); 16 | 17 | BoobstSocket = boobst.BoobstSocket; 18 | 19 | describe('xecute', function() { 20 | var bs; 21 | this.timeout(15000); 22 | bs = new BoobstSocket(require('./test.config')); 23 | beforeEach(function(done) { 24 | return bs.connect(function(err) { 25 | if (err) { 26 | throw err; 27 | } 28 | return done(); 29 | }); 30 | }); 31 | afterEach(function(done) { 32 | return bs.disconnect(function() { 33 | return done(); 34 | }); 35 | }); 36 | return describe('#run hello world', function() { 37 | return it('should properly gave us hello or disallowed', function(done) { 38 | return bs.xecute('write "hello"', function(err, data) { 39 | assert.equal(err, null); 40 | data = data.toString(); 41 | assert.ok(data === 'hello' || data === 'disallowed'); 42 | return done(); 43 | }); 44 | }); 45 | }); 46 | }); 47 | 48 | }).call(this); 49 | 50 | /* 51 | //@ sourceMappingURL=test.xecute.map 52 | */ 53 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 55 | 56 |
57 | 58 |
59 | Documentation generated by JSDoc 3.4.0 on Wed Aug 03 2016 15:56:44 GMT+0300 (MSK) 60 |
61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/test.getObject.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.getObject.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.getObject.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AAAA;;;CAAA;;CAIA;CAJA;CAAA;CAAA;CAAA,KAAA,8BAAA;;CAAA,CAMA,CAAS,GAAT,CAAS,CAAA;;CANT,CAOA,CAAS,GAAT,CAAS,IAAA;;CAPT,CAQA,CAAe,GAAM,MAArB;;CARA,CAUA,CAAS,GAAT,OAVA;;CAAA,CAYA,CAAsB,KAAtB,CAAsB,EAAtB;CACE,CAAA,MAAA;CAAA,GAAA,GAAA;CAAA,CACA,CAAS,CAAT,GAAsB,KAAb,GAAa;CADtB,EAKW,CAAX,KAAY,CAAZ;CACK,CAAD,CAAS,IAAX,EAAY,IAAZ;CACE,EAAA,CAAa,IAAb;CAAA,EAAA,aAAM;UAAN;CACA,GAAA,WAAA;CAFF,MAAW;CADb,IAAW;CALX,EAUU,CAAV,KAAA;CACK,CAAD,CAAc,CAAhB,EAAA,GAAiB,IAAjB;CACK,CAAD,CAAY,MAAA,CAAd,KAAA;CACE,GAAA,aAAA;CADF,QAAc;CADhB,MAAgB;CADlB,IAAU;CAKD,CAAc,CAAA,KAAvB,CAAuB,EAAvB,CAAA;CACE,SAAA,OAAA;CAAA,EAAS,GAAT;CAAS,CACE,CAAA,CAAA,CAAA,EAAT,CAAA;CADO,CAGL,MADF;CACE,CAAK,CAAL,OAAA;CAAA,CACK,CAAL,OAAA;UAJK;CAAA,CAKI,EALJ,IAKP,CAAA;CALO,CAMG,MAAV;CANF,OAAA;CAAA,CAQkB,CAAN,GAAZ,GAAA;CARA,CAUA,CAAiC,CAAA,EAAjC,GAAkC,mBAAlC;CACK,CAAD,CAAF,GAAA,GAA4B,MAA5B;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,IAAN;CACG,CAAD,CAAF,CAAmB,EAAnB,GAAoB,QAApB;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,MAAN;CAAA,CACmC,EAAd,CAAJ,CAAX,GAAN,GAAA;CACA,GAAA,eAAA;CAHF,UAAmB;CAFrB,QAA2B;CAD7B,MAAiC;CAQ9B,CAAH,CAAiD,CAAA,KAAC,IAAlD,+BAAA;CACK,CAAD,CAAF,GAAA,GAAA,MAAA;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,IAAN;CACG,CAAD,CAAF,CAA0B,EAA1B,GAAA,QAAA;CACE,CAAkB,CAAlB,CAAA,CAAA,CAAM,MAAN;CAAA,CACmC,EAAd,CAAJ,CAAX,GAAN,GAAA;CACA,GAAA,eAAA;CAHF,UAA0B;CAF5B,QAAkC;CADpC,MAAiD;CAnBnD,IAAuB;CAhBzB,EAAsB;CAZtB" 10 | } -------------------------------------------------------------------------------- /test/test.getObject.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | assert = require 'assert' 8 | boobst = require '../boobst' 9 | BoobstSocket = boobst.BoobstSocket 10 | 11 | GLOBAL = '^testObject'; 12 | 13 | describe 'getObject', () -> 14 | this.timeout 1000 15 | bs = new BoobstSocket(require './test.config') 16 | 17 | #bs.on('debug', console.log); # uncomment for debug messages 18 | 19 | beforeEach (done) -> 20 | bs.connect (err) -> 21 | throw err if err 22 | done() 23 | 24 | afterEach (done) -> 25 | bs.kill GLOBAL, (err) -> 26 | bs.disconnect () -> 27 | done() 28 | 29 | describe '#getObject', () -> 30 | object = { 31 | "array": ["a", "ab", "abc"] 32 | "object": 33 | "a": "a" 34 | "b": 2 35 | "boolean": true 36 | "number": 42 37 | } 38 | subscript = ['a', 'b'] 39 | 40 | it 'should return saved object', (done) -> 41 | bs.set GLOBAL, [], object, (err) -> 42 | assert.equal err, null 43 | bs.get GLOBAL, [], (err, data) -> 44 | assert.equal err, null 45 | assert.deepEqual JSON.parse(data), object 46 | done() 47 | 48 | it 'should return saved object with subscripts', (done) -> 49 | bs.set GLOBAL, subscript, object, (err) -> 50 | assert.equal err, null 51 | bs.get GLOBAL, subscript, (err, data) -> 52 | assert.equal err, null 53 | assert.deepEqual JSON.parse(data), object 54 | done() -------------------------------------------------------------------------------- /test/test.kill.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | /* 3 | * @author Andrew D.Laptev 4 | */ 5 | 6 | 7 | /*global describe, beforeEach, afterEach, it*/ 8 | 9 | 10 | (function() { 11 | var BoobstSocket, GLOBAL, assert, boobst; 12 | 13 | assert = require('assert'); 14 | 15 | boobst = require('../boobst'); 16 | 17 | BoobstSocket = boobst.BoobstSocket; 18 | 19 | GLOBAL = '^testKILL'; 20 | 21 | describe('kill', function() { 22 | var bs; 23 | this.timeout(15000); 24 | bs = new BoobstSocket(require('./test.config')); 25 | beforeEach(function(done) { 26 | return bs.connect(function(err) { 27 | if (err) { 28 | throw err; 29 | } 30 | return done(); 31 | }); 32 | }); 33 | afterEach(function(done) { 34 | return bs.disconnect(function() { 35 | return done(); 36 | }); 37 | }); 38 | return describe('#get-set-get-kill-get', function() { 39 | var value; 40 | value = 'hello'; 41 | return it('should properly switch between namespaces', function(done) { 42 | return bs.get(GLOBAL, function(err, data) { 43 | assert.notEqual(err, null); 44 | return bs.set(GLOBAL, value, function(err) { 45 | assert.equal(err, null); 46 | return bs.get(GLOBAL, function(err, data) { 47 | assert.equal(err, null); 48 | assert.equal(data, value); 49 | return bs.kill(GLOBAL, function(err) { 50 | assert.equal(err, null); 51 | return bs.get(GLOBAL, function(err) { 52 | assert.notEqual(err, null); 53 | return done(); 54 | }); 55 | }); 56 | }); 57 | }); 58 | }); 59 | }); 60 | }); 61 | }); 62 | 63 | }).call(this); 64 | 65 | /* 66 | //@ sourceMappingURL=test.kill.map 67 | */ 68 | -------------------------------------------------------------------------------- /test/test.order.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | assert = require 'assert' 8 | boobst = require '../boobst' 9 | BoobstSocket = boobst.BoobstSocket 10 | 11 | GLOBAL = '^test1'; 12 | 13 | describe 'order', () -> 14 | this.timeout 15000 15 | bs = new BoobstSocket(require './test.config') 16 | 17 | # bs.on('debug', console.log); # uncomment for debug messages 18 | 19 | beforeEach (done) -> 20 | bs.connect (err) -> 21 | if err 22 | throw err 23 | this.set GLOBAL, [1, 'city'], 'Moscow' 24 | this.set GLOBAL, [2, 'city'], 'London' 25 | this.set GLOBAL, [3, 'city'], 'Paris' 26 | this.set GLOBAL, [4, 'city'], 'Detroit' 27 | this.set GLOBAL, [5, 'city'], 'Ottawa', () -> 28 | done() 29 | 30 | afterEach (done) -> 31 | bs.kill GLOBAL, () -> 32 | bs.disconnect () -> 33 | done() 34 | 35 | describe '#order test an empty string', () -> 36 | it 'should return first key', (done) -> 37 | bs.order GLOBAL, [''], (err, data) -> 38 | assert.equal err, null 39 | assert.equal data, '1' 40 | done() 41 | 42 | describe '#next method should work as order', () -> 43 | it 'should return first key', (done) -> 44 | bs.next GLOBAL, [''], (err, data) -> 45 | assert.equal err, null 46 | assert.equal data, '1' 47 | done() 48 | 49 | describe '#order test a first key', () -> 50 | it 'should return second key', (done) -> 51 | bs.order GLOBAL, ['1'], (err, data) -> 52 | assert.equal err, null 53 | assert.equal data, '2' 54 | done() 55 | 56 | describe '#order test last key', () -> 57 | it 'should return empty string', (done) -> 58 | bs.order GLOBAL, ['5'], (err, data) -> 59 | assert.equal err, null 60 | assert.equal data, '' 61 | done() -------------------------------------------------------------------------------- /test/test.zn.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | assert = require 'assert' 8 | boobst = require '../boobst' 9 | BoobstSocket = boobst.BoobstSocket 10 | 11 | NAMESPACES = ['SOLP', 'SOULP'] 12 | GLOBAL = '^testZN'; 13 | 14 | describe 'zn', () -> 15 | this.timeout 15000 16 | bs = new BoobstSocket(require './test.config') 17 | 18 | #bs.on('debug', console.log); # uncomment for debug messages 19 | 20 | beforeEach (done) -> 21 | bs.connect (err) -> 22 | throw err if err 23 | done() 24 | 25 | afterEach (done) -> 26 | bs.disconnect () -> 27 | done() 28 | 29 | describe '#zn test simple switching', () -> 30 | it 'should properly switch between namespaces', (done) -> 31 | counter = 0 32 | NAMESPACES.forEach (ns) -> 33 | counter += 1 34 | bs.zn ns, (err, success) -> 35 | assert.equal err, null 36 | assert.equal success, true 37 | assert.equal ns, bs.ns 38 | counter -= 1 39 | done() if counter == 0 40 | 41 | describe '#zn switching with temporary global sets', () -> 42 | it 'should properly switch between namespaces', (done) -> 43 | NAMESPACES.forEach (ns) -> 44 | bs.zn ns 45 | bs.set GLOBAL, ns 46 | counter = 0 47 | NAMESPACES.forEach (ns) -> 48 | counter += 1 49 | bs.zn ns, (err,success) -> 50 | assert.equal err, null 51 | assert.equal success, true 52 | assert.equal ns, bs.ns 53 | bs.get GLOBAL, (err, data) -> 54 | assert.equal err, null 55 | assert.equal data, bs.ns 56 | counter -= 1 57 | if counter == 0 58 | counter = 0 59 | NAMESPACES.forEach (ns) -> 60 | counter += 1 61 | bs.zn ns 62 | bs.kill GLOBAL, (err) -> 63 | assert.equal err, null 64 | counter -= 1 65 | if counter == 0 66 | done() 67 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /test/test.getObject.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | /* 3 | * @author Andrew D.Laptev 4 | */ 5 | 6 | 7 | /*global describe, beforeEach, afterEach, it*/ 8 | 9 | 10 | (function() { 11 | var BoobstSocket, GLOBAL, assert, boobst; 12 | 13 | assert = require('assert'); 14 | 15 | boobst = require('../boobst'); 16 | 17 | BoobstSocket = boobst.BoobstSocket; 18 | 19 | GLOBAL = '^testObject'; 20 | 21 | describe('getObject', function() { 22 | var bs; 23 | this.timeout(1000); 24 | bs = new BoobstSocket(require('./test.config')); 25 | beforeEach(function(done) { 26 | return bs.connect(function(err) { 27 | if (err) { 28 | throw err; 29 | } 30 | return done(); 31 | }); 32 | }); 33 | afterEach(function(done) { 34 | return bs.kill(GLOBAL, function(err) { 35 | return bs.disconnect(function() { 36 | return done(); 37 | }); 38 | }); 39 | }); 40 | return describe('#getObject', function() { 41 | var object, subscript; 42 | object = { 43 | "array": ["a", "ab", "abc"], 44 | "object": { 45 | "a": "a", 46 | "b": 2 47 | }, 48 | "boolean": true, 49 | "number": 42 50 | }; 51 | subscript = ['a', 'b']; 52 | it('should return saved object', function(done) { 53 | return bs.set(GLOBAL, [], object, function(err) { 54 | assert.equal(err, null); 55 | return bs.get(GLOBAL, [], function(err, data) { 56 | assert.equal(err, null); 57 | assert.deepEqual(JSON.parse(data), object); 58 | return done(); 59 | }); 60 | }); 61 | }); 62 | return it('should return saved object with subscripts', function(done) { 63 | return bs.set(GLOBAL, subscript, object, function(err) { 64 | assert.equal(err, null); 65 | return bs.get(GLOBAL, subscript, function(err, data) { 66 | assert.equal(err, null); 67 | assert.deepEqual(JSON.parse(data), object); 68 | return done(); 69 | }); 70 | }); 71 | }); 72 | }); 73 | }); 74 | 75 | }).call(this); 76 | 77 | /* 78 | //@ sourceMappingURL=test.getObject.map 79 | */ 80 | -------------------------------------------------------------------------------- /test/test.order.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | 3 | /* 4 | * @author Andrew D.Laptev 5 | */ 6 | 7 | 8 | /*global describe, beforeEach, afterEach, it */ 9 | 10 | (function() { 11 | var BoobstSocket, GLOBAL, assert, boobst; 12 | 13 | assert = require('assert'); 14 | 15 | boobst = require('../boobst'); 16 | 17 | BoobstSocket = boobst.BoobstSocket; 18 | 19 | GLOBAL = '^test1'; 20 | 21 | describe('order', function() { 22 | var bs; 23 | this.timeout(15000); 24 | bs = new BoobstSocket(require('./test.config')); 25 | beforeEach(function(done) { 26 | return bs.connect(function(err) { 27 | if (err) { 28 | throw err; 29 | } 30 | this.set(GLOBAL, [1, 'city'], 'Moscow'); 31 | this.set(GLOBAL, [2, 'city'], 'London'); 32 | this.set(GLOBAL, [3, 'city'], 'Paris'); 33 | this.set(GLOBAL, [4, 'city'], 'Detroit'); 34 | return this.set(GLOBAL, [5, 'city'], 'Ottawa', function() { 35 | return done(); 36 | }); 37 | }); 38 | }); 39 | afterEach(function(done) { 40 | return bs.kill(GLOBAL, function() { 41 | return bs.disconnect(function() { 42 | return done(); 43 | }); 44 | }); 45 | }); 46 | describe('#order test an empty string', function() { 47 | return it('should return first key', function(done) { 48 | return bs.order(GLOBAL, [''], function(err, data) { 49 | assert.equal(err, null); 50 | assert.equal(data, '1'); 51 | return done(); 52 | }); 53 | }); 54 | }); 55 | describe('#next method should work as order', function() { 56 | return it('should return first key', function(done) { 57 | return bs.next(GLOBAL, [''], function(err, data) { 58 | assert.equal(err, null); 59 | assert.equal(data, '1'); 60 | return done(); 61 | }); 62 | }); 63 | }); 64 | describe('#order test a first key', function() { 65 | return it('should return second key', function(done) { 66 | return bs.order(GLOBAL, ['1'], function(err, data) { 67 | assert.equal(err, null); 68 | assert.equal(data, '2'); 69 | return done(); 70 | }); 71 | }); 72 | }); 73 | return describe('#order test last key', function() { 74 | return it('should return empty string', function(done) { 75 | return bs.order(GLOBAL, ['5'], function(err, data) { 76 | assert.equal(err, null); 77 | assert.equal(data, ''); 78 | return done(); 79 | }); 80 | }); 81 | }); 82 | }); 83 | 84 | }).call(this); 85 | 86 | //# sourceMappingURL=test.order.map 87 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /test/test.zn.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.zn.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.zn.coffee" 7 | ], 8 | "names": [], 9 | "mappings": "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" 10 | } -------------------------------------------------------------------------------- /test/test.order.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.order.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.order.coffee" 7 | ], 8 | "names": [], 9 | "mappings": "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" 10 | } -------------------------------------------------------------------------------- /test/test.zn.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | 3 | /* 4 | * @author Andrew D.Laptev 5 | */ 6 | 7 | 8 | /*global describe, beforeEach, afterEach, it */ 9 | 10 | (function() { 11 | var BoobstSocket, GLOBAL, NAMESPACES, assert, boobst; 12 | 13 | assert = require('assert'); 14 | 15 | boobst = require('../boobst'); 16 | 17 | BoobstSocket = boobst.BoobstSocket; 18 | 19 | NAMESPACES = ['SOLP', 'SOULP']; 20 | 21 | GLOBAL = '^testZN'; 22 | 23 | describe('zn', function() { 24 | var bs; 25 | this.timeout(15000); 26 | bs = new BoobstSocket(require('./test.config')); 27 | beforeEach(function(done) { 28 | return bs.connect(function(err) { 29 | if (err) { 30 | throw err; 31 | } 32 | return done(); 33 | }); 34 | }); 35 | afterEach(function(done) { 36 | return bs.disconnect(function() { 37 | return done(); 38 | }); 39 | }); 40 | describe('#zn test simple switching', function() { 41 | return it('should properly switch between namespaces', function(done) { 42 | var counter; 43 | counter = 0; 44 | return NAMESPACES.forEach(function(ns) { 45 | counter += 1; 46 | return bs.zn(ns, function(err, success) { 47 | assert.equal(err, null); 48 | assert.equal(success, true); 49 | assert.equal(ns, bs.ns); 50 | counter -= 1; 51 | if (counter === 0) { 52 | return done(); 53 | } 54 | }); 55 | }); 56 | }); 57 | }); 58 | return describe('#zn switching with temporary global sets', function() { 59 | return it('should properly switch between namespaces', function(done) { 60 | var counter; 61 | NAMESPACES.forEach(function(ns) { 62 | bs.zn(ns); 63 | return bs.set(GLOBAL, ns); 64 | }); 65 | counter = 0; 66 | return NAMESPACES.forEach(function(ns) { 67 | counter += 1; 68 | return bs.zn(ns, function(err, success) { 69 | assert.equal(err, null); 70 | assert.equal(success, true); 71 | assert.equal(ns, bs.ns); 72 | return bs.get(GLOBAL, function(err, data) { 73 | assert.equal(err, null); 74 | assert.equal(data, bs.ns); 75 | counter -= 1; 76 | if (counter === 0) { 77 | counter = 0; 78 | return NAMESPACES.forEach(function(ns) { 79 | counter += 1; 80 | bs.zn(ns); 81 | return bs.kill(GLOBAL, function(err) { 82 | assert.equal(err, null); 83 | counter -= 1; 84 | if (counter === 0) { 85 | return done(); 86 | } 87 | }); 88 | }); 89 | } 90 | }); 91 | }); 92 | }); 93 | }); 94 | }); 95 | }); 96 | 97 | }).call(this); 98 | 99 | //# sourceMappingURL=test.zn.map 100 | -------------------------------------------------------------------------------- /test/test.get.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * @author Andrew D.Laptev 3 | ### 4 | 5 | ###global describe, beforeEach, afterEach, it### 6 | 7 | 'use strict' 8 | 9 | assert = require 'assert' 10 | boobst = require '../boobst' 11 | BoobstSocket = boobst.BoobstSocket 12 | 13 | GLOBAL = '^testObject'; 14 | 15 | describe 'get', () -> 16 | this.timeout 1000 17 | bs = new BoobstSocket(require './test.config') 18 | 19 | # bs.on('debug', console.log); # uncomment for debug messages 20 | 21 | beforeEach (done) -> 22 | bs.connect (err) -> 23 | throw err if err 24 | bs.kill GLOBAL, (err) -> 25 | throw err if err 26 | done() 27 | 28 | afterEach (done) -> 29 | bs.kill GLOBAL, (err) -> 30 | throw err if err 31 | bs.disconnect () -> 32 | done() 33 | 34 | describe '#get', () -> 35 | object = { 36 | "array": ["a", "ab", "a\"bc"] 37 | "object": 38 | "a": "a" 39 | "b": 2 40 | "boolean": true 41 | "number": 42 42 | "quotes": 'some"thing' 43 | } 44 | subscript = ['a', 'b'] 45 | nodeData = 'node data' 46 | 47 | fulfill = (nd, callback, sub) -> 48 | bs.set GLOBAL, sub or [], object, (err) -> 49 | assert.equal err, null 50 | if nd 51 | bs.set GLOBAL, sub or [], nodeData, (err) -> 52 | assert.equal err, null 53 | callback() 54 | else 55 | callback() 56 | 57 | it 'sould return error if we don\'t have data in global', (done) -> 58 | bs.get GLOBAL, [], (err, data) -> 59 | assert.notEqual err, null 60 | assert.equal data, undefined 61 | done() 62 | 63 | it 'should return node data if we have $data(node)=11', (done) -> 64 | fulfill true, () -> 65 | bs.get GLOBAL, [], (err, data) -> 66 | assert.equal err, null 67 | assert.equal data, nodeData 68 | fulfill true, () -> 69 | bs.get GLOBAL, (err, data) -> 70 | assert.equal err, null 71 | assert.equal data, nodeData 72 | done() 73 | 74 | it 'should return json if we have $data(node)=10', (done) -> 75 | fulfill false, () -> 76 | bs.get GLOBAL, [], (err, data) -> 77 | assert.equal err, null 78 | assert.deepEqual JSON.parse(data), object 79 | fulfill false, () -> 80 | bs.get GLOBAL, (err, data) -> 81 | assert.equal err, null 82 | assert.deepEqual JSON.parse(data), object 83 | done() 84 | 85 | it 'should return json if we have forceJSON flag and $data(node)=11', (done) -> 86 | fulfill true, () -> 87 | bs.get GLOBAL, [], true, (err, data) -> 88 | assert.equal err, null 89 | assert.deepEqual JSON.parse(data), object 90 | fulfill true, () -> 91 | bs.get GLOBAL, [], true, (err, data) -> 92 | assert.equal err, null 93 | assert.deepEqual JSON.parse(data), object 94 | done() 95 | 96 | 97 | it '(with subscripts) should return node data if we have $data(node)=11', (done) -> 98 | fulfill true, () -> 99 | bs.get GLOBAL, subscript, (err, data) -> 100 | assert.equal err, null 101 | assert.equal data, nodeData 102 | done() 103 | , subscript 104 | 105 | it '(with subscripts) should return json if we have $data(node)=10', (done) -> 106 | fulfill false, () -> 107 | bs.get GLOBAL, subscript, (err, data) -> 108 | assert.equal err, null 109 | assert.deepEqual JSON.parse(data), object 110 | done() 111 | , subscript 112 | 113 | it '(with subscripts) should return json if we have forceJSON flag and $data(node)=11', (done) -> 114 | fulfill true, () -> 115 | bs.get GLOBAL, subscript, true, (err, data) -> 116 | assert.equal err, null 117 | assert.deepEqual JSON.parse(data), object 118 | done() 119 | , subscript -------------------------------------------------------------------------------- /test/test.get.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.get.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.get.coffee" 7 | ], 8 | "names": [], 9 | "mappings": "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" 10 | } -------------------------------------------------------------------------------- /test/test.get.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | 3 | /* 4 | * @author Andrew D.Laptev 5 | */ 6 | 7 | 8 | /*global describe, beforeEach, afterEach, it */ 9 | 10 | (function() { 11 | 'use strict'; 12 | var BoobstSocket, GLOBAL, assert, boobst; 13 | 14 | assert = require('assert'); 15 | 16 | boobst = require('../boobst'); 17 | 18 | BoobstSocket = boobst.BoobstSocket; 19 | 20 | GLOBAL = '^testObject'; 21 | 22 | describe('get', function() { 23 | var bs; 24 | this.timeout(1000); 25 | bs = new BoobstSocket(require('./test.config')); 26 | beforeEach(function(done) { 27 | return bs.connect(function(err) { 28 | if (err) { 29 | throw err; 30 | } 31 | return done(); 32 | }); 33 | }); 34 | afterEach(function(done) { 35 | return bs.kill(GLOBAL, function(err) { 36 | if (err) { 37 | throw err; 38 | } 39 | return bs.disconnect(function() { 40 | return done(); 41 | }); 42 | }); 43 | }); 44 | return describe('#get', function() { 45 | var fulfill, nodeData, object, subscript; 46 | object = { 47 | "array": ["a", "ab", "a\"bc"], 48 | "object": { 49 | "a": "a", 50 | "b": 2 51 | }, 52 | "boolean": true, 53 | "number": 42, 54 | "quotes": 'some"thing' 55 | }; 56 | subscript = ['a', 'b']; 57 | nodeData = 'node data'; 58 | fulfill = function(nd, callback, sub) { 59 | return bs.set(GLOBAL, sub || [], object, function(err) { 60 | assert.equal(err, null); 61 | if (nd) { 62 | return bs.set(GLOBAL, sub || [], nodeData, function(err) { 63 | assert.equal(err, null); 64 | return callback(); 65 | }); 66 | } else { 67 | return callback(); 68 | } 69 | }); 70 | }; 71 | it('sould return error if we don\'t have data in global', function(done) { 72 | return bs.get(GLOBAL, [], function(err, data) { 73 | assert.notEqual(err, null); 74 | assert.equal(data, void 0); 75 | return done(); 76 | }); 77 | }); 78 | it('should return node data if we have $data(node)=11', function(done) { 79 | return fulfill(true, function() { 80 | return bs.get(GLOBAL, [], function(err, data) { 81 | assert.equal(err, null); 82 | assert.equal(data, nodeData); 83 | return fulfill(true, function() { 84 | return bs.get(GLOBAL, function(err, data) { 85 | assert.equal(err, null); 86 | assert.equal(data, nodeData); 87 | return done(); 88 | }); 89 | }); 90 | }); 91 | }); 92 | }); 93 | it('should return json if we have $data(node)=10', function(done) { 94 | return fulfill(false, function() { 95 | return bs.get(GLOBAL, [], function(err, data) { 96 | assert.equal(err, null); 97 | assert.deepEqual(JSON.parse(data), object); 98 | return fulfill(false, function() { 99 | return bs.get(GLOBAL, function(err, data) { 100 | assert.equal(err, null); 101 | assert.deepEqual(JSON.parse(data), object); 102 | return done(); 103 | }); 104 | }); 105 | }); 106 | }); 107 | }); 108 | it('should return json if we have forceJSON flag and $data(node)=11', function(done) { 109 | return fulfill(true, function() { 110 | return bs.get(GLOBAL, [], true, function(err, data) { 111 | assert.equal(err, null); 112 | assert.deepEqual(JSON.parse(data), object); 113 | return fulfill(true, function() { 114 | return bs.get(GLOBAL, [], true, function(err, data) { 115 | assert.equal(err, null); 116 | assert.deepEqual(JSON.parse(data), object); 117 | return done(); 118 | }); 119 | }); 120 | }); 121 | }); 122 | }); 123 | it('(with subscripts) should return node data if we have $data(node)=11', function(done) { 124 | return fulfill(true, function() { 125 | return bs.get(GLOBAL, subscript, function(err, data) { 126 | assert.equal(err, null); 127 | assert.equal(data, nodeData); 128 | return done(); 129 | }); 130 | }, subscript); 131 | }); 132 | it('(with subscripts) should return json if we have $data(node)=10', function(done) { 133 | return fulfill(false, function() { 134 | return bs.get(GLOBAL, subscript, function(err, data) { 135 | assert.equal(err, null); 136 | assert.deepEqual(JSON.parse(data), object); 137 | return done(); 138 | }); 139 | }, subscript); 140 | }); 141 | return it('(with subscripts) should return json if we have forceJSON flag and $data(node)=11', function(done) { 142 | return fulfill(true, function() { 143 | return bs.get(GLOBAL, subscript, true, function(err, data) { 144 | assert.equal(err, null); 145 | assert.deepEqual(JSON.parse(data), object); 146 | return done(); 147 | }); 148 | }, subscript); 149 | }); 150 | }); 151 | }); 152 | 153 | }).call(this); 154 | 155 | //# sourceMappingURL=test.get.map 156 | -------------------------------------------------------------------------------- /test/test.set.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | assert = require 'assert' 4 | boobst = require '../boobst' 5 | BoobstSocket = boobst.BoobstSocket 6 | 7 | GLOBAL = '^testObject'; 8 | 9 | describe 'set', () -> 10 | this.timeout 1000 11 | bs = new BoobstSocket(require './test.config') 12 | 13 | # bs.on('debug', console.log); # uncomment for debug messages 14 | 15 | beforeEach (done) -> 16 | bs.connect (err) -> 17 | throw err if err 18 | done() 19 | 20 | afterEach (done) -> 21 | bs.kill GLOBAL, (err) -> 22 | throw err if err 23 | bs.disconnect () -> 24 | done() 25 | 26 | describe 'set primitives', () -> 27 | 28 | it 'should save numbers', (done) -> 29 | value = 5; 30 | bs.set GLOBAL, value 31 | .get GLOBAL, (err, data) -> 32 | assert.equal err, null 33 | assert.equal value, data 34 | done() 35 | 36 | it 'should save dates', (done) -> 37 | value = new Date() 38 | bs.set GLOBAL, value 39 | .get GLOBAL, (err, data) -> 40 | assert.equal err, null 41 | assert.equal value.toString(), new Date(data).toString() 42 | done() 43 | 44 | it 'should save strings', (done) -> 45 | value = 'string' 46 | bs.set GLOBAL, value 47 | .get GLOBAL, (err, data) -> 48 | assert.equal err, null 49 | assert.equal value, data 50 | done() 51 | 52 | it 'should save true boolean value', (done) -> 53 | bs.set GLOBAL, true 54 | .get GLOBAL, (err, data) -> 55 | assert.equal err, null 56 | assert.equal data, '1true' 57 | done() 58 | 59 | it 'should save false boolean value', (done) -> 60 | bs.set GLOBAL, false 61 | .get GLOBAL, (err, data) -> 62 | assert.equal err, null 63 | assert.equal data, '0false' 64 | done() 65 | 66 | it 'souldn\'t save null', (done) -> 67 | bs.set GLOBAL, null 68 | .get GLOBAL, (err) -> 69 | assert.notEqual err, null 70 | done() 71 | 72 | it 'souldn\'t save undefined', (done) -> 73 | bs.set GLOBAL, undefined 74 | .get GLOBAL, (err) -> 75 | assert.notEqual err, null 76 | done() 77 | 78 | describe 'set complex structures', () -> 79 | 80 | it 'should save array as an object', (done) -> 81 | value = [1, 2, 3] 82 | bs.set GLOBAL, value 83 | .get GLOBAL, (err, data) -> 84 | #console.log(data.toString()) 85 | assert.equal err, null 86 | assert.deepEqual JSON.parse(data.toString()), value 87 | done() 88 | 89 | it 'should save all nested values properly', (done) -> 90 | value = { 91 | number: 42 92 | boolean: true 93 | string: 'string' 94 | nested: { 95 | a: 1 96 | b: 'a' 97 | c: true 98 | } 99 | array: [1, 2, 3, { a: 1, b: '2' }] 100 | } 101 | bs.set GLOBAL, value 102 | .get GLOBAL, (err, data) -> 103 | assert.equal err, null 104 | assert.deepEqual JSON.parse(data.toString()), value 105 | done() 106 | 107 | it 'should save deep nested object properly', (done) -> 108 | value = { 109 | a: { 110 | b: { 111 | c: { 112 | d: { 113 | value: 'value' 114 | } 115 | } 116 | } 117 | } 118 | } 119 | bs.set GLOBAL, value 120 | .get GLOBAL, (err, data) -> 121 | #console.log(data.toString()) 122 | assert.equal err, null 123 | assert.deepEqual JSON.parse(data.toString()), value 124 | done() 125 | 126 | describe 'inline/callback set-get chaining', () -> 127 | value = 'VALUE' 128 | 129 | it 'should set a global without subscripts inline and then get it', (done) -> 130 | bs.set GLOBAL, value 131 | .get GLOBAL, (err, data) -> 132 | assert.equal err, null 133 | assert.equal value, data 134 | done(); 135 | 136 | it 'should set a global without subscripts with a callback and then get it', (done) -> 137 | bs.set GLOBAL, value, (err) -> 138 | assert.equal err, null 139 | bs.get GLOBAL, (err, data) -> 140 | assert.equal err, null 141 | assert.equal value, data 142 | done() 143 | 144 | it 'should set a global with subscripts inline and then get it', (done) -> 145 | bs.set GLOBAL, ['a', 1], value 146 | .get GLOBAL, ['a', 1], (err, data) -> 147 | assert.equal err, null 148 | assert.equal value, data 149 | done() 150 | 151 | it 'should set a global with subscripts with a callback and then get it', (done) -> 152 | bs.set GLOBAL, ['a', 1], value, (err) -> 153 | assert.equal err, null 154 | bs.get GLOBAL, ['a', 1], (err, data) -> 155 | assert.equal err, null 156 | assert.equal value, data 157 | done() 158 | 159 | describe 'different arguments in `set` method', () -> 160 | value = 'VALUE' 161 | array = ['a', 1] 162 | 163 | it 'works with two-arguments form', (done) -> 164 | bs.set GLOBAL, value 165 | .get GLOBAL, (err, data) -> 166 | assert.equal err, null 167 | assert.equal value, data 168 | done() 169 | 170 | it 'works with three-arguments form without callback', (done) -> 171 | bs.set GLOBAL, array, value 172 | .get GLOBAL, array, (err, data) -> 173 | assert.equal err, null 174 | assert.equal value, data 175 | done() 176 | 177 | it 'works with three-arguments form without callback even the value is array', (done) -> 178 | bs.set GLOBAL, array, array 179 | .get GLOBAL, array, (err, data) -> 180 | assert.equal err, null 181 | assert.deepEqual array, JSON.parse data.toString() 182 | done() 183 | 184 | it 'works with three-arguments form with callback even the value is array', (done) -> 185 | bs.set GLOBAL, array, (err) -> 186 | assert.equal err, null 187 | bs.get GLOBAL, (err, data) -> 188 | console.log err 189 | assert.equal err, null 190 | assert.deepEqual array, JSON.parse data.toString() 191 | done() 192 | 193 | it 'works with four-arguments form with callback even the value is array', (done) -> 194 | bs.set GLOBAL, array, array, (err) -> 195 | assert.equal err, null 196 | bs.get GLOBAL, array, (err, data) -> 197 | assert.equal err, null 198 | assert.deepEqual array, JSON.parse data.toString() 199 | done() 200 | 201 | describe 'setting large, binary and screening values', () -> 202 | it 'should save and restore screening values', (done) -> 203 | value = '"\\' 204 | bs.set GLOBAL, value 205 | .get GLOBAL, (err, data) -> 206 | assert.equal err, null 207 | assert.equal value, data 208 | done() 209 | 210 | ### 211 | describe '#set', () -> 212 | it 'shouldn\'t save function', (done) -> 213 | value = () -> 214 | bs.set GLOBAL, value 215 | .get GLOBAL, (err, data) -> 216 | assert.equal err, null 217 | assert.equal undefined, data 218 | done() 219 | 220 | ### -------------------------------------------------------------------------------- /docs/styles/jsdoc-default.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: normal; 4 | font-style: normal; 5 | src: url('../fonts/OpenSans-Regular-webfont.eot'); 6 | src: 7 | local('Open Sans'), 8 | local('OpenSans'), 9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), 10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), 11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); 12 | } 13 | 14 | @font-face { 15 | font-family: 'Open Sans Light'; 16 | font-weight: normal; 17 | font-style: normal; 18 | src: url('../fonts/OpenSans-Light-webfont.eot'); 19 | src: 20 | local('Open Sans Light'), 21 | local('OpenSans Light'), 22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), 23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'), 24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); 25 | } 26 | 27 | html 28 | { 29 | overflow: auto; 30 | background-color: #fff; 31 | font-size: 14px; 32 | } 33 | 34 | body 35 | { 36 | font-family: 'Open Sans', sans-serif; 37 | line-height: 1.5; 38 | color: #4d4e53; 39 | background-color: white; 40 | } 41 | 42 | a, a:visited, a:active { 43 | color: #0095dd; 44 | text-decoration: none; 45 | } 46 | 47 | a:hover { 48 | text-decoration: underline; 49 | } 50 | 51 | header 52 | { 53 | display: block; 54 | padding: 0px 4px; 55 | } 56 | 57 | tt, code, kbd, samp { 58 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 59 | } 60 | 61 | .class-description { 62 | font-size: 130%; 63 | line-height: 140%; 64 | margin-bottom: 1em; 65 | margin-top: 1em; 66 | } 67 | 68 | .class-description:empty { 69 | margin: 0; 70 | } 71 | 72 | #main { 73 | float: left; 74 | width: 70%; 75 | } 76 | 77 | article dl { 78 | margin-bottom: 40px; 79 | } 80 | 81 | section 82 | { 83 | display: block; 84 | background-color: #fff; 85 | padding: 12px 24px; 86 | border-bottom: 1px solid #ccc; 87 | margin-right: 30px; 88 | } 89 | 90 | .variation { 91 | display: none; 92 | } 93 | 94 | .signature-attributes { 95 | font-size: 60%; 96 | color: #aaa; 97 | font-style: italic; 98 | font-weight: lighter; 99 | } 100 | 101 | nav 102 | { 103 | display: block; 104 | float: right; 105 | margin-top: 28px; 106 | width: 30%; 107 | box-sizing: border-box; 108 | border-left: 1px solid #ccc; 109 | padding-left: 16px; 110 | } 111 | 112 | nav ul { 113 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; 114 | font-size: 100%; 115 | line-height: 17px; 116 | padding: 0; 117 | margin: 0; 118 | list-style-type: none; 119 | } 120 | 121 | nav ul a, nav ul a:visited, nav ul a:active { 122 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 123 | line-height: 18px; 124 | color: #4D4E53; 125 | } 126 | 127 | nav h3 { 128 | margin-top: 12px; 129 | } 130 | 131 | nav li { 132 | margin-top: 6px; 133 | } 134 | 135 | footer { 136 | display: block; 137 | padding: 6px; 138 | margin-top: 12px; 139 | font-style: italic; 140 | font-size: 90%; 141 | } 142 | 143 | h1, h2, h3, h4 { 144 | font-weight: 200; 145 | margin: 0; 146 | } 147 | 148 | h1 149 | { 150 | font-family: 'Open Sans Light', sans-serif; 151 | font-size: 48px; 152 | letter-spacing: -2px; 153 | margin: 12px 24px 20px; 154 | } 155 | 156 | h2, h3 157 | { 158 | font-size: 30px; 159 | font-weight: 700; 160 | letter-spacing: -1px; 161 | margin-bottom: 12px; 162 | } 163 | 164 | h4 165 | { 166 | font-size: 18px; 167 | letter-spacing: -0.33px; 168 | margin-bottom: 12px; 169 | color: #4d4e53; 170 | } 171 | 172 | h5, .container-overview .subsection-title 173 | { 174 | font-size: 120%; 175 | font-weight: bold; 176 | letter-spacing: -0.01em; 177 | margin: 8px 0 3px 0; 178 | } 179 | 180 | h6 181 | { 182 | font-size: 100%; 183 | letter-spacing: -0.01em; 184 | margin: 6px 0 3px 0; 185 | font-style: italic; 186 | } 187 | 188 | .ancestors { color: #999; } 189 | .ancestors a 190 | { 191 | color: #999 !important; 192 | text-decoration: none; 193 | } 194 | 195 | .clear 196 | { 197 | clear: both; 198 | } 199 | 200 | .important 201 | { 202 | font-weight: bold; 203 | color: #950B02; 204 | } 205 | 206 | .yes-def { 207 | text-indent: -1000px; 208 | } 209 | 210 | .type-signature { 211 | color: #aaa; 212 | } 213 | 214 | .name, .signature { 215 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 216 | } 217 | 218 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 219 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 220 | .details dd { margin-left: 70px; } 221 | .details ul { margin: 0; } 222 | .details ul { list-style-type: none; } 223 | .details li { margin-left: 30px; padding-top: 6px; } 224 | .details pre.prettyprint { margin: 0 } 225 | .details .object-value { padding-top: 0; } 226 | 227 | .description { 228 | margin-bottom: 1em; 229 | margin-top: 1em; 230 | } 231 | 232 | .code-caption 233 | { 234 | font-style: italic; 235 | font-size: 107%; 236 | margin: 0; 237 | } 238 | 239 | .prettyprint 240 | { 241 | border: 1px solid #ddd; 242 | width: 80%; 243 | overflow: auto; 244 | } 245 | 246 | .prettyprint.source { 247 | width: inherit; 248 | } 249 | 250 | .prettyprint code 251 | { 252 | font-size: 100%; 253 | line-height: 18px; 254 | display: block; 255 | padding: 4px 12px; 256 | margin: 0; 257 | background-color: #fff; 258 | color: #4D4E53; 259 | } 260 | 261 | .prettyprint code span.line 262 | { 263 | display: inline-block; 264 | } 265 | 266 | .prettyprint.linenums 267 | { 268 | padding-left: 70px; 269 | -webkit-user-select: none; 270 | -moz-user-select: none; 271 | -ms-user-select: none; 272 | user-select: none; 273 | } 274 | 275 | .prettyprint.linenums ol 276 | { 277 | padding-left: 0; 278 | } 279 | 280 | .prettyprint.linenums li 281 | { 282 | border-left: 3px #ddd solid; 283 | } 284 | 285 | .prettyprint.linenums li.selected, 286 | .prettyprint.linenums li.selected * 287 | { 288 | background-color: lightyellow; 289 | } 290 | 291 | .prettyprint.linenums li * 292 | { 293 | -webkit-user-select: text; 294 | -moz-user-select: text; 295 | -ms-user-select: text; 296 | user-select: text; 297 | } 298 | 299 | .params, .props 300 | { 301 | border-spacing: 0; 302 | border: 0; 303 | border-collapse: collapse; 304 | } 305 | 306 | .params .name, .props .name, .name code { 307 | color: #4D4E53; 308 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 309 | font-size: 100%; 310 | } 311 | 312 | .params td, .params th, .props td, .props th 313 | { 314 | border: 1px solid #ddd; 315 | margin: 0px; 316 | text-align: left; 317 | vertical-align: top; 318 | padding: 4px 6px; 319 | display: table-cell; 320 | } 321 | 322 | .params thead tr, .props thead tr 323 | { 324 | background-color: #ddd; 325 | font-weight: bold; 326 | } 327 | 328 | .params .params thead tr, .props .props thead tr 329 | { 330 | background-color: #fff; 331 | font-weight: bold; 332 | } 333 | 334 | .params th, .props th { border-right: 1px solid #aaa; } 335 | .params thead .last, .props thead .last { border-right: 1px solid #ddd; } 336 | 337 | .params td.description > p:first-child, 338 | .props td.description > p:first-child 339 | { 340 | margin-top: 0; 341 | padding-top: 0; 342 | } 343 | 344 | .params td.description > p:last-child, 345 | .props td.description > p:last-child 346 | { 347 | margin-bottom: 0; 348 | padding-bottom: 0; 349 | } 350 | 351 | .disabled { 352 | color: #454545; 353 | } 354 | -------------------------------------------------------------------------------- /boobst.m: -------------------------------------------------------------------------------- 1 | ; Socket documentation 2 | ; http://localhost:57772/csp/docbook/DocBook.UI.Page.cls?KEY=GIOD_tcp 3 | starter(msg) 4 | set lv="boobstServer"_$$port() 5 | lock +@(lv):0 e set msg="already running" write msg quit 6 | lock -@(lv) set msg="started on "_$$port() 7 | job start($$port()) 8 | quit 9 | allowXecute() 10 | quit 0 11 | ; 12 | port() 13 | quit 6666 14 | ; 15 | version() 16 | quit 9 17 | detailedVersion() 18 | quit $$version()_".0" 19 | start(Port) 20 | new io, port, lv 21 | set port=$g(Port,$$port()) 22 | set lv="boobstServer"_port 23 | lock +@(lv):0 e w "already running" QUIT ; already running 24 | set io="|TCP|1" 25 | ; "PTAS" ? 26 | open io:(/TRA=0:port:"CPAS":/NODELAY=0):20 e w "Port "_port_" already served" QUIT 27 | write "Boobst Server v.0."_$$detailedVersion()_" started on Port:"_port,! 28 | use io 29 | ; 30 | serverLoop 31 | read x 32 | job child:(:5:io:io) 33 | goto serverLoop 34 | ; 35 | child 36 | ; 37 | use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) 38 | do command 39 | quit 40 | ; 41 | 42 | cleardown 43 | ; 44 | new ignore, pid 45 | ; 46 | set pid="" 47 | f s pid=$o(^boobst("connected",pid)) q:pid="" d 48 | . if pid=$j quit 49 | . s ignore=1 50 | . l +^boobst("connected",pid):0 e s ignore=0 51 | . i ignore d 52 | . . l -^boobst("connected",pid) 53 | . . k ^boobst("connected",pid) 54 | . . k ^boobst("monitor","listener",pid) 55 | . . k ^boobst("monitor","output",pid) 56 | s pid="" 57 | f s pid=$o(^boobst("monitor","output",pid)) q:pid="" d 58 | . i pid=$j q 59 | . s ignore=1 60 | . l +^boobst("connected",pid):0 e s ignore=0 61 | . l -^boobst("connected",pid) 62 | . i ignore d 63 | . . k ^boobst("monitor","output",pid) 64 | QUIT 65 | 66 | command ; 67 | new authNeeded, c, crlf, input, output 68 | ; 69 | ;d cleardown 70 | set ^boobst("connected",$j)="" 71 | lock +^boobst("connected",$j) 72 | write $$version()_";"_$j_";"_$zu(5) 73 | write *-3 74 | loop 75 | ;set %CGIEVAR("AUTH_PASSWORD")="" 76 | ;set %CGIEVAR("AUTH_TYPE")="" 77 | set %CGIEVAR("CONTENT_TYPE")="" 78 | set %CGIEVAR("GATEWAY_INTERFACE")="CGI/1.1" 79 | set %CGIEVAR("HTTP_AUTHORIZATION")="" 80 | set %CGIEVAR("HTTP_COOKIE")="" 81 | set %CGIEVAR("HTTP_REFERER")="" 82 | ;set %CGIEVAR("HTTP_SOAPACTION")="" 83 | set %CGIEVAR("REMOTE_HOST")="" 84 | set %CGIEVAR("REMOTE_IDENT")="" 85 | set %CGIEVAR("REMOTE_USER")="" 86 | set %CGIEVAR("SERVER_PROTOCOL")="HTTP/1.1" 87 | set %CGIEVAR("SERVER_SOFTWARE")="Node.js" 88 | loop2 89 | read *c 90 | read input set input=$c(c)_input 91 | set input=$e(input,1,$l(input)-1) 92 | ;set ^%boobst("cmd",$i(^%boobst("cmd"))) = input 93 | if input="PING" s output="+PONG"_crlf w output g loop2 94 | if input="" g loop 95 | if $e(input,1,2)="S " do set($e(input,3,$l(input))) goto loop2 96 | if $e(input,1,2)="Q " do setKey($e(input,3,$l(input))) goto loop2 97 | if $e(input,1,2)="K " do kill($e(input,3,$l(input))) goto loop2 98 | if $e(input,1,2)="G " do get($e(input,3,$l(input))) goto loop2 99 | if $e(input,1,2)="O " do order($e(input,3,$l(input))) goto loop2 100 | if $e(input,1,2)="Z " do zn($e(input,3,$l(input))) goto loop 101 | if $e(input,1,2)="B " do blob($e(input,3,$l(input))) goto loopBlob 102 | if $e(input,1,2)="E " do exec($e(input,3,$l(input))) goto loop 103 | if $e(input,1,2)="X " do xecute($e(input,3,$l(input))) goto loop2 104 | if input="F" d flush goto loop 105 | if input="P" d ping goto loop2 106 | if $e(input,1,2)="8 " do setEncoding($e(input,3,$l(input))) goto loop2 107 | ;if input="UTF8" use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) goto loop 108 | ;if input="RAW" use $io:(/IOTABLE="RAW"::"-Q+W":$c(0)) goto loop 109 | if input="EXIT" goto halt 110 | if input="QUIT" goto quit 111 | if input="HALT" goto halt 112 | set output="-"_input_"- not recognized"_crlf write output 113 | do end 114 | goto loop2 115 | ; 116 | blob(name) 117 | set type = $p(name,"://",1) 118 | set where = $p(name,"://",2) 119 | use $io:(/IOTABLE="RAW"::"-TS"::32000) 120 | if type="file" d 121 | . set IO=$IO 122 | . open where:("WNS"):5 123 | . if $TEST=0 do 124 | . . close where 125 | . . use io 126 | . . use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) 127 | . . write "couldn't open device" 128 | . . goto quit 129 | else if type="global" do 130 | . set it = 0 131 | . set where = "^"_where 132 | quit 133 | ; 134 | loopBlob 135 | read *c 136 | read input s input=$c(c)_input 137 | set input=$e(input,1,$l(input)) 138 | if type="global" do 139 | . set it = it + 1 140 | . set @where@(it)=input 141 | else if type="file" do 142 | . use where:(/IOTABLE="RAW"::"-Q+W"::32000) 143 | . write input 144 | . use IO:(/IOTABLE="RAW"::"-TS"::32000) 145 | goto loopBlob 146 | ; 147 | halt 148 | kill ^boobst("connected", $j) 149 | halt 150 | ; 151 | quit 152 | ; 153 | if '$d(^boobst("monitor", "listener", $j)) goto halt 154 | kill ^boobst("monitor", "listener", $j) 155 | goto loop 156 | ; 157 | kill(%nameOfVariable) 158 | kill @%nameOfVariable 159 | write "ok.kill" 160 | do end 161 | quit 162 | ; 163 | setEncoding(name) 164 | use $io:(/IOTABLE=name::"-Q+W":$char(0)) 165 | write "ok.setEncoding" 166 | do end 167 | quit 168 | ; 169 | setKey(input) 170 | new %nameOfVariable 171 | set %nameOfVariable = $piece(input, $char(1), 1) 172 | set @%nameOfVariable = $extract(input, $length(%nameOfVariable) + 2, *) 173 | set %KEY(%nameOfVariable) = @%nameOfVariable 174 | write "ok.setKey" 175 | do end 176 | quit 177 | ; 178 | set(input) 179 | new %nameOfVariable 180 | set %nameOfVariable = $piece(input, $char(1), 1) 181 | set @%nameOfVariable = $extract(input, $length(%nameOfVariable) + 2, *) 182 | write "ok.set" 183 | do end 184 | quit 185 | ; 186 | get(%input) 187 | new %params, %name 188 | set %params=$piece(%input, $char(1), 1) 189 | ; params: n - get only node value 190 | ; f - force build json w/o first node value 191 | ; /empty/ - depends on first node value 192 | set %name=$piece(%input, $char(1), 2) 193 | if %params="f" do gl(%name) do end quit 194 | if $d(@%name)=10 do gl(%name) do end quit 195 | ; write @%name 196 | do create32kbString(%name) 197 | do end 198 | quit 199 | ; 200 | order(%nameOfRoutine) 201 | write $order(@%nameOfRoutine) 202 | do end 203 | quit 204 | ; 205 | zn(%nameOfNS) 206 | zn %nameOfNS 207 | write "ok.zn."_$zu(5) 208 | write *-3 209 | quit 210 | ; 211 | exec(%nameOfRoutine) 212 | do @%nameOfRoutine 213 | do end 214 | kill 215 | use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) 216 | quit 217 | xecute(%codeToExecute) 218 | if $$allowXecute() xecute (%codeToExecute) 219 | e w "disallowed" 220 | do end 221 | use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) 222 | quit 223 | flush 224 | kill 225 | write "ok.flush" 226 | use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0)) 227 | do end 228 | quit 229 | ; 230 | ping 231 | write "pong!" 232 | do end 233 | quit 234 | ; 235 | end 236 | ;write $c(0) 237 | write $c(0) 238 | write *-3 239 | quit 240 | ; 241 | gl(global) 242 | new key, inKey, level, isArray, notFirst 243 | set key = "" 244 | set isArray = $$numberTest(global) 245 | set notFirst = 0 246 | if isArray write "[" 247 | else write "{" 248 | for set key = $order(@$na(@global@(key))) quit:key="" do 249 | . ;w !,key,") ",$na(@global@(key)),$d(@$na(@global@(key))) 250 | . if notFirst w "," 251 | . else set notFirst = 1 252 | . set inKey = $na(@global@(key)), level = $d(@inKey) 253 | . if level = 10 do 254 | . . i 'isArray write """"_$replace(key,"""","\""")_""":" 255 | . . do gl(inKey) 256 | . else if level = 11 do 257 | . . write """"_key_""":" 258 | . . do create32kb(inKey) 259 | . else do 260 | . . if isArray write $$makeValue(@global@(key)) 261 | . . else write """"_$replace(key,"""","\""")_""":"_$$makeValue(@global@(key)) 262 | if isArray write "]" 263 | else write "}" 264 | quit 265 | numberTest(global) 266 | new key, is 267 | set key = "", is = 1, num = 0 268 | for set key = $order(@$na(@global@(key))) quit:key="" do 269 | . if key'=num set is = 0 quit 270 | . set num = num + 1 271 | quit is 272 | ; 273 | create32kb(global) 274 | new key 275 | set key = "" 276 | write """"_$replace(@$na(@global),"""","\""") 277 | for set key = $order(@$na(@global@(key))) quit:key="" do 278 | . write $replace(@$na(@global@(key)),"""","\""") 279 | write """" 280 | quit 281 | ; 282 | create32kbString(global) 283 | new key 284 | set key = "" 285 | write @$na(@global) 286 | for set key = $order(@global@(key)) quit:key="" do 287 | . if +key'=key quit 288 | . write $g(@global@(key)) 289 | quit 290 | ; 291 | makeValue(val) 292 | ; if val = +val quit val 293 | if val?0.1"-"1(1"0",1(1"1",1"2",1"3",1"4",1"5",1"6",1"7",1"8",1"9").N)0.1(1"."1.N)0.1(1"e+",1"e-".N) quit val 294 | if val = "1true" quit "true" 295 | if val = "0false" quit "false" 296 | set val = $$encodeJSON(val) 297 | quit """"_val_"""" 298 | ; 299 | encodeJSON(s) ; JSON encoding 300 | n a 301 | s a = $replace(s,"\","\\") 302 | s a = $replace(a,"""","\""") 303 | s a = $replace(a,$c(9),"\t") 304 | s a = $replace(a,$c(10),"\n") 305 | s a = $replace(a,$c(13),"") 306 | q a 307 | ; 308 | -------------------------------------------------------------------------------- /test/test.set.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "test.set.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "test.set.coffee" 7 | ], 8 | "names": [], 9 | "mappings": "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" 10 | } -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Boobst. Node.js Caché driver 2 | [![Build Status](https://travis-ci.org/agsh/boobst.png)](https://travis-ci.org/agsh/boobst) 3 | [![NPM version](https://badge.fury.io/js/boobst.png)](http://badge.fury.io/js/boobst) 4 | 5 | An Intersystems Caché driver that implements basic functionality and can run routines. 6 | Several things have yet to be implemented, but the driver can be used for simple use-cases. 7 | Server part was inspired by [M.Wire](https://github.com/robtweed/mdb) project. I took from it infinitive loop organization, fork methods and open/use directives. 8 | 9 | Main goal of this project is to replace Apache + Weblink connection with Node.js server. Or just to use Cache' as an hierarchical database to store you data (probably JSON data) and execute routines and functions. 10 | 11 | Licensed under the The MIT License which can be found at http://opensource.org/licenses/MIT 12 | 13 | ## Installation 14 | 15 | via npm: 16 | 17 | ``` 18 | npm install boobst 19 | ``` 20 | 21 | ## Usage 22 | 23 | 1. Import Caché Object Script program `boobst.m` (please rename it to `boobst.int`. I use `.m` extension for MUMPS legacy) to your Caché instance 24 | 2. Run Boobst server by typing `do start^boobst` in Caché terminal 25 | 26 | ## Sample program 27 | 28 | ``` Javascript 29 | var BoobstSocket = require('boobst').BoobstSocket 30 | , assert = require('assert') 31 | ; 32 | 33 | var bs = new BoobstSocket({ 34 | host: 'localhost' 35 | , port: 6666 36 | }); 37 | bs.connect(function(err){ 38 | var test = 'test'; 39 | // 'this' refers to the socket itself 40 | this.zn('USER').set('^test', [1, 2], test).get('^test', [1, 2], function(err, data) { 41 | assert.equal(data, test, 'should be "' + test + '"'); 42 | this.disconnect(); 43 | }); 44 | }); 45 | ``` 46 | 47 | ## Tests 48 | Tests use Mocha test framework. You can install it by typing `npm install mocha` 49 | You should specify configuration of Cache' Boobst server at ./test/test.config.js and then run tests this way: `npm test` 50 | 51 | ## Commands 52 | 53 | ### Set 54 | 55 | Set local or global variable. Type of value should be a string, number, buffer or object. Local variables could be accessed throw server process. 56 | 57 | ``` Javascript 58 | bs.set('^var', ['a', 1], 'value', function(err) { 59 | if (err) { console.log(err); return; } 60 | console.log('done'); 61 | }); 62 | ``` 63 | Set can accept values more than 32kb. In this case global or local will be splitted in this structure: 64 | ``` 65 | global(subscript) = 66 | global(subscript, 1) = 67 | global(subscript, 2) = 68 | ... 69 | ``` 70 | 71 | You can also save JSON objects in your database. Mapping JSON to globals is similar to document storage in this paper: http://www.mgateway.com/docs/universalNoSQL.pdf pp. 19-21 72 | ``` JSON 73 | { 74 | "array": ["a", "ab", "abc"], 75 | "object": { 76 | "a": "a", 77 | "b": 2 78 | }, 79 | "boolean": true, 80 | "number": 42 81 | } 82 | ``` 83 | 84 | ``` Javascript 85 | var obj = { 86 | a: { 87 | b: 1 88 | }, 89 | c: [1, 2, 3], 90 | d: 'e' 91 | }; 92 | 93 | bs.set('^test', obj, function(err) { 94 | if (err) { console.log(err); return; } 95 | console.log('object saved'); 96 | }); 97 | ``` 98 | 99 | Or, if we use subscripts: 100 | ``` Javascript 101 | bs.set('^test', ['sub1', 'sub2'], obj, function(err) { 102 | if (err) { console.log(err); return; } 103 | console.log('object saved'); 104 | }); 105 | ``` 106 | 107 | ### Get 108 | 109 | Get local or global variable. Notice that data type always has a Buffer type (for binary data) and you should manually convert it to string or other type if you want. 110 | 111 | ``` Javascript 112 | bs.get('^var', ['a', 1], function(err, data) { 113 | if (err) { console.log(err); return; } 114 | console.log(data.toString()); 115 | }); 116 | ``` 117 | 118 | If we have previously saved a javascript object with ```set``` or ```saveObject``` command, we can get it back. Driver can automaticly detects the global stucture and converts it into JSON. 119 | 120 | ```javascript 121 | bs.set('^var', ['a', 1], {a: 1, b: [2, 3], c: {d: 4}}, function(err) { 122 | bs.get('^var', ['a', 1], function(err, data) { 123 | if (err) { console.log(err); return; } 124 | console.log(JSON.parse(data.toString())); // {a: 1, b: [2, 3], c: {d: 4}} 125 | }); 126 | }); 127 | ``` 128 | 129 | This is a table of mapping different data types from javascript to Cache' and backwards: 130 | 131 | |Data type|JS sample value|DB representation after `set` command|JS representation after `get` command| 132 | |---------|---------------|-------------------------------------|-------------------------------------| 133 | |Number |42 |42 |42 | 134 | | |42.666 |42.666 |42.666 | 135 | | |3.16e+920 |3.16e+920 |3.16e920 | 136 | |Boolean |true |"1true" (to distinguish with numbers but save compatibility with if operator)|true| 137 | | |false |"0false" |false | 138 | |String |'sample' |"sample" |'sample' | 139 | |Object |{ a: 1, |("a")=1 |{a:1,b:'a',c:{d:0}} | 140 | | | b: 'a', |("b")="a" | | 141 | | | c: {d, 0}} |("c","d")=0 | | 142 | |Array |[4,8,15,16] |(0)=4,(1)=8,(2)=15,(3)=16 |[4,8,15,16] | 143 | |Function |function(){} |- |- | 144 | |Date |new Date() |"Sat Jan 01 2000 12:00:00" |'Sat Jan 01 2000 12:00:00' | 145 | |Null |null |- |- | 146 | |Undefined|undefined |- |- | 147 | 148 | In the case when we have wrong global stucture (which differs from what we got with `set` command), `get` command will return only node value. But we can try to force JSON generation with setting second/third optional argument `forceJSON` to `true`. 149 | 150 | ```javascript 151 | bs.get('^var', ['a', 1], true, function(err, data) { 152 | // working with JSON here 153 | }); 154 | ``` 155 | 156 | ### Order (Next) 157 | 158 | Gets the next key based on the current key. 159 | 160 | ``` Javascript 161 | bs.next('^var', ['a', 1], function(err, key) { 162 | assert.equal(err, null); 163 | assert.equal(key, 2); 164 | }); 165 | ``` 166 | 167 | ### Kill 168 | 169 | Kill global variable. 170 | 171 | ``` Javascript 172 | bs.kill('^var', ['a', 1], function(err) { 173 | if (err) { console.log(err); return; } 174 | console.log('done'); 175 | }); 176 | ``` 177 | 178 | ### Zn 179 | 180 | Change namespace 181 | 182 | ``` Javascript 183 | bs.zn('%SYS', function(err, switched) { 184 | if (err) { console.log(err); return; } 185 | console.log(switched ? 'successfully changed namespace' : 'already been there'); 186 | }); 187 | ``` 188 | 189 | ### Execute 190 | 191 | Executes the routine. All local variables that have been set previously are available in the routine. 192 | 193 | ``` Javascript 194 | bs.set('a', 'value', function(err) { 195 | if (err) { console.log(err); return; } 196 | this.execute('showVarA^test' /**program body: "w a q"*/, function(err, data) { 197 | if (err) { console.log(err); return; } 198 | console.log(data === 'value' ? 'successfully executed': 'something wrong'); 199 | }); 200 | }); 201 | ``` 202 | 203 | Considering that commands are sending to the database in series, we can write code which executing without callbacks. 204 | 205 | ``` Javascript 206 | bs.set('a', '2') 207 | .set('b', '2') 208 | .execute('multAB^test' /**program body: "w a*b q"*/, function(err, data) { 209 | if (err) { console.log(err); return; } 210 | console.log(data === '4' ? 'successfully executed': 'something wrong'); 211 | }); 212 | ``` 213 | 214 | Also, this two commands are equivalent and second version is preferable : 215 | ``` Javascript 216 | bs.set('a("abc",1)', 5); 217 | bs.set('a', ['abc', 1], 5); 218 | ``` 219 | 220 | ### SaveObject 221 | 222 | Deprecated. Use `set` command instead which can save javascript objects into database too. 223 | 224 | ### Blob 225 | 226 | Send stream to the database server. file://path/to/the/file saves file on the disk, global://blobGlobalName saves file into `^blobGlobalName` global. 227 | > Note: if you are using node.js v0.8 or later with old Streams API, it is better to pause you stream after creating. 228 | > There is no such problem in node.js v0.10 with "Streams2" API. 229 | 230 | ``` Javascript 231 | bs.blob('global://blob', fs.createReadStream('/home/und/00109721.jpg'), function(err) { 232 | if (err) { console.log(err); return; } 233 | console.log('file saved'); 234 | }); 235 | ``` 236 | 237 | ### Increment 238 | 239 | Increments a global/local variable by a numeric value. Works just like `$increment` command in MUMPS. Arguments are: 240 | 241 | - `name` global or local name 242 | - `subscript` (optional) subscripts 243 | - `value` (optional, defaults 1) 244 | - `callback` callback function with error and new incremented value 245 | 246 | ## Useful links 247 | [Socket programming](http://www.mumpster.org/viewtopic.php?f=10&t=1672) 248 | -------------------------------------------------------------------------------- /test/test.set.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | (function() { 3 | 'use strict'; 4 | var BoobstSocket, GLOBAL, assert, boobst; 5 | 6 | assert = require('assert'); 7 | 8 | boobst = require('../boobst'); 9 | 10 | BoobstSocket = boobst.BoobstSocket; 11 | 12 | GLOBAL = '^testObject'; 13 | 14 | describe('set', function() { 15 | var bs; 16 | this.timeout(1000); 17 | bs = new BoobstSocket(require('./test.config')); 18 | beforeEach(function(done) { 19 | return bs.connect(function(err) { 20 | if (err) { 21 | throw err; 22 | } 23 | return done(); 24 | }); 25 | }); 26 | afterEach(function(done) { 27 | return bs.kill(GLOBAL, function(err) { 28 | if (err) { 29 | throw err; 30 | } 31 | return bs.disconnect(function() { 32 | return done(); 33 | }); 34 | }); 35 | }); 36 | describe('set primitives', function() { 37 | it('should save numbers', function(done) { 38 | var value; 39 | value = 5; 40 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 41 | assert.equal(err, null); 42 | assert.equal(value, data); 43 | return done(); 44 | }); 45 | }); 46 | it('should save dates', function(done) { 47 | var value; 48 | value = new Date(); 49 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 50 | assert.equal(err, null); 51 | assert.equal(value.toString(), new Date(data).toString()); 52 | return done(); 53 | }); 54 | }); 55 | it('should save strings', function(done) { 56 | var value; 57 | value = 'string'; 58 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 59 | assert.equal(err, null); 60 | assert.equal(value, data); 61 | return done(); 62 | }); 63 | }); 64 | it('should save true boolean value', function(done) { 65 | return bs.set(GLOBAL, true).get(GLOBAL, function(err, data) { 66 | assert.equal(err, null); 67 | assert.equal(data, '1true'); 68 | return done(); 69 | }); 70 | }); 71 | it('should save false boolean value', function(done) { 72 | return bs.set(GLOBAL, false).get(GLOBAL, function(err, data) { 73 | assert.equal(err, null); 74 | assert.equal(data, '0false'); 75 | return done(); 76 | }); 77 | }); 78 | it('souldn\'t save null', function(done) { 79 | return bs.set(GLOBAL, null).get(GLOBAL, function(err) { 80 | assert.notEqual(err, null); 81 | return done(); 82 | }); 83 | }); 84 | return it('souldn\'t save undefined', function(done) { 85 | return bs.set(GLOBAL, void 0).get(GLOBAL, function(err) { 86 | assert.notEqual(err, null); 87 | return done(); 88 | }); 89 | }); 90 | }); 91 | describe('set complex structures', function() { 92 | it('should save array as an object', function(done) { 93 | var value; 94 | value = [1, 2, 3]; 95 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 96 | assert.equal(err, null); 97 | assert.deepEqual(JSON.parse(data.toString()), value); 98 | return done(); 99 | }); 100 | }); 101 | it('should save all nested values properly', function(done) { 102 | var value; 103 | value = { 104 | number: 42, 105 | boolean: true, 106 | string: 'string', 107 | nested: { 108 | a: 1, 109 | b: 'a', 110 | c: true 111 | }, 112 | array: [ 113 | 1, 2, 3, { 114 | a: 1, 115 | b: '2' 116 | } 117 | ] 118 | }; 119 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 120 | assert.equal(err, null); 121 | assert.deepEqual(JSON.parse(data.toString()), value); 122 | return done(); 123 | }); 124 | }); 125 | return it('should save deep nested object properly', function(done) { 126 | var value; 127 | value = { 128 | a: { 129 | b: { 130 | c: { 131 | d: { 132 | value: 'value' 133 | } 134 | } 135 | } 136 | } 137 | }; 138 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 139 | assert.equal(err, null); 140 | assert.deepEqual(JSON.parse(data.toString()), value); 141 | return done(); 142 | }); 143 | }); 144 | }); 145 | describe('inline/callback set-get chaining', function() { 146 | var value; 147 | value = 'VALUE'; 148 | it('should set a global without subscripts inline and then get it', function(done) { 149 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 150 | assert.equal(err, null); 151 | assert.equal(value, data); 152 | return done(); 153 | }); 154 | }); 155 | it('should set a global without subscripts with a callback and then get it', function(done) { 156 | return bs.set(GLOBAL, value, function(err) { 157 | assert.equal(err, null); 158 | return bs.get(GLOBAL, function(err, data) { 159 | assert.equal(err, null); 160 | assert.equal(value, data); 161 | return done(); 162 | }); 163 | }); 164 | }); 165 | it('should set a global with subscripts inline and then get it', function(done) { 166 | return bs.set(GLOBAL, ['a', 1], value).get(GLOBAL, ['a', 1], function(err, data) { 167 | assert.equal(err, null); 168 | assert.equal(value, data); 169 | return done(); 170 | }); 171 | }); 172 | return it('should set a global with subscripts with a callback and then get it', function(done) { 173 | return bs.set(GLOBAL, ['a', 1], value, function(err) { 174 | assert.equal(err, null); 175 | return bs.get(GLOBAL, ['a', 1], function(err, data) { 176 | assert.equal(err, null); 177 | assert.equal(value, data); 178 | return done(); 179 | }); 180 | }); 181 | }); 182 | }); 183 | describe('different arguments in `set` method', function() { 184 | var array, value; 185 | value = 'VALUE'; 186 | array = ['a', 1]; 187 | it('works with two-arguments form', function(done) { 188 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 189 | assert.equal(err, null); 190 | assert.equal(value, data); 191 | return done(); 192 | }); 193 | }); 194 | it('works with three-arguments form without callback', function(done) { 195 | return bs.set(GLOBAL, array, value).get(GLOBAL, array, function(err, data) { 196 | assert.equal(err, null); 197 | assert.equal(value, data); 198 | return done(); 199 | }); 200 | }); 201 | it('works with three-arguments form without callback even the value is array', function(done) { 202 | return bs.set(GLOBAL, array, array).get(GLOBAL, array, function(err, data) { 203 | assert.equal(err, null); 204 | assert.deepEqual(array, JSON.parse(data.toString())); 205 | return done(); 206 | }); 207 | }); 208 | it('works with three-arguments form with callback even the value is array', function(done) { 209 | return bs.set(GLOBAL, array, function(err) { 210 | assert.equal(err, null); 211 | return bs.get(GLOBAL, function(err, data) { 212 | console.log(err); 213 | assert.equal(err, null); 214 | assert.deepEqual(array, JSON.parse(data.toString())); 215 | return done(); 216 | }); 217 | }); 218 | }); 219 | return it('works with four-arguments form with callback even the value is array', function(done) { 220 | return bs.set(GLOBAL, array, array, function(err) { 221 | assert.equal(err, null); 222 | return bs.get(GLOBAL, array, function(err, data) { 223 | assert.equal(err, null); 224 | assert.deepEqual(array, JSON.parse(data.toString())); 225 | return done(); 226 | }); 227 | }); 228 | }); 229 | }); 230 | return describe('setting large, binary and screening values', function() { 231 | it('should save and restore screening values', function(done) { 232 | var value; 233 | value = '"\\'; 234 | return bs.set(GLOBAL, value).get(GLOBAL, function(err, data) { 235 | assert.equal(err, null); 236 | assert.equal(value, data); 237 | return done(); 238 | }); 239 | }); 240 | return it('should save string 65536 bytes length', function(done) { 241 | var value; 242 | value = new Array(4 * 1024 + 1).join('0123456789abcdef'); 243 | return bs.set(GLOBAL, ['a'], value).get(GLOBAL, ['a'], function(err, data) { 244 | assert.equal(err, null); 245 | console.log(value.length); 246 | console.log(data.toString().length); 247 | assert.equal(value, data.toString()); 248 | return done(); 249 | }); 250 | }); 251 | }); 252 | 253 | /* 254 | describe '#set', () -> 255 | it 'shouldn\'t save function', (done) -> 256 | value = () -> 257 | bs.set GLOBAL, value 258 | .get GLOBAL, (err, data) -> 259 | assert.equal err, null 260 | assert.equal undefined, data 261 | done() 262 | */ 263 | }); 264 | 265 | }).call(this); 266 | 267 | //# sourceMappingURL=test.set.map 268 | -------------------------------------------------------------------------------- /docs/scripts/prettify/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /docs/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Global 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Global

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
78 | 79 | 80 | 81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |

Members

96 | 97 | 98 | 99 |

(constant) BCMD :number

100 | 101 | 102 | 103 | 104 | 105 | 106 |
Type:
107 |
    108 |
  • 109 | 110 | number 111 | 112 | 113 |
  • 114 |
115 | 116 | 117 | 118 | 119 | 120 |
Properties:
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 |
NameTypeDescription
NOP 150 | 151 | 152 | number 153 | 154 | 155 | 156 |
SET 173 | 174 | 175 | number 176 | 177 | 178 | 179 |
GET 196 | 197 | 198 | number 199 | 200 | 201 | 202 |
EXECUTE 219 | 220 | 221 | number 222 | 223 | 224 | 225 |
SETENCODING 242 | 243 | 244 | number 245 | 246 | 247 | 248 |
FLUSH 265 | 266 | 267 | number 268 | 269 | 270 | 271 |
KILL 288 | 289 | 290 | number 291 | 292 | 293 | 294 |
DISCONNECT 311 | 312 | 313 | number 314 | 315 | 316 | 317 |
KEY 334 | 335 | 336 | number 337 | 338 | 339 | 340 |
PING 357 | 358 | 359 | number 360 | 361 | 362 | 363 |
ZN 380 | 381 | 382 | number 383 | 384 | 385 | 386 |
HI 403 | 404 | 405 | number 406 | 407 | 408 | 409 |
BLOB 426 | 427 | 428 | number 429 | 430 | 431 | 432 |
ORDER 449 | 450 | 451 | number 452 | 453 | 454 | 455 |
XECUTE 472 | 473 | 474 | number 475 | 476 | 477 | 478 |
INPUT 495 | 496 | 497 | number 498 | 499 | 500 | 501 |
513 | 514 | 515 | 516 | 517 |
518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 |
Source:
545 |
548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 |
556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 |

net

565 | 566 | 567 | 568 | 569 |
570 | Boobst module (boobst.js) 571 | A tiny database driver for DBMS Cache' 572 |
573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 |
581 | 582 | 583 |
Version:
584 |
  • 0.9.1
585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 |
Author:
603 |
604 | 607 |
608 | 609 | 610 | 611 | 612 | 613 |
License:
614 |
  • MIT
615 | 616 | 617 | 618 | 619 | 620 |
Source:
621 |
624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 |
632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 |
647 | 648 |
649 | 650 | 651 | 652 | 653 |
654 | 655 | 658 | 659 |
660 | 661 |
662 | Documentation generated by JSDoc 3.4.0 on Wed Aug 03 2016 15:56:44 GMT+0300 (MSK) 663 |
664 | 665 | 666 | 667 | 668 | -------------------------------------------------------------------------------- /docs/scripts/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p 5 | * @version 0.9.1 6 | * @license MIT 7 | **/ 8 | 9 | var net = require('net') 10 | , util = require('util') 11 | , events = require('events'); 12 | 13 | const 14 | EOL = ' ' + String.fromCharCode(0) // TODO избавиться от лишнего байта в s input=$e(input,1,$l(input)-1) 15 | , EON = String.fromCharCode(1) 16 | , VERSION = 9 17 | // , VALID_CACHE_VAR_RE = /^\^?%?[\-A-Z\.a-z]+[\w\d]*(\(("[A-Za-z_\-\.\+\\/0-9]+"|\d)(,("[A-Za-z_\-\.\+\\/0-9]+"|\d))*\))?$/ 18 | , CACHE_MAX_SIZE = 32754, 19 | /** 20 | * @readonly 21 | * @enum {number} 22 | */ 23 | BCMD = { 24 | NOP: 0 25 | , SET: 1 26 | , GET: 2 27 | , EXECUTE: 3 28 | , SETENCODING: 4 29 | , FLUSH: 5 30 | , KILL: 6 31 | , DISCONNECT: 7 32 | , KEY: 8 33 | , PING: 9 34 | , ZN: 10 35 | , HI: 11 36 | , BLOB: 12 37 | , ORDER: 13 38 | , XECUTE: 14 39 | , INPUT: 15 40 | } 41 | ; 42 | 43 | /** 44 | * @this boobst.BoobstSocket 45 | * @private 46 | */ 47 | function onConnection() { 48 | // unused event handler cause on connection server first of all sends greeting BCMD.HI to client 49 | } 50 | 51 | /** 52 | * Событие сокета на ошибку 53 | * @private 54 | * @this boobst.BoobstSocket 55 | */ 56 | function onError(err) { 57 | this.emit('debug', 'error: ' + err.toString()); 58 | if (this.callback) { 59 | 60 | if (this.command === BCMD.BLOB) { // blob errors we catch here TODO: think about properly closing MUMPS connection 61 | this.command = BCMD.NOP; 62 | } 63 | 64 | this.callback.call(this, err); 65 | } 66 | // self.socket = null; pass this if we don't want to connect anymore 67 | } 68 | 69 | /** 70 | * On close socket event 71 | * @private 72 | * @this BoobstSocket 73 | */ 74 | function onClose(transmittionErr) { 75 | this.connected = false; 76 | if (!this.killme) { // if we got connection troubles 77 | if (this.out) { 78 | this.out.end(); 79 | } 80 | if (this.command === BCMD.BLOB && this.callback) { // if we disconnected under .blob command 81 | this.callback.call(this, null); 82 | } else { 83 | this.emit('debug', 'disconnected'); 84 | if (this.data) { 85 | this.emit('debug', this.data.toString()); 86 | if (this.callback) { 87 | this.callback.call(this, new Error(this.data)); 88 | } 89 | } 90 | } 91 | this.command = BCMD.HI; 92 | // trying to establish connection at growing time intervals 93 | if (!this._connectionTimeout) { 94 | this._connectionTimeout = 0; 95 | } else { 96 | this._connectionTimeout += 1000; 97 | } 98 | setTimeout(function() { 99 | this.connect(); 100 | }.bind(this), this._connectionTimeout); 101 | //self.connect(); 102 | } else { // if we calls .disconnect() method 103 | if (this.callback) { 104 | this.callback.call(this); // disconnection callback 105 | } 106 | } 107 | } 108 | 109 | /** 110 | * Событие сокета на получение данных 111 | * @private 112 | * @this BoobstSocket 113 | */ 114 | function onData(data) { 115 | this.emit('debug', this.command + ' : ' + data.toString()); 116 | switch (this.command) { 117 | case BCMD.NOP: 118 | this.emit('debug', 'Data on NOP command: ' + data.toString()); 119 | this.command = BCMD.INPUT; 120 | this.callback = function(data) { 121 | this.emit('message', data); 122 | this.command = BCMD.NOP; 123 | this._runCommandFromQueue(); 124 | }; 125 | this.onDataCommon(data); 126 | break; 127 | case BCMD.SETENCODING: case BCMD.KEY: case BCMD.SET: case BCMD.KILL: case BCMD.EXECUTE: case BCMD.FLUSH: case BCMD.PING: case BCMD.GET: case BCMD.ORDER: case BCMD.XECUTE: case BCMD.INPUT: 128 | this.onDataCommon(data); 129 | break; 130 | case BCMD.ZN: 131 | this.onDataZn(data); 132 | break; 133 | case BCMD.BLOB: 134 | // do nothing, this error should be caught by onError event 135 | break; 136 | case BCMD.HI: 137 | this.killme = false; 138 | this.onDataGreeting(data); 139 | break; 140 | default: 141 | this.error('Lost data!'); 142 | this.log(data.toString()); 143 | } 144 | } 145 | 146 | /** 147 | * Boobst Socket 148 | * @param {Object} options 149 | * @param {number} [options.port] port 150 | * @param {string} [options.host] host 151 | * @property {Function} callback 152 | * @property {Function} emit 153 | * @extends events.EventEmitter 154 | * @constructor 155 | */ 156 | var BoobstSocket = function(options) { 157 | /** 158 | * Server's process id 159 | * @type {number} 160 | */ 161 | this.id = 0; 162 | options = options || {}; 163 | /** 164 | * Protocol varsion 165 | * @type {number} 166 | */ 167 | this.version = VERSION; 168 | this.out = null; 169 | /** 170 | * Commands queue 171 | * @type {Array} 172 | */ 173 | this.queue = []; 174 | /** 175 | * Port 176 | * @type {number} 177 | */ 178 | this.port = options.port || 6666; 179 | /** 180 | * Host 181 | * @type {string} 182 | */ 183 | this.host = options.host || options.server || 'localhost'; 184 | if (options.ns) { 185 | this.ns = options.ns; 186 | } 187 | this.command = BCMD.HI; 188 | this.connected = false; 189 | this.killme = false; 190 | /** 191 | * Connection socket 192 | * @type {net.Socket} 193 | */ 194 | this.socket = new net.Socket(); 195 | this.socket.bufferSize = 32000; 196 | this.socket.boobst = this; 197 | this.socket.on('connect', onConnection.bind(this)); 198 | this.socket.on('close', onClose.bind(this)); 199 | this.socket.on('data', onData.bind(this)); 200 | this.socket.on('error', onError.bind(this)); 201 | }; 202 | 203 | // events.EventEmitter inheritance 204 | util.inherits(BoobstSocket, events.EventEmitter); 205 | 206 | /** 207 | * Connect to DB 208 | * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback 209 | * @return {boobst.BoobstSocket} 210 | */ 211 | BoobstSocket.prototype.connect = function(callback) { 212 | try { 213 | this.emit('debug', 'trying to connect to ' + this.host + ':' + this.port + ' > ' + this.command); 214 | if (callback) { 215 | /** 216 | * 217 | * @type {(function(this:boobst.BoobstSocket, (null|Error)))} 218 | */ 219 | this.onConnectionCallback = callback; 220 | } 221 | this.socket.connect(this.port, this.host); 222 | delete this._connectionTimeout; 223 | } catch(e) { 224 | if (callback) { 225 | callback(new Error(e)); 226 | } 227 | } 228 | return this; 229 | }; 230 | 231 | //---------------------------------------------------------------------------------------------------------------------- 232 | /** 233 | * Common event handler 234 | * @private 235 | * @param {Buffer} data binary data chunk 236 | */ 237 | BoobstSocket.prototype.onDataCommon = function(data) { 238 | // check if this chunk is the last one 239 | // it must have \0 character at the end 240 | if ((data.length > 0) && (data[data.length - 1] === 0)) { 241 | if (this.out && (this.command === BCMD.EXECUTE || this.command === BCMD.XECUTE)){ // if we're writing into stream 242 | this.out.end(data.slice(0, data.length - 1)); 243 | delete this.out; 244 | if (this.callback) { // if we have callback 245 | this.callback.call(this, null); // we haven't get this.data here 246 | } 247 | } else { 248 | this.data = Buffer.concat([this.data, data.slice(0, data.length - 1)]); 249 | if (this.callback) { // if we have callback 250 | this.callback.call(this, null, this.data); 251 | } 252 | } 253 | process.nextTick(function() { 254 | this.command = BCMD.NOP; 255 | this._runCommandFromQueue(); 256 | }.bind(this)); 257 | } else { 258 | if (this.out && (this.command === BCMD.EXECUTE || this.command === BCMD.XECUTE)){ // if we're writing into stream 259 | this.out.write(data); 260 | } else { 261 | this.data = Buffer.concat([this.data, data]); 262 | } 263 | } 264 | }; 265 | 266 | BoobstSocket.prototype.onDataInput = function(data) { 267 | 268 | }; 269 | 270 | /** 271 | * Connect event handler 272 | * @private 273 | * @param {Buffer} data greeting 274 | */ 275 | BoobstSocket.prototype.onDataGreeting = function(data) { 276 | this.emit('debug', 'connected'); 277 | this.connected = true; 278 | var dataStr = data.toString().split(';'); 279 | 280 | if (parseInt(dataStr[0], 10) !== this.version) { 281 | var err = new Error('Mismatch of protocol versions! server: ' + dataStr[0] + ', client: ' + this.version); 282 | if (this.onConnectionCallback) { 283 | this.onConnectionCallback(err); 284 | } 285 | return; 286 | } 287 | 288 | // working with properly protocol version 289 | this.id = parseInt(dataStr[1], 10); 290 | // if we're in the different namespace when connected just switch to the right one 291 | if (this.ns) { 292 | if (this.ns !== dataStr[2]) { 293 | this.queue.unshift({ 294 | cmd: BCMD.ZN 295 | , name: this.ns 296 | }); 297 | } 298 | } else { 299 | this.ns = dataStr[2]; 300 | } 301 | 302 | if (this.onConnectionCallback) { 303 | this.onConnectionCallback.call(this); 304 | delete this.onConnectionCallback; 305 | } 306 | 307 | process.nextTick(function() { 308 | this.command = BCMD.NOP; 309 | this._runCommandFromQueue(); 310 | }.bind(this)); 311 | }; 312 | 313 | /** 314 | * Namespace change event handler 315 | * @private 316 | * @param {Buffer} data информация о смене 317 | */ 318 | BoobstSocket.prototype.onDataZn = function(data) { 319 | var str = data.toString().split('.'); 320 | 321 | if (str[0] === 'ok' && str[1] === 'zn') { 322 | this.ns = str[2].toUpperCase(); 323 | this.emit('debug', 'IM ON ::: ' + this.ns); 324 | if (this.callback) { 325 | this.callback.call(this, null, true); 326 | } 327 | } else { 328 | if (this.callback) { 329 | this.callback.call(this, new Error(str)); 330 | } 331 | } 332 | process.nextTick(function() { 333 | this.command = BCMD.NOP; 334 | this._runCommandFromQueue(); 335 | }.bind(this)); 336 | }; 337 | //-------------------------------------------------------------------------- 338 | /** 339 | * Try to execute command 340 | * If socket is not empty, command pushed into queue 341 | * @param {Object} commandObject 342 | * @private 343 | */ 344 | BoobstSocket.prototype._tryCommand = function(commandObject) { // попытаться выполнить комманду 345 | if (this.command !== BCMD.NOP || this.connected === false) { 346 | this.queue.push(commandObject); 347 | } else { 348 | this.data = new Buffer(0); 349 | this.command = commandObject.cmd; 350 | this.callback = commandObject.callback; 351 | this.emit('debug', 'command: ' + commandObject.cmd + 352 | (commandObject.name || commandObject.uri ? ', name: ' + (commandObject.name || commandObject.uri) : '') + 353 | (commandObject.value ? ', value:' +commandObject.value : '') 354 | ); 355 | switch (commandObject.cmd) { 356 | case BCMD.EXECUTE: 357 | if (commandObject.out) { 358 | this.out = commandObject.out; 359 | } 360 | this.socket.write('E ' + commandObject.name + EOL); 361 | break; 362 | case BCMD.XECUTE: 363 | if (commandObject.out) { 364 | this.out = commandObject.out; 365 | } 366 | this.socket.write('X ' + commandObject.name + EOL); 367 | break; 368 | case BCMD.GET: 369 | this.socket.write('G ' + commandObject.forceJSON + EON + commandObject.name + EOL); 370 | break; 371 | case BCMD.KEY: 372 | this.socket.write('Q ' + commandObject.name + EON + commandObject.value + EOL); 373 | break; 374 | case BCMD.SETENCODING: 375 | this.socket.write('8 ' + commandObject.value + EOL); 376 | break; 377 | case BCMD.SET: 378 | this.socket.write('S ' + commandObject.name + EON + commandObject.value + EOL); 379 | break; 380 | case BCMD.KILL: 381 | this.socket.write('K ' + commandObject.name + EOL); 382 | break; 383 | case BCMD.FLUSH: 384 | this.socket.write('F' + EOL); 385 | break; 386 | case BCMD.PING: 387 | this.socket.write('P' + EOL); 388 | break; 389 | case BCMD.ORDER: 390 | this.socket.write('O ' + commandObject.name + EOL); 391 | break; 392 | case BCMD.BLOB: 393 | this.socket.write('B ' + commandObject.uri + EOL); 394 | commandObject.stream.on('end', function() { 395 | this.socket.end(); 396 | /* 397 | if (this.callback) { // если у нас есть коллбек 398 | this.callback.call(this, null); 399 | } 400 | */ 401 | //this.command = BCMD.NOP; 402 | //this.connect(); 403 | }.bind(this)); 404 | commandObject.stream.pipe(this.socket); 405 | var version = process.versions.node.split('.').map(function(num) { 406 | return parseInt(num); 407 | }); 408 | if (version[0] === 0 && version[1] < 9) { // fix for old Streams 1 api 409 | commandObject.stream.resume(); 410 | } 411 | break; 412 | case BCMD.ZN: 413 | this.socket.write('Z ' + commandObject.name + EOL); 414 | break; 415 | case BCMD.DISCONNECT: 416 | this.killme = true; // this is state to disconnect gracefully 417 | this.command = BCMD.HI; // we are ready to the next greeting from server 418 | this.socket.end(); 419 | break; 420 | default: 421 | this.error("unknown command"); 422 | this.error(commandObject); 423 | } 424 | } 425 | }; 426 | 427 | /** 428 | * Execute routine 429 | * @param {string} name имя существующей команды 430 | * @param {stream.Stream} [outStream] поток, в который пересылать ответ сервера 431 | * @param {function(this:boobst.BoobstSocket, (null|Error), Object)} callback callback 432 | */ 433 | BoobstSocket.prototype.execute = function(name, outStream, callback) { 434 | var cmd = { 435 | cmd: BCMD.EXECUTE, 436 | name: name 437 | }; 438 | if (outStream) { 439 | if (typeof outStream === 'function') { 440 | cmd.callback = outStream; 441 | } else { 442 | cmd.out = outStream; 443 | if (callback) { 444 | cmd.callback = callback; 445 | } 446 | } 447 | } 448 | this._tryCommand(cmd); 449 | return this; 450 | }; 451 | 452 | /** 453 | * Evaluates any code on the server. Dangerous thing disabled on server by default 454 | * @param {string} xecute text to xecute 455 | * @param {stream.Stream} [outStream] stream to send data 456 | * @param {function(this:boobst.BoobstSocket, (null|Error), Object)} callback callback 457 | */ 458 | BoobstSocket.prototype.xecute = function(xecute, outStream, callback) { 459 | var cmd = { 460 | cmd: BCMD.XECUTE, 461 | name: xecute 462 | }; 463 | if (outStream) { 464 | if (typeof outStream === 'function') { 465 | cmd.callback = outStream; 466 | } else { 467 | cmd.out = outStream; 468 | if (callback) { 469 | cmd.callback = callback; 470 | } 471 | } 472 | } 473 | this._tryCommand(cmd); 474 | return this; 475 | }; 476 | 477 | /** 478 | * Get value 479 | * @param {string} name Name of variable or global node 480 | * @param {(Array|boolean|function(this:boobst.BoobstSocket, (null|Error), Object))} [subscript] 481 | * @param {boolean|function(this:boobst.BoobstSocket, (null|Error), Object)} [forceJSON] force get JSON from node 482 | * @param {function(this:boobst.BoobstSocket, (null|Error), Buffer)} callback Callback-function (error, data) 483 | */ 484 | BoobstSocket.prototype.get = function(name, subscript, forceJSON, callback) { 485 | if (callback === undefined) { 486 | if (forceJSON !== undefined) { 487 | callback = forceJSON; 488 | if (typeof subscript === 'boolean') { 489 | forceJSON = subscript; 490 | } else { 491 | name = createNameFromSubscript(name, subscript); 492 | forceJSON = false; 493 | } 494 | } else { 495 | callback = subscript; 496 | forceJSON = false; 497 | } 498 | } else { 499 | name = createNameFromSubscript(name, subscript); 500 | } 501 | this._tryCommand({ 502 | cmd: BCMD.GET, 503 | name: name, 504 | forceJSON: forceJSON ? 'f' : '', 505 | callback: callback 506 | }); 507 | return this; 508 | }; 509 | BoobstSocket.prototype.key = function(name, value, callback) { 510 | isValidCacheVar(name); 511 | this._tryCommand({ 512 | cmd: BCMD.KEY, 513 | name: name, 514 | value: value, 515 | callback: callback 516 | }); 517 | return this; 518 | }; 519 | BoobstSocket.prototype.setEncoding = function(value, callback) { 520 | this._tryCommand({ 521 | cmd: BCMD.SETENCODING, 522 | value: value, 523 | callback: callback 524 | }); 525 | return this; 526 | }; 527 | 528 | /** 529 | * Set the value of variable or global 530 | * @param {string} name variable or global name (global name starts with `^`) 531 | * @param {string|Buffer|Array} [subscripts] 532 | * @param {string|Buffer|function|number|Date} value variable value 533 | * @param {?function(this:boobst.BoobstSocket, Error?, string?)} [callback] callback 534 | * @return {boobst.BoobstSocket|BoobstSocket} 535 | */ 536 | BoobstSocket.prototype.set = function(name, subscripts, value, callback) { 537 | /** let this part will be filtered by server-side 538 | if (~name.indexOf('"')) { 539 | throw new Error("You couldn't use '\"' in variable names: " + name); 540 | } 541 | */ 542 | // polymorphism 543 | var completed 544 | , self = this 545 | , typeOfValue = typeof value 546 | ; 547 | if (typeOfValue === 'function' || typeOfValue === 'undefined') { // missing subscripts attribute 548 | callback = value; 549 | value = subscripts; 550 | subscripts = []; 551 | typeOfValue = typeof value; 552 | } 553 | 554 | // casting 555 | if (typeOfValue === 'undefined' || value === null) { 556 | return this; 557 | } else if (typeOfValue === 'number') { // number casts to string 558 | value = value.toString(); 559 | typeOfValue = 'string'; 560 | } else if (typeOfValue === 'boolean') { 561 | value = value ? '1true' : '0false'; 562 | typeOfValue = 'string'; 563 | } else if (value instanceof Date) { // date casts to string 564 | value = value.toJSON(); 565 | typeOfValue = 'string'; 566 | } 567 | 568 | if (typeOfValue === 'string' || Buffer.isBuffer(value)) { 569 | if (typeOfValue === 'string' && Buffer.byteLength(value) > CACHE_MAX_SIZE || value.length > CACHE_MAX_SIZE) { 570 | value = new Buffer(value); 571 | callback = callback || function() {}; 572 | completed = 0; 573 | for (var length = value.length, i = 0, begin = 0; begin < length; i += 1, begin += CACHE_MAX_SIZE) { 574 | completed += 1; 575 | this.set(name, i ? subscripts.concat(i) : subscripts, value.slice(begin, begin + CACHE_MAX_SIZE), function(err) { 576 | if (err) { 577 | callback(err); 578 | callback = function() {}; 579 | } else { 580 | completed -= 1; 581 | if (completed === 0) { 582 | callback.call(this, null); 583 | } 584 | } 585 | }); 586 | } 587 | return this; 588 | } else { 589 | name = createNameFromSubscript(name, subscripts); 590 | isValidCacheVar(name); 591 | this._tryCommand({ 592 | cmd: BCMD.SET, 593 | name: name, 594 | value: value, 595 | callback: callback 596 | }); 597 | return this; 598 | } 599 | } else if (typeOfValue === 'function') { 600 | // do nothing TODO function stringify option 601 | return this; 602 | } else if (typeOfValue === 'object') { // object or array 603 | completed = Object.keys(value).length; 604 | Object.keys(value).forEach(function(key) { 605 | self.set(name, subscripts.concat(key), value[key], function(err) { 606 | if (err && callback) { 607 | callback(err); 608 | callback = function() {}; 609 | } 610 | completed -= 1; 611 | if (completed === 0 && callback) { 612 | callback.call(this, null); 613 | } 614 | }); 615 | }); 616 | return this; 617 | } else { 618 | var err = new Error('Method `set` can accept only `string`, `object`, `Buffer`, `number`, `Date` value types. And ignores `function`. Not: ' + value); 619 | if (callback) { 620 | callback(err); 621 | } else { 622 | throw err; 623 | } 624 | return this; 625 | } 626 | }; 627 | 628 | 629 | /** 630 | * Save javascript-оbject in Cache' 631 | * @param {string} variable or global name (global name starts with `^`) 632 | * @param {Array.} [subscripts] 633 | * @param {Object} object javascript-object 634 | * @param {function(?Error)} [callback] callback 635 | * @deprecated 636 | */ 637 | BoobstSocket.prototype.saveObject = BoobstSocket.prototype.set; 638 | 639 | /** 640 | * Returns next subscript based on current 641 | * @param name 642 | * @param subscript 643 | * @param {Function} callback 644 | */ 645 | BoobstSocket.prototype.order = BoobstSocket.prototype.next = function(name, subscript, callback) { 646 | name = createNameFromSubscript(name, subscript); 647 | this._tryCommand({ 648 | cmd: BCMD.ORDER, 649 | name: name, 650 | callback: callback 651 | }); 652 | return this; 653 | }; 654 | 655 | /** 656 | * Changes namespace 657 | * @param {string} name existing namespace 658 | * @param {function} [callback] callback 659 | */ 660 | BoobstSocket.prototype.zn = function(name, callback) { 661 | this._tryCommand({ 662 | cmd: BCMD.ZN, 663 | name: name, 664 | callback: callback 665 | }); 666 | /* 667 | if (name.toUpperCase() !== this.ns) { 668 | this._tryCommand({ 669 | cmd: BCMD.ZN, 670 | name: name, 671 | callback: callback 672 | }); 673 | } else { 674 | if (callback) { 675 | callback.call(this, null, false); 676 | } 677 | } 678 | */ 679 | return this; 680 | }; 681 | 682 | /** 683 | * Kill a global or a local 684 | * @param {string} name 685 | * @param {Array | function(this:boobst.BoobstSocket, (null|Error))} [subscripts] 686 | * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback 687 | */ 688 | BoobstSocket.prototype.kill = function(name, subscripts, callback) { 689 | if (typeof callback === 'undefined' && typeof subscripts === 'function') { 690 | callback = subscripts; 691 | subscripts = []; 692 | } 693 | name = createNameFromSubscript(name, subscripts); 694 | this._tryCommand({ 695 | cmd: BCMD.KILL, 696 | name: name, 697 | callback: callback 698 | }); 699 | return this; 700 | }; 701 | 702 | /** 703 | * Send binary data 704 | * @param {string} uri uri format is: file:// or global:// 705 | * @param {Stream} stream data stream 706 | * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback 707 | */ 708 | BoobstSocket.prototype.blob = function(uri, stream, callback) { 709 | var arr = uri.split('://'); 710 | if (arr.length !== 2) { 711 | throw new Error('Invalid uri for blob command: "' + uri + '"'); 712 | } 713 | if (arr[0] === 'global') { 714 | isValidCacheVar(arr[1]); 715 | } 716 | this._tryCommand({ 717 | cmd: BCMD.BLOB 718 | , stream: stream 719 | , uri: uri 720 | , callback: callback 721 | }); 722 | return this; 723 | }; 724 | 725 | /** 726 | * Clear the local namespace and set the server variables again 727 | * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback 728 | */ 729 | BoobstSocket.prototype.flush = function(callback) { 730 | this._tryCommand({cmd: BCMD.FLUSH, callback: callback}); 731 | return this; 732 | }; 733 | 734 | /** 735 | * Check server state 736 | * @param {function(this:boobst.BoobstSocket, (null|Error), {string})} [callback] callback 737 | */ 738 | BoobstSocket.prototype.ping = function(callback) { 739 | this._tryCommand({cmd: BCMD.PING, callback: callback}); 740 | return this; 741 | }; 742 | 743 | BoobstSocket.prototype.increment = function(name, subscripts, value, callback) { 744 | if (callback === undefined) { 745 | switch (typeof subscripts) { 746 | case 'number': 747 | callback = value; 748 | value = subscripts; 749 | subscripts = []; 750 | break; 751 | case 'function': 752 | callback = subscripts; 753 | value = 1; 754 | subscripts = []; 755 | break; 756 | case 'object': 757 | callback = value; 758 | value = 1; 759 | } 760 | } 761 | this.get(name, subscripts, function(err, data) { 762 | var inc = Number(data.toString()); 763 | inc = (isNaN(inc) ? 0 : inc) + value; 764 | // TODO global lock 765 | this.set(name, subscripts, inc, function(err) { 766 | if (err) { 767 | callback(err); 768 | } else { 769 | callback(null, inc); 770 | } 771 | }); 772 | }); 773 | }; 774 | 775 | /** 776 | * Disconnect from the db 777 | * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback 778 | */ 779 | BoobstSocket.prototype.disconnect = function(callback) { 780 | this._tryCommand({cmd: BCMD.DISCONNECT, callback: callback}); 781 | return this; 782 | }; 783 | 784 | /** 785 | * Start next command from the queue 786 | * @private 787 | */ 788 | BoobstSocket.prototype._runCommandFromQueue = function() { 789 | if (this.queue.length > 0) { 790 | var task = this.queue.shift(); 791 | this._tryCommand(task); 792 | } 793 | }; 794 | 795 | //-------------------------------------------------------------------------- 796 | function isValidCacheVar(name) { 797 | /* TODO fix it 798 | if (!VALID_CACHE_VAR_RE.test(name)) { 799 | throw new Error('"' + name + "\" isn't a valid Cache' variable name"); 800 | } 801 | */ 802 | } 803 | 804 | function createNameFromSubscript(name, subscript) { 805 | if (Array.isArray(subscript) && subscript.length > 0) { 806 | return name + '(' + subscript.map(function(sub) {return '"' + sub + '"';}).join(',') + ')'; 807 | } else { 808 | return name; 809 | } 810 | } 811 | 812 | BoobstSocket.prototype.error = function(text) { 813 | this.emit('debug', text); 814 | }; 815 | BoobstSocket.prototype.log = function(text) { 816 | this.emit('debug', text); 817 | }; 818 | //-------------------------------------------------------------------------- 819 | BoobstSocket.prototype.port = 6666; 820 | 821 | exports.BoobstSocket = BoobstSocket; 822 | -------------------------------------------------------------------------------- /docs/boobst.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: boobst.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: boobst.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * Boobst module (boobst.js)
 31 |  * A tiny database driver for DBMS Cache'
 32 |  * @author Andrew D. Laptev <a.d.laptev@gmail.com>
 33 |  * @version 0.9.1
 34 |  * @license MIT
 35 |  **/
 36 | 
 37 | var net = require('net')
 38 | 	, util = require('util')
 39 | 	, events = require('events');
 40 | 
 41 | const
 42 | 	EOL = ' ' + String.fromCharCode(0) // TODO избавиться от лишнего байта в s input=$e(input,1,$l(input)-1)
 43 | 	, EON = String.fromCharCode(1)
 44 | 	, VERSION = 9
 45 | 	// , VALID_CACHE_VAR_RE = /^\^?%?[\-A-Z\.a-z]+[\w\d]*(\(("[A-Za-z_\-\.\+\\/0-9]+"|\d)(,("[A-Za-z_\-\.\+\\/0-9]+"|\d))*\))?$/
 46 | 	, CACHE_MAX_SIZE = 32754,
 47 | 	/**
 48 | 	 * @readonly
 49 | 	 * @enum {number}
 50 | 	 */
 51 |     BCMD = {
 52 | 		NOP: 0
 53 | 		, SET: 1
 54 | 		, GET: 2
 55 | 		, EXECUTE: 3
 56 | 		, SETENCODING: 4
 57 | 		, FLUSH: 5
 58 | 		, KILL: 6
 59 | 		, DISCONNECT: 7
 60 | 		, KEY: 8
 61 | 		, PING: 9
 62 | 		, ZN: 10
 63 | 		, HI: 11
 64 | 		, BLOB: 12
 65 | 		, ORDER: 13
 66 | 		, XECUTE: 14
 67 | 		, INPUT: 15
 68 | 	}
 69 | 	;
 70 | 
 71 | /**
 72 |  * @this boobst.BoobstSocket
 73 |  * @private
 74 |  */
 75 | function onConnection() {
 76 | 	// unused event handler cause on connection server first of all sends greeting BCMD.HI to client
 77 | }
 78 | 
 79 | /**
 80 |  * Событие сокета на ошибку
 81 |  * @private
 82 |  * @this boobst.BoobstSocket
 83 |  */
 84 | function onError(err) {
 85 | 	this.emit('debug', 'error: ' + err.toString());
 86 | 	if (this.callback) {
 87 | 
 88 | 		if (this.command === BCMD.BLOB) {  // blob errors we catch here   TODO: think about properly closing MUMPS connection
 89 | 			this.command = BCMD.NOP;
 90 | 		}
 91 | 
 92 | 		this.callback.call(this, err);
 93 | 	}
 94 | 	// self.socket = null; pass this if we don't want to connect anymore
 95 | }
 96 | 
 97 | /**
 98 |  * On close socket event
 99 |  * @private
100 |  * @this BoobstSocket
101 |  */
102 | function onClose(transmittionErr) {
103 | 	this.connected = false;
104 | 	if (!this.killme) { // if we got connection troubles
105 | 		if (this.out) {
106 | 			this.out.end();
107 | 		}
108 | 		if (this.command === BCMD.BLOB && this.callback) { // if we disconnected under .blob command
109 | 			this.callback.call(this, null);
110 | 		} else {
111 | 			this.emit('debug', 'disconnected');
112 | 			if (this.data) {
113 | 				this.emit('debug', this.data.toString());
114 | 				if (this.callback) {
115 | 					this.callback.call(this, new Error(this.data));
116 | 				}
117 | 			}
118 | 		}
119 | 		this.command = BCMD.HI;
120 | 		// trying to establish connection at growing time intervals
121 | 		if (!this._connectionTimeout) {
122 | 			this._connectionTimeout = 0;
123 | 		} else {
124 | 			this._connectionTimeout += 1000;
125 | 		}
126 | 		setTimeout(function() {
127 | 			this.connect();
128 | 		}.bind(this), this._connectionTimeout);
129 | 		//self.connect();
130 | 	} else { // if we calls .disconnect() method
131 | 		if (this.callback) {
132 | 			this.callback.call(this); // disconnection callback
133 | 		}
134 | 	}
135 | }
136 | 
137 | /**
138 |  * Событие сокета на получение данных
139 |  * @private
140 |  * @this BoobstSocket
141 |  */
142 | function onData(data) {
143 | 	this.emit('debug', this.command + ' : ' + data.toString());
144 | 	switch (this.command) {
145 | 		case BCMD.NOP:
146 | 			this.emit('debug', 'Data on NOP command: ' + data.toString());
147 | 			this.command = BCMD.INPUT;
148 | 			this.callback = function(data) {
149 | 				this.emit('message', data);
150 | 				this.command = BCMD.NOP;
151 | 				this._runCommandFromQueue();
152 | 			};
153 | 			this.onDataCommon(data);
154 | 			break;
155 | 		case BCMD.SETENCODING: case BCMD.KEY: case BCMD.SET: case BCMD.KILL: case BCMD.EXECUTE: case BCMD.FLUSH: case BCMD.PING: case BCMD.GET: case BCMD.ORDER: case BCMD.XECUTE: case BCMD.INPUT:
156 | 		this.onDataCommon(data);
157 | 			break;
158 | 		case BCMD.ZN:
159 | 			this.onDataZn(data);
160 | 			break;
161 | 		case BCMD.BLOB:
162 | 			// do nothing, this error should be caught by onError event
163 | 			break;
164 | 		case BCMD.HI:
165 | 			this.killme = false;
166 | 			this.onDataGreeting(data);
167 | 			break;
168 | 		default:
169 | 			this.error('Lost data!');
170 | 			this.log(data.toString());
171 | 	}
172 | }
173 | 
174 | /**
175 |  * Boobst Socket
176 |  * @param {Object} options
177 |  * @param {number} [options.port] port
178 |  * @param {string} [options.host] host
179 |  * @property {Function} callback
180 |  * @property {Function} emit
181 |  * @extends events.EventEmitter
182 |  * @constructor
183 |  */
184 | var BoobstSocket = function(options) {
185 | 	/**
186 | 	 * Server's process id
187 | 	 * @type {number}
188 | 	 */
189 | 	this.id = 0;
190 | 	options = options || {};
191 | 	/**
192 | 	 * Protocol varsion
193 | 	 * @type {number}
194 | 	 */
195 | 	this.version = VERSION;
196 | 	this.out = null;
197 | 	/**
198 | 	 * Commands queue
199 | 	 * @type {Array}
200 | 	 */
201 | 	this.queue = [];
202 | 	/**
203 | 	 * Port
204 | 	 * @type {number}
205 | 	 */
206 | 	this.port = options.port || 6666;
207 | 	/**
208 | 	 * Host
209 | 	 * @type {string}
210 | 	 */
211 | 	this.host = options.host || options.server || 'localhost';
212 | 	if (options.ns) {
213 | 		this.ns = options.ns;
214 | 	}
215 | 	this.command = BCMD.HI;
216 | 	this.connected = false;
217 | 	this.killme = false;
218 | 	/**
219 | 	 * Connection socket
220 | 	 * @type {net.Socket}
221 | 	 */
222 | 	this.socket = new net.Socket();
223 | 	this.socket.bufferSize = 32000;
224 | 	this.socket.boobst = this;
225 | 	this.socket.on('connect', onConnection.bind(this));
226 | 	this.socket.on('close', onClose.bind(this));
227 | 	this.socket.on('data', onData.bind(this));
228 | 	this.socket.on('error', onError.bind(this));
229 | };
230 | 
231 | // events.EventEmitter inheritance
232 | util.inherits(BoobstSocket, events.EventEmitter);
233 | 
234 | /**
235 |  * Connect to DB
236 |  * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback
237 |  * @return {boobst.BoobstSocket}
238 |  */
239 | BoobstSocket.prototype.connect = function(callback) {
240 | 	try {
241 | 		this.emit('debug', 'trying to connect to ' + this.host + ':' + this.port + ' > ' + this.command);
242 | 		if (callback) {
243 | 			/**
244 | 			 *
245 | 			 * @type {(function(this:boobst.BoobstSocket, (null|Error)))}
246 | 			 */
247 | 			this.onConnectionCallback = callback;
248 | 		}
249 | 		this.socket.connect(this.port, this.host);
250 | 		delete this._connectionTimeout;
251 | 	} catch(e) {
252 | 		if (callback) {
253 | 			callback(new Error(e));
254 | 		}
255 | 	}
256 | 	return this;
257 | };
258 | 
259 | //----------------------------------------------------------------------------------------------------------------------
260 | /**
261 |  * Common event handler
262 |  * @private
263 |  * @param {Buffer} data binary data chunk
264 |  */
265 | BoobstSocket.prototype.onDataCommon = function(data) {
266 | 	// check if this chunk is the last one
267 | 	// it must have \0 character at the end
268 | 	if ((data.length > 0) && (data[data.length - 1] === 0)) {
269 | 		if (this.out && (this.command === BCMD.EXECUTE || this.command === BCMD.XECUTE)){ // if we're writing into stream
270 | 			this.out.end(data.slice(0, data.length - 1));
271 | 			delete this.out;
272 | 			if (this.callback) { // if we have callback
273 | 				this.callback.call(this, null); // we haven't get this.data here
274 | 			}
275 | 		} else {
276 | 			this.data = Buffer.concat([this.data, data.slice(0, data.length - 1)]);
277 | 			if (this.callback) { // if we have callback
278 | 				this.callback.call(this, null, this.data);
279 | 			}
280 | 		}
281 | 		process.nextTick(function() {
282 | 			this.command = BCMD.NOP;
283 | 			this._runCommandFromQueue();
284 | 		}.bind(this));
285 | 	} else {
286 | 		if (this.out && (this.command === BCMD.EXECUTE || this.command === BCMD.XECUTE)){ // if we're writing into stream
287 | 			this.out.write(data);
288 | 		} else {
289 | 			this.data = Buffer.concat([this.data, data]);
290 | 		}
291 | 	}
292 | };
293 | 
294 | BoobstSocket.prototype.onDataInput = function(data) {
295 | 
296 | };
297 | 
298 | /**
299 |  * Connect event handler
300 |  * @private
301 |  * @param {Buffer} data greeting
302 |  */
303 | BoobstSocket.prototype.onDataGreeting = function(data) {
304 | 	this.emit('debug', 'connected');
305 | 	this.connected = true;
306 | 	var dataStr = data.toString().split(';');
307 | 
308 | 	if (parseInt(dataStr[0], 10) !== this.version) {
309 | 		var err = new Error('Mismatch of protocol versions! server: ' + dataStr[0] + ', client: ' + this.version);
310 | 		if (this.onConnectionCallback) {
311 | 			this.onConnectionCallback(err);
312 | 		}
313 | 		return;
314 | 	}
315 | 
316 | 	// working with properly protocol version
317 | 	this.id = parseInt(dataStr[1], 10);
318 | 	// if we're in the different namespace when connected just switch to the right one
319 | 	if (this.ns) {
320 | 		if (this.ns !== dataStr[2]) {
321 | 			this.queue.unshift({
322 | 				cmd: BCMD.ZN
323 | 				, name: this.ns
324 | 			});
325 | 		}
326 | 	} else {
327 | 		this.ns = dataStr[2];
328 | 	}
329 | 
330 | 	if (this.onConnectionCallback) {
331 | 		this.onConnectionCallback.call(this);
332 | 		delete this.onConnectionCallback;
333 | 	}
334 | 
335 | 	process.nextTick(function() {
336 | 		this.command = BCMD.NOP;
337 | 		this._runCommandFromQueue();
338 | 	}.bind(this));
339 | };
340 | 
341 | /**
342 |  * Namespace change event handler
343 |  * @private
344 |  * @param {Buffer} data информация о смене
345 |  */
346 | BoobstSocket.prototype.onDataZn = function(data) {
347 | 	var str = data.toString().split('.');
348 | 
349 | 	if (str[0] === 'ok' && str[1] === 'zn') {
350 | 		this.ns = str[2].toUpperCase();
351 | 		this.emit('debug', 'IM ON ::: ' + this.ns);
352 | 		if (this.callback) {
353 | 			this.callback.call(this, null, true);
354 | 		}
355 | 	} else {
356 | 		if (this.callback) {
357 | 			this.callback.call(this, new Error(str));
358 | 		}
359 | 	}
360 | 	process.nextTick(function() {
361 | 		this.command = BCMD.NOP;
362 | 		this._runCommandFromQueue();
363 | 	}.bind(this));
364 | };
365 | //--------------------------------------------------------------------------
366 | /**
367 |  * Try to execute command
368 |  * If socket is not empty, command pushed into queue
369 |  * @param {Object} commandObject
370 |  * @private
371 |  */
372 | BoobstSocket.prototype._tryCommand = function(commandObject) { // попытаться выполнить комманду
373 | 	if (this.command !== BCMD.NOP || this.connected === false) {
374 | 		this.queue.push(commandObject);
375 | 	} else {
376 | 		this.data = new Buffer(0);
377 | 		this.command = commandObject.cmd;
378 | 		this.callback = commandObject.callback;
379 | 		this.emit('debug', 'command: ' + commandObject.cmd +
380 | 			(commandObject.name || commandObject.uri ? ', name: ' + (commandObject.name || commandObject.uri) : '') +
381 | 			(commandObject.value ? ', value:' +commandObject.value : '')
382 | 		);
383 | 		switch (commandObject.cmd) {
384 | 			case BCMD.EXECUTE:
385 | 				if (commandObject.out) {
386 | 					this.out = commandObject.out;
387 | 				}
388 | 				this.socket.write('E ' + commandObject.name + EOL);
389 | 				break;
390 | 			case BCMD.XECUTE:
391 | 				if (commandObject.out) {
392 | 					this.out = commandObject.out;
393 | 				}
394 | 				this.socket.write('X ' + commandObject.name + EOL);
395 | 				break;
396 | 			case BCMD.GET:
397 | 				this.socket.write('G ' + commandObject.forceJSON + EON + commandObject.name + EOL);
398 | 				break;
399 | 			case BCMD.KEY:
400 | 				this.socket.write('Q ' + commandObject.name + EON + commandObject.value + EOL);
401 | 				break;
402 | 			case BCMD.SETENCODING:
403 | 				this.socket.write('8 ' + commandObject.value + EOL);
404 | 				break;
405 | 			case BCMD.SET:
406 | 				this.socket.write('S ' + commandObject.name + EON + commandObject.value + EOL);
407 | 				break;
408 | 			case BCMD.KILL:
409 | 				this.socket.write('K ' + commandObject.name + EOL);
410 | 				break;
411 | 			case BCMD.FLUSH:
412 | 				this.socket.write('F' + EOL);
413 | 				break;
414 | 			case BCMD.PING:
415 | 				this.socket.write('P' + EOL);
416 | 				break;
417 | 			case BCMD.ORDER:
418 | 				this.socket.write('O '  + commandObject.name +  EOL);
419 | 				break;
420 | 			case BCMD.BLOB:
421 | 				this.socket.write('B ' + commandObject.uri + EOL);
422 | 				commandObject.stream.on('end', function() {
423 | 					this.socket.end();
424 | 					/*
425 | 					if (this.callback) { // если у нас есть коллбек
426 | 						this.callback.call(this, null);
427 | 					}
428 | 					*/
429 | 					//this.command = BCMD.NOP;
430 | 					//this.connect();
431 | 				}.bind(this));
432 | 				commandObject.stream.pipe(this.socket);
433 | 				var version = process.versions.node.split('.').map(function(num) {
434 | 					return parseInt(num);
435 | 				});
436 | 				if (version[0] === 0 && version[1] < 9) { // fix for old Streams 1 api
437 | 					commandObject.stream.resume();
438 | 				}
439 | 				break;
440 | 			case BCMD.ZN:
441 | 				this.socket.write('Z ' + commandObject.name + EOL);
442 | 				break;
443 | 			case BCMD.DISCONNECT:
444 | 				this.killme = true; // this is state to disconnect gracefully
445 | 				this.command = BCMD.HI; // we are ready to the next greeting from server
446 | 				this.socket.end();
447 | 				break;
448 | 			default:
449 | 				this.error("unknown command");
450 | 				this.error(commandObject);
451 | 		}
452 | 	}
453 | };
454 | 
455 | /**
456 |  * Execute routine
457 |  * @param {string} name имя существующей команды
458 |  * @param {stream.Stream} [outStream] поток, в который пересылать ответ сервера
459 |  * @param {function(this:boobst.BoobstSocket, (null|Error), Object)} callback callback
460 |  */
461 | BoobstSocket.prototype.execute = function(name, outStream, callback) {
462 | 	var cmd = {
463 | 		cmd: BCMD.EXECUTE,
464 | 		name: name
465 | 	};
466 | 	if (outStream) {
467 | 		if (typeof outStream === 'function') {
468 | 			cmd.callback = outStream;
469 | 		} else {
470 | 			cmd.out = outStream;
471 | 			if (callback) {
472 | 				cmd.callback = callback;
473 | 			}
474 | 		}
475 | 	}
476 | 	this._tryCommand(cmd);
477 | 	return this;
478 | };
479 | 
480 | /**
481 |  * Evaluates any code on the server. Dangerous thing disabled on server by default
482 |  * @param {string} xecute text to xecute
483 |  * @param {stream.Stream} [outStream] stream to send data
484 |  * @param {function(this:boobst.BoobstSocket, (null|Error), Object)} callback callback
485 |  */
486 | BoobstSocket.prototype.xecute = function(xecute, outStream, callback) {
487 | 	var cmd = {
488 | 		cmd: BCMD.XECUTE,
489 | 		name: xecute
490 | 	};
491 | 	if (outStream) {
492 | 		if (typeof outStream === 'function') {
493 | 			cmd.callback = outStream;
494 | 		} else {
495 | 			cmd.out = outStream;
496 | 			if (callback) {
497 | 				cmd.callback = callback;
498 | 			}
499 | 		}
500 | 	}
501 | 	this._tryCommand(cmd);
502 | 	return this;
503 | };
504 | 
505 | /**
506 |  * Get value
507 |  * @param {string} name Name of variable or global node
508 |  * @param {(Array<string>|boolean|function(this:boobst.BoobstSocket, (null|Error), Object))} [subscript]
509 |  * @param {boolean|function(this:boobst.BoobstSocket, (null|Error), Object)} [forceJSON] force get JSON from node
510 |  * @param {function(this:boobst.BoobstSocket, (null|Error), Buffer)} callback Callback-function (error, data)
511 |  */
512 | BoobstSocket.prototype.get = function(name, subscript, forceJSON, callback) {
513 | 	if (callback === undefined) {
514 | 		if (forceJSON !== undefined) {
515 | 			callback = forceJSON;
516 | 			if (typeof subscript === 'boolean') {
517 | 				forceJSON = subscript;
518 | 			} else {
519 | 				name = createNameFromSubscript(name, subscript);
520 | 				forceJSON = false;
521 | 			}
522 | 		} else {
523 | 			callback = subscript;
524 | 			forceJSON = false;
525 | 		}
526 | 	} else {
527 | 		name = createNameFromSubscript(name, subscript);
528 | 	}
529 | 	this._tryCommand({
530 | 		cmd: BCMD.GET,
531 | 		name: name,
532 | 		forceJSON: forceJSON ? 'f' : '',
533 | 		callback: callback
534 | 	});
535 | 	return this;
536 | };
537 | BoobstSocket.prototype.key = function(name, value, callback) {
538 | 	isValidCacheVar(name);
539 | 	this._tryCommand({
540 | 		cmd: BCMD.KEY,
541 | 		name: name,
542 | 		value: value,
543 | 		callback: callback
544 | 	});
545 | 	return this;
546 | };
547 | BoobstSocket.prototype.setEncoding = function(value, callback) {
548 | 	this._tryCommand({
549 | 		cmd: BCMD.SETENCODING,
550 | 		value: value,
551 | 		callback: callback
552 | 	});
553 | 	return this;
554 | };
555 | 
556 | /**
557 |  * Set the value of variable or global
558 |  * @param {string} name variable or global name (global name starts with `^`)
559 |  * @param {string|Buffer|Array<string>} [subscripts]
560 |  * @param {string|Buffer|function|number|Date} value variable value
561 |  * @param {?function(this:boobst.BoobstSocket, Error?, string?)} [callback] callback
562 |  * @return {boobst.BoobstSocket|BoobstSocket}
563 |  */
564 | BoobstSocket.prototype.set = function(name, subscripts, value, callback) {
565 | 	/** let this part will be filtered by server-side
566 | 	if (~name.indexOf('"')) {
567 | 		throw new Error("You couldn't use '\"' in variable names: " + name);
568 | 	}
569 | 	*/
570 | 	// polymorphism
571 | 	var completed
572 | 		, self = this
573 | 		, typeOfValue = typeof value
574 | 		;
575 | 	if (typeOfValue === 'function' || typeOfValue === 'undefined') { // missing subscripts attribute
576 | 		callback = value;
577 | 		value = subscripts;
578 | 		subscripts = [];
579 | 		typeOfValue = typeof value;
580 | 	}
581 | 
582 | 	// casting
583 | 	if (typeOfValue === 'undefined' || value === null) {
584 | 		return this;
585 | 	} else if (typeOfValue === 'number') { // number casts to string
586 | 		value = value.toString();
587 | 		typeOfValue = 'string';
588 | 	} else if (typeOfValue === 'boolean') {
589 | 		value = value ? '1true' : '0false';
590 | 		typeOfValue = 'string';
591 | 	} else if (value instanceof Date) { // date casts to string
592 | 		value = value.toJSON();
593 | 		typeOfValue = 'string';
594 | 	}
595 | 
596 | 	if (typeOfValue === 'string' || Buffer.isBuffer(value)) {
597 | 		if (typeOfValue === 'string' && Buffer.byteLength(value) > CACHE_MAX_SIZE || value.length > CACHE_MAX_SIZE) {
598 | 			value = new Buffer(value);
599 | 			callback = callback || function() {};
600 | 			completed = 0;
601 | 			for (var length = value.length, i = 0, begin = 0; begin < length; i += 1, begin += CACHE_MAX_SIZE) {
602 | 				completed += 1;
603 | 				this.set(name, i ? subscripts.concat(i) : subscripts, value.slice(begin, begin + CACHE_MAX_SIZE), function(err) {
604 | 					if (err) {
605 | 						callback(err);
606 | 						callback = function() {};
607 | 					} else {
608 | 						completed -= 1;
609 | 						if (completed === 0) {
610 | 							callback.call(this, null);
611 | 						}
612 | 					}
613 | 				});
614 | 			}
615 | 			return this;
616 | 		} else {
617 | 			name = createNameFromSubscript(name, subscripts);
618 | 			isValidCacheVar(name);
619 | 			this._tryCommand({
620 | 				cmd: BCMD.SET,
621 | 				name: name,
622 | 				value: value,
623 | 				callback: callback
624 | 			});
625 | 			return this;
626 | 		}
627 | 	} else if (typeOfValue === 'function') {
628 | 		// do nothing TODO function stringify option
629 | 		return this;
630 | 	} else if (typeOfValue === 'object') { // object or array
631 | 		completed = Object.keys(value).length;
632 | 		Object.keys(value).forEach(function(key) {
633 | 			self.set(name, subscripts.concat(key), value[key], function(err) {
634 | 				if (err && callback) {
635 | 					callback(err);
636 | 					callback = function() {};
637 | 				}
638 | 				completed -= 1;
639 | 				if (completed === 0 && callback) {
640 | 					callback.call(this, null);
641 | 				}
642 | 			});
643 | 		});
644 | 		return this;
645 | 	} else {
646 | 		var err = new Error('Method `set` can accept only `string`, `object`, `Buffer`, `number`, `Date` value types. And ignores `function`. Not: ' + value);
647 | 		if (callback) {
648 | 			callback(err);
649 | 		} else {
650 | 			throw err;
651 | 		}
652 | 		return this;
653 | 	}
654 | };
655 | 
656 | 
657 | /**
658 |  * Save javascript-оbject in Cache'
659 |  * @param {string} variable or global name (global name starts with `^`)
660 |  * @param {Array.<string>} [subscripts]
661 |  * @param {Object} object javascript-object
662 |  * @param {function(?Error)} [callback] callback
663 |  * @deprecated
664 |  */
665 | BoobstSocket.prototype.saveObject = BoobstSocket.prototype.set;
666 | 
667 | /**
668 |  * Returns next subscript based on current
669 |  * @param name
670 |  * @param subscript
671 |  * @param {Function} callback
672 |  */
673 | BoobstSocket.prototype.order = BoobstSocket.prototype.next = function(name, subscript, callback) {
674 | 	name = createNameFromSubscript(name, subscript);
675 | 	this._tryCommand({
676 | 		cmd: BCMD.ORDER,
677 | 		name: name,
678 | 		callback: callback
679 | 	});
680 | 	return this;
681 | };
682 | 
683 | /**
684 |  * Changes namespace
685 |  * @param {string} name existing namespace
686 |  * @param {function} [callback] callback
687 |  */
688 | BoobstSocket.prototype.zn = function(name, callback) {
689 | 	this._tryCommand({
690 | 		cmd: BCMD.ZN,
691 | 		name: name,
692 | 		callback: callback
693 | 	});
694 | 	/*
695 | 	if (name.toUpperCase() !== this.ns) {
696 | 		this._tryCommand({
697 | 			cmd: BCMD.ZN,
698 | 			name: name,
699 | 			callback: callback
700 | 		});
701 | 	} else {
702 | 		if (callback) {
703 | 			callback.call(this, null, false);
704 | 		}
705 | 	}
706 | 	*/
707 | 	return this;
708 | };
709 | 
710 | /**
711 |  * Kill a global or a local
712 |  * @param {string} name
713 |  * @param {Array<string> | function(this:boobst.BoobstSocket, (null|Error))} [subscripts]
714 |  * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback
715 |  */
716 | BoobstSocket.prototype.kill = function(name, subscripts, callback) {
717 | 	if (typeof callback === 'undefined' && typeof subscripts === 'function') {
718 | 		callback = subscripts;
719 | 		subscripts = [];
720 | 	}
721 | 	name = createNameFromSubscript(name, subscripts);
722 | 	this._tryCommand({
723 | 		cmd: BCMD.KILL,
724 | 		name: name,
725 | 		callback: callback
726 | 	});
727 | 	return this;
728 | };
729 | 
730 | /**
731 |  * Send binary data
732 |  * @param {string} uri uri format is: file://<file_path> or global://<global_name_w/o_^>
733 |  * @param {Stream} stream data stream
734 |  * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback
735 |  */
736 | BoobstSocket.prototype.blob = function(uri, stream, callback) {
737 | 	var arr = uri.split('://');
738 | 	if (arr.length !== 2) {
739 | 		throw new Error('Invalid uri for blob command: "' + uri + '"');
740 | 	}
741 | 	if (arr[0] === 'global') {
742 | 		isValidCacheVar(arr[1]);
743 | 	}
744 | 	this._tryCommand({
745 | 		cmd: BCMD.BLOB
746 | 		, stream: stream
747 | 		, uri: uri
748 | 		, callback: callback
749 | 	});
750 | 	return this;
751 | };
752 | 
753 | /**
754 |  * Clear the local namespace and set the server variables again
755 |  * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback
756 |  */
757 | BoobstSocket.prototype.flush = function(callback) {
758 | 	this._tryCommand({cmd: BCMD.FLUSH, callback: callback});
759 | 	return this;
760 | };
761 | 
762 | /**
763 |  * Check server state
764 |  * @param {function(this:boobst.BoobstSocket, (null|Error), {string})} [callback] callback
765 |  */
766 | BoobstSocket.prototype.ping = function(callback) {
767 | 	this._tryCommand({cmd: BCMD.PING, callback: callback});
768 | 	return this;
769 | };
770 | 
771 | BoobstSocket.prototype.increment = function(name, subscripts, value, callback) {
772 | 	if (callback === undefined) {
773 | 		switch (typeof subscripts) {
774 | 			case 'number':
775 | 				callback = value;
776 | 				value = subscripts;
777 | 				subscripts = [];
778 | 				break;
779 | 			case 'function':
780 | 				callback = subscripts;
781 | 				value = 1;
782 | 				subscripts = [];
783 | 				break;
784 | 			case 'object':
785 | 				callback = value;
786 | 				value = 1;
787 | 		}
788 | 	}
789 | 	this.get(name, subscripts, function(err, data) {
790 | 		var inc = Number(data.toString());
791 | 		inc = (isNaN(inc) ? 0 : inc) + value;
792 | 		// TODO global lock
793 | 		this.set(name, subscripts, inc, function(err) {
794 | 			if (err) {
795 | 				callback(err);
796 | 			} else {
797 | 				callback(null, inc);
798 | 			}
799 | 		});
800 | 	});
801 | };
802 | 
803 | /**
804 |  * Disconnect from the db
805 |  * @param {function(this:boobst.BoobstSocket, (null|Error))} [callback] callback
806 |  */
807 | BoobstSocket.prototype.disconnect = function(callback) {
808 | 	this._tryCommand({cmd: BCMD.DISCONNECT, callback: callback});
809 | 	return this;
810 | };
811 | 
812 | /**
813 |  * Start next command from the queue
814 |  * @private
815 |  */
816 | BoobstSocket.prototype._runCommandFromQueue = function() {
817 | 	if (this.queue.length > 0) {
818 | 		var task = this.queue.shift();
819 | 		this._tryCommand(task);
820 | 	}
821 | };
822 | 
823 | //--------------------------------------------------------------------------
824 | function isValidCacheVar(name) {
825 | 	/* TODO fix it
826 | 	if (!VALID_CACHE_VAR_RE.test(name)) {
827 | 		throw new Error('"' + name + "\" isn't a valid Cache' variable name");
828 | 	}
829 | 	*/
830 | }
831 | 
832 | function createNameFromSubscript(name, subscript) {
833 | 	if (Array.isArray(subscript) && subscript.length > 0) {
834 | 		return name + '(' + subscript.map(function(sub) {return '"' + sub + '"';}).join(',') + ')';
835 | 	} else {
836 | 		return name;
837 | 	}
838 | }
839 | 
840 | BoobstSocket.prototype.error = function(text) {
841 | 	this.emit('debug', text);
842 | };
843 | BoobstSocket.prototype.log = function(text) {
844 | 	this.emit('debug', text);
845 | };
846 | //--------------------------------------------------------------------------
847 | BoobstSocket.prototype.port = 6666;
848 | 
849 | exports.BoobstSocket = BoobstSocket;
850 | 
851 |
852 |
853 | 854 | 855 | 856 | 857 |
858 | 859 | 862 | 863 |
864 | 865 |
866 | Documentation generated by JSDoc 3.4.0 on Wed Aug 03 2016 15:56:44 GMT+0300 (MSK) 867 |
868 | 869 | 870 | 871 | 872 | 873 | --------------------------------------------------------------------------------