finish modeling full pet appearance

This commit is contained in:
Emi Matchu 2020-09-19 04:22:39 -07:00
parent 50537758c5
commit 41e70ba8d0
7 changed files with 228 additions and 43 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-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", "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", "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 --no-data openneo_impress items item_translations pet_types pet_states swf_assets | sed 's/ AUTO_INCREMENT=[0-9]*//g' > scripts/setup-mysql-dev-schema.sql && yarn --silent mysqldump openneo_impress species species_translations colors color_translations > scripts/setup-mysql-dev-constants.sql", "download-mysql-schema": "yarn --silent mysqldump --no-data openneo_impress items item_translations parents_swf_assets pet_types pet_states swf_assets | sed 's/ AUTO_INCREMENT=[0-9]*//g' > 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": "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", "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", "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 */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-09-19 4:00:01 -- Dump completed on 2020-09-19 4:19:07

View file

@ -68,6 +68,25 @@ CREATE TABLE `item_translations` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `parents_swf_assets`
--
DROP TABLE IF EXISTS `parents_swf_assets`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `parents_swf_assets` (
`parent_id` mediumint(9) NOT NULL,
`swf_asset_id` mediumint(9) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_type` varchar(8) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_parents_swf_assets` (`parent_id`,`swf_asset_id`),
KEY `parents_swf_assets_swf_asset_id` (`swf_asset_id`),
KEY `index_parents_swf_assets_on_parent_id_and_parent_type` (`parent_id`,`parent_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Table structure for table `pet_types` -- Table structure for table `pet_types`
-- --
@ -148,4 +167,4 @@ CREATE TABLE `swf_assets` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-09-19 3:59:55 -- Dump completed on 2020-09-19 4:19:01

View file

@ -401,8 +401,8 @@ const buildSwfAssetByRemoteIdLoader = (db) =>
const entities = rows.map(normalizeRow); const entities = rows.map(normalizeRow);
return swfAssetIds.map((remoteId) => return typeAndRemoteIdPairs.map(({ type, remoteId }) =>
entities.find((e) => e.remoteId === remoteId) entities.find((e) => e.type === type && e.remoteId === remoteId)
); );
}, },
{ cacheKeyFn: ({ type, remoteId }) => `${type},${remoteId}` } { cacheKeyFn: ({ type, remoteId }) => `${type},${remoteId}` }
@ -583,9 +583,9 @@ const buildPetStateByPetTypeAndAssetsLoader = (db) =>
const qs = petTypeIdAndAssetIdsPairs const qs = petTypeIdAndAssetIdsPairs
.map((_) => "(pet_type_id = ? AND swf_asset_ids = ?)") .map((_) => "(pet_type_id = ? AND swf_asset_ids = ?)")
.join(" OR "); .join(" OR ");
const values = petTypeIdAndAssetIdsPairs.map( const values = petTypeIdAndAssetIdsPairs
({ petTypeId, swfAssetIds }) => [petTypeId, swfAssetIds] .map(({ petTypeId, swfAssetIds }) => [petTypeId, swfAssetIds])
); .flat();
const [rows, _] = await db.execute( const [rows, _] = await db.execute(
`SELECT * FROM pet_states WHERE ${qs}`, `SELECT * FROM pet_states WHERE ${qs}`,
values values

View file

@ -90,6 +90,14 @@ describe("Pet", () => {
id id
pose pose
bodyId bodyId
restrictedZones {
id
}
layers {
id
swfUrl
}
} }
items( items(

View file

@ -490,13 +490,11 @@ Array [
], ],
Array [ Array [
"SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)", "SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)",
Array [
Array [ Array [
"1", "1",
"21057,21060,24008,7941,7942,7946", "21057,21060,24008,7941,7942,7946",
], ],
], ],
],
Array [ Array [
"INSERT INTO pet_states (female, labeled, mood_id, pet_type_id, swf_asset_ids, unconverted) VALUES (?, ?, ?, ?, ?, ?);", "INSERT INTO pet_states (female, labeled, mood_id, pet_type_id, swf_asset_ids, unconverted) VALUES (?, ?, ?, ?, ?, ?);",
Array [ Array [
@ -508,6 +506,54 @@ Array [
false, false,
], ],
], ],
Array [
"SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)",
Array [
"1",
"21057,21060,24008,7941,7942,7946",
],
],
Array [
"SELECT * FROM swf_assets WHERE (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?)",
Array [
"biology",
"7942",
"biology",
"7941",
"biology",
"24008",
"biology",
"21060",
"biology",
"21057",
"biology",
"7946",
],
],
Array [
"INSERT INTO parents_swf_assets (parent_type, parent_id, swf_asset_id)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?);",
Array [
"PetState",
"1",
"9",
"PetState",
"1",
"10",
"PetState",
"1",
"11",
"PetState",
"1",
"12",
"PetState",
"1",
"13",
"PetState",
"1",
"14",
],
],
] ]
`; `;
@ -590,7 +636,34 @@ Object {
"petAppearance": Object { "petAppearance": Object {
"bodyId": "180", "bodyId": "180",
"id": "1", "id": "1",
"layers": Array [
Object {
"id": "9",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/007/7942_2eab06fd7b.swf",
},
Object {
"id": "10",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/007/7941_2c4cc4b846.swf",
},
Object {
"id": "11",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/024/24008_a05fe9876a.swf",
},
Object {
"id": "12",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/021/21060_d77ba93b7b.swf",
},
Object {
"id": "13",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/021/21057_4550efbb2f.swf",
},
Object {
"id": "14",
"swfUrl": "http://images.neopets.com/cp/bio/swf/000/000/007/7946_0348dad587.swf",
},
],
"pose": "SAD_MASC", "pose": "SAD_MASC",
"restrictedZones": Array [],
}, },
} }
`; `;
@ -639,6 +712,16 @@ Array [
"1", "1",
], ],
], ],
Array [
"SELECT sa.*, rel.parent_id FROM swf_assets sa
INNER JOIN parents_swf_assets rel ON
rel.parent_type = \\"PetState\\" AND
rel.swf_asset_id = sa.id
WHERE rel.parent_id IN (?)",
Array [
"1",
],
],
] ]
`; `;
@ -979,13 +1062,11 @@ Array [
], ],
Array [ Array [
"SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)", "SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)",
Array [
Array [ Array [
"1", "1",
"21057,21060,24008,7941,7942,7946", "21057,21060,24008,7941,7942,7946",
], ],
], ],
],
Array [ Array [
"INSERT INTO pet_states (female, labeled, mood_id, pet_type_id, swf_asset_ids, unconverted) VALUES (?, ?, ?, ?, ?, ?);", "INSERT INTO pet_states (female, labeled, mood_id, pet_type_id, swf_asset_ids, unconverted) VALUES (?, ?, ?, ?, ?, ?);",
Array [ Array [
@ -997,6 +1078,54 @@ Array [
false, false,
], ],
], ],
Array [
"SELECT * FROM pet_states WHERE (pet_type_id = ? AND swf_asset_ids = ?)",
Array [
"1",
"21057,21060,24008,7941,7942,7946",
],
],
Array [
"SELECT * FROM swf_assets WHERE (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?) OR (type = ? AND remote_id = ?)",
Array [
"biology",
"7942",
"biology",
"7941",
"biology",
"24008",
"biology",
"21060",
"biology",
"21057",
"biology",
"7946",
],
],
Array [
"INSERT INTO parents_swf_assets (parent_type, parent_id, swf_asset_id)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?);",
Array [
"PetState",
"1",
"9",
"PetState",
"1",
"10",
"PetState",
"1",
"11",
"PetState",
"1",
"12",
"PetState",
"1",
"13",
"PetState",
"1",
"14",
],
],
] ]
`; `;

View file

@ -211,8 +211,7 @@ async function saveModelingData(
const incomingSwfAssets = [...incomingItemSwfAssets, ...incomingPetSwfAssets]; const incomingSwfAssets = [...incomingItemSwfAssets, ...incomingPetSwfAssets];
const incomingPetTypes = [ const incomingPetType = {
{
colorId: String(customPet.color_id), colorId: String(customPet.color_id),
speciesId: String(customPet.species_id), speciesId: String(customPet.species_id),
bodyId: String(customPet.body_id), bodyId: String(customPet.body_id),
@ -221,11 +220,10 @@ async function saveModelingData(
// here I don't want to bother with an update. We could maybe do // 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 // a merge function to make it on create only, but eh, I don't
// care enough ^_^` // care enough ^_^`
}, };
];
await Promise.all([ await Promise.all([
syncToDb(db, incomingPetTypes, { syncToDb(db, [incomingPetType], {
loader: petTypeBySpeciesAndColorLoader, loader: petTypeBySpeciesAndColorLoader,
tableName: "pet_types", tableName: "pet_types",
buildLoaderKey: (row) => ({ buildLoaderKey: (row) => ({
@ -276,8 +274,7 @@ async function saveModelingData(
colorId: String(customPet.color_id), colorId: String(customPet.color_id),
speciesId: String(customPet.species_id), speciesId: String(customPet.species_id),
}); });
const incomingPetStates = [ const incomingPetState = {
{
petTypeId: petType.id, petTypeId: petType.id,
swfAssetIds: incomingPetSwfAssets swfAssetIds: incomingPetSwfAssets
.map((a) => a.remoteId) .map((a) => a.remoteId)
@ -287,10 +284,9 @@ async function saveModelingData(
moodId: petMetaData.mood, moodId: petMetaData.mood,
unconverted: incomingPetSwfAssets.length === 1, unconverted: incomingPetSwfAssets.length === 1,
labeled: true, labeled: true,
}, };
];
await syncToDb(db, incomingPetStates, { await syncToDb(db, [incomingPetState], {
loader: petStateByPetTypeAndAssetsLoader, loader: petStateByPetTypeAndAssetsLoader,
tableName: "pet_states", tableName: "pet_states",
buildLoaderKey: (row) => ({ buildLoaderKey: (row) => ({
@ -304,6 +300,35 @@ async function saveModelingData(
], ],
includeCreatedAt: false, includeCreatedAt: false,
includeUpdatedAt: false, includeUpdatedAt: false,
// For pet states, syncing assets is easy: a new set of assets counts as a
// new state, so, whatever! Just insert the relationships when inserting
// the pet state, and ignore them any other time.
afterInsert: async () => {
// We need to load from the db to get the actual inserted IDs. Not lovely
// for perf, but this is a real new-data model, so that's fine!
let [petState, swfAssets] = await Promise.all([
petStateByPetTypeAndAssetsLoader.load({
petTypeId: incomingPetState.petTypeId,
swfAssetIds: incomingPetState.swfAssetIds,
}),
swfAssetByRemoteIdLoader.loadMany(
incomingPetSwfAssets.map((row) => ({
type: row.type,
remoteId: row.remoteId,
}))
),
]);
swfAssets = swfAssets.filter((sa) => sa != null);
const qs = swfAssets.map((_) => `(?, ?, ?)`).join(", ");
const values = swfAssets
.map((sa) => ["PetState", petState.id, sa.id])
.flat();
await db.execute(
`INSERT INTO parents_swf_assets (parent_type, parent_id, swf_asset_id)
VALUES ${qs};`,
values
);
},
}); });
} }
@ -329,6 +354,7 @@ async function syncToDb(
buildUpdateCondition, buildUpdateCondition,
includeCreatedAt = true, includeCreatedAt = true,
includeUpdatedAt = true, includeUpdatedAt = true,
afterInsert = null,
} }
) { ) {
const loaderKeys = incomingRows.map(buildLoaderKey); const loaderKeys = incomingRows.map(buildLoaderKey);
@ -396,6 +422,9 @@ async function syncToDb(
`INSERT INTO ${tableName} (${columnsStr}) VALUES ${rowQs};`, `INSERT INTO ${tableName} (${columnsStr}) VALUES ${rowQs};`,
rowFields.flat() rowFields.flat()
); );
if (afterInsert) {
await afterInsert();
}
} }
// Do parallel updates of anything that needs updated. // Do parallel updates of anything that needs updated.