add db snapshotting & better translation loader

This commit is contained in:
Matt Dunn-Rankin 2020-04-22 12:00:52 -07:00
parent ecebb93ec5
commit 8f4ed8e10d
5 changed files with 32 additions and 32 deletions

View file

@ -1,7 +1,7 @@
const { ApolloServer, gql } = require("apollo-server"); const { ApolloServer, gql } = require("apollo-server");
const connectToDb = require("./db"); const connectToDb = require("./db");
const { loadItems, loadItemTranslation } = require("./loaders"); const { loadItems, buildItemTranslationLoader } = require("./loaders");
const typeDefs = gql` const typeDefs = gql`
type Item { type Item {
@ -16,8 +16,8 @@ const typeDefs = gql`
const resolvers = { const resolvers = {
Item: { Item: {
name: async (item, _, { db }) => { name: async (item, _, { itemTranslationLoader }) => {
const translation = await loadItemTranslation(db, item.id, "en"); const translation = await itemTranslationLoader.load(item.id);
return translation.name; return translation.name;
}, },
}, },
@ -31,7 +31,10 @@ const server = new ApolloServer({
resolvers, resolvers,
context: async () => { context: async () => {
const db = await connectToDb(); const db = await connectToDb();
return { db }; return {
db,
itemTranslationLoader: buildItemTranslationLoader(db),
};
}, },
}); });

View file

@ -72,24 +72,11 @@ it("can load items", async () => {
], ],
], ],
Array [ Array [
"SELECT * FROM item_translations WHERE item_id = ? AND locale = ? LIMIT 1", "SELECT * FROM item_translations WHERE item_id IN (?,?,?) AND locale = \\"en\\"",
Array [ Array [
38911, 38911,
"en",
],
],
Array [
"SELECT * FROM item_translations WHERE item_id = ? AND locale = ? LIMIT 1",
Array [
38912, 38912,
"en",
],
],
Array [
"SELECT * FROM item_translations WHERE item_id = ? AND locale = ? LIMIT 1",
Array [
38913, 38913,
"en",
], ],
], ],
] ]

View file

@ -1,3 +1,5 @@
const DataLoader = require("dataloader");
async function loadItems(db, ids) { async function loadItems(db, ids) {
const qs = ids.map((_) => "?").join(","); const qs = ids.map((_) => "?").join(",");
const [rows, _] = await db.execute( const [rows, _] = await db.execute(
@ -8,19 +10,21 @@ async function loadItems(db, ids) {
return rows; return rows;
} }
async function loadItemTranslation(db, itemId, locale) { const buildItemTranslationLoader = (db) =>
const [ new DataLoader(async (itemIds) => {
rows, const qs = itemIds.map((_) => "?").join(",");
_, const [rows, _] = await db.execute(
] = await db.execute( `SELECT * FROM item_translations WHERE item_id IN (${qs}) AND locale = "en"`,
`SELECT * FROM item_translations WHERE item_id = ? AND locale = ? LIMIT 1`, itemIds
[itemId, locale]
); );
if (rows.length === 0) {
throw new Error(`could not load translation for ${itemId}, ${locale}`);
}
return rows[0]; const rowsByItemId = new Map(rows.map((row) => [row.item_id, row]));
}
module.exports = { loadItems, loadItemTranslation }; return itemIds.map(
(itemId) =>
rowsByItemId.get(itemId) ||
new Error(`could not find translation for item ${itemId}`)
);
});
module.exports = { loadItems, buildItemTranslationLoader };

View file

@ -6,6 +6,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"apollo-server": "^2.12.0", "apollo-server": "^2.12.0",
"dataloader": "^2.0.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"graphql": "^15.0.0", "graphql": "^15.0.0",
"mysql2": "^2.1.0" "mysql2": "^2.1.0"

View file

@ -1686,6 +1686,11 @@ data-urls@^1.1.0:
whatwg-mimetype "^2.2.0" whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0" whatwg-url "^7.0.0"
dataloader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f"
integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ==
debug@2.6.9, debug@^2.2.0, debug@^2.3.3: debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"