Skip to content

Expose #deleteFromCacheByFields #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,9 @@ this.findByFields({
`this.deleteFromCacheById(id)`

Deletes a document from the cache that was fetched with `findOneById` or `findManyByIds`.

### deleteFromCacheByFields

`this.deleteFromCacheByFields(fields)`

Deletes a document from the cache that was fetched with `findByFields`. Fields should be passed in exactly the same way they were used to find with.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@ declare module 'apollo-datasource-mongodb' {
): Promise<(TData | null | undefined)[]>

deleteFromCacheById(id: ObjectId | string): Promise<void>
deleteFromCacheByFields(fields: Fields): Promise<void>
}
}
27 changes: 21 additions & 6 deletions src/__tests__/cache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ describe('createCachingMethods', () => {
it('adds the right methods', () => {
expect(api.findOneById).toBeDefined()
expect(api.findManyByIds).toBeDefined()
expect(api.findByFields).toBeDefined()
expect(api.deleteFromCacheById).toBeDefined()

expect(api.findByFields).toBeDefined()
expect(api.deleteFromCacheByFields).toBeDefined()
})

it('finds one with ObjectId', async () => {
Expand Down Expand Up @@ -171,7 +173,7 @@ describe('createCachingMethods', () => {
expect(collection.find.mock.calls.length).toBe(1)
})

it('finds by mutiple fields', async () => {
it('finds by multiple fields', async () => {
const foundDocs = await api.findByFields({
tags: ['foo', 'bar'],
foo: 'bar'
Expand Down Expand Up @@ -222,7 +224,7 @@ describe('createCachingMethods', () => {
expect(value).toBeUndefined()
})

it(`caches`, async () => {
it(`caches by ID`, async () => {
await api.findOneById(docs.one._id, { ttl: 1 })
const value = await cache.get(cacheKeyById(docs.one._id))
expect(value).toEqual(EJSON.stringify(docs.one))
Expand All @@ -241,15 +243,15 @@ describe('createCachingMethods', () => {
expect(collection.find.mock.calls.length).toBe(1)
})

it(`caches with ttl`, async () => {
it(`caches ID with ttl`, async () => {
await api.findOneById(docs.one._id, { ttl: 1 })
await wait(1001)

const value = await cache.get(cacheKeyById(docs.one._id))
expect(value).toBeUndefined()
})

it(`deletes from cache`, async () => {
it(`deletes from cache by ID`, async () => {
for (const doc of [docs.one, docs.two, stringDoc]) {
await api.findOneById(doc._id, { ttl: 1 })

Expand All @@ -263,7 +265,7 @@ describe('createCachingMethods', () => {
}
})

it('deletes from DataLoader cache', async () => {
it('deletes from DataLoader cache by ID', async () => {
for (const id of [docs.one._id, docs.two._id, stringDoc._id]) {
await api.findOneById(id)
expect(collection.find).toHaveBeenCalled()
Expand All @@ -277,6 +279,19 @@ describe('createCachingMethods', () => {
expect(collection.find).toHaveBeenCalled()
}
})

it(`deletes from cache by fields`, async () => {
const fields = { foo: 'bar' }
await api.findByFields(fields, { ttl: 1 })

const valueBefore = await cache.get(cacheKeyByFields(fields))
expect(valueBefore).toEqual(EJSON.stringify([docs.one, docs.two]))

await api.deleteFromCacheByFields(fields)

const valueAfter = await cache.get(cacheKeyByFields(fields))
expect(valueAfter).toBeUndefined()
})
})

describe('isValidObjectIdString', () => {
Expand Down
3 changes: 3 additions & 0 deletions src/__tests__/datasource.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ describe('MongoDataSource', () => {
const source = new Users(users)
source.initialize()
expect(source.findOneById).toBeDefined()
expect(source.findByFields).toBeDefined()
expect(source.deleteFromCacheById).toBeDefined()
expect(source.deleteFromCacheByFields).toBeDefined()
expect(source.collection).toEqual(users)
})
})
Expand Down
19 changes: 19 additions & 0 deletions src/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,25 @@ export const createCachingMethods = ({ collection, model, cache }) => {
deleteFromCacheById: async id => {
loader.clear(JSON.stringify({ id }))
await cache.delete(cachePrefix + idToString(id))
},
deleteFromCacheByFields: async fields => {
const cleanedFields = {}

Object.keys(fields)
.sort()
.forEach(key => {
if (typeof key !== 'undefined') {
cleanedFields[key] = Array.isArray(fields[key])
? fields[key]
: [fields[key]]
}
})

const loaderJSON = JSON.stringify(cleanedFields)

const key = cachePrefix + loaderJSON
loader.clear(loaderJSON)
await cache.delete(key)
}
}

Expand Down