data

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 6, 2019 License: Apache-2.0 Imports: 6 Imported by: 10

README

Data 📚

GoDoc Go Report Card Build Status Codecov

Swappable Database Adapters for Go

This library helps to make simple database calls as easily as possible, by providing a simple, common interface that we can implement for every database we need. The goal of this package is to provide simple CRUD operations only, so each database will support many advanced features that are not available through this library.

The "Object" interface
// Object wraps all of the methods that a Domain Object must provide to Presto
type Object interface {

    // ID returns the primary key of the object
    ID() string

    // IsNew returns TRUE if the object has not yet been saved to the database
    IsNew() bool

    // SetCreated stamps the CreateDate and UpdateDate of the object, and adds a note to the Journal.
    SetCreated(comment string)

    // SetUpdated stamps the UpdateDate of the object, and adds a note to the Journal.
    SetUpdated(comment string)

    // SetDeleted marks the object virtually "deleted", and adds a note to the Journal.
    SetDeleted(comment string)
}

To implement this quickly, just attach the data.Journal object to your domain objects, and most of your work is already done.

Using datasources

// Configure your database
ds := mongodb.New(uri, dbname)

// Create a new session, one per server request.
session := ds.Session()
defer session.Close()

// Load from database into a person object
err := session.Load("Person", criteria, &person)

// Insert/Update a person object in the database
err := session.Save("Person", person)

// Delete a person from the database
err := session.Delete("Person", person)

data.mongodb

This adapter implements the data interface for MongoDB. It uses the standard MongoDB driver.

data.memory

This adapter implements the data interface for an in-memory datastore. It is the world's worst database, and should only be used for creating unit tests. If you use this "database" in production (hell, or even as a proof-of-concept demo) then you deserve the merciless mockery that fate holds for you.

Minimal Expression Builder

Every database has its own query language, so this library provides in intermediate format that should be easy to convert into whatever specific language you need to use.

// build a data directly
c := data.Criteria{{"id", "=", 42}, {"deleteDate", "=", 0}}

// build a data incrementally
c := data.Criteria{}

c.Add("id", data.OperatorEqual, 42)
c.Add("deleteDate", data.OperatorEqual, 0)

// combine data expressions into a single value
finalResult = data.combined(data1, data2, data3)

// Constants define standard expected operators
data.OperatorEqual    = "="
data.OperatorNotEqual = "!="
data.LessThan         = "<"
data.LessOrEqual      = "<="
data.GreaterThan      = ">"
data.GreaterOrEqual   = ">="

Documentation

Overview

Package data provides a data structure for defining simple database filters. This is not able to represent every imaginable query criteria, but it does a good job of making common criteria simple to format and pass around in your application.

Index

Constants

View Source
const OperatorEqual = "="

OperatorEqual represents an "equals" comparison, when used in Predicates and Criteria

View Source
const OperatorGreaterOrEqual = ">="

OperatorGreaterOrEqual represents an "equals" comparison, when used in Predicates and Criteria

View Source
const OperatorGreaterThan = ">"

OperatorGreaterThan represents an "equals" comparison, when used in Predicates and Criteria

View Source
const OperatorLessOrEqual = "<="

OperatorLessOrEqual represents an "equals" comparison, when used in Predicates and Criteria

View Source
const OperatorLessThan = "<"

OperatorLessThan represents an "equals" comparison, when used in Predicates and Criteria

View Source
const OperatorNotEqual = "!="

OperatorNotEqual represents an "equals" comparison, when used in Predicates and Criteria

Variables

This section is empty.

Functions

This section is empty.

Types

type Datastore

type Datastore interface {
	Session(context.Context) Session
}

Datastore is an abstract representation of a database and its connection information.

type Expression

type Expression []struct {
	Name     string      // The name of the field being compared
	Operator string      // The type of comparison (=, !=, >, >=, <, <=).  If this value is empty string, it is assumed to be "="
	Value    interface{} // The value that the field is being compared to
}

Expression represents a comparison or filter, to be used when loading objects from the database. Each service and database driver is expected to use this common format for query criteria, and then map it into the specific format required for that database.

func (*Expression) Add

func (exp *Expression) Add(name string, operator string, value interface{}) *Expression

Add appends a new predicate to an existing criteria expression.

func (Expression) Join

func (exp Expression) Join(criteriaToCombine ...Expression) Expression

Combine merges together the predicates of all provided criteria expressions, into a single criteria expression.

func (Expression) Match

func (exp Expression) Match(object interface{}) bool

Match uses reflection to compare this expression with an arbitrary struct. It is included here to simplify testing and development, but should not be used for production-ready code.

type Journal

type Journal struct {
	CreateDate int64  `json:"createDate" bson:"createDate"`
	UpdateDate int64  `json:"updateDate" bson:"updateDate"`
	DeleteDate int64  `json:"deleteDate" bson:"deleteDate"`
	Note       string `json:"note"       bson:"note"`
	Revision   int64  `json:"signature"  bson:"signature"`
}

Journal tracks a summary of changes to an object over time. Journal implements *most* of the data.Object interface (except for the ID function) right out of the box, so it's a useful example for implementing the data.Object interface, or even to embed directly into an existing model object.

func (*Journal) ETag

func (journal *Journal) ETag() string

ETag returns the signature for this object. It currently returns the "revision number" which should be fine unless we make out-of-band updates to objects.

func (*Journal) IsDeleted

func (journal *Journal) IsDeleted() bool

IsDeleted returns TRUE if the object has been "virtually deleted" from the database

func (*Journal) IsNew

func (journal *Journal) IsNew() bool

IsNew returns TRUE if the object has not yet been saved to the database

func (*Journal) SetCreated

func (journal *Journal) SetCreated(note string)

SetCreated must be called whenever a new object is added to the database

func (*Journal) SetDeleted

func (journal *Journal) SetDeleted(note string)

SetDeleted must be called to "virtual-delete" an object in the database

func (*Journal) SetUpdated

func (journal *Journal) SetUpdated(note string)

SetUpdated must be called whenever an existing object is updated in the database

type Object

type Object interface {

	// ID returns the primary key of the object
	ID() string

	// IsNew returns TRUE if the object has not yet been saved to the database
	IsNew() bool

	// SetCreated stamps the CreateDate and UpdateDate of the object, and makes a note
	SetCreated(comment string)

	// SetUpdated stamps the UpdateDate of the object, and makes a note
	SetUpdated(comment string)

	// SetDeleted marks the object virtually "deleted", and makes a note
	SetDeleted(comment string)
}

Object interface defines all of the methods that a Domain Object must provide to Presto

type Predicate

type Predicate struct {
	Name     string      // The name of the field being compared
	Operator string      // The type of comparison (=, !=, >, >=, <, <=).  If this value is empty string, it is assumed to be "="
	Value    interface{} // The value that the field is being compared to
}

Predicate represents a single expression, such as [name = "John Connor"]

func (Predicate) Validate

func (p Predicate) Validate() Predicate

Validate verifies that the values in the predicate are well formed. At this point, this just means that the operator is one of the valid operations.

type Session

type Session interface {
	Load(collection string, filter Expression, target Object) *derp.Error
	Save(collection string, object Object, note string) *derp.Error
	Delete(collection string, object Object, note string) *derp.Error
	Close()
}

Session represents a single database session, that is opened to support a single transactional request, and then closed when this transaction is complete

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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