pouchdb

package module
v0.0.0-...-472388d Latest Latest
Warning

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

Go to latest
Published: May 1, 2017 License: Apache-2.0 Imports: 9 Imported by: 0

README

Build Status GoDoc

!!! Notice !!!

This package has been superceded by my new package Kivik, which provides a common, isomorphic interface for both Go and GopherJS apps using CouchDB and PouchDB. For new applications, you should use Kivik instead of go-pouchdb. It has many more features, and is under active development.

go-pouchdb

GopherJS bindings for PouchDB.

Requirements

This package requires PouchDB 4.0.2 or newer.

Installation

Installation is a two-step process, because there is the Go code, and the node.js code:

Install Go code

Usually the simplest way to do this is simply to run gopherjs get in your Go project's directory, to fetch all of the build requirements simultaneously. If you want to explicitly install go-pouchdb, you can do so with the following command:

gopherjs get github.com/flimzy/go-pouchdb
Install Node.js code

For larger projects with multiple Node.js requirements, you will likely want to maintain a package.json file, as you would for most Node or JavaScript packages. A minimal package.json file for use with go-pouchdb could look like this:

{
    "name": "app",
    "dependencies": {
        "pouchdb": ">=4.0.2"
    }
}

With this in place, you can run npm install from your package directory to install pouchdb and its requirements, with npm. To directly and explicitly install just pouchdb, you can also use the command npm install pouchdb.

Deployment

When deploying your code for use in a browser, you have a couple of options. My recommended method is simply to use Browserify to bundle your GopherJS app with the nodejs requirements into a single, shippable .js file. If this does not work for your purposes, the next simplest option is simply to load PouchDB in the browser before loading your GopherJS app. go-pouchdb will look for a global pouchdb object when it starts. If it cannot find one, and it cannot load pouchdb, it will generate a runtime error.

Alternatives

If you have different requirements, and cannot load pouchdb globally, there is one alternative. You can load the PouchDB module into a custom variable, and tell go-pouchdb by setting the pouchdb.GlobalPouch variable in your init() function:

package main

import (
    "github.com/flimzy/go-pouchdb"
    "github.com/gopherjs/gopherjs/js"
)

func init() {
    pouchdb.GlobalPouch = js.Global.Get("someOtherPouchDBObject")
}

General philosophy

There are a number of design decisions that must be made when writing wrappers and/or bindings between langauges. One common approach is to write the smallest, most minimal wrapper necessary around. The JavaScript bindings in GopherJS take this approach, and I believe that is an appropriate decision in that case, where the goal is to provide access to the underlying JavaScript primatives, with the least amount of abstraction so that users of the bindings can accomplish anything they need.

I have taken a different approach with this package. Rather than attempting to provide a minimal wrapper around the existing PouchDB, I have decided to take the approach that my goal is not to wrap PouchDB, but rather to provide client-side database access for GopherJS programs. In other words, I want to accomplish the same goal as PouchDB, but in client-side Go, rather than in client-side JavaScript.

What this means in concrete terms is that much of this API doesn't look very PouchDB-ish. And it doens't look very JavaScript-ish. You won't find any callbacks here! Under the hood, PouchDB still uses callbacks, but go-pouchdb abstracts that away, to give you a much more Go-idiomatic interface. Many functions have been renamed from their PouchDB versions, to be more Go-idiomatic, as well. I have followed the lead of Felix Lange, author of the popular Go CouchDB library http://godoc.org/github.com/fjl/go-couchdb, and whenever there has been a choice between the PouchDB name and the go-couchdb name, I have chosen the latter.

This decision may mean that anyone familiar with PouchDB in JavaScript may have a slightly steeper learning curve when using this library. But I think that's a small price to pay when considering that anyone already familiar with Go will have a much easier time. And it is primarily the latter group of people (which includes myself!) to which I a hope to cater with this library.

Status

This is a work in progress. Use at your own risk. Please contribute pull requests!

The following table shows the status of each API method.

PouchDB name go-pouchdb signature(s) Comments
new() New(db_name string) *PouchDB
NewFromOpts(Options) *PouchDB
destroy() (db *PouchDB) Destroy(Options) error
put() (db *PouchDB) Put(doc interface{}) (newrev string, err error)
get() (db *PouchDB) Get(id string, doc interface{}, opts Options) error
remove() (db *PouchDB) Remove(doc interface{}, opts Options) (newrev string, err error)
bulkDocs() (db *PouchDB) BulkDocs(docs interface{}, opts Options) ([]Result, error)
allDocs() (db *PouchDB) AllDocs(result interface{}, opts Options) error
viewCleanup() (db *PouchDB) ViewCleanup() error
info() (db *PouchDB) Info() (*js.Object, error)
compact() (db *PouchDB) Compact(opts Options) error
revsDiff() --
defaults() n/a Pass options to New() instead
debug.enable() Debug(module string)
debug.disable() DebugDisable()
changes() --
replicate() Replicate(source, target *PouchDB, opts Options) (Result, error) "One-shot" replication only
replicate.to() n/a Use Replicate()
replicate.from() n/a Use Replicate()
sync() Sync(source, target *PouchDB, opts Options) ([]Results, error)
putAttachment() (db *PouchDB) PutAttachment(docid string, att *Attachment, rev string) (string, error)
getAttachment() (db *PouchDB) Attachment(docid, name, rev string) (*Attachment, error)
removeAttachment() (db *PouchDB) DeleteAttachment(docid, name, rev string) (string, error)
query() (db *PouchDB) Query(view string, result interface{}, opts Options) error
query() (db *PouchDB) QueryFunc(view MapFunc, result interface{}, opts Options) error
on() --
plugin() Plugin(*js.Object) *Primarily for internal use
-- (db *PouchDB) Call(name string, interface{} ...) (*js.Object, error)
TODO
  • Add support for Changes Feeds (for use by changes() and live replication)
  • Add support for plugins
  • Add support for 'created' and 'destroyed' event handlers (??)

Implementation notes

On the handling of JSON

Go has some spiffy JSON capabilities that don't exist in JavaScript. Of particular note, the encoding/json package understands special struct tags, and does some handy key-name manipulation for us. However, PouchDB gives us already-parsed JSON objects, which means we can't take advantage of Go's enhanced JSON handling. To get around this, every document read from PouchDB is first converted back into JSON with the json.Marshal() method, then converted back into an object, this time as a native Go object. And when putting documents into PouchDB, the reverse is done. This allows you to take advantage of Go's "superior" (or at least more idiomatic) JSON handling.

Related to this, rather than methods such as Get() simply returning an object, as they do in PouchDB, they take a document reference as an argument, and assign the document to this reference. This allows you to provide a prescribed data type into which the document is expected to fit. This is how the popular fjl/go-couchdb library works, too. In fact, I have copied a lot from fjl in this package.

License

This software is released under the terms of the Apache 2.0 license. See LICENCE.md, or read the full license.

Documentation

Overview

Package pouchdb provides GopherJS bindings for PouchDB. Whenever possible, the PouchDB function calls have been made more Go idiomatic. This means:

  • They don't take optional arguments. Where appropriate, multiple versions of a function exist with different argument lists.
  • They don't use call backs or return Promises
  • They have been made synchronous. If you need asynchronous operation, wrap your calls in goroutines
  • They return errors as the last return value (Go style) rather than the first (JS style)

Index

Constants

This section is empty.

Variables

View Source
var GlobalPouch *js.Object

GlobalPouch is the global pouchdb object. The package will look for it in the global object (js.Global), or try to require it if it is not found. If this does not work for you, you ought to set it explicitly yourself:

pouchdb.GlobalPouch = js.Global.Call("require", "/path/to/your/copy/of/pouchdb")

Functions

func ConvertJSONObject

func ConvertJSONObject(input, output interface{}) error

ConvertJSONObject takes an intterface{} and runs it through json.Marshal() and json.Unmarshal() so that any struct tags will be applied.

func ConvertJSObject

func ConvertJSObject(jsObj *js.Object, output interface{}) error

convertJSObject converts the provided *js.Object to an interface{} then calls convertJSONObject. This is necessary for objects, because json.Marshal ignores any unexported fields in objects, and this includes practically everything inside a js.Object.

func Debug

func Debug(module string)

Debug enables debugging for the specified module. Note this only affects connections made after this is run. See: http://pouchdb.com/api.html#debug_mode

func DebugDisable

func DebugDisable()

DebugDisable disables debugging.

func ErrorMessage

func ErrorMessage(err error) string

ErrorMessage returns the message portion of a PouchError, or "" for other errors

func ErrorName

func ErrorName(err error) string

ErrorName returns the name portion of a PouchError, or "" for other errors

func ErrorReason

func ErrorReason(err error) string

ErrorReason returns the reason portion of a PouchError, or "" for other errors

func ErrorStatus

func ErrorStatus(err error) int

ErrorStatus returns the status of a PouchError, or 0 for other errors

func IsConflict

func IsConflict(err error) bool

IsConflict returns true if the passed error is a PouchError with a status of 409 (conflict)

func IsNotExist

func IsNotExist(err error) bool

IsNotExist returns true if the passed error represents a PouchError with a status of 404 (not found)

func IsPouchError

func IsPouchError(err error) bool

IsPouchError returns true if the passed error is a PouchError, false if it is any other type of error.

func IsWarning

func IsWarning(err error) bool

IsWarning returns true of the error message is a PouchDB warning, otherwise false.

func NewPouchError

func NewPouchError(err *js.Error) error

NewPouchError creates a new PouchError from a js.Error object returned from the PouchDB library

func NewResultWaiter

func NewResultWaiter() *resultWaiter

func OnCreate

func OnCreate(fn func(dbName string))

OnCreate registers the function as an event listener for the 'created' event. See https://pouchdb.com/api.html#events

func OnDestroy

func OnDestroy(fn func(dbName string))

OnDestroy registers the function as an event listener for the 'destroyed' event. See https://pouchdb.com/api.html#events

func Plugin

func Plugin(plugin *js.Object)

Plugin registers a loaded plugin with the global PouchDB object

Types

type Attachment

type Attachment struct {
	Name string    // File name
	Type string    // MIME type of the Body
	MD5  []byte    // MD5 checksum of the Body
	Body io.Reader // The body itself
}

Attachment represents document attachments. This structure is borrowed from http://godoc.org/github.com/fjl/go-couchdb#Attachment

type DBInfo

type DBInfo struct {
	DBName    string `json:"db_name"`
	DocCount  uint   `json:"doc_count"`
	UpdateSeq uint64 `json:"update_seq"`
}

type MapFunc

type MapFunc func(string)

type Options

type Options struct {
	// This turns on auto compaction, which means compact() is called after
	// every change to the database. Defaults to false.
	//
	// Used by New(), for local databases only
	AutoCompaction bool

	// One of 'idb', 'leveldb', 'websql', or 'http'. If unspecified, PouchDB
	// will infer this automatically, preferring IndexedDB to WebSQL in
	// browsers that support both.
	//
	// Used by New(), for local databases only.
	Adapter string

	// See https://github.com/Level/levelup#options
	DB *js.Object

	// Specify how many old revisions we keep track (not a copy) of.
	//
	// Used by New(), for local databases only.
	RevsLimit int

	// Remote databases only.) Ajax requester options. These are passed
	// verbatim to request (in Node.js) or a request shim (in the browser),
	// with the exception of 'cache'.
	//  - cache: Appends a random string to the end of all HTTP GET requests
	//    to avoid them being cached on IE. Set this to true to prevent this
	//    happening.
	//  - headers: Allows you to customise headers that are sent to the remote
	//    HTTP Server.
	//  - username + password: Alternate method to provide auth credentians to
	//    using a database name in the form `http://user:pass@host/name`
	//  - withCredentials: Set to false to disable transferring cookies or HTTP
	//    Auth information. Defaults to true.
	//  - skip_setup: Initially PouchDB checks if the database exists, and
	//    tries to create it, if it does not exist yet. Set this to true to skip
	//    this setup.
	//
	// Used by any method that accesses a remote database.
	Ajax map[string]interface{}

	// Specifies whether you want to use persistent or temporary storage.
	//
	// Used by New(), for IndexedDB only.
	Storage string

	// Amount in MB to request for storage, which you will need if you are
	// storing >5MB in order to avoid storage limit errors on iOS/Safari.
	//
	// Used by New(), for WebSQL only.
	Size int

	// Fetch specific revision of a document. Defaults to winning revision.
	//
	// Used by Get().
	Rev string

	// Include revision history of the document.
	//
	// Used by Get().
	Revs bool

	// Include a list of revisions of the document, and their availability.
	//
	// Used by Get().
	RevsInfo bool

	// Fetch requested leaf revisions in the order specified.
	//
	// Used by Get().
	OpenRevs []string

	// Fetch all leaf revisions.
	//
	// Used by Get().
	AllOpenRevs bool

	// If specified, conflicting leaf revisions will be attached in _conflicts
	// array.
	//
	// Used by Get(), AllDocs() and Query().
	Conflicts bool

	// Include attachment data.
	//
	// Used by Get(), AllDocs() and Query().
	Attachments bool

	// Include the document itself in each row in the doc field. The default
	// is to only return the _id and _rev properties.
	//
	// Used by AllDocs() and Query().
	IncludeDocs bool

	// Get documents with IDs in a certain range (inclusive/inclusive).
	//
	// Used by AllDocs() and Query().
	StartKey string
	EndKey   string

	// Exclude documents having an ID equal to the given EndKey.
	// Note this flag has the reverse sense of the PouchDB inclusive_end flag.
	//
	// Used by AllDocs() and Query().
	ExclusiveEnd bool

	// Maximum number of documents to return.
	//
	// Used by AllDocs() and Query()
	Limit int

	// Number of docs to skip before returning.
	//
	// Used by AllDocs() and Query().
	Skip int

	// Reverse the order of the output documents. Note that the order of
	// StartKey and EndKey is reversed when Descending is true.
	//
	// Used by AllDocs() and Query().
	Descending bool

	// Only return documents with IDs matching this string.
	//
	// Used by AllDocs() and Query().
	Key string

	// Array of string keys to fetch in a single shot.
	//  - Neither StartKey nor EndKey can be specified with this option.
	//  - The rows are returned in the same order as the supplied keys array.
	//  - The row for a deleted document will have the revision ID of the
	//    deletion, and an extra key "deleted":true in the value property.
	//  - The row for a nonexistent document will just contain an "error"
	//    property with the value "not_found".
	//  - For details, see the CouchDB query options documentation:
	//    http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
	//
	// Used by AllDocs() and Query().
	Keys []string

	// Reference a filter function from a design document to selectively get
	// updates. To use a view function, pass _view here and provide a reference
	// to the view function in options.view.
	// See also: https://pouchdb.com/api.html#filtered-replication
	//
	// Used by Replicate()
	Filter string

	// Only show changes for docs with these ids (array of strings).
	//
	// Used by Replicate().
	DocIDs []string

	// Object containing properties that are passed to the filter function,
	// e.g. {"foo":"bar"}.
	//
	// Used by Replicate().
	QueryParams map[string]interface{}

	// Specify a view function (e.g. 'design_doc_name/view_name' or 'view_name'
	// as shorthand for 'view_name/view_name') to act as a filter.
	//
	// Used by Replicate().
	View string

	// Replicate changes after the given sequence number.
	//
	// Used by Replicate().
	Since int64

	Heartbeat       int64
	Timeout         int64
	BatchSize       int
	BatchesLimit    int
	BackOffFunction func(int) int

	// The name of a view in an existing design document (e.g.
	// 'mydesigndoc/myview', or 'myview' as a shorthand for 'myview/myview').
	//
	// Used by Query().
	MapFuncName string

	// A JavaScript object representing a map function. It is not possible to
	// define map functions in GopherJS.
	//
	// Used by Query()
	MapFunc *js.Object

	// The name of a built-in reduce function: '_sum', '_count', or '_stats'.
	//
	// Used by Query()
	ReduceFuncName string

	// A JavaScript object representing a reduce function. It is not possible
	// to define reduce functions in GopherJS.
	//
	// Used by Query()
	ReduceFunc *js.Object

	// True if you want the reduce function to group results by keys, rather
	// than returning a single result.
	//
	// Used by Query().
	Group bool

	// Number of elements in a key to group by, assuming the keys are arrays.
	// Defaults to the full length of the array.
	//
	// Used by Query().
	GroupLevel int

	// Only applies to saved views. Can be one of:
	//  - unspecified (default): Returns the latest results, waiting for the
	//    view to build if necessary.
	//  - 'ok': Returns results immediately, even if they’re out-of-date.
	//  - 'update_after': Returns results immediately, but kicks off a build
	//    afterwards.
	//
	// Used by Query().
	Stale string
}

Options represents the optional configuration options for a PouchDB operation.

type PouchDB

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

func New

func New(db_name string) *PouchDB

New creates a database or opens an existing one. See: http://pouchdb.com/api.html#create_database

func NewWithOpts

func NewWithOpts(db_name string, opts Options) *PouchDB

NewWithOpts creates a database or opens an existing one. See: http://pouchdb.com/api.html#create_database

func (*PouchDB) AllDocs

func (db *PouchDB) AllDocs(result interface{}, opts Options) error

AllDocs will fetch multiple documents. The output of the query is unmarshalled into the given result. The format of the result depends on the options. Please refer to the CouchDB HTTP API documentation for all the possible options that can be set.

See http://pouchdb.com/api.html#batch_fetch and http://docs.couchdb.org/en/latest/api/database/bulk-api.html#db-all-docs

func (*PouchDB) Attachment

func (db *PouchDB) Attachment(docid, name, rev string) (*Attachment, error)

Attachment retrieves an attachment. The rev argument can be left empty to retrieve the latest revision. The caller is responsible for closing the attachment's Body if the returned error is nil.

Note that PouchDB's getDocument() does not fetch meta data (except for the MIME type in the browser only), so the MD5 sum and (in node) the content type fields will be empty.

See http://pouchdb.com/api.html#get_attachment and http://godoc.org/github.com/fjl/go-couchdb#Attachment

func (*PouchDB) BulkDocs

func (db *PouchDB) BulkDocs(docs interface{}, opts Options) ([]Result, error)

BulkDocs will create, update or delete multiple documents.

See: http://pouchdb.com/api.html#batch_create

func (*PouchDB) Call

func (db *PouchDB) Call(name string, args ...interface{}) *js.Object

Call calls the underlying PouchDB object's method with the given name and arguments. This method is used internally, and may also facilitate the use of plugins which may add methods to PouchDB which are not implemented in the GopherJS bindings.

func (*PouchDB) Compact

func (db *PouchDB) Compact(opts Options) error

Compact triggers a compaction operation in the local or remote database.

See: http://pouchdb.com/api.html#compaction

func (*PouchDB) DeleteAttachment

func (db *PouchDB) DeleteAttachment(docid, name, rev string) (newrev string, err error)

func (*PouchDB) Destroy

func (db *PouchDB) Destroy(opts Options) error

Deestroy will delete the database. See: http://pouchdb.com/api.html#delete_database

func (*PouchDB) Get

func (db *PouchDB) Get(docId string, doc interface{}, opts Options) error

Get retrieves a document, specified by docId. The document is unmarshalled into the given object. Some fields (like _conflicts) will only be returned if the options require it. Please refer to the CouchDB HTTP API documentation for more information.

See http://pouchdb.com/api.html#fetch_document and http://docs.couchdb.org/en/latest/api/document/common.html?highlight=doc#get--db-docid

func (*PouchDB) GetJS

func (db *PouchDB) GetJS(name string) *js.Object

GetJS gets the requested key from the underlying PouchDB object

func (*PouchDB) Info

func (db *PouchDB) Info() (DBInfo, error)

Info fetches information about a database.

See: http://pouchdb.com/api.html#database_information

func (*PouchDB) Put

func (db *PouchDB) Put(doc interface{}) (newrev string, err error)

Put will create a new document or update an existing document. See: http://pouchdb.com/api.html#create_document

func (*PouchDB) PutAttachment

func (db *PouchDB) PutAttachment(docid string, att *Attachment, rev string) (newrev string, err error)

PutAttachment creates or updates an attachment. To create an attachment on a non-existing document, pass an empty rev.

See http://pouchdb.com/api.html#save_attachment and http://godoc.org/github.com/fjl/go-couchdb#DB.PutAttachment

func (*PouchDB) Query

func (db *PouchDB) Query(view string, result interface{}, opts Options) error

Invoke a map/reduce function, which allows you to perform more complex queries on PouchDB than what you get with allDocs().

See http://pouchdb.com/api.html#query_database

func (*PouchDB) QueryFunc

func (db *PouchDB) QueryFunc(fn MapFunc, result interface{}, opts Options) error

func (*PouchDB) Remove

func (db *PouchDB) Remove(doc interface{}, opts Options) (newrev string, err error)

Remove will delete the document. The document must specify both _id and _rev. On success, it returns the _rev of the new document with _delete set to true.

See: http://pouchdb.com/api.html#delete_document

func (*PouchDB) ViewCleanup

func (db *PouchDB) ViewCleanup() error

ViewCleanup cleans up any stale map/reduce indexes.

See: http://pouchdb.com/api.html#view_cleanup

type PouchError

type PouchError struct {
	Status  int    `js:"status"`
	Message string `js:"message"`
	Name    string `js:"name"`
	IsError bool   `js:"isError"`
	Reason  string `js:"reason"`
	// contains filtered or unexported fields
}

PouchError records an error returned by the PouchDB library

func (*PouchError) Error

func (e *PouchError) Error() string

Error satisfies the error interface for the PouchError type

func (*PouchError) Underlying

func (e *PouchError) Underlying() *js.Error

Underlying returns the underlying js.Error object, as returned from the PouchDB library

type Result

type Result map[string]interface{}

func Replicate

func Replicate(source, target *PouchDB, opts Options) (Result, error)

Replicate will replicate data from source to target in the foreground. For "live" replication use ReplicateLive() See: http://pouchdb.com/api.html#replication

func Sync

func Sync(source, target *PouchDB, opts Options) ([]Result, error)

Sync data from src to target and target to src. This is a convenience method for bidirectional data replication.

See http://pouchdb.com/api.html#sync

type Warning

type Warning struct {
	Message string
}

Warning represents a non-fatal PouchDB warning.

func (*Warning) Error

func (w *Warning) Error() string

Directories

Path Synopsis
plugins

Jump to

Keyboard shortcuts

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