Further fixes related to the previous commit
This commit is contained in:
1 parent
ec1360217b
commit
9dd6980da2
1 file changed
+62
-36
+62
-36
@@ -142,15 +142,17 @@ fetchDevice = (id, timestamp, patterns, callback) ->
|
|||||||
children = {}
|
children = {}
|
||||||
for pat in pats
|
for pat in pats
|
||||||
fragment = pat[0][path.length] or '*'
|
fragment = pat[0][path.length] or '*'
|
||||||
load = 0
|
|
||||||
if fragment == '*'
|
if fragment == '*'
|
||||||
projection[path.join('.')] = 1
|
projection[path.join('.')] = 1 if pat[1] << path.length
|
||||||
return
|
return
|
||||||
|
|
||||||
projTree[fragment] ?= {}
|
projTree[fragment] ?= {}
|
||||||
|
|
||||||
if pat[1] & (1 << path.length)
|
if pat[1] & (1 << path.length)
|
||||||
projection[path.concat('_timestamp').join('.')] = 1
|
projection[path.concat('_timestamp').join('.')] = 1
|
||||||
|
projection[path.concat('_object').join('.')] = 1
|
||||||
|
projection[path.concat('_instance').join('.')] = 1
|
||||||
projection[path.concat([fragment, '_timestamp']).join('.')] = 1
|
projection[path.concat([fragment, '_timestamp']).join('.')] = 1
|
||||||
projection[path.concat([fragment, '_value']).join('.')] = 1
|
projection[path.concat([fragment, '_value']).join('.')] = 1
|
||||||
projection[path.concat([fragment, '_type']).join('.')] = 1
|
projection[path.concat([fragment, '_type']).join('.')] = 1
|
||||||
@@ -189,18 +191,20 @@ fetchDevice = (id, timestamp, patterns, callback) ->
|
|||||||
projection['_lastBootstrap'] = 1
|
projection['_lastBootstrap'] = 1
|
||||||
projection['_registered'] = 1
|
projection['_registered'] = 1
|
||||||
loaded.push([['Events'], ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Events'], ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'Events.Inform._writable' or k == 'Events.Inform'
|
else if k == 'Events.Inform._writable' or k == 'Events.Inform'
|
||||||
projection['_lastInform'] = 1
|
projection['_lastInform'] = 1
|
||||||
loaded.push([['Events', 'Inform'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Events', 'Inform'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'Events.1_BOOT._writable' or k == 'Events.1_BOOT'
|
else if k == 'Events.1_BOOT._writable' or k == 'Events.1_BOOT'
|
||||||
projection['_lastBoot'] = 1
|
projection['_lastBoot'] = 1
|
||||||
loaded.push([['Events', '1_BOOT'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Events', '1_BOOT'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'Events.0_BOOTSTRAP._writable' or k == 'Events.0_BOOTSTRAP'
|
else if k == 'Events.0_BOOTSTRAP._writable' or k == 'Events.0_BOOTSTRAP'
|
||||||
projection['_lastBootstrap'] = 1
|
projection['_lastBootstrap'] = 1
|
||||||
loaded.push([['Events', '0_BOOTSTRAP'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Events', '0_BOOTSTRAP'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'Events.Registered._writable' or k == 'Events.Registered'
|
else if k == 'Events.Registered._writable' or k == 'Events.Registered'
|
||||||
projection['_registered'] = 1
|
projection['_registered'] = 1
|
||||||
loaded.push([['Events', 'Registered'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Events', 'Registered'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
|
else if k.endsWith('._writable') and k != 'Events._writable'
|
||||||
|
loaded.push([k.split('.').slice(0, 2), 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
delete projection[k] if k != ''
|
delete projection[k] if k != ''
|
||||||
|
|
||||||
if k == '' or k == 'DeviceID' or k.startsWith('DeviceID.')
|
if k == '' or k == 'DeviceID' or k.startsWith('DeviceID.')
|
||||||
@@ -212,30 +216,37 @@ fetchDevice = (id, timestamp, patterns, callback) ->
|
|||||||
projection['_id'] = 1
|
projection['_id'] = 1
|
||||||
projection['_deviceId'] = 1
|
projection['_deviceId'] = 1
|
||||||
loaded.push([['DeviceID'], ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID'], ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'DeviceID.ID._writable' or k == 'DeviceID.ID'
|
else if k == 'DeviceID.ID._writable' or k == 'DeviceID.ID'
|
||||||
projection['_id'] = 1
|
projection['_id'] = 1
|
||||||
loaded.push([['DeviceID', 'ID'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID', 'ID'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'DeviceID.Manufacturer._writable' or k == 'DeviceID.DeManufacturer'
|
else if k == 'DeviceID.Manufacturer._writable' or k == 'DeviceID.DeManufacturer'
|
||||||
projection['_deviceId._Manufacturer'] = 1
|
projection['_deviceId._Manufacturer'] = 1
|
||||||
loaded.push([['DeviceID', 'Manufacturer'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID', 'Manufacturer'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'DeviceID.ProductClass._writable' or k == 'DeviceID.ProductClass'
|
else if k == 'DeviceID.ProductClass._writable' or k == 'DeviceID.ProductClass'
|
||||||
projection['_deviceId._ProductClass'] = 1
|
projection['_deviceId._ProductClass'] = 1
|
||||||
loaded.push([['DeviceID', 'ProductClass'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID', 'ProductClass'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'DeviceID.OUI._writable' or k == 'DeviceID.OUI'
|
else if k == 'DeviceID.OUI._writable' or k == 'DeviceID.OUI'
|
||||||
projection['_deviceId._OUI'] = 1
|
projection['_deviceId._OUI'] = 1
|
||||||
loaded.push([['DeviceID', 'ProductClass'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID', 'ProductClass'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
if k == 'DeviceID.SerialNumber._writable' or k == 'DeviceID.SerialNumber'
|
else if k == 'DeviceID.SerialNumber._writable' or k == 'DeviceID.SerialNumber'
|
||||||
projection['_deviceId._SerialNumber'] = 1
|
projection['_deviceId._SerialNumber'] = 1
|
||||||
loaded.push([['DeviceID', 'SerialNumber'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['DeviceID', 'SerialNumber'], 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
|
else if k.endsWith('._writable') and k != 'DeviceID._writable'
|
||||||
|
loaded.push([k.split('.').slice(0, 2), 1 ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
delete projection[k] if k != ''
|
delete projection[k] if k != ''
|
||||||
|
|
||||||
if k == 'Tags' or k.startsWith('Tags.')
|
if k == 'Tags' or k.startsWith('Tags.')
|
||||||
if not projection['_tags']
|
if not projection['_tags']
|
||||||
projection['_tags'] = 1
|
projection['_tags'] = 1
|
||||||
loaded.push([['Tags'], ((1 << MAX_DEPTH) - 1)])
|
loaded.push([['Tags'], ((1 << MAX_DEPTH) - 1)])
|
||||||
delete projection[k] if k != ''
|
delete projection[k]
|
||||||
|
|
||||||
proj = if projection[''] then {} else projection
|
if projection['']
|
||||||
|
proj = {}
|
||||||
|
else if Object.keys(projection).length == 0
|
||||||
|
proj = {'_id': 1}
|
||||||
|
else
|
||||||
|
proj = projection
|
||||||
|
|
||||||
devicesCollection.findOne({'_id' : id}, proj, (err, device) ->
|
devicesCollection.findOne({'_id' : id}, proj, (err, device) ->
|
||||||
return callback(err) if err or not device?
|
return callback(err) if err or not device?
|
||||||
@@ -246,18 +257,27 @@ fetchDevice = (id, timestamp, patterns, callback) ->
|
|||||||
else
|
else
|
||||||
if projection[path.join('.')]
|
if projection[path.join('.')]
|
||||||
descendantsFetched = true
|
descendantsFetched = true
|
||||||
loaded.push([path, ((1 << path.length) - 1) ^ ((1 << MAX_DEPTH) - 1)])
|
if path.length and projection[path.slice(0, -1).concat("_timestamp").join('.')]
|
||||||
if projection[path.concat('_writable').join('.')]
|
thisFetched = true
|
||||||
|
loaded.push([path, ((1 << (path.length - 1)) - 1) ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
|
else
|
||||||
|
loaded.push([path, ((1 << path.length) - 1) ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
|
else if projection[path.concat('_writable').join('.')]
|
||||||
loaded.push([path, 1 << (path.length - 1)])
|
loaded.push([path, 1 << (path.length - 1)])
|
||||||
thisFetched = true
|
thisFetched = true
|
||||||
|
|
||||||
if obj['_timestamp']?
|
if obj['_timestamp']?
|
||||||
obj['_timestamp'] = +obj['_timestamp']
|
obj['_timestamp'] = +obj['_timestamp']
|
||||||
|
|
||||||
|
# For compatibility with v1.0 database
|
||||||
|
if obj['_instance'] and not obj['_object']?
|
||||||
|
obj['_object'] = true
|
||||||
|
|
||||||
if thisFetched
|
if thisFetched
|
||||||
attrs = {}
|
attrs = {}
|
||||||
|
|
||||||
t = if obj['_timestamp'] > timestamp then obj['_timestamp'] else timestamp
|
t = obj['_timestamp'] or 1
|
||||||
|
t = timestamp if timestamp > t
|
||||||
|
|
||||||
if obj['_value']?
|
if obj['_value']?
|
||||||
attrs.value = [obj['_timestamp'] or 1, [obj['_value'], obj['_type']]]
|
attrs.value = [obj['_timestamp'] or 1, [obj['_value'], obj['_type']]]
|
||||||
@@ -265,28 +285,28 @@ fetchDevice = (id, timestamp, patterns, callback) ->
|
|||||||
obj['_object'] = false
|
obj['_object'] = false
|
||||||
|
|
||||||
if obj['_writable']?
|
if obj['_writable']?
|
||||||
attrs.writable = [timestamp, if obj['_writable'] then 1 else 0]
|
attrs.writable = [timestamp or 1, if obj['_writable'] then 1 else 0]
|
||||||
|
|
||||||
if obj['_object']? or obj['_instance']?
|
if obj['_object']?
|
||||||
attrs.object = [t, if (obj['_object'] or obj['_instance']) then 1 else 0]
|
attrs.object = [t, if obj['_object'] then 1 else 0]
|
||||||
|
|
||||||
res.push([path, t, attrs])
|
res.push([path, t, attrs])
|
||||||
|
|
||||||
for k, v of obj
|
for k, v of obj
|
||||||
if k[0] != '_'
|
if not k.startsWith('_')
|
||||||
kk = k
|
kk = k
|
||||||
obj['_object'] = true
|
obj['_object'] = true
|
||||||
storeParams(v, path.concat(k), obj['_timestamp'] or 1, descendantsFetched, projTree?[k])
|
storeParams(v, path.concat(k), obj['_timestamp'], descendantsFetched, projTree?[k])
|
||||||
delete projTree[kk] if projTree
|
delete projTree[kk] if projTree
|
||||||
|
|
||||||
if obj['_timestamp']
|
if not descendantsFetched
|
||||||
if descendantsFetched
|
for k, v of projTree
|
||||||
res.push([path.concat('*'), obj['_timestamp']])
|
p = path.concat(k)
|
||||||
else
|
loaded.push([p, ((1 << path.length) - 1) ^ ((1 << MAX_DEPTH) - 1)])
|
||||||
for k, v of projTree
|
if (obj['_object'] or path.length == 0) and obj['_timestamp']
|
||||||
p = path.concat(k)
|
|
||||||
res.push([p, obj['_timestamp']])
|
res.push([p, obj['_timestamp']])
|
||||||
loaded.push([p, ((1 << path.length) - 1) ^ ((1 << MAX_DEPTH) - 1)])
|
else if (obj['_object'] or path.length == 0) and obj['_timestamp']
|
||||||
|
res.push([path.concat('*'), obj['_timestamp']])
|
||||||
|
|
||||||
for k, v of device
|
for k, v of device
|
||||||
switch k
|
switch k
|
||||||
@@ -413,17 +433,17 @@ saveDevice = (deviceId, deviceData, isNew, callback) ->
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for attrName of diff[2]
|
for attrName of diff[2]
|
||||||
if diff[2][attrName][1]? or diff[1]?[attrName]?[1]?
|
if diff[2][attrName][1]?
|
||||||
switch attrName
|
switch attrName
|
||||||
when 'value'
|
when 'value'
|
||||||
if not diff[1] or diff[2].value[1][0] != diff[1].value?[1][0]
|
if diff[2].value[1][0] != diff[1]?.value?[1]?[0]
|
||||||
if diff[2].value[1][1] == 'xsd:dateTime' and Number.isInteger(diff[2].value[1][0])
|
if diff[2].value[1][1] == 'xsd:dateTime' and Number.isInteger(diff[2].value[1][0])
|
||||||
update['$set'][path.concat('_value').join('.')] = new Date(diff[2].value[1][0])
|
update['$set'][path.concat('_value').join('.')] = new Date(diff[2].value[1][0])
|
||||||
else
|
else
|
||||||
update['$set'][path.concat('_value').join('.')] = diff[2].value[1][0]
|
update['$set'][path.concat('_value').join('.')] = diff[2].value[1][0]
|
||||||
if not diff[1] or diff[2].value[1][1] != diff[1].value?[1][1]
|
if diff[2].value[1][1] != diff[1]?.value?[1]?[1]
|
||||||
update['$set'][path.concat('_type').join('.')] = diff[2].value[1][1]
|
update['$set'][path.concat('_type').join('.')] = diff[2].value[1][1]
|
||||||
if not diff[1] or diff[2].value[0] != diff[1].value?[0]
|
if diff[2].value[0] != diff[1]?.value?[0]
|
||||||
update['$set'][path.concat('_timestamp').join('.')] = new Date(diff[2].value[0])
|
update['$set'][path.concat('_timestamp').join('.')] = new Date(diff[2].value[0])
|
||||||
when 'object'
|
when 'object'
|
||||||
if not diff[1]?.object or diff[2].object[1] != diff[1].object?[1]
|
if not diff[1]?.object or diff[2].object[1] != diff[1].object?[1]
|
||||||
@@ -434,12 +454,21 @@ saveDevice = (deviceId, deviceData, isNew, callback) ->
|
|||||||
|
|
||||||
if diff[1]
|
if diff[1]
|
||||||
for attrName of diff[1]
|
for attrName of diff[1]
|
||||||
if attrName not of diff[2]
|
if diff[1][attrName][1]? and not diff[2]?[attrName]?[1]?
|
||||||
update['$unset'][path.concat("_#{attrName}").join('.')] = 1
|
update['$unset'][path.concat("_#{attrName}").join('.')] = 1
|
||||||
if attrName is 'value'
|
if attrName is 'value'
|
||||||
update['$unset'][path.concat('_type').join('.')] = 1
|
update['$unset'][path.concat('_type').join('.')] = 1
|
||||||
update['$unset'][path.concat('_timestamp').join('.')] = 1
|
update['$unset'][path.concat('_timestamp').join('.')] = 1
|
||||||
|
|
||||||
|
update['$unset'] = optimizeProjection(update['$unset'])
|
||||||
|
|
||||||
|
# Remove overlap possibly caused by parameters changing from objects
|
||||||
|
# to regular parameters or vice versa. Reason being that _timestamp
|
||||||
|
# represents two different things depending on whether the parameter
|
||||||
|
# is an object or not.
|
||||||
|
for k of update['$unset']
|
||||||
|
delete update['$unset'][k] if update['$set'][k]?
|
||||||
|
|
||||||
# Remove empty keys
|
# Remove empty keys
|
||||||
for k of update
|
for k of update
|
||||||
if k == '$addToSet'
|
if k == '$addToSet'
|
||||||
@@ -452,9 +481,6 @@ saveDevice = (deviceId, deviceData, isNew, callback) ->
|
|||||||
|
|
||||||
return callback() if Object.keys(update).length == 0
|
return callback() if Object.keys(update).length == 0
|
||||||
|
|
||||||
if (update['$unset']?)
|
|
||||||
update['$unset'] = optimizeProjection(update['$unset'])
|
|
||||||
|
|
||||||
if update['$addToSet'] and update['$pull']
|
if update['$addToSet'] and update['$pull']
|
||||||
# Mongo doesn't allow $addToSet and $pull at the same time
|
# Mongo doesn't allow $addToSet and $pull at the same time
|
||||||
update2 = {'$pull': update['$pull']}
|
update2 = {'$pull': update['$pull']}
|
||||||
|
|||||||
Reference in new issue
Block a user