I’m working on a project which will post periodic XML updates for users. I’m attempting to suppress information which hasn’t changed since the last update.
Within node.js, I have assembled a user object which will be used to generate the XML:
users =
# actual application has 25 properties per user
[
{
USERID: 150927,
EMAIL: 'irving.block@email.net',
FIRSTNAME: 'Irving',
LASTNAME: 'Block',
COLOR: 'Green'
},
{
USERID: 1246007,
EMAIL: 'allen.adler@email.net',
FIRSTNAME: 'Adler',
LASTNAME: 'Allen',
COLOR: 'Blue'
},
{
CLKEY: 1248350,
EMAIL: 'walter.pidgeon@email.net',
FIRSTNAME: 'Walter',
LASTNAME: 'Pidgeon',
COLOR: 'Red'
}
]
I also have an object loaded which helps map user data to the eventual XML fields:
xml_map =
[
{
ID: 1,
ELEMENT: 'xml_map_assigned_id',
MAPPPED: 'USERID'
},
{
ID: 2,
ELEMENT: 'xml_map_email_address',
MAPPPED: 'EMAIL'
},
{
ID: 3,
ELEMENT: 'xml_map_user_firstname',
MAPPPED: 'FIRSTNAME'
},
{
ID: 4,
ELEMENT: 'xml_map_user_lastname',
MAPPPED: 'LASTNAME'
},
{
ID: 5,
ELEMENT: 'xml_map_user_color',
MAPPED: 'COLOR'
}
]
Using these objects, I need to compare with the last update, and remove matching properties (since I only want to post updates for data that has changed). Here’s an example of what the last update (stored in the DB) might look like:
# nothing like this is used in the real application
# just showing here to give an idea of what the DB could look like
db_data =
[
{
USERID: 150927,
EMAIL: 'irving.block@email.net',
FIRSTNAME: 'IRVING',
LASTNAME: 'Block',
COLOR: 'Orange'
},
{
USERID: 1246007,
EMAIL: 'new.email@somewhere.com',
FIRSTNAME: 'Adler',
LASTNAME: 'Allen',
COLOR: 'Blue'
},
{
USERID: 1248350,
EMAIL: 'walter.pidgeon@email.net',
FIRSTNAME: 'Walt',
LASTNAME: 'Pidgeon',
COLOR: 'Red'
}
]
Using these examples, I’d like to end up with a User object like this (since only 1 thing has changed for each user):
users_final =
[
{
USERID: 150927,
COLOR: 'Orange'
},
{
USERID: 1246007,
EMAIL: 'new.email@somewhere.com',
},
{
USERID: 1248350,
FIRSTNAME: 'Walt',
}
]
And now for the pseudo-code that shows how I’ve been trying to accomplish this:
async = require "async"
handleChanges = (users, map, callback) ->
sql1 = "select..."
sql2 = "update..."
sql3 = "insert..."
db.query sql1, [], (err, rows, def) ->
if err? then console.log err
if rows[0]
if rows[0].ELEMENT_VALUE.toString() is users[map.MAPPED].toString()
# nothing has changed since last update
db.query sql2, ['Old'], (err, rows, def) ->
if err? then console.log err
callback null, map.MAPPED
else # this value has changed since the last update. Run update query
db.query sql2, ['New'], (err, rows, def) ->
if err? then console.log err
callback null, null
else # no value has ever been saved for this combo. Run insert query
db.query sql3, [], (err, rows, def) ->
if err? then console.log err
callback null, null
updateStore = (users, callback) ->
for map in xml_map
do(map) ->
handleChanges users, map, (err, del) ->
if del? then delete r[del]
callback null, r
async.map users, updateStore, (err, results) ->
console.log results
This obviously doesn’t work right. I’m sure the updateStore function needs to be doing something different, but I’m at a loss.
Thanks in advance for your help!
I did similar thing in the project, but I use json instead of xml.
What I have done is
retrieve a list of objects from db. and calculate a hash value for each of the object.
on the client side, I do compare the each old hash to the new hash. if different I use php.js or underscore.js. php.js can do array_diff to get differents between two object. Of course you can just do array_diff with comparing hash.
If your data structure is nested like this
you can flatten it to following before doing array_diff because array_diff only work on one level.