@@ -33,15 +33,23 @@ exports.putter = function(db) {
3333 type = request . type ;
3434
3535 // Validate the date and type.
36- if ( ! type_re . test ( type ) ) return callback ( { error : "invalid type" } ) , - 1 ;
36+ var keys = type . split ( '.' ) ;
37+ keys . forEach ( function ( t ) {
38+ if ( ! type_re . test ( t ) ) {
39+ return callback ( { error : "invalid type" , type : type } ) , - 1 ;
40+ }
41+ } ) ;
42+ var type = keys [ 0 ] ;
43+ var key = keys . slice ( 1 ) . join ( '.' ) ;
44+
3745 if ( isNaN ( time ) ) return callback ( { error : "invalid time" } ) , - 1 ;
3846
3947 // If an id is specified, promote it to Mongo's primary key.
4048 var event = { t : time , d : request . data } ;
4149 if ( "id" in request ) event . _id = request . id ;
4250
4351 // If this is a known event type, save immediately.
44- if ( type in knownByType ) return save ( type , event ) ;
52+ if ( type in knownByType ) return save ( type , event , key ) ;
4553
4654 // If someone is already creating the event collection for this new type,
4755 // then append this event to the queue for later save.
@@ -77,7 +85,7 @@ exports.putter = function(db) {
7785 // Save any pending events to the new collection.
7886 function saveEvents ( ) {
7987 knownByType [ type ] = true ;
80- eventsToSaveByType [ type ] . forEach ( function ( event ) { save ( type , event ) ; } ) ;
88+ eventsToSaveByType [ type ] . forEach ( function ( event ) { save ( type , event , key ) ; } ) ;
8189 delete eventsToSaveByType [ type ] ;
8290 }
8391 } ) ;
@@ -91,8 +99,32 @@ exports.putter = function(db) {
9199 // delay between saving the event and invalidating the metrics reduces the
92100 // likelihood of a race condition between when the events are read by the
93101 // evaluator and when the newly-computed metrics are saved.
94- function save ( type , event ) {
95- collection ( type ) . events . save ( event , handle ) ;
102+ function save ( type , event , key ) {
103+ if ( event . _id !== undefined ) {
104+ var updater = { t : event . t } ;
105+ updater [ key !== '' ? 'd.' + key : 'd' ] = event . d ;
106+ collection ( type ) . events . update ( { _id : event . _id } , { $set : updater } , { safe : true , upsert : true } , handle ) ;
107+ } else {
108+
109+ if ( key !== '' ) {
110+ // Convert sub-keys into event.d properties
111+ var d = event . d ;
112+ delete event . d ;
113+
114+ var prev = event [ 'd' ] = { } ;
115+
116+ var keys = key . split ( '.' ) . forEach ( function ( k ) {
117+ prev = prev [ k ] = { } ;
118+ } ) ;
119+
120+ Object . keys ( d ) . forEach ( function ( p ) {
121+ prev [ p ] = d [ p ] ;
122+ } ) ;
123+ }
124+
125+ collection ( type ) . events . save ( event , handle ) ;
126+ }
127+
96128 queueInvalidation ( type , event ) ;
97129 }
98130
0 commit comments