Documentation
¶
Overview ¶
Package couch provides a small wrapper around the kivik CouchDB driver to make it easier to configure connections and persist models.
Index ¶
- Constants
- Variables
- func Delete(ctx context.Context, db *kivik.DB, m Persistable) error
- func Fetch(ctx context.Context, db *kivik.DB, d Persistable) error
- func FetchModel(ctx context.Context, db *kivik.DB, m Persistable) error
- func RevAfter(a, b string) bool
- func Store(ctx context.Context, db *kivik.DB, m Persistable) error
- func StoreModel(ctx context.Context, db *kivik.DB, m Persistable) error
- type Client
- type Config
- type Design
- type Document
- type Model
- func (m *Model) GetCreatedAt() at.Timestamp
- func (m *Model) GetDeleted() bool
- func (m *Model) GetID() string
- func (m *Model) GetRev() string
- func (m *Model) GetUpdatedAt() at.Timestamp
- func (m *Model) Persisted() bool
- func (m *Model) Reset()
- func (m *Model) SetID(id string)
- func (m *Model) SetRev(rev string)
- func (m *Model) UpdateTimestamps()
- type Persistable
- type ShardByYear
- type ShardRules
- type Shardable
- type Shards
- type View
Constants ¶
const DefaultSeparator = "_"
DefaultSeparator determines the character(s) to use to separate a prefix from the database name. Underscore is the default to be consistent with SQL table naming and JSON attributes.
Variables ¶
var ( // ErrNotFound is returned when a document does not exist. ErrNotFound = errors.New("not found") // ErrAlreadyExists is returned on a document revision conflict. ErrAlreadyExists = errors.New("already exists") )
Errors returned by the persistence helpers, wrapping the underlying kivik/CouchDB failure. Match them with errors.Is.
Functions ¶
func Fetch ¶
Fetch wraps around the kivik persistence methods to update the model with the data from the database or raise an error if it does not exist.
func FetchModel ¶
FetchModel is the now deprecated way of Fetching a model from the database.
func RevAfter ¶
RevAfter returns true if CouchDB revision a is newer than revision b. Revisions have the format "<seq>-<hash>", e.g. "13-a9e7c9c1...". This must be used instead of direct string comparison (a > b) because lexicographic ordering breaks when sequence numbers cross digit boundaries (e.g. "9-xxx" > "13-xxx" is true lexicographically but incorrect).
func Store ¶
Store attempts to persist the provided persistable object to the database.
A model carrying the `_deleted` marker (see Model.Deleted) is refused: putting it back is how CouchDB deletes a document, and a save that silently deletes instead would be a nasty way to find that out. Deletions read from a change feed are meant to be reacted to, not written; use Delete to remove a document.
func StoreModel ¶
StoreModel is the deprecated way of persisting updates to the database and simply wraps around the Store method.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps around a kivik package Client and helps make it easier to configure the connection and prepare the database.
func New ¶
New provides a new instance of the default CouchDB client. This call will block until the server responds or the context causes a timeout.
type Config ¶
type Config struct {
Scheme string `json:"scheme"`
Host string `json:"host"`
Port string `json:"port"`
Username string `json:"username"`
Password string `json:"password"`
Prefix string `json:"prefix"`
Separator string `json:"separator"`
}
Config is used to define the connection details to a database.
type Design ¶
type Design struct {
Model
Language string `json:"language"`
// Options stores additional options for the design document.
Options map[string]any `json:"options,omitempty"`
Filters map[string]string `json:"filters,omitempty"`
Views map[string]*View `json:"views,omitempty"`
}
Design represents the special design documents used to query documents using pre-defined indexes. Only designs that have changed will be synchronised with the database using a simple SHA256 comparison algorithm that checks for changes in the views.
func (*Design) Checksum ¶
Checksum generates a SHA256 sum by joining all the filters and views together to form a single string and running the result through the digest algorithm. The result is a Hexadecimal string.
func (*Design) SetFilter ¶
SetFilter adds the provided filter to the design document. Existing filters with the same name will be replaced.
type Document ¶
Document is a simplified object that conforms to the Persistable implementation. Unlike the Model implementation, it doesn't include any timestamping.
func (*Document) Persisted ¶
Persisted returns true if the revision has been set, a value that should always be provided by the database server.
func (*Document) SetRev ¶
SetRev update's the documents's revision ID. The should mainly be used by persistence layers.
func (*Document) UpdateTimestamps ¶
func (d *Document) UpdateTimestamps()
UpdateTimestamps in the context of a simple CouchDB document does nothing.
type Model ¶
type Model struct {
ID string `json:"_id,omitempty"`
Rev string `json:"_rev,omitempty"`
// Attachments keeps together the special list of attachments that belong to
// model. Without this placeholder, they'll get deleted after an update.
Attachments kivik.Attachments `json:"_attachments,omitempty"`
// Deleted reflects CouchDB's `_deleted` marker: true means this is a
// tombstone rather than a document. It is set when reading a deletion —
// from a change feed started WithDeletions, or anywhere else a tombstone
// surfaces — so consumers can react to a document being removed, including
// one deleted by hand in the database.
//
// It is read-only in practice: Store refuses to persist a model carrying
// it, since writing `_deleted` back is how a document gets deleted and
// having that happen as a side effect of a save would be surprising. Use
// Delete instead.
Deleted bool `json:"_deleted,omitempty"`
CreatedAt at.Timestamp `json:"created_at"`
UpdatedAt at.Timestamp `json:"updated_at"`
}
Model is a standard representation of a model to be stored in CouchDB that takes care of the ID, Revision, and adds timestamps.
func (*Model) GetCreatedAt ¶
GetCreatedAt provides the model's CreatedAt timestamp in situations where the model is being treated as an interface. May be zero if the model has not been prepared for persistence.
func (*Model) GetDeleted ¶ added in v0.2.0
GetDeleted reports whether the model represents a deleted document, so persistence layers can check the marker through an interface rather than depending on the concrete type.
func (*Model) GetUpdatedAt ¶
GetUpdatedAt provides the model's UpdatedAt timestamp in situations where the model is being treated as an interface. May be zero if the model has not been prepared for persistence.
func (*Model) Persisted ¶
Persisted returns true if the revision has been set, a value that should always be provided by the database server.
func (*Model) Reset ¶
func (m *Model) Reset()
Reset sets the rev, created and update at timestamps to zero usually so that the same model can be persisted to multiple database without having the revision and timestamps copied between instances.
func (*Model) SetRev ¶
SetRev update's the model's revision ID. The should mainly be used by persistence layers.
func (*Model) UpdateTimestamps ¶
func (m *Model) UpdateTimestamps()
UpdateTimestamps ensures the model's created and update at stamps are set.
type Persistable ¶
type Persistable interface {
UpdateTimestamps()
GetID() string
GetRev() string
SetID(string)
SetRev(string)
}
Persistable defines what is expected from a model for it to be persisted to the database.
type ShardByYear ¶
type ShardByYear struct {
// contains filtered or unexported fields
}
ShardByYear implements database sharding by year.
func NewShardByYear ¶
func NewShardByYear(name string, start int) *ShardByYear
NewShardByYear provides a common implementation of sharding databases according to the year encoded in a time-based UUID (versions 1, 6 and 7). For this to work, the model must implement a ShardValue method that returns its UUID as a string:
```
func (m *Model) ShardValue() interface{} {
return m.ID
}
```
Shards are always ordered by reverse chronological order, so the newest shards are listed first.
This slightly naive implementation assumes that the service will be restarted and migrated at least once per year so that the following year's shard is prepared.
If the ShardValue is a string that is not a UUID, it is assumed to be the name of the shard and used directly.
func NewShardByYearWithStatic ¶
func NewShardByYearWithStatic(name string, start int, static string) *ShardByYear
NewShardByYearWithStatic creates a new shard rule that supports time-based UUIDs **and** random/name-based ones (versions 3, 4 and 5).
The "static" parameter enables support for non-time-based IDs that will be persisted to a fixed shard instead of by year. This is useful to being able to distinguish between data that is always relevant (static) and data that becomes less useful over time.
func (*ShardByYear) Key ¶
func (s *ShardByYear) Key(v any) (string, error)
Key converts the shardable key's value into a usable shard. The value must be a string: either a UUID (whose timestamp determines the year) or an already-prepared shard name.
func (*ShardByYear) List ¶
func (s *ShardByYear) List() []string
List provides an array of acceptable shards
func (*ShardByYear) Template ¶
func (s *ShardByYear) Template() string
Template provides the base name into which the shard will be inserted.
type ShardRules ¶
type ShardRules interface {
// Template provides the base name into which the shard will be inserted.
// It must be an fmt.Sprintf format string with a single %s verb where
// the shard name is substituted (see NewShards).
Template() string
// List provides an array of acceptable shards
List() []string
// Key provides a usable string from a shardable value.
Key(v interface{}) (string, error)
}
ShardRules provides the basic details we require to properly handle sharding of a type of object.
type Shardable ¶
type Shardable interface {
ShardValue() interface{}
}
Shardable defines what we expect from a document, entity, or model that we intend to persist to the database.
type Shards ¶
type Shards struct {
// contains filtered or unexported fields
}
Shards is a special implementation of sharding at the software level. The aim is to make it easier to manage a set of separate CouchDB databases each of which is used according to sharding details provided.
func NewShards ¶
func NewShards(client *Client, rules ShardRules) *Shards
NewShards instantiates a new sharding wrapper. Databases cannot be assigned dynamically, a complete list of databases must be prepared.