From 8994bf41f95b28b21cbb4a6498d46edc55ab11e8 Mon Sep 17 00:00:00 2001 From: Otavio Jacobi Date: Thu, 28 Nov 2024 14:58:44 -0300 Subject: [PATCH] Rewrite service install FKs on balena model Change-type: patch --- src/balena-init.sql | 22 ++++- src/balena-model.ts | 81 +++++++++---------- src/balena.sbvr | 16 +--- ...vice-service-env-var-unique-constraint.sql | 14 ++++ src/translations/v7/v7.ts | 6 +- 5 files changed, 76 insertions(+), 63 deletions(-) create mode 100644 src/migrations/00099-change-device-service-env-var-unique-constraint.sql diff --git a/src/balena-init.sql b/src/balena-init.sql index 1b7bddecc..519caf1b5 100644 --- a/src/balena-init.sql +++ b/src/balena-init.sql @@ -81,10 +81,7 @@ ON "device family" ("is manufactured by-device manufacturer"); -- "device tag"."device" is the first part of an automated unique index --- "device environment variable"."device" is created with the unique index -CREATE UNIQUE INDEX IF NOT EXISTS "device service environment variable_device_service_name_key" -ON "device service environment variable" ("device", "service", "name"); - +-- "device environment variable"."device" is created with the unique index created by the "device service environment variable_device_service_name_key" constraint CREATE INDEX IF NOT EXISTS "device_service_environment_variable_service_idx" ON "device service environment variable" ("service"); @@ -206,3 +203,20 @@ ADD CONSTRAINT "user$M+9koFfMHn7kQFDNBaQZbS7gAvNMB1QkrTtsaVZoETw=" CHECK (NOT ( )); ALTER TABLE "user" ADD UNIQUE ("email"); + +-- This is here temporarily due to a change on the sbvr for device service environment variable +-- in order to keep the database schema in sync with the sbvr +-- and will be removed once we drop the service install column +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'device service environment variable_service install_name_key' + ) THEN + ALTER TABLE "device service environment variable" + ADD CONSTRAINT "device service environment variable_service install_name_key" + UNIQUE ("service install", "name"); + END IF; +END +$$; diff --git a/src/balena-model.ts b/src/balena-model.ts index 788118100..ced1a046f 100644 --- a/src/balena-model.ts +++ b/src/balena-model.ts @@ -600,16 +600,13 @@ export interface Service { >; device__installs__service?: Array; service_install?: Array; - device__installs__application__has__service_name__has__name?: Array< + device__has__application__has__service_name__has__name?: Array< DeviceServiceEnvironmentVariable['Read'] >; - device__installs__service__has__name?: Array< + device__has__service__has__name?: Array< DeviceServiceEnvironmentVariable['Read'] >; - device__installs__service_environment_variable?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - service_install__has__name?: Array< + device__has__service_environment_variable?: Array< DeviceServiceEnvironmentVariable['Read'] >; device_service_environment_variable?: Array< @@ -783,30 +780,27 @@ export interface Device { device_environment_variable?: Array; device__has__config_var_name?: Array; device_config_variable?: Array; - device__has__tag_key?: Array; - device_tag?: Array; - device__installs__image?: Array; - image_install?: Array; - device__installs__application__has__service_name?: Array< - ServiceInstall['Read'] - >; - device__installs__service?: Array; - service_install?: Array; - device__installs__application__has__service_name__has__name?: Array< + device__has__application__has__service_name__has__name?: Array< DeviceServiceEnvironmentVariable['Read'] >; - device__installs__service__has__name?: Array< + device__has__service__has__name?: Array< DeviceServiceEnvironmentVariable['Read'] >; - device__installs__service_environment_variable?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - service_install__has__name?: Array< + device__has__service_environment_variable?: Array< DeviceServiceEnvironmentVariable['Read'] >; device_service_environment_variable?: Array< DeviceServiceEnvironmentVariable['Read'] >; + device__has__tag_key?: Array; + device_tag?: Array; + device__installs__image?: Array; + image_install?: Array; + device__installs__application__has__service_name?: Array< + ServiceInstall['Read'] + >; + device__installs__service?: Array; + service_install?: Array; installs__image?: Array; installs__application__has__service_name?: Array; installs__service?: Array; @@ -941,21 +935,6 @@ export interface ServiceInstall { device: { __id: Device['Read']['id'] } | [Device['Read']]; installs__service: { __id: Service['Read']['id'] } | [Service['Read']]; id: Types['Serial']['Read']; - device__installs__application__has__service_name__has__name?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - device__installs__service__has__name?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - device__installs__service_environment_variable?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - service_install__has__name?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; - device_service_environment_variable?: Array< - DeviceServiceEnvironmentVariable['Read'] - >; application__has__service_name: | { __id: Service['Read']['id'] } | [Service['Read']]; @@ -964,6 +943,18 @@ export interface ServiceInstall { | { __id: Service['Read']['id'] } | [Service['Read']]; is_installed_on__device: { __id: Device['Read']['id'] } | [Device['Read']]; + is_of__device__has__application__has__service_name__has__name?: Array< + DeviceServiceEnvironmentVariable['Read'] + >; + is_of__device__has__service__has__name?: Array< + DeviceServiceEnvironmentVariable['Read'] + >; + is_of__device__has__service_environment_variable?: Array< + DeviceServiceEnvironmentVariable['Read'] + >; + is_of__device_service_environment_variable?: Array< + DeviceServiceEnvironmentVariable['Read'] + >; }; Write: { created_at: Types['Date Time']['Write']; @@ -978,14 +969,14 @@ export interface DeviceServiceEnvironmentVariable { Read: { created_at: Types['Date Time']['Read']; modified_at: Types['Date Time']['Read']; - service_install: - | { __id: ServiceInstall['Read']['id'] } - | [ServiceInstall['Read']]; + device: { __id: Device['Read']['id'] } | [Device['Read']]; + service: { __id: Service['Read']['id'] } | [Service['Read']]; name: Types['Short Text']['Read']; id: Types['Serial']['Read']; value: Types['Text']['Read']; - service: { __id: Service['Read']['id'] } | [Service['Read']]; - device: { __id: Device['Read']['id'] } | [Device['Read']]; + service_install: + | { __id: ServiceInstall['Read']['id'] } + | [ServiceInstall['Read']]; device__installs__application__has__service_name: | { __id: ServiceInstall['Read']['id'] } | [ServiceInstall['Read']]; @@ -999,12 +990,12 @@ export interface DeviceServiceEnvironmentVariable { Write: { created_at: Types['Date Time']['Write']; modified_at: Types['Date Time']['Write']; - service_install: ServiceInstall['Write']['id']; + device: Device['Write']['id']; + service: Service['Write']['id']; name: Types['Short Text']['Write']; id: Types['Serial']['Write']; value: Types['Text']['Write']; - service: Service['Write']['id']; - device: Device['Write']['id']; + service_install: ServiceInstall['Write']['id']; }; } @@ -1329,7 +1320,7 @@ export default interface $Model { device__has__config_var_name: DeviceConfigVariable; device__installs__image: ImageInstall; device__installs__application__has__service_name: ServiceInstall; - device__installs__application__has__service_name__has__name: DeviceServiceEnvironmentVariable; + device__has__application__has__service_name__has__name: DeviceServiceEnvironmentVariable; device__has__tag_key: DeviceTag; release: Release; release__has__tag_key: ReleaseTag; diff --git a/src/balena.sbvr b/src/balena.sbvr index 1ade14cf6..a7ec4f273 100644 --- a/src/balena.sbvr +++ b/src/balena.sbvr @@ -395,9 +395,7 @@ Term: device Term Form: service install Database Table Name: service install - -- Target form for this table is: - -- Fact type: device has service has env var name - Fact type: service install has name (Auth) + Fact type: device has service has name (Auth) Term Form: device service environment variable Database Table Name: device service environment variable @@ -814,16 +812,8 @@ Fact type: image environment variable has value Fact type: device service environment variable has value Necessity: each device service environment variable has exactly one value. -Fact type: device service environment variable has service - -- This is the default name that will be given to the synonymous form - -- once the device service environment variable origin fact type changes - Synonymous form: service has device service environment variable - Necessity: each device service environment variable has exactly one service. -Fact type: device service environment variable has device - -- This is the default name that will be given to the synonymous form - -- once the device service environment variable origin fact type changes - Synonymous form: device has device service environment variable - Necessity: each device service environment variable has exactly one device. +Fact type: device service environment variable has service install + Necessity: each device service environment variable has exactly one service install. -- application tag diff --git a/src/migrations/00099-change-device-service-env-var-unique-constraint.sql b/src/migrations/00099-change-device-service-env-var-unique-constraint.sql new file mode 100644 index 000000000..675e7d74a --- /dev/null +++ b/src/migrations/00099-change-device-service-env-var-unique-constraint.sql @@ -0,0 +1,14 @@ +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'device service environment variable_device_service_name_key' + ) THEN + ALTER TABLE "device service environment variable" + ADD CONSTRAINT "device service environment variable_device_service_name_key" + -- see migration 00095 which adds the index already on ("device", "service", "name") + UNIQUE USING INDEX "device service environment variable_device_service_name_key"; + END IF; +END +$$; diff --git a/src/translations/v7/v7.ts b/src/translations/v7/v7.ts index 823543bd3..a897721ea 100644 --- a/src/translations/v7/v7.ts +++ b/src/translations/v7/v7.ts @@ -19,5 +19,9 @@ overrideFieldType(v7AbstractSqlModel, 'release', 'version', 'JSON'); userHasDirectAccessToApplication.addToModel(v7AbstractSqlModel); // eslint-disable-next-line @typescript-eslint/no-unused-vars -- So that the interface is already well defined. export const getV7Translations = (_abstractSqlModel = v7AbstractSqlModel) => { - return {} satisfies ConfigLoader.Model['translations']; + return { + 'device-installs-application-has-service name-has-name': { + $toResource: 'device-has-application-has-service name-has-name', + }, + } satisfies ConfigLoader.Model['translations']; };