Skip to content

Commit

Permalink
Update diet
Browse files Browse the repository at this point in the history
  • Loading branch information
chrbala committed Sep 12, 2020
1 parent 14798aa commit 9e139a3
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 41 deletions.
95 changes: 63 additions & 32 deletions packages/graphql-api/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, TableType } from './types';
import { Context, TableType, Diet } from './types';
import {
BackendPlant,
BackendAnimal,
Expand Down Expand Up @@ -65,19 +65,10 @@ const createTable = <T>(
};
};

const getDiet = async (id: string) => {
const outEdges = database.diets.outEdges(id);
const inEdges = database.diets.inEdges(id);

if (!outEdges || !inEdges) return Promise.reject(new Error('not_found'));

const diet = outEdges.map(({ w }) => w);
const eatenBy = inEdges.map(({ v }) => v);

return { diet, eatenBy };
};

const idsAreValid = (ids: Array<string>, context: Context): Promise<boolean> =>
const idsAreValid = (
ids: Array<string>,
context: Pick<Context, 'plant' | 'animal'>
): Promise<boolean> =>
Promise.all(
ids.map(async id => {
const res = await parse(ID, id);
Expand All @@ -93,6 +84,61 @@ const idsAreValid = (ids: Array<string>, context: Context): Promise<boolean> =>
() => false
);

const createDiet = (ctx: Pick<Context, 'plant' | 'animal'>) => {
const getDiet = async (id: string) => {
const outEdges = database.diets.outEdges(id);
const inEdges = database.diets.inEdges(id);

if (!outEdges || !inEdges) return Promise.reject(new Error('not_found'));

const diet = outEdges.map(({ w }) => w);
const eatenBy = inEdges.map(({ v }) => v);

return { diet, eatenBy };
};

const setDiet = async (id: string, diets: Diet) => {
const allIds = [id, ...diets.diet, ...diets.eatenBy];
if (!idsAreValid(allIds, ctx)) return Promise.reject('not_found');

if (!database.diets.hasNode(id)) database.diets.setNode(id);

diets.diet.forEach(outEdge => database.diets.setEdge(id, outEdge));
diets.eatenBy.forEach(inEdge => database.diets.setEdge(inEdge, id));

return getDiet(id);
};

const updateDiet = async (
id: string,
diets: Partial<Diet>
): Promise<Diet> => {
const allIds = [id, ...(diets.diet ?? []), ...(diets.eatenBy ?? [])];
if (!idsAreValid(allIds, ctx)) return Promise.reject('not_found');

if (!database.diets.hasNode(id)) database.diets.setNode(id);

const inEdges = database.diets.inEdges(id);
if (inEdges && diets.eatenBy)
inEdges.forEach(e => database.diets.removeEdge(e));

const outEdges = database.diets.outEdges(id);
if (outEdges && diets.diet)
outEdges.forEach(e => database.diets.removeEdge(e));

return setDiet(id, {
diet: diets.diet ?? [],
eatenBy: diets.eatenBy ?? [],
});
};

return {
get: getDiet,
set: setDiet,
update: updateDiet,
};
};

export const context = (): Context => {
const Plants = createTable(
database.plants,
Expand All @@ -105,24 +151,9 @@ export const context = (): Context => {
BackendAnimalPatchInput
);

const ctx: Context = {
return {
plant: Plants,
animal: Animals,
diet: {
get: getDiet,
set: async (id, diets) => {
const allIds = [id, ...diets.diet, ...diets.eatenBy];
if (!idsAreValid(allIds, ctx)) return Promise.reject('not_found');

if (!database.diets.hasNode(id)) database.diets.setNode(id);

diets.diet.forEach(outEdge => database.diets.setEdge(id, outEdge));
diets.eatenBy.forEach(inEdge => database.diets.setEdge(inEdge, id));

return getDiet(id);
},
},
};

return ctx;
diet: createDiet({ plant: Plants, animal: Animals }),
} as Context;
};
24 changes: 15 additions & 9 deletions packages/graphql-api/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,17 @@ export const resolvers = {

const globalId = toGlobalId(id);

if (input.__typename === 'Animal') {
if (input.__typename === 'Animal')
await context.diet.set(globalId, {
diet: input.diet,
eatenBy: input.eatenBy,
});
}

if (input.__typename === 'Plant') {
if (input.__typename === 'Plant')
await context.diet.set(globalId, {
diet: [],
eatenBy: input.eatenBy,
});
}

return {
__typename: 'AddLivingThingPayload',
Expand All @@ -154,15 +152,23 @@ export const resolvers = {

const { id, patch } = res.data.input;

const [table, typename] =
id.table === Table.Animal
? [context.animal, 'Animal']
: [context.plant, 'Plant'];
const table = id.table === Table.Animal ? context.animal : context.plant;
const updated = await table.update(id.id, patch);

if (patch.__typename === 'Animal')
await context.diet.update(id.serialized, {
diet: patch.diet,
eatenBy: patch.eatenBy,
});

if (patch.__typename === 'Plant')
await context.diet.update(id.serialized, {
eatenBy: patch.eatenBy,
});

return {
__typename: 'UpdateLivingThingPayload',
node: { __typename: typename, id: id.serialized, ...updated },
node: { __typename: patch.__typename, id: id.serialized, ...updated },
};
},
deleteLivingThing: async (
Expand Down
1 change: 1 addition & 0 deletions packages/graphql-api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export type Context = {
diet: {
get: (id: string) => Promise<Diet>;
set: (id: string, diet: Diet) => Promise<Diet>;
update: (id: string, diet: Partial<Diet>) => Promise<Diet>;
};
};

0 comments on commit 9e139a3

Please sign in to comment.