Convert from BoltDB to Maildir storage for emails

This commit is contained in:
2018-06-26 03:08:51 +01:00
parent d25ed6c1bd
commit a3c2508160
19 changed files with 869 additions and 175 deletions

View File

@@ -5,11 +5,18 @@ import (
"crypto/tls"
"fmt"
"io"
"os"
"path/filepath"
"github.com/asdine/storm"
"github.com/coreos/bbolt"
)
const (
DatabaseFilename = "crockery.db"
MailboxesDirname = "mailboxes"
)
type Interface interface {
Domain() string
TLS() tls.Certificate
@@ -19,26 +26,42 @@ type Interface interface {
SetTLS([]byte, []byte) error
AccountInterface
MailboxInterface
MaildirInterface
MessageInterface
SpoolInterface
io.Closer
}
func buildPath(parts ...string) string {
if len(parts) == 0 || parts[0] == "" {
return ""
}
return filepath.Join(parts...)
}
func BuildDatabasePath(home string) string {
return buildPath(home, DatabaseFilename)
}
func BuildMailboxesPath(home string) string {
return buildPath(home, MailboxesDirname)
}
func IsNotFound(err error) bool {
return err.Error() == "not found" // Magic hardcoded value in storm
}
func New(ctx context.Context, filename string) (Interface, error) {
func New(ctx context.Context, home string) (Interface, error) {
filename := BuildDatabasePath(home)
db, err := storm.Open(filename, storm.BoltOptions(0600, &bolt.Options{}))
if err != nil {
return nil, err
}
out := &concrete{
filename: filename,
storm: db,
home: home,
storm: db,
}
if err := out.setup(); err != nil {
@@ -48,19 +71,30 @@ func New(ctx context.Context, filename string) (Interface, error) {
return out, nil
}
func Init(filename, domain string, certPEM, keyPEM []byte) error {
func Init(home, domain string, certPEM, keyPEM []byte) error {
filename := BuildDatabasePath(home)
mailboxes := BuildMailboxesPath(home)
if _, err := os.Stat(mailboxes); !os.IsNotExist(err) {
return fmt.Errorf("mailboxes directory %q already exists", mailboxes)
}
db, err := storm.Open(filename, storm.BoltOptions(0600, &bolt.Options{}))
if err != nil {
return err
}
builder := &concrete{
filename: filename,
storm: db,
home: home,
storm: db,
}
defer builder.Close()
if err := os.Mkdir(mailboxes, 0700); err != nil {
return fmt.Errorf("Couldn't create mailboxes directory %q: %v", mailboxes, err)
}
if err := builder.SetDomain(domain); err != nil {
return fmt.Errorf("Couldn't set domain: %v", err)
}
@@ -73,8 +107,9 @@ func Init(filename, domain string, certPEM, keyPEM []byte) error {
}
type concrete struct {
filename string
storm *storm.DB
home string
storm *storm.DB
domainBucket storm.Node
// These are persisted in BoltDB, but we might as well keep them in memory