Documentation ¶
Overview ¶
Package mongo mask the connection to MongoDB using mgo package.
This is made with function Connect, that saves Session and Mongo object which will be used later from other packages. Also, I've embedded the Collection, Database and Query types, to allow mocking via interfaces. The embedded was necessary for the functions to use the interfaces as return values, that way, the code can use the original, or generate a mock of them for testing purposes.
The package can be used like this:
// To connect with MongoDB database. mongo.Connect() defer mongo.Disconnect() // You can use mgo known functions with mongo.CurrentSession() or // mongo.Mongo(). If you want to use only the Database object to // handle the operations on MongoDB with a handler, use: mongo.ConsumeDatabaseOnSession(func(db elements.Databaser) { // Make db object available on handlers. p := handler.NewProductHandler() p.Link(db) // ... Do other operations. })
Other option of usage is through the use of mongo.DatabaseSocket:
// To connect with MongoDB database. mongo.Connect() defer mongo.Disconnect() // Create socket s := mongo.NewSocket() defer s.Close() // Make db object available on handlers. p := handler.NewProductHandler() p.Link(s.DB()) // ... Do other operations.
Or even through the concept of LinkedHandlers, as described later:
// To connect with MongoDB database. mongo.Connect() defer mongo.Disconnect() // Create a linked handler p, _ := handler.NewLinkedProductHandler() // ... Do other operations.
Further usage it's the same way mgo package is used. Look into mgo docs page: https://godoc.org/github.com/globalsign/mgo
The Connect function tries to connect to a MONGODB_URL environment variable, but when it's not defined, it uses a default URL:
mongodb://localhost:27017/severo-rest-db
You can mock some functions of this package, by mocking the mgo called functions mgo.ParseURL and mgo.Dial. Use the MockMongoSetup presented on this package (only in test environment), like:
create, _ := mongo.NewMockMongoSetup(t) defer create.Finish() create.ParseURL().Returns(db, nil) create.Dial().Returns(info, nil) // Call any preparations on connection ... if err := mongo.Connect(); err != nil { t.fail() }
Documenter ¶
Mongo package also contain utility functions to help modeling documents.
The package contains a interface Documenter which contain getters for important attributes to any document on MongoDB: _id, created_on and updated_on. It also contains functions that generates correctly the created_on and updated_on attributes.
The Documenter can be used like this:
// Create a type representing the Document type type Product struct { IDV ObjectId `json:"_id,omitempty" bson:"_id,omitempty"` CreatedOnV int64 `json:"created_on,omitempty" bson:"created_on,omitempty"` UpdatedOnV int64 `json:"updated_on,omitempty" bson:"updated_on,omitempty"` NameV string `json:"name" form:"name" binding:"required" bson:"name"` PriceV float32 `json:"price" form:"price" binding:"required" bson:"price"` } // Implement the Documenter interface. func (p *Product) ID() (id ObjectId) { id = p.IDV return } func (p *Product) CreatedOn() (t int64) { t = p.CreatedOnV return } func (p *Product) UpdatedOn() (t int64) { t = p.UpdatedOnV return } func (p *Product) New() (doc mongo.Documenter) { doc = &Product{} return } // On these methods, you can use the functions implemented mongo // package. func (p *Product) Map() (out M, err error) { out, err = mongo.MapDocumenter(p) return } func (p *Product) Init(in M) (err error) { var doc mongo.Documenter = p err = mongo.InitDocumenter(in, &doc) return } func (p *Product) GenerateID() { p.IDV = mongo.NewID() } func (p *Product) CalculateCreatedOn() { p.CreatedOnV = mongo.NowInMilli() } func (p *Product) CalculateUpdatedOn() { p.UpdatedOnV = mongo.NowInMilli() } // Create a product variable, and try its methods. p := Product{} p.CalculateCreatedOn() t := p.CreatedOn()
You can also mock some other functions of this package, by mocking some called functions time.Now and NewObjectId. Use the MockModelSetup presented on this package (only in test environment), like:
create, _ := mongo.NewMockModelSetup(t) defer create.Finish() create.Now().Returns(time.Parse("02-01-2006", "22/12/2006")) create.NewID().Returns(ObjectIdHex("anyID")) var d mongo.Documenter // Call any needed methods ... d.GenerateID() d.CalculateCreatedOn()
Handle ¶
Mongo package also enable creation of Handle, a type that connects to database collections and do some operations.
The Handle were made to be imported on embedding type, and through overriding of some methods, to implement an adequate Handler for a desired type of Document. The Handle type assumes to operate on a Documenter type, that will contain information about the operation to made with Handle.
The package should be used to create new types. Use the Handler type for creating embedding types.
type ProductHandle struct { *mongo.Handle DocumentV *product.Product }
For each new type, a constructor may be needed, and for that Handler has a basic constructor.
func New() (p *ProductHandle) { p = &ProductHandle{ Handle: mongo.NewHandle("products"), DocumentV: product.New(), } return } func NewLinked() (p *ProductHandle, err error) { p = &ProductHandle{ DocumentV: product.New(), } p.Handle, err = mongo.NewLinkedHandle("products") }
All functions were made to be overridden and rewrite. First thing to do it's creating the Link method, as it follows:
func (p *ProductHandle) Link(db mongo.Databaser) (err error) { err = p.Handle.Link(db) return }
The creation of Insert, Remove and RemoveAll are trivial. Call it with a Document getter function defined like:
func (p *ProductHandle) Document() (d *product.Product) { d = p.DocumentV return } func (p *ProductHandle) Insert() (err error) { err = p.Handle.Insert(p.Document()) return }
The Clean function is simple and helps a lot:
func (p *ProductHandle) Clean() { p.Handle.Clean() p.DocumentV = product.New() }
The Update function uses an id as an argument:
func (p *ProductHandle) Update(id ObjectId) (err error) { err = p.Handle.Update(id, p.Document()) return }
The complicated functions are Find and FindAll which requires casting for the Document type:
func (p *ProductHandle) Find() (prod *product.Product, err error) { var doc mongo.Documenter = product.New() err = p.Handle.Find(p.Document(), doc) prod = doc.(*product.Product) return } func (p *ProductHandle) FindAll() (proda []*product.Product, err error) { var da []mongo.Documenter err = p.Handle.FindAll(p.Document(), &da) proda = make([]*product.Product, len(da)) for i := range da { //noinspection GoNilContainerIndexing proda[i] = da[i].(*product.Product) } return }
For all functions written, verification it's advisable.
Index ¶
- Constants
- Variables
- func Connect() (err error)
- func ConsumeDatabaseOnSession(f func(elements.Databaser))
- func CurrentSession() (s elements.Sessioner)
- func Disconnect()
- func InitDocumenter(in M, out *Documenter) (err error)
- func Mongo() (m *elements.DialInfo)
- func NewID() (id bson.ObjectId)
- func NowInMilli() (t int64)
- type DatabaseSocket
- type Documenter
- type FakeDialer
- type FakeNewIDer
- type FakeNower
- type FakeParseURLer
- type Handle
- func (h *Handle) Clean()
- func (h *Handle) Close()
- func (h *Handle) Count() (n int, err error)
- func (h *Handle) Find(doc Documenter, out Documenter) (err error)
- func (h *Handle) FindAll(doc Documenter, out *[]Documenter) (err error)
- func (h *Handle) Insert(doc Documenter) (err error)
- func (h *Handle) IsSearchEmpty() (result bool)
- func (h *Handle) Link(db ...elements.Databaser) (err error)
- func (h *Handle) Name() (n string)
- func (h *Handle) Remove(id ObjectId) (err error)
- func (h *Handle) RemoveAll(doc Documenter) (info *elements.ChangeInfo, err error)
- func (h *Handle) SearchM() (s M)
- func (h *Handle) SetSocket(s *DatabaseSocket)
- func (h *Handle) Socket() (s *DatabaseSocket)
- func (h *Handle) Update(id ObjectId, doc Documenter) (err error)
- type M
- type MockCollectioner
- type MockDatabaser
- type MockMGOSetup
- type MockModelSetup
- type MockMongoSetup
- type ObjectId
Constants ¶
const ( // DBUrl is the default MongoDB url that will be used to // connect to the database. DBUrl = "mongodb://localhost:27017/test" )
Variables ¶
var ( // ErrIDNotDefined it's an error received when an ID isn't defined. ErrIDNotDefined = errors.New("ID not defined") // ErrDBNotDefined it's an error received when an DB is nil or // undefined. ErrDBNotDefined = errors.New("DB not defined") // ErrHandlerNotLinked it's an error received when the Handler // isn't linked to any collection. ErrHandlerNotLinked = errors.New("handler not linked to collection") // ErrTryRelinkWithNoSocket it's an error received when the Handler // tries a second Link with no socket defined on SetSocket(). ErrTryRelinkWithNoSocket = errors.New("no socket defined for relink") )
Functions ¶
func Connect ¶
func Connect() (err error)
Connect to MongoDB of server. It tries to connect with MONGODB_URL, but without defining this environment variable, tris to connect with default URL.
func ConsumeDatabaseOnSession ¶ added in v0.7.0
ConsumeDatabaseOnSession clones a session and use it to creates a Databaser object to be consumed in f function. Closes session after consume of Databaser object.
func CurrentSession ¶ added in v0.8.0
CurrentSession return connected mongo session.
func Disconnect ¶ added in v0.9.0
func Disconnect()
Disconnect undo the connection made. Preparing package for a new connection.
func InitDocumenter ¶ added in v1.0.0
func InitDocumenter(in M, out *Documenter) (err error)
InitDocumenter translates a M received, to the Documenter structure received as a pointer. It fills the structure fields with the values of each key in the M received.
func NowInMilli ¶ added in v1.0.0
func NowInMilli() (t int64)
NowInMilli returns the actual time, in a int64 value in Millisecond unit, used by the updaters of created_on and updated_on.
Types ¶
type DatabaseSocket ¶ added in v1.2.0
type DatabaseSocket struct {
// contains filtered or unexported fields
}
DatabaseSocket it's a socket connection with a specified MongoDB database, that can be closed after using it. It's used to make calls to the mongo collections parallel and independent.
func NewSocket ¶ added in v1.2.0
func NewSocket() (db *DatabaseSocket)
NewSocket creates a new DatabaseSocket, initializing channel values, supporting the DB calls.
func (*DatabaseSocket) Close ¶ added in v1.2.0
func (d *DatabaseSocket) Close()
Close the socket open when DB is called.
func (*DatabaseSocket) DB ¶ added in v1.2.0
func (d *DatabaseSocket) DB() (db elements.Databaser)
DB returns the database object returned by a cloned session of Mongo connection. Requires closing after operation is done, to avoid memory leak.
type Documenter ¶ added in v1.0.0
type Documenter interface { New() Documenter Map() (M, error) Init(M) error ID() ObjectId CreatedOn() int64 UpdatedOn() int64 GenerateID() CalculateCreatedOn() CalculateUpdatedOn() }
Documenter it's an interface that could be common to any documents types used to store values on a MongoDB. It contains getters and generates to important documents values: _id, created_on and updated_on
type FakeDialer ¶ added in v0.8.4
type FakeDialer interface { Returns(elements.Sessioner, error) GetFunction() func(string) (elements.Sessioner, error) }
FakeDialer it's a function mocking object, needed for mock purposes.
type FakeNewIDer ¶ added in v1.0.0
FakeNewIDer it's a function mocking object, needed for mock purposes.
type FakeNower ¶ added in v1.0.0
FakeNower it's a function mocking object, needed for mock purposes.
type FakeParseURLer ¶ added in v0.8.4
type FakeParseURLer interface { Returns(*elements.DialInfo, error) GetFunction() func(string) (*elements.DialInfo, error) }
FakeParseURLer it's a function mocking object, needed for mock purposes.
type Handle ¶ added in v1.0.0
type Handle struct { SearchMV M // contains filtered or unexported fields }
Handle it's a type implementing the Handler interface, responsible of taking documents and using them to manipulate collections.
func NewHandle ¶ added in v1.0.0
NewHandle creates a new Handle to be embedded onto handle for other types.
func NewLinkedHandle ¶ added in v1.2.0
NewLinkedHandle creates a new linked Handle to be embedded onto handle for other types. It fits for use on real application, since it tries for a direct connection with the MongoDB.
func (*Handle) Close ¶ added in v1.2.0
func (h *Handle) Close()
Close ends connection with the MongoDB collection for this handle. Resets socket to be used again after relinked with Link. If no Socket is defined, do nothing to avoid errors.
func (*Handle) Count ¶ added in v1.0.0
Count returns the number of documents on collection connected to Handle.
func (*Handle) Find ¶ added in v1.0.0
func (h *Handle) Find(doc Documenter, out Documenter) (err error)
Find search for a document matching the doc data on collection connected to Handle.
func (*Handle) FindAll ¶ added in v1.0.0
func (h *Handle) FindAll(doc Documenter, out *[]Documenter) (err error)
FindAll search for all documents matching the doc data on collection connected to Handle.
func (*Handle) Insert ¶ added in v1.0.0
func (h *Handle) Insert(doc Documenter) (err error)
Insert puts a new document on collection connected to Handle, using doc data.
func (*Handle) IsSearchEmpty ¶ added in v1.0.0
IsSearchEmpty verify if there aren't any key defined on the SearchM value.
func (*Handle) Link ¶ added in v1.0.0
Link connects the database to the Handle, enabling operations.
func (*Handle) Remove ¶ added in v1.0.0
Remove delete a document on collection connected to Handle, matching id received.
func (*Handle) RemoveAll ¶ added in v1.0.0
func (h *Handle) RemoveAll(doc Documenter) (info *elements.ChangeInfo, err error)
RemoveAll delete all documents on collection connected to Handle, matching the doc data.
func (*Handle) SetSocket ¶ added in v1.2.0
func (h *Handle) SetSocket(s *DatabaseSocket)
SetSocket defines a database socket to use on Handle for linking.
func (*Handle) Socket ¶ added in v1.2.0
func (h *Handle) Socket() (s *DatabaseSocket)
Socket returns the database socket used on Handle for linking.
type M ¶ added in v1.1.0
M is a convenient alias for a map[string]interface{} map, useful for dealing with BSON in a native way. For instance:
M{"a": 1, "b": true}
There's no special handling for this type in addition to what's done anyway for an equivalent map type. Elements in the map will be dumped in an undefined ordered.
func MapDocumenter ¶ added in v1.0.0
func MapDocumenter(in Documenter) (out M, err error)
MapDocumenter translates a Documenter in whatever structure it has, to a M object, more easily read by mgo.Collection methods.
type MockCollectioner ¶
type MockCollectioner = mocks.MockCollectioner
MockCollectioner is a mock of Collectioner interface
type MockDatabaser ¶
type MockDatabaser = mocks.MockDatabaser
MockDatabaser is a mock of Databaser interface
type MockMGOSetup ¶
type MockMGOSetup = mocks.MockMGOSetup
MockMGOSetup it's a setup type for configuring mocking of mgo package.
func NewMockMGOSetup ¶
func NewMockMGOSetup(t *testing.T) (s *MockMGOSetup, err error)
NewMockMGOSetup returns a new MockMGOSetup, already configuring mock environment for the mgo classes mocked with gomock. It requires a test environment to be running.
type MockModelSetup ¶ added in v1.0.0
type MockModelSetup struct {
// contains filtered or unexported fields
}
MockModelSetup it's a setup type for configuring mocking for util functions.
func NewMockModelSetup ¶ added in v1.0.0
func NewMockModelSetup(t *testing.T) (s *MockModelSetup, err error)
NewMockModelSetup returns a new MockModelSetup, already configuring a FakeNow function, and a FakeNewID function on the setup. It requires a test environment to be running.
func (*MockModelSetup) Finish ¶ added in v1.0.0
func (s *MockModelSetup) Finish()
Finish restore the functions mocked to the original ones.
func (*MockModelSetup) NewID ¶ added in v1.0.0
func (s *MockModelSetup) NewID() (f FakeNewIDer)
NewID returns the fake NewID object on this setup.
func (*MockModelSetup) Now ¶ added in v1.0.0
func (s *MockModelSetup) Now() (f FakeNower)
Now returns the fake Now object on this setup.
type MockMongoSetup ¶ added in v0.8.4
type MockMongoSetup struct {
// contains filtered or unexported fields
}
MockMongoSetup it's a setup type for configuring mocking for connect functions.
func NewMockMongoSetup ¶ added in v0.8.4
func NewMockMongoSetup(t *testing.T) (s *MockMongoSetup, err error)
NewMockMongoSetup returns a new MockMongoSetup, already configuring a FakeParseURL function, and a FakeDial function on the setup. It requires a test environment to be running.
func (*MockMongoSetup) Dial ¶ added in v0.8.4
func (s *MockMongoSetup) Dial() (f FakeDialer)
Dial returns the fake Dial object on this setup.
func (*MockMongoSetup) Finish ¶ added in v0.8.4
func (s *MockMongoSetup) Finish()
Finish restore the functions mocked to the original ones.
func (*MockMongoSetup) ParseURL ¶ added in v0.8.4
func (s *MockMongoSetup) ParseURL() (f FakeParseURLer)
ParseURL returns the fake ParseURL object on this setup.
type ObjectId ¶ added in v1.1.0
ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes long. MongoDB objects by default have such a property set in their "_id" property.
http://www.mongodb.org/display/DOCS/Object+Ids
func ObjectIdHex ¶ added in v1.1.0
ObjectIdHex returns an ObjectId from the provided hex representation. Calling this function with an invalid hex representation will cause a runtime panic.