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

View file

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

View file

@ -1,3 +1,5 @@
const DataLoader = require("dataloader");
async function loadItems(db, ids) {
const qs = ids.map((_) => "?").join(",");
const [rows, _] = await db.execute(
@ -8,19 +10,21 @@ async function loadItems(db, ids) {
return rows;
}
async function loadItemTranslation(db, itemId, locale) {
const [
rows,
_,
] = await db.execute(
`SELECT * FROM item_translations WHERE item_id = ? AND locale = ? LIMIT 1`,
[itemId, locale]
);
if (rows.length === 0) {
throw new Error(`could not load translation for ${itemId}, ${locale}`);
}
const buildItemTranslationLoader = (db) =>
new DataLoader(async (itemIds) => {
const qs = itemIds.map((_) => "?").join(",");
const [rows, _] = await db.execute(
`SELECT * FROM item_translations WHERE item_id IN (${qs}) AND locale = "en"`,
itemIds
);
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",
"dependencies": {
"apollo-server": "^2.12.0",
"dataloader": "^2.0.0",
"dotenv": "^8.2.0",
"graphql": "^15.0.0",
"mysql2": "^2.1.0"

View file

@ -1686,6 +1686,11 @@ data-urls@^1.1.0:
whatwg-mimetype "^2.2.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:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"