背景
DynamoDB の更新式を動的に作りたい、という目的からまずは
- 引数から動的オブジェクトの生成を
という課題を解決することに
結論
作成例
import _, { keyBy } from "lodash";
const createUpdatingFormula = async (content: any) => {
let mergeData = {};
Object.keys(content).forEach((k) => {
if (typeof content[k] == "object") {
// 再帰処理へ
} else {
console.log("k", k);
let keyName = `#${k}`;
mergeData = _.merge(mergeData, {
ExpressionAttributeNames: {
[`#${k}`]: k
},
ExpressionAttributeValues: {
[`:${k}`]: content[k]
}
});
}
})
console.log(mergeData);
}
const item = {
age: 33, name: "hoge", items: {
Key: "hoge",
Value: 15,
}
};
createUpdatingFormula(item);
結果はこんな感じ
結果例
{
ExpressionAttributeNames: { '#age': 'age', '#name': 'name' },
ExpressionAttributeValues: { ':age': 33, ':name': 'hoge' }
}
説明
Object.keys/entries
これを使って、オブジェクトのキーを取得して作成していく
オブジェクトが内部にある場合は、typeof で型取得をして再帰するしかなさそう・・(とりあえず今はパス
Object.keys でキー一覧
[ 'age', 'name', 'items' ]
Object.entries で要素一覧
[
[ 'age', 33 ],
[ 'name', 'hoge' ],
[ 'items', { Key: 'hoge', Value: 15 } ]
]
computed property で、プロパティを動的定義
"#column" や ":column" という名称でのプロパティ定義は、これを使って定義していく
更新式の動的定義
ExpressionAttributeNames: {
[`#${k}`]: k
},
_.merge() で、結合
存在しているプロパティをすべて結合していけば完了
結合
mergeData = _.merge(mergeData, {
ExpressionAttributeNames: {
[`#${k}`]: k
},
ExpressionAttributeValues: {
[`:${k}`]: content[k]
}
});
失敗の記録
TypescriptParser は静的解析
当初、オブジェクト解析と考えて、TypescriptParser を試行したら・・
Class等の静的解析用だった・・。いつか使うこともあるだろう、Roslyn みたいに・・
parser
const parser = new TypescriptParser();
const parsedCode = await parser.parseFile('./lib.ts', '');
const parsedSource = await parser.parseSource(`class Person {
// クラスの型宣言
name: string
age: number
// constructorの引数に型宣言
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
`);
console.log(parsedSource);
parseFile の第二引数は、内部で、path.relative() で第一引数を補完している
あとがき
再帰処理も頑張るか・・・どうか・・
まずは必要かを検討してこよう