123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /**
- * Module dependencies.
- * @ignore
- */
- var BinaryParser = require('./binary_parser').BinaryParser;
- /**
- * 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}$");
- /**
- * Create a new ObjectID instance
- *
- * @class
- * @param {(string|number)} id Can be a 24 byte hex string, 12 byte binary string or a Number.
- * @property {number} generationTime The generation time of this ObjectId instance
- * @return {ObjectID} instance of ObjectID.
- */
- var ObjectID = function ObjectID(id) {
- if(!(this instanceof ObjectID)) return new ObjectID(id);
- if((id instanceof ObjectID)) return id;
- this._bsontype = 'ObjectID';
- var __id = null;
- var valid = ObjectID.isValid(id);
- // Throw an error if it's not a valid setup
- if(!valid && id != null){
- throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters");
- } else if(valid && typeof id == 'string' && id.length == 24) {
- return ObjectID.createFromHexString(id);
- } else if(id == null || typeof id == 'number') {
- // convert to 12 byte binary string
- this.id = this.generate(id);
- } else if(id != null && id.length === 12) {
- // assume 12 byte string
- this.id = id;
- }
- if(ObjectID.cacheHexString) this.__id = this.toHexString();
- };
- // Allow usage of ObjectId as well as ObjectID
- var ObjectId = ObjectID;
- // Precomputed hex table enables speedy hex string conversion
- var hexTable = [];
- for (var i = 0; i < 256; i++) {
- hexTable[i] = (i <= 15 ? '0' : '') + i.toString(16);
- }
- /**
- * Return the ObjectID id as a 24 byte hex string representation
- *
- * @method
- * @return {string} return the 24 byte hex string representation.
- */
- ObjectID.prototype.toHexString = function() {
- if(ObjectID.cacheHexString && this.__id) return this.__id;
- var hexString = '';
- for (var i = 0; i < this.id.length; i++) {
- hexString += hexTable[this.id.charCodeAt(i)];
- }
- if(ObjectID.cacheHexString) this.__id = hexString;
- return hexString;
- };
- /**
- * Update the ObjectID index used in generating new ObjectID's on the driver
- *
- * @method
- * @return {number} returns next index value.
- * @ignore
- */
- ObjectID.prototype.get_inc = function() {
- return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF;
- };
- /**
- * Update the ObjectID index used in generating new ObjectID's on the driver
- *
- * @method
- * @return {number} returns next index value.
- * @ignore
- */
- ObjectID.prototype.getInc = function() {
- return this.get_inc();
- };
- /**
- * Generate a 12 byte id string used in ObjectID's
- *
- * @method
- * @param {number} [time] optional parameter allowing to pass in a second based timestamp.
- * @return {string} return the 12 byte id binary string.
- */
- ObjectID.prototype.generate = function(time) {
- if ('number' != typeof time) {
- time = parseInt(Date.now()/1000,10);
- }
-
- var time4Bytes = BinaryParser.encodeInt(time, 32, true, true);
- /* for time-based ObjectID the bytes following the time will be zeroed */
- var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false);
- var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid % 0xFFFF);
- var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true);
- return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes;
- };
- /**
- * Converts the id into a 24 byte hex string for printing
- *
- * @return {String} return the 24 byte hex string representation.
- * @ignore
- */
- ObjectID.prototype.toString = function() {
- return this.toHexString();
- };
- /**
- * Converts to a string representation of this Id.
- *
- * @return {String} return the 24 byte hex string representation.
- * @ignore
- */
- ObjectID.prototype.inspect = ObjectID.prototype.toString;
- /**
- * Converts to its JSON representation.
- *
- * @return {String} return the 24 byte hex string representation.
- * @ignore
- */
- ObjectID.prototype.toJSON = function() {
- return this.toHexString();
- };
- /**
- * Compares the equality of this ObjectID with `otherID`.
- *
- * @method
- * @param {object} otherID ObjectID instance to compare against.
- * @return {boolean} the result of comparing two ObjectID's
- */
- ObjectID.prototype.equals = function equals (otherID) {
- if(otherID == null) return false;
- var id = (otherID instanceof ObjectID || otherID.toHexString)
- ? otherID.id
- : ObjectID.createFromHexString(otherID).id;
- return this.id === id;
- }
- /**
- * Returns the generation date (accurate up to the second) that this ID was generated.
- *
- * @method
- * @return {date} the generation date
- */
- ObjectID.prototype.getTimestamp = function() {
- var timestamp = new Date();
- timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000);
- return timestamp;
- }
- /**
- * @ignore
- */
- ObjectID.index = parseInt(Math.random() * 0xFFFFFF, 10);
- /**
- * @ignore
- */
- ObjectID.createPk = function createPk () {
- return new ObjectID();
- };
- /**
- * Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID.
- *
- * @method
- * @param {number} time an integer number representing a number of seconds.
- * @return {ObjectID} return the created ObjectID
- */
- ObjectID.createFromTime = function createFromTime (time) {
- var id = BinaryParser.encodeInt(time, 32, true, true) +
- BinaryParser.encodeInt(0, 64, true, true);
- return new ObjectID(id);
- };
- /**
- * Creates an ObjectID from a hex string representation of an ObjectID.
- *
- * @method
- * @param {string} hexString create a ObjectID from a passed in 24 byte hexstring.
- * @return {ObjectID} return the created ObjectID
- */
- ObjectID.createFromHexString = function createFromHexString (hexString) {
- // Throw an error if it's not a valid setup
- if(typeof hexString === 'undefined' || hexString != null && 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;
- if(len > 12*2) {
- throw new Error('Id cannot be longer than 12 bytes');
- }
- var result = ''
- , string
- , number;
- for (var index = 0; index < len; index += 2) {
- string = hexString.substr(index, 2);
- number = parseInt(string, 16);
- result += BinaryParser.fromByte(number);
- }
- return new ObjectID(result, hexString);
- };
- /**
- * Checks if a value is a valid bson ObjectId
- *
- * @method
- * @return {boolean} return true if the value is a valid bson ObjectId, return false otherwise.
- */
- ObjectID.isValid = function isValid(id) {
- if(id == null) return false;
- if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) {
- return false;
- } else {
- // Check specifically for hex correctness
- if(typeof id == 'string' && id.length == 24) return checkForHexRegExp.test(id);
- return true;
- }
- };
- /**
- * @ignore
- */
- Object.defineProperty(ObjectID.prototype, "generationTime", {
- enumerable: true
- , get: function () {
- return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true));
- }
- , set: function (value) {
- var value = BinaryParser.encodeInt(value, 32, true, true);
- this.id = value + this.id.substr(4);
- // delete this.__id;
- this.toHexString();
- }
- });
- /**
- * Expose.
- */
- module.exports = ObjectID;
- module.exports.ObjectID = ObjectID;
- module.exports.ObjectId = ObjectID;
|