modeling saves pet type

This commit is contained in:
Emi Matchu 2020-09-19 03:28:53 -07:00
parent 9111dfddd3
commit ff3fc943d7
7 changed files with 140 additions and 30 deletions

View file

@ -45,7 +45,7 @@
"mysql-dev": "mysql --host=localhost --user=impress_2020_dev --password=impress_2020_dev --database=impress_2020_dev",
"mysql-admin": "mysql --host=impress.openneo.net --user=matchu --password --database=openneo_impress",
"mysqldump": "mysqldump --host=impress.openneo.net --user=$(dotenv -p IMPRESS_MYSQL_USER) --password=$(dotenv -p IMPRESS_MYSQL_PASSWORD) --column-statistics=0",
"download-mysql-schema": "yarn --silent mysqldump openneo_impress species species_translations colors color_translations > scripts/setup-mysql-dev-constants.sql && yarn --silent mysqldump --no-data openneo_impress items item_translations swf_assets > scripts/setup-mysql-dev-schema.sql",
"download-mysql-schema": "yarn --silent mysqldump --no-data openneo_impress items item_translations pet_types pet_states swf_assets > scripts/setup-mysql-dev-schema.sql && yarn --silent mysqldump openneo_impress species species_translations colors color_translations > scripts/setup-mysql-dev-constants.sql",
"setup-mysql": "yarn mysql-admin < scripts/setup-mysql.sql",
"setup-mysql-dev": "yarn mysql-dev < scripts/setup-mysql-dev-constants.sql && yarn mysql-dev < scripts/setup-mysql-dev-schema.sql",
"build-cached-data": "node -r dotenv/config scripts/build-cached-data.js",

View file

@ -133,4 +133,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-09-19 2:56:30
-- Dump completed on 2020-09-19 3:12:59

View file

@ -68,6 +68,26 @@ CREATE TABLE `item_translations` (
) ENGINE=InnoDB AUTO_INCREMENT=215780 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `pet_types`
--
DROP TABLE IF EXISTS `pet_types`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `pet_types` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`color_id` tinyint(4) NOT NULL,
`species_id` tinyint(4) NOT NULL,
`created_at` datetime NOT NULL,
`body_id` smallint(6) NOT NULL,
`image_hash` varchar(8) COLLATE utf8_unicode_ci DEFAULT NULL,
`basic_image_hash` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `pet_types_species_color` (`species_id`,`color_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4795 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `swf_assets`
--
@ -106,4 +126,4 @@ CREATE TABLE `swf_assets` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-09-19 2:56:34
-- Dump completed on 2020-09-19 3:12:53

View file

@ -57,7 +57,7 @@ describe("Pet", () => {
`);
});
it("models new item data", async () => {
it("models new pet and item data", async () => {
useTestDb();
const res = await query({
@ -86,6 +86,18 @@ describe("Pet", () => {
const res2 = await query({
query: gql`
query {
petAppearance(colorId: "75", speciesId: "54", pose: SAD_MASC) {
id
pose
layers {
id
swfUrl
}
restrictedZones {
id
}
}
items(
ids: [
"37229"

View file

@ -82,7 +82,7 @@ Object {
}
`;
exports[`Pet models new item data 1`] = `
exports[`Pet models new pet and item data 1`] = `
Object {
"petOnNeopetsDotCom": Object {
"items": Array [
@ -155,8 +155,15 @@ Object {
}
`;
exports[`Pet models new item data 2`] = `
exports[`Pet models new pet and item data 2`] = `
Array [
Array [
"SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)",
Array [
"54",
"75",
],
],
Array [
"SELECT * FROM items WHERE id IN (?,?,?,?,?,?,?,?)",
Array [
@ -204,6 +211,15 @@ Array [
"56478",
],
],
Array [
"INSERT INTO pet_types (body_id, color_id, created_at, species_id) VALUES (?, ?, ?, ?);",
Array [
"180",
"75",
2020-01-01T00:00:00.000Z,
"54",
],
],
Array [
"INSERT INTO items (category, created_at, id, price, rarity_index, thumbnail_url, type, updated_at, weight_lbs, zones_restrict) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
Array [
@ -414,7 +430,7 @@ Array [
]
`;
exports[`Pet models new item data 3`] = `
exports[`Pet models new pet and item data 3`] = `
Object {
"items": Array [
Object {
@ -490,11 +506,19 @@ Object {
"thumbnailUrl": "http://images.neopets.com/items/clo_altcuplogo_brooch.gif",
},
],
"petAppearance": null,
}
`;
exports[`Pet models new item data 4`] = `
exports[`Pet models new pet and item data 4`] = `
Array [
Array [
"SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)",
Array [
"54",
"75",
],
],
Array [
"SELECT * FROM item_translations WHERE item_id IN (?,?,?,?,?,?,?,?) AND locale = \\"en\\"",
Array [
@ -526,6 +550,13 @@ Array [
exports[`Pet models updated item data 1`] = `
Array [
Array [
"SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)",
Array [
"54",
"75",
],
],
Array [
"SELECT * FROM items WHERE id IN (?,?,?,?,?,?,?,?)",
Array [
@ -573,6 +604,15 @@ Array [
"56478",
],
],
Array [
"INSERT INTO pet_types (body_id, color_id, created_at, species_id) VALUES (?, ?, ?, ?);",
Array [
"180",
"75",
2020-01-01T00:00:00.000Z,
"54",
],
],
Array [
"INSERT INTO items (category, created_at, id, price, rarity_index, thumbnail_url, type, updated_at, weight_lbs, zones_restrict) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
Array [

View file

@ -49,28 +49,27 @@ const resolvers = {
petOnNeopetsDotCom: async (
_,
{ petName },
{ db, itemLoader, itemTranslationLoader, swfAssetByRemoteIdLoader }
{
db,
petTypeBySpeciesAndColorLoader,
itemLoader,
itemTranslationLoader,
swfAssetByRemoteIdLoader,
}
) => {
// Start all these requests as soon as possible...
const petMetaDataPromise = loadPetMetaData(petName);
const customPetDataPromise = loadCustomPetData(petName);
const modelingPromise = customPetDataPromise.then((customPetData) =>
saveModelingData(customPetData, {
db,
itemLoader,
itemTranslationLoader,
swfAssetByRemoteIdLoader,
})
);
// ...then wait on all of them before finishing. It's important to wait
// on modeling, so that it doesn't get cut off when the request ends!
const [petMetaData, customPetData, __] = await Promise.all([
petMetaDataPromise,
customPetDataPromise,
modelingPromise,
const [customPetData, petMetaData, __] = await Promise.all([
loadCustomPetData(petName),
loadPetMetaData(petName),
]);
await saveModelingData(customPetData, petMetaData, {
db,
petTypeBySpeciesAndColorLoader,
itemLoader,
itemTranslationLoader,
swfAssetByRemoteIdLoader,
});
const outfit = {
// TODO: This isn't a fully-working Outfit object. It works for the
// client as currently implemented, but we'll probably want to
@ -154,8 +153,16 @@ function getPoseFromPetData(petMetaData, petCustomData) {
async function saveModelingData(
customPetData,
{ db, itemLoader, itemTranslationLoader, swfAssetByRemoteIdLoader }
petMetaData,
{
db,
petTypeBySpeciesAndColorLoader,
itemLoader,
itemTranslationLoader,
swfAssetByRemoteIdLoader,
}
) {
const customPet = customPetData.custom_pet;
const objectInfos = Object.values(customPetData.object_info_registry);
const objectAssets = Object.values(customPetData.object_asset_registry);
@ -187,10 +194,37 @@ async function saveModelingData(
// TODO: This doesn't actually work... sometimes it needs to be 0, yeah?
// So we actually have to do asset writing after we load the current
// row and compare... maybe a cutesy fn syntax here?
bodyId: customPetData.custom_pet.body_id,
bodyId: customPet.body_id,
}));
const incomingPetTypes = [
{
colorId: String(customPet.color_id),
speciesId: String(customPet.species_id),
bodyId: String(customPet.body_id),
// NOTE: I skip the image_hash stuff here... on Rails, we set a hash on
// creation, and may or may not bother to update it, I forget? But
// here I don't want to bother with an update. We could maybe do
// a merge function to make it on create only, but eh, I don't
// care enough ^_^`
},
];
await Promise.all([
syncToDb(db, incomingPetTypes, {
loader: petTypeBySpeciesAndColorLoader,
tableName: "pet_types",
buildLoaderKey: (row) => ({
speciesId: row.speciesId,
colorId: row.colorId,
}),
buildUpdateCondition: (row) => [
`species_id = ? AND color_id = ?`,
row.speciesId,
row.colorId,
],
includeUpdatedAt: false,
}),
syncToDb(db, incomingItems, {
loader: itemLoader,
tableName: "items",
@ -254,7 +288,8 @@ async function syncToDb(
const currentRow = currentRows[index];
// If there is no corresponding row in the database, prepare an insert.
if (currentRow instanceof Error) {
// TODO: Should probably converge on whether not-found is null or an error
if (currentRow == null || currentRow instanceof Error) {
const insert = { ...incomingRow };
if (includeCreatedAt) {
insert.createdAt = new Date();

View file

@ -208,6 +208,9 @@ const resolvers = {
speciesId,
colorId,
});
if (!petType) {
return null;
}
// TODO: We could query for this more directly, instead of loading all
// appearances 🤔