imapsql

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2019 License: MIT Imports: 27 Imported by: 1

README

go-imap-sql

Travis CI CodeCov

SQL-based storage backend for go-imap library.

Building

Go 1.11 is required because we are using modules. Things may work on older versions but these configurations will not be supported.

RDBMS support

go-imap-sql is known to work with (and constantly being tested against) following RDBMS:

  • SQLite 3.25.0
  • MySQL 8.0 (or MariaDB 10.2)
  • PostgreSQL 9.6
IMAP Extensions Supported

Due to go-imap architecture, some extensions require support from used backend. Here are extensions supported by go-imap-sql:

UIDVALIDITY

go-imap-sql never invalidates UIDs in an existing mailbox. If mailbox is DELETE'd then UIDVALIDITY value changes.

Unlike many popular IMAP server implementations, go-imap-sql uses randomly generated UIDVALIDITY values instead of timestamps.

This makes several things easier to implement with less edge cases. And answer to the question you are already probably asked: To make go-imap-sql malfunction you need to get Go's PRNG to generate two equal integers in range of [1, 2^32-1] just at right moment (seems unlikely enough to ignore it). Even then, it will not cause much problems due to the way most client implementations work.

go-imap-sql uses separate math/rand.Rand instance and seeds it with system time on initialization (in New).

You can provide custom pre-seeded struct implementing math/rand.Source in Opts struct (PRNG field).

Internal/External BLOBs

go-imap-sql can store message bodies in two ways: In database rows (works well with SQLite3) or in "external" key-value store (works better with any server-based RDBMS). By default former approach is used.

To switch to "external store", set Opts.ExternalStore field before passing Opts object to New.

If you switch already populated database to "external store", all new messages will be stored in the external store, but old ones will be still in DB.

This repository provides simple filesystem-based key-value store implementation, see fsstore package.

Maddy

You can use go-imap-sql as part of the maddy mail server.

imapsql-ctl

For direct access to database you can use imapsql-ctl console utility. See more information in separate README here.

go install github.com/foxcpp/go-imap-sql/cmd/imapsql-ctl

Documentation

Index

Constants

View Source
const MailboxPathSep = "."
View Source
const SchemaVersion = 2

Incremented each time DB schema changes.

View Source
const VersionMajor = 0
View Source
const VersionMinor = 1
View Source
const VersionPatch = 0
View Source
const VersionStr = "0.2"
View Source
const VersionSuppl = ""

Variables

View Source
var (
	ErrUserAlreadyExists = errors.New("imap: user already exists")
	ErrUserDoesntExists  = errors.New("imap: user doesn't exists")
)

Functions

This section is empty.

Types

type Backend added in v0.2.0

type Backend struct {
	Opts Opts
	DB   *sql.DB
	// contains filtered or unexported fields
}

func New added in v0.2.0

func New(driver, dsn string, opts Opts) (*Backend, error)

func (*Backend) CheckPlain added in v0.2.0

func (b *Backend) CheckPlain(username, password string) bool

func (*Backend) Close added in v0.2.0

func (b *Backend) Close() error

func (*Backend) CreateMessageLimit added in v0.2.0

func (b *Backend) CreateMessageLimit() *uint32

func (*Backend) CreateUser added in v0.2.0

func (b *Backend) CreateUser(username, password string) error

func (*Backend) DeleteUser added in v0.2.0

func (b *Backend) DeleteUser(username string) error

func (*Backend) EnableChildrenExt added in v0.2.0

func (b *Backend) EnableChildrenExt() bool

func (*Backend) GetOrCreateUser added in v0.2.0

func (b *Backend) GetOrCreateUser(username string) (backend.User, error)

func (*Backend) GetUser added in v0.2.0

func (b *Backend) GetUser(username string) (backend.User, error)

func (*Backend) ListUsers added in v0.2.0

func (b *Backend) ListUsers() ([]string, error)

func (*Backend) Login added in v0.2.0

func (b *Backend) Login(_ *imap.ConnInfo, username, password string) (backend.User, error)

func (*Backend) SetMessageLimit added in v0.2.0

func (b *Backend) SetMessageLimit(val *uint32) error

func (*Backend) SetUserPassword added in v0.2.0

func (b *Backend) SetUserPassword(username, newPassword string) error

func (*Backend) Updates added in v0.2.0

func (b *Backend) Updates() <-chan backend.Update

func (*Backend) UserCreds added in v0.2.0

func (b *Backend) UserCreds(username string) (uint64, []byte, []byte, error)

type ExternalStore added in v0.2.0

type ExternalStore interface {
	Create(key string) (io.WriteCloser, error)
	Open(key string) (io.ReadCloser, error)
	Delete(keys []string) error
}

ExternalStore is an interface used by go-imap-sql to store message bodies outside of main database.

type Mailbox added in v0.2.0

type Mailbox struct {
	// contains filtered or unexported fields
}

func (*Mailbox) Check added in v0.2.0

func (m *Mailbox) Check() error

func (*Mailbox) CopyMessages added in v0.2.0

func (m *Mailbox) CopyMessages(uid bool, seqset *imap.SeqSet, dest string) error

func (*Mailbox) CreateMessage added in v0.2.0

func (m *Mailbox) CreateMessage(flags []string, date time.Time, fullBody imap.Literal) error

func (*Mailbox) CreateMessageLimit added in v0.2.0

func (m *Mailbox) CreateMessageLimit() *uint32

func (*Mailbox) DelMessages added in v0.2.0

func (m *Mailbox) DelMessages(uid bool, seqset *imap.SeqSet) error

func (*Mailbox) Expunge added in v0.2.0

func (m *Mailbox) Expunge() error

func (*Mailbox) Info added in v0.2.0

func (m *Mailbox) Info() (*imap.MailboxInfo, error)

func (*Mailbox) ListMessages added in v0.2.0

func (m *Mailbox) ListMessages(uid bool, seqset *imap.SeqSet, items []imap.FetchItem, ch chan<- *imap.Message) error

func (*Mailbox) MoveMessages added in v0.2.0

func (m *Mailbox) MoveMessages(uid bool, seqset *imap.SeqSet, dest string) error

func (*Mailbox) Name added in v0.2.0

func (m *Mailbox) Name() string

func (*Mailbox) SearchMessages added in v0.2.0

func (m *Mailbox) SearchMessages(uid bool, criteria *imap.SearchCriteria) ([]uint32, error)

func (*Mailbox) SetMessageLimit added in v0.2.0

func (m *Mailbox) SetMessageLimit(val *uint32) error

func (*Mailbox) SetSubscribed added in v0.2.0

func (m *Mailbox) SetSubscribed(subscribed bool) error

func (*Mailbox) Status added in v0.2.0

func (m *Mailbox) Status(items []imap.StatusItem) (*imap.MailboxStatus, error)

func (*Mailbox) UidNext added in v0.2.0

func (m *Mailbox) UidNext(tx *sql.Tx) (uint32, error)

func (*Mailbox) UpdateMessagesFlags added in v0.2.0

func (m *Mailbox) UpdateMessagesFlags(uid bool, seqset *imap.SeqSet, operation imap.FlagsOp, flags []string) error

type Opts added in v0.2.0

type Opts struct {
	// Maximum amount of bytes that backend will accept.
	// Intended for use with APPENDLIMIT extension.
	// nil value means no limit, 0 means zero limit (no new messages allowed)
	MaxMsgBytes *uint32

	// Controls when channel returned by Updates should be created.
	// If set to false - channel will be created before NewBackend returns.
	// If set to true - channel will be created upon first call to Updates.
	// Second is useful for tests that don't consume values from Updates
	// channel.
	LazyUpdatesInit bool

	// UpdatesChan allows to pass custom channel object used for unilateral
	// updates dispatching.
	//
	// You can use this to change default updates buffer size (20) or to split
	// initializaton into phases (which allows to break circular dependencies
	// if you need updates channel before database initialization).
	UpdatesChan chan backend.Update

	// Custom randomness source for UIDVALIDITY values generation.
	PRNG Rand

	// (SQLite3 only) Don't force WAL journaling mode.
	NoWAL bool

	// (SQLite3 only) Use different value for busy_timeout. Default is 50000.
	// To set to 0, use -1 (you probably don't want this).
	BusyTimeout int

	// (SQLite3 only) Use EXCLUSIVE locking mode.
	ExclusiveLock bool

	// (SQLite3 only) Change page cache size. Positive value indicates cache
	// size in pages, negative in KiB. If set 0 - SQLite default will be used.
	CacheSize int

	// (SQLite3 only) Repack database file into minimal amount of disk space on
	// Close.
	// It runs VACUUM and PRAGMA wal_checkpoint(TRUNCATE).
	MinimizeOnClose bool

	// External storage to use to store message bodies. If specified - all new messages
	// will be saved to it. However, already existing messages stored in DB
	// directly will not be moved.
	ExternalStore ExternalStore

	// Automatically update database schema on imapsql.New.
	AllowSchemaUpgrade bool
}

Opts structure specifies additional settings that may be set for backend.

Please use names to reference structure members on creation, fields may be reordered or added without major version increment.

type Rand added in v0.2.0

type Rand interface {
	Uint32() uint32
}

type User added in v0.2.0

type User struct {
	// contains filtered or unexported fields
}

func (*User) CreateMailbox added in v0.2.0

func (u *User) CreateMailbox(name string) error

func (*User) CreateMessageLimit added in v0.2.0

func (u *User) CreateMessageLimit() *uint32

func (*User) DeleteMailbox added in v0.2.0

func (u *User) DeleteMailbox(name string) error

func (*User) GetMailbox added in v0.2.0

func (u *User) GetMailbox(name string) (backend.Mailbox, error)

func (*User) ID added in v0.2.0

func (u *User) ID() uint64

func (*User) ListMailboxes added in v0.2.0

func (u *User) ListMailboxes(subscribed bool) ([]backend.Mailbox, error)

func (*User) Logout added in v0.2.0

func (u *User) Logout() error

func (*User) RenameMailbox added in v0.2.0

func (u *User) RenameMailbox(existingName, newName string) error

func (*User) SetMessageLimit added in v0.2.0

func (u *User) SetMessageLimit(val *uint32) error

func (*User) Username added in v0.2.0

func (u *User) Username() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL