Skip to content

a8m/documentdb

Repository files navigation

DocumentDB Go Build status

Go driver for Microsoft Azure DocumentDB

Table of contents:

Get Started

Installation

$ go get github.com/a8m/documentdb

Add to your project

import (
	"github.com/a8m/documentdb"
)

func main() {
	config := documentdb.NewConfig(&documentdb.Key{
		Key: "master-key",
	})
	client := documentdb.New("connection-url", config)

	// Start using DocumentDB
	dbs, err := client.ReadDatabases()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(dbs)
}

Databases

ReadDatabase

func main() {
	// ...
	db, err := client.ReadDatabase("self_link")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(db.Self, db.Id)
}

QueryDatabases

func main() {
	// ...
	dbs, err := client.QueryDatabases("SELECT * FROM ROOT r")
	if err != nil {
		log.Fatal(err)
	}
	for _, db := range dbs {
		fmt.Println("DB Name:", db.Id)
	}
}

ReadDatabases

func main() {
	// ...
	dbs, err := client.ReadDatabases()
	if err != nil {
		log.Fatal(err)
	}
	for _, db := range dbs {
		fmt.Println("DB Name:", db.Id)
	}
}

CreateDatabase

func main() {
	// ...
	db, err := client.CreateDatabase(`{ "id": "test" }`)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(db)

	// or ...
	var db documentdb.Database
	db.Id = "test"
	db, err = client.CreateDatabase(&db)
}

ReplaceDatabase

func main() {
	// ...
	db, err := client.ReplaceDatabase("self_link", `{ "id": "test" }`)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(db)

	// or ...
	var db documentdb.Database
	db, err = client.ReplaceDatabase("self_link", &db)
}

DeleteDatabase

func main() {
	// ...
	err := client.DeleteDatabase("self_link")
	if err != nil {
		log.Fatal(err)
	}
}

Collections

ReadCollection

func main() {
	// ...
	coll, err := client.ReadCollection("self_link")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(coll.Self, coll.Id)
}

QueryCollections

func main() {
	// ...
	colls, err := client.QueryCollections("db_self_link", "SELECT * FROM ROOT r")
	if err != nil {
		log.Fatal(err)
	}
	for _, coll := range colls {
		fmt.Println("Collection Name:", coll.Id)
	}
}

ReadCollections

func main() {
	// ...
	colls, err := client.ReadCollections("db_self_link")
	if err != nil {
		log.Fatal(err)
	}
	for _, coll := range colls {
		fmt.Println("Collection Name:", coll.Id)
	}
}

CreateCollection

func main() {
	// ...
	coll, err := client.CreateCollection("db_self_link", `{"id": "my_test"}`)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Collection Name:", coll.Id)

	// or ...
	var coll documentdb.Collection
	coll.Id = "test"
	coll, err = client.CreateCollection("db_self_link", &coll)
}

DeleteCollection

func main() {
	// ...
	err := client.DeleteCollection("self_link")
	if err != nil {
		log.Fatal(err)
	}
}

Documents

ReadDocument

type Document struct {
	documentdb.Document
	// Your external fields
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
}

func main() {
	// ...
	var doc Document
	err = client.ReadDocument("self_link", &doc)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Document Name:", doc.Name)
}

QueryDocuments

type User struct {
	documentdb.Document
	// Your external fields
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
}

func main() {
	// ...
	var users []User
	_, err = client.QueryDocuments(
        "coll_self_link", 
        documentdb.NewQuery("SELECT * FROM ROOT r WHERE r.name=@name", documentdb.P{"@name", "john"}),
        &users,
    )
	if err != nil {
		log.Fatal(err)
	}
	for _, user := range users {
		fmt.Print("Name:", user.Name, "Email:", user.Email)
	}
}

QueryDocuments with partition key

type User struct {
	documentdb.Document
	// Your external fields
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
}

func main() {
	// ...
	var users []User
	_, err = client.QueryDocuments(
        "coll_self_link", 
		documentdb.NewQuery(
			"SELECT * FROM ROOT r WHERE r.name=@name AND r.company_id = @company_id", 
			documentdb.P{"@name", "john"}, 
			documentdb.P{"@company_id", "1234"},
		),
		&users,
		documentdb.PartitionKey("1234")
    )
	if err != nil {
		log.Fatal(err)
	}
	for _, user := range users {
		fmt.Print("Name:", user.Name, "Email:", user.Email)
	}
}

ReadDocuments

type User struct {
	documentdb.Document
	// Your external fields
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
}

func main() {
	// ...
	var users []User
	err = client.ReadDocuments("coll_self_link", &users)
	if err != nil {
		log.Fatal(err)
	}
	for _, user := range users {
		fmt.Print("Name:", user.Name, "Email:", user.Email)
	}
}

CreateDocument

type User struct {
	documentdb.Document
	// Your external fields
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
}

func main() {
	// ...
	var user User
	// Note: If the `id` is missing(or empty) in the payload it will generate
	// random document id(i.e: uuid4)
	user.Id = "uuid"
	user.Name = "Ariel"
	user.Email = "ariel@test.com"
	err := client.CreateDocument("coll_self_link", &doc)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print("Name:", user.Name, "Email:", user.Email)
}

ReplaceDocument

type User struct {
	documentdb.Document
	// Your external fields
	IsAdmin bool   `json:"isAdmin,omitempty"`
}

func main() {
	// ...
	var user User
	user.Id = "uuid"
	user.IsAdmin = false
	err := client.ReplaceDocument("doc_self_link", &user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print("Is Admin:", user.IsAdmin)
}

DeleteDocument

func main() {
	// ...
	err := client.DeleteDocument("doc_self_link")
	if err != nil {
		log.Fatal(err)
	}
}

ExecuteStoredProcedure

func main() {
	// ...
	var docs []Document
	err := client.ExecuteStoredProcedure("sporc_self", [...]interface{}{p1, p2}, &docs)
	if err != nil {
		log.Fatal(err)
	}
	// ...
}

Iterator

DocumentIterator

func main() {
	// ...
	var docs []Document

	iterator := documentdb.NewIterator(
		client, documentdb.NewDocumentIterator("coll_self_link", nil, &docs, documentdb.PartitionKey("1"), documentdb.Limit(1)),
	)

	for iterator.Next() {
		if err := iterator.Error(); err != nil {
			log.Fatal(err)
		}
		fmt.Println(len(docs))
	}    

	// ...
}

Authentication with Azure AD

You can authenticate with Cosmos DB using Azure AD and a service principal, including full RBAC support. To configure Cosmos DB to use Azure AD, take a look at the Cosmos DB documentation.

To use this library with a service principal:

import (
	"github.com/Azure/go-autorest/autorest/adal"
	"github.com/a8m/documentdb"
)

func main() {
	// Azure AD application (service principal) client credentials
	tenantId := "tenant-id"
	clientId := "client-id"
	clientSecret := "client-secret"

	// Azure AD endpoint may be different for sovereign clouds
	oauthConfig, err := adal.NewOAuthConfig("https://#.microsoftonline.com/", tenantId)
	if err != nil {
		log.Fatal(err)
	}
	spt, err := adal.NewServicePrincipalToken(*oauthConfig, clientId, clientSecret, "https://cosmos.azure.com") // Always "https://cosmos.azure.com"
	if err != nil {
		log.Fatal(err)
	}

	config := documentdb.NewConfigWithServicePrincipal(spt)
	client := documentdb.New("connection-url", config)
}

Examples

License

Distributed under the MIT license, which is available in the file LICENSE.

About

Go driver for Microsoft Azure DocumentDB

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages