diff --git a/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql index 0ca3e5f7bb..b8faaedafd 100644 --- a/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql +++ b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql @@ -21,5 +21,5 @@ $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_set_updated_at BEFORE UPDATE ON zitadel.instances FOR EACH ROW -WHEN (NEW.updated_at IS NULL) +WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) EXECUTE FUNCTION zitadel.set_updated_at(); diff --git a/backend/v3/storage/database/dialect/postgres/migration/002_organization_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/002_organization_table/up.sql index 0c1558ceb6..e8b5acef4b 100644 --- a/backend/v3/storage/database/dialect/postgres/migration/002_organization_table/up.sql +++ b/backend/v3/storage/database/dialect/postgres/migration/002_organization_table/up.sql @@ -20,5 +20,5 @@ CREATE UNIQUE INDEX org_unique_instance_id_name_idx CREATE TRIGGER trigger_set_updated_at BEFORE UPDATE ON zitadel.organizations FOR EACH ROW -WHEN (NEW.updated_at IS NULL) +WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) EXECUTE FUNCTION zitadel.set_updated_at(); diff --git a/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql index 1536ffd6d1..fb8ae476b3 100644 --- a/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql +++ b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql @@ -53,14 +53,14 @@ CREATE INDEX idx_org_domain ON zitadel.org_domains(instance_id, domain); CREATE TRIGGER trg_set_updated_at_instance_domains BEFORE UPDATE ON zitadel.instance_domains FOR EACH ROW - WHEN (NEW.updated_at IS NULL) + WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) EXECUTE FUNCTION zitadel.set_updated_at(); -- Trigger to update the updated_at timestamp on org_domains CREATE TRIGGER trg_set_updated_at_org_domains BEFORE UPDATE ON zitadel.org_domains FOR EACH ROW - WHEN (NEW.updated_at IS NULL) + WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) EXECUTE FUNCTION zitadel.set_updated_at(); -- Function to check for already verified org domains diff --git a/internal/query/projection/instance_domain_relational.go b/internal/query/projection/instance_domain_relational.go index 0c8f0c597c..0deb4e82a4 100644 --- a/internal/query/projection/instance_domain_relational.go +++ b/internal/query/projection/instance_domain_relational.go @@ -89,13 +89,24 @@ func (p *instanceDomainRelationalProjection) reduceDomainPrimarySet(event events return zerrors.ThrowInvalidArgumentf(nil, "HANDL-QnjHo", "reduce.wrong.db.pool %T", ex) } domainRepo := repository.InstanceRepository(v3_sql.SQLTx(tx)).Domains(false) + + condition := database.And( + domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), + domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), + domainRepo.TypeCondition(domain.DomainTypeCustom), + ) + _, err := domainRepo.Update(ctx, - database.And( - domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), - domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), - domainRepo.TypeCondition(domain.DomainTypeCustom), - ), + condition, domainRepo.SetPrimary(), + ) + if err != nil { + return err + } + // we need to split the update into two statements because multiple events can have the same creation date + // therefore we first do not set the updated_at timestamp + _, err = domainRepo.Update(ctx, + condition, domainRepo.SetUpdatedAt(e.CreationDate()), ) return err diff --git a/internal/query/projection/org_domain_relational.go b/internal/query/projection/org_domain_relational.go index 558c119b33..747a21a2cb 100644 --- a/internal/query/projection/org_domain_relational.go +++ b/internal/query/projection/org_domain_relational.go @@ -86,13 +86,22 @@ func (p *orgDomainRelationalProjection) reducePrimarySet(event eventstore.Event) return zerrors.ThrowInvalidArgumentf(nil, "HANDL-h6xF0", "reduce.wrong.db.pool %T", ex) } domainRepo := repository.OrganizationRepository(v3_sql.SQLTx(tx)).Domains(false) + condition := database.And( + domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), + domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), + domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), + ) _, err := domainRepo.Update(ctx, - database.And( - domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), - domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), - domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), - ), + condition, domainRepo.SetPrimary(), + ) + if err != nil { + return err + } + // we need to split the update into two statements because multiple events can have the same creation date + // therefore we first do not set the updated_at timestamp + _, err = domainRepo.Update(ctx, + condition, domainRepo.SetUpdatedAt(e.CreationDate()), ) return err @@ -141,13 +150,23 @@ func (p *orgDomainRelationalProjection) reduceVerificationAdded(event eventstore return zerrors.ThrowInvalidArgumentf(nil, "HANDL-yF03i", "reduce.wrong.db.pool %T", ex) } domainRepo := repository.OrganizationRepository(v3_sql.SQLTx(tx)).Domains(false) + condition := database.And( + domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), + domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), + domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), + ) + _, err := domainRepo.Update(ctx, - database.And( - domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), - domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), - domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), - ), + condition, domainRepo.SetValidationType(validationType), + ) + if err != nil { + return err + } + // we need to split the update into two statements because multiple events can have the same creation date + // therefore we first do not set the updated_at timestamp + _, err = domainRepo.Update(ctx, + condition, domainRepo.SetUpdatedAt(e.CreationDate()), ) return err @@ -165,15 +184,27 @@ func (p *orgDomainRelationalProjection) reduceVerified(event eventstore.Event) ( return zerrors.ThrowInvalidArgumentf(nil, "HANDL-0ZGqC", "reduce.wrong.db.pool %T", ex) } domainRepo := repository.OrganizationRepository(v3_sql.SQLTx(tx)).Domains(false) + + condition := database.And( + domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), + domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), + domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), + ) + _, err := domainRepo.Update(ctx, - database.And( - domainRepo.InstanceIDCondition(e.Aggregate().InstanceID), - domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner), - domainRepo.DomainCondition(database.TextOperationEqual, e.Domain), - ), + condition, domainRepo.SetVerified(), domainRepo.SetUpdatedAt(e.CreationDate()), ) + if err != nil { + return err + } + // we need to split the update into two statements because multiple events can have the same creation date + // therefore we first do not set the updated_at timestamp + _, err = domainRepo.Update(ctx, + condition, + domainRepo.SetUpdatedAt(e.CreationDate()), + ) return err }), nil }