Usage Examples

Jonathan Hall edited this page Sep 4, 2017 · 14 revisions

Introduction

The kivik package provides a generic interface around CouchDB or CouchDB-like databases. See the official documentation for details.

This page provides example usage patterns.

Database driver

The kivik package must be used in conjunction with a driver. See the complete list of drivers.

The documentation below assumes a driver has been imported as so:

import (
    "github.com/flimzy/kivik"
    _ "github.com/go-kivik/couchdb" // The CouchDB driver
)

Connecting to a database

New is used to create a database handle:

client, err := kivik.New(context.TODO(), driver, dataSourceName)

Where driver specifies a database driver, and dataSourceName specifies database-specific connection information, such as a URL.

Note that open may or may not verify the existence of the database, permissions, etc. Depending on the driver, such checks may be deferred until a request is made.

Authentication

Different drivers may support different authentication methods. The CouchDB driver (and the PouchDB driver for remote connections) supports auth credentials in the data source URL:

client, err := kivik.New(context.GODO(), "couch", "http://admin:abc123@localhost/")

User management

By default, users in CouchDB are stored as user documents in the _users database. This means user management is just a matter of manipulating these documents as usual. For example, to create a new user:

usersDB, _ := client.DB(context.TODO(), "_users") // Connect to the _users database
user := map[string]interface{}{
		"_id":      kivik.UserPrefix + "username",
		"type":     "user",
		"password": "abc123",
	}
rev, _ := usersDB.Put(context.TODO(), kivik.UserPrefix+"username", user)

Storing a single document

Storing a document is done with Put or Create which correspond to PUT /{db}/{doc}, POST /{db} respectively. In most cases, you should use Put:

type Animal struct {
    ID       string `json:"_id"`
    Rev      string `json:"_rev,omitempty"`
    Feet     int    `json:"feet"`
    Greeting string `json:"greeting"`
}

cow := Animal{ID: "cow", Feet: 4, Greeting: "moo"}
rev, err := db.Put(context.TODO(), "cow", cow)
if err != nil {
    panic(err)
}
cow.Rev = rev

Updating a document

Updating a document is the same as storing one, except that the _rev parameter must match that stored on the server.

cow.Rev = rev // Must be set
cow.Greeting = "Moo!"
newRev, err := db.Put(context.TODO(), "cow", cow)
if err != nil {
    panic(err)
}
cow.Rev = newRev

Deleting a document

As with updating a document, deletion depends on the proper _rev parameter.

newRev, err := db.Delete(context.TODO(), "cow", "2-9c65296036141e575d32ba9c034dd3ee")
if err != nil {
    panic(err)
}
fmt.Printf("The tombstone document has revision %s\n", newRev)

Fetching a document

When fetching a document, the document will be unmarshaled from JSON into your structure by the row.ScanDoc method.

row, err := db.Get(context.TODO(), "cow")
if err != nil {
    panic(err)
}
var cow Animal
if err = row.ScanDoc(&cow); err != nil {
    panic(err)
}
fmt.Printf("The cow says '%s'\n", cow.Greeting)

Design documents

Design documents are treated identically to normal documents by Kivik, the only difference being the document ID.

Create or update a View

Store your document normally, formatted with your views (or other functions). Example:

db.Put(context.TODO(), "_design/foo", map[string]interface{}{
    "_id": "_design/foo",
   "views": map[string]interface{}{
        "foo_view": map[string]interface{}{
            "view": "function(doc) { ... }",
        },
    },
})

Query a view

rows, err := db.Query(context.TODO(), "_design/foo", "_view/bar")
if err != nil {
    panic(err)
}
for rows.Next() {
    var doc interface{}
    if err := rows.ScanDoc(&doc); err != nil {
        panic(err)
    }
    /* do something with doc */
}
if rows.Err() != nil {
    panic(rows.Err())
}

Map/Reduce

Use the Query method with the appropriate options. See Query a view for a more complete example of querying a view.

rows, err := db.Query(context.TODO(), "_design/foo", "_view/bar", map[string]interface{}{"group": true})
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.