RejectedSoftware Forums

Sign up

Timestamps with mongodb

Hello !

I can not find a way to use timestamps with vibe.d mongodb, I basically want to have a field that is updated with current time on every update operation and be able to find records that has been updated since a certain timestamp value.

In SQL it's something like this:

create table atable(id integer primary key, data text, mdate datetime default CURRENT_TIMESTAMP);

insert into atable(data, mdate) values('avalue', CURRENTTIMESTAMP);
update atable set data='another value', mdate=CURRENT
TIMESTAMP where id = 1;

select * from atable where mdate > '2014-12-12 00:00:00';

In vibe.d:

Mongo db = connectMongoDB(mongo_uri);
auto atable = db.getCollection("atable");
atable.insert(["data": "avalue", "mdate": ????);
atable.update(["data": "another value", "mdate": ???]);
atable.find(Bson(["mdate": ["$gt": "2014-12-12 00:00:00 ???"]]));

I want it in a generic way so I can make the "mdate" update in one place for all collections through a wrapper:

bool updateMongo(MondoDB db, string collectionname, string theid, string[string] record)
{
auto collection = db.getCollection(collectionname);
alias str
rec = string[string];
str_rec[string] rec;
rec["$set"] = record;
rec["$currentDate"] = ["mdate": { "$type": "timestamp" }]; //????????

collection.update(["id":Bson(BsonObjectID.fromString(theid))], record);
}

Thanks in advance for any help !

Re: Timestamps with mongodb

I end doing this and is working for my needs right now, cheers !

protected void postRecordToCollection(MongoClient mongodb, HTTPServerResponse res, string the_id, 
	const string collection_name, ref string[string] record, bool withTimestamp=false)
{
	auto collection = mongodb.getCollection(collection_name);
	foreach(k; record.keys)
	{
		record[k] = record[k].strip;
	}
	try
	{
		auto brec = serializeToBson(record);
		if(the_id.length > 0)
		{
			if(withTimestamp)
			{
				brec["mdate"] = BsonDate(Clock.currTime(UTC()));
			}
			auto query = Bson.emptyObject;
			query["$set"] = brec;
			/*
			if(withTimestamp)
			{
				query["$currentDate"] = BsonTimestampField;
			}
			logInfo("query: %s", query.toString);
			*/
			collection.update(["_id":Bson(BsonObjectID.fromString(the_id))], query);
		} else {
			if(withTimestamp)
			{
				auto now = BsonDate(Clock.currTime(UTC()));
				brec["mdate"] = now;
				brec["cdate"] = now;
			}
			collection.insert(brec); //actually there is no way to check if insert fails due to duplicated key or other reasons
		}
	}
	catch(Throwable e)
	{
		logInfo("Error: %s", e.msg);
	}
	if(res) {
		res.writeBody(format(q{{"ok":"The record was %s !"}}, the_id.length > 0 ? "updated" : "inserted"), "application/json");
	}
}

Re: Timestamps with mongodb

Just use std.datetime.SysTime

brec["mdate"] = Clock.currTime.serializeToBson;
...
auto timestamp = brec["mdata"].deserializeBson!SysTime;