Convert to transaction function/refactor

- update incorrect variables
This commit is contained in:
mattwr18 2019-12-10 16:35:27 +01:00 committed by roschaefer
parent deefc4e12f
commit 12236c9324
3 changed files with 93 additions and 80 deletions

View File

@ -44,22 +44,29 @@ export default {
} }
const offset = args.offset && typeof args.offset === 'number' ? `SKIP ${args.offset}` : '' const offset = args.offset && typeof args.offset === 'number' ? `SKIP ${args.offset}` : ''
const limit = args.first && typeof args.first === 'number' ? `LIMIT ${args.first}` : '' const limit = args.first && typeof args.first === 'number' ? `LIMIT ${args.first}` : ''
const cypher = `
MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id}) const readTxResultPromise = session.readTransaction(async transaction => {
${whereClause} const notificationsTransactionResponse = await transaction.run(
WITH user, notification, resource, `
[(resource)<-[:WROTE]-(author:User) | author {.*}] as authors, MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id})
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] as posts ${whereClause}
WITH resource, user, notification, authors, posts, WITH user, notification, resource,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} as finalResource [(resource)<-[:WROTE]-(author:User) | author {.*}] as authors,
RETURN notification {.*, from: finalResource, to: properties(user)} [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] as posts
${orderByClause} WITH resource, user, notification, authors, posts,
${offset} ${limit} resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} as finalResource
` RETURN notification {.*, from: finalResource, to: properties(user)}
${orderByClause}
${offset} ${limit}
`,
{ id: currentUser.id },
)
log(notificationsTransactionResponse)
return notificationsTransactionResponse.records.map(record => record.get('notification'))
})
try { try {
const result = await session.run(cypher, { id: currentUser.id }) const notifications = await readTxResultPromise
log(result) return notifications
return result.records.map(r => r.get('notification'))
} finally { } finally {
session.close() session.close()
} }

View File

@ -184,6 +184,7 @@ describe('given some notifications', () => {
data: { data: {
notifications: expect.arrayContaining(expected), notifications: expect.arrayContaining(expected),
}, },
errors: undefined,
}) })
}) })
}) })
@ -233,7 +234,10 @@ describe('given some notifications', () => {
` `
await expect( await expect(
mutate({ mutation: deletePostMutation, variables: { id: 'p3' } }), mutate({ mutation: deletePostMutation, variables: { id: 'p3' } }),
).resolves.toMatchObject({ data: { DeletePost: { id: 'p3', deleted: true } } }) ).resolves.toMatchObject({
data: { DeletePost: { id: 'p3', deleted: true } },
errors: undefined,
})
authenticatedUser = await user.toJson() authenticatedUser = await user.toJson()
} }
@ -242,11 +246,12 @@ describe('given some notifications', () => {
query({ query: notificationQuery, variables: { ...variables, read: false } }), query({ query: notificationQuery, variables: { ...variables, read: false } }),
).resolves.toMatchObject({ ).resolves.toMatchObject({
data: { notifications: [expect.any(Object), expect.any(Object)] }, data: { notifications: [expect.any(Object), expect.any(Object)] },
errors: undefined,
}) })
await deletePostAction() await deletePostAction()
await expect( await expect(
query({ query: notificationQuery, variables: { ...variables, read: false } }), query({ query: notificationQuery, variables: { ...variables, read: false } }),
).resolves.toMatchObject({ data: { notifications: [] } }) ).resolves.toMatchObject({ data: { notifications: [] }, errors: undefined })
}) })
}) })
}) })

View File

@ -13,12 +13,12 @@ const transformReturnType = record => {
export default { export default {
Mutation: { Mutation: {
fileReport: async (_parent, params, context, _resolveInfo) => { fileReport: async (_parent, params, context, _resolveInfo) => {
let createdRelationshipWithNestedAttributes
const { resourceId, reasonCategory, reasonDescription } = params const { resourceId, reasonCategory, reasonDescription } = params
const { driver, user } = context const { driver, user } = context
const session = driver.session() const session = driver.session()
const reportWriteTxResultPromise = session.writeTransaction(async txc => { const reportWriteTxResultPromise = session.writeTransaction(async transaction => {
const cypher = ` const reportTransactionResponse = await transaction.run(
`
MATCH (submitter:User {id: $submitterId}) MATCH (submitter:User {id: $submitterId})
MATCH (resource {id: $resourceId}) MATCH (resource {id: $resourceId})
WHERE resource:User OR resource:Post OR resource:Comment WHERE resource:User OR resource:Post OR resource:Comment
@ -28,33 +28,32 @@ export default {
CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter)
RETURN report, resource, labels(resource)[0] AS type RETURN report, resource, labels(resource)[0] AS type
` `,
const params = { {
resourceId, resourceId,
submitterId: user.id, submitterId: user.id,
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
reasonCategory, reasonCategory,
reasonDescription, reasonDescription,
} },
const reportTransactionResponse = await txc.run(cypher, params) )
log(reportTransactionResponse) log(reportTransactionResponse)
return reportTransactionResponse.records.map(transformReturnType) return reportTransactionResponse.records.map(transformReturnType)
}) })
try { try {
const txResult = await reportWriteTxResultPromise const [createdRelationshipWithNestedAttributes] = await reportWriteTxResultPromise
if (!txResult[0]) return null if (!createdRelationshipWithNestedAttributes) return null
createdRelationshipWithNestedAttributes = txResult[0] return createdRelationshipWithNestedAttributes
} finally { } finally {
session.close() session.close()
} }
return createdRelationshipWithNestedAttributes
}, },
}, },
Query: { Query: {
reports: async (_parent, params, context, _resolveInfo) => { reports: async (_parent, params, context, _resolveInfo) => {
const { driver } = context const { driver } = context
const session = driver.session() const session = driver.session()
let reports, orderByClause, filterClause let orderByClause, filterClause
switch (params.orderBy) { switch (params.orderBy) {
case 'createdAt_asc': case 'createdAt_asc':
orderByClause = 'ORDER BY report.createdAt ASC' orderByClause = 'ORDER BY report.createdAt ASC'
@ -83,35 +82,35 @@ export default {
params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : '' params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : ''
const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : '' const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : ''
const reportReadTxPromise = session.readTransaction(async tx => { const reportReadTxPromise = session.readTransaction(async transaction => {
const cypher = ` const allReportsTransactionResponse = await transaction.run(
MATCH (report:Report)-[:BELONGS_TO]->(resource) `
WHERE (resource:User OR resource:Post OR resource:Comment) MATCH (report:Report)-[:BELONGS_TO]->(resource)
${filterClause} WHERE (resource:User OR resource:Post OR resource:Comment)
WITH report, resource, ${filterClause}
[(submitter:User)-[filed:FILED]->(report) | filed {.*, submitter: properties(submitter)} ] as filed, WITH report, resource,
[(moderator:User)-[reviewed:REVIEWED]->(report) | reviewed {.*, moderator: properties(moderator)} ] as reviewed, [(submitter:User)-[filed:FILED]->(report) | filed {.*, submitter: properties(submitter)} ] as filed,
[(resource)<-[:WROTE]-(author:User) | author {.*} ] as optionalAuthors, [(moderator:User)-[reviewed:REVIEWED]->(report) | reviewed {.*, moderator: properties(moderator)} ] as reviewed,
[(resource)-[:COMMENTS]->(post:Post) | post {.*} ] as optionalCommentedPosts, [(resource)<-[:WROTE]-(author:User) | author {.*} ] as optionalAuthors,
resource {.*, __typename: labels(resource)[0] } as resourceWithType [(resource)-[:COMMENTS]->(post:Post) | post {.*} ] as optionalCommentedPosts,
WITH report, optionalAuthors, optionalCommentedPosts, reviewed, filed, resource {.*, __typename: labels(resource)[0] } as resourceWithType
resourceWithType {.*, post: optionalCommentedPosts[0], author: optionalAuthors[0] } as finalResource WITH report, optionalAuthors, optionalCommentedPosts, reviewed, filed,
RETURN report {.*, resource: finalResource, filed: filed, reviewed: reviewed } resourceWithType {.*, post: optionalCommentedPosts[0], author: optionalAuthors[0] } as finalResource
${orderByClause} RETURN report {.*, resource: finalResource, filed: filed, reviewed: reviewed }
${offset} ${limit} ${orderByClause}
` ${offset} ${limit}
const allReportsTransactionResponse = await tx.run(cypher) `,
)
log(allReportsTransactionResponse) log(allReportsTransactionResponse)
return allReportsTransactionResponse.records.map(record => record.get('report')) return allReportsTransactionResponse.records.map(record => record.get('report'))
}) })
try { try {
const txResult = await reportReadTxPromise const reports = await reportReadTxPromise
if (!txResult[0]) return null if (!reports) return []
reports = txResult return reports
} finally { } finally {
session.close() session.close()
} }
return reports
}, },
}, },
Report: { Report: {
@ -120,23 +119,24 @@ export default {
const session = context.driver.session() const session = context.driver.session()
const { id } = parent const { id } = parent
let filed let filed
const readTxPromise = session.readTransaction(async tx => { const readTxPromise = session.readTransaction(async transaction => {
const cypher = ` const filedReportsTransactionResponse = await transaction.run(
MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id}) `
RETURN filed, submitter MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id})
` RETURN filed, submitter
const params = { id } `,
const allReportsTransactionResponse = await tx.run(cypher, params) { id },
log(allReportsTransactionResponse) )
return allReportsTransactionResponse.records.map(record => ({ log(filedReportsTransactionResponse)
return filedReportsTransactionResponse.records.map(record => ({
submitter: record.get('submitter').properties, submitter: record.get('submitter').properties,
filed: record.get('filed').properties, filed: record.get('filed').properties,
})) }))
}) })
try { try {
const txResult = await readTxPromise const filedReports = await readTxPromise
if (!txResult[0]) return null if (!filedReports) return []
filed = txResult.map(reportedRecord => { filed = filedReports.map(reportedRecord => {
const { submitter, filed } = reportedRecord const { submitter, filed } = reportedRecord
const relationshipWithNestedAttributes = { const relationshipWithNestedAttributes = {
...filed, ...filed,
@ -154,23 +154,24 @@ export default {
const session = context.driver.session() const session = context.driver.session()
const { id } = parent const { id } = parent
let reviewed let reviewed
const readTxPromise = session.readTransaction(async tx => { const readTxPromise = session.readTransaction(async transaction => {
const cypher = ` const reviewedReportsTransactionResponse = await transaction.run(
MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User) `
RETURN moderator, review MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User)
ORDER BY report.updatedAt DESC, review.updatedAt DESC RETURN moderator, review
` ORDER BY report.updatedAt DESC, review.updatedAt DESC
const params = { id } `,
const allReportsTransactionResponse = await tx.run(cypher, params) { id },
log(allReportsTransactionResponse) )
return allReportsTransactionResponse.records.map(record => ({ log(reviewedReportsTransactionResponse)
return reviewedReportsTransactionResponse.records.map(record => ({
review: record.get('review').properties, review: record.get('review').properties,
moderator: record.get('moderator').properties, moderator: record.get('moderator').properties,
})) }))
}) })
try { try {
const txResult = await readTxPromise const reviewedReports = await readTxPromise
reviewed = txResult.map(reportedRecord => { reviewed = reviewedReports.map(reportedRecord => {
const { review, moderator } = reportedRecord const { review, moderator } = reportedRecord
const relationshipWithNestedAttributes = { const relationshipWithNestedAttributes = {
...review, ...review,