Documentation
¶
Overview ¶
Package store owns the SQLite database: opening it, migrating it and, later, the repositories.
Index ¶
- Constants
- Variables
- func Migrate(ctx context.Context, db *sql.DB) error
- func Open(ctx context.Context, dataDir string) (*sql.DB, error)
- type Account
- type Action
- type ActivityFilter
- type ActivityRow
- type Batch
- type CleanupBatch
- type Contact
- type Correction
- type Decision
- type FeedCursor
- type Folder
- type Message
- type NewRule
- type RuleStat
- type RuleUse
- type SenderDecision
- type SenderSeen
- type Signals
- type Snapshot
- type Store
- func (s *Store) Account(ctx context.Context, id int64) (Account, error)
- func (s *Store) AccountSecret(ctx context.Context, master []byte, id int64) (string, error)
- func (s *Store) Accounts(ctx context.Context) ([]Account, error)
- func (s *Store) Action(ctx context.Context, id int64) (Action, error)
- func (s *Store) Activity(ctx context.Context, f ActivityFilter) ([]ActivityRow, error)
- func (s *Store) ActivityFor(ctx context.Context, messageID int64) (ActivityRow, error)
- func (s *Store) AddBatchProgress(ctx context.Context, id int64, done, skipped, tokens int, costUSD float64) error
- func (s *Store) AddCorrection(ctx context.Context, userID int64, c Correction, always string) (int64, error)
- func (s *Store) AddDecision(ctx context.Context, d Decision, state string) (int64, error)
- func (s *Store) AddFolder(ctx context.Context, accountID int64, name string) error
- func (s *Store) AddLearnedSenderRule(ctx context.Context, userID int64, address string, ruleID, now int64) (bool, error)
- func (s *Store) AddUsage(ctx context.Context, day, provider, model, purpose string, ...) error
- func (s *Store) AdvanceFolder(ctx context.Context, ref mail.MsgRef) error
- func (s *Store) Batch(ctx context.Context, id int64) (Batch, error)
- func (s *Store) BatchActionCounts(ctx context.Context, batchID int64) (map[string]int, error)
- func (s *Store) BatchActions(ctx context.Context, batchID int64) ([]Action, error)
- func (s *Store) Batches(ctx context.Context, kind string, before int64, limit int) ([]Batch, error)
- func (s *Store) ClaimSummary(ctx context.Context, userID, dueAt, now int64, maxAttempts int) (id int64, attempt int, ok bool, err error)
- func (s *Store) Corrections(ctx context.Context, userID int64, limit int) ([]Correction, error)
- func (s *Store) CountMessages(ctx context.Context, state string) (int, error)
- func (s *Store) CreateAccount(ctx context.Context, master []byte, a Account, secret string) (Account, error)
- func (s *Store) CreateBatch(ctx context.Context, kind, status string, now int64) (int64, error)
- func (s *Store) CreateCleanupBatch(ctx context.Context, accountID int64, folder string, since int64, ...) (Batch, error)
- func (s *Store) CreateCleanupRun(ctx context.Context, cs []CleanupBatch, now int64) ([]Batch, error)
- func (s *Store) CreateFirstUser(ctx context.Context, email, passwordHash string, now int64) (User, error)
- func (s *Store) CreateRule(ctx context.Context, r rules.Rule, now int64) (rules.Rule, error)
- func (s *Store) CreateRules(ctx context.Context, userID int64, added []NewRule, now int64) ([]rules.Rule, error)
- func (s *Store) CreateSession(ctx context.Context, tokenHash string, userID, now, expiresAt int64) error
- func (s *Store) DeleteAccount(ctx context.Context, id int64) error
- func (s *Store) DeleteRule(ctx context.Context, userID, id int64) error
- func (s *Store) DeleteSenderRule(ctx context.Context, userID int64, matchType, value string) error
- func (s *Store) DeleteSession(ctx context.Context, tokenHash string) error
- func (s *Store) DoneActionsSince(ctx context.Context, ruleID, since int64) ([]Action, error)
- func (s *Store) DryRun(ctx context.Context, def bool) (bool, error)
- func (s *Store) DueMessages(ctx context.Context, accountID, now int64) ([]Message, error)
- func (s *Store) ExtendSession(ctx context.Context, tokenHash string, expiresAt int64) error
- func (s *Store) FailRunningBatches(ctx context.Context) error
- func (s *Store) FinishAction(ctx context.Context, a Action) error
- func (s *Store) FinishSummary(ctx context.Context, id int64, sent bool, periodStart, periodEnd, now int64) error
- func (s *Store) FirstUser(ctx context.Context) (User, error)
- func (s *Store) Folder(ctx context.Context, accountID int64, name string) (Folder, error)
- func (s *Store) Folders(ctx context.Context, accountID int64) ([]Folder, error)
- func (s *Store) HasUsers(ctx context.Context) (bool, error)
- func (s *Store) HitSenderRule(ctx context.Context, id int64) error
- func (s *Store) ImportRules(ctx context.Context, userID int64, imported []rules.Rule, now int64) (created, updated int, err error)
- func (s *Store) IngestMessage(ctx context.Context, ref mail.MsgRef, now int64) (m Message, fresh bool, err error)
- func (s *Store) InsertAction(ctx context.Context, a Action) (int64, error)
- func (s *Store) IsContact(ctx context.Context, accountID int64, address string) (bool, error)
- func (s *Store) LastMailAt(ctx context.Context, accountID int64) (int64, error)
- func (s *Store) LastSentSummary(ctx context.Context, userID int64) (Summary, error)
- func (s *Store) LeaveOwnMail(ctx context.Context) (bool, error)
- func (s *Store) LiveBatch(ctx context.Context, now time.Time) (int64, error)
- func (s *Store) MarkActionUndone(ctx context.Context, a Action, restored mail.MsgRef, now int64) error
- func (s *Store) Message(ctx context.Context, id int64) (Message, error)
- func (s *Store) MessageActions(ctx context.Context, messageID int64) ([]Action, error)
- func (s *Store) MessageByMessageID(ctx context.Context, accountID int64, messageID string, except int64) (Message, error)
- func (s *Store) MessageCorrections(ctx context.Context, messageID int64) ([]Correction, error)
- func (s *Store) MessageDecisions(ctx context.Context, messageID int64) ([]Decision, error)
- func (s *Store) Ping(ctx context.Context) error
- func (s *Store) PutSenderRule(ctx context.Context, sr rules.SenderRule, now int64) (rules.SenderRule, error)
- func (s *Store) QuietRules(ctx context.Context, userID, since int64) (int, error)
- func (s *Store) Rebind(ctx context.Context, fresh, known int64, ref mail.MsgRef) (bool, error)
- func (s *Store) RecentSenderDecisions(ctx context.Context, userID int64, address string, n int) ([]SenderDecision, error)
- func (s *Store) ReorderRules(ctx context.Context, userID int64, ids []int64) error
- func (s *Store) Retain(ctx context.Context, now int64, retentionDays int) (blanked, deleted int64, err error)
- func (s *Store) Rule(ctx context.Context, userID, id int64) (rules.Rule, error)
- func (s *Store) RuleCosts(ctx context.Context, userID, since int64) ([]RuleUse, error)
- func (s *Store) RuleStats(ctx context.Context, userID, since int64) (map[int64]RuleStat, error)
- func (s *Store) Rules(ctx context.Context, userID int64) ([]rules.Rule, error)
- func (s *Store) SaveFolders(ctx context.Context, accountID int64, folders []Folder) error
- func (s *Store) SaveMessageSummary(ctx context.Context, m Message) error
- func (s *Store) SenderRules(ctx context.Context, userID int64) ([]rules.SenderRule, error)
- func (s *Store) SendersSeen(ctx context.Context, userID, since int64) ([]SenderSeen, error)
- func (s *Store) SessionUser(ctx context.Context, tokenHash string, now int64) (User, int64, error)
- func (s *Store) SetAccountCapabilities(ctx context.Context, id int64, capabilities []string) error
- func (s *Store) SetAccountSecret(ctx context.Context, master []byte, id int64, secret string) error
- func (s *Store) SetAccountStatus(ctx context.Context, id int64, status, lastError string, now int64) error
- func (s *Store) SetBatchProgress(ctx context.Context, id int64, total, done int) error
- func (s *Store) SetBatchStatus(ctx context.Context, id int64, status string) error
- func (s *Store) SetDryRun(ctx context.Context, on bool) error
- func (s *Store) SetFolderPosition(ctx context.Context, accountID int64, name string, uidValidity, lastUID uint32) error
- func (s *Store) SetMessageState(ctx context.Context, id int64, state string, attempts int, nextAttemptAt int64) error
- func (s *Store) SetPassword(ctx context.Context, userID int64, passwordHash string) error
- func (s *Store) SetSetting(ctx context.Context, key, value string) error
- func (s *Store) SetSettings(ctx context.Context, values map[string]*string) error
- func (s *Store) SetTrashToFolder(ctx context.Context, on bool) error
- func (s *Store) Setting(ctx context.Context, key string) (string, error)
- func (s *Store) Settings(ctx context.Context) (map[string]string, error)
- func (s *Store) StatsTotals(ctx context.Context, userID, since int64) (Totals, error)
- func (s *Store) SummaryCost(ctx context.Context, userID, from, to int64) (costUSD float64, calls int, err error)
- func (s *Store) SummaryReview(ctx context.Context, userID int64, limit int) ([]SummaryEmail, int, error)
- func (s *Store) SummaryRules(ctx context.Context, userID, from, to int64) ([]RuleUse, error)
- func (s *Store) SummaryTrashed(ctx context.Context, userID, from, to int64, limit int) ([]SummaryEmail, int, error)
- func (s *Store) TopRules(ctx context.Context, userID, since int64, limit int) ([]RuleUse, error)
- func (s *Store) TrashToFolder(ctx context.Context) (bool, error)
- func (s *Store) UpdateAccount(ctx context.Context, a Account) error
- func (s *Store) UpdateRule(ctx context.Context, r rules.Rule, now int64) error
- func (s *Store) UpsertContacts(ctx context.Context, accountID int64, contacts []Contact) error
- func (s *Store) Usage(ctx context.Context, sinceDay string) ([]UsageRow, error)
- func (s *Store) UserByEmail(ctx context.Context, email string) (User, error)
- type Summary
- type SummaryEmail
- type Totals
- type UsageRow
- type User
Constants ¶
const ( ActionDone = "done" ActionDryRun = "dry_run" ActionFailed = "failed" ActionUndone = "undone" )
Action statuses, as stored in actions.status.
const ( BatchLive = "live" BatchCleanup = "cleanup" BatchCorrection = "correction" BatchUndo = "undo" BatchRunning = "running" BatchDone = "done" BatchFailed = "failed" BatchUndone = "undone" )
Batch kinds and statuses, as stored in batches.
const ( SettingTrashToFolder = "trash_to_folder" DefaultTrashToFolder = true )
SettingTrashToFolder is the settings key of the switch that sends trashed mail to an ordinary folder of MailRules' own instead of the server's Trash, which providers empty on their own. DefaultTrashToFolder is in force until it is set, for a new install and an existing one alike.
const ( SettingLeaveOwnMail = "leave_own_mail" DefaultLeaveOwnMail = true )
SettingLeaveOwnMail is the settings key of the switch that leaves mail sent from the mailbox's own address alone (Account.OwnAddresses): no rule, model or action touches it. DefaultLeaveOwnMail is in force until it is set.
const ( StateNew = "new" // ingested, not yet decided StateDecided = "decided" // a decision is recorded, its actions are not finished StateActed = "acted" // the decision's actions ran (or were recorded as dry-run) StateReview = "review" // waiting in Needs review StateSkipped = "skipped" // nothing to do: no rule matched, or the message was gone StateError = "error" // failed; the retry job runs it again at NextAttemptAt )
Message states, as stored in messages.state.
const ( CorrectionFix = "correction" CorrectionReview = "review" )
What a correction was: a fix made from the feed, or an answer given in Needs review.
const ( SummarySending = "sending" SummarySent = "sent" SummaryFailed = "failed" )
Summary statuses, as stored in summaries.status.
const KeepMessagesDays = 180
KeepMessagesDays is how long a message's row is kept. After that it is deleted with its decisions and actions, unless one of its actions can still be undone: a move or a flag change that is in effect and was made in the last UndoDays. A recorded "keep" changed nothing worth putting back, so it does not hold a row.
const SettingSummary = "summary"
SettingSummary holds the summary email's settings, one JSON object (internal/summary).
const UndoDays = 30
UndoDays is how long an action stays undoable. Older ones are history: undo refuses them (actions.ErrTooOld) and they no longer hold their message's row.
Variables ¶
var ErrAlreadySetUp = errors.New("already set up")
ErrAlreadySetUp means the first-run admin account already exists.
var ErrNotFound = errors.New("not found")
ErrNotFound means the row does not exist (or, for a session, has expired).
var ErrRuleSet = errors.New("the list must name every rule exactly once")
ErrRuleSet means a reorder did not name each of the user's rules exactly once.
var Outcomes = []string{"sorted", "trashed", "inbox", "review"}
Outcomes are the four places a processed message ends up: the groups of the Overview bar (Totals.Went*) and the values of ActivityFilter.Outcome.
Functions ¶
Types ¶
type Account ¶
type Account struct {
ID int64
UserID int64
Label string
Preset string
Host string
Port int
TLSMode string
Username string
WatchFolder string
Status string // new | live | reconnecting | auth_failed | error | paused
LastError string
LastEventAt int64
Capabilities []string
CreatedAt int64
}
Account is one mailbox the daemon watches. Its password is never part of this struct: read it with AccountSecret at the moment a connection is made.
func (Account) OwnAddresses ¶
OwnAddresses returns the account's own email addresses, lowercase: the username when it is a full address and, for a provider whose domains are known (presets.Preset.Domains), the name before "@" at each of them, so an iCloud username of only "jane" is jane@icloud.com, jane@me.com and jane@mac.com. Aliases are not known. It is nil when no address can be told: a username without "@" on a provider whose domains are not known.
type Action ¶
type Action struct {
ID int64
DecisionID int64 // 0 = none
BatchID int64 // 0 = none
MessageID int64
AccountID int64
Kind string // move | trash | archive | junk | flag | unflag | read | unread | keep | review
Folder string // params.folder: the destination of a move, or of a trash sent to MailRules' own folder (trash_to_folder)
Before Snapshot
After *Snapshot // nil unless the action is done (or was, before an undo)
Status string
Error string
CreatedAt int64
UndoneAt int64
}
Action is one row of actions: one step taken (or, in dry-run, not taken) on a message.
type ActivityFilter ¶
type ActivityFilter struct {
ID int64 // only this message
AccountID int64
RuleID int64
Stage string
State string // a message state; StateReview lists Needs review
Action string // an action kind: only messages with such an action
Outcome string // one of Outcomes: where the message ended up, as the stats count it
After FeedCursor
Limit int // 0 = 50
}
ActivityFilter narrows Activity. Zero fields do not filter.
type ActivityRow ¶
ActivityRow is a message with its latest decision and every action taken on it, oldest first; Decision is nil until one is made.
func (ActivityRow) Cursor ¶
func (r ActivityRow) Cursor() FeedCursor
Cursor is the position of this row in the feed, for the page after it.
type Batch ¶
type Batch struct {
ID int64
Kind string // live | cleanup | review | correction | undo
Status string // running | done | failed | undone
Total int // how many items the batch set out to handle; 0 = not counted (live)
Done int // how many it has handled
CreatedAt int64
// What a cleanup batch sorted, and what its model calls have cost so far. Zero for
// the other kinds.
AccountID int64
Folder string
Since int64 // only mail received from this time on; 0 = all of it
Tokens int // model tokens, in and out
CostUSD float64
// Skipped is how many selected emails a cleanup Sort passed over because they were no
// longer where its check found them (MAI-44). 0 for the other kinds.
Skipped int
// ScanLimit is the most emails the cleanup's check was allowed to cover, and ScanMatched
// how many the folder held in the range before that cut (MAI-48). ScanLimit 0 = not
// recorded (a batch made before this), and then ScanMatched means nothing.
ScanLimit int
ScanMatched int
// RunID joins the batches of one manual run over several mailboxes, one per mailbox
// (MAI-43): it is the id of the run's first batch, the same on every one. 0 = not part of
// such a run, which is every other batch and a cleanup of one mailbox.
RunID int64
}
Batch is one row of batches: a group of actions that can be undone together.
type CleanupBatch ¶ added in v0.1.2
type CleanupBatch struct {
AccountID int64
Folder string
Since int64 // only mail received from this time on; 0 = all of it
// ScanLimit and ScanMatched say how much mail the check behind the batch covered: the
// most emails it was allowed and how many the range held before that cut. ScanLimit 0
// records nothing.
ScanLimit, ScanMatched int
Total int // emails the batch sorts
}
CleanupBatch is what a cleanup batch is opened with.
type Correction ¶
type Correction struct {
ID int64
MessageID int64
WrongRuleID int64 // 0 = no rule had been applied
RightRuleID int64 // 0 = keep in the inbox
RightRule string // that rule's name, when read back; empty for keep, or once the rule is deleted
Kind string // CorrectionFix | CorrectionReview; empty is stored as CorrectionFix
Example string // JSON message.Summary, the few-shot example
CreatedAt int64
}
Correction is one row of corrections: the user said a message belongs to another rule.
type Decision ¶
type Decision struct {
ID int64
MessageID int64
Stage string // sender | condition | decider | fallback | none
RuleID int64 // 0 = no rule; in Needs review, the rule the model suggested
RuleName string // the rule's name: as it is now, or as it was when decided if the rule is gone
RuleVersion int
Confidence float64
Reason string
Model string
TokensIn int
TokensOut int
CostUSD float64
LatencyMS int64
CreatedAt int64
// Probabilities is what the decision model gave each candidate rule, by rule id, with
// 0 for "none of these". nil when the model gives no such spread, or none was asked.
Probabilities map[int64]float64
}
Decision is one row of decisions: what was decided for a message, and what it cost.
type FeedCursor ¶
FeedCursor is where a page of Activity ends: the ActedAt and ID of its last row. The next page starts after it in the feed's order. The zero value is the first page.
type Folder ¶
type Folder struct {
AccountID int64
Name string
Delimiter string
SpecialUse string // \Junk \Trash \Archive \Sent \Drafts or empty
UIDValidity uint32
LastUID uint32 // highest UID processed
}
Folder is one folder of an account, with the watch position when it is watched.
type Message ¶
type Message struct {
ID int64
AccountID int64
Folder string // where it arrived; with UIDValidity and UID, the dedupe key
UIDValidity uint32
UID uint32
MessageID string // RFC 5322 Message-ID, without angle brackets
FromAddr string
FromName string // the From display name; may be empty
FromDomain string
ToAddrs []string
Subject string
Snippet string
ReceivedAt int64
ListID string
HasAttachment bool
Size int64
Signals Signals
State string
Attempts int // retries made after a failure
NextAttemptAt int64 // 0 = not waiting for the retry job
CreatedAt int64
// ActedAt is when MailRules last decided the message, or CreatedAt until a decision is
// made. The feed is ordered by it.
ActedAt int64
// Where the executor last left the message; zero while it is still where it arrived.
CurFolder string
CurUIDValidity uint32
CurUID uint32
}
Message is one row of messages: what is kept of an email. The body never is.
type RuleStat ¶
type RuleStat struct {
Hits int // messages it was applied to since the time asked for
LastMatchAt int64 // 0 = never
}
RuleStat is how often a rule has been applied.
type RuleUse ¶
type RuleUse struct {
RuleID int64
RuleName string
Emails int
Calls int // decisions a model was asked for
CostUSD float64
}
RuleUse is what one rule did, or cost. RuleID is 0 with a name for a rule that has been deleted since, and 0 without one for "no rule".
type SenderDecision ¶
type SenderDecision struct {
Stage string
RuleID int64
Confidence float64
Corrected bool // the user corrected that message afterwards
}
SenderDecision is one past decision for a sender, as the learner reads it.
type SenderSeen ¶
type SenderSeen struct {
Address string
Name string // the From display name of the newest email; may be empty
Messages int // emails seen since the time asked for
LastSeenAt int64
ListUnsubscribe bool // at least one of them carried a List-Unsubscribe header
}
SenderSeen is what the messages table knows about one sender address.
type Signals ¶
type Signals struct {
Bulk bool `json:"bulk"`
Noreply bool `json:"noreply"`
Contact bool `json:"is_contact"`
RepliedBefore bool `json:"replied_before"`
DMARC string `json:"dmarc"`
// ListUnsubscribe is set when the email carries a List-Unsubscribe header.
ListUnsubscribe bool `json:"list_unsubscribe"`
}
Signals is the JSON in messages.signals.
type Snapshot ¶
type Snapshot struct {
Folder string `json:"folder"`
UIDValidity uint32 `json:"uidvalidity"`
UID uint32 `json:"uid"`
Flags []string `json:"flags"`
}
Snapshot is the JSON in actions.before and actions.after: where a message was and which flags it had.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the repository over the database. All times are unix seconds.
func (*Store) AccountSecret ¶
AccountSecret decrypts an account's app password or token. It returns crypto.ErrDecrypt when the master key is not the one the secret was sealed under.
func (*Store) Activity ¶
func (s *Store) Activity(ctx context.Context, f ActivityFilter) ([]ActivityRow, error)
Activity lists messages, each with its latest decision, by when MailRules acted on them (ActedAt), newest first; messages acted on in the same second come newest row first.
func (*Store) ActivityFor ¶
ActivityFor returns one message's activity row, or ErrNotFound.
func (*Store) AddBatchProgress ¶
func (s *Store) AddBatchProgress(ctx context.Context, id int64, done, skipped, tokens int, costUSD float64) error
AddBatchProgress records that a cleanup batch handled more emails, passed over some that had moved, and what their model calls cost.
func (*Store) AddCorrection ¶
func (s *Store) AddCorrection(ctx context.Context, userID int64, c Correction, always string) (int64, error)
AddCorrection records a correction in one transaction: it inserts the row, forgets the learned sender rule for that message's sender and marks the message acted. With always (rules.MatchAddress or rules.MatchDomain; "" = neither) it also stores a user sender rule that sends the address, or its whole domain, to the right rule (or keeps it in the inbox), replacing whatever that address or domain had.
func (*Store) AddDecision ¶
AddDecision records a decision and moves its message to state in one transaction, and returns the decision's id. The message's ActedAt becomes the decision's time.
func (*Store) AddFolder ¶
AddFolder records a folder MailRules itself just created on the server, so it shows up before the next folder discovery. A folder already on record is left as it is.
func (*Store) AddLearnedSenderRule ¶
func (s *Store) AddLearnedSenderRule(ctx context.Context, userID int64, address string, ruleID, now int64) (bool, error)
AddLearnedSenderRule routes an address to a rule unless the address already has a sender rule, which is never overwritten. It reports whether a rule was created.
func (*Store) AddUsage ¶
func (s *Store) AddUsage(ctx context.Context, day, provider, model, purpose string, calls, tokensIn, tokensOut int, costUSD float64) error
AddUsage adds model calls to the day's cost-ledger row for that provider, model and purpose (decide | escalate | compose | test | cleanup), creating it if needed.
func (*Store) AdvanceFolder ¶
AdvanceFolder raises a watched folder's last processed UID to ref's. It never lowers it, except when the folder's UIDVALIDITY changed, where the old position means nothing.
func (*Store) BatchActionCounts ¶
BatchActionCounts counts a batch's own actions by status.
func (*Store) BatchActions ¶
BatchActions lists a batch's actions, oldest first.
func (*Store) Batches ¶
Batches lists batches, newest first: of one kind, or of every kind when kind is empty. before is the cursor (only batches with a smaller id; 0 = from the newest).
func (*Store) ClaimSummary ¶
func (s *Store) ClaimSummary(ctx context.Context, userID, dueAt, now int64, maxAttempts int) (id int64, attempt int, ok bool, err error)
ClaimSummary records an attempt at the summary due at dueAt and reports whether this caller is to make it, and which attempt it is. It is one statement, so of two callers at once only one gets it. It is not to be made when it was sent, when an attempt is running or was cut off (status sending), after maxAttempts, or while the last failed attempt is younger than its back-off: a minute after the first, doubling each time.
func (*Store) Corrections ¶
Corrections lists the user's newest corrections, newest first, with the example each stored: the pool few-shot retrieval ranks.
func (*Store) CountMessages ¶
CountMessages counts the messages in a state, e.g. StateReview for the Needs review badge.
func (*Store) CreateAccount ¶
func (s *Store) CreateAccount(ctx context.Context, master []byte, a Account, secret string) (Account, error)
CreateAccount stores an account with its secret encrypted under the master key. The ciphertext is bound to the row id, which only exists after the insert, so the row is inserted, sealed and updated in one transaction: no reader ever sees it without a secret.
func (*Store) CreateBatch ¶
CreateBatch opens a batch and returns its id.
func (*Store) CreateCleanupBatch ¶
func (s *Store) CreateCleanupBatch(ctx context.Context, accountID int64, folder string, since int64, scanLimit, scanMatched, total int, now int64) (Batch, error)
CreateCleanupBatch opens the batch of one cleanup run over total emails, running.
scanLimit and scanMatched say how much mail the check behind it covered: the most emails it was allowed and how many the range held before that cut. scanLimit 0 records nothing.
func (*Store) CreateCleanupRun ¶ added in v0.1.2
func (s *Store) CreateCleanupRun(ctx context.Context, cs []CleanupBatch, now int64) ([]Batch, error)
CreateCleanupRun opens one running cleanup batch per mailbox for a manual run over several mailboxes, all or none: they share a RunID, the id of the first, so they read back as one run. A run of one mailbox is a plain cleanup batch with no RunID.
func (*Store) CreateFirstUser ¶
func (s *Store) CreateFirstUser(ctx context.Context, email, passwordHash string, now int64) (User, error)
CreateFirstUser inserts the admin account only if no user exists yet.
func (*Store) CreateRule ¶
CreateRule inserts a rule at version 1 and returns it with its id. The caller validates the rule first.
func (*Store) CreateRules ¶
func (s *Store) CreateRules(ctx context.Context, userID int64, added []NewRule, now int64) ([]rules.Rule, error)
CreateRules inserts rules in one transaction and returns them as saved, in the order given. Each lands at its position in the priority order, or at the end; the priorities of all the user's rules are then renumbered from 1, which is not an edit, so versions stay. The caller validates the rules first.
func (*Store) CreateSession ¶
func (s *Store) CreateSession(ctx context.Context, tokenHash string, userID, now, expiresAt int64) error
CreateSession stores a login session by the hash of its token, and sweeps expired ones.
func (*Store) DeleteAccount ¶
DeleteAccount wipes an account with its secret, folders, contacts, messages, decisions, actions, corrections and the rules scoped to it. Every one of those references the account with ON DELETE CASCADE, so the one statement is the whole transaction.
func (*Store) DeleteRule ¶
DeleteRule removes a rule. The schema takes the sender rules that route to it along (ON DELETE CASCADE) and keeps its decisions and corrections, with their rule set to NULL.
func (*Store) DeleteSenderRule ¶
DeleteSenderRule removes a sender's verdict; deleting a missing one is not an error.
func (*Store) DeleteSession ¶
DeleteSession ends a session; deleting a missing one is not an error.
func (*Store) DoneActionsSince ¶
DoneActionsSince lists the actions made at or after since that are still in effect, newest first: the ones "undo everything since" reverses. With ruleID, only those a decision for that rule led to.
func (*Store) DryRun ¶
DryRun reports whether the global dry-run switch is on. def is used until the switch has been set (MAILRULES_DRY_RUN).
func (*Store) DueMessages ¶
DueMessages lists an account's failed messages whose retry time has come, oldest first.
func (*Store) ExtendSession ¶
ExtendSession slides a session's expiry forward.
func (*Store) FailRunningBatches ¶
FailRunningBatches marks every batch still running as failed. The daemon calls it at startup: a batch that was running when the daemon stopped will never finish.
func (*Store) FinishAction ¶
FinishAction stores how an action ended. For a done action, after is the message's state afterwards, and the message's location is updated with it in the same transaction.
func (*Store) FinishSummary ¶
func (s *Store) FinishSummary(ctx context.Context, id int64, sent bool, periodStart, periodEnd, now int64) error
FinishSummary records how a claimed attempt ended: sent, with the time it covered, or failed.
func (*Store) FirstUser ¶
FirstUser returns the admin account, or ErrNotFound before first-run setup.
func (*Store) HitSenderRule ¶
HitSenderRule counts one more email settled by a sender rule.
func (*Store) ImportRules ¶
func (s *Store) ImportRules(ctx context.Context, userID int64, imported []rules.Rule, now int64) (created, updated int, err error)
ImportRules stores the rules of a YAML file in one transaction. A rule whose name is already in use replaces that rule, including its mailbox (AccountID, which the caller has set to the one to keep when the file says nothing), and keeps its place and id; the others are added after the existing rules, in file order. Rules the file does not name are left alone. The caller validates the rules first.
func (*Store) IngestMessage ¶
func (s *Store) IngestMessage(ctx context.Context, ref mail.MsgRef, now int64) (m Message, fresh bool, err error)
IngestMessage records that a message arrived, once. fresh is false when the row was already there (the watcher repeats a message after a crash); the stored row is returned either way. A known message that the executor itself put at ref (an undo back into the watched folder gets a new UID) is not new mail either: its existing row is returned.
func (*Store) InsertAction ¶
InsertAction writes an action row and returns its id.
func (*Store) LastMailAt ¶
LastMailAt is when the newest email MailRules has seen in an account arrived (its received date, or when it was first seen if it carried none); 0 when it has seen none.
func (*Store) LastSentSummary ¶
LastSentSummary returns the user's latest summary that went out, or ErrNotFound.
func (*Store) LeaveOwnMail ¶
LeaveOwnMail reports whether mail from the mailbox's own address is left alone. The pipeline reads it for every email.
func (*Store) LiveBatch ¶
LiveBatch returns the batch that collects the actions of live processing for now's day (UTC), creating it on the day's first action, so "undo today" is one batch undo. Once a day's batch has been undone, later mail that day starts a new one.
func (*Store) MarkActionUndone ¶
func (s *Store) MarkActionUndone(ctx context.Context, a Action, restored mail.MsgRef, now int64) error
MarkActionUndone marks a done action undone and records where its message is now.
func (*Store) MessageActions ¶
MessageActions lists every action taken on a message, oldest first.
func (*Store) MessageByMessageID ¶
func (s *Store) MessageByMessageID(ctx context.Context, accountID int64, messageID string, except int64) (Message, error)
MessageByMessageID returns the account's newest row, other than except, for the email with this Message-ID header, or ErrNotFound.
func (*Store) MessageCorrections ¶
MessageCorrections lists the corrections the user made to a message, oldest first.
func (*Store) MessageDecisions ¶
MessageDecisions lists every decision made for a message, oldest first. A message has more than one when the retry job ran it again.
func (*Store) PutSenderRule ¶
func (s *Store) PutSenderRule(ctx context.Context, sr rules.SenderRule, now int64) (rules.SenderRule, error)
PutSenderRule stores the verdict for a sender address or domain, replacing any earlier one for the same sender, and returns it with its id.
func (*Store) QuietRules ¶
QuietRules counts the user's enabled rules that were applied to no email since `since`.
func (*Store) Rebind ¶
Rebind records that the email of row known is now at ref, where it was just ingested as row fresh, and removes fresh, so the email keeps one row. fresh must be a row MailRules has done nothing with yet: when it has a decision, an action or a correction, Rebind changes nothing and reports false.
func (*Store) RecentSenderDecisions ¶
func (s *Store) RecentSenderDecisions(ctx context.Context, userID int64, address string, n int) ([]SenderDecision, error)
RecentSenderDecisions returns the decisions of the newest n decided emails from one address across the user's accounts, newest first. An email decided more than once (a retry, a cleanup run) counts once, by its latest decision. A decision whose actions were recorded in dry-run is left out, so a dry-run period teaches the learner nothing, then or once MailRules is live.
func (*Store) ReorderRules ¶
ReorderRules sets the rules' priorities to the order of ids, in one transaction. A reorder is not an edit, so versions stay as they are.
func (*Store) Retain ¶
func (s *Store) Retain(ctx context.Context, now int64, retentionDays int) (blanked, deleted int64, err error)
Retain is the retention job's one step: it blanks the snippet of every message first seen more than retentionDays ago, and deletes the messages first seen more than KeepMessagesDays ago that have no action left to undo, that is, none in effect from the last UndoDays (their decisions, actions and corrections go with them). It returns how many rows each part touched.
func (*Store) RuleCosts ¶
RuleCosts lists, per rule, the emails decided for it since `since` and what the model decisions among them cost, dearest first. Every decision counts here, a retry too: it was paid for.
func (*Store) RuleStats ¶
RuleStats counts, per rule, the messages it was applied to since `since`, with the time of the latest one ever. Mail waiting in Needs review does not count: nothing was applied.
func (*Store) Rules ¶
Rules returns all of the user's rules, disabled ones included, in priority order.
func (*Store) SaveFolders ¶
SaveFolders replaces an account's folder list with what discovery found. Watch positions of folders that still exist are kept; folders that are gone are removed.
func (*Store) SaveMessageSummary ¶
SaveMessageSummary stores the parsed header fields, snippet and signals of a message.
func (*Store) SenderRules ¶
SenderRules returns all of the user's sender rules.
func (*Store) SendersSeen ¶
SendersSeen lists every address the user's accounts have seen mail from since `since` (by when MailRules first saw the email).
func (*Store) SessionUser ¶
SessionUser returns the user behind a live session and when it expires.
func (*Store) SetAccountCapabilities ¶
SetAccountCapabilities stores what the server advertised at the last login.
func (*Store) SetAccountSecret ¶
SetAccountSecret replaces an account's app password, sealed under a fresh data key.
func (*Store) SetAccountStatus ¶
func (s *Store) SetAccountStatus(ctx context.Context, id int64, status, lastError string, now int64) error
SetAccountStatus records the connection state; lastError is cleared by passing "".
func (*Store) SetBatchProgress ¶
SetBatchProgress records how far a batch has come.
func (*Store) SetBatchStatus ¶
SetBatchStatus moves a batch to a status.
func (*Store) SetDryRun ¶
SetDryRun turns the global dry-run switch on or off. A running daemon reads it before every action, so it takes effect at once.
func (*Store) SetFolderPosition ¶
func (s *Store) SetFolderPosition(ctx context.Context, accountID int64, name string, uidValidity, lastUID uint32) error
SetFolderPosition records how far a watched folder has been processed.
func (*Store) SetMessageState ¶
func (s *Store) SetMessageState(ctx context.Context, id int64, state string, attempts int, nextAttemptAt int64) error
SetMessageState moves a message to a state. nextAttemptAt is when the retry job should run it again; 0 means it is not waiting.
func (*Store) SetPassword ¶ added in v0.1.2
SetPassword replaces a user's password hash and, in the same transaction, ends every session the user has: a session someone else holds does not outlive the password that opened it. A missing user is ErrNotFound.
func (*Store) SetSetting ¶
SetSetting stores a JSON value under key, replacing any previous one.
func (*Store) SetSettings ¶
SetSettings stores several settings in one transaction, so a change is never half applied. A nil value removes the key, which puts its default back in force.
func (*Store) SetTrashToFolder ¶
SetTrashToFolder turns the trash_to_folder switch on or off.
func (*Store) StatsTotals ¶
StatsTotals counts the user's emails decided since `since`.
func (*Store) SummaryCost ¶
func (s *Store) SummaryCost(ctx context.Context, userID, from, to int64) (costUSD float64, calls int, err error)
SummaryCost is what the model decisions made in [from, to) cost, and how many asked a model.
func (*Store) SummaryReview ¶
func (s *Store) SummaryReview(ctx context.Context, userID int64, limit int) ([]SummaryEmail, int, error)
SummaryReview lists the user's emails waiting in Needs review now, newest first, at most limit of them, and how many there are.
func (*Store) SummaryRules ¶
SummaryRules lists, per rule, the emails a rule was applied to (sorted or trashed, as the Overview counts them) whose latest decision was made in [from, to), most first.
func (*Store) SummaryTrashed ¶
func (s *Store) SummaryTrashed(ctx context.Context, userID, from, to int64, limit int) ([]SummaryEmail, int, error)
SummaryTrashed lists the emails trashed (or, in dry-run, recorded as trashed) in [from, to) and not undone since, newest first, at most limit of them, and how many there are.
func (*Store) TopRules ¶
TopRules lists the rules applied to the most emails since `since`, most first.
func (*Store) TrashToFolder ¶
TrashToFolder reports whether trashed mail goes to MailRules' own folder rather than the server's Trash. The executor reads it before every trash action.
func (*Store) UpdateAccount ¶
UpdateAccount stores an account's label, watch folder and status (the fields the user edits).
func (*Store) UpdateRule ¶
UpdateRule rewrites a rule's editable columns and bumps its version, so past decisions keep pointing at the wording they were made under.
func (*Store) UpsertContacts ¶
UpsertContacts adds addresses to an account's contacts, keeping the latest sent time.
type Summary ¶
type Summary struct {
ID int64
UserID int64
DueAt int64
Status string
Attempts int
LastAttemptAt int64
PeriodStart int64 // 0 until sent
PeriodEnd int64
SentAt int64
}
Summary is one row of summaries: a scheduled summary email.
type SummaryEmail ¶
type SummaryEmail struct {
MessageID int64
FromName string
FromAddr string
Subject string
Folder string // a trashed email: the folder the trash moved it to; "" = the server's Trash
DryRun bool // a trashed email: the trash was only recorded, in dry-run
}
SummaryEmail is one email as a summary lists it: who sent it, its subject and, for a trashed one, where it went. Never its text.
type Totals ¶
type Totals struct {
Processed int // emails decided
Sorted int // of those, a rule or sender rule was applied (or recorded, in dry-run) and not undone since
WithoutModel int // of those, a sender rule or condition rule acted on, with no model asked; never more than Processed
Trashed int // emails with a trash action that is in effect (or recorded, in dry-run)
// Where the processed emails ended up; the four add up to Processed.
WentSorted int // a rule was applied and it did not trash the email
WentTrash int // a rule was applied and it trashed the email
WentReview int // waiting in Needs review
WentNowhere int // left in the inbox: no rule matched, it was the mailbox's own mail, it could not be handled, or all that was done to it was undone
}
Totals are the counts of the stats tiles.