0

ユーザー向けに定期的な XML 更新を投稿するプロジェクトに取り組んでいます。前回の更新から変更されていない情報を抑制しようとしています。

node.js 内で、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'
    }
  ]

また、ユーザー データを最終的な XML フィールドにマップするのに役立つオブジェクトをロードしました。

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'
    }
  ]

これらのオブジェクトを使用して、最後の更新と比較し、一致するプロパティを削除する必要があります (変更されたデータの更新のみを投稿したいため)。(DB に格納された) 最後の更新がどのように見えるかの例を次に示します。

# 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'
    }
  ]

これらの例を使用して、次のような User オブジェクトを作成したいと思います (ユーザーごとに 1 つのことだけが変更されているため)。

users_final = 
  [
    {
      USERID: 150927,
      COLOR: 'Orange'
    },
    {
      USERID: 1246007,
      EMAIL: 'new.email@somewhere.com',
    },
    {
      USERID: 1248350,
      FIRSTNAME: 'Walt',
    }
  ]

そして今、私がこれを達成しようとしてきた方法を示す疑似コードのために:

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

これは明らかに正しく機能しません。updateStore 関数は別のことをする必要があると確信していますが、途方に暮れています。

よろしくお願いします。

4

2 に答える 2

1

プロジェクトでも同様のことを行いましたが、xml の代わりに json を使用しています。

私が行ったことは、db からオブジェクトのリストを取得することです。各オブジェクトのハッシュ値を計算します。

users = 
  [
    {
      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'
    }
  ]
hash = [
  'c8addc875913a367486ba8343f68e349667e0334',
  'df3d067e876437996237d0fde90466703ea303b9'
]

クライアント側では、古いハッシュと新しいハッシュを比較します。異なる場合は、php.js または underscore.js を使用します。php.js は array_diff を実行して、2 つのオブジェクト間の違いを取得できます。もちろん、ハッシュを比較して array_diff を実行することもできます。

データ構造がこのようにネストされている場合

{
  User: {
    FIRSTNAME: 'Irving',
    LASTNAME: 'Block',
    USERID: 150927
  }
  OtherInfo: {
    EMAIL: 'irving.block@email.net'
  }
}

array_diff は 1 つのレベルでしか機能しないため、array_diff を実行する前に次のように平坦化できます。

{
  "User.FIRSTNAME": 'Irving',
  "User.LASTNAME": 'Block',
  "User.USERID": 150927,
  "OtherInfo.EMAIL": 'irving.block@email.net'
}
于 2012-12-04T02:49:18.950 に答える
0

予想される XML 出力に関する情報が十分にあるかどうかはわかりませんが、users_final探している結果はかなり単純な比較アルゴリズムで計算できます。コア アルゴリズムは次のとおりです。

difference = (a, b, idFieldName) ->
  if a[idFieldName] != b[idFieldName]
    throw new Error("#{idFieldName} values must match.")
  diff = {}
  diff[idFieldName] = a[idFieldName]
  isDifferent = false
  for key, value of b
    if key != idFieldName and a[key].toUpperCase() != value.toUpperCase()
      isDifferent = true
      diff[key] = value
  if isDifferent
    return diff
  else
    return false

これは、あなたが提供した入力を使用することを含む完全に機能する例です... 1つの例外があります。usersリテラルにタイプミスがあると思います。CLKEYからに切り替えたUSERIDので、他の行と一致します。リンクをたどった後、右上隅にある「実行」ボタンをクリックするだけで、期待されるusers_final結果が表示されます。

于 2012-12-05T04:17:52.620 に答える