Skip to content

Commit

Permalink
Merge pull request #759 from MartinNowak/generateTimeStamp
Browse files Browse the repository at this point in the history
Allow to generate a unique BsonObjectID with a specified timestamp.
  • Loading branch information
s-ludwig committed Jul 31, 2014
2 parents dcc09b0 + d361c5c commit fbb2b38
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions source/vibe/data/bson.d
Original file line number Diff line number Diff line change
Expand Up @@ -693,19 +693,22 @@ struct BsonObjectID {
alias fromString fromHexString;

/** Generates a unique object ID.
*
* By default it will use the Clock.currTime(UTC()) as timestamp
* which guarantees that BsonObjectIDs are chronologically
* sorted.
*/
static BsonObjectID generate()
static BsonObjectID generate(in SysTime time = Clock.currTime(UTC()))
{
import std.datetime;
import std.process;
import std.random;

if( ms_pid == -1 ) ms_pid = getpid();
if( MACHINE_ID == 0 ) MACHINE_ID = uniform(0, 0xffffff);
auto unixTime = Clock.currTime(UTC()).toUnixTime();

BsonObjectID ret = void;
ret.m_bytes[0 .. 4] = toBigEndianData(cast(uint)unixTime)[];
ret.m_bytes[0 .. 4] = toBigEndianData(cast(uint)time.toUnixTime())[];
ret.m_bytes[4 .. 7] = toBsonData(MACHINE_ID)[0 .. 3];
ret.m_bytes[7 .. 9] = toBsonData(cast(ushort)ms_pid)[];
ret.m_bytes[9 .. 12] = toBigEndianData(ms_inc++)[1 .. 4];
Expand All @@ -720,10 +723,10 @@ struct BsonObjectID {
this date part is only 32-bit wide and is limited to the same timespan as a
32-bit Unix timestamp.
*/
static BsonObjectID createDateID(in SysTime date)
static BsonObjectID createDateID(in SysTime time)
{
BsonObjectID ret;
ret.m_bytes[0 .. 4] = toBigEndianData(cast(uint)date.toUnixTime())[];
ret.m_bytes[0 .. 4] = toBigEndianData(cast(uint)time.toUnixTime())[];
return ret;
}

Expand Down Expand Up @@ -772,6 +775,23 @@ struct BsonObjectID {
}
}

unittest {
auto t0 = SysTime(Clock.currTime(UTC()).toUnixTime.unixTimeToStdTime);
auto id = BsonObjectID.generate();
auto t1 = SysTime(Clock.currTime(UTC()).toUnixTime.unixTimeToStdTime);
assert(t0 <= id.timeStamp);
assert(id.timeStamp <= t1);

id = BsonObjectID.generate(t0);
assert(id.timeStamp == t0);

id = BsonObjectID.generate(t1);
assert(id.timeStamp == t1);

immutable dt = DateTime(2014, 07, 31, 19, 14, 55);
id = BsonObjectID.generate(SysTime(dt, UTC()));
assert(id.timeStamp == SysTime(dt, UTC()));
}

/**
Represents a BSON date value (Bson.Type.date).
Expand Down Expand Up @@ -1338,7 +1358,7 @@ struct BsonSerializer {

// auto ref does't work for DMD 2.064
void writeValue(T)(/*auto ref const*/ in T value) { writeValueH!(T, true)(value); }

private void writeValueH(T, bool write_header)(/*auto ref const*/ in T value)
{
static if (write_header) writeCompositeEntryHeader(getBsonTypeID(value));
Expand Down Expand Up @@ -1603,4 +1623,4 @@ pure {
}

/// private
package template isBsonSerializable(T) { enum isBsonSerializable = is(typeof(T.init.toBson()) == Bson) && is(typeof(T.fromBson(Bson())) == T); }
package template isBsonSerializable(T) { enum isBsonSerializable = is(typeof(T.init.toBson()) == Bson) && is(typeof(T.fromBson(Bson())) == T); }

0 comments on commit fbb2b38

Please sign in to comment.