add other colors to modeling GQL

This commit is contained in:
Emi Matchu 2020-09-15 03:06:17 -07:00
parent 32822b250d
commit c3c8d924b5
5 changed files with 5555 additions and 167 deletions

View file

@ -53,8 +53,7 @@ BEGIN
8, -- Blue (Standard) 8, -- Blue (Standard)
6, -- Baby 6, -- Baby
44, -- Maraquan 44, -- Maraquan
46, -- Mutant 46 -- Mutant
92 -- 8-bit
) )
AND items.modeling_status_hint IS NULL AND items.modeling_status_hint IS NULL
GROUP BY color_id, item_id GROUP BY color_id, item_id

View file

@ -240,7 +240,7 @@ const buildItemSearchToFitLoader = (db, loaders) =>
}); });
let lastKnownUpdate = "1970-01-01"; // start it out very old! let lastKnownUpdate = "1970-01-01"; // start it out very old!
let lastResult = []; let lastResult = new Map();
const buildItemsThatNeedModelsLoader = (db) => const buildItemsThatNeedModelsLoader = (db) =>
new DataLoader(async (keys) => { new DataLoader(async (keys) => {
// Essentially, I want to take easy advantage of DataLoader's caching, for // Essentially, I want to take easy advantage of DataLoader's caching, for
@ -279,7 +279,16 @@ const buildItemsThatNeedModelsLoader = (db) =>
const rows = rawRows.map(normalizeRow); const rows = rawRows.map(normalizeRow);
lastKnownUpdate = varRows[0]["@LastActualUpdate"]; lastKnownUpdate = varRows[0]["@LastActualUpdate"];
lastResult = rows;
// We build lastResult into a Map up-front, to speed up the many lookups
// that the GQL resolvers will do as we group this data into GQL nodes!
lastResult = new Map();
for (const { colorId, itemId, ...row } of rows) {
if (!lastResult.has(colorId)) {
lastResult.set(colorId, new Map());
}
lastResult.get(colorId).set(itemId, row);
}
} }
return [lastResult]; return [lastResult];

View file

@ -383,15 +383,10 @@ describe("Item", () => {
it("loads items that need models", async () => { it("loads items that need models", async () => {
jest.setTimeout(20000); jest.setTimeout(20000);
const buildLoaders = require("../loaders");
const db = await require("../db")();
const { itemsThatNeedModelsLoader } = buildLoaders(db);
await itemsThatNeedModelsLoader.load("all");
const res = await query({ const res = await query({
query: gql` query: gql`
query { query {
itemsThatNeedModels { standardItems: itemsThatNeedModels {
id id
name name
speciesThatNeedModels { speciesThatNeedModels {
@ -399,148 +394,39 @@ describe("Item", () => {
name name
} }
} }
babyItems: itemsThatNeedModels(colorId: "6") {
id
name
speciesThatNeedModels(colorId: "6") {
id
name
}
}
maraquanItems: itemsThatNeedModels(colorId: "44") {
id
name
speciesThatNeedModels(colorId: "44") {
id
name
}
}
mutantItems: itemsThatNeedModels(colorId: "46") {
id
name
speciesThatNeedModels(colorId: "46") {
id
name
}
}
} }
`, `,
}); });
expect(res).toHaveNoErrors(); expect(res).toHaveNoErrors();
expect(res.data).toMatchSnapshot(); expect(res.data).toMatchSnapshot();
expect(getDbCalls()).toMatchInlineSnapshot(` expect(getDbCalls()).toMatchSnapshot();
Array [
Array [
"SELECT * FROM item_translations WHERE item_id IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND locale = \\"en\\"",
Array [
"36907",
"42448",
"42544",
"42546",
"50669",
"50670",
"50671",
"50672",
"51646",
"51651",
"51653",
"51654",
"51655",
"53324",
"53325",
"58285",
"59848",
"62939",
"64195",
"64387",
"67317",
"68228",
"69311",
"70843",
"71110",
"71937",
"71938",
"73707",
"73708",
"73724",
"74259",
"74260",
"74261",
"76108",
"76109",
"77441",
"77442",
"81144",
"81145",
"81229",
"81230",
"81232",
"81233",
"81234",
"81237",
"81238",
"81240",
"81241",
"81242",
"81243",
"81245",
"81246",
"81547",
"81619",
"81630",
"81657",
"81658",
"81659",
"81660",
"81664",
"81667",
"81670",
"81671",
"81672",
"81674",
"81675",
"81693",
],
],
Array [
"SELECT * FROM species_translations
WHERE species_id IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND locale = \\"en\\"",
Array [
"1",
"4",
"5",
"6",
"7",
"8",
"11",
"12",
"15",
"16",
"17",
"19",
"20",
"21",
"22",
"23",
"24",
"26",
"27",
"30",
"32",
"34",
"36",
"39",
"40",
"42",
"44",
"47",
"48",
"49",
"50",
"54",
"2",
"13",
"14",
"25",
"29",
"37",
"38",
"43",
"45",
"46",
"51",
"52",
"53",
"3",
"9",
"31",
"41",
"10",
"18",
"28",
"35",
"33",
"55",
],
],
]
`);
}); });
}); });

File diff suppressed because it is too large Load diff

View file

@ -31,10 +31,12 @@ const typeDefs = gql`
# layer data from this API should be interpreted! # layer data from this API should be interpreted!
explicitlyBodySpecific: Boolean! explicitlyBodySpecific: Boolean!
# NOTE: I think we'll probably deprecate this and add more complexity to # Get the species that we need modeled for this item for the given color.
# this API, because right now we're only looking at standard colors #
# but it would be good to report gaps in Mutant etc items too. # NOTE: Most color IDs won't be accepted here. Either pass the ID of a
speciesThatNeedModels: [Species!]! # major special color like Baby (#6), or leave it blank for standard
# bodies like Blue, Green, Red, etc.
speciesThatNeedModels(colorId: ID): [Species!]!
} }
type ItemAppearance { type ItemAppearance {
@ -63,7 +65,13 @@ const typeDefs = gql`
offset: Int offset: Int
limit: Int limit: Int
): ItemSearchResult! ): ItemSearchResult!
itemsThatNeedModels: [Item!]!
# Get items that need models for the given color.
#
# NOTE: Most color IDs won't be accepted here. Either pass the ID of a
# major special color like Baby (#6), or leave it blank for standard
# bodies like Blue, Green, Red, etc.
itemsThatNeedModels(colorId: ID): [Item!]!
} }
`; `;
@ -135,15 +143,23 @@ const resolvers = {
const item = await itemLoader.load(id); const item = await itemLoader.load(id);
return item.explicitlyBodySpecific; return item.explicitlyBodySpecific;
}, },
speciesThatNeedModels: async ({ id }, _, { itemsThatNeedModelsLoader }) => { speciesThatNeedModels: async (
const allItems = await itemsThatNeedModelsLoader.load("all"); { id },
const item = allItems.find( { colorId = "8" }, // Blue
(row) => row.itemId === id && row.colorId === "8" { itemsThatNeedModelsLoader }
) => {
const speciesIdsByColorIdAndItemId = await itemsThatNeedModelsLoader.load(
"all"
); );
const modeledSpeciesIds = item.modeledSpeciesIds.split(","); const row = speciesIdsByColorIdAndItemId.get(colorId)?.get(id);
if (!row) {
return [];
}
const modeledSpeciesIds = row.modeledSpeciesIds.split(",");
// HACK: Needs to be updated if more species are added! // HACK: Needs to be updated if more species are added!
const allSpeciesIds = Array.from( const allSpeciesIds = Array.from(
{ length: item.supportsVandagyre ? 55 : 54 }, { length: row.supportsVandagyre ? 55 : 54 },
(_, i) => String(i + 1) (_, i) => String(i + 1)
); );
const unmodeledSpeciesIds = allSpeciesIds.filter( const unmodeledSpeciesIds = allSpeciesIds.filter(
@ -208,14 +224,16 @@ const resolvers = {
const zones = zoneIds.map((id) => ({ id })); const zones = zoneIds.map((id) => ({ id }));
return { query, zones, items }; return { query, zones, items };
}, },
itemsThatNeedModels: async (_, __, { itemsThatNeedModelsLoader }) => { itemsThatNeedModels: async (
const rows = await itemsThatNeedModelsLoader.load("all"); _,
let itemIds = rows { colorId = "8" }, // Defaults to Blue
.filter((row) => row.colorId === "8") { itemsThatNeedModelsLoader }
.map((row) => row.itemId); ) => {
itemIds = new Set(itemIds); const speciesIdsByColorIdAndItemId = await itemsThatNeedModelsLoader.load(
itemIds = [...itemIds].sort(); "all"
return itemIds.map((id) => ({ id })); );
const itemIds = speciesIdsByColorIdAndItemId.get(colorId)?.keys() || [];
return Array.from(itemIds, (id) => ({ id }));
}, },
}, },
}; };