diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index fcf15e03af..b4aa397883 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -24,6 +24,7 @@ "helmet": "^3.22.0", "knex": "^0.21.1", "morgan": "^1.10.0", + "sqlite3": "^4.2.0", "uuid": "^8.0.0", "winston": "^3.2.1", "yaml": "^1.9.2", diff --git a/plugins/catalog-backend/src/database/Database.test.ts b/plugins/catalog-backend/src/database/Database.test.ts index c375d13fdb..5660d4ae35 100644 --- a/plugins/catalog-backend/src/database/Database.test.ts +++ b/plugins/catalog-backend/src/database/Database.test.ts @@ -59,4 +59,20 @@ describe('Database', () => { /Found no location/, ); }); + + it('instead of adding second location with the same target, returns existing one', async () => { + // Prepare + const catalog = new Database(database); + const input: AddDatabaseLocation = { type: 'a', target: 'b' }; + const output1: DatabaseLocation = await catalog.addLocation(input); + + // Try to insert the same location + const output2: DatabaseLocation = await catalog.addLocation(input); + const locations = await catalog.locations(); + + // Output is the same + expect(output2).toEqual(output1); + // Locations contain only one record + expect(locations).toEqual([output1]); + }); }); diff --git a/plugins/catalog-backend/src/database/Database.ts b/plugins/catalog-backend/src/database/Database.ts index ed11f091fe..39e075efb8 100644 --- a/plugins/catalog-backend/src/database/Database.ts +++ b/plugins/catalog-backend/src/database/Database.ts @@ -60,14 +60,29 @@ export class Database { } async addLocation(location: AddDatabaseLocation): Promise { - const id = uuidv4(); - const { type, target } = location; - await this.database('locations').insert({ - id, - type, - target, + return await this.database.transaction(async (tx) => { + const existingLocation = await tx('locations') + .where({ + target: location.target, + }) + .select(); + + if (existingLocation?.[0]) { + return existingLocation[0]; + } + + const id = uuidv4(); + const { type, target } = location; + await tx('locations').insert({ + id, + type, + target, + }); + + return ( + await tx('locations').where({ id }).select() + )![0]; }); - return await this.location(id); } async removeLocation(id: string): Promise {