UNPKG

mongo-portable

Version:

Portable Pure JS MongoDB - Based on Monglodb (https://github.com/euforic/monglodb.git) by Christian Sullivan (http://RogueSynaptics.com)

298 lines 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var jsw_logger_1 = require("jsw-logger"); var _ = require("lodash"); var index_1 = require("../binary/index"); /*** * Machine id. * * Create a random 3-byte value (i.e. unique for this * process). Other drivers use a md5 of the machine id here, but * that would mean an asyc call to gethostname, so we don"t bother. * * @ignore */ var MACHINE_ID = parseInt("" + Math.random() * 0xFFFFFF, 10); // Regular expression that checks for hex value var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); var isValidHexRegExp = function (str, len) { if (len === void 0) { len = 24; } if (str.length === len && checkForHexRegExp.test(str)) { return true; } return false; }; var pid = Math.floor(Math.random() * 100000); try { if (!_.isNil(process)) { pid = process.pid; } } catch (e) { // "process" does not exists -> keep the value from Math.random } /*** * ObjectId * * @module ObjectId * @since 0.0.1 * @author Eduardo Astolfi <eastolfi91@gmail.com> * @copyright 2016 Eduardo Astolfi <eastolfi91@gmail.com> * @license MIT Licensed * * @classdesc Represents the BSON ObjectId type * * @param {string|number} id - Can be a 24 byte hex string, a 12 byte binary string or a Number. */ var ObjectId = /** @class */ (function () { function ObjectId(id) { // if (!(this instanceof ObjectId)) return new ObjectId(id, _hex); this.logger = jsw_logger_1.JSWLogger.instance; this.binaryParser = new index_1.BinaryParser(); if (_.isNil(id)) { this.id = this.generate(); } else { if (_.isNumber(id)) { this.id = this.generate(id); } else { // String or Hex if (_.isString(id) && (id.length === 12 || id.length === 24)) { if (isValidHexRegExp(id)) { // Valid Hex var _id = ObjectId.createFromHexString(id); this.id = _id.id; } else if (id.length === 12) { // Valid Byte String this.id = id; } else { this.logger.throw("Value passed in is not a valid 24 character hex string"); } } else { this.logger.throw("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); } } } if (ObjectId.cacheHexString) { this.cachedId = this.toHexString(); } } /*** * Return the ObjectId id as a 24 byte hex string representation * * @method ObjectId#toHexString * * @returns {String} The 24 byte hex string representation. */ ObjectId.prototype.toHexString = function () { if (ObjectId.cacheHexString && this.cachedId) { return this.cachedId; } var hexString = ""; var num; var value; for (var index = 0, len = this.id.length; index < len; index++) { var idChar = this.id[index]; if (_.isNaN(parseInt(idChar, 10))) { idChar = "" + idChar.charCodeAt(0); } value = this.binaryParser.toByte(parseInt(idChar, 10)); num = value <= 15 ? "0" + value.toString(16) : value.toString(16); hexString = hexString + num; } if (ObjectId.cacheHexString) { this.cachedId = hexString; } return hexString; }; /*** * Alias for {@link ObjectId#toHexString} * * @method Cursor#next */ ObjectId.prototype.toString = function () { return this.toHexString(); }; /*** * Alias for {@link ObjectId#toHexString} * * @method Cursor#next */ ObjectId.prototype.toJSON = function () { return this.toHexString(); }; /*** * Update the ObjectId index used in generating new ObjectId"s on the driver * * @method ObjectId#get_inc * @private * * @returns {Number} Next index value. */ ObjectId.prototype.getInc = function () { return ObjectId.index = (ObjectId.index + 1) % 0xFFFFFF; }; ObjectId.prototype.returnHash = function (length) { var abc = "abcdefghijklmnopqrstuvwxyz1234567890".split(""); var token = ""; for (var i = 0; i < length; i++) { token += abc[Math.floor(Math.random() * abc.length)]; } return token; // Will return a 32 bit "hash" }; /*** * Generate a 12 byte id string used in ObjectId"s * * @method ObjectId#generate * @private * * @param {Number} [time] - Second based timestamp to the generation. * * @return {String} The 12 byte id binary string. */ ObjectId.prototype.generate = function (time) { // If is a number string, parse it if (!_.isNil(time) && _.isString(time) && !_.isNaN(parseInt(time, 10))) { time = _.toNumber(time); } // If its still a non-number, take a new timestamp if (_.isNil(time) || !_.isNumber(time)) { // let now = _.toString(Date.now()); // let first = now.substr(0, now.length / 2); // let second = now.substr(now.length / 2, now.length); // time = parseInt(first, 10) + parseInt(second, 10); // time = parseInt(`${second}${time}`, 10); // time = time / 1000; // time = Date.now() / 1000; return this.binaryParser.generate12string(); } else { /* for time-based ObjectId the bytes following the time will be zeroed */ var time4Bytes = this.binaryParser.encodeInt(time, 32, true, true); var machine3Bytes = this.binaryParser.encodeInt(MACHINE_ID, 24, false); var pid2Bytes = this.binaryParser.fromShort(pid); var index3Bytes = this.binaryParser.encodeInt(this.getInc(), 24, false, true); return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; } // // If is a number string, parse it // if (!_.isNil(time) && _.isString(time) && !_.isNaN(parseInt(<string>time))) { // time = <number>_.toNumber(time); // } // // If its still a non-number, take a new timestamp // if (_.isNil(time) || !_.isNumber(time)) { // let now = _.toString(Date.now()); // let first = now.substr(0, now.length / 2); // let second = now.substr(now.length / 2, now.length); // time = parseInt(first, 10) + parseInt(second, 10); // time = parseInt(`${second}${time}`, 10); // time = time / 1000; // // time = Date.now() / 1000; // } // /* for time-based ObjectId the bytes following the time will be zeroed */ // var time4Bytes = this.binaryParser.encodeInt(<number>time, 32, true, true); // // let time4Bytes = this.returnHash(4); // var machine3Bytes = this.binaryParser.encodeInt(MACHINE_ID, 24, false); // var pid2Bytes = this.binaryParser.fromShort(pid); // var index3Bytes = this.binaryParser.encodeInt(this.getInc(), 24, false, true); // return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; }; /*** * Compares the equality of this ObjectId with [otherID]. * * @method ObjectId#equals * * @param {Object} otherID - ObjectId instance to compare against. * * @returns {Boolean} The result of comparing two ObjectId"s */ ObjectId.prototype.equals = function (otherID) { var id = (otherID instanceof ObjectId || otherID.toHexString) ? otherID.id : ObjectId.createFromHexString(otherID).id; return this.id === id; }; /*** * Returns the generation time in seconds that this ID was generated. * * @method ObjectId#getTimestamp * * @returns {Number} Number of seconds in the timestamp part of the 12 byte id. */ ObjectId.prototype.getTimestamp = function () { var timestamp = new Date(); timestamp.setTime(Math.floor(this.binaryParser.decodeInt(this.id.substring(0, 4), 32, true, true)) * 1000); return timestamp; }; Object.defineProperty(ObjectId.prototype, "generationTime", { /* GETTER - SETTER */ get: function () { return Math.floor(this.binaryParser.decodeInt(this.id.substring(0, 4), 32, true, true)); }, set: function (value) { value = this.binaryParser.encodeInt(value, 32, true, true); this.id = value + this.id.substr(4); // delete this.cachedId; this.toHexString(); }, enumerable: true, configurable: true }); /* STATIC METHODS */ /*** * Creates an ObjectId from a hex string representation of an ObjectId. * * @method ObjectId#createFromHexString * * @param {String} hexString - An ObjectId 24 byte hexstring representation. * * @returns {ObjectId} The created ObjectId */ ObjectId.createFromHexString = function (hexString) { // Throw an error if it"s not a valid setup if (_.isNil(hexString) || hexString.length !== 24) { throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); } var len = hexString.length; var result = ""; var str; var num; for (var index = 0; index < len; index += 2) { str = hexString.substr(index, 2); num = parseInt(str, 16); result += new index_1.BinaryParser().fromByte(num); } return new ObjectId(result); }; /*** * Creates an ObjectId from a second based number, with the rest of the ObjectId zeroed out. * Used for comparisons or sorting the ObjectId. * * @method ObjectId#createFromTime * * @param {Number} time - A number of seconds. * * @returns {ObjectId} The created ObjectId */ ObjectId.createFromTime = function (time) { var binaryParser = new index_1.BinaryParser(); var id = binaryParser.encodeInt(time, 32, true, true) + binaryParser.encodeInt(0, 64, true, true); return new ObjectId(id); }; /*** * Creates an ObjectId from a second based number, with the rest of the ObjectId zeroed out. Used for comparisons or sorting the ObjectId. * * @method ObjectId#createPk * * @param {Number} time an integer number representing a number of seconds. * @return {ObjectId} return the created ObjectId */ ObjectId.createPk = function () { return new ObjectId(); }; ObjectId.index = 0; return ObjectId; }()); exports.ObjectId = ObjectId; //# sourceMappingURL=ObjectId.js.map