diff --git a/mutations_upsert_channel.go b/mutations_upsert_channel.go new file mode 100644 index 0000000..fa6dee3 --- /dev/null +++ b/mutations_upsert_channel.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + "strings" +) + +// UpsertChannel — create or update a channel. Channels are lightweight tags. +type UpsertChannel struct { + Slug string + Name string + Description string +} + +func (m *UpsertChannel) Kind() string { return "upsert_channel" } + +func (m *UpsertChannel) AffectedAuthors() []string { + return nil // channels don't attribute to an author +} + +func (m *UpsertChannel) Validate(s *Store) error { + if strings.TrimSpace(m.Slug) == "" { + return &ValidationError{Field: "slug", Message: "required"} + } + for _, r := range m.Slug { + if r == ' ' || r == '\t' || r == '\n' || r == '/' { + return &ValidationError{Field: "slug", Message: "must not contain whitespace or slashes"} + } + } + if strings.TrimSpace(m.Name) == "" { + return &ValidationError{Field: "name", Message: "required"} + } + return nil +} + +func (m *UpsertChannel) Apply(s *Store, lock LockRegion) error { + now := s.Now() + c := &Channel{ + Slug: m.Slug, + Name: m.Name, + Description: m.Description, + CreatedAt: now, + } + s.mu.Lock() + defer s.mu.Unlock() + if existing, ok := s.channels[m.Slug]; ok { + c.CreatedAt = existing.CreatedAt + } + s.channels[m.Slug] = c + return nil +} + +var _ = fmt.Sprintf // keep fmt for future error formatting