couchdb

package
v0.0.0-...-820a931 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2024 License: AGPL-3.0 Imports: 24 Imported by: 58

Documentation

Index

Constants

View Source
const (
	// ChangesModeNormal is the only mode supported by cozy-stack
	ChangesModeNormal ChangesFeedMode = "normal"
	// ChangesStyleAllDocs pass all revisions including conflicts
	ChangesStyleAllDocs ChangesFeedStyle = "all_docs"
	// ChangesStyleMainOnly only pass the winning revision
	ChangesStyleMainOnly ChangesFeedStyle = "main_only"
)
View Source
const (
	EventCreate = realtime.EventCreate
	EventUpdate = realtime.EventUpdate
	EventDelete = realtime.EventDelete
)

Events to hook into

View Source
const IndexViewsVersion int = 37

IndexViewsVersion is the version of current definition of views & indexes. This number should be incremented when this file changes.

View Source
const MaxString = mango.MaxString

MaxString is the unicode character "\uFFFF", useful in query as a upperbound for string.

View Source
const SelectorReferencedBy = "referenced_by"

SelectorReferencedBy is the string constant for the references in a JSON document.

Variables

View Source
var ContactByEmail = &View{
	Name:    "contacts-by-email",
	Doctype: consts.Contacts,
	Map: `
function(doc) {
	if (isArray(doc.email)) {
		for (var i = 0; i < doc.email.length; i++) {
			emit(doc.email[i].address, doc._id);
		}
	}
}
`,
}

ContactByEmail is used to find a contact by its email address

View Source
var DirNotSynchronizedOnView = &View{
	Name:    "not-synchronized-on",
	Doctype: consts.Files,
	Reduce:  "_count",
	Map: `
function(doc) {
  if (doc.type === "directory" && isArray(doc.not_synchronized_on)) {
    for (var i = 0; i < doc.not_synchronized_on.length; i++) {
      emit([doc.not_synchronized_on[i].type, doc.not_synchronized_on[i].id]);
    }
  }
}`,
}

DirNotSynchronizedOnView is the view used for fetching directories that are not synchronized on a given device.

View Source
var DiskUsageView = &View{
	Name:    "disk-usage",
	Doctype: consts.Files,
	Map: `
function(doc) {
  if (doc.type === 'file') {
    emit(doc.dir_id, +doc.size);
  }
}
`,
	Reduce: "_sum",
}

DiskUsageView is the view used for computing the disk usage for files

View Source
var DomainAndAliasesView = &View{
	Name:    "domain-and-aliases",
	Doctype: consts.Instances,
	Map: `
function(doc) {
  emit(doc.domain);
  if (isArray(doc.domain_aliases)) {
    for (var i = 0; i < doc.domain_aliases.length; i++) {
      emit(doc.domain_aliases[i]);
    }
  }
}
`,
}

DomainAndAliasesView defines a view to fetch instances by domain and domain aliases.

View Source
var FilesByParentView = &View{
	Name:    "by-parent-type-name",
	Doctype: consts.Files,
	Map: `
function(doc) {
  emit([doc.dir_id, doc.type, doc.name])
}`,
	Reduce: "_count",
}

FilesByParentView is the view used for fetching files referenced by a given document

View Source
var FilesReferencedByView = &View{
	Name:    "referenced-by",
	Doctype: consts.Files,
	Reduce:  "_count",
	Map: `
function(doc) {
  if (isArray(doc.referenced_by)) {
    for (var i = 0; i < doc.referenced_by.length; i++) {
      emit([doc.referenced_by[i].type, doc.referenced_by[i].id]);
    }
  }
}`,
}

FilesReferencedByView is the view used for fetching files referenced by a given document

View Source
var Indexes = []*mango.Index{

	mango.MakeIndex(consts.Permissions, "by-source-and-type", mango.IndexDef{Fields: []string{"source_id", "type"}}),

	mango.MakeIndex(consts.Files, "dir-children", mango.IndexDef{Fields: []string{"dir_id", "_id"}}),

	mango.MakeIndex(consts.Files, "dir-by-path", mango.IndexDef{Fields: []string{"path"}}),

	mango.MakeIndex(consts.Files, "by-mime-updated-at", mango.IndexDef{Fields: []string{"mime", "trashed", "updated_at"}}),

	mango.MakeIndex(consts.Files, "with-conflicts", mango.IndexDef{Fields: []string{"_conflicts"}}),

	mango.MakeIndex(consts.Files, "by-sharing-status", mango.IndexDef{Fields: []string{"metadata.sharing.status"}}),

	mango.MakeIndex(consts.Files, "by-dir-id-updated-at", mango.IndexDef{Fields: []string{"dir_id", "updated_at"}}),

	mango.MakeIndex(consts.Jobs, "by-worker-and-state", mango.IndexDef{Fields: []string{"worker", "state"}}),
	mango.MakeIndex(consts.Jobs, "by-trigger-id", mango.IndexDef{Fields: []string{"trigger_id", "queued_at"}}),
	mango.MakeIndex(consts.Jobs, "by-queued-at", mango.IndexDef{Fields: []string{"queued_at"}}),

	mango.MakeIndex(consts.Triggers, "by-worker-and-type", mango.IndexDef{Fields: []string{"worker", "type"}}),

	mango.MakeIndex(consts.OAuthClients, "by-client-name", mango.IndexDef{Fields: []string{"client_name"}}),
	mango.MakeIndex(consts.OAuthClients, "by-notification-platform", mango.IndexDef{Fields: []string{"notification_platform"}}),
	mango.MakeIndex(consts.OAuthClients, "connected-user-clients", mango.IndexDef{
		Fields: []string{"client_kind", "client_name"},
		PartialFilter: mango.And(
			mango.In("client_kind", []interface{}{"browser", "desktop", "mobile"}),
			mango.NotExists("pending"),
		),
	}),

	mango.MakeIndex(consts.SessionsLogins, "by-os-browser-ip", mango.IndexDef{Fields: []string{"os", "browser", "ip"}}),

	mango.MakeIndex(consts.Notifications, "by-source-id", mango.IndexDef{Fields: []string{"source_id", "created_at"}}),

	mango.MakeIndex(consts.Contacts, "by-me", mango.IndexDef{Fields: []string{"me"}}),

	mango.MakeIndex(consts.BitwardenCiphers, "by-folder-id", mango.IndexDef{Fields: []string{"folder_id"}}),
	mango.MakeIndex(consts.BitwardenCiphers, "by-organization-id", mango.IndexDef{Fields: []string{"organization_id"}}),

	mango.MakeIndex(consts.Contacts, "by-groups", mango.IndexDef{Fields: []string{"relationships.groups.data"}}),

	mango.MakeIndex(consts.Sharings, "active", mango.IndexDef{Fields: []string{"active"}}),
}

Indexes is the index list required by an instance to run properly.

View Source
var OldVersionsDiskUsageView = &View{
	Name:    "old-versions-disk-usage",
	Doctype: consts.FilesVersions,
	Map: `
function(doc) {
  emit(doc._id, +doc.size);
}
`,
	Reduce: "_sum",
}

OldVersionsDiskUsageView is the view used for computing the disk usage for the old versions of file contents.

View Source
var PermissionsByDoctype = &View{
	Name:    "permissions-by-doctype",
	Doctype: consts.Permissions,
	Map: `
function(doc) {
  if (doc.permissions) {
    Object.keys(doc.permissions).forEach(function(k) {
	  emit([doc.permissions[k].type, doc.type]);
	});
  }
}
`,
}

PermissionsByDoctype returns a list of permissions that have at least one rule for the given doctype.

View Source
var PermissionsShareByCView = &View{
	Name:    "byToken",
	Doctype: consts.Permissions,
	Map: `
function(doc) {
  if (doc.type && doc.type.slice(0, 5) === "share" && doc.codes) {
    Object.keys(doc.codes).forEach(function(k) {
      emit(doc.codes[k]);
    })
  }
}`,
}

PermissionsShareByCView is the view for fetching the permissions associated to a document via a token code.

View Source
var PermissionsShareByDocView = &View{
	Name:    "byDoc",
	Doctype: consts.Permissions,
	Map: `
function(doc) {
  if (doc.type === "share" && doc.permissions) {
    Object.keys(doc.permissions).forEach(function(k) {
      var p = doc.permissions[k];
      var selector = p.selector || "_id";
      for (var i=0; i<p.values.length; i++) {
        emit([p.type, selector, p.values[i]], p.verbs);
      }
    });
  }
}`,
}

PermissionsShareByDocView is the view for fetching a list of permissions associated to a list of IDs.

View Source
var PermissionsShareByShortcodeView = &View{
	Name:    "by-short-code",
	Doctype: consts.Permissions,
	Map: `
function(doc) {
	if(doc.shortcodes) {
		for(var idx in doc.shortcodes) {
			emit(doc.shortcodes[idx], idx);
		}
	}
}`,
}

PermissionsShareByShortcodeView is the view for fetching the permissions associated to a document via a token code.

View Source
var ReferencedBySortedByDatetimeView = &View{
	Name:    "referenced-by-sorted-by-datetime",
	Doctype: consts.Files,
	Reduce:  "_count",
	Map: `
function(doc) {
  if (isArray(doc.referenced_by)) {
    for (var i = 0; i < doc.referenced_by.length; i++) {
      var datetime = (doc.metadata && doc.metadata.datetime) || '';
      emit([doc.referenced_by[i].type, doc.referenced_by[i].id, datetime]);
    }
  }
}`,
}

ReferencedBySortedByDatetimeView is the view used for fetching files referenced by a given document, sorted by the datetime

View Source
var SharedDocsBySharingID = &View{
	Name:    "shared-docs-by-sharingid",
	Doctype: consts.Shared,
	Map: `
function(doc) {
  if (doc.infos) {
    Object.keys(doc.infos).forEach(function(k) {
      emit(k, doc._id);
    });
  }
}`,
}

SharedDocsBySharingID is the view for fetching a list of shared doctype/id associated with a sharingid

View Source
var SharingsByDocTypeView = &View{
	Name:    "sharings-by-doctype",
	Doctype: consts.Sharings,
	Map: `
function(doc) {
	if (isArray(doc.rules)) {
		for (var i = 0; i < doc.rules.length; i++) {
			if (!doc.rules[i].local) {
				emit(doc.rules[i].doctype, doc._id);
			}
		}
	}
}`,
}

SharingsByDocTypeView is the view for fetching a list of sharings associated with a doctype

Views is the list of all views that are created by the stack.

Functions

func AddHook

func AddHook(doctype, event string, hook listener)

AddHook adds an hook for the given doctype and event. Useful for special doctypes cleanup

func AllDoctypes

func AllDoctypes(db prefixer.Prefixer) ([]string, error)

AllDoctypes returns a list of all the doctypes that have a database on a given instance

func BulkDeleteDocs

func BulkDeleteDocs(db prefixer.Prefixer, doctype string, docs []Doc) error

BulkDeleteDocs is used to delete serveral documents in one call.

func BulkForceUpdateDocs

func BulkForceUpdateDocs(db prefixer.Prefixer, doctype string, docs []map[string]interface{}) error

BulkForceUpdateDocs is used to update several docs in one call, and to force the revisions history. It is used by replications.

func BulkGetDocs

func BulkGetDocs(db prefixer.Prefixer, doctype string, payload []IDRev) ([]map[string]interface{}, error)

BulkGetDocs returns the documents with the given id at the given revision

func BulkUpdateDocs

func BulkUpdateDocs(db prefixer.Prefixer, doctype string, docs, olddocs []interface{}) error

BulkUpdateDocs is used to update several docs in one call, as a bulk. olddocs parameter is used for realtime / event triggers.

func CheckDesignDocCanBeDeleted

func CheckDesignDocCanBeDeleted(doctype, name string) bool

CheckDesignDocCanBeDeleted will return false for an index or view used by the stack.

func CheckStatus

func CheckStatus(ctx context.Context) (time.Duration, error)

CheckStatus checks that the stack can talk to CouchDB, and returns an error if it is not the case.

func Compact

func Compact(db prefixer.Prefixer, doctype string) error

Compact asks CouchDB to compact a database.

func Copy

func Copy(db prefixer.Prefixer, doctype, path, destination string) (map[string]interface{}, error)

Copy copies an existing doc to a specified destination

func CountAllDocs

func CountAllDocs(db prefixer.Prefixer, doctype string) (int, error)

CountAllDocs returns the number of documents of the given doctype.

func CountNormalDocs

func CountNormalDocs(db prefixer.Prefixer, doctype string) (int, error)

CountNormalDocs returns the number of documents of the given doctype, and excludes the design docs from the count.

func CreateDB

func CreateDB(db prefixer.Prefixer, doctype string) error

CreateDB creates the necessary database for a doctype

func CreateDoc

func CreateDoc(db prefixer.Prefixer, doc Doc) error

CreateDoc is used to persist the given document in the couchdb database. The document's SetRev and SetID function will be called with the document's new ID and Rev. This function creates a database if this is the first document of its type

func CreateNamedDoc

func CreateNamedDoc(db prefixer.Prefixer, doc Doc) error

CreateNamedDoc persist a document with an ID. if the document already exist, it will return a 409 error. The document ID should be fillled. The doc SetRev function will be called with the new rev.

func CreateNamedDocWithDB

func CreateNamedDocWithDB(db prefixer.Prefixer, doc Doc) error

CreateNamedDocWithDB is equivalent to CreateNamedDoc but creates the database if it does not exist

func DefineIndex

func DefineIndex(db prefixer.Prefixer, index *mango.Index) error

DefineIndex define the index on the doctype database see query package on how to define an index

func DefineIndexes

func DefineIndexes(g *errgroup.Group, db prefixer.Prefixer, indexes []*mango.Index)

DefineIndexes defines a list of indexes.

func DefineView

func DefineView(db prefixer.Prefixer, v *View) error

DefineView ensure that a view exists, or creates it.

func DefineViews

func DefineViews(g *errgroup.Group, db prefixer.Prefixer, views []*View)

DefineViews creates a design doc with some views

func DeleteAllDBs

func DeleteAllDBs(db prefixer.Prefixer) error

DeleteAllDBs will remove all the couchdb doctype databases for a couchdb.DB.

func DeleteDB

func DeleteDB(db prefixer.Prefixer, doctype string) error

DeleteDB destroy the database for a doctype

func DeleteDoc

func DeleteDoc(db prefixer.Prefixer, doc Doc) error

DeleteDoc deletes a struct implementing the couchb.Doc interface If the document's current rev does not match the one passed, a CouchdbError(409 conflict) will be returned. The document's SetRev will be called with tombstone revision

func DeleteLocal

func DeleteLocal(db prefixer.Prefixer, doctype, id string) error

DeleteLocal will delete a local document in CouchDB.

func EnsureDBExist

func EnsureDBExist(db prefixer.Prefixer, doctype string) error

EnsureDBExist creates the database for the doctype if it doesn't exist

func EscapeCouchdbName

func EscapeCouchdbName(name string) string

EscapeCouchdbName can be used to build the name of a database from the instance prefix and doctype.

func ExecView

func ExecView(db prefixer.Prefixer, view *View, req *ViewRequest, results interface{}) error

ExecView executes the specified view function

func FindDocs

func FindDocs(db prefixer.Prefixer, doctype string, req *FindRequest, results interface{}) error

FindDocs returns all documents matching the passed FindRequest documents will be unmarshalled in the provided results slice.

func FindDocsUnoptimized

func FindDocsUnoptimized(db prefixer.Prefixer, doctype string, req *FindRequest, results interface{}) error

FindDocsUnoptimized allows search on non-indexed fields. /!\ Use with care

func ForeachDocs

func ForeachDocs(db prefixer.Prefixer, doctype string, fn func(id string, doc json.RawMessage) error) error

ForeachDocs traverse all the documents from the given database with the specified doctype and calls a function for each document.

func ForeachDocsWithCustomPagination

func ForeachDocsWithCustomPagination(db prefixer.Prefixer, doctype string, limit int, fn func(id string, doc json.RawMessage) error) error

ForeachDocsWithCustomPagination traverse all the documents from the given database, and calls a function for each document. The documents are fetched from CouchDB with a pagination with a custom number of items per page.

func GetAllDocs

func GetAllDocs(db prefixer.Prefixer, doctype string, req *AllDocsRequest, results interface{}) (err error)

GetAllDocs returns all documents of a specified doctype. It filters out the possible _design document.

func GetDesignDocs

func GetDesignDocs(db prefixer.Prefixer, doctype string, req *AllDocsRequest, results interface{}) (err error)

GetDesignDocs does the same as GetAllDocs, but it keeps the design docs.

func GetDoc

func GetDoc(db prefixer.Prefixer, doctype, id string, out Doc) error

GetDoc fetches a document by its docType and id It fills with out by json.Unmarshal-ing

func GetDocRev

func GetDocRev(db prefixer.Prefixer, doctype, id, rev string, out Doc) error

GetDocRev fetch a document by its docType and ID on a specific revision, out is filled with the document by json.Unmarshal-ing

func GetDocWithRevs

func GetDocWithRevs(db prefixer.Prefixer, doctype, id string, out Doc) error

GetDocWithRevs fetches a document by its docType and ID. out is filled with the document by json.Unmarshal-ing and contains the list of all revisions

func GetLocal

func GetLocal(db prefixer.Prefixer, doctype, id string) (map[string]interface{}, error)

GetLocal fetch a local document from CouchDB http://docs.couchdb.org/en/stable/api/local.html#get--db-_local-docid

func IndexesByDoctype

func IndexesByDoctype(doctype string) []*mango.Index

IndexesByDoctype returns the list of indexes for a specified doc type.

func InitGlobalDB

func InitGlobalDB(ctx context.Context) error

InitGlobalDB defines views and indexes on the global databases. It is called on every startup of the stack.

func IsConflictError

func IsConflictError(err error) bool

IsConflictError checks if an error from the error tree contains a CouchDB 409 (Conflict) status code.

func IsDeletedError

func IsDeletedError(err error) bool

IsDeletedError checks if an error from the error tree contains a CouchDB a "not_found" error with the "deleted" reason. It means that a document has existed but is now deleted.

func IsFileExists

func IsFileExists(err error) bool

IsFileExists checks if an error from the error tree contains a CouchDB a "file_exists" error.

func IsInternalServerError

func IsInternalServerError(err error) bool

IsInternalServerError checks if an error from the error tree contains a CouchDB error with a 5xx code

func IsNoDatabaseError

func IsNoDatabaseError(err error) bool

IsNoDatabaseError checks if an error from the error tree contains a CouchDB a "no_db_file" error.

func IsNoUsableIndexError

func IsNoUsableIndexError(err error) bool

IsNoUsableIndexError checks if an error from the error tree contains a "no_usable_index" error.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError checks if an error from the error tree contains a CouchDB a "not_found" error.

func MakeAllDocsRequest

func MakeAllDocsRequest(db prefixer.Prefixer, doctype string, params *AllDocsRequest) (io.ReadCloser, error)

func NewEmptyObjectOfSameType

func NewEmptyObjectOfSameType(obj interface{}) interface{}

NewEmptyObjectOfSameType takes an object and returns a new object of the same type. For example, if NewEmptyObjectOfSameType is called with a pointer to a JSONDoc, it will return a pointer to an empty JSONDoc (and not a nil pointer).

func Proxy

func Proxy(db prefixer.Prefixer, doctype, path string) *httputil.ReverseProxy

Proxy generate a httputil.ReverseProxy which forwards the request to the correct route.

func ProxyBulkDocs

func ProxyBulkDocs(db prefixer.Prefixer, doctype string, req *http.Request) (*httputil.ReverseProxy, *http.Request, error)

ProxyBulkDocs generates a httputil.ReverseProxy to forward the couchdb request on the _bulk_docs endpoint. This endpoint is specific since it will mutate many document in database, the stack has to read the response from couch to emit the correct realtime events.

func PutLocal

func PutLocal(db prefixer.Prefixer, doctype, id string, doc map[string]interface{}) error

PutLocal will put a local document in CouchDB. Note that you should put the last revision in `doc` to avoid conflicts.

func RTEvent

func RTEvent(db prefixer.Prefixer, verb string, doc, oldDoc Doc)

RTEvent published a realtime event for a couchDB change

func ResetDB

func ResetDB(db prefixer.Prefixer, doctype string) error

ResetDB destroy and recreate the database for a doctype

func StaticChangesFilter

func StaticChangesFilter(filter string) (string, error)

StaticChangesFilter checks that the filter is static (ie doesn't depend of a design doc)

func UpdateDoc

func UpdateDoc(db prefixer.Prefixer, doc Doc) error

UpdateDoc update a document. The document ID and Rev should be filled. The doc SetRev function will be called with the new rev.

func UpdateDocWithOld

func UpdateDocWithOld(db prefixer.Prefixer, doc, oldDoc Doc) error

UpdateDocWithOld updates a document, like UpdateDoc. The difference is that if we already have oldDoc there is no need to refetch it from database.

func UpdateIndexesAndViews

func UpdateIndexesAndViews(db prefixer.Prefixer, indexes []*mango.Index, views []*View) error

UpdateIndexesAndViews creates views and indexes that are missing or not up-to-date.

func Upsert

func Upsert(db prefixer.Prefixer, doc Doc) error

Upsert create the doc or update it if it already exists.

Types

type AllDocsRequest

type AllDocsRequest struct {
	Descending bool     `url:"descending,omitempty"`
	Limit      int      `url:"limit,omitempty"`
	Skip       int      `url:"skip,omitempty"`
	StartKey   string   `url:"startkey,omitempty"`
	EndKey     string   `url:"endkey,omitempty"`
	Keys       []string `url:"keys,omitempty"`
}

AllDocsRequest is used to build a _all_docs request

func (*AllDocsRequest) Values

func (adr *AllDocsRequest) Values() (url.Values, error)

Values transforms a AllDocsRequest into a query string suitable for couchdb ie, where non-scalar fields have been JSON+URL encoded.

type AllDocsResponse

type AllDocsResponse struct {
	Offset    int          `json:"offset"`
	TotalRows int          `json:"total_rows"`
	Rows      []AllDocsRow `json:"rows"`
}

AllDocsResponse is the response we receive from an _all_docs request

type AllDocsRow

type AllDocsRow struct {
	ID  string          `json:"id"`
	Doc json.RawMessage `json:"doc"`
}

AllDocsRow is a row inside the _all_docs response

type BulkGetResponse

type BulkGetResponse struct {
	Results []struct {
		Docs []struct {
			OK map[string]interface{} `json:"ok"`
		} `json:"docs"`
	} `json:"results"`
}

BulkGetResponse is the response we receive from a _bulk_get request

type Change

type Change struct {
	DocID   string  `json:"id"`
	Seq     string  `json:"seq"`
	Doc     JSONDoc `json:"doc,omitempty"`
	Deleted bool    `json:"deleted,omitempty"`
	Changes []struct {
		Rev string `json:"rev"`
	} `json:"changes"`
}

A Change is an atomic change in couchdb

type ChangesFeedMode

type ChangesFeedMode string

ChangesFeedMode is a value for the feed parameter of a ChangesRequest

func ValidChangesMode

func ValidChangesMode(feed string) (ChangesFeedMode, error)

ValidChangesMode convert any string into a ChangesFeedMode or gives an error if the string is invalid.

type ChangesFeedStyle

type ChangesFeedStyle string

ChangesFeedStyle is a value for the style parameter of a ChangesRequest

func ValidChangesStyle

func ValidChangesStyle(style string) (ChangesFeedStyle, error)

ValidChangesStyle convert any string into a ChangesFeedStyle or gives an error if the string is invalid.

type ChangesRequest

type ChangesRequest struct {
	DocType string `url:"-"`
	// see Changes Feeds. Default is normal.
	Feed ChangesFeedMode `url:"feed,omitempty"`
	// Maximum period in milliseconds to wait for a change before the response
	// is sent, even if there are no results. Only applicable for longpoll or
	// continuous feeds. Default value is specified by httpd/changes_timeout
	// configuration option. Note that 60000 value is also the default maximum
	// timeout to prevent undetected dead connections.
	Timeout int `url:"timeout,omitempty"`
	// Period in milliseconds after which an empty line is sent in the results.
	// Only applicable for longpoll, continuous, and eventsource feeds. Overrides
	// any timeout to keep the feed alive indefinitely. Default is 60000. May be
	// true to use default value.
	Heartbeat int `url:"heartbeat,omitempty"`
	// Includes conflicts information in response. Ignored if include_docs isn’t
	// true. Default is false.
	Conflicts bool `url:"conflicts,omitempty"`
	// Return the change results in descending sequence order (most recent change
	// first). Default is false.
	Descending bool `url:"descending,omitempty"`
	// Include the associated document with each result. If there are conflicts,
	// only the winning revision is returned. Default is false.
	IncludeDocs bool `url:"include_docs,omitempty"`
	// Include the Base64-encoded content of attachments in the documents that
	// are included if include_docs is true. Ignored if include_docs isn’t true.
	// Default is false.
	Attachments bool `url:"attachments,omitempty"`
	// Include encoding information in attachment stubs if include_docs is true
	// and the particular attachment is compressed. Ignored if include_docs isn’t
	// true. Default is false.
	AttEncodingInfo bool `url:"att_encoding_info,omitempty"`
	// Alias of Last-Event-ID header.
	LastEventID int `url:"last,omitempty"`
	// Limit number of result rows to the specified value (note that using 0 here
	//  has the same effect as 1).
	Limit int `url:"limit,omitempty"`
	// Start the results from the change immediately after the given update
	// sequence. Can be valid update sequence or now value. Default is 0.
	Since string `url:"since,omitempty"`
	// Specifies how many revisions are returned in the changes array. The
	// default, main_only, will only return the current “winning” revision;
	// all_docs will return all leaf revisions (including conflicts and deleted
	// former conflicts).
	Style ChangesFeedStyle `url:"style,omitempty"`
	// Reference to a filter function from a design document that will filter
	// whole stream emitting only filtered events. See the section Change
	// Notifications in the book CouchDB The Definitive Guide for more
	// information.
	Filter string `url:"filter,omitempty"`
	// Allows to use view functions as filters. Documents counted as “passed” for
	// view filter in case if map function emits at least one record for them.
	// See _view for more info.
	View string `url:"view,omitempty"`
	// SeqInterval tells CouchDB to only calculate the update seq with every
	// Nth result returned. It is used by PouchDB replication, and helps to
	// lower the load on a CouchDB cluster.
	SeqInterval int `url:"seq_interval,omitempty"`
}

A ChangesRequest are all parameters than can be passed to a changes feed

type ChangesResponse

type ChangesResponse struct {
	LastSeq string   `json:"last_seq"` // Last change update sequence
	Pending int      `json:"pending"`  // Count of remaining items in the feed
	Results []Change `json:"results"`  // Changes made to a database
}

A ChangesResponse is the response provided by a GetChanges call

func GetChanges

func GetChanges(db prefixer.Prefixer, req *ChangesRequest) (*ChangesResponse, error)

GetChanges returns a list of changes in couchdb

func PostChanges

func PostChanges(db prefixer.Prefixer, req *ChangesRequest, body io.ReadCloser) (*ChangesResponse, error)

PostChanges returns a list of changes in couchdb

type Cursor

type Cursor interface {
	HasMore() bool
	ApplyTo(req *ViewRequest)
	UpdateFrom(res *ViewResponse)
}

A Cursor holds a reference to a page in a couchdb View

func NewKeyCursor

func NewKeyCursor(limit int, key interface{}, id string) Cursor

NewKeyCursor returns a new key based Cursor pointing to the given start_key & startkey_docid

func NewSkipCursor

func NewSkipCursor(limit, skip int) Cursor

NewSkipCursor returns a new skip based Cursor pointing to the page after skip items

type DBStatusResponse

type DBStatusResponse struct {
	DBName    string `json:"db_name"`
	UpdateSeq string `json:"update_seq"`
	Sizes     struct {
		File     int `json:"file"`
		External int `json:"external"`
		Active   int `json:"active"`
	} `json:"sizes"`
	PurgeSeq interface{} `json:"purge_seq"` // Was an int before CouchDB 2.3, and a string since then
	Other    struct {
		DataSize int `json:"data_size"`
	} `json:"other"`
	DocDelCount       int    `json:"doc_del_count"`
	DocCount          int    `json:"doc_count"`
	DiskSize          int    `json:"disk_size"`
	DiskFormatVersion int    `json:"disk_format_version"`
	DataSize          int    `json:"data_size"`
	CompactRunning    bool   `json:"compact_running"`
	InstanceStartTime string `json:"instance_start_time"`
}

DBStatusResponse is the response from DBStatus

func DBStatus

func DBStatus(db prefixer.Prefixer, doctype string) (*DBStatusResponse, error)

DBStatus responds with informations on the database: size, number of documents, sequence numbers, etc.

type DesignDoc

type DesignDoc struct {
	ID    string           `json:"_id,omitempty"`
	Rev   string           `json:"_rev,omitempty"`
	Lang  string           `json:"language"`
	Views map[string]*View `json:"views"`
}

DesignDoc is the structure if a _design doc containing views

type Doc

type Doc interface {
	ID() string
	Rev() string
	DocType() string
	Clone() Doc

	SetID(id string)
	SetRev(rev string)
}

Doc is the interface that encapsulate a couchdb document, of any serializable type. This interface defines method to set and get the ID of the document.

type DocReference

type DocReference struct {
	ID   string `json:"id"`
	Type string `json:"type"`
}

DocReference is a reference to a document

type Error

type Error struct {
	StatusCode  int    `json:"status_code"`
	CouchdbJSON []byte `json:"-"`
	Name        string `json:"error"`
	Reason      string `json:"reason"`
	Original    error  `json:"-"`
}

Error represent an error from couchdb

func IsCouchError

func IsCouchError(err error) (*Error, bool)

IsCouchError returns whether or not one error from the error tree is of type couchdb.Error.

func (*Error) Error

func (e *Error) Error() string

func (*Error) JSON

func (e *Error) JSON() map[string]interface{}

JSON returns the json representation of this error

type ExecutionStats

type ExecutionStats struct {
	TotalKeysExamined       int     `json:"total_keys_examined,omitempty"`
	TotalDocsExamined       int     `json:"total_docs_examined,omitempty"`
	TotalQuorumDocsExamined int     `json:"total_quorum_docs_examined,omitempty"`
	ResultsReturned         int     `json:"results_returned,omitempty"`
	ExecutionTimeMs         float32 `json:"execution_time_ms,omitempty"`
}

ExecutionStats is returned by CouchDB on _find queries

type FindRequest

type FindRequest struct {
	Selector       mango.Filter `json:"selector"`
	UseIndex       string       `json:"use_index,omitempty"`
	Bookmark       string       `json:"bookmark,omitempty"`
	Limit          int          `json:"limit,omitempty"`
	Skip           int          `json:"skip,omitempty"`
	Sort           mango.SortBy `json:"sort,omitempty"`
	Fields         []string     `json:"fields,omitempty"`
	Conflicts      bool         `json:"conflicts,omitempty"`
	ExecutionStats bool         `json:"execution_stats,omitempty"`
}

FindRequest is used to build a find request

type FindResponse

type FindResponse struct {
	Warning        string          `json:"warning"`
	Bookmark       string          `json:"bookmark"`
	Docs           json.RawMessage `json:"docs"`
	ExecutionStats *ExecutionStats `json:"execution_stats,omitempty"`
}

FindResponse is the response from couchdb on a find request

func FindDocsRaw

func FindDocsRaw(db prefixer.Prefixer, doctype string, req interface{}, results interface{}) (*FindResponse, error)

FindDocsRaw find documents

type IDRev

type IDRev struct {
	ID  string `json:"id"`
	Rev string `json:"rev,omitempty"`
}

IDRev is used for the payload of POST _bulk_get

type IndexCreationResponse

type IndexCreationResponse struct {
	Result string `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
	Reason string `json:"reason,omitempty"`
	ID     string `json:"id,omitempty"`
	Name   string `json:"name,omitempty"`
}

IndexCreationResponse is the response from couchdb when we create an Index

func DefineIndexRaw

func DefineIndexRaw(db prefixer.Prefixer, doctype string, index interface{}) (*IndexCreationResponse, error)

DefineIndexRaw defines a index

type JSONDoc

type JSONDoc struct {
	M    map[string]interface{}
	Type string
}

JSONDoc is a map representing a simple json object that implements the Doc interface.

func (*JSONDoc) Clone

func (j *JSONDoc) Clone() Doc

Clone is used to create a copy of the document

func (*JSONDoc) DocType

func (j *JSONDoc) DocType() string

DocType returns the document type of the document

"io.cozy.event" == doc.Doctype()

func (*JSONDoc) Fetch

func (j *JSONDoc) Fetch(field string) []string

Fetch implements permission.Fetcher on JSONDoc.

The `referenced_by` selector is a special case: the `values` field of such rule has the format "doctype/id" and it cannot directly be compared to the same field of a JSONDoc since, in the latter, the format is: "referenced_by": [

{"type": "doctype1", "id": "id1"},
{"type": "doctype2", "id": "id2"},

]

func (*JSONDoc) Get

func (j *JSONDoc) Get(key string) interface{}

Get returns the value of one of the db fields

func (*JSONDoc) ID

func (j *JSONDoc) ID() string

ID returns the identifier field of the document

"io.cozy.event/123abc123" == doc.ID()

func (*JSONDoc) MarshalJSON

func (j *JSONDoc) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaller by proxying to internal map

func (*JSONDoc) Rev

func (j *JSONDoc) Rev() string

Rev returns the revision field of the document

"3-1234def1234" == doc.Rev()

func (*JSONDoc) SetID

func (j *JSONDoc) SetID(id string)

SetID is used to set the identifier of the document

func (*JSONDoc) SetRev

func (j *JSONDoc) SetRev(rev string)

SetRev is used to set the revision of the document

func (*JSONDoc) ToMapWithType

func (j *JSONDoc) ToMapWithType() map[string]interface{}

ToMapWithType returns the JSONDoc internal map including its DocType its used in request response.

func (*JSONDoc) UnmarshalJSON

func (j *JSONDoc) UnmarshalJSON(bytes []byte) error

UnmarshalJSON implements json.Unmarshaller by proxying to internal map

type NormalDocsResponse

type NormalDocsResponse struct {
	Total          int               `json:"total_rows"`
	Rows           []json.RawMessage `json:"rows"`
	Bookmark       string            `json:"bookmark"`
	ExecutionStats *ExecutionStats   `json:"execution_stats,omitempty"`
}

NormalDocsResponse is the response the stack send for _normal_docs queries

func NormalDocs

func NormalDocs(db prefixer.Prefixer, doctype string, skip, limit int, bookmark string, executionStats bool) (*NormalDocsResponse, error)

NormalDocs returns all the documents from a database, with pagination, but it excludes the design docs.

type SkipCursor

type SkipCursor struct {

	// Skip is the number of elements to start from
	Skip int
	// contains filtered or unexported fields
}

SkipCursor is a Cursor using Skip to know how deep in the request it is.

func (*SkipCursor) ApplyTo

func (c *SkipCursor) ApplyTo(req *ViewRequest)

ApplyTo applies the cursor to a ViewRequest the transformed ViewRequest will retrieve elements from Cursor to Limit or EndKey whichever comes first /!\ Mutates req

func (SkipCursor) HasMore

func (c SkipCursor) HasMore() bool

HasMore returns true if there is more document after the current batch. This value is meaning full only after UpdateFrom

func (*SkipCursor) UpdateFrom

func (c *SkipCursor) UpdateFrom(res *ViewResponse)

UpdateFrom change the cursor status depending on information from the view's response

type StartKeyCursor

type StartKeyCursor struct {

	// NextKey & NextDocID contains a reference to the document
	// right after the last fetched one
	NextKey   interface{}
	NextDocID string
	// contains filtered or unexported fields
}

StartKeyCursor is a Cursor using start_key, ie a reference to the last fetched item to keep pagination

func (*StartKeyCursor) ApplyTo

func (c *StartKeyCursor) ApplyTo(req *ViewRequest)

ApplyTo applies the cursor to a ViewRequest the transformed ViewRequest will retrieve elements from Cursor to Limit or EndKey whichever comes first /!\ Mutates req

func (StartKeyCursor) HasMore

func (c StartKeyCursor) HasMore() bool

HasMore returns true if there is more document after the current batch. This value is meaning full only after UpdateFrom

func (*StartKeyCursor) UpdateFrom

func (c *StartKeyCursor) UpdateFrom(res *ViewResponse)

UpdateFrom change the cursor status depending on information from the view's response

type UpdateResponse

type UpdateResponse struct {
	ID     string `json:"id"`
	Rev    string `json:"rev"`
	Ok     bool   `json:"ok"`
	Error  string `json:"error"`
	Reason string `json:"reason"`
}

UpdateResponse is the response from couchdb when updating documents

type View

type View struct {
	Name    string      `json:"-"`
	Doctype string      `json:"-"`
	Map     interface{} `json:"map"`
	Reduce  interface{} `json:"reduce,omitempty"`
	Options interface{} `json:"options,omitempty"`
}

View is the map/reduce thing in CouchDB

func ViewsByDoctype

func ViewsByDoctype(doctype string) []*View

ViewsByDoctype returns the list of views for a specified doc type.

type ViewRequest

type ViewRequest struct {
	Key      interface{} `json:"key,omitempty" url:"key,omitempty"`
	StartKey interface{} `json:"start_key,omitempty" url:"start_key,omitempty"`
	EndKey   interface{} `json:"end_key,omitempty" url:"end_key,omitempty"`

	StartKeyDocID string `json:"startkey_docid,omitempty" url:"startkey_docid,omitempty"`
	EndKeyDocID   string `json:"endkey_docid,omitempty" url:"endkey_docid,omitempty"`

	// Keys cannot be used in url mode
	Keys []interface{} `json:"keys,omitempty" url:"-"`

	Limit       int  `json:"limit,omitempty" url:"limit,omitempty"`
	Skip        int  `json:"skip,omitempty" url:"skip,omitempty"`
	Descending  bool `json:"descending,omitempty" url:"descending,omitempty"`
	IncludeDocs bool `json:"include_docs,omitempty" url:"include_docs,omitempty"`

	InclusiveEnd bool `json:"inclusive_end,omitempty" url:"inclusive_end,omitempty"`

	Reduce     bool `json:"reduce" url:"reduce"`
	Group      bool `json:"group" url:"group"`
	GroupLevel int  `json:"group_level,omitempty" url:"group_level,omitempty"`
}

ViewRequest are all params that can be passed to a view It can be encoded either as a POST-json or a GET-url.

func (*ViewRequest) Values

func (vr *ViewRequest) Values() (url.Values, error)

Values transforms a ViewRequest into a query string suitable for couchdb ie, where non-scalar fields have been JSON+URL encoded.

type ViewResponse

type ViewResponse struct {
	Total  int                `json:"total_rows"`
	Offset int                `json:"offset,omitempty"`
	Rows   []*ViewResponseRow `json:"rows"`
}

ViewResponse is the response we receive when executing a view

type ViewResponseRow

type ViewResponseRow struct {
	ID    string          `json:"id"`
	Key   interface{}     `json:"key"`
	Value interface{}     `json:"value"`
	Doc   json.RawMessage `json:"doc"`
}

ViewResponseRow is a row in a ViewResponse

Directories

Path Synopsis
The stream package can be used for streaming CouchDB responses in JSON format from the CouchDB cluster to a client, with the stack doing stuff like filtering some fields.
The stream package can be used for streaming CouchDB responses in JSON format from the CouchDB cluster to a client, with the stack doing stuff like filtering some fields.

Jump to

Keyboard shortcuts

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