diff --git a/services/api-db/docker-entrypoint-initdb.d/00-tables.sql b/services/api-db/docker-entrypoint-initdb.d/00-tables.sql index 3dbdac8a51..c28d50de9d 100644 --- a/services/api-db/docker-entrypoint-initdb.d/00-tables.sql +++ b/services/api-db/docker-entrypoint-initdb.d/00-tables.sql @@ -259,6 +259,7 @@ CREATE TABLE IF NOT EXISTS task_file ( CREATE TABLE IF NOT EXISTS environment_fact ( id int NOT NULL auto_increment PRIMARY KEY, environment int REFERENCES environment (id), + service varchar(300) NULL, name varchar(300) NOT NULL, value varchar(300) NOT NULL, type ENUM('TEXT', 'URL', 'SEMVER') DEFAULT 'TEXT', @@ -267,7 +268,7 @@ CREATE TABLE IF NOT EXISTS environment_fact ( created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, category TEXT NULL DEFAULT '', key_fact TINYINT(1) NOT NULL DEFAULT(0), - UNIQUE(environment, name) + CONSTRAINT environment_fact UNIQUE(environment, name, source) ); CREATE TABLE IF NOT EXISTS environment_fact_reference ( diff --git a/services/api-db/docker-entrypoint-initdb.d/01-migrations.sql b/services/api-db/docker-entrypoint-initdb.d/01-migrations.sql index 1c14e2af26..5f466850ff 100644 --- a/services/api-db/docker-entrypoint-initdb.d/01-migrations.sql +++ b/services/api-db/docker-entrypoint-initdb.d/01-migrations.sql @@ -1094,6 +1094,39 @@ CREATE OR REPLACE PROCEDURE END; $$ +CREATE OR REPLACE PROCEDURE + update_unique_environment_fact() + + BEGIN + IF EXISTS( + SELECT null FROM INFORMATION_SCHEMA.STATISTICS WHERE + TABLE_NAME = 'environment_fact' and INDEX_NAME = 'environment' + ) THEN + ALTER TABLE `environment_fact` + DROP INDEX `environment`; + ALTER TABLE `environment_fact` ADD CONSTRAINT environment_fact_unique UNIQUE(environment, name, source); + END IF; + END; +$$ + +CREATE OR REPLACE PROCEDURE + add_service_to_environment_fact() + + BEGIN + IF NOT EXISTS( + SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE + table_name = 'environment_fact' + AND table_schema = 'infrastructure' + AND column_name = 'service' + ) THEN + ALTER TABLE `environment_fact` + ADD `service` varchar(300) NULL; + END IF; + END; +$$ + CREATE OR REPLACE PROCEDURE update_user_password() @@ -1585,6 +1618,8 @@ CALL add_fact_source_and_description_to_environment_fact(); CALL add_fact_type_to_environment_fact(); CALL add_fact_category_to_environment_fact(); CALL add_fact_key_to_environment_fact(); +CALL update_unique_environment_fact(); +CALL add_service_to_environment_fact(); CALL add_metadata_to_project(); CALL add_content_type_to_project_notification(); CALL convert_project_production_routes_to_text(); diff --git a/services/api/src/resources/fact/resolvers.ts b/services/api/src/resources/fact/resolvers.ts index 718cd0faf2..cc2134daf5 100644 --- a/services/api/src/resources/fact/resolvers.ts +++ b/services/api/src/resources/fact/resolvers.ts @@ -127,7 +127,7 @@ export const getEnvironmentsByFactSearch: ResolverFn = async ( export const addFact: ResolverFn = async ( root, - { input: { id, environment: environmentId, name, value, source, description, type, category, keyFact } }, + { input: { id, environment: environmentId, name, value, source, description, type, category, keyFact, service } }, { sqlClientPool, hasPermission, userActivityLogger } ) => { const environment = await environmentHelpers( @@ -148,7 +148,8 @@ export const addFact: ResolverFn = async ( description, type, keyFact, - category + category, + service }), ); @@ -166,7 +167,8 @@ export const addFact: ResolverFn = async ( name, value, source, - description + description, + service } } }); @@ -199,7 +201,7 @@ export const addFacts: ResolverFn = async ( const returnFacts = []; for (let i = 0; i < facts.length; i++) { - const { environment, name, value, source, description, type, category, keyFact } = facts[i]; + const { environment, name, value, source, description, type, category, keyFact, service } = facts[i]; const { insertId } = await query( @@ -212,7 +214,8 @@ export const addFacts: ResolverFn = async ( description, type, keyFact, - category + category, + service }), ); diff --git a/services/api/src/resources/fact/sql.ts b/services/api/src/resources/fact/sql.ts index 2773bb876b..1908719edb 100644 --- a/services/api/src/resources/fact/sql.ts +++ b/services/api/src/resources/fact/sql.ts @@ -10,7 +10,8 @@ const standardFactReturn = { description: 'description', type: 'type', category: 'category', - keyFact: 'keyFact' + keyFact: 'keyFact', + service: 'service', }; export const Sql = { @@ -37,8 +38,8 @@ export const Sql = { return q.orderBy('f.id', 'asc').toString() }, - insertFact: ({ environment, name, value, source, description, type, category, keyFact }) => - knex('environment_fact').insert({ environment, name, value, source, description, type, category, keyFact }).toString(), + insertFact: ({ environment, name, value, source, description, type, category, keyFact, service }) => + knex('environment_fact').insert({ environment, name, value, source, description, type, category, keyFact, service }).toString(), deleteFact: (environment, name) => knex('environment_fact') .where({ diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index 0d3f998424..0f39ac05e0 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -267,6 +267,7 @@ const typeDefs = gql` type: FactType category: String references: [FactReference] + service: String } input AddFactInput { @@ -279,6 +280,7 @@ const typeDefs = gql` keyFact: Boolean type: FactType category: String + service: String } input AddFactsInput { @@ -294,6 +296,7 @@ const typeDefs = gql` keyFact: Boolean type: FactType category: String + service: String } input UpdateFactInput {