oven

package module
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2023 License: Apache-2.0 Imports: 7 Imported by: 0

README

oven

Cloud Firestore client helper library

test Go Report Card GitHub go.mod Go version codecov GoDoc

Overview

Cloud Firestore is a Serverless document database. It comes with with multi-regional replication, powerful query engine, and seamless integration into the broader Google Cloud. I found myself use it frequently over last few years. While Firestore exposes both HTTP and RPC APIs to which you can make direct calls, most people rely on one of the client libraries, and the Go library for Firestore is certainly well documented.

Having used Firestore on a few projects though, I did find it wee bit verbose and repetitive in some places. Oven is a wrapper the the standard Firestore client library. It hides some of the complexity (e.g. iterator over resulting documents), and shortens a few of the more verbose, but common, use-cases.

Features

  • Easy Save, Update, Get, Delete
  • Structured criteria Query
  • Extends Firestore client

Install

go get github.com/mchmarny/oven

Usage

The examples folder includes some of the most common use-cases with two fully functional code:

Save

b := Book{
	ID:     "id-123",
	Title:  "The Hitchhiker's Guide to the Galaxy",
	Author: "Douglas Adams",
}

if err := oven.Save(ctx, client, "books", b.ID, &b); err != nil {
	handleErr(err)
}

Get

b, err := oven.Get[Book](ctx, client, "books", "id-123")
if err != nil {
	handleErr(err)
}

Update

Using Title field with firestore:"title" tag

m := map[string]interface{}{
	"title": "Some new title",
}

if err := oven.Update(ctx, client, "books", "id-123", m); err != nil {
	handleErr(err)
}

Delete

if err := oven.Delete(ctx, client, "books", "id-123"); err != nil {
	handleErr(err)
}

Query

q := &oven.Criteria{
	Collection: book.CollectionName,
	Criterions: []*oven.Criterion{
		{
			Path:      "author", // `firestore:"author"`
			Operation: oven.OperationTypeEqual,
			Value:     bookAuthor,
		},
	},
	OrderBy: "published", // `firestore:"published"`
	Desc:    true,
	Limit:   bookCollectionSize,
}

list, err := oven.Query(ctx, client, q)
if err != nil {
	handleErr(err)
}

Iterator

In case you already have the Firestore iterator and want to just avoid the verbose for loop of spooling the documents into a list, oven provides the ToStructs method

// given it as *firestore.DocumentIterator
it := col.Documents(ctx)

// this returns a slice of books ([]*Book)
list, err := oven.ToStructs[Book](it)

There is also support for a handler in case you need to reason over individual item. When handler returns an error, the entire ToStructsWithHandler method will exit with that error.

Only items for which the handler returns true will be appended to the result slice. This allows for filtering the results when such filters are not possible in the Firestore itself.

it := col.Documents(ctx)

return store.ToStructsWithHandler(it, func(item *Person) (bool, error) {
	item.Age = time.Since(item.DOB)
	return true, nil
})

Disclaimer

This is my personal project and it does not represent my employer. While I do my best to ensure that everything works, I take no responsibility for issues caused by this code.

Documentation

Index

Constants

View Source
const (
	// MaxBatchSize is the maximum number of items that can be batched together.
	MaxBatchSize = 500
)

Variables

View Source
var (
	// ErrDataNotFound is thrown when query does not find the requested data.
	ErrDataNotFound = errors.New("data not found")
)
View Source
var (
	// ErrInvalidDestinationType is thrown when the item type is not a pointer to a struct.
	ErrInvalidDestinationType = errors.New("destination type must be a non nil pointer")
)

Functions

func BatchSet added in v0.4.1

func BatchSet[T Identifiable](ctx context.Context, client *firestore.Client, col string, items ...T) error

func Delete added in v0.3.1

func Delete(ctx context.Context, client *firestore.Client, col, id string) error

Delete deletes specific record by id.

func Get added in v0.3.1

func Get[T any](ctx context.Context, client *firestore.Client, col, id string) (*T, error)

Get sets the in parameter to specific store record by id.

func GetClient added in v0.4.3

func GetClient(ctx context.Context, projectID string) (client *firestore.Client, err error)

GetClient returns instantiated Firestore client.

func GetClientOrPanic added in v0.4.3

func GetClientOrPanic(ctx context.Context, projectID string) *firestore.Client

GetClientOrPanic returns instantiated Firestore client or panics on error.

func GetCollection added in v0.3.1

func GetCollection(client *firestore.Client, name string) (col *firestore.CollectionRef, err error)

GetCollection returns specific store collection by name.

func Query added in v0.1.1

func Query[T any](ctx context.Context, client *firestore.Client, c *Criteria) ([]*T, error)

Query retreaves access info for all users since last update.

func Save added in v0.3.1

func Save[T any](ctx context.Context, client *firestore.Client, col, id string, in *T) error

Save saves the data to the store.

func ToStructs added in v0.3.2

func ToStructs[T any](it *firestore.DocumentIterator) ([]*T, error)

ToStructs converts the Firestore document iterator into a slice of structs.

func ToStructsWithHandler added in v0.4.1

func ToStructsWithHandler[T any](it *firestore.DocumentIterator, h func(item *T) (bool, error)) ([]*T, error)

ToStructsWithHandler converts the Firestore document iterator into a slice of structs.

func Update added in v0.3.1

func Update(ctx context.Context, client *firestore.Client, col, id string, args map[string]interface{}) error

Update updates the data in the store.

Types

type Criteria added in v0.3.1

type Criteria struct {
	Collection string
	Criterions []*Criterion
	OrderBy    string
	Desc       bool
	Limit      int
}

Criteria represents a query to be executed against the Firestore.

type Criterion added in v0.1.1

type Criterion struct {
	Path      string
	Operation OperationType
	Value     interface{}
}

Criterion represents a single criteria for a query.

type Identifiable added in v0.4.1

type Identifiable interface {
	GetID() string
}

type OperationType added in v0.1.1

type OperationType string

OperationType represents the type of operation to be performed.

const (
	// OperationTypeEqual is equal to.
	OperationTypeEqual OperationType = "=="
	// OperationTypeNotEqual is not equal to.
	OperationTypeNotEqual OperationType = "!="
	// OperationTypeLessThan is less than.
	OperationTypeLessThan OperationType = "<"
	// OperationTypeLessThanOrEqual is less than or equal to.
	OperationTypeLessThanOrEqual OperationType = "<="
	// OperationTypeGreaterThan is greater than.
	OperationTypeGreaterThan OperationType = ">"
	// OperationTypeGreaterThanOrEqual is greater than or equal to.
	OperationTypeGreaterThanOrEqual OperationType = ">="
	// OperationTypeArrayContains is array contains.
	OperationTypeArrayContains OperationType = "array-contains"
	// OperationTypeArrayContainsAny is array contains any.
	OperationTypeArrayContainsAny OperationType = "array-contains-any"
	// OperationTypeIn is in.
	OperationTypeIn OperationType = "in"
	// OperationTypeNotIn is not in.
	OperationTypeNotIn OperationType = "not-in"
)

Directories

Path Synopsis
examples
pkg
id

Jump to

Keyboard shortcuts

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