-
Notifications
You must be signed in to change notification settings - Fork 5
ja_JP: cont_TypeScript に関する備考
SQL を クエリビルダで組み立てる際、使用するプレースホルダは重複してはいけません。
例えば:
query.andWhere(new Brackets(qb => {
for (const type of ps.fileType) {
qb.orWhere(`:type = ANY(note.attachedFileTypes)`, { type: type });
}
}));
のように実装すると、ループ中で type
というプレースホルダが 複数回使われてしまうため、不具合を生じます。
したがって、次のように実装する必要があります。
query.andWhere(new Brackets(qb => {
for (const type of ps.fileType) {
const i = ps.fileType.indexOf(type);
qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, { [`type${i}`]: type });
}
}));
例えば:
const foo = await Foos.findOne({
bar: Not(null)
});
のような クエリ(bar
がnull
ではない) は期待通りに動作しません。
したがって、次のように実装する必要があります。
const foo = await Foos.findOne({
bar: Not(IsNull())
});
SQL を発行する際、パラメータが null
になる可能性のある場合は、SQL文を分けて発行する必要があります。
例えば:
query.where('file.folderId = :folderId', { folderId: ps.folderId });
という処理では、
ps.folderId
が null
の場合、結果的に file.folderId = null
のようなクエリが発行されてしまいます。
これは、正しい SQL ではないので、期待した結果が得られません。
したがって、次のように実装する必要があります。
if (ps.folderId) {
query.where('file.folderId = :folderId', { folderId: ps.folderId });
} else {
query.where('file.folderId IS NULL');
}
SQL を発行する際、IN
のパラメータが []
(空の配列) になる可能性のある場合は、SQL文を分けて発行する必要があります。
例えば:
const users = await Users.find({
id: In(userIds)
});
という処理では、
userIds
が []
の場合、結果的に user.id IN ()
のようなクエリが発行されてしまいます。
これは、正しい SQL ではないので、期待した結果が得られません。
したがって、次のように実装する必要があります。
const users = userIds.length > 0 ? await Users.find({
id: In(userIds)
}) : [];
SQL では 配列のインデックス は 1始まり です。
[a, b, c]
の a
にアクセスしたい場合、 [0]
ではなく [1]
と書きます。
データベースからレコードを取得する場合、undefined
になる可能性が限りなく低い場合でも、
TypeScript では undefined
チェックを行う必要があります。
そこで、簡素な undefined
チェックが可能な ensure
というユーティリティ関数を用意しています。
例えば:
const user = await Users.findOne(userId);
// この時点で user の型は User | undefined
if (user == null) {
throw 'missing user';
}
// この時点で user の型は User
という処理で ensure
を使うと
const user = await Users.findOne(userId).then(ensure);
// この時点で user の型は User
という実装が可能です。
万が一 undefined
だった場合、Promise が Reject され後続の処理は実行されません。
const user = await Users.findOne(userId).then(ensure);
// 万が一 Users.findOne の結果が undefined の場合、ensure でエラーが発生するので
// この行に到達することはありません
// なので、.then(ensure) は
// if (user == null) {
// throw 'missing user';
// }
// の糖衣構文のような扱いです