diff --git a/lib/cube/event.js b/lib/cube/event.js index 4825904e..730b76f4 100644 --- a/lib/cube/event.js +++ b/lib/cube/event.js @@ -8,7 +8,7 @@ var mongodb = require("mongodb"), bisect = require("./bisect"), ObjectID = mongodb.ObjectID; -var type_re = /^[a-z][a-zA-Z0-9_]+$/, +var type_re = /^[a-z]?[a-zA-Z0-9_]+$/, invalidate = {$set: {i: true}}, multi = {multi: true}, metric_options = {capped: true, size: 1e7, autoIndexId: true}; @@ -33,7 +33,15 @@ exports.putter = function(db) { type = request.type; // Validate the date and type. - if (!type_re.test(type)) return callback({error: "invalid type"}), -1; + var keys = type.split('.'); + keys.forEach(function(t) { + if (!type_re.test(t)) { + return callback({error: "invalid type"}), -1; + } + }); + var type = keys[0]; + var key = keys.slice(1).join('.'); + if (isNaN(time)) return callback({error: "invalid time"}), -1; // If an id is specified, promote it to Mongo's primary key. @@ -41,7 +49,7 @@ exports.putter = function(db) { if ("id" in request) event._id = request.id; // If this is a known event type, save immediately. - if (type in knownByType) return save(type, event); + if (type in knownByType) return save(type, event, key); // If someone is already creating the event collection for this new type, // then append this event to the queue for later save. @@ -77,7 +85,7 @@ exports.putter = function(db) { // Save any pending events to the new collection. function saveEvents() { knownByType[type] = true; - eventsToSaveByType[type].forEach(function(event) { save(type, event); }); + eventsToSaveByType[type].forEach(function(event) { save(type, event, key); }); delete eventsToSaveByType[type]; } }); @@ -91,8 +99,11 @@ exports.putter = function(db) { // delay between saving the event and invalidating the metrics reduces the // likelihood of a race condition between when the events are read by the // evaluator and when the newly-computed metrics are saved. - function save(type, event) { - collection(type).events.save(event, handle); + function save(type, event, key) { + var updater = {t: event.t}; + updater[key !== '' ? 'd.' + key : 'd'] = event.d; + updater = {$set: updater} + collection(type).events.update({_id: event._id}, updater, {safe: true, upsert: true}, handle); queueInvalidation(type, event); }