Documentation
¶
Overview ¶
Package memory provides an in-memory Store implementation for testing. This store is not suitable for production use - data is not persisted.
Index ¶
- type Store
- func (s *Store) AddTag(ctx context.Context, id string, tagID string) error
- func (s *Store) AddTagByFilter(_ context.Context, ownerID string, filters []store.Filter, tagID string) (int64, error)
- func (s *Store) AgeMessages(d time.Duration)
- func (s *Store) AgeMessagesByID(d time.Duration, ids ...string)
- func (s *Store) AgeScheduleAll(d time.Duration)
- func (s *Store) AgeScheduleByID(d time.Duration, ids ...string)
- func (s *Store) AgeTTLAll(d time.Duration)
- func (s *Store) AgeTTLByID(d time.Duration, ids ...string)
- func (s *Store) Close(_ context.Context) error
- func (s *Store) Connect(_ context.Context) error
- func (s *Store) Count(ctx context.Context, filters []store.Filter) (int64, error)
- func (s *Store) CountByFolders(ctx context.Context, ownerID string, folderIDs []string) (map[string]store.FolderCounts, error)
- func (s *Store) CreateMessage(ctx context.Context, data store.MessageData) (store.Message, error)
- func (s *Store) CreateMessageIdempotent(ctx context.Context, data store.MessageData, idempotencyKey string) (store.Message, bool, error)
- func (s *Store) CreateMessages(ctx context.Context, data []store.MessageData) ([]store.Message, error)
- func (s *Store) CreateMessagesIdempotent(ctx context.Context, entries []store.IdempotentCreateEntry) ([]store.IdempotentCreateResult, error)
- func (s *Store) Delete(ctx context.Context, id string) error
- func (s *Store) DeleteByFilter(_ context.Context, ownerID string, filters []store.Filter) (int64, error)
- func (s *Store) DeleteDraft(ctx context.Context, id string) error
- func (s *Store) DeleteExpiredMessages(ctx context.Context, cutoff time.Time) (int64, error)
- func (s *Store) DeleteExpiredTrash(ctx context.Context, cutoff time.Time) (int64, error)
- func (s *Store) DeleteMessagesByIDs(ctx context.Context, ids []string) ([]string, error)
- func (s *Store) DeleteTTLExpiredMessages(ctx context.Context, now time.Time) (int64, error)
- func (s *Store) Find(ctx context.Context, filters []store.Filter, opts store.ListOptions) (*store.MessageList, error)
- func (s *Store) FindWithCount(ctx context.Context, filters []store.Filter, opts store.ListOptions) (*store.MessageList, int64, error)
- func (s *Store) Get(ctx context.Context, id string) (store.Message, error)
- func (s *Store) GetDraft(ctx context.Context, id string) (store.DraftMessage, error)
- func (s *Store) HardDelete(ctx context.Context, id string) error
- func (s *Store) ListDistinctFolders(ctx context.Context, ownerID string) ([]string, error)
- func (s *Store) ListDrafts(ctx context.Context, ownerID string, opts store.ListOptions) (*store.DraftList, error)
- func (s *Store) MailboxStats(ctx context.Context, ownerID string) (*store.MailboxStats, error)
- func (s *Store) MarkAllRead(ctx context.Context, ownerID, folderID string) (int64, error)
- func (s *Store) MarkRead(ctx context.Context, id string, read bool) error
- func (s *Store) MarkReadByFilter(_ context.Context, ownerID string, filters []store.Filter, read bool) (int64, error)
- func (s *Store) MoveByFilter(_ context.Context, ownerID string, filters []store.Filter, folderID string) (int64, error)
- func (s *Store) MoveToFolder(ctx context.Context, id string, folderID string, opts ...store.MoveOption) error
- func (s *Store) NewDraft(ownerID string) store.DraftMessage
- func (s *Store) OutboxEnabled() bool
- func (s *Store) RemoveTag(ctx context.Context, id string, tagID string) error
- func (s *Store) RemoveTagByFilter(_ context.Context, ownerID string, filters []store.Filter, tagID string) (int64, error)
- func (s *Store) Restore(ctx context.Context, id string) error
- func (s *Store) SaveDraft(ctx context.Context, draft store.DraftMessage) (store.DraftMessage, error)
- func (s *Store) Search(ctx context.Context, query store.SearchQuery) (*store.MessageList, error)
- func (s *Store) ThreadParticipants(ctx context.Context, threadID string) ([]string, error)
- func (s *Store) WithOutboxCtx(ctx context.Context, fn func(ctx context.Context) error) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store implements store.Store with in-memory storage. Thread-safe for concurrent use. Not suitable for production.
func (*Store) AddTag ¶
AddTag adds a tag to a message. Uses per-message locking to prevent concurrent mutation races.
func (*Store) AddTagByFilter ¶ added in v0.6.5
func (*Store) AgeMessages ¶ added in v0.6.3
AgeMessages shifts createdAt and updatedAt backward by the given duration for all non-draft messages in the store. This is intended for testing time-dependent cleanup operations like message retention and trash expiry.
This method is NOT safe for concurrent use. Call it only when no other goroutines are reading or writing messages (e.g., between test setup and the operation under test).
func (*Store) AgeMessagesByID ¶ added in v0.6.3
AgeMessagesByID shifts createdAt and updatedAt backward by the given duration for the specified message IDs. This is intended for testing time-dependent cleanup operations where only specific messages should be aged.
This method is NOT safe for concurrent use. See AgeMessages for details.
func (*Store) AgeScheduleAll ¶ added in v0.6.5
AgeScheduleAll shifts availableAt backward by the given duration for all non-draft messages that have availableAt set. This is intended for testing scheduled delivery.
This method is NOT safe for concurrent use. See AgeMessages for details.
func (*Store) AgeScheduleByID ¶ added in v0.6.5
AgeScheduleByID shifts availableAt backward by the given duration for the specified message IDs. This is intended for testing scheduled delivery.
This method is NOT safe for concurrent use. See AgeMessages for details.
func (*Store) AgeTTLAll ¶ added in v0.6.5
AgeTTLAll shifts expiresAt backward by the given duration for all non-draft messages that have expiresAt set. This is intended for testing per-message TTL cleanup.
This method is NOT safe for concurrent use. See AgeMessages for details.
func (*Store) AgeTTLByID ¶ added in v0.6.5
AgeTTLByID shifts expiresAt backward by the given duration for the specified message IDs. This is intended for testing per-message TTL cleanup.
This method is NOT safe for concurrent use. See AgeMessages for details.
func (*Store) CountByFolders ¶
func (s *Store) CountByFolders(ctx context.Context, ownerID string, folderIDs []string) (map[string]store.FolderCounts, error)
CountByFolders returns message counts and unread counts for the given folders. Implements store.FolderCounter for optimized batch counting.
func (*Store) CreateMessage ¶
CreateMessage creates a new message from the given data.
func (*Store) CreateMessageIdempotent ¶
func (s *Store) CreateMessageIdempotent(ctx context.Context, data store.MessageData, idempotencyKey string) (store.Message, bool, error)
CreateMessageIdempotent atomically creates a message or returns existing.
Uses sync.Map.LoadOrStore for atomic check-and-create. This provides the same semantics as MongoDB's findOneAndUpdate with upsert or PostgreSQL's INSERT ON CONFLICT, but in memory.
The idempotency index maps "ownerID:idempotencyKey" to message ID.
func (*Store) CreateMessages ¶
func (s *Store) CreateMessages(ctx context.Context, data []store.MessageData) ([]store.Message, error)
CreateMessages creates multiple messages atomically. For the memory store, this uses a simple loop since sync.Map operations are already atomic per-key. In production stores, this should use database transactions for true atomicity.
func (*Store) CreateMessagesIdempotent ¶ added in v0.6.5
func (s *Store) CreateMessagesIdempotent(ctx context.Context, entries []store.IdempotentCreateEntry) ([]store.IdempotentCreateResult, error)
CreateMessagesIdempotent creates multiple messages with idempotency keys. Delegates to CreateMessageIdempotent per entry.
func (*Store) Delete ¶
Delete soft-deletes a message. Uses per-message locking to prevent concurrent mutation races.
func (*Store) DeleteByFilter ¶ added in v0.6.5
func (*Store) DeleteDraft ¶
DeleteDraft permanently removes a draft.
func (*Store) DeleteExpiredMessages ¶ added in v0.6.3
DeleteExpiredMessages atomically deletes all non-draft messages older than cutoff.
func (*Store) DeleteExpiredTrash ¶
DeleteExpiredTrash atomically deletes all messages in trash older than cutoff.
Safe to call concurrently - each message is deleted exactly once. Uses sync.Map.Range + Delete which is safe for concurrent access.
func (*Store) DeleteMessagesByIDs ¶ added in v0.6.3
DeleteMessagesByIDs deletes the specified messages and returns the IDs that were actually deleted by this call. Uses LoadAndDelete for atomic winner determination — only the goroutine that successfully removes the entry sees loaded=true.
func (*Store) DeleteTTLExpiredMessages ¶ added in v0.6.5
DeleteTTLExpiredMessages atomically deletes all non-draft messages whose expires_at is non-null and before the given time.
func (*Store) Find ¶
func (s *Store) Find(ctx context.Context, filters []store.Filter, opts store.ListOptions) (*store.MessageList, error)
Find retrieves messages matching the filters.
func (*Store) FindWithCount ¶
func (s *Store) FindWithCount(ctx context.Context, filters []store.Filter, opts store.ListOptions) (*store.MessageList, int64, error)
FindWithCount retrieves messages and total count in a single pass. Implements store.FindWithCounter for optimized list operations.
func (*Store) HardDelete ¶
HardDelete permanently removes a message. Uses per-message locking to prevent concurrent mutation races.
func (*Store) ListDistinctFolders ¶
ListDistinctFolders returns all distinct folder IDs for a user's non-deleted messages. Implements store.FolderLister for custom folder discovery.
func (*Store) ListDrafts ¶
func (s *Store) ListDrafts(ctx context.Context, ownerID string, opts store.ListOptions) (*store.DraftList, error)
ListDrafts returns all drafts for a user.
func (*Store) MailboxStats ¶ added in v0.3.0
MailboxStats returns aggregate statistics for a user's mailbox in a single pass.
func (*Store) MarkAllRead ¶ added in v0.4.0
MarkAllRead marks all unread non-draft messages in a folder as read. Uses per-message locking for each update to prevent concurrent mutation races.
func (*Store) MarkRead ¶
MarkRead sets the read status of a message. Uses per-message locking to prevent concurrent mutation races.
func (*Store) MarkReadByFilter ¶ added in v0.6.5
func (*Store) MoveByFilter ¶ added in v0.6.5
func (*Store) MoveToFolder ¶
func (s *Store) MoveToFolder(ctx context.Context, id string, folderID string, opts ...store.MoveOption) error
MoveToFolder moves a message to a different folder. When called with store.FromFolder, the move is conditional: it succeeds only if the message is currently in the specified source folder. Uses per-message locking to prevent concurrent mutation races.
func (*Store) NewDraft ¶
func (s *Store) NewDraft(ownerID string) store.DraftMessage
NewDraft creates a new empty draft for the given owner.
func (*Store) OutboxEnabled ¶ added in v0.6.5
OutboxEnabled returns false — memory store has no real outbox.
func (*Store) RemoveTag ¶
RemoveTag removes a tag from a message. Uses per-message locking to prevent concurrent mutation races.
func (*Store) RemoveTagByFilter ¶ added in v0.6.5
func (*Store) Restore ¶
Restore restores a soft-deleted message from trash. Uses per-message locking to prevent concurrent mutation races.
func (*Store) SaveDraft ¶
func (s *Store) SaveDraft(ctx context.Context, draft store.DraftMessage) (store.DraftMessage, error)
SaveDraft persists a draft.
func (*Store) Search ¶
func (s *Store) Search(ctx context.Context, query store.SearchQuery) (*store.MessageList, error)
Search performs full-text search on messages.
func (*Store) ThreadParticipants ¶ added in v0.7.9
ThreadParticipants returns distinct owner IDs of all non-deleted, non-draft messages with the given thread_id.