-
Notifications
You must be signed in to change notification settings - Fork 234
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
Feature/741 b prisma transactions #779
Changes from all commits
2c7b550
2ee473e
e5b56c3
332edfc
daba440
e971b4f
9b37201
2dfbd03
f42a685
eaa2254
03aebdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,13 +3,17 @@ import { InjectMapper } from '@automapper/nestjs'; | |
import { Injectable, NotFoundException } from '@nestjs/common'; | ||
import { WORKFLOW_NOT_FOUND_ERR_MESSAGE } from '../api/err.messages'; | ||
import { Workflow } from '../models/workflow'; | ||
import { BpiAccount, Workflow as WorkflowModel } from '@prisma/client'; | ||
import { PrismaService } from '../../../../shared/prisma/prisma.service'; | ||
import { PrismaPromise } from '@prisma/client'; | ||
import { BpiAccountStorageAgent } from '../../../state/bpiAccounts/agents/bpiAccountsStorage.agent'; | ||
|
||
@Injectable() | ||
export class WorkflowStorageAgent { | ||
constructor( | ||
@InjectMapper() private mapper: Mapper, | ||
private readonly prisma: PrismaService, | ||
private readonly bpiAccountStorageAgent: BpiAccountStorageAgent, | ||
) {} | ||
|
||
async getWorkflowById(id: string): Promise<Workflow | undefined> { | ||
|
@@ -49,14 +53,14 @@ export class WorkflowStorageAgent { | |
}); | ||
} | ||
|
||
async storeNewWorkflow(workflow: Workflow): Promise<Workflow> { | ||
storeNewWorkflow(workflow: Workflow): PrismaPromise<WorkflowModel> { | ||
const workstepIds = workflow.worksteps.map((w) => { | ||
return { | ||
id: w.id, | ||
}; | ||
}); | ||
|
||
const newWorkflowModel = await this.prisma.workflow.create({ | ||
return this.prisma.workflow.create({ | ||
data: { | ||
id: workflow.id, | ||
name: workflow.name, | ||
|
@@ -71,8 +75,6 @@ export class WorkflowStorageAgent { | |
bpiAccount: true, | ||
}, | ||
}); | ||
|
||
return this.mapper.map(newWorkflowModel, Workflow, Workflow); | ||
} | ||
|
||
async updateWorkflow(workflow: Workflow): Promise<Workflow> { | ||
|
@@ -104,4 +106,24 @@ export class WorkflowStorageAgent { | |
where: { id: workflow.id }, | ||
}); | ||
} | ||
|
||
async storeWorkflowTransaction( | ||
bpiAccountCandidate: BpiAccount, | ||
workflowCandidate: Workflow, | ||
): Promise<any> { | ||
const boundStoreNewWorkflow = this.storeNewWorkflow.bind(this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why binding this here? |
||
const boundStoreNewBpiAccount = | ||
this.bpiAccountStorageAgent.storeNewBpiAccount.bind( | ||
this.bpiAccountStorageAgent, | ||
); | ||
const results = await this.prisma.executeTransaction(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are still passing only one operation here, so not quite showing array of sequential operations, it should be array [storeBpiAccount, storeWorkflow], not storeBpiAccount.then(storeWorkflow)? this way it seems we are controlling this execution, and prisma should sequentially execute all or nothing behind the scenes if i understand correctly |
||
return boundStoreNewBpiAccount(bpiAccountCandidate).then( | ||
(newBpiAccount: { id: string }) => { | ||
workflowCandidate.bpiAccountId = newBpiAccount.id; | ||
return boundStoreNewWorkflow(workflowCandidate); | ||
}, | ||
); | ||
}); | ||
return results; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,23 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { PrismaClient } from '@prisma/client'; | ||
import { PrismaClient, PrismaPromise } from '@prisma/client'; | ||
|
||
type DbOperation = () => Promise<any> | PrismaPromise<any>; | ||
|
||
@Injectable() | ||
export class PrismaService extends PrismaClient { | ||
constructor() { | ||
super({ log: ['info'] }); | ||
} | ||
|
||
public async executeTransaction( | ||
...operations: DbOperation[] | ||
): Promise<any[]> { | ||
return await this.$transaction(async () => { | ||
const results: any[] = []; | ||
for (const operation of operations) { | ||
results.push(await operation()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to await operations? |
||
} | ||
return results; | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure i understand changes to this method, could you please add more details?