fix edge case bugs in itemByName and itemsByName

not-found case was erroring instead of returning a simple null, and string trimming wasn't working right, oops!
This commit is contained in:
Emi Matchu 2020-11-08 00:20:21 -08:00
parent f621391446
commit f6723bb67a
3 changed files with 65 additions and 154 deletions

View file

@ -148,8 +148,10 @@ const buildItemTranslationLoader = (db) =>
}); });
const buildItemByNameLoader = (db, loaders) => const buildItemByNameLoader = (db, loaders) =>
new DataLoader(async (names) => { new DataLoader(
async (names) => {
const qs = names.map((_) => "?").join(", "); const qs = names.map((_) => "?").join(", ");
const normalizedNames = names.map((name) => name.trim().toLowerCase());
const [rows, _] = await db.execute( const [rows, _] = await db.execute(
{ {
// NOTE: In our MySQL schema, this is a case-insensitive exact search. // NOTE: In our MySQL schema, this is a case-insensitive exact search.
@ -158,25 +160,27 @@ const buildItemByNameLoader = (db, loaders) =>
WHERE name IN (${qs}) AND locale = "en"`, WHERE name IN (${qs}) AND locale = "en"`,
nestTables: true, nestTables: true,
}, },
names normalizedNames
); );
const entities = rows.map((row) => { const entitiesByName = new Map();
for (const row of rows) {
const item = normalizeRow(row.items); const item = normalizeRow(row.items);
const itemTranslation = normalizeRow(row.item_translations); const itemTranslation = normalizeRow(row.item_translations);
loaders.itemLoader.prime(item.id, item); loaders.itemLoader.prime(item.id, item);
loaders.itemTranslationLoader.prime(item.id, itemTranslation); loaders.itemTranslationLoader.prime(item.id, itemTranslation);
return { item, itemTranslation };
});
return names.map((name) => const normalizedName = itemTranslation.name.trim().toLowerCase();
entities.find( entitiesByName.set(normalizedName, { item, itemTranslation });
(e) => }
e.itemTranslation.name.trim().toLowerCase() ===
name.trim().toLowerCase() return normalizedNames.map(
) (name) =>
entitiesByName.get(name) || { item: null, itemTranslation: null }
);
},
{ cacheKeyFn: (name) => name.trim().toLowerCase() }
); );
});
const buildItemSearchLoader = (db, loaders) => const buildItemSearchLoader = (db, loaders) =>
new DataLoader(async (queries) => { new DataLoader(async (queries) => {

View file

@ -113,7 +113,14 @@ describe("Item", () => {
name name
thumbnailUrl thumbnailUrl
} }
itemsByName(names: ["Zafara Agent Robe", "pile of dung"]) { notFoundItem: itemByName(name: "?! fake name") {
id
name
thumbnailUrl
}
itemsByName(
names: [" Zafara Agent Robe ", "pile of dung", "?! fake name"]
) {
id id
name name
thumbnailUrl thumbnailUrl

View file

@ -742,7 +742,9 @@ Object {
"name": "Pile of Dung", "name": "Pile of Dung",
"thumbnailUrl": "http://images.neopets.com/items/med_booby_5.gif", "thumbnailUrl": "http://images.neopets.com/items/med_booby_5.gif",
}, },
null,
], ],
"notFoundItem": null,
} }
`; `;
@ -753,16 +755,18 @@ Array [
"nestTables": true, "nestTables": true,
"sql": "SELECT items.*, item_translations.* FROM item_translations "sql": "SELECT items.*, item_translations.* FROM item_translations
INNER JOIN items ON items.id = item_translations.item_id INNER JOIN items ON items.id = item_translations.item_id
WHERE name IN (?, ?, ?) AND locale = \\"en\\"", WHERE name IN (?, ?, ?, ?) AND locale = \\"en\\"",
"values": Array [ "values": Array [
"Moon and Stars Background", "moon and stars background",
"Zafara Agent Robe", "?! fake name",
"zafara agent robe",
"pile of dung", "pile of dung",
], ],
}, },
Array [ Array [
"Moon and Stars Background", "moon and stars background",
"Zafara Agent Robe", "?! fake name",
"zafara agent robe",
"pile of dung", "pile of dung",
], ],
], ],
@ -790,10 +794,6 @@ Object {
"id": "28", "id": "28",
"name": "Krawk", "name": "Krawk",
}, },
Object {
"id": "46",
"name": "Techo",
},
], ],
}, },
Object { Object {
@ -812,10 +812,6 @@ Object {
"id": "38", "id": "38",
"name": "Peophin", "name": "Peophin",
}, },
Object {
"id": "46",
"name": "Techo",
},
], ],
}, },
Object { Object {
@ -838,10 +834,6 @@ Object {
"id": "38", "id": "38",
"name": "Peophin", "name": "Peophin",
}, },
Object {
"id": "46",
"name": "Techo",
},
], ],
}, },
Object { Object {
@ -948,10 +940,6 @@ Object {
"id": "36", "id": "36",
"name": "Nimmo", "name": "Nimmo",
}, },
Object {
"id": "37",
"name": "Ogrin",
},
Object { Object {
"id": "39", "id": "39",
"name": "Poogle", "name": "Poogle",
@ -972,10 +960,6 @@ Object {
"id": "45", "id": "45",
"name": "Skeith", "name": "Skeith",
}, },
Object {
"id": "46",
"name": "Techo",
},
Object { Object {
"id": "47", "id": "47",
"name": "Tonu", "name": "Tonu",
@ -1050,10 +1034,6 @@ Object {
"id": "36", "id": "36",
"name": "Nimmo", "name": "Nimmo",
}, },
Object {
"id": "37",
"name": "Ogrin",
},
Object { Object {
"id": "39", "id": "39",
"name": "Poogle", "name": "Poogle",
@ -1062,10 +1042,6 @@ Object {
"id": "41", "id": "41",
"name": "Quiggle", "name": "Quiggle",
}, },
Object {
"id": "42",
"name": "Ruki",
},
Object { Object {
"id": "43", "id": "43",
"name": "Scorchio", "name": "Scorchio",
@ -1074,10 +1050,6 @@ Object {
"id": "45", "id": "45",
"name": "Skeith", "name": "Skeith",
}, },
Object {
"id": "46",
"name": "Techo",
},
Object { Object {
"id": "47", "id": "47",
"name": "Tonu", "name": "Tonu",
@ -1160,10 +1132,6 @@ Object {
"id": "36", "id": "36",
"name": "Nimmo", "name": "Nimmo",
}, },
Object {
"id": "37",
"name": "Ogrin",
},
Object { Object {
"id": "38", "id": "38",
"name": "Peophin", "name": "Peophin",
@ -1184,10 +1152,6 @@ Object {
"id": "45", "id": "45",
"name": "Skeith", "name": "Skeith",
}, },
Object {
"id": "46",
"name": "Techo",
},
Object { Object {
"id": "47", "id": "47",
"name": "Tonu", "name": "Tonu",
@ -1212,10 +1176,6 @@ Object {
"id": "81137", "id": "81137",
"name": "Maraquan Ocean Blue Contacts", "name": "Maraquan Ocean Blue Contacts",
"speciesThatNeedModels": Array [ "speciesThatNeedModels": Array [
Object {
"id": "8",
"name": "Chomby",
},
Object { Object {
"id": "13", "id": "13",
"name": "Flotsam", "name": "Flotsam",
@ -1270,10 +1230,6 @@ Object {
"id": "81287", "id": "81287",
"name": "Maraquan White Lace Gown", "name": "Maraquan White Lace Gown",
"speciesThatNeedModels": Array [ "speciesThatNeedModels": Array [
Object {
"id": "8",
"name": "Chomby",
},
Object { Object {
"id": "13", "id": "13",
"name": "Flotsam", "name": "Flotsam",
@ -1324,10 +1280,6 @@ Object {
"id": "7", "id": "7",
"name": "Chia", "name": "Chia",
}, },
Object {
"id": "8",
"name": "Chomby",
},
Object { Object {
"id": "13", "id": "13",
"name": "Flotsam", "name": "Flotsam",
@ -1398,10 +1350,6 @@ Object {
"id": "7", "id": "7",
"name": "Chia", "name": "Chia",
}, },
Object {
"id": "8",
"name": "Chomby",
},
Object { Object {
"id": "13", "id": "13",
"name": "Flotsam", "name": "Flotsam",
@ -1900,10 +1848,6 @@ Object {
"id": "53", "id": "53",
"name": "Yurble", "name": "Yurble",
}, },
Object {
"id": "54",
"name": "Zafara",
},
Object { Object {
"id": "55", "id": "55",
"name": "Vandagyre", "name": "Vandagyre",
@ -1932,10 +1876,6 @@ Object {
"id": "21", "id": "21",
"name": "Jubjub", "name": "Jubjub",
}, },
Object {
"id": "24",
"name": "Kiko",
},
Object { Object {
"id": "28", "id": "28",
"name": "Krawk", "name": "Krawk",
@ -1990,10 +1930,6 @@ Object {
"id": "21", "id": "21",
"name": "Jubjub", "name": "Jubjub",
}, },
Object {
"id": "24",
"name": "Kiko",
},
Object { Object {
"id": "28", "id": "28",
"name": "Krawk", "name": "Krawk",
@ -2048,10 +1984,6 @@ Object {
"id": "21", "id": "21",
"name": "Jubjub", "name": "Jubjub",
}, },
Object {
"id": "24",
"name": "Kiko",
},
Object { Object {
"id": "28", "id": "28",
"name": "Krawk", "name": "Krawk",
@ -3126,6 +3058,10 @@ Object {
"id": "4", "id": "4",
"name": "Bori", "name": "Bori",
}, },
Object {
"id": "5",
"name": "Bruce",
},
Object { Object {
"id": "6", "id": "6",
"name": "Buzz", "name": "Buzz",
@ -4714,6 +4650,20 @@ Object {
}, },
], ],
}, },
Object {
"id": "67237",
"name": "Winter Lights Effect",
"speciesThatNeedModels": Array [
Object {
"id": "28",
"name": "Krawk",
},
Object {
"id": "38",
"name": "Peophin",
},
],
},
Object { Object {
"id": "69311", "id": "69311",
"name": "MME17-S4a: Snow-Covered Balustrade Foreground", "name": "MME17-S4a: Snow-Covered Balustrade Foreground",
@ -6998,10 +6948,6 @@ Object {
"id": "4", "id": "4",
"name": "Bori", "name": "Bori",
}, },
Object {
"id": "7",
"name": "Chia",
},
Object { Object {
"id": "9", "id": "9",
"name": "Cybunny", "name": "Cybunny",
@ -7014,14 +6960,6 @@ Object {
"id": "17", "id": "17",
"name": "Grundo", "name": "Grundo",
}, },
Object {
"id": "20",
"name": "Jetsam",
},
Object {
"id": "24",
"name": "Kiko",
},
Object { Object {
"id": "33", "id": "33",
"name": "Meerca", "name": "Meerca",
@ -7032,28 +6970,10 @@ Object {
}, },
], ],
}, },
Object {
"id": "81736",
"name": "Purple & Black Ponytails Wig",
"speciesThatNeedModels": Array [
Object {
"id": "7",
"name": "Chia",
},
Object {
"id": "20",
"name": "Jetsam",
},
],
},
Object { Object {
"id": "81783", "id": "81783",
"name": "Dyeworks Blue: Decorated Witch Hat and Wig", "name": "Dyeworks Blue: Decorated Witch Hat and Wig",
"speciesThatNeedModels": Array [ "speciesThatNeedModels": Array [
Object {
"id": "7",
"name": "Chia",
},
Object { Object {
"id": "26", "id": "26",
"name": "Korbat", "name": "Korbat",
@ -7068,18 +6988,6 @@ Object {
"id": "5", "id": "5",
"name": "Bruce", "name": "Bruce",
}, },
Object {
"id": "7",
"name": "Chia",
},
Object {
"id": "20",
"name": "Jetsam",
},
Object {
"id": "24",
"name": "Kiko",
},
], ],
}, },
Object { Object {
@ -7094,10 +7002,6 @@ Object {
"id": "11", "id": "11",
"name": "Elephante", "name": "Elephante",
}, },
Object {
"id": "28",
"name": "Krawk",
},
Object { Object {
"id": "46", "id": "46",
"name": "Techo", "name": "Techo",
@ -7106,10 +7010,6 @@ Object {
"id": "48", "id": "48",
"name": "Tuskaninny", "name": "Tuskaninny",
}, },
Object {
"id": "49",
"name": "Uni",
},
Object { Object {
"id": "52", "id": "52",
"name": "Xweetok", "name": "Xweetok",
@ -7146,6 +7046,7 @@ Array [
"62939", "62939",
"64195", "64195",
"64387", "64387",
"67237",
"69311", "69311",
"70843", "70843",
"71937", "71937",
@ -7177,7 +7078,6 @@ Array [
"81697", "81697",
"81708", "81708",
"81709", "81709",
"81736",
"81783", "81783",
"81785", "81785",
"81792", "81792",