Skip to content

Commit

Permalink
Fix data loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
thenamankumar committed Jun 5, 2020
1 parent 1114278 commit c1c1d88
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 66 deletions.
4 changes: 2 additions & 2 deletions api/config/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = {
pool: { maxConnections: 5, maxIdleTime: 30 },
language: 'en',
alter: false,
logging: false,
logging: true,
define: {
underscored: true,
underscoredAll: true,
Expand Down Expand Up @@ -48,7 +48,7 @@ module.exports = {
maxConcurrentQueries: 100,
pool: { maxConnections: 5, maxIdleTime: 30 },
language: 'en',
logging: false,
logging: true,
define: {
underscored: true,
underscoredAll: true,
Expand Down
4 changes: 2 additions & 2 deletions api/graphql/query/CalendarEvent/inviteStatus.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const inviteStatus = async (parent, _args, { viewer, loaders }) => {
if (!viewer) return null;

return await loaders.viewerCalendarEventInviteStatus.load({
return await loaders.eventInviteStatus.load({
event_id: parent.id,
viewer,
user_id: viewer.id,
});
};

Expand Down
2 changes: 1 addition & 1 deletion api/graphql/query/CalendarEventInvite/availability.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const availability = async (parent, _args, { loaders }) => {
return loaders.userAvailability.load({
user_id: parent.user_id,
dateTimeRange: { start_at: event.start_at, end_at: event.end_at },
exculdeEvents: [event.id],
excludeEvents: [event.id],
});
};

Expand Down
2 changes: 1 addition & 1 deletion api/graphql/query/User/availability.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const availability = async (parent, { dateTimeRange }, { loaders }) =>
loaders.userAvailability.load({
user_id: parent.id,
dateTimeRange,
exculdeEvents: [],
excludeEvent: [],
});

export default availability;
2 changes: 1 addition & 1 deletion api/routes/graphql/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const server = new ApolloServer({
viewer: req.viewer,
loaders: {
userAvailability: User.getAvailabilityLoader(),
viewerCalendarEventInviteStatus: CalendarEventInvite.getViewerCalendarEventInviteStatusLoader(),
eventInviteStatus: CalendarEventInvite.getStatusLoader(),
},
}),
});
Expand Down
17 changes: 17 additions & 0 deletions api/services/BaseModelService/Loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import DataLoader from 'dataloader';

class BaseLoader {
constructor(keys) {
this.keys = keys;
}
}

BaseLoader.loader = function () {
return () => {
const Loader = this;

return new DataLoader(async (keys) => new Loader(keys).load());
};
};

export default BaseLoader;
20 changes: 20 additions & 0 deletions api/services/CalendarEventInvite/Loaders/InviteStatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Models from 'Models';
import BaseLoader from 'Services/BaseModelService/Loader';

export default class InviteStatus extends BaseLoader {
async load() {
const invites = await Models.CalendarEventInvite.findAll({
where: {
[Models.Sequelize.Op.or]: this.keys.map(({ user_id, event_id }) => ({
user_id,
event_id,
})),
},
});

return this.keys.map(
(key) =>
invites.find((invite) => invite.event_id === key.event_id)?.status,
);
}
}
24 changes: 3 additions & 21 deletions api/services/CalendarEventInvite/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Models from 'Models';
import DataLoader from 'dataloader';
import BaseModelService, {
saveInstance,
requireInstance,
} from 'Services/BaseModelService';
import InviteStatus from './Loaders/InviteStatus';

export default class CalendarEventInvite extends BaseModelService {
static getStatusLoader = InviteStatus.loader();

@saveInstance
async create(body) {
const [invite, created] = await Models.CalendarEventInvite.findOrCreate({
Expand Down Expand Up @@ -57,24 +59,4 @@ export default class CalendarEventInvite extends BaseModelService {

return this.instance;
}

static async findAllCalenderEventInviteStatus(keys) {
return Models.CalendarEventInvite.findAll({
where: {
user_id: keys[0].viewer.id,
event_id: {
[Models.Sequelize.Op.in]: keys.map(({ event_id }) => event_id),
},
},
}).then((invites) =>
keys.map(
(key) =>
invites.find((invite) => invite.event_id === key.event_id)?.status,
),
);
}

static getViewerCalendarEventInviteStatusLoader() {
return new DataLoader(CalendarEventInvite.findAllCalenderEventInviteStatus);
}
}
51 changes: 51 additions & 0 deletions api/services/User/Loaders/Availability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Models from 'Models';
import BaseLoader from 'Services/BaseModelService/Loader';
import overlapDateTimeClause from 'Utils/overlapDateTimeClause';

export default class Availability extends BaseLoader {
load = async () => {
const invites = await Models.CalendarEventInvite.scope('visible').findAll({
include: [
{
model: Models.CalendarEvent,
as: 'event',
where: {
[Models.Sequelize.Op.or]: this.keys.map(
({ user_id, dateTimeRange, excludeEvents = [] }) => ({
[Models.Sequelize.Op.and]: [
{
$user_id$: user_id,
},
{
id: {
[Models.Sequelize.Op.notIn]: excludeEvents,
},
},
overlapDateTimeClause(dateTimeRange),
],
}),
),
},
required: true,
},
],
});

return this.keys.map(
(key) => !invites.find((invite) => this.equateKeyAndInvite(key, invite)),
);
};

equateKeyAndInvite({ user_id, excludedEvents = [], dateTimeRange }, invite) {
if (invite.user_id !== user_id || excludedEvents.includes(invite.event.id))
return false;

if (
new Date(invite.event.start_at) > new Date(dateTimeRange.end_at) ||
new Date(invite.event.end_at) < new Date(dateTimeRange.start_at)
)
return false;

return true;
}
}
41 changes: 4 additions & 37 deletions api/services/User/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import uuid from 'uuid/v4';
import Models from 'Models';
import config from 'Config';
import DataLoader from 'dataloader';
import jwt from 'jsonwebtoken';
import BaseModelService, {
saveInstance,
requireInstance,
} from 'Services/BaseModelService';
import overlapDateTimeClause from 'Utils/overlapDateTimeClause';
import Availability from './Loaders/Availability';

export default class User extends BaseModelService {
static findByUsername(username) {
Expand Down Expand Up @@ -38,48 +37,16 @@ export default class User extends BaseModelService {
}
}

static async findAllAvailabilityDuring(keys) {
return Promise.all(
keys.map(
async (key) =>
!(await Models.CalendarEventInvite.scope('visible').findOne({
where: {
user_id: key.user_id,
},
include: [
{
model: Models.CalendarEvent,
as: 'event',
where: {
[Models.Sequelize.Op.and]: [
overlapDateTimeClause(key.dateTimeRange),
{
id: {
[Models.Sequelize.Op.notIn]: key.exculdeEvents || [],
},
},
],
},
required: true,
},
],
})),
),
);
}

static getAvailabilityLoader() {
return new DataLoader(User.findAllAvailabilityDuring);
}
static getAvailabilityLoader = Availability.loader();

@requireInstance
async ifAvailableDuring(dateTimeRange, exculdeEvents) {
async ifAvailableDuring(dateTimeRange, excludeEvents) {
return (
await User.findAllAvailabilityDuring([
{
user_id: this.instance.id,
dateTimeRange,
exculdeEvents,
excludeEvents,
},
])
)[0];
Expand Down
3 changes: 2 additions & 1 deletion app/modals/EditEvent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import CREATE_INVITE from 'Mutations/calendarEventInvite.graphql';
import DELETE_INVITE from 'Mutations/calendarEventInviteDelete.graphql';
import CREATE_RESOURCE from 'Mutations/resourceCreate.graphql';
import DELETE_RESOURCE from 'Mutations/resourceDelete.graphql';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import { ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';

const EditEvent = ({ loading, onClose, types, event }) => {
const [title, setTitle] = useState(event.title);
Expand Down Expand Up @@ -234,4 +234,5 @@ export default createPage({
Component: EditEvent,
query: QUERY,
variables: ({ id }) => ({ id }),
Layout: null,
});

0 comments on commit c1c1d88

Please sign in to comment.