mogo

package module
v0.0.0-...-788c0d7 Latest Latest
Warning

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

Go to latest
Published: May 26, 2022 License: MIT Imports: 14 Imported by: 0

README

What's Mogo?

Mogo is a wrapper for mgo (https://github.com/globalsign/mgo) that adds ODM, hooks, validation, and population process to its raw Mongo functions. Mogo started as a fork of the bongo project and aims to be a re-thinking of the already developed concepts, nearest to the backend mgo driver, but without giving up the simplicity of use. It also adds advanced features such as pagination, population of referenced document which belongs to other collections, and index creation on document fields.

Mogo is tested using GoConvey (https://github.com/smartystreets/goconvey)

(note: if you like this repo and want to collaborate, please don't hesitate more ;-)

Usage

Basic Usage

Import the Library

go get github.com/goonode/mogo

import "github.com/goonode/mogo"

And install dependencies:

cd $GOHOME/src/github.com/goonode/mogo && go get .

Connect to a Database

Create a new mogo.Config instance:

config := &mogo.Config{
	ConnectionString: "localhostPort",
	Database:         "dbName",
}

Then just call the Connect func passing the config, and make sure to handle any connection errors:

connection, err := mogo.Connect(config)

if err != nil {
	log.Fatal(err)
}

Connect will create a connection for you and will also store this connection in the DBConn global var. This global var can be used to access the Connection object from any place inside the application and it will be used from all internal functions when an access to the connection is needed.

If you need to, you can access the raw mgo session with connection.Session.

Create a Model

A Model contains all information related to the the interface between a Document and the underlying mgo driver. You need to register a Model (and all Models you want to use in your application) before.

To create a new Model you need to define the document struct, attach the DocumentModel struct to it, and than you need to register it to mogo global registry:

type Bongo struct {
	mogo.DocumentModel `bson:",inline" coll:"mogo-registry-coll"`
	Name          string
	Friends       RefField `ref:"Macao"`
}

type Macao struct {
	mogo.DocumentModel `bson:",inline" coll:"mogo-registry-coll"`
	Name          string
}

mogo.ModelRegistry.Register(Bongo{}, Macao{})

ModelRegistry is an helper struct and can be used to globally register all models of the application. It will be used internally to store information about the document that will be used to perform internal magic.

Create a Document

Any struct can be used as a document, as long as it embeds the DocumentModel struct in a field. The DocumentModel provided with mogo implements the Document interface as well as the Model, NewTracker, TimeCreatedTracker and TimeModifiedTracker interfaces (to keep track of new/existing documents and created/modified timestamps). The DocumentModel must be embedded with bson:",inline" tag, otherwise you will get nested behavior when the data goes to your database. Also, it requires the coll or collection tag which will be used to assign the model to a mongo collection. The coll tag can be used only on this field of the struct, and each document can only have one collection. The idx or index tag can be used to create indexes (the index feature is in development stage and very limited at the moment). The syntax for the idx tag is {field1,...},unique,sparse,.... The field name must follow the bson tag specs.

The recommended way to create a new document model instance is by calling the NewDoc that returns a pointer to a newly created document.

type Person struct {
	mogo.DocumentModel `bson:",inline" coll:"user-coll"`
	FirstName string
	LastName string
	Gender string
}

func main() {
	Person := NewDoc(Person{}).(*Person)
	...
}

You can use child structs as well.

type HomeAddress struct {
		Street string
		Suite string
		City string
		State string
		Zip string
}

type Person struct {
	mogo.DocumentModel `bson:",inline" coll:"user-coll"`
	FirstName string
	LastName string
	Gender string
	HomeAddress HomeAddress
}

func main() {
	Person := NewDoc(Person{}).(*Person)
	...
}

Indexes can be defined using the idx tag on the field you want to create the index for. The syntax for the idx tag is

`idx:{field || field1,field2,...},keyword1,keyword2,...`

Supported keywords are unique, sparse, background and dropdups.

type HomeAddress struct {
		Street string
		Suite string
		City string
		State string
		Zip string
}

type Person struct {
	mogo.DocumentModel `bson:",inline" coll:"user-coll"`
	FirstName string	`idx:"{firstname},unique"`
	LastName string		`idx:"{lastname},unique"`
	Gender string
	HomeAddress HomeAddress `idx:"{homeaddress.street, homeaddress.city},unique,sparse"`
}

func main() {
	Person := NewDoc(Person{}).(*Person)
	...
}

Also composite literal can be used to initialize the document before creating a new instance:

func main() {
	Person := NewDoc(Person{
		FirstName: "MyFirstName",
		LastName: "MyLastName",
		...
	}).(*Person)
	...
}
Hooks

You can add special methods to your document type that will automatically get called by mogo during certain actions. Currently available hooks are:

  • func (s *DocumentStruct) Validate() []error (returns a slice of errors - if it is empty then it is assumed that validation succeeded)
  • func (s *DocumentStruct) BeforeSave() error
  • func (s *DocumentStruct) AfterSave() error
  • func (s *DocumentStruct) BeforeDelete() error
  • func (s *DocumentStruct) AfterDelete() error
  • func (s *DocumentStruct) AfterFind() error
Saving or Updating Models

To save a document just call Save() helper func passing the instance as parameter, or using the instance method of the created document instance. Actually the Save() func make a call to the underlying mgo.UpsertId() func, so it can be used to perform a document update, too.

myPerson := NewDoc(Person{}).(*Person)
myPerson.FirstName = "Bingo"
myPerson.LastName = "Mogo"

err := Save(myPerson)

or the equivalent form using the Save() method of the new instance:

myPerson := NewDoc(Person{}).(*Person)
myPerson.FirstName = "Bingo"
myPerson.LastName = "Mogo"

err := myPerson.Save()

Now you'll have a new document in the collection user-coll as defined into the Person model. If there is an error, you can check if it is a validation error using a type assertion:

if vErr, ok := err.(*Bongo.ValidationError); ok {
	fmt.Println("Validation errors are:", vErr.Errors)
} else {
	fmt.Println("Got a real error:", err.Error())
}
Deleting Documents

There are several ways to delete a document.

Remove / RemoveAll helper funcs

Same thing as Save - just call Remove passing the Document instance or RemoveAll by passing a slice of Documents.

err := Remove(person)

This will run the BeforeDelete and AfterDelete hooks, if applicable.

RemoveBySelector / RemoveAllBySelector helper funcs

This just delegates to mgo.Collection.Remove and mgo.Collection.RemoveAll. It will not run the BeforeDelete and AfterDelete hooks. The RemoveAllBySelector accepts a map of selectors for which the key is the interface name of the model and returns a map of *ChangeInfoWithError one for each passed interface.

err := RemoveBySelector(bson.M{"FirstName":"Testy"})
Finding

There are several ways to make a find. Finding methods are glued to the mgo driver so each method can use mgo driver directly (but this way also disable the hooks execution). The Query and Iter objects are defined as extensions of the mgo equivalent ones and for this reason all results are to be accessed using the iterator.

The define a query the Query object can be used as for example:

conn := getConnection()
defer conn.Session.Close()

ModelRegistry.Register(noHookDocument{}, hookedDocument{})

doc := NewDoc(noHookDocument{}).(*noHookDocument)

iter := doc.Find(nil).Iter()
for iter.Next(doc) {
	count++
}
Populate

It is possible to use a document field to store references to other documents. The document field needs to be of type RefField or RefFieldSlice and the ref tag needs to be attached to that field.

type Bongo struct {
	mogo.DocumentModel `bson:",inline" coll:"mogo-registry"` // The mogo will be stored in the mogo-registry collection
	Name          string
	Friends       RefFieldSlice `ref:"Macao"` // The field Friends of mogo is a reference to a slice of Macao objects
	BestFriend    RefField      `ref:"Macao"`
}

type Macao struct {
	mogo.DocumentModel `bson:",inline" coll:"mogo-registry"` // The Macao will be stored in the mogo-registry collection
	Name          string
}

mogo.ModelRegistry.Register(Bongo{}, Macao{})

The RefField accepts a bson id that will be stored in the related field of the document. To load the RefField with the referenced object, the Populate() method will be used. The Populate() works on loaded document (i.e. document returned by Find()/Iter() methods). The following example show how to use this feature.

...

bongo := NewDoc(Bongo{}).(*Bongo)

// All friends of bongo are macaos, and now we will give some friends to bongo
for i := 0; i < 10; i++ {
	macao := NewDoc(Macao{}).(*Macao)
	macao.Name = fmt.Sprintf("Macky%d", i)
	Save(macao)
	bongo.Friends = append(bongo.Friends, &RefField{ID: macao.ID})
}

// But bongo best friend is Polly
macao := NewDoc(Macao{}).(*Macao)
macao.Name = "Polly"
Save(macao)

bongo.BestFriend = RefField{ID: macao.ID}
Save(bongo)

// Now bongo.Friends contains a lot of ids, now we need to access to their data
q := bongo.Populate("Friends").All()

...

The Populate() method returns a special kind of mogo.Query object, for the referenced object, for which it is possible to chain a filter using the Find() method. In this case a bson.M type should be used as query interface.

...
q := bongo.Populate("Friends").Find(bson.M{"name": "Macky3"}).All()
...
Pagination: Paginate and NextPage

To enable pagination you need to call the Paginate() method and the NextPage() iterator.

conn := getConnection()
defer conn.Session.Close()

mogo.ModelRegistry.Register(noHookDocument{}, hookedDocument{})

doc := NewDoc(noHookDocument{}).(*noHookDocument)

iter := doc.Find(nil).Paginate(3).Iter()
results := make([]*noHookDocument, 3) 

for iter.NextPage(&results) {
	...
}

FindOne and FindByID helper funcs

You can use doc.FindOne() and doc.FindByID() as replacement of doc.Find().One() and doc.FindID().One()

Change Tracking

If your model struct implements the Trackable interface, it will automatically track changes to your model so you can compare the current values with the original. For example:

type MyModel struct {
	mogo.DocumentModel `bson:",inline"`
	StringVal string
	diffTracker *Bongo.DiffTracker
}

// Easy way to lazy load a diff tracker
func (m *MyModel) GetDiffTracker() *DiffTracker {
	if m.diffTracker == nil {
		m.diffTracker = mogo.NewDiffTracker(m)
	}

	return m.diffTracker
}

myModel := NewDoc(&MyModel{}).(*MyModel{})

Use as follows:

Check if a field has been modified
// Store the current state for comparison
myModel.GetDiffTracker().Reset()

// Change a property...
myModel.StringVal = "foo"

// We know it's been instantiated so no need to use GetDiffTracker()
fmt.Println(myModel.diffTracker.Modified("StringVal")) // true
myModel.diffTracker.Reset()
fmt.Println(myModel.diffTracker.Modified("StringVal")) // false
Get all modified fields
myModel.StringVal = "foo"
// Store the current state for comparison
myModel.GetDiffTracker().Reset()

isNew, modifiedFields := myModel.GetModified()

fmt.Println(isNew, modifiedFields) // false, ["StringVal"]
myModel.diffTracker.Reset()

isNew, modifiedFields = myModel.GetModified()
fmt.Println(isNew, modifiedFields) // false, []
Diff-tracking Session

If you are going to be checking more than one field, you should instantiate a new DiffTrackingSession with diffTracker.NewSession(useBsonTags bool). This will load the changed fields into the session. Otherwise with each call to diffTracker.Modified(), it will have to recalculate the changed fields.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ModelRegistry = make(ModelReg, 0)

ModelRegistry is the centralized registry of all models used for the app

Functions

func BuildIndex

func BuildIndex(p ParsedIndex) *mgo.Index

BuildIndex build an mgo Index using the values of a ParsedIndex struct

func GetBsonName

func GetBsonName(field reflect.StructField) string

GetBsonName ...

func GetChangedFields

func GetChangedFields(struct1 interface{}, struct2 interface{}, useBson bool) ([]string, error)

GetChangedFields ...

func MakeDoc

func MakeDoc(d interface{}) interface{}

MakeDoc (no returning new) adds the DocumentModel to an existant interface ((TODO))

func NewDoc

func NewDoc(d interface{}) interface{}

NewDoc ...

func Populate

func Populate(doc Document, query interface{}, ref string)

Populate (TODO: make this wrapper)

func Remove

func Remove(doc Document) error

Remove is a convenience (haha) method for Document.Remove

func RemoveAll

func RemoveAll(docs []Document) map[bson.ObjectId]error

RemoveAll is convenience method for Collection.RemoveAll

func RemoveAllBySelector

func RemoveAllBySelector(selectors map[Model]interface{}) map[string]*ChangeInfoWithError

RemoveAllBySelector is convenience method for Collection.RemoveAllBySelector

func RemoveBySelector

func RemoveBySelector(model Model, selector interface{}) error

RemoveBySelector is convenience method for Collection.RemoveBySelector The model argument here is used to reference its Collection to call the mgo driver on it.

func Save

func Save(doc Document) error

Save helper function

func TrimAllSpaces

func TrimAllSpaces(src string) string

TrimAllSpaces removes all spaces from the passed string and returns the trimmed string

func ValidateInclusionIn

func ValidateInclusionIn(value string, options []string) bool

ValidateInclusionIn ...

func ValidateMongoIDRef

func ValidateMongoIDRef(id bson.ObjectId, collection *Collection) bool

ValidateMongoIDRef ...

func ValidateRequired

func ValidateRequired(val interface{}) bool

ValidateRequired ...

func ValueOf

func ValueOf(d interface{}) reflect.Value

ValueOf return the reflect Value of d. In case of slice or map it reduces to a new primitive type.

Types

type AfterDeleteHook

type AfterDeleteHook interface {
	AfterDelete() error
}

AfterDeleteHook ...

type AfterFindHook

type AfterFindHook interface {
	AfterFind() error
}

AfterFindHook ...

type AfterSaveHook

type AfterSaveHook interface {
	AfterSave() error
}

AfterSaveHook ...

type BeforeDeleteHook

type BeforeDeleteHook interface {
	BeforeDelete() error
}

BeforeDeleteHook ...

type BeforeSaveHook

type BeforeSaveHook interface {
	BeforeSave() error
}

BeforeSaveHook ...

type ChangeInfoWithError

type ChangeInfoWithError struct {
	Info *mgo.ChangeInfo
	Err  error
}

ChangeInfoWithError is a return value for most of mgo methods

type Collection

type Collection struct {
	Name       string
	Database   string
	Context    *Context
	Connection *Connection
}

Collection ...

func (*Collection) C

func (c *Collection) C() *mgo.Collection

C ...

func (*Collection) Find

func (c *Collection) Find(query interface{}) *Query

Find is a wrapper to the mgo Find. This is the entry point to the Query object. Populate makes a call to this method with a special meaning

func (*Collection) FindID

func (c *Collection) FindID(id interface{}) *Query

FindID is a wrapper to the mgo FindId

func (*Collection) PreSave

func (c *Collection) PreSave(doc Document) error

PreSave ...

func (*Collection) Remove

func (c *Collection) Remove(doc Document) error

Remove removes the passed document from database, executing before and after delete hooks

func (*Collection) RemoveAll

func (c *Collection) RemoveAll(docs []Document) map[bson.ObjectId]error

RemoveAll removes all documents passed in slice executing, for each one, the before and after delete hooks. Document in slice can belong to different collections.

func (*Collection) RemoveAllBySelector

func (c *Collection) RemoveAllBySelector(selectors map[Model]interface{}) map[string]*ChangeInfoWithError

RemoveAllBySelector is a wrapper aorund mgo.RemoveAll method.

This is faster then Collection.RemoveAll method but it doesn't run before / after delete hooks.

The selectors argument is a map[Model]interface{}, where the key is the model (collection) on which we are going to apply the selector and the interface is the mgo selector.

func (*Collection) RemoveBySelector

func (c *Collection) RemoveBySelector(selector interface{}) error

RemoveBySelector is a wrapper aorund mgo.Remove method. This is faster the Collection.Remove method but it doesn't run before / after delete hooks

func (*Collection) Save

func (c *Collection) Save(doc Document) error

Save ...

type Config

type Config struct {
	ConnectionString string
	Database         string
	DialInfo         *mgo.DialInfo
}

Config ...

type Connection

type Connection struct {
	Config  *Config
	Session *mgo.Session
	Context *Context
}

Connection ...

var DBConn *Connection

DBConn is the connection initialized after Connect is called. All underlying operations are made using this connection

func Connect

func Connect(config *Config) (*Connection, error)

Connect creates a new connection and run Connect()

func (*Connection) Collection

func (m *Connection) Collection(name string) *Collection

Collection ...

func (*Connection) CollectionFromDatabase

func (m *Connection) CollectionFromDatabase(name string, database string) *Collection

CollectionFromDatabase ...

func (*Connection) Connect

func (m *Connection) Connect() (err error)

Connect to the database using the provided config

type Context

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

Context struct

func (*Context) Delete

func (c *Context) Delete(key string) bool

Delete ...

func (*Context) Get

func (c *Context) Get(key string) interface{}

Get ...

func (*Context) Set

func (c *Context) Set(key string, value interface{})

Set ...

type DiffTracker

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

DiffTracker ...

func NewDiffTracker

func NewDiffTracker(doc interface{}) *DiffTracker

NewDiffTracker ...

func (*DiffTracker) Clear

func (d *DiffTracker) Clear()

Clear ...

func (*DiffTracker) Compare

func (d *DiffTracker) Compare(useBson bool) (bool, []string, error)

Compare ...

func (*DiffTracker) GetModified

func (d *DiffTracker) GetModified(useBson bool) (bool, []string)

GetModified ...

func (*DiffTracker) GetOriginalValue

func (d *DiffTracker) GetOriginalValue(field string) (interface{}, error)

GetOriginalValue ...

func (*DiffTracker) Modified

func (d *DiffTracker) Modified(field string) bool

Modified test on DiffTracker struct...

func (*DiffTracker) NewSession

func (d *DiffTracker) NewSession(useBsonTags bool) (*DiffTrackingSession, error)

NewSession ...

func (*DiffTracker) Reset

func (d *DiffTracker) Reset()

Reset ...

func (*DiffTracker) SetOriginal

func (d *DiffTracker) SetOriginal(orig interface{})

SetOriginal ...

type DiffTrackingSession

type DiffTrackingSession struct {
	ChangedFields []string
	IsNew         bool
}

DiffTrackingSession ...

func (*DiffTrackingSession) Modified

func (s *DiffTrackingSession) Modified(field string) bool

Modified ...

type Document

type Document interface {
	Model
	GetID() bson.ObjectId
	SetID(bson.ObjectId)

	BsonID() *bson.M

	AsNew()
	AsDocument() Document
	AsModel() Model

	SetCInfo(*mgo.ChangeInfo)
	GetCInfo() *mgo.ChangeInfo
}

Document ...

type DocumentModel

type DocumentModel struct {
	ID       bson.ObjectId `bson:"_id,omitempty" json:"_id"`
	Created  time.Time     `bson:"_created" json:"_created"`
	Modified time.Time     `bson:"_modified" json:"_modified"`
	// contains filtered or unexported fields
}

DocumentModel ...

func (*DocumentModel) AsDocument

func (d *DocumentModel) AsDocument() Document

AsDocument tranforms the DocumentModel to Document interface

func (*DocumentModel) AsModel

func (d *DocumentModel) AsModel() Model

AsModel tranforms the DocumentModel to Document interface

func (*DocumentModel) AsNew

func (d *DocumentModel) AsNew()

AsNew assigns a new ID to the current document so it can be considered as a new document.

func (*DocumentModel) BsonID

func (d *DocumentModel) BsonID() *bson.M

BsonID returns the document id using bson.M interface style This method can be directly used with Find, but not with FindID which expects directly id interface{} (i.e. d.ID/d.GetID())

func (*DocumentModel) Find

func (d *DocumentModel) Find(query interface{}) *Query

Find is the wrapper method to mgo Find

func (*DocumentModel) FindByID

func (d *DocumentModel) FindByID(id interface{}, result interface{}) error

FindByID is a shortcut for FindID().One()

func (*DocumentModel) FindID

func (d *DocumentModel) FindID(id interface{}) *Query

FindID is a wrapper to the mgo FindId

func (*DocumentModel) FindOne

func (d *DocumentModel) FindOne(query interface{}, result interface{}) error

FindOne is a shortcut for Find().One()

func (*DocumentModel) GetAllIndex

func (d *DocumentModel) GetAllIndex() []*mgo.Index

GetAllIndex returns the mgo.Index struct required to mgo.EnsureIndex method using the ParsedIndex information stored in the index map of the Model. TODO: discard bad formatted indexes

func (*DocumentModel) GetAllParsedIndex

func (d *DocumentModel) GetAllParsedIndex() map[string][]ParsedIndex

GetAllParsedIndex returns all stored parsed indexes

func (*DocumentModel) GetCInfo

func (d *DocumentModel) GetCInfo() *mgo.ChangeInfo

GetCInfo gets the document cinfo field (see mgo.upsert)

func (*DocumentModel) GetColl

func (d *DocumentModel) GetColl() *Collection

GetColl implementation for Model interface

func (*DocumentModel) GetCollName

func (d *DocumentModel) GetCollName() string

GetCollName implementation for the Model interface

func (*DocumentModel) GetConn

func (d *DocumentModel) GetConn() *Connection

GetConn ...

func (*DocumentModel) GetCreated

func (d *DocumentModel) GetCreated() time.Time

GetCreated gets the created date

func (*DocumentModel) GetID

func (d *DocumentModel) GetID() bson.ObjectId

GetID satisfies the document interface

func (*DocumentModel) GetIndex

func (d *DocumentModel) GetIndex(name string) []*mgo.Index

GetIndex returns the mgo.Index struct required to mgo.EnsureIndex method using the ParsedIndex information stored for passed field name. TODO: discard bad formatted indexes

func (*DocumentModel) GetMe

func (d *DocumentModel) GetMe() (iname string, me interface{})

GetMe is used to save the iname, me fields of the document model. This is useful after returning from one of a find method where mgo driver return a freshly create zero filled struct.DocumentModel Note: mgo should consider bson "-" tag also on unmarshal, actually overwrites it

func (*DocumentModel) GetModified

func (d *DocumentModel) GetModified() time.Time

GetModified gets the modified date

func (*DocumentModel) GetParsedIndex

func (d *DocumentModel) GetParsedIndex(name string) []ParsedIndex

GetParsedIndex returns the index stored with the passed field name

func (*DocumentModel) GetRefIndex

func (d *DocumentModel) GetRefIndex(name string) RefIndex

GetRefIndex returns the RefIndex struct for the given field

func (*DocumentModel) IsNew

func (d *DocumentModel) IsNew() bool

IsNew to ask Is the document new

func (*DocumentModel) Populate

func (d *DocumentModel) Populate(f string) *Query

Populate builds a Query to populate the referenced field (see scratch) The returned Query object refers to the target field object not the original one.

func (*DocumentModel) Ref

func (d *DocumentModel) Ref(name string) RefIndex

Ref same as GetRefIndex

func (*DocumentModel) Remove

func (d *DocumentModel) Remove() error

Remove removes document from database, running before and after delete hooks

func (*DocumentModel) Save

func (d *DocumentModel) Save() error

Save ...

func (*DocumentModel) SetCInfo

func (d *DocumentModel) SetCInfo(ci *mgo.ChangeInfo)

SetCInfo sets the document cinfo field

func (*DocumentModel) SetCollName

func (d *DocumentModel) SetCollName(name string)

SetCollName implementation for Model interface (why may you need to change collection name at runtime ?)

func (*DocumentModel) SetConn

func (d *DocumentModel) SetConn(c *Connection)

SetConn ...

func (*DocumentModel) SetCreated

func (d *DocumentModel) SetCreated(t time.Time)

SetCreated sets the created date

func (*DocumentModel) SetID

func (d *DocumentModel) SetID(id bson.ObjectId)

SetID sets the ID for the document

func (*DocumentModel) SetIsNew

func (d *DocumentModel) SetIsNew(isNew bool)

SetIsNew satisfies the new tracker interface

func (*DocumentModel) SetMe

func (d *DocumentModel) SetMe(iname string, me interface{})

SetMe is used to set the iname and me fields

func (*DocumentModel) SetModified

func (d *DocumentModel) SetModified(t time.Time)

SetModified sets the modified date

type Iter

type Iter struct {
	MgoQ    *mgo.Query
	MgoI    *mgo.Iter
	Timeout bool
	Err     error

	Pagination *Paginate
}

Iter is the mgo.Iter wrapper

func (*Iter) Done

func (i *Iter) Done() bool

Done is a wrapper around mgo.Iter.Done

func (*Iter) Next

func (i *Iter) Next(result interface{}) bool

Next is a wrapper around mgo.Iter.Next. It executes AfterFindHook and updates the NewTracker interface if needed.

func (*Iter) NextPage

func (i *Iter) NextPage(results interface{}) bool

NextPage is the paginated version of the Next iterator. It fills the results slice using the Pagination field of the Iterator. Before using this the Query should be initialized using the Paginate() receiver.

type Model

type Model interface {
	GetCollName() string
	SetCollName(name string)
	GetColl() *Collection

	GetParsedIndex(name string) []ParsedIndex
	GetAllParsedIndex() map[string][]ParsedIndex
	GetIndex(name string) []*mgo.Index
	GetAllIndex() []*mgo.Index

	GetRefIndex(name string) RefIndex

	GetConn() *Connection
	SetConn(*Connection)

	GetMe() (iname string, me interface{})
	SetMe(iname string, me interface{})

	Find(interface{}) *Query
	FindID(interface{}) *Query

	Save() error
	Remove() error
}

Model ...

type ModelInternals

type ModelInternals struct {
	// Idx is the index of the field containing the DM
	Idx int
	// The Type
	Type reflect.Type

	// Model internal data
	Collection string
	Indexes    map[string][]ParsedIndex
	Refs       map[string]RefIndex
}

ModelInternals contains some internal information about the model

type ModelReg

type ModelReg map[string]*ModelInternals

ModelReg ...

func (ModelReg) Exists

func (r ModelReg) Exists(i interface{}) (string, *ModelInternals, bool)

Exists ...

func (ModelReg) ExistsByName

func (r ModelReg) ExistsByName(n string) (string, *ModelInternals, bool)

ExistsByName ...

func (ModelReg) Field

func (r ModelReg) Field(i int, d interface{}) reflect.Value

Field meturn the field the passed document model

func (ModelReg) Index

func (r ModelReg) Index(n string) int

Index returns the index of the DocumentModel field in the struct or -1 if the struct name passed is not found

func (ModelReg) New

func (r ModelReg) New(n string) interface{}

New ...

func (ModelReg) Refs

func (r ModelReg) Refs(n string) map[string]RefIndex

Refs returns the Refs of the DocumentModel field in the struct or nil if the struct name passed is not found

func (ModelReg) Register

func (r ModelReg) Register(i ...interface{})

Register ...

func (ModelReg) SearchRef

func (r ModelReg) SearchRef(i interface{}, n string) (*ModelInternals, *RefIndex)

SearchRef performs a search for n in Refs map and returns the *ModelInternals and *RefIndex if found it, or nil if not found.

func (ModelReg) TypeOf

func (r ModelReg) TypeOf(n string) reflect.Type

TypeOf ...

type NewTracker

type NewTracker interface {
	SetIsNew(bool)
	IsNew() bool
}

NewTracker ...

type Paginate

type Paginate struct {
	Page   int `json:"page"`   // Current page
	Pages  int `json:"pages"`  // Total pages
	N      int `json:"items"`  // Items per pages
	T      int `json:"total"`  // Total records in query
	OnPage int `json:"onPage"` // Records in current page
}

Paginate ...

type ParsedIndex

type ParsedIndex struct {
	Fields  []string
	Options []string
	// contains filtered or unexported fields
}

ParsedIndex contains a parsed index

func IndexScan

func IndexScan(src string) []ParsedIndex

IndexScan ... TODO:

add optional parameter to pass the name of the field to be used
in case of empty {} or if filled name is empty

type PopulateInfo

type PopulateInfo struct {
	RefField RefIndex
	Query    *Query
	Iter     *Iter
}

PopulateInfo ...

type Query

type Query struct {
	MgoC *mgo.Collection
	MgoQ *mgo.Query

	Pagination *Paginate

	// Populate if true says this query is a populate type query
	Populate bool

	// Query is the query used to build the mgo.Query. In case of populate query its type is bson.M
	// with $and operator to merge with the target id(s) of the target Model
	Query interface{}
}

Query is the mgo.Query wrapper

func Find

func Find(doc Document, query interface{}) *Query

Find is convenience method for Collection.Find

func FindID

func FindID(doc Document, id interface{}) *Query

FindID is convenience method for Collection.FindID

func (*Query) All

func (q *Query) All(result interface{}) error

All is a wrapper around mgo.Query.All (TODO: hooks should be triggered)

func (*Query) C

func (q *Query) C() *mgo.Collection

C direct access to mgo driver Collection layer

func (*Query) Find

func (q *Query) Find(query interface{}) *Query

Find makes a query filter and returns a Query object. If q is a populate type of Query object append the filter to the $and array.

func (*Query) Iter

func (q *Query) Iter() *Iter

Iter is a wrapper around mgo.Query.Iter

func (*Query) Limit

func (q *Query) Limit(n int) *Query

Limit is a wrapper around mgo.Query.Limit

func (*Query) One

func (q *Query) One(result interface{}) error

One is a wrapper around mgo.Query.One

func (*Query) Paginate

func (q *Query) Paginate(n int) *Query

Paginate prepares the Query to allow pagination

func (*Query) Q

func (q *Query) Q() *mgo.Query

Q direct access to mgo driver Query layer

func (*Query) Skip

func (q *Query) Skip(n int) *Query

Skip is a wrapper around mgo.Query.Skip

type RefField

type RefField struct {
	ID bson.ObjectId `bson:"_id,omitempty" json:"_id"`
}

RefField is a reference field to another model. The receiver will return the real object.

type RefFieldSlice

type RefFieldSlice []*RefField

RefFieldSlice is a slice of RefField. The receiver will return an Iterator to this field.

type RefIndex

type RefIndex struct {
	// The docuemnt model name
	Model string

	// The referenced object name
	Ref string

	// The field index in the parsed struct
	Idx int

	// The kind of the field (slice or other)
	Kind reflect.Kind

	// The type of the field
	Type reflect.Type

	// Whenever the reference object exists in the Registry
	Exists bool
}

RefIndex contains the object stored as reference in database

type Registry

type Registry interface {
	Register(...interface{})
	Exists(interface{}) (string, *ModelInternals, bool)
	ExistByName(string) (string, *ModelInternals, bool)

	Index(string) int
	TypeOf(string) reflect.Type

	New(string) interface{}

	Field(string, interface{}) interface{}
}

Registry ...

type Stringer

type Stringer interface {
	String() string
}

Stringer ...

type TimeCreatedTracker

type TimeCreatedTracker interface {
	GetCreated() time.Time
	SetCreated(time.Time)
}

TimeCreatedTracker ...

type TimeModifiedTracker

type TimeModifiedTracker interface {
	GetModified() time.Time
	SetModified(time.Time)
}

TimeModifiedTracker ...

type Trackable

type Trackable interface {
	GetDiffTracker() *DiffTracker
}

Trackable ...

type ValidateHook

type ValidateHook interface {
	Validate() []error
}

ValidateHook ...

type ValidationError

type ValidationError struct {
	Errors []error
}

ValidationError ...

func (*ValidationError) Error

func (v *ValidationError) Error() string

Jump to

Keyboard shortcuts

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