Skip to content

Commit

Permalink
copy collection now uses transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratatinator97 committed Apr 15, 2024
1 parent 09bab29 commit 02e108d
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 85 deletions.
5 changes: 2 additions & 3 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export class AuthController {
await this.collectionService.createSider(user);
if (createUserDto.publicBundleId) {
const publicBundleCollection: Collection = await this.collectionService.getCollectionById(createUserDto.publicBundleId, user);
const pictoIdsFromBundle: number[] = await Promise.all(publicBundleCollection?.pictos.map(async (picto) => await this.collectionService.copyPicto(rootId, picto, user)));
const collectionIdsFromBundle: number[] = await Promise.all(publicBundleCollection?.collections.map(async (collection) => await this.collectionService.copyCollection(rootId, collection.id, user)))
const pictoIdsFromBundle: number[] = await Promise.all(publicBundleCollection?.pictos.map(async (picto) => this.collectionService.copyPicto(rootId, picto, user)));
const collectionIdsFromBundle: number[] = await Promise.all(publicBundleCollection?.collections.map(async (collection) => this.collectionService.copyCollectionWithTransaction(rootId, collection.id, user)));
const modifyCollectionDto : modifyCollectionDto = {
meaning : null,
speech : null,
Expand All @@ -52,7 +52,6 @@ export class AuthController {
const multipleShareCollectionDto: multipleShareCollectionDto = { access: 1, usernames: user.directSharers, role: 'editor'}
await this.collectionService.shareCollectionVerification(rootId, user, multipleShareCollectionDto);
}
console.log(await this.collectionService.getCollectionById(rootId, user))
return;
}

Expand Down
22 changes: 3 additions & 19 deletions src/collection/collection.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,9 @@ export class CollectionController {
@UseGuards(AuthGuard())
@Post('copy')
@ApiOperation({summary : 'copy a collection with its ID'})
async copyCollection(@Body() copyCollectionDto: copyCollectionDto, @GetUser() user: User): Promise<Collection>{
// const fatherCollection = await this.collectionService.getCollectionById(copyCollectionDto.fatherCollectionId, user);
// const copiedId = await this.collectionService.copyCollection(copyCollectionDto.fatherCollectionId, copyCollectionDto.collectionId, user);
// let fatherCollectionsIds = fatherCollection.collections.map(collection => {
// return collection.id;
// })
// fatherCollectionsIds.push(copiedId);
// const modifyCollectionDto : modifyCollectionDto = {
// meaning : null,
// speech : null,
// pictoIds : null,
// priority : 10,
// color : null,
// collectionIds : fatherCollectionsIds,
// pictohubId: null
// }
// await this.collectionService.modifyCollection(copyCollectionDto.fatherCollectionId, user, modifyCollectionDto, null);
// return this.getCollectionById(copyCollectionDto.fatherCollectionId, user);
return await this.collectionService.copyCollectionWithTransaction(copyCollectionDto.fatherCollectionId, copyCollectionDto.collectionId, user);
async copyCollection(@Body() copyCollectionDto: copyCollectionDto, @GetUser() user: User): Promise<Collection>{
await this.collectionService.copyCollectionWithTransaction(copyCollectionDto.fatherCollectionId, copyCollectionDto.collectionId, user);
return this.getCollectionById(copyCollectionDto.fatherCollectionId, user);
}

@UseGuards(AuthGuard())
Expand Down
5 changes: 3 additions & 2 deletions src/collection/collection.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class CollectionRepository extends Repository<Collection> {
await collection.save();
}
else {
await manager.save(collection);
await manager.save(Collection, collection);
}
} catch (error) {
throw new InternalServerErrorException(error);
Expand Down Expand Up @@ -134,9 +134,10 @@ export class CollectionRepository extends Repository<Collection> {
if (!manager) {
await collection.save();
} else {
await manager.save(collection);
await manager.save(Collection, collection);
}
} catch (error) {
console.error(error);
throw new InternalServerErrorException(
`could not save collection properly`,
);
Expand Down
65 changes: 9 additions & 56 deletions src/collection/collection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class CollectionService {
collection = await this.collectionRepository.findOne({ relations: ["pictos", "collections"], where: { id } });
} else {
collection = await manager.findOne(Collection, { relations: ["pictos", "collections"], where: { id } });

}
if (!collection) {
throw new NotFoundException(`Collection with ID '${id}' not found`);
Expand Down Expand Up @@ -137,7 +138,7 @@ export class CollectionService {
const collection = await this.getCollectionById(id, user, manager);
const index = collection.editors.indexOf(user.username);
if (collection.userId === user.id || index != -1) {
modifyCollectionDto = await this.verifyOwnership(modifyCollectionDto, user);
modifyCollectionDto = await this.verifyOwnership(modifyCollectionDto, user, manager);
if (collection.public) {
const admins = await this.authService.admins();
admins.map(async (admin) => {
Expand Down Expand Up @@ -268,7 +269,7 @@ export class CollectionService {
async getPublicCollection(SearchCollectionDto: SearchCollectionDto): Promise<Collection[]> {
return this.collectionRepository.getPublicCollections(SearchCollectionDto);
}
async copyCollectionWithTransaction(fatherId: number, collectionId: number, user: User): Promise<Collection> {
async copyCollectionWithTransaction(fatherId: number, collectionId: number, user: User): Promise<number> {
return await this.collectionRepository.manager.transaction(async manager => {
const fatherCollection = await this.getCollectionById(fatherId, user, manager);
const copiedId = await this.copyCollectionRecursive(fatherId, collectionId, user, manager);
Expand All @@ -279,21 +280,21 @@ export class CollectionService {
const modifyCollectionDto: modifyCollectionDto = {
meaning: null,
speech: null,
pictoIds: null,
pictoIds: undefined,
priority: 10,
color: null,
collectionIds: fatherCollectionsIds,
pictohubId: null
}
await this.modifyCollection(fatherId, user, modifyCollectionDto, null, manager);
return this.getCollectionById(fatherId, user, manager);
return copiedId;
});
}
async copyCollectionRecursive(fatherId: number, collectionId: number, user: User, entityManager: EntityManager): Promise<number> {
try {
const collection = await entityManager.findOne(Collection, {
where: { id: collectionId },
relations: ['collections', 'pictos'],
relations: ["pictos", "collections"],
});
if (collection) {
const createCollectionDto = {
Expand All @@ -302,7 +303,7 @@ export class CollectionService {
color: collection.color,
pictohubId: null,
collectionIds: await Promise.all(collection.collections.map(child => this.copyCollectionRecursive(collection.id, child.id, user, entityManager))),
pictoIds: await Promise.all(collection.pictos.map(picto => this.copyPictotransaction(collection.id, picto, user, entityManager))),
pictoIds: await Promise.all(collection.pictos.map(picto => this.copyPicto(collection.id, picto, user, entityManager))),
fatherCollectionId: fatherId,
share: 0,
userId: user.id,
Expand All @@ -316,28 +317,7 @@ export class CollectionService {
throw new InternalServerErrorException(`couldn't copy Collection`);
}
}
async copyPictotransaction(fatherId: number, picto: Picto, user: User, entityManager: EntityManager): Promise<number> {
const editor = picto.editors.indexOf(user.username);
const viewer = picto.viewers.indexOf(user.username);
if (picto.userId === user.id || editor !== -1 || viewer !== -1 || picto.public) {
const createPictoDto = {
meaning: picto.meaning,
speech: picto.speech,
color: picto.color,
collectionIds: null,
fatherCollectionId: fatherId,
share: 1,
pictohubId: null,
userId: user.id,
image: picto.image,
};
const copiedPicto = await entityManager.save(Picto, createPictoDto);
return copiedPicto.id;
} else {
return null;
}
}
async copyPicto(fatherId: number, picto: Picto, user: User): Promise<number> {
async copyPicto(fatherId: number, picto: Picto, user: User, manager?: EntityManager): Promise<number> {
const editor = picto.editors.indexOf(user.username);
const viewer = picto.viewers.indexOf(user.username);
if (picto.userId === user.id || editor != -1 || viewer != -1 || picto.public) {
Expand All @@ -350,40 +330,13 @@ export class CollectionService {
share: 1,
pictohubId: null,
}
const copiedPicto = await this.pictoService.createPicto(createPictoDto, user, picto.image);
const copiedPicto = await this.pictoService.createPicto(createPictoDto, user, picto.image, manager);
return copiedPicto.id;
} else {
return null;
}
}

async copyCollection(fatherId: number, collectionId: number, user: User): Promise<number> {
try {
const collection = await this.getCollectionById(collectionId, user);
if (collection) {
const createCollectionDto: createCollectionDto = {
meaning: collection.meaning,
speech: collection.speech,
color: collection.color,
pictohubId: null,
collectionIds: await Promise.all(collection.collections.map(child => { return this.copyCollection(collection.id, child.id, user); })),
pictoIds: await Promise.all(collection.pictos.map(child => { return this.copyPicto(collection.id, child, user); })),
fatherCollectionId: fatherId,
share: 0,
}
const copiedCollection = await this.createCollection(createCollectionDto, user, collection.image);
return copiedCollection.id;
}
} catch (error) {
if (error.status == "401" || error.status == "404") {
return null;
} else {
console.log(error);
throw new InternalServerErrorException(`couldn't copy Collection`);
}
}
}

async moveToCollection(user: User, moveToCollectionDto: MoveToCollectionDto, fatherCollectionId: number): Promise<Collection> {
// this ugly ass looking code implicitly checks if user has access to said ressources when we run getByID
const targetCollection = await this.getCollectionById(moveToCollectionDto.targetCollectionId, user);
Expand Down
9 changes: 7 additions & 2 deletions src/picto/picto.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Picto } from 'src/entities/picto.entity';
import { User } from 'src/entities/user.entity';
import { parseNumberArray } from 'src/utilities/tools';
import { CustomRepository } from 'src/utilities/typeorm-ex.decorator';
import { Repository } from 'typeorm';
import { EntityManager, Repository } from 'typeorm';
import { createPictoDto } from './dto/picto.create.dto';
import { modifyPictoDto } from './dto/picto.modify.dto';
import { sharePictoDto } from './dto/picto.share.dto';
Expand All @@ -15,6 +15,7 @@ export class PictoRepository extends Repository<Picto> {
createPictoDto: createPictoDto,
user: User,
filename: string,
manager?: EntityManager
): Promise<Picto> {
let { meaning, speech, collectionIds, color, pictohubId } = createPictoDto;
const picto = new Picto();
Expand Down Expand Up @@ -43,7 +44,11 @@ export class PictoRepository extends Repository<Picto> {
);
}
try {
await picto.save();
if (!manager) {
await picto.save();
} else {
await manager.save(Picto, picto);
}
} catch (error) {
throw new InternalServerErrorException(error);
}
Expand Down
6 changes: 3 additions & 3 deletions src/picto/picto.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class PictoService {

async getPictoById(id: number, user : User, manager?: EntityManager): Promise<Picto>{
let picto: Picto;
if (manager){
if (!manager){
picto = await this.pictoRepository.findOne({where : {id}});
} else {
picto = await manager.findOne(Picto,{where : {id}, relations: ["collections"]});
Expand Down Expand Up @@ -83,8 +83,8 @@ export class PictoService {
return found;
}

async createPicto(createPictoDto: createPictoDto, user: User, filename: string): Promise<Picto> {
return this.pictoRepository.createPicto(createPictoDto, user, filename);
async createPicto(createPictoDto: createPictoDto, user: User, filename: string, manager?: EntityManager): Promise<Picto> {
return this.pictoRepository.createPicto(createPictoDto, user, filename, manager);
}

async deletePicto(deletePictoDto: deletePictoDto, user: User): Promise<void> {
Expand Down

0 comments on commit 02e108d

Please sign in to comment.