@@ -33,15 +33,23 @@ exports.putter = function(db) {
33
33
type = request . type ;
34
34
35
35
// 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
+
37
45
if ( isNaN ( time ) ) return callback ( { error : "invalid time" } ) , - 1 ;
38
46
39
47
// If an id is specified, promote it to Mongo's primary key.
40
48
var event = { t : time , d : request . data } ;
41
49
if ( "id" in request ) event . _id = request . id ;
42
50
43
51
// 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 ) ;
45
53
46
54
// If someone is already creating the event collection for this new type,
47
55
// then append this event to the queue for later save.
@@ -77,7 +85,7 @@ exports.putter = function(db) {
77
85
// Save any pending events to the new collection.
78
86
function saveEvents ( ) {
79
87
knownByType [ type ] = true ;
80
- eventsToSaveByType [ type ] . forEach ( function ( event ) { save ( type , event ) ; } ) ;
88
+ eventsToSaveByType [ type ] . forEach ( function ( event ) { save ( type , event , key ) ; } ) ;
81
89
delete eventsToSaveByType [ type ] ;
82
90
}
83
91
} ) ;
@@ -91,8 +99,32 @@ exports.putter = function(db) {
91
99
// delay between saving the event and invalidating the metrics reduces the
92
100
// likelihood of a race condition between when the events are read by the
93
101
// 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
+
96
128
queueInvalidation ( type , event ) ;
97
129
}
98
130
0 commit comments