nosqldb-oraclejs
Version:
Oracle NoSQL Database JS Driver
414 lines (375 loc) • 12.4 kB
JavaScript
/*-
*
* This file is part of Oracle NoSQL Database
* Copyright (C) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
*
* If you have received this file as part of Oracle NoSQL Database the
* following applies to the work as a whole:
*
* Oracle NoSQL Database server software is free software: you can
* redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation,
* version 3.
*
* Oracle NoSQL Database is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more message.
*
* If you have received this file as part of Oracle NoSQL Database Client or
* distributed separately the following applies:
*
* Oracle NoSQL Database client software is free software: you can
* redistribute it and/or modify it under the terms of the Apache License
* as published by the Apache Software Foundation, version 2.0.
*
* You should have received a copy of the GNU Affero General Public License
* and/or the Apache License in the LICENSE file along with Oracle NoSQL
* Database client or server distribution. If not, see
* <http://www.gnu.org/licenses/>
* or
* <http://www.apache.org/licenses/LICENSE-2.0>.
*
* An active Oracle commercial licensing agreement for this product supersedes
* these licenses and in such case the license notices, but not the copyright
* notice, may be removed by you in connection with your distribution that is
* in accordance with the commercial licensing terms.
*
* For more information please contact:
*
* berkeleydb-info_us@oracle.com
*
*/
'use strict';
var Int64 = require('node-int64');
var Parse = require('../lib/parse');
var crypto = require('crypto');
exports.parse = Parse;
var client = require('../nosqldb');
var Types = client.Types;
function assertDescriptive(/*Object*/
result,
/*String*/
error,
/*String*/
message) {
if ((result === null) || (result === undefined))
throw new Error('Expected error: ' + error);
assert(result.message.search(error) !== -1,
message + ' - Actual: ' + result.message + ' Expected: ' + error + '');
}
exports.assertDescriptive = assertDescriptive;
function assertEqual(/*Object*/ arg1, /*Error*/ arg2, /*String*/ message) {
assert.equal(arg1, arg2,
message + ' - Actual: ' + arg1 + ' Expected: ' + arg2 + '')
}
exports.assertEqual = assertEqual;
function split(/*String*/ string, /*String*/ separator) {
var pos = string.indexOf(separator);
var result = [];
while (pos >= 0) {
result.push(string.slice(0, pos));
pos = string.indexOf(separator);
}
if (result.length == 0)
result.push(string);
return result;
}
exports.split = split;
function compareArrays(/*Array*/ array1, /*Array*/ array2) {
// Testing for nulls
if ((!array1) || (!array2))
return false;
// Test for Array type
if (!(array1 instanceof Array) || !(array2 instanceof Array))
return false;
// Test for Arrays Lengths
if (array1.length !== array2.length)
return false;
for (var i = 0, l = array1.length; i < l; i++) {
// Check for nested arrays
if ((array1[i] instanceof Array && array2[i] instanceof Array) &&
(!compareArrays(array1[i], array2[i])))
return false;
if (array1[i] != array2[i])
return false;
}
return true;
}
exports.compareArrays = compareArrays;
function compareRows(/*Object*/ row1, /*Object*/ row2) {
// Testing for nulls
if (!row1)
return 'First row is not defined';
if (!row2)
return 'Second row is not defined';
for (var key in row1) {
// check key on row2
if (!(key in row2))
return key + ' property not found in row2';
// Check for Int64
if ((row1[key] instanceof Int64 && row2[key] instanceof Int64)) {
if (row1[key].toOctetString('') === row2[key].toOctetString(''))
return null;
else
return key + ' property not equal (Int64)';
}
//Check for Array
if ((row1[key] instanceof Array && row2[key] instanceof Array) &&
(!compareArrays(row1[key], row2[key]))) {
return key + ' property not equal (Array)';
// Check for nested objects
}
if ((row1[key] instanceof Object && row2[key] instanceof Object) &&
(!compareRows(row1[key], row1[key]))) {
return key + ' property not equal (Object)';
// Normal value
}
if (row1[key] != row2[key]) {
return key + ' property not equal (Value) [' + row1[key] + ',' +
row2[key] + ']';
}
}
return null;
}
exports.compareRows = compareRows;
// Preparing Row
var file64 = new Buffer(fs.readFileSync(__dirname + '/image.jpg'))
.toString('base64');
var fbin64 = new Buffer('1234567890').toString('base64');
function Row(/*Number*/ id, /*Number*/ shardKey) {
if (id == null)
id = 0;
if (shardKey == null)
shardKey = id;
this.shardKey = shardKey;
this.id = id;
this.indexKey1 = id;
this.indexKey2 = id;
this.s = 'String value';
this.l = new Int64('1111222233334444'); // using Int64 for big numbers
this.f = 9.123456; //float
this.d = 9.12345678901234; //double
this.bool = true;
this.bin = file64;
this.fbin = fbin64;
this.arrStr = ['X', 'Y', 'Z'];
this.e = 'A';
this.address = {
street: 'address street', city: 'address city',
state: 'address state', zip: 55555
};
this.m = {field1: 'map field 1', field2: 'map field 2'};
}
exports.Row = Row;
/**
* Create a row with given id and shard key and populate with random
* values and an expiration of 1 day.
* @param id
* @param shardKey
* @return
*/
function RandomRow(/*Number*/ id, /*Number*/ shardKey) {
if (id == null)
id = 0;
if (shardKey == null)
shardKey = id;
this.shardKey = shardKey;
this.id = id;
this.indexKey1 = Math.floor(Math.random() * 100000);
this.indexKey2 = Math.floor(Math.random() * 100000);
this.l = Math.floor(Math.random() * 100000);
this.f = Math.random() * 10; //float
this.d = Math.random() * 100; //double
this.bool = (Math.random() * 10) > 5;
this.bin = generateRandomData().toString('base64');
this.fbin = fbin64;
this.arrStr = [generateRandomString(), generateRandomString()];
this.e = 'A';
this.address = {
street: generateRandomString(), city: generateRandomString(),
state: generateRandomString(), zip: Math.floor(Math.random() * 10000)
};
this.m = {field1: generateRandomString(), field2: generateRandomString()};
var shasum = crypto.createHash('sha1');
shasum.update(this.indexKey1.toString());
shasum.update(this.indexKey2.toString());
shasum.update(this.l.toString());
shasum.update(this.bool.toString());
shasum.update(this.bin.toString());
shasum.update(this.fbin.toString());
shasum.update(this.arrStr[0]);
shasum.update(this.arrStr[1]);
shasum.update(this.e);
shasum.update(this.address.street);
shasum.update(this.address.city);
shasum.update(this.address.state);
shasum.update(this.address.zip.toString());
shasum.update(this.m.field1);
shasum.update(this.m.field2);
this.s = shasum.digest('hex');
this.ttl = new Types.TimeToLive(1, Types.TimeUnit.DAYS);
}
exports.RandomRow = RandomRow;
function calculateHashRow(/*Row*/ row) {
var shasum = crypto.createHash('sha1');
shasum.update(row.indexKey1.toString());
shasum.update(row.indexKey2.toString());
shasum.update(row.l.toString());
shasum.update(row.bool.toString());
shasum.update(row.bin.toString());
shasum.update(row.fbin.toString());
shasum.update(row.arrStr[0]);
shasum.update(row.arrStr[1]);
shasum.update(row.e);
shasum.update(row.address.street);
shasum.update(row.address.city);
shasum.update(row.address.state);
shasum.update(row.address.zip.toString());
shasum.update(row.m.field1);
shasum.update(row.m.field2);
return shasum.digest('hex');
}
exports.calculateHashRow = calculateHashRow;
function PKey(/*Number*/ id) {
if (id == null)
id = 0;
this.shardKey = id;
this.id = id;
}
exports.PKey = PKey;
function Row_child(/*Number*/ id) {
if (id == null)
id = 0;
this.shardKey = id;
this.id = id;
this.id_child = id;
this.s_child = 'String value';
this.l_child = new Int64('1111222233334444'); // using Int64 for big numbers
this.f_child = 9.123456; //float
this.d_child = 9.12345678901234; //double
this.bool_child = true;
this.bin_child = file64;
this.fbin_child = fbin64;
this.arrStr_child = ['X', 'Y', 'Z'];
this.e_child = 'A';
}
exports.Row_child = Row_child;
function PKey_child(/*Number*/ id) {
if (id == null)
id = 0;
this.shardKey = id;
this.id = id;
this.id_child = id;
}
exports.PKey_child = PKey_child;
function checkSetup(store, callback) {
console.log(' Verifying table for testing: ' + TABLE_NAME);
store.open(function (err) {
if (err)
callback(err);
else {
store.get(TABLE_NAME, {shardKey: 1, id: 1},
function (err) {
if (err) {
err = new Error('Testing Error, table or data not available ' +
'for this test, use `mocha -g Setup`');
callback(err);
} else {
callback();
}
}); // execute
}
}); // open
}
exports.checkSetup = checkSetup;
var TABLE_NAME = 'NODEJS_TEST';
exports.TABLE_NAME = TABLE_NAME;
exports.TABLE_NAME_CHILD = 'NODEJS_TEST.CHILD';
exports.TABLE_IDX1 = 'NODEJS_TEST_IDX1';
exports.TABLE_IDX2 = 'NODEJS_TEST_IDX2';
var TABLE_DEFINITION =
' ( shardKey INTEGER, ' +
' id INTEGER, ' +
' indexKey1 INTEGER, ' +
' indexKey2 INTEGER, ' + '' +
' s STRING, ' +
' f FLOAT, ' +
' d DOUBLE, ' +
' l LONG, ' +
' bool BOOLEAN, ' +
' arrStr ARRAY(STRING), ' +
' bin BINARY, ' +
' fbin BINARY(10), ' +
' e ENUM(A,B,C), ' +
' address RECORD (street STRING, city STRING, state STRING, ' +
' zip INTEGER), ' +
' m MAP (STRING), ' +
' primary KEY(SHARD(shardKey), id) ) ';
exports.TABLE_DEFINITION = TABLE_DEFINITION;
exports.TABLE_CHILD_DEFINITION =
' ( id_child INTEGER, ' +
' s_child STRING, ' +
' f_child FLOAT, ' +
' d_child DOUBLE, ' +
' l_child LONG, ' +
' bool_child BOOLEAN, ' +
' arrStr_child ARRAY(STRING), ' +
' bin_child BINARY, ' +
' fbin_child BINARY(10), ' +
' e_child ENUM(A,B,C), ' +
' primary KEY(id_child) ) ';
function generateRandomData() {
var buf = new Buffer(1024);
for (var offset = 0; offset < 1024; offset++) {
buf.writeUInt8(Math.floor(Math.random() * 256), offset);
}
return buf;
}
exports.generateRandomData = generateRandomData;
function generateRandomString() {
var buf = new Buffer(1024);
for (var offset = 0; offset < 1024; offset++) {
buf.writeUInt8(Math.floor(Math.random() * 30 + 40), offset);
}
return buf.toString();
}
function multiPut(/*Array*/ operations,
/*Object*/ store,
/*function*/ callback) {
var durability =
new Types.Durability(Types.SyncPolicy.NO_SYNC,
Types.ReplicaAckPolicy.SIMPLE_MAJORITY,
Types.SyncPolicy.NO_SYNC);
var writeOptions = new Types.WriteOptions(durability, 1000);
writeOptions.updateTTL = true;
var counter = 0;
function back (err, result) {
if (err)
results.push(err);
else
results.push(result);
if (++counter == TOTAL_OPS)
callback(null, results);
}
var results = [];
var TOTAL_OPS = operations.length;
for (var index in operations) {
switch (operations[index].type) {
case Types.OperationType.PUT:
//console.log(operations[index].ta);
store.put(operations[index].tableName, operations[index].row, writeOptions, back);
break;
case Types.OperationType.PUT_IF_ABSENT:
store.putIfAbsent(operations[index].tableName, operations[index].row, writeOptions, back);
break;
case Types.OperationType.PUT_IF_PRESENT:
store.putIfPresent(operations[index].tableName, operations[index].row, back);
break;
case Types.OperationType.PUT_IF_VERSION:
store.putIfVersion(operations[index].tableName, operations[index].row, back);
break;
}
} // for
}
exports.multiPut = multiPut;