package projection import ( "context" "github.com/zitadel/zitadel/internal/eventstore" old_handler "github.com/zitadel/zitadel/internal/eventstore/handler" "github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/limits" ) const ( LimitsProjectionTable = "projections.limits" LimitsColumnAggregateID = "aggregate_id" LimitsColumnCreationDate = "creation_date" LimitsColumnChangeDate = "change_date" LimitsColumnResourceOwner = "resource_owner" LimitsColumnInstanceID = "instance_id" LimitsColumnSequence = "sequence" LimitsColumnAuditLogRetention = "audit_log_retention" LimitsColumnBlock = "block" ) type limitsProjection struct{} func newLimitsProjection(ctx context.Context, config handler.Config) *handler.Handler { return handler.NewHandler(ctx, &config, &limitsProjection{}) } func (*limitsProjection) Name() string { return LimitsProjectionTable } func (*limitsProjection) Init() *old_handler.Check { return handler.NewTableCheck( handler.NewTable([]*handler.InitColumn{ handler.NewColumn(LimitsColumnAggregateID, handler.ColumnTypeText), handler.NewColumn(LimitsColumnCreationDate, handler.ColumnTypeTimestamp), handler.NewColumn(LimitsColumnChangeDate, handler.ColumnTypeTimestamp), handler.NewColumn(LimitsColumnResourceOwner, handler.ColumnTypeText), handler.NewColumn(LimitsColumnInstanceID, handler.ColumnTypeText), handler.NewColumn(LimitsColumnSequence, handler.ColumnTypeInt64), handler.NewColumn(LimitsColumnAuditLogRetention, handler.ColumnTypeInterval, handler.Nullable()), handler.NewColumn(LimitsColumnBlock, handler.ColumnTypeBool, handler.Nullable()), }, handler.NewPrimaryKey(LimitsColumnInstanceID, LimitsColumnResourceOwner), ), ) } func (p *limitsProjection) Reducers() []handler.AggregateReducer { return []handler.AggregateReducer{ { Aggregate: limits.AggregateType, EventReducers: []handler.EventReducer{ { Event: limits.SetEventType, Reduce: p.reduceLimitsSet, }, { Event: limits.ResetEventType, Reduce: p.reduceLimitsReset, }, }, }, { Aggregate: instance.AggregateType, EventReducers: []handler.EventReducer{ { Event: instance.InstanceRemovedEventType, Reduce: reduceInstanceRemovedHelper(LimitsColumnInstanceID), }, }, }, } } func (p *limitsProjection) reduceLimitsSet(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*limits.SetEvent](event) if err != nil { return nil, err } conflictCols := []handler.Column{ handler.NewCol(LimitsColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(LimitsColumnResourceOwner, e.Aggregate().ResourceOwner), } updateCols := []handler.Column{ handler.NewCol(LimitsColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(LimitsColumnResourceOwner, e.Aggregate().ResourceOwner), handler.NewCol(LimitsColumnCreationDate, handler.OnlySetValueOnInsert(LimitsProjectionTable, e.CreationDate())), handler.NewCol(LimitsColumnChangeDate, e.CreationDate()), handler.NewCol(LimitsColumnSequence, e.Sequence()), handler.NewCol(LimitsColumnAggregateID, e.Aggregate().ID), } if e.AuditLogRetention != nil { updateCols = append(updateCols, handler.NewCol(LimitsColumnAuditLogRetention, *e.AuditLogRetention)) } if e.Block != nil { updateCols = append(updateCols, handler.NewCol(LimitsColumnBlock, *e.Block)) } return handler.NewUpsertStatement(e, conflictCols, updateCols), nil } func (p *limitsProjection) reduceLimitsReset(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*limits.ResetEvent](event) if err != nil { return nil, err } return handler.NewDeleteStatement( e, []handler.Condition{ handler.NewCond(LimitsColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(LimitsColumnResourceOwner, e.Aggregate().ResourceOwner), }, ), nil }