├── test ├── config.js ├── put-inc-get-tests.js └── scan-tests.js ├── examples ├── incRow.js ├── delRow.js ├── inc.js ├── putRow.js ├── put.js ├── scan.js ├── del.js ├── getRow.js └── get.js ├── src ├── inc.js ├── del.js ├── lru-cache.js ├── put.js ├── cache.js ├── mutate.js ├── serde.js ├── get.js ├── scan.js ├── scan-stream.js ├── client-pool.js ├── service.js └── client.js ├── LICENSE ├── .gitignore ├── package.json ├── README.md ├── 1.1.13 └── hbase.thrift └── gen-nodejs └── hbase_types.js /test/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | assets: { 3 | testTableName: 'test:test' 4 | }, 5 | hbase: { 6 | hosts: ['localhost'], 7 | port: 9090, 8 | minConnections: 0, 9 | maxConnections: 20, 10 | idleTimeoutMillis: 5 * 60 * 1000, 11 | timeout: 60000 12 | } 13 | }; -------------------------------------------------------------------------------- /examples/incRow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rubinus on 14-10-20. 3 | */ 4 | var HBase = require('../'); 5 | 6 | var config = { 7 | host: 'master', 8 | port: 9090 9 | }; 10 | 11 | var hbaseClient = HBase.client(config); 12 | 13 | 14 | hbaseClient.incRow('users','row1','info:counter',function(err,data){ //inc users table 15 | if(err){ 16 | console.log('error:',err); 17 | return; 18 | } 19 | console.log(err,data); 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /examples/delRow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rubinus on 14-10-20. 3 | */ 4 | var HBase = require('../'); 5 | 6 | var config = { 7 | host: 'master', 8 | port: 9090 9 | }; 10 | 11 | var hbaseClient = HBase.client(config); 12 | 13 | hbaseClient.delRow('users','row1','info:name',1414137991649,function(err){ //put users table 14 | if(err){ 15 | console.log('error:',err); 16 | return; 17 | } 18 | console.log(err,'del is successfully'); 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /examples/inc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rubinus on 14-10-20. 3 | */ 4 | var HBase = require('../'); 5 | 6 | var config = { 7 | host: 'master', 8 | port: 9090 9 | }; 10 | 11 | var hbaseClient = HBase.client(config); 12 | 13 | var inc = hbaseClient.Inc('row1'); //row1 is rowKey 14 | 15 | inc.add('info','counter'); 16 | 17 | inc.add('info','counter2'); 18 | 19 | hbaseClient.inc('users',inc,function(err,data){ //inc users table 20 | if(err){ 21 | console.log('error:',err); 22 | return; 23 | } 24 | console.log(err,data); 25 | }); 26 | 27 | -------------------------------------------------------------------------------- /src/inc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const HBaseTypes = require('../gen-nodejs/hbase_types'); 4 | 5 | const Mutate = require('./mutate'); 6 | 7 | class Inc extends Mutate { 8 | 9 | static getThriftType() { 10 | return HBaseTypes.TIncrement; 11 | } 12 | 13 | static getThriftColumnType(){ 14 | return HBaseTypes.TColumnIncrement; 15 | } 16 | 17 | add(family, qualifier, amount) { 18 | const familyMap = {}; 19 | familyMap.family = family; 20 | familyMap.qualifier = qualifier; 21 | familyMap.amount = (amount === 0) ? 0 : (amount || 1); 22 | this.columns.push(familyMap); 23 | return this; 24 | } 25 | 26 | } 27 | 28 | module.exports = Inc; -------------------------------------------------------------------------------- /examples/putRow.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = { 4 | hosts: ["master"], 5 | port: "9090", 6 | }; 7 | 8 | var HBase = require('../src/service')(config); 9 | 10 | HBase.putRow('users', 'row1', 'info:name', 'phoneqq.com', 1414140874929, 11 | function (err) { 12 | if (err) { 13 | console.log('error:', err); 14 | return; 15 | } 16 | console.log('Put is successfull.'); 17 | }); 18 | 19 | HBase.putRowAsync('users', 'row1', 'info:name', 'phoneqq.com', 1414140874929) 20 | .then(function () { 21 | console.log('Put is successfull.'); 22 | }) 23 | .catch(function (err) { 24 | console.log('error:', err); 25 | }); 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Exposebox 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | 3 | # Created by .ignore support plugin (hsz.mobi) 4 | ### Node template 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (http://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional REPL history 41 | .node_repl_history -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-thrift2-hbase", 3 | "version": "0.6.2", 4 | "description": "Easy to CRUD for hbase by node-thrift-hbase", 5 | "main": "src/service.js", 6 | "dependencies": { 7 | "bluebird": "^3.5.5", 8 | "caching-map": "git+https://github.com/exposebox/caching-map.git", 9 | "debug": "^4.1.1", 10 | "generic-pool": "^2.5.4", 11 | "ms": "^2.1.1", 12 | "node-int64": "^0.4.0", 13 | "thrift": "^0.12.0", 14 | "underscore": "^1.9.1" 15 | }, 16 | "devDependencies": { 17 | "mocha": "^6.1.4", 18 | "should": "^13.2.3" 19 | }, 20 | "scripts": { 21 | "test": "mocha" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "http://github.com/exposebox/node-thrift2-hbase" 26 | }, 27 | "author": "orel@exposebox.com", 28 | "contributors": [ 29 | "orel@exposebox.com", 30 | "ran@exposebox.com", 31 | "eran@exposebox.com" 32 | ], 33 | "license": "ISC", 34 | "keywords": [ 35 | "hbase", 36 | "node", 37 | "thrift" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /examples/put.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = { 4 | hosts: ["master"], 5 | port: "9090", 6 | }; 7 | 8 | var HBase = require('../src/service')(config); 9 | 10 | var put = HBase.Put('row1'); 11 | 12 | // cf qualifier value 13 | put.add('info', 'money', {type: 'float', value: 12.34}); 14 | 15 | put.add('info', 'click', {type: 'integer', value: 100}); 16 | 17 | //string values don't need a wrapper object 18 | put.add('ecf', 'name', 'zhudaxian'); 19 | 20 | // timestamp 21 | put.add('info', 'name', 'beijing', new Date().getTime()); 22 | 23 | 24 | HBase.put('users', put, function (err) { 25 | if (err) { 26 | console.log('error:', err); 27 | return; 28 | } 29 | 30 | console.log('Put is successful.'); 31 | }); 32 | 33 | HBase.putAsync('users', put) 34 | .then(function () { 35 | console.log('Put is successful.'); 36 | }) 37 | .catch(function (err) { 38 | console.log('error:', err); 39 | }); 40 | -------------------------------------------------------------------------------- /examples/scan.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | 5 | var config = { 6 | hosts: ["master"], 7 | port: "9090", 8 | }; 9 | 10 | var HBase = require('../src/service')(config); 11 | 12 | 13 | var scan = HBase.Scan(); 14 | 15 | scan.setStartRow('start'); 16 | scan.setStartRow('end'); 17 | scan.add('sc'); //scan all family info 18 | 19 | HBase.scan('dmp:users_categories', scan, function (err, data) { //get users table 20 | if (err) { 21 | console.log('error:', err); 22 | return; 23 | } 24 | 25 | console.log('Total rows scanned:', data.length); 26 | 27 | console.log('First row column values:'); 28 | console.log('========================'); 29 | _.each(data[0].columnValues, function (colVal, index) { 30 | console.log('Column value #', index); 31 | console.log('family:', colVal.family.toString()); 32 | console.log('qualifier:', colVal.qualifier.toString()); 33 | console.log('value:', colVal.value.readInt32BE(0, 4)); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/del.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Mutate = require('./mutate'); 4 | 5 | class Del extends Mutate { 6 | 7 | add(family, qualifier, timestamp) { 8 | var familyMap = {}; 9 | familyMap.family = family; 10 | if (qualifier) { 11 | familyMap.qualifier = qualifier; 12 | } 13 | if (timestamp) { 14 | familyMap.timestamp = timestamp; 15 | } 16 | this.columns.push(familyMap); 17 | return this; 18 | } 19 | 20 | addFamily(family) { 21 | var familyMap = {}; 22 | familyMap.family = family; 23 | this.columns.push(familyMap); 24 | return this; 25 | } 26 | 27 | addColumn(family, qualifier) { 28 | var familyMap = {}; 29 | familyMap.family = family; 30 | familyMap.qualifier = qualifier; 31 | this.columns.push(familyMap); 32 | return this; 33 | } 34 | 35 | addTimestamp(family, qualifier, timestamp) { 36 | var familyMap = {}; 37 | familyMap.family = family; 38 | familyMap.qualifier = qualifier; 39 | familyMap.timestamp = timestamp; 40 | this.columns.push(familyMap); 41 | return this; 42 | } 43 | } 44 | 45 | module.exports = Del; -------------------------------------------------------------------------------- /examples/del.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rubinus on 14-10-20. 3 | */ 4 | var HBase = require('../'); 5 | 6 | var config = { 7 | host: 'master', 8 | port: 9090 9 | }; 10 | 11 | var hbaseClient = HBase.client(config); 12 | 13 | var del = hbaseClient.Del('row1'); //row1 is rowKey 14 | 15 | //del.addFamily('ips'); //delete family ips 16 | //del.addColumn('info','name'); //delete family and qualifier info:name 17 | //del.addTimestamp('info','tel',1414136046864); //delete info:tel and timestamp 18 | 19 | //or Recommend this function add 20 | 21 | del.add('info'); //delete all family info 22 | del.add('info','name'); //delete family and qualifier info:name 23 | del.add('info','tel',1414136046864); //delete info:tel and timestamp 24 | 25 | del.add('ecf'); //delete other family ecf 26 | del.add('ecf','name'); //delete family and qualifier ecf:name 27 | del.add('ecf','tel',1414136119207); //delete info:tel and timestamp 28 | 29 | //del.add('ips'); //is error ,because this family ips is not exist 30 | 31 | hbaseClient.del('users',del,function(err){ //put users table 32 | if(err){ 33 | console.log('error:',err); 34 | return; 35 | } 36 | console.log(err,'del is successfully'); 37 | }); 38 | 39 | -------------------------------------------------------------------------------- /src/lru-cache.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | const Promise = require('bluebird'); 5 | const LRUCache = require('lru-native'); 6 | const crypto = require('crypto'); 7 | 8 | const debug = require('debug')('node-thrift2-hbase:HBaseFallThroughLRUCache'); 9 | 10 | function md5(data) { 11 | if (!data) 12 | return; 13 | return crypto.createHash('md5').update(data, 'utf8').digest("hex"); 14 | } 15 | 16 | class HBaseFallThroughLRUCache { 17 | 18 | constructor(fetch, options) { 19 | this.cache = new LRUCache(options); 20 | this.fetch = fetch; 21 | } 22 | 23 | get(table, getObj, options, callback) { 24 | const cache = this.cache; 25 | const cacheKey = md5(JSON.stringify(getObj.row) + JSON.stringify(options)); 26 | const value = cache.get(cacheKey); 27 | 28 | function _callback(err, valueFromHBase) { 29 | if (err) { 30 | debug('error fetching data:', err); 31 | return callback(err); 32 | } 33 | 34 | cache.set(cacheKey, valueFromHBase); 35 | callback(null, valueFromHBase); 36 | } 37 | 38 | if (value) { 39 | return callback(null, value) 40 | } 41 | else { 42 | this.fetch(table, getObj, _callback); 43 | } 44 | } 45 | } 46 | 47 | Promise.promisifyAll(HBaseFallThroughLRUCache.prototype); 48 | 49 | module.exports = HBaseFallThroughLRUCache; -------------------------------------------------------------------------------- /src/put.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const HBaseTypes = require('../gen-nodejs/hbase_types'); 4 | 5 | const Int64 = require('node-int64'); 6 | 7 | const serde = require('./serde'); 8 | 9 | const Mutate = require('./mutate'); 10 | 11 | class Put extends Mutate { 12 | 13 | static getThriftType() { 14 | return HBaseTypes.TPut; 15 | } 16 | 17 | static getThriftColumnType() { 18 | return HBaseTypes.TColumnValue; 19 | } 20 | 21 | add(family, qualifier, value, timestamp) { 22 | var familyMap = {}; 23 | familyMap.family = family; 24 | familyMap.qualifier = qualifier; 25 | familyMap.value = serde.serialize(value); 26 | 27 | if (timestamp) { 28 | familyMap.timestamp = new Int64(timestamp); 29 | } 30 | 31 | this.columns.push(familyMap); 32 | return this; 33 | } 34 | 35 | addObject(family, object, timestamp) { 36 | for (const prop in object) { 37 | const value = object[prop]; 38 | if (value !== undefined && value !== null) { 39 | if (Array.isArray(value)) { 40 | this.add(family, prop, {type: 'json', value}, timestamp); 41 | } else if (typeof value === 'object') { 42 | this.addObject(family, value, timestamp); 43 | } else { 44 | this.add(family, prop, value, timestamp); 45 | } 46 | } 47 | } 48 | } 49 | 50 | } 51 | 52 | 53 | module.exports = Put; -------------------------------------------------------------------------------- /examples/getRow.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = { 4 | hosts: ["master"], 5 | port: "9090", 6 | }; 7 | 8 | var HBase = require('../src/service')(config); 9 | 10 | HBase.getRow('users', 'row1', ['info:name', 'ecf'], 1, 11 | function (err, data) { 12 | if (err) { 13 | console.log('error:', err); 14 | return; 15 | } 16 | console.log("Data for user with key 'row1':"); 17 | console.log('=============================='); 18 | _.each(data[0].columnValues, function (colVal, index) { 19 | console.log('Column value #', index); 20 | console.log('family:', colVal.family.toString()); 21 | console.log('qualifier:', colVal.qualifier.toString()); 22 | console.log('value:', colVal.value.readInt32BE(0, 4)); 23 | }); 24 | }); 25 | 26 | HBase.getRowAsync('users', 'row1', ['info:name', 'ecf'], 1) 27 | .then(function (data) { 28 | console.log("Data for user with key 'row1':"); 29 | console.log('=============================='); 30 | _.each(data[0].columnValues, function (colVal, index) { 31 | console.log('Column value #', index); 32 | console.log('family:', colVal.family.toString()); 33 | console.log('qualifier:', colVal.qualifier.toString()); 34 | console.log('value:', colVal.value.readInt32BE(0, 4)); 35 | }); 36 | }) 37 | .catch(function (err) { 38 | console.log('error:', err); 39 | }); -------------------------------------------------------------------------------- /src/cache.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | const ms = require('ms'); 5 | const Promise = require('bluebird'); 6 | const Cache = require('caching-map'); 7 | 8 | const debug = require('debug')('node-thrift2-hbase:cache'); 9 | 10 | 11 | class HBaseThriftClientCache extends Cache { 12 | 13 | constructor(fetchfunction, options) { 14 | super((options && options.limit ) || 500000); 15 | 16 | this.fetch = fetchfunction; 17 | this.ttl = (options && options.ttl) || ms('5m'); 18 | this.materialize = function (getObj) { 19 | debug('materializing', getObj); 20 | return fetchfunction(getObj.table, getObj); 21 | }; 22 | 23 | this.generateKey = function(keyObj) { 24 | return [keyObj.table, 25 | keyObj.row, 26 | keyObj.maxVersions, 27 | keyObj.timeRange, 28 | keyObj.columns.map(cell => cell.family + ":" + cell.qualifier).sort().join(","), 29 | Object.entries(keyObj.columnTypes).map(keyValue => keyValue.join(":")).sort().join(",")].join("."); 30 | } 31 | } 32 | 33 | 34 | get(table, getObj, options, callback) { 35 | getObj.table = table; 36 | debug(getObj); 37 | 38 | super.get(getObj) 39 | .then(value =>{ 40 | callback(null, value); 41 | }) 42 | .catch(err => callback(err)); 43 | } 44 | 45 | } 46 | 47 | Promise.promisifyAll(HBaseThriftClientCache.prototype); 48 | 49 | module.exports = HBaseThriftClientCache; -------------------------------------------------------------------------------- /src/mutate.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class Mutate { 4 | 5 | static getThriftType() { 6 | throw new Error('UNIMPLEMENTED'); 7 | } 8 | 9 | static getThriftColumnType(){ 10 | throw new Error('UNIMPLEMENTED'); 11 | } 12 | 13 | constructor(row) { 14 | this.row = row; 15 | this.columns = []; 16 | } 17 | 18 | setDurability(type) { 19 | this.durability = type; 20 | } 21 | 22 | setSkipWalDurability() { 23 | this.setDurability(1); 24 | } 25 | 26 | setAsyncWalDurability() { 27 | this.setDurability(2); 28 | } 29 | 30 | setSyncWalDurability() { 31 | this.setDurability(3); 32 | } 33 | 34 | setFSyncWalDurability() { 35 | this.setDurability(4); 36 | } 37 | 38 | setAttributes(attributeMap) { 39 | this.attributes = attributeMap; 40 | } 41 | 42 | createThriftArgs() { 43 | 44 | const ThriftColumnType = this.constructor.getThriftColumnType(); 45 | 46 | const thriftArgs = { 47 | row: this.row, 48 | durability: this.durability, 49 | attributes: this.attributes 50 | }; 51 | 52 | const qcolumns = []; 53 | if (this.columns && this.columns.length > 0) { 54 | for (const col of this.columns) { 55 | qcolumns.push(new ThriftColumnType(col)); 56 | } 57 | thriftArgs.columns = qcolumns; 58 | } 59 | 60 | thriftArgs.columnValues = qcolumns; 61 | 62 | return thriftArgs; 63 | } 64 | 65 | createThriftObject() { 66 | 67 | const args = this.createThriftArgs(); 68 | 69 | const ThriftType = this.constructor.getThriftType(); 70 | 71 | return new ThriftType(args); 72 | } 73 | 74 | } 75 | 76 | module.exports = Mutate; -------------------------------------------------------------------------------- /examples/get.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = { 4 | hosts: ["master"], 5 | port: "9090", 6 | }; 7 | 8 | var HBase = require('../src/service')(config); 9 | 10 | var get = HBase.Get('row1'); //row1 is rowKey 11 | get.addFamily('cf'); 12 | // get.add('cf'); identical to addFamily 13 | 14 | get.addColumn('info', 'name'); 15 | // get.add('info', 'name'); identical to addColumn 16 | 17 | get.addTimestamp('info', 'name', 1414385447707); 18 | // get.add('info', 'name', 1414385447707); identical to addTimestamp 19 | 20 | get.setMaxVersions(3); 21 | 22 | //last ten days as timerange 23 | get.setTimeRange({ 24 | minStamp: Date.now() - 10 * 24 * 60 * 60 * 1000, 25 | maxStamp: Date.now() 26 | }); 27 | 28 | HBase.getAsync('users', get) 29 | .then(function (data) { 30 | console.log("Data for user with key 'row1':"); 31 | console.log('=============================='); 32 | _.each(data[0].columnValues, function (colVal, index) { 33 | console.log('Column value #', index); 34 | console.log('family:', colVal.family.toString()); 35 | console.log('qualifier:', colVal.qualifier.toString()); 36 | console.log('value:', colVal.value.readInt32BE(0, 4)); 37 | }); 38 | }) 39 | .catch(function (err) { 40 | console.log('error:', err); 41 | }); 42 | 43 | HBase.get('users', get, function (err, data) { //get users table 44 | if (err) { 45 | console.log('error:', err); 46 | return; 47 | } 48 | 49 | console.log("Data for user with key 'row1':"); 50 | console.log('=============================='); 51 | _.each(data[0].columnValues, function (colVal, index) { 52 | console.log('Column value #', index); 53 | console.log('family:', colVal.family.toString()); 54 | console.log('qualifier:', colVal.qualifier.toString()); 55 | console.log('value:', colVal.value.readInt32BE(0, 4)); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /src/serde.js: -------------------------------------------------------------------------------- 1 | const Int64 = require('node-int64'); 2 | 3 | function serialize(valueObj) { 4 | if (typeof valueObj != 'object') { 5 | return new Buffer(valueObj.toString()); 6 | } 7 | 8 | switch (valueObj.type) { 9 | case "string": 10 | return new Buffer(valueObj.value.toString()); 11 | case "json": 12 | return new Buffer(JSON.stringify(valueObj.value)); 13 | case "integer": 14 | case "integer32": 15 | var buf = new Buffer(4); 16 | buf.writeInt32BE(valueObj.value, 0); 17 | return buf; 18 | case "float": 19 | var buf = new Buffer(4); 20 | buf.writeFloatBE(valueObj.value, 0); 21 | return buf; 22 | case 'double': 23 | var buf = new Buffer(8); 24 | buf.writeDoubleBE(valueObj.value, 0); 25 | return buf; 26 | case "number": 27 | case "integer48": 28 | var buf = new Buffer(8); 29 | buf.writeIntBE(valueObj.value, 2, 6); 30 | return buf; 31 | case "UInteger48": 32 | var buf = new Buffer(6); 33 | buf.writeUIntBE(valueObj.value, 0); 34 | return buf; 35 | case "int64": 36 | return valueObj.value.buffer; 37 | default: 38 | return new Buffer(valueObj.toString()); 39 | } 40 | } 41 | 42 | function deserialize(buf, type) { 43 | switch (type) { 44 | case "string": 45 | return buf.toString(); 46 | case "json": 47 | return JSON.parse(buf.toString()); 48 | case "integer": 49 | case "integer32": 50 | return buf.readInt32BE(); 51 | case "float": 52 | return buf.readFloatBE(); 53 | case 'double': 54 | return buf.readDoubleBE(); 55 | case "number": 56 | case "integer48": 57 | return buf.readIntBE(2, 6); 58 | case "UInteger48": 59 | return buf.readUIntBE(0); 60 | case "int64": 61 | return new Int64(buf); 62 | default: 63 | return buf.toString(); 64 | } 65 | } 66 | 67 | module.exports = { 68 | serialize, 69 | deserialize 70 | }; -------------------------------------------------------------------------------- /src/get.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const _ = require('underscore'); 3 | var Int64 = require('node-int64'); 4 | 5 | const serde = require('./serde'); 6 | 7 | class Get { 8 | constructor(row, options) { 9 | this.row = row; 10 | this.setMaxVersions(options && options.maxVersions); 11 | this.setTimeRange(options && options.timeRange); 12 | this.columns = []; 13 | this.columnTypes = {}; 14 | } 15 | 16 | add(family, qualifier, timestamp) { 17 | var familyMap = {}; 18 | familyMap.family = family; 19 | if (qualifier) { 20 | if (typeof qualifier === 'object') { 21 | familyMap.qualifier = qualifier.name; 22 | const columnFullName = family + qualifier.name; 23 | this.columnTypes[columnFullName] = qualifier.type; 24 | } 25 | else { 26 | familyMap.qualifier = qualifier; 27 | } 28 | } 29 | 30 | if (timestamp) { 31 | familyMap.timestamp = new Int64(timestamp); 32 | } 33 | this.columns.push(familyMap); 34 | return this; 35 | } 36 | 37 | objectFromData(hbaseRowData) { 38 | if (_.isEmpty(this.columnTypes)) { 39 | return hbaseRowData; 40 | } 41 | 42 | const obj = {}; 43 | obj.rowkey = hbaseRowData.row ? hbaseRowData.row.toString() : null; 44 | _.each(hbaseRowData.columnValues, colVal => { 45 | const family = colVal.family.toString(); 46 | const qualName = colVal.qualifier.toString(); 47 | const columnFullName = family + qualName; 48 | const columnType = this.columnTypes[columnFullName]; 49 | obj[family] = obj[family] || {}; 50 | obj[family][qualName] = serde.deserialize(colVal.value, columnType); 51 | }); 52 | 53 | return obj; 54 | } 55 | 56 | addFamily(family) { 57 | var familyMap = {}; 58 | familyMap.family = family; 59 | this.columns.push(familyMap); 60 | return this; 61 | } 62 | 63 | addColumn(family, qualifier) { 64 | return this.add(family, qualifier); 65 | } 66 | 67 | addTimestamp(family, qualifier, timestamp) { 68 | return this.add(family, qualifier, timestamp); 69 | } 70 | 71 | // default to 1 for performance, HBase default is 3 72 | setMaxVersions(maxVersions) { 73 | if (!maxVersions || maxVersions <= 0) { 74 | maxVersions = 1; 75 | } 76 | this.maxVersions = maxVersions; 77 | return this; 78 | } 79 | 80 | setTimeRange(timeRange) { 81 | this.timeRange = timeRange; 82 | return this; 83 | } 84 | } 85 | 86 | module.exports = Get; -------------------------------------------------------------------------------- /src/scan.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const _ = require('underscore'); 4 | const serde = require('./serde'); 5 | const Int64 = require('node-int64'); 6 | 7 | class Scan { 8 | constructor(options) { 9 | Object.assign(this, this.getDefaultOptions(), options); 10 | } 11 | 12 | getDefaultOptions() { 13 | return { 14 | startRow: undefined, 15 | stopRow: undefined, 16 | maxVersions: 1, 17 | filterString: undefined, 18 | columns: [], 19 | columnTypes: {}, 20 | chunkSize: 250 21 | }; 22 | } 23 | 24 | setStartRow(startRow) { 25 | this.startRow = startRow; 26 | return this; 27 | }; 28 | 29 | setStopRow(stopRow) { 30 | this.stopRow = stopRow; 31 | return this; 32 | }; 33 | 34 | setLimit(numRows) { 35 | this.numRows = numRows; 36 | return this; 37 | }; 38 | 39 | setMaxVersions(maxVersions) { 40 | if (maxVersions <= 0) { 41 | maxVersions = 1; 42 | } 43 | this.maxVersions = maxVersions; 44 | return this; 45 | }; 46 | 47 | setFilterString(filterString) { 48 | this.filterString = filterString; 49 | return this; 50 | }; 51 | 52 | setChunkSize(chunkSize) { 53 | this.chunkSize = chunkSize; 54 | return this; 55 | }; 56 | 57 | add(family, qualifier, timestamp) { 58 | var familyMap = {}; 59 | familyMap.family = family; 60 | if (qualifier) { 61 | if (typeof qualifier === 'object') { 62 | familyMap.qualifier = qualifier.name; 63 | const columnFullName = family + qualifier.name; 64 | this.columnTypes[columnFullName] = qualifier.type; 65 | } 66 | else { 67 | familyMap.qualifier = qualifier; 68 | } 69 | } 70 | 71 | if (timestamp) { 72 | familyMap.timestamp = new Int64(timestamp); 73 | } 74 | this.columns.push(familyMap); 75 | return this; 76 | }; 77 | 78 | objectsFromData(hbaseRowsData) { 79 | if (_.isEmpty(this.columnTypes)) { 80 | return hbaseRowsData; 81 | } 82 | 83 | return _.map(hbaseRowsData, rowData => { 84 | const obj = {}; 85 | obj.rowkey = rowData.row.toString(); 86 | _.each(rowData.columnValues, colVal => { 87 | const family = colVal.family.toString(); 88 | const qualName = colVal.qualifier.toString(); 89 | const columnFullName = family + qualName; 90 | const columnType = this.columnTypes[columnFullName]; 91 | obj[family] = obj[family] || {}; 92 | obj[family][qualName] = serde.deserialize(colVal.value, columnType); 93 | }); 94 | 95 | return obj; 96 | }); 97 | } 98 | } 99 | 100 | module.exports = Scan; -------------------------------------------------------------------------------- /test/put-inc-get-tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | const should = require('should'); 5 | 6 | const Int64 = require('node-int64'); 7 | 8 | const config = require('./config'); 9 | const hbaseServiceCreate = require('../src/service'); 10 | 11 | const testTable = config.assets.testTableName; 12 | 13 | describe('PUT operation', function () { 14 | this.timeout(10000); 15 | 16 | const putValues = { 17 | string: 'abcd', 18 | integer: 321, 19 | float: 1.5, 20 | double: 1024.2048, 21 | number: Math.pow(2, 34) + 1, 22 | int64: new Int64('123456789abc') 23 | }; 24 | 25 | before(function () { 26 | this.hbaseClient = hbaseServiceCreate(config.hbase); 27 | }); 28 | 29 | after(function () { 30 | this.hbaseClient.destroy(); 31 | }); 32 | 33 | const now = Date.now(); 34 | 35 | for (let [valueType, expectedValue] of Object.entries(putValues)) { 36 | const testTitle = `should put a ${valueType.toString()} value (${expectedValue})`; 37 | 38 | it(testTitle, async function () { 39 | const hbaseClient = this.hbaseClient; 40 | 41 | const rowKey = `put.${now}.${valueType}`; 42 | 43 | const putObject = new hbaseClient.Put(rowKey); 44 | putObject.add('f', valueType, {type: valueType, value: expectedValue}); 45 | 46 | console.log('Putting row...', testTable, putObject); 47 | 48 | await hbaseClient.putAsync(testTable, putObject); 49 | 50 | const getObject = new hbaseClient.Get(rowKey); 51 | getObject.add('f', {name: valueType, type: valueType}); 52 | 53 | console.log('Getting row...', getObject); 54 | 55 | const rowData = await hbaseClient.getAsync(testTable, getObject, {}); 56 | 57 | let actualValue = rowData && rowData.f && rowData.f[valueType]; 58 | 59 | if (valueType === 'int64') { 60 | should.equal(actualValue.compare(expectedValue), 0); 61 | } else { 62 | should.equal(actualValue, expectedValue); 63 | } 64 | }); 65 | } 66 | }); 67 | 68 | describe('Inc operation', function () { 69 | this.timeout(10000); 70 | 71 | before(function () { 72 | this.hbaseClient = hbaseServiceCreate(config.hbase); 73 | }); 74 | 75 | after(function () { 76 | this.hbaseClient.destroy(); 77 | }); 78 | 79 | const now = Date.now(); 80 | 81 | const incValues = [undefined, 3, -2]; 82 | 83 | let sum = 0; 84 | 85 | for (const incVal of incValues) { 86 | 87 | it(`inc a row with amount ${incVal}`, async function () { 88 | const hbaseClient = this.hbaseClient; 89 | 90 | const rowKey = `inc.${now}`; 91 | 92 | const incObject = new hbaseClient.Inc(rowKey); 93 | 94 | incObject.add('f', 'counter', incVal); 95 | 96 | console.log('Incrementing row...', testTable, incObject); 97 | 98 | await hbaseClient.incAsync(testTable, incObject); 99 | 100 | const getObject = new hbaseClient.Get(rowKey); 101 | getObject.add('f', {name: "counter", type: "number"}); 102 | 103 | console.log('Getting row...', getObject); 104 | 105 | const rowData = await hbaseClient.getAsync(testTable, getObject, {}); 106 | 107 | let actualValue = rowData && rowData.f && rowData.f.counter; 108 | 109 | sum += incVal || 1; 110 | 111 | should.equal(actualValue, sum); 112 | 113 | }); 114 | } 115 | }); -------------------------------------------------------------------------------- /src/scan-stream.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Readable = require('stream').Readable; 4 | const HBaseTypes = require('../gen-nodejs/hbase_types'); 5 | 6 | class ScanStream extends Readable { 7 | constructor(hbaseClientPool, table, scan) { 8 | super({objectMode: true}); 9 | 10 | const tScan = new HBaseTypes.TScan(scan); 11 | 12 | Object.assign(this, {hbaseClientPool, table, scan, tScan}); 13 | 14 | this.numberOfRowsRead = 0; 15 | } 16 | 17 | async startScan() { 18 | if (this._scannerClosed) return; 19 | 20 | return new Promise((resolve, reject) => { 21 | this.hbaseClientPool.acquire((aquireError, hbaseClient) => { 22 | if (aquireError) { 23 | return this.closeScanner(aquireError, resolve); 24 | } 25 | 26 | const hbaseThriftClient = hbaseClient.thriftClient; 27 | 28 | this.hbaseClient = hbaseClient; 29 | this.hbaseThriftClient = hbaseThriftClient; 30 | 31 | if (this._scannerClosed) { 32 | return this.closeScanner(undefined, resolve); 33 | } 34 | 35 | hbaseThriftClient.openScanner(this.table, this.tScan, (openScannerError, scannerId) => { 36 | if (openScannerError) { 37 | return this.closeScanner(openScannerError, resolve); 38 | } 39 | 40 | this.scannerId = scannerId; 41 | 42 | if (this._scannerClosed) { 43 | return this.closeScanner(undefined, resolve); 44 | } 45 | 46 | resolve(); 47 | }); 48 | }); 49 | }); 50 | } 51 | 52 | calcNextBatchSize() { 53 | if (this.scan.numRows > 0) { 54 | return Math.min(this.scan.chunkSize, this.scan.numRows - this.numberOfRowsRead); 55 | } else { 56 | return this.scan.chunkSize; 57 | } 58 | } 59 | 60 | async _read() { 61 | if (this._scannerClosed) return; 62 | 63 | if (!this._readStarted) { 64 | await this.startScan(); 65 | 66 | if (this._scannerClosed) { 67 | return this.closeScanner(undefined); 68 | } 69 | 70 | this._readStarted = true; 71 | } 72 | 73 | this.hbaseThriftClient 74 | .getScannerRows(this.scannerId, this.calcNextBatchSize(), (scanError, data) => { 75 | // error 76 | if (scanError) { 77 | return this.closeScanner(scanError); 78 | } 79 | 80 | this.numberOfRowsRead += data.length; 81 | 82 | // incoming data 83 | if (data.length > 0) { 84 | this.push(this.scan.objectsFromData(data)) 85 | } 86 | // end of data or reached the limit 87 | if (data.length === 0 || 88 | this.scan.numRows > 0 && this.numberOfRowsRead >= this.scan.numRows) { 89 | 90 | this.closeScanner(); 91 | 92 | this.push(null); 93 | 94 | return; 95 | } 96 | }); 97 | } 98 | 99 | async closeScanner(closeByError, scannerClosedCallback) { 100 | this._scannerClosed = true; 101 | 102 | if (this.scannerId !== undefined) { 103 | try { 104 | await new Promise((resolve, reject) => 105 | this.hbaseThriftClient.closeScanner(this.scannerId, err => !err ? resolve() : reject(err))); 106 | 107 | this.scannerId = undefined; 108 | } catch (err) { 109 | this.emit('error', err); 110 | } 111 | } 112 | 113 | if (this.hbaseClient !== undefined) { 114 | try { 115 | this.hbaseClientPool.release(this.hbaseClient); 116 | 117 | this.hbaseClient = undefined; 118 | } catch (err) { 119 | this.emit('error', err); 120 | } 121 | } 122 | 123 | if (closeByError !== undefined) { 124 | this.emit('error', closeByError); 125 | } 126 | 127 | try { 128 | scannerClosedCallback && scannerClosedCallback(); 129 | } catch (err) { 130 | this.emit('error', err); 131 | } 132 | } 133 | } 134 | 135 | module.exports = ScanStream; -------------------------------------------------------------------------------- /test/scan-tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | const should = require('should'); 5 | const Promise = require('bluebird'); 6 | 7 | const config = require('./config'); 8 | const hbaseServiceCreate = require('../src/service'); 9 | 10 | const testStartMs = Date.now(); 11 | const generatedRowsCount = 2000; 12 | const testTable = config.assets.testTableName; 13 | const testQualifier = `q${testStartMs}`; 14 | 15 | const testScanOptions = { 16 | columns: [{family: 'f', qualifier: testQualifier}] 17 | }; 18 | 19 | describe('SCAN operation', function () { 20 | this.timeout(60000); 21 | 22 | before(async function () { 23 | this.hbaseClient = hbaseServiceCreate(config.hbase); 24 | 25 | await putTestRows(); 26 | }); 27 | 28 | after(function () { 29 | this.hbaseClient.destroy(); 30 | }); 31 | 32 | it('should get all rows', async function () { 33 | const rows = await scanRows({ 34 | numRows: generatedRowsCount 35 | }); 36 | 37 | should.equal(rows.length, generatedRowsCount); 38 | }); 39 | 40 | it('should get range of rows', async function () { 41 | const rows = await scanRows({ 42 | startRow: createRowKey(1300), 43 | stopRow: createRowKey(1600), 44 | numRows: generatedRowsCount * 2, 45 | }); 46 | 47 | should.equal(rows.length, 300); 48 | }); 49 | 50 | it('should get last 10 rows', async function () { 51 | const firstRows = await scanRows({ 52 | chunkSize: 10, 53 | numRows: 10 54 | }); 55 | 56 | const latRows = await scanRows({ 57 | chunkSize: 10, 58 | numRows: 10, 59 | reversed: true 60 | }); 61 | 62 | should.equal(latRows.length, 10); 63 | should.equal(firstRows.length, 10); 64 | should.notEqual(latRows, firstRows, "Last 10 rows should be different from first 10 rows") 65 | }); 66 | 67 | it('should get all rows - 200 rows per iteration', function (done) { 68 | const chunkSize = 200; 69 | const limit = 1500; 70 | let numberOfRows = 0; 71 | 72 | createScanStream({ 73 | numRows: limit, 74 | chunkSize: chunkSize 75 | }) 76 | .on('data', rows => { 77 | console.log(`Received ${rows && rows.length} rows...`); 78 | 79 | numberOfRows += rows.length; 80 | 81 | rows.should.not.be.empty(); 82 | (rows.length).should.be.belowOrEqual(chunkSize); 83 | }) 84 | .on('error', err => done(err)) 85 | .on('end', () => { 86 | 87 | numberOfRows.should.be.equal(limit); 88 | 89 | done(null); 90 | }); 91 | }); 92 | 93 | it('should get range of rows - 50 rows per iteration', function (done) { 94 | const chunkSize = 50; 95 | 96 | let totalRows = 0; 97 | 98 | createScanStream({ 99 | startRow: createRowKey(1300), 100 | stopRow: createRowKey(1655), 101 | numRows: generatedRowsCount * 2, 102 | chunkSize: chunkSize 103 | }) 104 | .on('data', rows => { 105 | console.log(`Received ${rows && rows.length} rows...`); 106 | 107 | rows.should.not.be.empty(); 108 | (rows.length).should.be.belowOrEqual(chunkSize); 109 | 110 | totalRows += rows.length; 111 | }) 112 | .on('error', err => done(err)) 113 | .on('end', () => { 114 | should.equal(totalRows, 355); 115 | 116 | done(null); 117 | }); 118 | }); 119 | 120 | let scanRows = async scanOptions => { 121 | const hbaseClient = this.ctx.hbaseClient; 122 | 123 | const scanObject = new hbaseClient.Scan(Object.assign({}, testScanOptions, scanOptions)); 124 | 125 | console.log('Scanning rows...', scanObject); 126 | 127 | return hbaseClient.scanAsync(testTable, scanObject); 128 | }; 129 | 130 | let createScanStream = scanOptions => { 131 | const hbaseClient = this.ctx.hbaseClient; 132 | 133 | const scanObject = new hbaseClient.Scan(Object.assign({}, testScanOptions, scanOptions)); 134 | 135 | console.log('Scanning rows...', scanObject); 136 | 137 | return hbaseClient.createScanStream(testTable, scanObject); 138 | }; 139 | 140 | const putTestRows = async () => { 141 | const hbaseClient = this.ctx.hbaseClient; 142 | 143 | console.log(`Putting ${generatedRowsCount} rows on table ${testTable}...`); 144 | 145 | await Promise.map(generateRange(1000, 1000 + generatedRowsCount), async generatedIndex => { 146 | const rowKey = createRowKey(generatedIndex); 147 | 148 | const putObject = new hbaseClient.Put(rowKey); 149 | putObject.add('f', testQualifier, {type: 'string', value: 't'}); 150 | 151 | await hbaseClient.putAsync(testTable, putObject); 152 | }); 153 | 154 | console.log('Put rows completed'); 155 | }; 156 | 157 | const createRowKey = index => `scan.${testStartMs}.${index}`; 158 | 159 | const generateRange = function* (start, end) { 160 | for (let i = start; i < end; i++) { 161 | yield i; 162 | } 163 | }; 164 | }); -------------------------------------------------------------------------------- /src/client-pool.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | 5 | const thrift = require('thrift'); 6 | 7 | const HBase = require('../gen-nodejs/THBaseService'); 8 | 9 | const poolModule = require('generic-pool'); 10 | 11 | const Client = require('./client'); 12 | 13 | const debug = require('debug')('node-thrift2-hbase:client-pool'); 14 | 15 | const createClientPool = function (options) { 16 | const hostsHistory = {}; 17 | options = JSON.parse(JSON.stringify(options)); 18 | 19 | switch (options.transport) { 20 | case 'framed': 21 | options.transport = thrift.TFramedTransport; 22 | break; 23 | case 'buffered': 24 | default: 25 | options.transport = thrift.TBufferedTransport; 26 | } 27 | 28 | switch (options.protocol) { 29 | case 'compact': 30 | options.protocol = thrift.TCompactProtocol; 31 | break; 32 | case 'json': 33 | options.protocol = thrift.TJSONProtocol; 34 | break; 35 | case 'binary': 36 | default: 37 | options.protocol = thrift.TBinaryProtocol; 38 | } 39 | 40 | options.hosts.forEach(function (host) { 41 | const hostHistory = { 42 | host: host, 43 | errors: 0, 44 | lastErrorTime: 0 45 | }; 46 | hostsHistory[host] = hostHistory; 47 | }); 48 | 49 | const halfLifeErrorsInterval = setInterval(function halfLifeErrors() { 50 | _.forEach(hostsHistory, function (hostHistory) { 51 | hostHistory.errors = Math.floor(hostHistory.errors / 2); 52 | }); 53 | }, 60 * 1000); 54 | 55 | const markHostError = (host) => { 56 | const hostHistory = hostsHistory[host]; 57 | 58 | if (hostHistory) { 59 | hostHistory.lastErrorTime = Date.now(); 60 | hostHistory.errors += 1; 61 | hostsHistory[host] = hostHistory; 62 | } 63 | }; 64 | 65 | const pool = 66 | poolModule.Pool({ 67 | name: 'hbase', 68 | create: function (callback) { 69 | let isCallbackCalled = false; 70 | 71 | function callbackWrapper(error, client) { 72 | if (isCallbackCalled) 73 | return; 74 | 75 | if (error) { 76 | client._invalid = true; 77 | markHostError(client.host); 78 | } 79 | 80 | isCallbackCalled = true; 81 | callback(error, client); 82 | } 83 | 84 | if (!options.hosts || options.hosts.length < 1) { 85 | return callback(new Error('hosts is empty')); 86 | } 87 | 88 | //filter hostsHistory with connect error. 89 | const hostsToSelect = _.values(hostsHistory).filter(function (hostHistory) { 90 | return !hostHistory.errors || 91 | ((Date.now() - hostHistory.lastErrorTime) > Math.pow(2, hostHistory.errors)); 92 | }); 93 | 94 | if (hostsToSelect.length < 1) 95 | return callback(new Error('All host appear to be down')); 96 | 97 | //select one host from list randomly 98 | const host = hostsToSelect[Math.floor(Math.random() * 99 | hostsToSelect.length)].host; 100 | 101 | const clientOption = Object.assign(options, { 102 | host 103 | }); 104 | const client = new Client(clientOption); 105 | 106 | client.connection.on('connect', function () { 107 | client.thriftClient = thrift.createClient(HBase, client.connection); 108 | callbackWrapper(null, client); 109 | }); 110 | 111 | //todo: 1. Need to retry with different host. 2. Add cool time for host with errors. 112 | client.connection.on('error', function (err) { 113 | debug('Thrift connection error', err, client.host); 114 | client.releaseCommandCallbacksOnError(err); 115 | callbackWrapper(err, client); 116 | }); 117 | 118 | client.connection.on('close', function () { 119 | debug('Thrift close connection error', client.host); 120 | let error = new Error('Thrift close connection'); 121 | client.releaseCommandCallbacksOnError(error); 122 | callbackWrapper(error, client); 123 | }); 124 | 125 | client.connection.on('timeout', function () { 126 | debug('Thrift timeout connection error', client.host); 127 | const error = new Error('Thrift timeout connection'); 128 | client.releaseCommandCallbacksOnError(error); 129 | callbackWrapper(error, client); 130 | }); 131 | 132 | }, 133 | validate: function (client) { 134 | return !client._invalid && client.connection && client.connection.connected; 135 | }, 136 | destroy: function (client) { 137 | client.connection.end(); 138 | //try to disconnect from child process gracefully 139 | client.child && client.child.disconnect(); 140 | }, 141 | min: options.minConnections || 0, 142 | max: options.maxConnections || 10, 143 | idleTimeoutMillis: options.idleTimeoutMillis || 5000 144 | }); 145 | 146 | pool.drain = _.wrap(pool.drain, wrapped => { 147 | clearInterval(halfLifeErrorsInterval); 148 | 149 | wrapped.call(pool); 150 | }); 151 | 152 | return pool; 153 | }; 154 | 155 | 156 | module.exports = createClientPool; -------------------------------------------------------------------------------- /src/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('underscore'); 4 | const Promise = require('bluebird'); 5 | 6 | const createClientPool = require('./client-pool'); 7 | const Cache = require('./cache'); 8 | const serde = require('./serde'); 9 | 10 | const Get = require('./get'); 11 | const Put = require('./put'); 12 | const Del = require('./del'); 13 | const Inc = require('./inc'); 14 | const Scan = require('./scan'); 15 | const ScanStream = require('./scan-stream'); 16 | 17 | const debug = require('debug')('node-thrift2-hbase:service'); 18 | 19 | const Service = function (options) { 20 | this.clientPool = createClientPool(options); 21 | this.hosts = options.hosts; 22 | this.saltMap = options.saltMap || {}; 23 | let cachedTables = options.cachedTables || []; 24 | this.cachedTablesSet = new Set(cachedTables); 25 | this.cache = new Cache( 26 | _.bind(this.applyGetOnClientAsync, this), 27 | options.cacheOptions); 28 | }; 29 | 30 | Service.create = function (options) { 31 | return new Service(options); 32 | }; 33 | 34 | Service.prototype.destroy = function (callback) { 35 | return this.clientPool.drain(callback); 36 | }; 37 | 38 | Service.prototype.serde = serde; 39 | 40 | function noop(k) { 41 | return k; 42 | } 43 | 44 | function saltByLastKeyCharCode(key) { 45 | const charCode = key.codePointAt(key.length - 1); 46 | const salt = charCode % 10; 47 | const salted = salt.toString() + key; 48 | debug('salting key', key, '=>', salted); 49 | return salted; 50 | } 51 | 52 | Service.prototype.saltFunctions = { 53 | saltByLastKeyCharCode: saltByLastKeyCharCode 54 | }; 55 | 56 | Service.prototype.salt = function (table, key) { 57 | return (this.saltMap[table] || noop)(key); 58 | }; 59 | 60 | Service.prototype.applyActionOnClient = function (actionName, table, queryObj, callback) { 61 | debug('applyActionOnClient: applying action', queryObj); 62 | const hbasePool = this.clientPool; 63 | this.clientPool.acquire(function (err, hbaseClient) { 64 | if (err) 65 | return callback(err); 66 | 67 | function releaseAndCallback(err, data) { 68 | if (err) { 69 | //destroy client on error 70 | hbasePool.destroy(hbaseClient); 71 | return callback(err); 72 | } 73 | //release client in the end of use. 74 | hbasePool.release(hbaseClient); 75 | return callback(null, data); 76 | } 77 | 78 | try { 79 | hbaseClient[actionName](table, queryObj, releaseAndCallback); 80 | }catch(err){ 81 | //release client on exception in creating thrift command 82 | hbasePool.release(hbaseClient); 83 | callback(err); 84 | } 85 | }); 86 | }; 87 | 88 | Service.prototype.applyGetOnClient = function (table, queryObj, callback) { 89 | this.applyActionOnClient('get', table, queryObj, callback); 90 | } 91 | Service.prototype.Get = Get; 92 | Service.prototype.get = function (table, get, options, callback) { 93 | if (callback == null) { 94 | callback = options; 95 | options = {}; 96 | } 97 | 98 | get.row = this.salt(table, get.row); 99 | const cache = this.cache; 100 | debug('getting from table', table); 101 | debug(get); 102 | 103 | if ((options && options.cacheQuery) || this.cachedTablesSet.has(table)) { 104 | cache.get(table, get, options, callback) 105 | } else { 106 | this.applyActionOnClient('get', table, get, callback); 107 | } 108 | }; 109 | Service.prototype.getRow = function (table, key, columns, options, callback) { 110 | debug('getting row', key, 'from table', table, 'with columns', columns); 111 | const getObj = new Get(key, options); 112 | 113 | if (columns && columns.length > 0) { 114 | _.each(columns, function (ele, idx) { 115 | if (ele.indexOf(':') != -1) { 116 | const cols = ele.split(':'); 117 | const family = cols[0]; 118 | const qualifier = cols[1]; 119 | getObj.addColumn(family, qualifier); 120 | } else { 121 | getObj.addFamily(ele); 122 | } 123 | }); 124 | } 125 | 126 | this.get(table, getObj, options, callback); 127 | }; 128 | 129 | Service.prototype.Put = Put; 130 | Service.prototype.put = function (table, put, callback) { 131 | put.row = this.salt(table, put.row); 132 | this.applyActionOnClient('put', table, put, callback); 133 | }; 134 | Service.prototype.putRow = function (table, key, cf, valuesMap, callback) { 135 | const hbasePool = this.clientPool; 136 | key = this.salt(table, key); 137 | 138 | this.clientPool.acquire(function (err, hbaseClient) { 139 | if (err) 140 | return callback(err); 141 | 142 | const put = hbaseClient.Put(key); 143 | for (const col in valuesMap) { 144 | const value = valuesMap[col]; 145 | if (value !== undefined && value !== null) 146 | put.add(cf, col, value); 147 | } 148 | hbaseClient.put(table, put, function releaseAndCallback(err, data) { 149 | if (err) { 150 | //destroy client on error 151 | hbasePool.destroy(hbaseClient); 152 | return callback(err); 153 | } 154 | //release client in the end of use. 155 | hbasePool.release(hbaseClient); 156 | return callback(null, data); 157 | }); 158 | }); 159 | }; 160 | 161 | //cellAmounts = [{cf:f,qualifier:q,amount:1}, ...] 162 | Service.prototype.incRow = function (table, key, cellAmounts, callback) { 163 | const hbasePool = this.clientPool; 164 | key = this.salt(table, key); 165 | 166 | this.clientPool.acquire(function (err, hbaseClient) { 167 | if (err) 168 | return callback(err); 169 | 170 | const inc = hbaseClient.Inc(key); 171 | for (const cellIndx in cellAmounts) { 172 | const incCell = cellAmounts[cellIndx]; 173 | if (incCell.cf && incCell.qualifier) 174 | inc.add(incCell.cf, incCell.qualifier, incCell.amount); 175 | else 176 | return callback(new Error("CellAmount must be in the form of {cf:\"f\",qualifier:\"q\",amount:\"1\"")); 177 | } 178 | hbaseClient.inc(table, inc, function releaseAndCallback(err, data) { 179 | if (err) { 180 | //destroy client on error 181 | hbasePool.destroy(hbaseClient); 182 | return callback(err); 183 | } 184 | //release client in the end of use. 185 | hbasePool.release(hbaseClient); 186 | return callback(null, data); 187 | }); 188 | }); 189 | }; 190 | 191 | Service.prototype.Scan = Scan; 192 | Service.prototype.scan = function (table, scan, callback) { 193 | this.applyActionOnClient('scan', table, scan, callback); 194 | }; 195 | 196 | Service.prototype.Del = Del; 197 | Service.prototype.del = function (table, del, callback) { 198 | this.applyActionOnClient('del', table, del, callback); 199 | }; 200 | 201 | Service.prototype.Inc = Inc; 202 | Service.prototype.inc = function (table, inc, callback) { 203 | inc.row = this.salt(table, inc.row); 204 | this.applyActionOnClient('inc', table, inc, callback); 205 | }; 206 | 207 | Promise.promisifyAll(Service.prototype); 208 | 209 | Service.prototype.createScanStream = function (table, scan) { 210 | return new ScanStream(this.clientPool, table, scan); 211 | }; 212 | 213 | module.exports = Service.create; -------------------------------------------------------------------------------- /src/client.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const _ = require('underscore'); 4 | const Int64 = require('node-int64'); 5 | 6 | const Put = require('./put'); 7 | const Del = require('./del'); 8 | const Inc = require('./inc'); 9 | const thrift = require('thrift'); 10 | const HBaseTypes = require('../gen-nodejs/hbase_types'); 11 | 12 | class Client { 13 | constructor(options) { 14 | 15 | if (!options.host || !options.port) { 16 | throw new Error('host or port is none'); 17 | } 18 | this.host = options.host || 'master'; 19 | this.port = options.port || '9090'; 20 | 21 | options.connect_timeout = options.timeout || 0; 22 | options.max_attempts = options.maxAttempts; 23 | options.retry_max_delay = options.retryMaxDelay; 24 | 25 | const connection = thrift.createConnection(this.host, this.port, options); 26 | connection.connection.setKeepAlive(true); 27 | this.connection = connection; 28 | 29 | this.commandCallbacks = new Set(); 30 | } 31 | 32 | /** 33 | * @deprecated Use thriftClient instead. 34 | */ 35 | get client(){ 36 | return this.thriftClient; 37 | } 38 | 39 | releaseCommandCallbacksOnError(err) { 40 | for (const callback of this.commandCallbacks) { 41 | callback(err); 42 | } 43 | this.commandCallbacks.clear(); 44 | } 45 | 46 | create(options) { 47 | return new Client(options); 48 | } 49 | 50 | Put(row) { 51 | return new Put(row); 52 | } 53 | 54 | Del(row) { 55 | return new Del(row); 56 | } 57 | 58 | Inc(row) { 59 | return new Inc(row); 60 | } 61 | 62 | scan(table, scan, callback) { 63 | const tScan = new HBaseTypes.TScan(scan); 64 | 65 | this.commandCallbacks.add(callback); 66 | 67 | this.thriftClient.getScannerResults(table, tScan, scan.numRows, (serr, data) => { 68 | 69 | this.commandCallbacks.delete(callback); 70 | 71 | if (serr) { 72 | callback(serr.message.slice(0, 120)); 73 | } else { 74 | callback(null, scan.objectsFromData(data)); 75 | } 76 | }); 77 | } 78 | 79 | get(table, getObj, callback) { 80 | const tGet = new HBaseTypes.TGet(getObj); 81 | 82 | this.commandCallbacks.add(callback); 83 | 84 | this.thriftClient.get(table, tGet, (err, data) => { 85 | 86 | this.commandCallbacks.delete(callback); 87 | 88 | if (err) { 89 | callback(err.message.slice(0, 120)); 90 | } else { 91 | callback(null, getObj.objectFromData(data)); 92 | } 93 | 94 | }); 95 | } 96 | 97 | put(table, put, callback) { 98 | const row = put.row; 99 | if (!row) { 100 | callback(null, 'rowKey is null'); 101 | } 102 | 103 | const tPut = put.createThriftObject(); 104 | 105 | this.commandCallbacks.add(callback); 106 | 107 | this.thriftClient.put(table, tPut, (err) => { 108 | 109 | this.commandCallbacks.delete(callback); 110 | 111 | if (err) { 112 | callback(err); 113 | } else { 114 | callback(null); 115 | } 116 | }); 117 | } 118 | 119 | putRow(table, row, columns, value, timestamp, callback) { 120 | const args = arguments; 121 | const query = {}; 122 | 123 | if (args.length <= 0) { 124 | throw new Error('Expected 5 arguments got 0'); 125 | } 126 | 127 | callback = args[args.length - 1]; 128 | 129 | if (callback && typeof callback !== 'function') { 130 | throw new Error('callback is not a function'); 131 | } 132 | 133 | if (args.length < 5) { 134 | callback(new Error('arguments arg short of 5')); 135 | return; 136 | } 137 | 138 | if (args.length >= 5) { 139 | if (args[2].indexOf(':') === -1) { 140 | callback(new Error('family and qualifier must have it,example ["info:name"]')); 141 | return; 142 | } 143 | } 144 | 145 | query.row = row; 146 | const qcolumns = []; 147 | if (columns) { 148 | let cols = [], temp = {}; 149 | cols = columns.split(':'); 150 | temp = { 151 | family: cols[0], 152 | qualifier: cols[1], 153 | value: value 154 | }; 155 | if (timestamp) { 156 | temp.timestamp = new Int64(timestamp); 157 | } 158 | qcolumns.push(new HBaseTypes.TColumnValue(temp)); 159 | query.columnValues = qcolumns; 160 | } 161 | 162 | const tPut = new HBaseTypes.TPut(query); 163 | 164 | this.commandCallbacks.add(callback); 165 | 166 | this.thriftClient.put(table, tPut, (err) => { 167 | 168 | this.commandCallbacks.delete(callback); 169 | 170 | if (err) { 171 | callback(err); 172 | } else { 173 | callback(null); 174 | } 175 | }); 176 | } 177 | 178 | del(table, param, callback) { 179 | const tDelete = new HBaseTypes.TDelete(param); 180 | 181 | this.commandCallbacks.add(callback); 182 | 183 | this.thriftClient.deleteSingle(table, tDelete, (err) => { 184 | 185 | this.commandCallbacks.delete(callback); 186 | 187 | if (err) { 188 | callback(err); 189 | } else { 190 | callback(null); 191 | } 192 | }); 193 | } 194 | 195 | delRow(table, row, columns, timestamp, callback) { 196 | const args = arguments; 197 | const query = {}; 198 | 199 | if (args.length <= 0) { 200 | throw new Error('Expected 3 arguments got 0'); 201 | } 202 | 203 | callback = args[args.length - 1]; 204 | 205 | if (callback && typeof callback !== 'function') { 206 | throw new Error('callback is not a function'); 207 | } 208 | 209 | if (args.length < 3) { 210 | callback(new Error('arguments arg short of 3')); 211 | return; 212 | } 213 | 214 | if (args.length === 5) { 215 | if (args[2].indexOf(':') === -1) { 216 | callback(new Error('family and qualifier must have it,example ["info:name"]')); 217 | return; 218 | } 219 | } 220 | 221 | query.row = row; 222 | const qcolumns = []; 223 | if (args.length >= 4 && columns) { 224 | let cols = [], temp = {}; 225 | if (columns.indexOf(':') != -1) { 226 | cols = columns.split(':'); 227 | temp = { 228 | family: cols[0], 229 | qualifier: cols[1] 230 | }; 231 | if (args.length === 5) { 232 | temp.timestamp = timestamp; 233 | } 234 | } else { 235 | temp = { 236 | family: columns 237 | } 238 | } 239 | 240 | qcolumns.push(new HBaseTypes.TColumn(temp)); 241 | query.columns = qcolumns; 242 | } 243 | 244 | const tDelete = new HBaseTypes.TDelete(query); 245 | 246 | this.commandCallbacks.add(callback); 247 | 248 | this.thriftClient.deleteSingle(table, tDelete, (err, data) => { 249 | 250 | this.commandCallbacks.delete(callback); 251 | 252 | if (err) { 253 | callback(err); 254 | } else { 255 | callback(null, data); 256 | } 257 | }); 258 | } 259 | 260 | inc(table, inc, callback) { 261 | const row = inc.row; 262 | if (!row) { 263 | callback(new Error('rowKey is null')); 264 | } 265 | 266 | const tIncrement = inc.createThriftObject(); 267 | 268 | this.commandCallbacks.add(callback); 269 | 270 | this.thriftClient.increment(table, tIncrement, (err, data) => { 271 | 272 | this.commandCallbacks.delete(callback); 273 | 274 | if (err) { 275 | callback(err); 276 | } else { 277 | callback(null, data); 278 | } 279 | }); 280 | 281 | } 282 | 283 | incRow(table, row, columns, callback) { 284 | const args = arguments; 285 | const query = {}; 286 | 287 | if (args.length <= 0) { 288 | throw new Error('Expected 3 arguments got 0'); 289 | } 290 | 291 | callback = args[args.length - 1]; 292 | 293 | if (callback && typeof callback !== 'function') { 294 | throw new Error('callback is not a function'); 295 | } 296 | 297 | if (args.length < 3) { 298 | callback(new Error('arguments arg short of 3')); 299 | return; 300 | } 301 | 302 | if (args.length >= 3) { 303 | if (args[2].indexOf(':') === -1) { 304 | callback(new Error('family and qualifier must have it,example ["info:counter"]')); 305 | return; 306 | } 307 | } 308 | 309 | query.row = row; 310 | const qcolumns = []; 311 | if (columns) { 312 | let cols = [], temp = {}; 313 | cols = columns.split(':'); 314 | temp = { 315 | family: cols[0], 316 | qualifier: cols[1] 317 | }; 318 | qcolumns.push(new HBaseTypes.TColumn(temp)); 319 | query.columns = qcolumns; 320 | } 321 | 322 | const tIncrement = new HBaseTypes.TIncrement(query); 323 | 324 | this.commandCallbacks.add(callback); 325 | 326 | this.thriftClient.increment(table, tIncrement, (err, data) => { 327 | 328 | this.commandCallbacks.delete(callback); 329 | 330 | if (err) { 331 | callback(err); 332 | } else { 333 | callback(null, data); 334 | } 335 | }); 336 | } 337 | } 338 | 339 | module.exports = Client; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A simple, performant, connection-pooled, cached and promisified HBase client library for NodeJS. 2 | --- 3 | 4 | # API 5 | ## Instantiating the HBase client 6 | ```javascript 7 | const config = { 8 | hosts: ["master"], 9 | port: "9090", 10 | }; 11 | 12 | const HBase = require('node-thrift2-hbase')(config); 13 | ``` 14 | 15 | ## Get 16 | 17 | ```javascript 18 | var get = HBase.Get('row1'); //row1 is rowKey 19 | get.addFamily('cf'); 20 | // get.add('cf'); identical to addFamily 21 | 22 | get.addColumn('info', 'name'); 23 | // get.add('info', 'name'); identical to addColumn 24 | 25 | get.addTimestamp('info', 'name', 1414385447707); 26 | // get.add('info', 'name', 1414385447707); identical to addTimestamp 27 | 28 | get.setMaxVersions(3); 29 | 30 | //last ten days as timerange 31 | get.setTimeRange({ 32 | minStamp: Date.now() - 10 * 24 * 60 * 60 * 1000, 33 | maxStamp: Date.now() 34 | }); 35 | 36 | HBase.getAsync('users', get) 37 | .then(function (data) { 38 | console.log("Data for user with key 'row1':"); 39 | console.log('=============================='); 40 | _.each(data[0].columnValues, function (colVal, index) { 41 | console.log('Column value #', index); 42 | console.log('family:', colVal.family.toString()); 43 | console.log('qualifier:', colVal.qualifier.toString()); 44 | console.log('value:', colVal.value.readInt32BE(0, 4)); 45 | }); 46 | }) 47 | .catch(function (err) { 48 | console.log('error:', err); 49 | }); 50 | 51 | HBase.get('users', get, function (err, data) { //get users table 52 | if (err) { 53 | console.log('error:', err); 54 | return; 55 | } 56 | 57 | console.log("Data for user with key 'row1':"); 58 | console.log('=============================='); 59 | _.each(data[0].columnValues, function (colVal, index) { 60 | console.log('Column value #', index); 61 | console.log('family:', colVal.family.toString()); 62 | console.log('qualifier:', colVal.qualifier.toString()); 63 | console.log('value:', colVal.value.readInt32BE(0, 4)); 64 | }); 65 | }); 66 | ``` 67 | A shorthand version is the `getRow` function: 68 | ```javascript 69 | HBase.getRow('users', 'row1', ['info:name', 'ecf'], 1, 70 | function (err, data) { 71 | if (err) { 72 | console.log('error:', err); 73 | return; 74 | } 75 | console.log("Data for user with key 'row1':"); 76 | console.log('=============================='); 77 | _.each(data[0].columnValues, function (colVal, index) { 78 | console.log('Column value #', index); 79 | console.log('family:', colVal.family.toString()); 80 | console.log('qualifier:', colVal.qualifier.toString()); 81 | console.log('value:', colVal.value.readInt32BE(0, 4)); 82 | }); 83 | }); 84 | 85 | HBase.getRowAsync('users', 'row1', ['info:name', 'ecf'], 1) 86 | .then(function (data) { 87 | console.log("Data for user with key 'row1':"); 88 | console.log('=============================='); 89 | _.each(data[0].columnValues, function (colVal, index) { 90 | console.log('Column value #', index); 91 | console.log('family:', colVal.family.toString()); 92 | console.log('qualifier:', colVal.qualifier.toString()); 93 | console.log('value:', colVal.value.readInt32BE(0, 4)); 94 | }); 95 | }) 96 | .catch(function (err) { 97 | console.log('error:', err); 98 | }); 99 | ``` 100 | 101 | ### Qualifier serialization/deserialization: 102 | When adding a qualifier via `add` methods to `Get`, `Put` and `Scan` objects you can specify the type of value expected for that qualifier. That means that instead of reading the value of the qualifier's buffer yourself, the library can do it for you. For example: 103 | ```javascript 104 | var get = HBase.Get('row1'); //row1 is rowKey 105 | // column family "f", qualifier "q1", value is a float 106 | get.add('f', {name: 'q1', type: 'float'}); 107 | // column family "f", qualifier "q2", value is a json object 108 | get.add('f', {name: 'q2', type: 'json'}); 109 | // column family "f", qualifier "q3" type unspecified - default is string 110 | get.add('f', 'q3'); 111 | 112 | HBase.get("table", get).then(rowData => console.log(rowData)); 113 | shouldEqual(rowData, { 114 | rowkey: "row1", 115 | d:{ 116 | q1: 123.321 117 | q2: {prop:"val"}, 118 | q3: "123.321" 119 | } 120 | }); 121 | ``` 122 | 123 | The following types are supported: 124 | `string` (if type is unspecified, defaults to `string`) 125 | `json` (parses the value as a JSON string) 126 | `integer` (alias: `integer32`) 127 | `float` 128 | `double` 129 | `number` (alias: `integer48`) 130 | `UInteger48` 131 | `int64` 132 | 133 | ## Put 134 | 135 | ```javascript 136 | var put = HBase.Put('row1'); 137 | 138 | // cf qualifier value 139 | put.add('info', 'money', {type: 'float', value: 12.34}); 140 | 141 | put.add('info', 'click', {type: 'integer', value: 100}); 142 | 143 | //string values don't need a wrapper object 144 | put.add('ecf', 'name', 'zhudaxian'); 145 | 146 | // timestamp 147 | put.add('info', 'name', 'beijing', new Date().getTime()); 148 | 149 | 150 | HBase.put('users', put, function (err) { 151 | if (err) { 152 | console.log('error:', err); 153 | return; 154 | } 155 | 156 | console.log('Put is successful.'); 157 | }); 158 | 159 | HBase.putAsync('users', put) 160 | .then(function () { 161 | console.log('Put is successful.'); 162 | }) 163 | .catch(function (err) { 164 | console.log('error:', err); 165 | }); 166 | ``` 167 | A shorthand version is the `putRow` function: 168 | ```javascript 169 | HBase.putRow('users', 'row1', 'info:name', 'phoneqq.com', 1414140874929, 170 | function (err) { 171 | if (err) { 172 | console.log('error:', err); 173 | return; 174 | } 175 | console.log('Put is successfull.'); 176 | }); 177 | 178 | HBase.putRowAsync('users', 'row1', 'info:name', 'phoneqq.com', 1414140874929) 179 | .then(function () { 180 | console.log('Put is successfull.'); 181 | }) 182 | .catch(function (err) { 183 | console.log('error:', err); 184 | }); 185 | ``` 186 | 187 | # Inc 188 | ```javascript 189 | 190 | var inc = hbaseClient.Inc('row1'); //row1 is rowKey 191 | 192 | inc.add('info','counter'); 193 | 194 | inc.add('info','counter2'); 195 | 196 | hbaseClient.inc('users',inc,function(err,data){ 197 | //inc users table 198 | 199 | if(err){ 200 | console.log('error:',err); 201 | return; 202 | } 203 | 204 | console.log(err,data); 205 | 206 | }); 207 | 208 | ``` 209 | 210 | # Del 211 | ```javascript 212 | 213 | var del = hbaseClient.Del('row1'); //row1 is rowKey 214 | 215 | //del.addFamily('ips'); //delete family ips 216 | //del.addColumn('info','click2'); //delete family and qualifier info:click2 217 | //del.addTimestamp('info','click3',1414136046864); //delete info:click3 and timestamp 218 | 219 | //or Recommend this function add 220 | 221 | del.add('info'); //delete all family info 222 | del.add('info','name'); //delete family and qualifier info:name 223 | del.add('info','tel',1414136046864); //delete info:tel and timestamp 224 | 225 | del.add('ecf'); //delete other family ecf 226 | del.add('ecf','name'); //delete family and qualifier ecf:name 227 | del.add('ecf','tel',1414136119207); //delete info:tel and timestamp 228 | 229 | //del.add('ips'); //is error ,because this family ips is not exist 230 | 231 | hbaseClient.del('users',del,function(err){ //put users table 232 | if(err){ 233 | console.log('error:',err); 234 | return; 235 | } 236 | console.log(err,'del is successfully'); 237 | }); 238 | 239 | ``` 240 | 241 | # Scan 242 | ```javascript 243 | 244 | var scan = hbaseClient.Scan(); 245 | 246 | //get.addFamily('cf'); //add not found column is error 247 | 248 | //scan.addFamily('info'); //add all family 249 | 250 | //scan.addStartRow('row1'); //start rowKey 251 | 252 | //scan.addStopRow('row1p'); //stop rowKey 253 | 254 | //scan.addColumn('info','name'); //add family and qualifier 255 | 256 | //scan.addColumn('ecf','name'); //add other family 257 | 258 | //scan.setMaxVersions(1); //set maxversions 259 | 260 | //scan.addNumRows(10); //search how much number rows 261 | 262 | //or Recommend this function add 263 | 264 | scan.addStartRow('row1'); //start rowKey 265 | 266 | scan.addStopRow('row1p'); //stop rowKey 267 | 268 | scan.add('info'); //scan all family info 269 | 270 | scan.add('info','name'); //scan family and qualifier info:name 271 | 272 | scan.add('ecf'); //scan other family ecf 273 | 274 | scan.add('ecf','name'); //scan family and qualifier ecf:name 275 | 276 | scan.setMaxVersions(1); //set maxversions 277 | 278 | scan.addNumRows(10); //search how much number rows 279 | 280 | hbaseClient.scan('users',scan,function(err,data){ //get users table 281 | if(err){ 282 | console.log('error:',err); 283 | return; 284 | } 285 | console.log(err,data); 286 | 287 | // console.log(err,data[0].columnValues); 288 | }); 289 | 290 | ``` 291 | 292 | # Scan Stream 293 | ```javascript 294 | const tableName = 'test:test_table'; 295 | 296 | const scanObject = 297 | hbaseClient.Scan({ 298 | family: 'f', // Column family 299 | qualifier: 'test', // Qualifier 300 | startRow: 'test.row.1', // Start scan row key (STARTROW) 301 | stopRow: 'test.row.100', // Stop scan row key (STOPROW) 302 | numRows: 50, // Max total rows to fetch (LIMIT) 303 | chunkSize: 10 // Max rows to fetch for one batch 304 | }); 305 | 306 | hbaseClient 307 | .createScanStream(tableName, scanObject) 308 | .on('data', rows => { 309 | console.log(`Received ${rows.length} rows...`); 310 | }) 311 | .on('error', err => { 312 | errorHandler(err); 313 | }) 314 | .on('end', () => { 315 | console.log('scan ended'); 316 | }); 317 | ``` 318 | 319 | # Table Salting 320 | What is "salting"? The term is taken from the encryption nomenclature, but for our purposes it just means adding a predictable string to a key. The way HBase stores rows means that if the keys are not spread across the string spectrum, then the data will physically be kept in a "not spread" manner - for example, having most rows of a table on very few `Region Server`s. So if your keys are well-spread, so is your data. This allows for faster and more parallel reads/writes en-masse. The only problem is keeping track of which table has its keys salted, and exactly how were the keys salted. We have a solution for that: 321 | 322 | ```javascript 323 | var hbase = require('node-thrift2-hbase')(hbaseConfig); 324 | hbase.saltMap = { 325 | 'myTable1': hbase.saltFunctions.saltByLastKeyCharCode, 326 | 'myTable2': hbase.saltFunctions.saltByLastKeyCharCode 327 | }; 328 | ``` 329 | 330 | All `get` and `put` operations for tables specified in the `saltMap` will be 331 | salted using the given function. `hbase.saltFunctions` contains some ready-made salt functions. If you have a salt function you find useful, don't hesitate to make a PR adding it! 332 | 333 | 334 | --- 335 | #### Working HBase-Thrift compiler combinations 336 | The code supplied here used Thrift 0.9.3 to generate code for HBase 0.98.4. 337 | If you'd like to use this library with different versions, download the desired HBase Thrift definition file and compile it using the Thrift compiler of your choice into the project's `gen-nodejs` folder. 338 | If you are successfully working with different HBase/Thrift compiler combination please tell us and we'll add the info here. 339 | 340 | HBase |Thrift Compiler | 341 | :--------:|:----------------: 342 | 0.98.4 | 0.9.3 | 343 | 1.1.2 | 0.9.3 | 344 | 1.1.2 | 0.10.0 | 345 | 346 | --- 347 | 348 | **This library was initially based on https://www.npmjs.com/package/node-thrift-hbase but 349 | due to that library's abandonment by the author we had to republish it with our contributions.** -------------------------------------------------------------------------------- /1.1.13/hbase.thrift: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | // NOTE: The "required" and "optional" keywords for the service methods are purely for documentation 20 | 21 | namespace java org.apache.hadoop.hbase.thrift2.generated 22 | namespace cpp apache.hadoop.hbase.thrift2 23 | namespace rb Apache.Hadoop.Hbase.Thrift2 24 | namespace py hbase 25 | namespace perl Hbase 26 | 27 | struct TTimeRange { 28 | 1: required i64 minStamp, 29 | 2: required i64 maxStamp 30 | } 31 | 32 | /** 33 | * Addresses a single cell or multiple cells 34 | * in a HBase table by column family and optionally 35 | * a column qualifier and timestamp 36 | */ 37 | struct TColumn { 38 | 1: required binary family, 39 | 2: optional binary qualifier, 40 | 3: optional i64 timestamp 41 | } 42 | 43 | /** 44 | * Represents a single cell and its value. 45 | */ 46 | struct TColumnValue { 47 | 1: required binary family, 48 | 2: required binary qualifier, 49 | 3: required binary value, 50 | 4: optional i64 timestamp, 51 | 5: optional binary tags 52 | } 53 | 54 | /** 55 | * Represents a single cell and the amount to increment it by 56 | */ 57 | struct TColumnIncrement { 58 | 1: required binary family, 59 | 2: required binary qualifier, 60 | 3: optional i64 amount = 1 61 | } 62 | 63 | /** 64 | * if no Result is found, row and columnValues will not be set. 65 | */ 66 | struct TResult { 67 | 1: optional binary row, 68 | 2: required list columnValues 69 | } 70 | 71 | /** 72 | * Specify type of delete: 73 | * - DELETE_COLUMN means exactly one version will be removed, 74 | * - DELETE_COLUMNS means previous versions will also be removed. 75 | */ 76 | enum TDeleteType { 77 | DELETE_COLUMN = 0, 78 | DELETE_COLUMNS = 1 79 | } 80 | 81 | /** 82 | * Specify Durability: 83 | * - SKIP_WAL means do not write the Mutation to the WAL. 84 | * - ASYNC_WAL means write the Mutation to the WAL asynchronously, 85 | * - SYNC_WAL means write the Mutation to the WAL synchronously, 86 | * - FSYNC_WAL means Write the Mutation to the WAL synchronously and force the entries to disk. 87 | */ 88 | 89 | enum TDurability { 90 | SKIP_WAL = 1, 91 | ASYNC_WAL = 2, 92 | SYNC_WAL = 3, 93 | FSYNC_WAL = 4 94 | } 95 | struct TAuthorization { 96 | 1: optional list labels 97 | } 98 | 99 | struct TCellVisibility { 100 | 1: optional string expression 101 | } 102 | /** 103 | * Used to perform Get operations on a single row. 104 | * 105 | * The scope can be further narrowed down by specifying a list of 106 | * columns or column families. 107 | * 108 | * To get everything for a row, instantiate a Get object with just the row to get. 109 | * To further define the scope of what to get you can add a timestamp or time range 110 | * with an optional maximum number of versions to return. 111 | * 112 | * If you specify a time range and a timestamp the range is ignored. 113 | * Timestamps on TColumns are ignored. 114 | */ 115 | struct TGet { 116 | 1: required binary row, 117 | 2: optional list columns, 118 | 119 | 3: optional i64 timestamp, 120 | 4: optional TTimeRange timeRange, 121 | 122 | 5: optional i32 maxVersions, 123 | 6: optional binary filterString, 124 | 7: optional map attributes 125 | 8: optional TAuthorization authorizations 126 | } 127 | 128 | /** 129 | * Used to perform Put operations for a single row. 130 | * 131 | * Add column values to this object and they'll be added. 132 | * You can provide a default timestamp if the column values 133 | * don't have one. If you don't provide a default timestamp 134 | * the current time is inserted. 135 | * 136 | * You can specify how this Put should be written to the write-ahead Log (WAL) 137 | * by changing the durability. If you don't provide durability, it defaults to 138 | * column family's default setting for durability. 139 | */ 140 | struct TPut { 141 | 1: required binary row, 142 | 2: required list columnValues 143 | 3: optional i64 timestamp, 144 | 5: optional map attributes, 145 | 6: optional TDurability durability, 146 | 7: optional TCellVisibility cellVisibility 147 | } 148 | 149 | /** 150 | * Used to perform Delete operations on a single row. 151 | * 152 | * The scope can be further narrowed down by specifying a list of 153 | * columns or column families as TColumns. 154 | * 155 | * Specifying only a family in a TColumn will delete the whole family. 156 | * If a timestamp is specified all versions with a timestamp less than 157 | * or equal to this will be deleted. If no timestamp is specified the 158 | * current time will be used. 159 | * 160 | * Specifying a family and a column qualifier in a TColumn will delete only 161 | * this qualifier. If a timestamp is specified only versions equal 162 | * to this timestamp will be deleted. If no timestamp is specified the 163 | * most recent version will be deleted. To delete all previous versions, 164 | * specify the DELETE_COLUMNS TDeleteType. 165 | * 166 | * The top level timestamp is only used if a complete row should be deleted 167 | * (i.e. no columns are passed) and if it is specified it works the same way 168 | * as if you had added a TColumn for every column family and this timestamp 169 | * (i.e. all versions older than or equal in all column families will be deleted) 170 | * 171 | * You can specify how this Delete should be written to the write-ahead Log (WAL) 172 | * by changing the durability. If you don't provide durability, it defaults to 173 | * column family's default setting for durability. 174 | */ 175 | struct TDelete { 176 | 1: required binary row, 177 | 2: optional list columns, 178 | 3: optional i64 timestamp, 179 | 4: optional TDeleteType deleteType = 1, 180 | 6: optional map attributes, 181 | 7: optional TDurability durability 182 | 183 | } 184 | 185 | /** 186 | * Used to perform Increment operations for a single row. 187 | * 188 | * You can specify how this Increment should be written to the write-ahead Log (WAL) 189 | * by changing the durability. If you don't provide durability, it defaults to 190 | * column family's default setting for durability. 191 | */ 192 | struct TIncrement { 193 | 1: required binary row, 194 | 2: required list columns, 195 | 4: optional map attributes, 196 | 5: optional TDurability durability 197 | 6: optional TCellVisibility cellVisibility 198 | } 199 | 200 | /* 201 | * Used to perform append operation 202 | */ 203 | struct TAppend { 204 | 1: required binary row, 205 | 2: required list columns, 206 | 3: optional map attributes, 207 | 4: optional TDurability durability 208 | 5: optional TCellVisibility cellVisibility 209 | } 210 | 211 | /** 212 | * Any timestamps in the columns are ignored, use timeRange to select by timestamp. 213 | * Max versions defaults to 1. 214 | */ 215 | struct TScan { 216 | 1: optional binary startRow, 217 | 2: optional binary stopRow, 218 | 3: optional list columns 219 | 4: optional i32 caching, 220 | 5: optional i32 maxVersions=1, 221 | 6: optional TTimeRange timeRange, 222 | 7: optional binary filterString, 223 | 8: optional i32 batchSize, 224 | 9: optional map attributes 225 | 10: optional TAuthorization authorizations 226 | 11: optional bool reversed 227 | } 228 | 229 | /** 230 | * Atomic mutation for the specified row. It can be either Put or Delete. 231 | */ 232 | union TMutation { 233 | 1: TPut put, 234 | 2: TDelete deleteSingle, 235 | } 236 | 237 | /** 238 | * A TRowMutations object is used to apply a number of Mutations to a single row. 239 | */ 240 | struct TRowMutations { 241 | 1: required binary row 242 | 2: required list mutations 243 | } 244 | 245 | // 246 | // Exceptions 247 | // 248 | 249 | /** 250 | * A TIOError exception signals that an error occurred communicating 251 | * to the HBase master or a HBase region server. Also used to return 252 | * more general HBase error conditions. 253 | */ 254 | exception TIOError { 255 | 1: optional string message 256 | } 257 | 258 | /** 259 | * A TIllegalArgument exception indicates an illegal or invalid 260 | * argument was passed into a procedure. 261 | */ 262 | exception TIllegalArgument { 263 | 1: optional string message 264 | } 265 | 266 | service THBaseService { 267 | 268 | /** 269 | * Test for the existence of columns in the table, as specified in the TGet. 270 | * 271 | * @return true if the specified TGet matches one or more keys, false if not 272 | */ 273 | bool exists( 274 | /** the table to check on */ 275 | 1: required binary table, 276 | 277 | /** the TGet to check for */ 278 | 2: required TGet tget 279 | ) throws (1:TIOError io) 280 | 281 | /** 282 | * Method for getting data from a row. 283 | * 284 | * If the row cannot be found an empty Result is returned. 285 | * This can be checked by the empty field of the TResult 286 | * 287 | * @return the result 288 | */ 289 | TResult get( 290 | /** the table to get from */ 291 | 1: required binary table, 292 | 293 | /** the TGet to fetch */ 294 | 2: required TGet tget 295 | ) throws (1: TIOError io) 296 | 297 | /** 298 | * Method for getting multiple rows. 299 | * 300 | * If a row cannot be found there will be a null 301 | * value in the result list for that TGet at the 302 | * same position. 303 | * 304 | * So the Results are in the same order as the TGets. 305 | */ 306 | list getMultiple( 307 | /** the table to get from */ 308 | 1: required binary table, 309 | 310 | /** a list of TGets to fetch, the Result list 311 | will have the Results at corresponding positions 312 | or null if there was an error */ 313 | 2: required list tgets 314 | ) throws (1: TIOError io) 315 | 316 | /** 317 | * Commit a TPut to a table. 318 | */ 319 | void put( 320 | /** the table to put data in */ 321 | 1: required binary table, 322 | 323 | /** the TPut to put */ 324 | 2: required TPut tput 325 | ) throws (1: TIOError io) 326 | 327 | /** 328 | * Atomically checks if a row/family/qualifier value matches the expected 329 | * value. If it does, it adds the TPut. 330 | * 331 | * @return true if the new put was executed, false otherwise 332 | */ 333 | bool checkAndPut( 334 | /** to check in and put to */ 335 | 1: required binary table, 336 | 337 | /** row to check */ 338 | 2: required binary row, 339 | 340 | /** column family to check */ 341 | 3: required binary family, 342 | 343 | /** column qualifier to check */ 344 | 4: required binary qualifier, 345 | 346 | /** the expected value, if not provided the 347 | check is for the non-existence of the 348 | column in question */ 349 | 5: binary value, 350 | 351 | /** the TPut to put if the check succeeds */ 352 | 6: required TPut tput 353 | ) throws (1: TIOError io) 354 | 355 | /** 356 | * Commit a List of Puts to the table. 357 | */ 358 | void putMultiple( 359 | /** the table to put data in */ 360 | 1: required binary table, 361 | 362 | /** a list of TPuts to commit */ 363 | 2: required list tputs 364 | ) throws (1: TIOError io) 365 | 366 | /** 367 | * Deletes as specified by the TDelete. 368 | * 369 | * Note: "delete" is a reserved keyword and cannot be used in Thrift 370 | * thus the inconsistent naming scheme from the other functions. 371 | */ 372 | void deleteSingle( 373 | /** the table to delete from */ 374 | 1: required binary table, 375 | 376 | /** the TDelete to delete */ 377 | 2: required TDelete tdelete 378 | ) throws (1: TIOError io) 379 | 380 | /** 381 | * Bulk commit a List of TDeletes to the table. 382 | * 383 | * Throws a TIOError if any of the deletes fail. 384 | * 385 | * Always returns an empty list for backwards compatibility. 386 | */ 387 | list deleteMultiple( 388 | /** the table to delete from */ 389 | 1: required binary table, 390 | 391 | /** list of TDeletes to delete */ 392 | 2: required list tdeletes 393 | ) throws (1: TIOError io) 394 | 395 | /** 396 | * Atomically checks if a row/family/qualifier value matches the expected 397 | * value. If it does, it adds the delete. 398 | * 399 | * @return true if the new delete was executed, false otherwise 400 | */ 401 | bool checkAndDelete( 402 | /** to check in and delete from */ 403 | 1: required binary table, 404 | 405 | /** row to check */ 406 | 2: required binary row, 407 | 408 | /** column family to check */ 409 | 3: required binary family, 410 | 411 | /** column qualifier to check */ 412 | 4: required binary qualifier, 413 | 414 | /** the expected value, if not provided the 415 | check is for the non-existence of the 416 | column in question */ 417 | 5: binary value, 418 | 419 | /** the TDelete to execute if the check succeeds */ 420 | 6: required TDelete tdelete 421 | ) throws (1: TIOError io) 422 | 423 | TResult increment( 424 | /** the table to increment the value on */ 425 | 1: required binary table, 426 | 427 | /** the TIncrement to increment */ 428 | 2: required TIncrement tincrement 429 | ) throws (1: TIOError io) 430 | 431 | TResult append( 432 | /** the table to append the value on */ 433 | 1: required binary table, 434 | 435 | /** the TAppend to append */ 436 | 2: required TAppend tappend 437 | ) throws (1: TIOError io) 438 | 439 | /** 440 | * Get a Scanner for the provided TScan object. 441 | * 442 | * @return Scanner Id to be used with other scanner procedures 443 | */ 444 | i32 openScanner( 445 | /** the table to get the Scanner for */ 446 | 1: required binary table, 447 | 448 | /** the scan object to get a Scanner for */ 449 | 2: required TScan tscan, 450 | ) throws (1: TIOError io) 451 | 452 | /** 453 | * Grabs multiple rows from a Scanner. 454 | * 455 | * @return Between zero and numRows TResults 456 | */ 457 | list getScannerRows( 458 | /** the Id of the Scanner to return rows from. This is an Id returned from the openScanner function. */ 459 | 1: required i32 scannerId, 460 | 461 | /** number of rows to return */ 462 | 2: i32 numRows = 1 463 | ) throws ( 464 | 1: TIOError io, 465 | 466 | /** if the scannerId is invalid */ 467 | 2: TIllegalArgument ia 468 | ) 469 | 470 | /** 471 | * Closes the scanner. Should be called to free server side resources timely. 472 | * Typically close once the scanner is not needed anymore, i.e. after looping 473 | * over it to get all the required rows. 474 | */ 475 | void closeScanner( 476 | /** the Id of the Scanner to close **/ 477 | 1: required i32 scannerId 478 | ) throws ( 479 | 1: TIOError io, 480 | 481 | /** if the scannerId is invalid */ 482 | 2: TIllegalArgument ia 483 | ) 484 | 485 | /** 486 | * mutateRow performs multiple mutations atomically on a single row. 487 | */ 488 | void mutateRow( 489 | /** table to apply the mutations */ 490 | 1: required binary table, 491 | 492 | /** mutations to apply */ 493 | 2: required TRowMutations trowMutations 494 | ) throws (1: TIOError io) 495 | 496 | /** 497 | * Get results for the provided TScan object. 498 | * This helper function opens a scanner, get the results and close the scanner. 499 | * 500 | * @return between zero and numRows TResults 501 | */ 502 | list getScannerResults( 503 | /** the table to get the Scanner for */ 504 | 1: required binary table, 505 | 506 | /** the scan object to get a Scanner for */ 507 | 2: required TScan tscan, 508 | 509 | /** number of rows to return */ 510 | 3: i32 numRows = 1 511 | ) throws ( 512 | 1: TIOError io 513 | ) 514 | 515 | } -------------------------------------------------------------------------------- /gen-nodejs/hbase_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.13.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | "use strict"; 7 | 8 | var thrift = require('thrift'); 9 | var Thrift = thrift.Thrift; 10 | var Q = thrift.Q; 11 | var Int64 = require('node-int64'); 12 | 13 | 14 | var ttypes = module.exports = {}; 15 | ttypes.TDeleteType = { 16 | 'DELETE_COLUMN' : 0, 17 | 'DELETE_COLUMNS' : 1 18 | }; 19 | ttypes.TDurability = { 20 | 'SKIP_WAL' : 1, 21 | 'ASYNC_WAL' : 2, 22 | 'SYNC_WAL' : 3, 23 | 'FSYNC_WAL' : 4 24 | }; 25 | var TTimeRange = module.exports.TTimeRange = function(args) { 26 | this.minStamp = null; 27 | this.maxStamp = null; 28 | if (args) { 29 | if (args.minStamp !== undefined && args.minStamp !== null) { 30 | this.minStamp = args.minStamp; 31 | } else { 32 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field minStamp is unset!'); 33 | } 34 | if (args.maxStamp !== undefined && args.maxStamp !== null) { 35 | this.maxStamp = args.maxStamp; 36 | } else { 37 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field maxStamp is unset!'); 38 | } 39 | } 40 | }; 41 | TTimeRange.prototype = {}; 42 | TTimeRange.prototype.read = function(input) { 43 | input.readStructBegin(); 44 | while (true) { 45 | var ret = input.readFieldBegin(); 46 | var ftype = ret.ftype; 47 | var fid = ret.fid; 48 | if (ftype == Thrift.Type.STOP) { 49 | break; 50 | } 51 | switch (fid) { 52 | case 1: 53 | if (ftype == Thrift.Type.I64) { 54 | this.minStamp = input.readI64(); 55 | } else { 56 | input.skip(ftype); 57 | } 58 | break; 59 | case 2: 60 | if (ftype == Thrift.Type.I64) { 61 | this.maxStamp = input.readI64(); 62 | } else { 63 | input.skip(ftype); 64 | } 65 | break; 66 | default: 67 | input.skip(ftype); 68 | } 69 | input.readFieldEnd(); 70 | } 71 | input.readStructEnd(); 72 | return; 73 | }; 74 | 75 | TTimeRange.prototype.write = function(output) { 76 | output.writeStructBegin('TTimeRange'); 77 | if (this.minStamp !== null && this.minStamp !== undefined) { 78 | output.writeFieldBegin('minStamp', Thrift.Type.I64, 1); 79 | output.writeI64(this.minStamp); 80 | output.writeFieldEnd(); 81 | } 82 | if (this.maxStamp !== null && this.maxStamp !== undefined) { 83 | output.writeFieldBegin('maxStamp', Thrift.Type.I64, 2); 84 | output.writeI64(this.maxStamp); 85 | output.writeFieldEnd(); 86 | } 87 | output.writeFieldStop(); 88 | output.writeStructEnd(); 89 | return; 90 | }; 91 | 92 | var TColumn = module.exports.TColumn = function(args) { 93 | this.family = null; 94 | this.qualifier = null; 95 | this.timestamp = null; 96 | if (args) { 97 | if (args.family !== undefined && args.family !== null) { 98 | this.family = args.family; 99 | } else { 100 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field family is unset!'); 101 | } 102 | if (args.qualifier !== undefined && args.qualifier !== null) { 103 | this.qualifier = args.qualifier; 104 | } 105 | if (args.timestamp !== undefined && args.timestamp !== null) { 106 | this.timestamp = args.timestamp; 107 | } 108 | } 109 | }; 110 | TColumn.prototype = {}; 111 | TColumn.prototype.read = function(input) { 112 | input.readStructBegin(); 113 | while (true) { 114 | var ret = input.readFieldBegin(); 115 | var ftype = ret.ftype; 116 | var fid = ret.fid; 117 | if (ftype == Thrift.Type.STOP) { 118 | break; 119 | } 120 | switch (fid) { 121 | case 1: 122 | if (ftype == Thrift.Type.STRING) { 123 | this.family = input.readBinary(); 124 | } else { 125 | input.skip(ftype); 126 | } 127 | break; 128 | case 2: 129 | if (ftype == Thrift.Type.STRING) { 130 | this.qualifier = input.readBinary(); 131 | } else { 132 | input.skip(ftype); 133 | } 134 | break; 135 | case 3: 136 | if (ftype == Thrift.Type.I64) { 137 | this.timestamp = input.readI64(); 138 | } else { 139 | input.skip(ftype); 140 | } 141 | break; 142 | default: 143 | input.skip(ftype); 144 | } 145 | input.readFieldEnd(); 146 | } 147 | input.readStructEnd(); 148 | return; 149 | }; 150 | 151 | TColumn.prototype.write = function(output) { 152 | output.writeStructBegin('TColumn'); 153 | if (this.family !== null && this.family !== undefined) { 154 | output.writeFieldBegin('family', Thrift.Type.STRING, 1); 155 | output.writeBinary(this.family); 156 | output.writeFieldEnd(); 157 | } 158 | if (this.qualifier !== null && this.qualifier !== undefined) { 159 | output.writeFieldBegin('qualifier', Thrift.Type.STRING, 2); 160 | output.writeBinary(this.qualifier); 161 | output.writeFieldEnd(); 162 | } 163 | if (this.timestamp !== null && this.timestamp !== undefined) { 164 | output.writeFieldBegin('timestamp', Thrift.Type.I64, 3); 165 | output.writeI64(this.timestamp); 166 | output.writeFieldEnd(); 167 | } 168 | output.writeFieldStop(); 169 | output.writeStructEnd(); 170 | return; 171 | }; 172 | 173 | var TColumnValue = module.exports.TColumnValue = function(args) { 174 | this.family = null; 175 | this.qualifier = null; 176 | this.value = null; 177 | this.timestamp = null; 178 | this.tags = null; 179 | if (args) { 180 | if (args.family !== undefined && args.family !== null) { 181 | this.family = args.family; 182 | } else { 183 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field family is unset!'); 184 | } 185 | if (args.qualifier !== undefined && args.qualifier !== null) { 186 | this.qualifier = args.qualifier; 187 | } else { 188 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field qualifier is unset!'); 189 | } 190 | if (args.value !== undefined && args.value !== null) { 191 | this.value = args.value; 192 | } else { 193 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field value is unset!'); 194 | } 195 | if (args.timestamp !== undefined && args.timestamp !== null) { 196 | this.timestamp = args.timestamp; 197 | } 198 | if (args.tags !== undefined && args.tags !== null) { 199 | this.tags = args.tags; 200 | } 201 | } 202 | }; 203 | TColumnValue.prototype = {}; 204 | TColumnValue.prototype.read = function(input) { 205 | input.readStructBegin(); 206 | while (true) { 207 | var ret = input.readFieldBegin(); 208 | var ftype = ret.ftype; 209 | var fid = ret.fid; 210 | if (ftype == Thrift.Type.STOP) { 211 | break; 212 | } 213 | switch (fid) { 214 | case 1: 215 | if (ftype == Thrift.Type.STRING) { 216 | this.family = input.readBinary(); 217 | } else { 218 | input.skip(ftype); 219 | } 220 | break; 221 | case 2: 222 | if (ftype == Thrift.Type.STRING) { 223 | this.qualifier = input.readBinary(); 224 | } else { 225 | input.skip(ftype); 226 | } 227 | break; 228 | case 3: 229 | if (ftype == Thrift.Type.STRING) { 230 | this.value = input.readBinary(); 231 | } else { 232 | input.skip(ftype); 233 | } 234 | break; 235 | case 4: 236 | if (ftype == Thrift.Type.I64) { 237 | this.timestamp = input.readI64(); 238 | } else { 239 | input.skip(ftype); 240 | } 241 | break; 242 | case 5: 243 | if (ftype == Thrift.Type.STRING) { 244 | this.tags = input.readBinary(); 245 | } else { 246 | input.skip(ftype); 247 | } 248 | break; 249 | default: 250 | input.skip(ftype); 251 | } 252 | input.readFieldEnd(); 253 | } 254 | input.readStructEnd(); 255 | return; 256 | }; 257 | 258 | TColumnValue.prototype.write = function(output) { 259 | output.writeStructBegin('TColumnValue'); 260 | if (this.family !== null && this.family !== undefined) { 261 | output.writeFieldBegin('family', Thrift.Type.STRING, 1); 262 | output.writeBinary(this.family); 263 | output.writeFieldEnd(); 264 | } 265 | if (this.qualifier !== null && this.qualifier !== undefined) { 266 | output.writeFieldBegin('qualifier', Thrift.Type.STRING, 2); 267 | output.writeBinary(this.qualifier); 268 | output.writeFieldEnd(); 269 | } 270 | if (this.value !== null && this.value !== undefined) { 271 | output.writeFieldBegin('value', Thrift.Type.STRING, 3); 272 | output.writeBinary(this.value); 273 | output.writeFieldEnd(); 274 | } 275 | if (this.timestamp !== null && this.timestamp !== undefined) { 276 | output.writeFieldBegin('timestamp', Thrift.Type.I64, 4); 277 | output.writeI64(this.timestamp); 278 | output.writeFieldEnd(); 279 | } 280 | if (this.tags !== null && this.tags !== undefined) { 281 | output.writeFieldBegin('tags', Thrift.Type.STRING, 5); 282 | output.writeBinary(this.tags); 283 | output.writeFieldEnd(); 284 | } 285 | output.writeFieldStop(); 286 | output.writeStructEnd(); 287 | return; 288 | }; 289 | 290 | var TColumnIncrement = module.exports.TColumnIncrement = function(args) { 291 | this.family = null; 292 | this.qualifier = null; 293 | this.amount = new Int64(1); 294 | if (args) { 295 | if (args.family !== undefined && args.family !== null) { 296 | this.family = args.family; 297 | } else { 298 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field family is unset!'); 299 | } 300 | if (args.qualifier !== undefined && args.qualifier !== null) { 301 | this.qualifier = args.qualifier; 302 | } else { 303 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field qualifier is unset!'); 304 | } 305 | if (args.amount !== undefined && args.amount !== null) { 306 | this.amount = args.amount; 307 | } 308 | } 309 | }; 310 | TColumnIncrement.prototype = {}; 311 | TColumnIncrement.prototype.read = function(input) { 312 | input.readStructBegin(); 313 | while (true) { 314 | var ret = input.readFieldBegin(); 315 | var ftype = ret.ftype; 316 | var fid = ret.fid; 317 | if (ftype == Thrift.Type.STOP) { 318 | break; 319 | } 320 | switch (fid) { 321 | case 1: 322 | if (ftype == Thrift.Type.STRING) { 323 | this.family = input.readBinary(); 324 | } else { 325 | input.skip(ftype); 326 | } 327 | break; 328 | case 2: 329 | if (ftype == Thrift.Type.STRING) { 330 | this.qualifier = input.readBinary(); 331 | } else { 332 | input.skip(ftype); 333 | } 334 | break; 335 | case 3: 336 | if (ftype == Thrift.Type.I64) { 337 | this.amount = input.readI64(); 338 | } else { 339 | input.skip(ftype); 340 | } 341 | break; 342 | default: 343 | input.skip(ftype); 344 | } 345 | input.readFieldEnd(); 346 | } 347 | input.readStructEnd(); 348 | return; 349 | }; 350 | 351 | TColumnIncrement.prototype.write = function(output) { 352 | output.writeStructBegin('TColumnIncrement'); 353 | if (this.family !== null && this.family !== undefined) { 354 | output.writeFieldBegin('family', Thrift.Type.STRING, 1); 355 | output.writeBinary(this.family); 356 | output.writeFieldEnd(); 357 | } 358 | if (this.qualifier !== null && this.qualifier !== undefined) { 359 | output.writeFieldBegin('qualifier', Thrift.Type.STRING, 2); 360 | output.writeBinary(this.qualifier); 361 | output.writeFieldEnd(); 362 | } 363 | if (this.amount !== null && this.amount !== undefined) { 364 | output.writeFieldBegin('amount', Thrift.Type.I64, 3); 365 | output.writeI64(this.amount); 366 | output.writeFieldEnd(); 367 | } 368 | output.writeFieldStop(); 369 | output.writeStructEnd(); 370 | return; 371 | }; 372 | 373 | var TResult = module.exports.TResult = function(args) { 374 | this.row = null; 375 | this.columnValues = null; 376 | if (args) { 377 | if (args.row !== undefined && args.row !== null) { 378 | this.row = args.row; 379 | } 380 | if (args.columnValues !== undefined && args.columnValues !== null) { 381 | this.columnValues = Thrift.copyList(args.columnValues, [ttypes.TColumnValue]); 382 | } else { 383 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field columnValues is unset!'); 384 | } 385 | } 386 | }; 387 | TResult.prototype = {}; 388 | TResult.prototype.read = function(input) { 389 | input.readStructBegin(); 390 | while (true) { 391 | var ret = input.readFieldBegin(); 392 | var ftype = ret.ftype; 393 | var fid = ret.fid; 394 | if (ftype == Thrift.Type.STOP) { 395 | break; 396 | } 397 | switch (fid) { 398 | case 1: 399 | if (ftype == Thrift.Type.STRING) { 400 | this.row = input.readBinary(); 401 | } else { 402 | input.skip(ftype); 403 | } 404 | break; 405 | case 2: 406 | if (ftype == Thrift.Type.LIST) { 407 | this.columnValues = []; 408 | var _rtmp31 = input.readListBegin(); 409 | var _size0 = _rtmp31.size || 0; 410 | for (var _i2 = 0; _i2 < _size0; ++_i2) { 411 | var elem3 = null; 412 | elem3 = new ttypes.TColumnValue(); 413 | elem3.read(input); 414 | this.columnValues.push(elem3); 415 | } 416 | input.readListEnd(); 417 | } else { 418 | input.skip(ftype); 419 | } 420 | break; 421 | default: 422 | input.skip(ftype); 423 | } 424 | input.readFieldEnd(); 425 | } 426 | input.readStructEnd(); 427 | return; 428 | }; 429 | 430 | TResult.prototype.write = function(output) { 431 | output.writeStructBegin('TResult'); 432 | if (this.row !== null && this.row !== undefined) { 433 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 434 | output.writeBinary(this.row); 435 | output.writeFieldEnd(); 436 | } 437 | if (this.columnValues !== null && this.columnValues !== undefined) { 438 | output.writeFieldBegin('columnValues', Thrift.Type.LIST, 2); 439 | output.writeListBegin(Thrift.Type.STRUCT, this.columnValues.length); 440 | for (var iter4 in this.columnValues) { 441 | if (this.columnValues.hasOwnProperty(iter4)) { 442 | iter4 = this.columnValues[iter4]; 443 | iter4.write(output); 444 | } 445 | } 446 | output.writeListEnd(); 447 | output.writeFieldEnd(); 448 | } 449 | output.writeFieldStop(); 450 | output.writeStructEnd(); 451 | return; 452 | }; 453 | 454 | var TAuthorization = module.exports.TAuthorization = function(args) { 455 | this.labels = null; 456 | if (args) { 457 | if (args.labels !== undefined && args.labels !== null) { 458 | this.labels = Thrift.copyList(args.labels, [null]); 459 | } 460 | } 461 | }; 462 | TAuthorization.prototype = {}; 463 | TAuthorization.prototype.read = function(input) { 464 | input.readStructBegin(); 465 | while (true) { 466 | var ret = input.readFieldBegin(); 467 | var ftype = ret.ftype; 468 | var fid = ret.fid; 469 | if (ftype == Thrift.Type.STOP) { 470 | break; 471 | } 472 | switch (fid) { 473 | case 1: 474 | if (ftype == Thrift.Type.LIST) { 475 | this.labels = []; 476 | var _rtmp36 = input.readListBegin(); 477 | var _size5 = _rtmp36.size || 0; 478 | for (var _i7 = 0; _i7 < _size5; ++_i7) { 479 | var elem8 = null; 480 | elem8 = input.readString(); 481 | this.labels.push(elem8); 482 | } 483 | input.readListEnd(); 484 | } else { 485 | input.skip(ftype); 486 | } 487 | break; 488 | case 0: 489 | input.skip(ftype); 490 | break; 491 | default: 492 | input.skip(ftype); 493 | } 494 | input.readFieldEnd(); 495 | } 496 | input.readStructEnd(); 497 | return; 498 | }; 499 | 500 | TAuthorization.prototype.write = function(output) { 501 | output.writeStructBegin('TAuthorization'); 502 | if (this.labels !== null && this.labels !== undefined) { 503 | output.writeFieldBegin('labels', Thrift.Type.LIST, 1); 504 | output.writeListBegin(Thrift.Type.STRING, this.labels.length); 505 | for (var iter9 in this.labels) { 506 | if (this.labels.hasOwnProperty(iter9)) { 507 | iter9 = this.labels[iter9]; 508 | output.writeString(iter9); 509 | } 510 | } 511 | output.writeListEnd(); 512 | output.writeFieldEnd(); 513 | } 514 | output.writeFieldStop(); 515 | output.writeStructEnd(); 516 | return; 517 | }; 518 | 519 | var TCellVisibility = module.exports.TCellVisibility = function(args) { 520 | this.expression = null; 521 | if (args) { 522 | if (args.expression !== undefined && args.expression !== null) { 523 | this.expression = args.expression; 524 | } 525 | } 526 | }; 527 | TCellVisibility.prototype = {}; 528 | TCellVisibility.prototype.read = function(input) { 529 | input.readStructBegin(); 530 | while (true) { 531 | var ret = input.readFieldBegin(); 532 | var ftype = ret.ftype; 533 | var fid = ret.fid; 534 | if (ftype == Thrift.Type.STOP) { 535 | break; 536 | } 537 | switch (fid) { 538 | case 1: 539 | if (ftype == Thrift.Type.STRING) { 540 | this.expression = input.readString(); 541 | } else { 542 | input.skip(ftype); 543 | } 544 | break; 545 | case 0: 546 | input.skip(ftype); 547 | break; 548 | default: 549 | input.skip(ftype); 550 | } 551 | input.readFieldEnd(); 552 | } 553 | input.readStructEnd(); 554 | return; 555 | }; 556 | 557 | TCellVisibility.prototype.write = function(output) { 558 | output.writeStructBegin('TCellVisibility'); 559 | if (this.expression !== null && this.expression !== undefined) { 560 | output.writeFieldBegin('expression', Thrift.Type.STRING, 1); 561 | output.writeString(this.expression); 562 | output.writeFieldEnd(); 563 | } 564 | output.writeFieldStop(); 565 | output.writeStructEnd(); 566 | return; 567 | }; 568 | 569 | var TGet = module.exports.TGet = function(args) { 570 | this.row = null; 571 | this.columns = null; 572 | this.timestamp = null; 573 | this.timeRange = null; 574 | this.maxVersions = null; 575 | this.filterString = null; 576 | this.attributes = null; 577 | this.authorizations = null; 578 | if (args) { 579 | if (args.row !== undefined && args.row !== null) { 580 | this.row = args.row; 581 | } else { 582 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 583 | } 584 | if (args.columns !== undefined && args.columns !== null) { 585 | this.columns = Thrift.copyList(args.columns, [ttypes.TColumn]); 586 | } 587 | if (args.timestamp !== undefined && args.timestamp !== null) { 588 | this.timestamp = args.timestamp; 589 | } 590 | if (args.timeRange !== undefined && args.timeRange !== null) { 591 | this.timeRange = new ttypes.TTimeRange(args.timeRange); 592 | } 593 | if (args.maxVersions !== undefined && args.maxVersions !== null) { 594 | this.maxVersions = args.maxVersions; 595 | } 596 | if (args.filterString !== undefined && args.filterString !== null) { 597 | this.filterString = args.filterString; 598 | } 599 | if (args.attributes !== undefined && args.attributes !== null) { 600 | this.attributes = Thrift.copyMap(args.attributes, [null]); 601 | } 602 | if (args.authorizations !== undefined && args.authorizations !== null) { 603 | this.authorizations = new ttypes.TAuthorization(args.authorizations); 604 | } 605 | } 606 | }; 607 | TGet.prototype = {}; 608 | TGet.prototype.read = function(input) { 609 | input.readStructBegin(); 610 | while (true) { 611 | var ret = input.readFieldBegin(); 612 | var ftype = ret.ftype; 613 | var fid = ret.fid; 614 | if (ftype == Thrift.Type.STOP) { 615 | break; 616 | } 617 | switch (fid) { 618 | case 1: 619 | if (ftype == Thrift.Type.STRING) { 620 | this.row = input.readBinary(); 621 | } else { 622 | input.skip(ftype); 623 | } 624 | break; 625 | case 2: 626 | if (ftype == Thrift.Type.LIST) { 627 | this.columns = []; 628 | var _rtmp311 = input.readListBegin(); 629 | var _size10 = _rtmp311.size || 0; 630 | for (var _i12 = 0; _i12 < _size10; ++_i12) { 631 | var elem13 = null; 632 | elem13 = new ttypes.TColumn(); 633 | elem13.read(input); 634 | this.columns.push(elem13); 635 | } 636 | input.readListEnd(); 637 | } else { 638 | input.skip(ftype); 639 | } 640 | break; 641 | case 3: 642 | if (ftype == Thrift.Type.I64) { 643 | this.timestamp = input.readI64(); 644 | } else { 645 | input.skip(ftype); 646 | } 647 | break; 648 | case 4: 649 | if (ftype == Thrift.Type.STRUCT) { 650 | this.timeRange = new ttypes.TTimeRange(); 651 | this.timeRange.read(input); 652 | } else { 653 | input.skip(ftype); 654 | } 655 | break; 656 | case 5: 657 | if (ftype == Thrift.Type.I32) { 658 | this.maxVersions = input.readI32(); 659 | } else { 660 | input.skip(ftype); 661 | } 662 | break; 663 | case 6: 664 | if (ftype == Thrift.Type.STRING) { 665 | this.filterString = input.readBinary(); 666 | } else { 667 | input.skip(ftype); 668 | } 669 | break; 670 | case 7: 671 | if (ftype == Thrift.Type.MAP) { 672 | this.attributes = {}; 673 | var _rtmp315 = input.readMapBegin(); 674 | var _size14 = _rtmp315.size || 0; 675 | for (var _i16 = 0; _i16 < _size14; ++_i16) { 676 | var key17 = null; 677 | var val18 = null; 678 | key17 = input.readBinary(); 679 | val18 = input.readBinary(); 680 | this.attributes[key17] = val18; 681 | } 682 | input.readMapEnd(); 683 | } else { 684 | input.skip(ftype); 685 | } 686 | break; 687 | case 8: 688 | if (ftype == Thrift.Type.STRUCT) { 689 | this.authorizations = new ttypes.TAuthorization(); 690 | this.authorizations.read(input); 691 | } else { 692 | input.skip(ftype); 693 | } 694 | break; 695 | default: 696 | input.skip(ftype); 697 | } 698 | input.readFieldEnd(); 699 | } 700 | input.readStructEnd(); 701 | return; 702 | }; 703 | 704 | TGet.prototype.write = function(output) { 705 | output.writeStructBegin('TGet'); 706 | if (this.row !== null && this.row !== undefined) { 707 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 708 | output.writeBinary(this.row); 709 | output.writeFieldEnd(); 710 | } 711 | if (this.columns !== null && this.columns !== undefined) { 712 | output.writeFieldBegin('columns', Thrift.Type.LIST, 2); 713 | output.writeListBegin(Thrift.Type.STRUCT, this.columns.length); 714 | for (var iter19 in this.columns) { 715 | if (this.columns.hasOwnProperty(iter19)) { 716 | iter19 = this.columns[iter19]; 717 | iter19.write(output); 718 | } 719 | } 720 | output.writeListEnd(); 721 | output.writeFieldEnd(); 722 | } 723 | if (this.timestamp !== null && this.timestamp !== undefined) { 724 | output.writeFieldBegin('timestamp', Thrift.Type.I64, 3); 725 | output.writeI64(this.timestamp); 726 | output.writeFieldEnd(); 727 | } 728 | if (this.timeRange !== null && this.timeRange !== undefined) { 729 | output.writeFieldBegin('timeRange', Thrift.Type.STRUCT, 4); 730 | this.timeRange.write(output); 731 | output.writeFieldEnd(); 732 | } 733 | if (this.maxVersions !== null && this.maxVersions !== undefined) { 734 | output.writeFieldBegin('maxVersions', Thrift.Type.I32, 5); 735 | output.writeI32(this.maxVersions); 736 | output.writeFieldEnd(); 737 | } 738 | if (this.filterString !== null && this.filterString !== undefined) { 739 | output.writeFieldBegin('filterString', Thrift.Type.STRING, 6); 740 | output.writeBinary(this.filterString); 741 | output.writeFieldEnd(); 742 | } 743 | if (this.attributes !== null && this.attributes !== undefined) { 744 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 7); 745 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 746 | for (var kiter20 in this.attributes) { 747 | if (this.attributes.hasOwnProperty(kiter20)) { 748 | var viter21 = this.attributes[kiter20]; 749 | output.writeBinary(kiter20); 750 | output.writeBinary(viter21); 751 | } 752 | } 753 | output.writeMapEnd(); 754 | output.writeFieldEnd(); 755 | } 756 | if (this.authorizations !== null && this.authorizations !== undefined) { 757 | output.writeFieldBegin('authorizations', Thrift.Type.STRUCT, 8); 758 | this.authorizations.write(output); 759 | output.writeFieldEnd(); 760 | } 761 | output.writeFieldStop(); 762 | output.writeStructEnd(); 763 | return; 764 | }; 765 | 766 | var TPut = module.exports.TPut = function(args) { 767 | this.row = null; 768 | this.columnValues = null; 769 | this.timestamp = null; 770 | this.attributes = null; 771 | this.durability = null; 772 | this.cellVisibility = null; 773 | if (args) { 774 | if (args.row !== undefined && args.row !== null) { 775 | this.row = args.row; 776 | } else { 777 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 778 | } 779 | if (args.columnValues !== undefined && args.columnValues !== null) { 780 | this.columnValues = Thrift.copyList(args.columnValues, [ttypes.TColumnValue]); 781 | } else { 782 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field columnValues is unset!'); 783 | } 784 | if (args.timestamp !== undefined && args.timestamp !== null) { 785 | this.timestamp = args.timestamp; 786 | } 787 | if (args.attributes !== undefined && args.attributes !== null) { 788 | this.attributes = Thrift.copyMap(args.attributes, [null]); 789 | } 790 | if (args.durability !== undefined && args.durability !== null) { 791 | this.durability = args.durability; 792 | } 793 | if (args.cellVisibility !== undefined && args.cellVisibility !== null) { 794 | this.cellVisibility = new ttypes.TCellVisibility(args.cellVisibility); 795 | } 796 | } 797 | }; 798 | TPut.prototype = {}; 799 | TPut.prototype.read = function(input) { 800 | input.readStructBegin(); 801 | while (true) { 802 | var ret = input.readFieldBegin(); 803 | var ftype = ret.ftype; 804 | var fid = ret.fid; 805 | if (ftype == Thrift.Type.STOP) { 806 | break; 807 | } 808 | switch (fid) { 809 | case 1: 810 | if (ftype == Thrift.Type.STRING) { 811 | this.row = input.readBinary(); 812 | } else { 813 | input.skip(ftype); 814 | } 815 | break; 816 | case 2: 817 | if (ftype == Thrift.Type.LIST) { 818 | this.columnValues = []; 819 | var _rtmp323 = input.readListBegin(); 820 | var _size22 = _rtmp323.size || 0; 821 | for (var _i24 = 0; _i24 < _size22; ++_i24) { 822 | var elem25 = null; 823 | elem25 = new ttypes.TColumnValue(); 824 | elem25.read(input); 825 | this.columnValues.push(elem25); 826 | } 827 | input.readListEnd(); 828 | } else { 829 | input.skip(ftype); 830 | } 831 | break; 832 | case 3: 833 | if (ftype == Thrift.Type.I64) { 834 | this.timestamp = input.readI64(); 835 | } else { 836 | input.skip(ftype); 837 | } 838 | break; 839 | case 5: 840 | if (ftype == Thrift.Type.MAP) { 841 | this.attributes = {}; 842 | var _rtmp327 = input.readMapBegin(); 843 | var _size26 = _rtmp327.size || 0; 844 | for (var _i28 = 0; _i28 < _size26; ++_i28) { 845 | var key29 = null; 846 | var val30 = null; 847 | key29 = input.readBinary(); 848 | val30 = input.readBinary(); 849 | this.attributes[key29] = val30; 850 | } 851 | input.readMapEnd(); 852 | } else { 853 | input.skip(ftype); 854 | } 855 | break; 856 | case 6: 857 | if (ftype == Thrift.Type.I32) { 858 | this.durability = input.readI32(); 859 | } else { 860 | input.skip(ftype); 861 | } 862 | break; 863 | case 7: 864 | if (ftype == Thrift.Type.STRUCT) { 865 | this.cellVisibility = new ttypes.TCellVisibility(); 866 | this.cellVisibility.read(input); 867 | } else { 868 | input.skip(ftype); 869 | } 870 | break; 871 | default: 872 | input.skip(ftype); 873 | } 874 | input.readFieldEnd(); 875 | } 876 | input.readStructEnd(); 877 | return; 878 | }; 879 | 880 | TPut.prototype.write = function(output) { 881 | output.writeStructBegin('TPut'); 882 | if (this.row !== null && this.row !== undefined) { 883 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 884 | output.writeBinary(this.row); 885 | output.writeFieldEnd(); 886 | } 887 | if (this.columnValues !== null && this.columnValues !== undefined) { 888 | output.writeFieldBegin('columnValues', Thrift.Type.LIST, 2); 889 | output.writeListBegin(Thrift.Type.STRUCT, this.columnValues.length); 890 | for (var iter31 in this.columnValues) { 891 | if (this.columnValues.hasOwnProperty(iter31)) { 892 | iter31 = this.columnValues[iter31]; 893 | iter31.write(output); 894 | } 895 | } 896 | output.writeListEnd(); 897 | output.writeFieldEnd(); 898 | } 899 | if (this.timestamp !== null && this.timestamp !== undefined) { 900 | output.writeFieldBegin('timestamp', Thrift.Type.I64, 3); 901 | output.writeI64(this.timestamp); 902 | output.writeFieldEnd(); 903 | } 904 | if (this.attributes !== null && this.attributes !== undefined) { 905 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 5); 906 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 907 | for (var kiter32 in this.attributes) { 908 | if (this.attributes.hasOwnProperty(kiter32)) { 909 | var viter33 = this.attributes[kiter32]; 910 | output.writeBinary(kiter32); 911 | output.writeBinary(viter33); 912 | } 913 | } 914 | output.writeMapEnd(); 915 | output.writeFieldEnd(); 916 | } 917 | if (this.durability !== null && this.durability !== undefined) { 918 | output.writeFieldBegin('durability', Thrift.Type.I32, 6); 919 | output.writeI32(this.durability); 920 | output.writeFieldEnd(); 921 | } 922 | if (this.cellVisibility !== null && this.cellVisibility !== undefined) { 923 | output.writeFieldBegin('cellVisibility', Thrift.Type.STRUCT, 7); 924 | this.cellVisibility.write(output); 925 | output.writeFieldEnd(); 926 | } 927 | output.writeFieldStop(); 928 | output.writeStructEnd(); 929 | return; 930 | }; 931 | 932 | var TDelete = module.exports.TDelete = function(args) { 933 | this.row = null; 934 | this.columns = null; 935 | this.timestamp = null; 936 | this.deleteType = 1; 937 | this.attributes = null; 938 | this.durability = null; 939 | if (args) { 940 | if (args.row !== undefined && args.row !== null) { 941 | this.row = args.row; 942 | } else { 943 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 944 | } 945 | if (args.columns !== undefined && args.columns !== null) { 946 | this.columns = Thrift.copyList(args.columns, [ttypes.TColumn]); 947 | } 948 | if (args.timestamp !== undefined && args.timestamp !== null) { 949 | this.timestamp = args.timestamp; 950 | } 951 | if (args.deleteType !== undefined && args.deleteType !== null) { 952 | this.deleteType = args.deleteType; 953 | } 954 | if (args.attributes !== undefined && args.attributes !== null) { 955 | this.attributes = Thrift.copyMap(args.attributes, [null]); 956 | } 957 | if (args.durability !== undefined && args.durability !== null) { 958 | this.durability = args.durability; 959 | } 960 | } 961 | }; 962 | TDelete.prototype = {}; 963 | TDelete.prototype.read = function(input) { 964 | input.readStructBegin(); 965 | while (true) { 966 | var ret = input.readFieldBegin(); 967 | var ftype = ret.ftype; 968 | var fid = ret.fid; 969 | if (ftype == Thrift.Type.STOP) { 970 | break; 971 | } 972 | switch (fid) { 973 | case 1: 974 | if (ftype == Thrift.Type.STRING) { 975 | this.row = input.readBinary(); 976 | } else { 977 | input.skip(ftype); 978 | } 979 | break; 980 | case 2: 981 | if (ftype == Thrift.Type.LIST) { 982 | this.columns = []; 983 | var _rtmp335 = input.readListBegin(); 984 | var _size34 = _rtmp335.size || 0; 985 | for (var _i36 = 0; _i36 < _size34; ++_i36) { 986 | var elem37 = null; 987 | elem37 = new ttypes.TColumn(); 988 | elem37.read(input); 989 | this.columns.push(elem37); 990 | } 991 | input.readListEnd(); 992 | } else { 993 | input.skip(ftype); 994 | } 995 | break; 996 | case 3: 997 | if (ftype == Thrift.Type.I64) { 998 | this.timestamp = input.readI64(); 999 | } else { 1000 | input.skip(ftype); 1001 | } 1002 | break; 1003 | case 4: 1004 | if (ftype == Thrift.Type.I32) { 1005 | this.deleteType = input.readI32(); 1006 | } else { 1007 | input.skip(ftype); 1008 | } 1009 | break; 1010 | case 6: 1011 | if (ftype == Thrift.Type.MAP) { 1012 | this.attributes = {}; 1013 | var _rtmp339 = input.readMapBegin(); 1014 | var _size38 = _rtmp339.size || 0; 1015 | for (var _i40 = 0; _i40 < _size38; ++_i40) { 1016 | var key41 = null; 1017 | var val42 = null; 1018 | key41 = input.readBinary(); 1019 | val42 = input.readBinary(); 1020 | this.attributes[key41] = val42; 1021 | } 1022 | input.readMapEnd(); 1023 | } else { 1024 | input.skip(ftype); 1025 | } 1026 | break; 1027 | case 7: 1028 | if (ftype == Thrift.Type.I32) { 1029 | this.durability = input.readI32(); 1030 | } else { 1031 | input.skip(ftype); 1032 | } 1033 | break; 1034 | default: 1035 | input.skip(ftype); 1036 | } 1037 | input.readFieldEnd(); 1038 | } 1039 | input.readStructEnd(); 1040 | return; 1041 | }; 1042 | 1043 | TDelete.prototype.write = function(output) { 1044 | output.writeStructBegin('TDelete'); 1045 | if (this.row !== null && this.row !== undefined) { 1046 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 1047 | output.writeBinary(this.row); 1048 | output.writeFieldEnd(); 1049 | } 1050 | if (this.columns !== null && this.columns !== undefined) { 1051 | output.writeFieldBegin('columns', Thrift.Type.LIST, 2); 1052 | output.writeListBegin(Thrift.Type.STRUCT, this.columns.length); 1053 | for (var iter43 in this.columns) { 1054 | if (this.columns.hasOwnProperty(iter43)) { 1055 | iter43 = this.columns[iter43]; 1056 | iter43.write(output); 1057 | } 1058 | } 1059 | output.writeListEnd(); 1060 | output.writeFieldEnd(); 1061 | } 1062 | if (this.timestamp !== null && this.timestamp !== undefined) { 1063 | output.writeFieldBegin('timestamp', Thrift.Type.I64, 3); 1064 | output.writeI64(this.timestamp); 1065 | output.writeFieldEnd(); 1066 | } 1067 | if (this.deleteType !== null && this.deleteType !== undefined) { 1068 | output.writeFieldBegin('deleteType', Thrift.Type.I32, 4); 1069 | output.writeI32(this.deleteType); 1070 | output.writeFieldEnd(); 1071 | } 1072 | if (this.attributes !== null && this.attributes !== undefined) { 1073 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 6); 1074 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 1075 | for (var kiter44 in this.attributes) { 1076 | if (this.attributes.hasOwnProperty(kiter44)) { 1077 | var viter45 = this.attributes[kiter44]; 1078 | output.writeBinary(kiter44); 1079 | output.writeBinary(viter45); 1080 | } 1081 | } 1082 | output.writeMapEnd(); 1083 | output.writeFieldEnd(); 1084 | } 1085 | if (this.durability !== null && this.durability !== undefined) { 1086 | output.writeFieldBegin('durability', Thrift.Type.I32, 7); 1087 | output.writeI32(this.durability); 1088 | output.writeFieldEnd(); 1089 | } 1090 | output.writeFieldStop(); 1091 | output.writeStructEnd(); 1092 | return; 1093 | }; 1094 | 1095 | var TIncrement = module.exports.TIncrement = function(args) { 1096 | this.row = null; 1097 | this.columns = null; 1098 | this.attributes = null; 1099 | this.durability = null; 1100 | this.cellVisibility = null; 1101 | if (args) { 1102 | if (args.row !== undefined && args.row !== null) { 1103 | this.row = args.row; 1104 | } else { 1105 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 1106 | } 1107 | if (args.columns !== undefined && args.columns !== null) { 1108 | this.columns = Thrift.copyList(args.columns, [ttypes.TColumnIncrement]); 1109 | } else { 1110 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field columns is unset!'); 1111 | } 1112 | if (args.attributes !== undefined && args.attributes !== null) { 1113 | this.attributes = Thrift.copyMap(args.attributes, [null]); 1114 | } 1115 | if (args.durability !== undefined && args.durability !== null) { 1116 | this.durability = args.durability; 1117 | } 1118 | if (args.cellVisibility !== undefined && args.cellVisibility !== null) { 1119 | this.cellVisibility = new ttypes.TCellVisibility(args.cellVisibility); 1120 | } 1121 | } 1122 | }; 1123 | TIncrement.prototype = {}; 1124 | TIncrement.prototype.read = function(input) { 1125 | input.readStructBegin(); 1126 | while (true) { 1127 | var ret = input.readFieldBegin(); 1128 | var ftype = ret.ftype; 1129 | var fid = ret.fid; 1130 | if (ftype == Thrift.Type.STOP) { 1131 | break; 1132 | } 1133 | switch (fid) { 1134 | case 1: 1135 | if (ftype == Thrift.Type.STRING) { 1136 | this.row = input.readBinary(); 1137 | } else { 1138 | input.skip(ftype); 1139 | } 1140 | break; 1141 | case 2: 1142 | if (ftype == Thrift.Type.LIST) { 1143 | this.columns = []; 1144 | var _rtmp347 = input.readListBegin(); 1145 | var _size46 = _rtmp347.size || 0; 1146 | for (var _i48 = 0; _i48 < _size46; ++_i48) { 1147 | var elem49 = null; 1148 | elem49 = new ttypes.TColumnIncrement(); 1149 | elem49.read(input); 1150 | this.columns.push(elem49); 1151 | } 1152 | input.readListEnd(); 1153 | } else { 1154 | input.skip(ftype); 1155 | } 1156 | break; 1157 | case 4: 1158 | if (ftype == Thrift.Type.MAP) { 1159 | this.attributes = {}; 1160 | var _rtmp351 = input.readMapBegin(); 1161 | var _size50 = _rtmp351.size || 0; 1162 | for (var _i52 = 0; _i52 < _size50; ++_i52) { 1163 | var key53 = null; 1164 | var val54 = null; 1165 | key53 = input.readBinary(); 1166 | val54 = input.readBinary(); 1167 | this.attributes[key53] = val54; 1168 | } 1169 | input.readMapEnd(); 1170 | } else { 1171 | input.skip(ftype); 1172 | } 1173 | break; 1174 | case 5: 1175 | if (ftype == Thrift.Type.I32) { 1176 | this.durability = input.readI32(); 1177 | } else { 1178 | input.skip(ftype); 1179 | } 1180 | break; 1181 | case 6: 1182 | if (ftype == Thrift.Type.STRUCT) { 1183 | this.cellVisibility = new ttypes.TCellVisibility(); 1184 | this.cellVisibility.read(input); 1185 | } else { 1186 | input.skip(ftype); 1187 | } 1188 | break; 1189 | default: 1190 | input.skip(ftype); 1191 | } 1192 | input.readFieldEnd(); 1193 | } 1194 | input.readStructEnd(); 1195 | return; 1196 | }; 1197 | 1198 | TIncrement.prototype.write = function(output) { 1199 | output.writeStructBegin('TIncrement'); 1200 | if (this.row !== null && this.row !== undefined) { 1201 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 1202 | output.writeBinary(this.row); 1203 | output.writeFieldEnd(); 1204 | } 1205 | if (this.columns !== null && this.columns !== undefined) { 1206 | output.writeFieldBegin('columns', Thrift.Type.LIST, 2); 1207 | output.writeListBegin(Thrift.Type.STRUCT, this.columns.length); 1208 | for (var iter55 in this.columns) { 1209 | if (this.columns.hasOwnProperty(iter55)) { 1210 | iter55 = this.columns[iter55]; 1211 | iter55.write(output); 1212 | } 1213 | } 1214 | output.writeListEnd(); 1215 | output.writeFieldEnd(); 1216 | } 1217 | if (this.attributes !== null && this.attributes !== undefined) { 1218 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 4); 1219 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 1220 | for (var kiter56 in this.attributes) { 1221 | if (this.attributes.hasOwnProperty(kiter56)) { 1222 | var viter57 = this.attributes[kiter56]; 1223 | output.writeBinary(kiter56); 1224 | output.writeBinary(viter57); 1225 | } 1226 | } 1227 | output.writeMapEnd(); 1228 | output.writeFieldEnd(); 1229 | } 1230 | if (this.durability !== null && this.durability !== undefined) { 1231 | output.writeFieldBegin('durability', Thrift.Type.I32, 5); 1232 | output.writeI32(this.durability); 1233 | output.writeFieldEnd(); 1234 | } 1235 | if (this.cellVisibility !== null && this.cellVisibility !== undefined) { 1236 | output.writeFieldBegin('cellVisibility', Thrift.Type.STRUCT, 6); 1237 | this.cellVisibility.write(output); 1238 | output.writeFieldEnd(); 1239 | } 1240 | output.writeFieldStop(); 1241 | output.writeStructEnd(); 1242 | return; 1243 | }; 1244 | 1245 | var TAppend = module.exports.TAppend = function(args) { 1246 | this.row = null; 1247 | this.columns = null; 1248 | this.attributes = null; 1249 | this.durability = null; 1250 | this.cellVisibility = null; 1251 | if (args) { 1252 | if (args.row !== undefined && args.row !== null) { 1253 | this.row = args.row; 1254 | } else { 1255 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 1256 | } 1257 | if (args.columns !== undefined && args.columns !== null) { 1258 | this.columns = Thrift.copyList(args.columns, [ttypes.TColumnValue]); 1259 | } else { 1260 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field columns is unset!'); 1261 | } 1262 | if (args.attributes !== undefined && args.attributes !== null) { 1263 | this.attributes = Thrift.copyMap(args.attributes, [null]); 1264 | } 1265 | if (args.durability !== undefined && args.durability !== null) { 1266 | this.durability = args.durability; 1267 | } 1268 | if (args.cellVisibility !== undefined && args.cellVisibility !== null) { 1269 | this.cellVisibility = new ttypes.TCellVisibility(args.cellVisibility); 1270 | } 1271 | } 1272 | }; 1273 | TAppend.prototype = {}; 1274 | TAppend.prototype.read = function(input) { 1275 | input.readStructBegin(); 1276 | while (true) { 1277 | var ret = input.readFieldBegin(); 1278 | var ftype = ret.ftype; 1279 | var fid = ret.fid; 1280 | if (ftype == Thrift.Type.STOP) { 1281 | break; 1282 | } 1283 | switch (fid) { 1284 | case 1: 1285 | if (ftype == Thrift.Type.STRING) { 1286 | this.row = input.readBinary(); 1287 | } else { 1288 | input.skip(ftype); 1289 | } 1290 | break; 1291 | case 2: 1292 | if (ftype == Thrift.Type.LIST) { 1293 | this.columns = []; 1294 | var _rtmp359 = input.readListBegin(); 1295 | var _size58 = _rtmp359.size || 0; 1296 | for (var _i60 = 0; _i60 < _size58; ++_i60) { 1297 | var elem61 = null; 1298 | elem61 = new ttypes.TColumnValue(); 1299 | elem61.read(input); 1300 | this.columns.push(elem61); 1301 | } 1302 | input.readListEnd(); 1303 | } else { 1304 | input.skip(ftype); 1305 | } 1306 | break; 1307 | case 3: 1308 | if (ftype == Thrift.Type.MAP) { 1309 | this.attributes = {}; 1310 | var _rtmp363 = input.readMapBegin(); 1311 | var _size62 = _rtmp363.size || 0; 1312 | for (var _i64 = 0; _i64 < _size62; ++_i64) { 1313 | var key65 = null; 1314 | var val66 = null; 1315 | key65 = input.readBinary(); 1316 | val66 = input.readBinary(); 1317 | this.attributes[key65] = val66; 1318 | } 1319 | input.readMapEnd(); 1320 | } else { 1321 | input.skip(ftype); 1322 | } 1323 | break; 1324 | case 4: 1325 | if (ftype == Thrift.Type.I32) { 1326 | this.durability = input.readI32(); 1327 | } else { 1328 | input.skip(ftype); 1329 | } 1330 | break; 1331 | case 5: 1332 | if (ftype == Thrift.Type.STRUCT) { 1333 | this.cellVisibility = new ttypes.TCellVisibility(); 1334 | this.cellVisibility.read(input); 1335 | } else { 1336 | input.skip(ftype); 1337 | } 1338 | break; 1339 | default: 1340 | input.skip(ftype); 1341 | } 1342 | input.readFieldEnd(); 1343 | } 1344 | input.readStructEnd(); 1345 | return; 1346 | }; 1347 | 1348 | TAppend.prototype.write = function(output) { 1349 | output.writeStructBegin('TAppend'); 1350 | if (this.row !== null && this.row !== undefined) { 1351 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 1352 | output.writeBinary(this.row); 1353 | output.writeFieldEnd(); 1354 | } 1355 | if (this.columns !== null && this.columns !== undefined) { 1356 | output.writeFieldBegin('columns', Thrift.Type.LIST, 2); 1357 | output.writeListBegin(Thrift.Type.STRUCT, this.columns.length); 1358 | for (var iter67 in this.columns) { 1359 | if (this.columns.hasOwnProperty(iter67)) { 1360 | iter67 = this.columns[iter67]; 1361 | iter67.write(output); 1362 | } 1363 | } 1364 | output.writeListEnd(); 1365 | output.writeFieldEnd(); 1366 | } 1367 | if (this.attributes !== null && this.attributes !== undefined) { 1368 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 3); 1369 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 1370 | for (var kiter68 in this.attributes) { 1371 | if (this.attributes.hasOwnProperty(kiter68)) { 1372 | var viter69 = this.attributes[kiter68]; 1373 | output.writeBinary(kiter68); 1374 | output.writeBinary(viter69); 1375 | } 1376 | } 1377 | output.writeMapEnd(); 1378 | output.writeFieldEnd(); 1379 | } 1380 | if (this.durability !== null && this.durability !== undefined) { 1381 | output.writeFieldBegin('durability', Thrift.Type.I32, 4); 1382 | output.writeI32(this.durability); 1383 | output.writeFieldEnd(); 1384 | } 1385 | if (this.cellVisibility !== null && this.cellVisibility !== undefined) { 1386 | output.writeFieldBegin('cellVisibility', Thrift.Type.STRUCT, 5); 1387 | this.cellVisibility.write(output); 1388 | output.writeFieldEnd(); 1389 | } 1390 | output.writeFieldStop(); 1391 | output.writeStructEnd(); 1392 | return; 1393 | }; 1394 | 1395 | var TScan = module.exports.TScan = function(args) { 1396 | this.startRow = null; 1397 | this.stopRow = null; 1398 | this.columns = null; 1399 | this.caching = null; 1400 | this.maxVersions = 1; 1401 | this.timeRange = null; 1402 | this.filterString = null; 1403 | this.batchSize = null; 1404 | this.attributes = null; 1405 | this.authorizations = null; 1406 | this.reversed = null; 1407 | if (args) { 1408 | if (args.startRow !== undefined && args.startRow !== null) { 1409 | this.startRow = args.startRow; 1410 | } 1411 | if (args.stopRow !== undefined && args.stopRow !== null) { 1412 | this.stopRow = args.stopRow; 1413 | } 1414 | if (args.columns !== undefined && args.columns !== null) { 1415 | this.columns = Thrift.copyList(args.columns, [ttypes.TColumn]); 1416 | } 1417 | if (args.caching !== undefined && args.caching !== null) { 1418 | this.caching = args.caching; 1419 | } 1420 | if (args.maxVersions !== undefined && args.maxVersions !== null) { 1421 | this.maxVersions = args.maxVersions; 1422 | } 1423 | if (args.timeRange !== undefined && args.timeRange !== null) { 1424 | this.timeRange = new ttypes.TTimeRange(args.timeRange); 1425 | } 1426 | if (args.filterString !== undefined && args.filterString !== null) { 1427 | this.filterString = args.filterString; 1428 | } 1429 | if (args.batchSize !== undefined && args.batchSize !== null) { 1430 | this.batchSize = args.batchSize; 1431 | } 1432 | if (args.attributes !== undefined && args.attributes !== null) { 1433 | this.attributes = Thrift.copyMap(args.attributes, [null]); 1434 | } 1435 | if (args.authorizations !== undefined && args.authorizations !== null) { 1436 | this.authorizations = new ttypes.TAuthorization(args.authorizations); 1437 | } 1438 | if (args.reversed !== undefined && args.reversed !== null) { 1439 | this.reversed = args.reversed; 1440 | } 1441 | } 1442 | }; 1443 | TScan.prototype = {}; 1444 | TScan.prototype.read = function(input) { 1445 | input.readStructBegin(); 1446 | while (true) { 1447 | var ret = input.readFieldBegin(); 1448 | var ftype = ret.ftype; 1449 | var fid = ret.fid; 1450 | if (ftype == Thrift.Type.STOP) { 1451 | break; 1452 | } 1453 | switch (fid) { 1454 | case 1: 1455 | if (ftype == Thrift.Type.STRING) { 1456 | this.startRow = input.readBinary(); 1457 | } else { 1458 | input.skip(ftype); 1459 | } 1460 | break; 1461 | case 2: 1462 | if (ftype == Thrift.Type.STRING) { 1463 | this.stopRow = input.readBinary(); 1464 | } else { 1465 | input.skip(ftype); 1466 | } 1467 | break; 1468 | case 3: 1469 | if (ftype == Thrift.Type.LIST) { 1470 | this.columns = []; 1471 | var _rtmp371 = input.readListBegin(); 1472 | var _size70 = _rtmp371.size || 0; 1473 | for (var _i72 = 0; _i72 < _size70; ++_i72) { 1474 | var elem73 = null; 1475 | elem73 = new ttypes.TColumn(); 1476 | elem73.read(input); 1477 | this.columns.push(elem73); 1478 | } 1479 | input.readListEnd(); 1480 | } else { 1481 | input.skip(ftype); 1482 | } 1483 | break; 1484 | case 4: 1485 | if (ftype == Thrift.Type.I32) { 1486 | this.caching = input.readI32(); 1487 | } else { 1488 | input.skip(ftype); 1489 | } 1490 | break; 1491 | case 5: 1492 | if (ftype == Thrift.Type.I32) { 1493 | this.maxVersions = input.readI32(); 1494 | } else { 1495 | input.skip(ftype); 1496 | } 1497 | break; 1498 | case 6: 1499 | if (ftype == Thrift.Type.STRUCT) { 1500 | this.timeRange = new ttypes.TTimeRange(); 1501 | this.timeRange.read(input); 1502 | } else { 1503 | input.skip(ftype); 1504 | } 1505 | break; 1506 | case 7: 1507 | if (ftype == Thrift.Type.STRING) { 1508 | this.filterString = input.readBinary(); 1509 | } else { 1510 | input.skip(ftype); 1511 | } 1512 | break; 1513 | case 8: 1514 | if (ftype == Thrift.Type.I32) { 1515 | this.batchSize = input.readI32(); 1516 | } else { 1517 | input.skip(ftype); 1518 | } 1519 | break; 1520 | case 9: 1521 | if (ftype == Thrift.Type.MAP) { 1522 | this.attributes = {}; 1523 | var _rtmp375 = input.readMapBegin(); 1524 | var _size74 = _rtmp375.size || 0; 1525 | for (var _i76 = 0; _i76 < _size74; ++_i76) { 1526 | var key77 = null; 1527 | var val78 = null; 1528 | key77 = input.readBinary(); 1529 | val78 = input.readBinary(); 1530 | this.attributes[key77] = val78; 1531 | } 1532 | input.readMapEnd(); 1533 | } else { 1534 | input.skip(ftype); 1535 | } 1536 | break; 1537 | case 10: 1538 | if (ftype == Thrift.Type.STRUCT) { 1539 | this.authorizations = new ttypes.TAuthorization(); 1540 | this.authorizations.read(input); 1541 | } else { 1542 | input.skip(ftype); 1543 | } 1544 | break; 1545 | case 11: 1546 | if (ftype == Thrift.Type.BOOL) { 1547 | this.reversed = input.readBool(); 1548 | } else { 1549 | input.skip(ftype); 1550 | } 1551 | break; 1552 | default: 1553 | input.skip(ftype); 1554 | } 1555 | input.readFieldEnd(); 1556 | } 1557 | input.readStructEnd(); 1558 | return; 1559 | }; 1560 | 1561 | TScan.prototype.write = function(output) { 1562 | output.writeStructBegin('TScan'); 1563 | if (this.startRow !== null && this.startRow !== undefined) { 1564 | output.writeFieldBegin('startRow', Thrift.Type.STRING, 1); 1565 | output.writeBinary(this.startRow); 1566 | output.writeFieldEnd(); 1567 | } 1568 | if (this.stopRow !== null && this.stopRow !== undefined) { 1569 | output.writeFieldBegin('stopRow', Thrift.Type.STRING, 2); 1570 | output.writeBinary(this.stopRow); 1571 | output.writeFieldEnd(); 1572 | } 1573 | if (this.columns !== null && this.columns !== undefined) { 1574 | output.writeFieldBegin('columns', Thrift.Type.LIST, 3); 1575 | output.writeListBegin(Thrift.Type.STRUCT, this.columns.length); 1576 | for (var iter79 in this.columns) { 1577 | if (this.columns.hasOwnProperty(iter79)) { 1578 | iter79 = this.columns[iter79]; 1579 | iter79.write(output); 1580 | } 1581 | } 1582 | output.writeListEnd(); 1583 | output.writeFieldEnd(); 1584 | } 1585 | if (this.caching !== null && this.caching !== undefined) { 1586 | output.writeFieldBegin('caching', Thrift.Type.I32, 4); 1587 | output.writeI32(this.caching); 1588 | output.writeFieldEnd(); 1589 | } 1590 | if (this.maxVersions !== null && this.maxVersions !== undefined) { 1591 | output.writeFieldBegin('maxVersions', Thrift.Type.I32, 5); 1592 | output.writeI32(this.maxVersions); 1593 | output.writeFieldEnd(); 1594 | } 1595 | if (this.timeRange !== null && this.timeRange !== undefined) { 1596 | output.writeFieldBegin('timeRange', Thrift.Type.STRUCT, 6); 1597 | this.timeRange.write(output); 1598 | output.writeFieldEnd(); 1599 | } 1600 | if (this.filterString !== null && this.filterString !== undefined) { 1601 | output.writeFieldBegin('filterString', Thrift.Type.STRING, 7); 1602 | output.writeBinary(this.filterString); 1603 | output.writeFieldEnd(); 1604 | } 1605 | if (this.batchSize !== null && this.batchSize !== undefined) { 1606 | output.writeFieldBegin('batchSize', Thrift.Type.I32, 8); 1607 | output.writeI32(this.batchSize); 1608 | output.writeFieldEnd(); 1609 | } 1610 | if (this.attributes !== null && this.attributes !== undefined) { 1611 | output.writeFieldBegin('attributes', Thrift.Type.MAP, 9); 1612 | output.writeMapBegin(Thrift.Type.STRING, Thrift.Type.STRING, Thrift.objectLength(this.attributes)); 1613 | for (var kiter80 in this.attributes) { 1614 | if (this.attributes.hasOwnProperty(kiter80)) { 1615 | var viter81 = this.attributes[kiter80]; 1616 | output.writeBinary(kiter80); 1617 | output.writeBinary(viter81); 1618 | } 1619 | } 1620 | output.writeMapEnd(); 1621 | output.writeFieldEnd(); 1622 | } 1623 | if (this.authorizations !== null && this.authorizations !== undefined) { 1624 | output.writeFieldBegin('authorizations', Thrift.Type.STRUCT, 10); 1625 | this.authorizations.write(output); 1626 | output.writeFieldEnd(); 1627 | } 1628 | if (this.reversed !== null && this.reversed !== undefined) { 1629 | output.writeFieldBegin('reversed', Thrift.Type.BOOL, 11); 1630 | output.writeBool(this.reversed); 1631 | output.writeFieldEnd(); 1632 | } 1633 | output.writeFieldStop(); 1634 | output.writeStructEnd(); 1635 | return; 1636 | }; 1637 | 1638 | var TMutation = module.exports.TMutation = function(args) { 1639 | this.put = null; 1640 | this.deleteSingle = null; 1641 | if (args) { 1642 | if (args.put !== undefined && args.put !== null) { 1643 | this.put = new ttypes.TPut(args.put); 1644 | } 1645 | if (args.deleteSingle !== undefined && args.deleteSingle !== null) { 1646 | this.deleteSingle = new ttypes.TDelete(args.deleteSingle); 1647 | } 1648 | } 1649 | }; 1650 | TMutation.prototype = {}; 1651 | TMutation.prototype.read = function(input) { 1652 | input.readStructBegin(); 1653 | while (true) { 1654 | var ret = input.readFieldBegin(); 1655 | var ftype = ret.ftype; 1656 | var fid = ret.fid; 1657 | if (ftype == Thrift.Type.STOP) { 1658 | break; 1659 | } 1660 | switch (fid) { 1661 | case 1: 1662 | if (ftype == Thrift.Type.STRUCT) { 1663 | this.put = new ttypes.TPut(); 1664 | this.put.read(input); 1665 | } else { 1666 | input.skip(ftype); 1667 | } 1668 | break; 1669 | case 2: 1670 | if (ftype == Thrift.Type.STRUCT) { 1671 | this.deleteSingle = new ttypes.TDelete(); 1672 | this.deleteSingle.read(input); 1673 | } else { 1674 | input.skip(ftype); 1675 | } 1676 | break; 1677 | default: 1678 | input.skip(ftype); 1679 | } 1680 | input.readFieldEnd(); 1681 | } 1682 | input.readStructEnd(); 1683 | return; 1684 | }; 1685 | 1686 | TMutation.prototype.write = function(output) { 1687 | output.writeStructBegin('TMutation'); 1688 | if (this.put !== null && this.put !== undefined) { 1689 | output.writeFieldBegin('put', Thrift.Type.STRUCT, 1); 1690 | this.put.write(output); 1691 | output.writeFieldEnd(); 1692 | } 1693 | if (this.deleteSingle !== null && this.deleteSingle !== undefined) { 1694 | output.writeFieldBegin('deleteSingle', Thrift.Type.STRUCT, 2); 1695 | this.deleteSingle.write(output); 1696 | output.writeFieldEnd(); 1697 | } 1698 | output.writeFieldStop(); 1699 | output.writeStructEnd(); 1700 | return; 1701 | }; 1702 | 1703 | var TRowMutations = module.exports.TRowMutations = function(args) { 1704 | this.row = null; 1705 | this.mutations = null; 1706 | if (args) { 1707 | if (args.row !== undefined && args.row !== null) { 1708 | this.row = args.row; 1709 | } else { 1710 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field row is unset!'); 1711 | } 1712 | if (args.mutations !== undefined && args.mutations !== null) { 1713 | this.mutations = Thrift.copyList(args.mutations, [ttypes.TMutation]); 1714 | } else { 1715 | throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field mutations is unset!'); 1716 | } 1717 | } 1718 | }; 1719 | TRowMutations.prototype = {}; 1720 | TRowMutations.prototype.read = function(input) { 1721 | input.readStructBegin(); 1722 | while (true) { 1723 | var ret = input.readFieldBegin(); 1724 | var ftype = ret.ftype; 1725 | var fid = ret.fid; 1726 | if (ftype == Thrift.Type.STOP) { 1727 | break; 1728 | } 1729 | switch (fid) { 1730 | case 1: 1731 | if (ftype == Thrift.Type.STRING) { 1732 | this.row = input.readBinary(); 1733 | } else { 1734 | input.skip(ftype); 1735 | } 1736 | break; 1737 | case 2: 1738 | if (ftype == Thrift.Type.LIST) { 1739 | this.mutations = []; 1740 | var _rtmp383 = input.readListBegin(); 1741 | var _size82 = _rtmp383.size || 0; 1742 | for (var _i84 = 0; _i84 < _size82; ++_i84) { 1743 | var elem85 = null; 1744 | elem85 = new ttypes.TMutation(); 1745 | elem85.read(input); 1746 | this.mutations.push(elem85); 1747 | } 1748 | input.readListEnd(); 1749 | } else { 1750 | input.skip(ftype); 1751 | } 1752 | break; 1753 | default: 1754 | input.skip(ftype); 1755 | } 1756 | input.readFieldEnd(); 1757 | } 1758 | input.readStructEnd(); 1759 | return; 1760 | }; 1761 | 1762 | TRowMutations.prototype.write = function(output) { 1763 | output.writeStructBegin('TRowMutations'); 1764 | if (this.row !== null && this.row !== undefined) { 1765 | output.writeFieldBegin('row', Thrift.Type.STRING, 1); 1766 | output.writeBinary(this.row); 1767 | output.writeFieldEnd(); 1768 | } 1769 | if (this.mutations !== null && this.mutations !== undefined) { 1770 | output.writeFieldBegin('mutations', Thrift.Type.LIST, 2); 1771 | output.writeListBegin(Thrift.Type.STRUCT, this.mutations.length); 1772 | for (var iter86 in this.mutations) { 1773 | if (this.mutations.hasOwnProperty(iter86)) { 1774 | iter86 = this.mutations[iter86]; 1775 | iter86.write(output); 1776 | } 1777 | } 1778 | output.writeListEnd(); 1779 | output.writeFieldEnd(); 1780 | } 1781 | output.writeFieldStop(); 1782 | output.writeStructEnd(); 1783 | return; 1784 | }; 1785 | 1786 | var TIOError = module.exports.TIOError = function(args) { 1787 | Thrift.TException.call(this, "TIOError"); 1788 | this.name = "TIOError"; 1789 | this.message = null; 1790 | if (args) { 1791 | if (args.message !== undefined && args.message !== null) { 1792 | this.message = args.message; 1793 | } 1794 | } 1795 | }; 1796 | Thrift.inherits(TIOError, Thrift.TException); 1797 | TIOError.prototype.name = 'TIOError'; 1798 | TIOError.prototype.read = function(input) { 1799 | input.readStructBegin(); 1800 | while (true) { 1801 | var ret = input.readFieldBegin(); 1802 | var ftype = ret.ftype; 1803 | var fid = ret.fid; 1804 | if (ftype == Thrift.Type.STOP) { 1805 | break; 1806 | } 1807 | switch (fid) { 1808 | case 1: 1809 | if (ftype == Thrift.Type.STRING) { 1810 | this.message = input.readString(); 1811 | } else { 1812 | input.skip(ftype); 1813 | } 1814 | break; 1815 | case 0: 1816 | input.skip(ftype); 1817 | break; 1818 | default: 1819 | input.skip(ftype); 1820 | } 1821 | input.readFieldEnd(); 1822 | } 1823 | input.readStructEnd(); 1824 | return; 1825 | }; 1826 | 1827 | TIOError.prototype.write = function(output) { 1828 | output.writeStructBegin('TIOError'); 1829 | if (this.message !== null && this.message !== undefined) { 1830 | output.writeFieldBegin('message', Thrift.Type.STRING, 1); 1831 | output.writeString(this.message); 1832 | output.writeFieldEnd(); 1833 | } 1834 | output.writeFieldStop(); 1835 | output.writeStructEnd(); 1836 | return; 1837 | }; 1838 | 1839 | var TIllegalArgument = module.exports.TIllegalArgument = function(args) { 1840 | Thrift.TException.call(this, "TIllegalArgument"); 1841 | this.name = "TIllegalArgument"; 1842 | this.message = null; 1843 | if (args) { 1844 | if (args.message !== undefined && args.message !== null) { 1845 | this.message = args.message; 1846 | } 1847 | } 1848 | }; 1849 | Thrift.inherits(TIllegalArgument, Thrift.TException); 1850 | TIllegalArgument.prototype.name = 'TIllegalArgument'; 1851 | TIllegalArgument.prototype.read = function(input) { 1852 | input.readStructBegin(); 1853 | while (true) { 1854 | var ret = input.readFieldBegin(); 1855 | var ftype = ret.ftype; 1856 | var fid = ret.fid; 1857 | if (ftype == Thrift.Type.STOP) { 1858 | break; 1859 | } 1860 | switch (fid) { 1861 | case 1: 1862 | if (ftype == Thrift.Type.STRING) { 1863 | this.message = input.readString(); 1864 | } else { 1865 | input.skip(ftype); 1866 | } 1867 | break; 1868 | case 0: 1869 | input.skip(ftype); 1870 | break; 1871 | default: 1872 | input.skip(ftype); 1873 | } 1874 | input.readFieldEnd(); 1875 | } 1876 | input.readStructEnd(); 1877 | return; 1878 | }; 1879 | 1880 | TIllegalArgument.prototype.write = function(output) { 1881 | output.writeStructBegin('TIllegalArgument'); 1882 | if (this.message !== null && this.message !== undefined) { 1883 | output.writeFieldBegin('message', Thrift.Type.STRING, 1); 1884 | output.writeString(this.message); 1885 | output.writeFieldEnd(); 1886 | } 1887 | output.writeFieldStop(); 1888 | output.writeStructEnd(); 1889 | return; 1890 | }; 1891 | 1892 | --------------------------------------------------------------------------------