diff --git a/lib/cube/event.js b/lib/cube/event.js index a06c6227..1c111b38 100644 --- a/lib/cube/event.js +++ b/lib/cube/event.js @@ -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", type: 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,32 @@ 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) { + if (event._id !== undefined) { + var updater = {t: event.t}; + updater[key !== '' ? 'd.' + key : 'd'] = event.d; + collection(type).events.update({_id: event._id}, {$set: updater}, {safe: true, upsert: true}, handle); + } else { + + if (key !== '') { + // Convert sub-keys into event.d properties + var d = event.d; + delete event.d; + + var prev = event['d'] = {}; + + var keys = key.split('.').forEach(function(k) { + prev = prev[ k ] = {}; + }); + + Object.keys(d).forEach(function(p) { + prev[p] = d[p]; + }); + } + + collection(type).events.save(event, handle); + } + queueInvalidation(type, event); }