mgdb

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: May 27, 2016 License: MIT Imports: 3 Imported by: 0

README

DFSS - MGDB lib

This library is used in order to manage a connection to mongoDB It uses the mgo driver, but aims at simplifying the queries to the database

Mongo Manager

The struct handling the connection is MongoManager. It requires an uri in order to initialize a connection : it is the uri containing the informations to connect to mongo. For example, in a test environment, we may have :

uri=localhost (require a mongo instance running on default port 27017)

In a prod environment however, it will more likely be :

uri=adm1n:AStr0ngPassw0rd@10.0.4.4:27017

Declaring an entity

Several conditions must be fulfilled to make a correct mapping between a golang struct and a mongo document :

  • All the mapped fields must be public
  • All the mapped fields must have the annotations key and bson
  • For a field, the value of the bson and key annotation must be equal
  • Among the fields, one and only one must have the annotated value '_id'

Now, you've noticed that there are two different annotations, yet containing the exact same value, why is that ? Well, it's a choice a modeling : the value of these annotation represents the field of the document in the database, but the bson will use it to marshall and unmarshall documents into structs, whereas the key annotation will use it to build complex queries. In short : two purposes -> two annotations

For example, given the entity :

type card struct {
    Id bson.ObjectId `key:_id bson:_id` // The order doesn't matter, this field is the id of the object, must be unique
    Height string    `key:height bson:height` // Height of the card
    Color color      `key:color bson:color` // Color of the card
}

The bson.ObjectId comes from mgo/bson, but you can very well have your own id :

type user struct {
    Mail        string   `key:_id bson:_id`
    Firstname   string   `key:fname bson:fname`
    Lastname    string   `key:lname bson:lname`
    Preferences []string `key:pref bson:pref`
    age         int
}

Here, the age field won't be persisted into the database, and all the users will have different mails.

Mongo Collection

Please refer to the example to see the API in practice.

Documentation

Overview

Package mgdb simplifies the mapping between Go and Mgo.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Metadata

type Metadata struct {

	// Mapping maps the go fields to the database fields
	Mapping map[string]string
}

Metadata represents the metadata for a struct

type MetadataFactory

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

MetadataFactory is a factory of metadata for structs Metadata are stored in a map, indexed by the struct name

func NewMetadataFactory

func NewMetadataFactory() *MetadataFactory

NewMetadataFactory instantiate a new empty factory

func (*MetadataFactory) Metadata

func (factory *MetadataFactory) Metadata(element interface{}) *Metadata

Metadata get the Metadata associated to the struct When querying with a yet unknown struct, the associated Metadata is built If it is already known, just returns the stored Metadata

func (*MetadataFactory) ToMap

func (factory *MetadataFactory) ToMap(element interface{}) map[string]interface{}

ToMap uses the metadata associated to the struct to returns the map of the struct. Keys are the database fields and values are the values stored in the struct

type MongoCollection

type MongoCollection struct {
	// Collection is the mgo.Collection struct
	Collection *mgo.Collection
	// contains filtered or unexported fields
}

MongoCollection is a wrapped around an mgo Collection to query to database

func (*MongoCollection) Count

func (manager *MongoCollection) Count() int

Count returns the number of entities currently in the Collection

func (*MongoCollection) DeleteAll

func (manager *MongoCollection) DeleteAll(query interface{}) (int, error)

DeleteAll deletes all the entities matching the selector The format of the selector is expected to follow the one provided in mgo's documentation Return the number of deleted entities

func (*MongoCollection) DeleteByID

func (manager *MongoCollection) DeleteByID(id interface{}) (bool, error)

DeleteByID deletes the entity matching the id Return true if the deletion was successful

func (*MongoCollection) Drop

func (manager *MongoCollection) Drop() error

Drop drops the current Collection This action is irreversible !

func (*MongoCollection) FindAll

func (manager *MongoCollection) FindAll(query interface{}, result interface{}) error

FindAll finds all entities matching the selector and put them into the result slice The format of the selector is expected to follow the one provided in mgo's documentation

func (*MongoCollection) FindByID

func (manager *MongoCollection) FindByID(id interface{}, result interface{}) error

FindByID fill the entity from the document with matching id

func (*MongoCollection) Insert

func (manager *MongoCollection) Insert(entity interface{}) (bool, error)

Insert persists an Entity into the selected Collection The _id field must be present in the mapping (see example provided)

func (*MongoCollection) UpdateAll

func (manager *MongoCollection) UpdateAll(selector interface{}, update interface{}) (int, error)

UpdateAll updates the entities matching the selector with the query The format of the parameters is expected to follow the one provided in mgo's documentation Return the number of updated entities

func (*MongoCollection) UpdateByID

func (manager *MongoCollection) UpdateByID(entity interface{}) (bool, error)

UpdateByID updates the entity with the new value provided. The _id of an Entity cannot be changed this way

type MongoManager

type MongoManager struct {

	// Session is the mgo.Session struct
	Session *mgo.Session

	// Database is the mgo.Database struct
	Database *mgo.Database

	Collections map[string]*MongoCollection
}

MongoManager is aimed at handling the Mongo connection through the mgo driver

Example
//Define an animal to be use in further tests
type animal struct {
	Name string `key:"_id" bson:"_id"`
	Race string `key:"race" bson:"race"`
	Age  int    `key:"age" bson:"age"`
}

//Initializes a MongoManager for the 'demo' database
manager, err := NewManager(dbURI)
if err != nil { /* Handle error */
}

// Connects to the collection named 'animals'
// If inexistant, it is created
animals := manager.Get("animals")

// Creates then insert a new animal into the collection
tails := animal{"Tails", "Fox", 15}
ok, _ := animals.Insert(tails)
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))

// Get the previously inserted animal
ani := animal{Name: "Tails"}
res := animal{}
err = animals.FindByID(ani, &res)
if err != nil { /* Handle error */
}

// res now contains the animal {"Tails", "Fox", 15}
// It is also possible to provided a struct with several field filled
// For example, the following code would have produced the same result
err = animals.FindByID(tails, &res)
if err != nil { /* Handle error */
}

// Update an entity and persist the changes in the database
res.Age += 2
ok, _ = animals.UpdateByID(res)
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))

// The database now contains the document {"_id": "Tails", "race": "Fox", age: 17}

ok, _ = animals.DeleteByID(res)
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))

// Tails has been successfully deleted from the database

// Insert a bunch of data for following examples

ok, _ = animals.Insert(animal{"Sonic", "Hedgehog", 12})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Eggman", "Robot", 15})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Amy", "Hedgehog", 12})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Tails", "Fox", 12})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Metal Sonic", "Robot", 14})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Knuckles", "Echidna", 13})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"EggRobo", "Robot", 15})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Tikal", "Echidna", 14})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Shadow", "Hedgehog", 13})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))
ok, _ = animals.Insert(animal{"Silver", "Hedgehog", 15})
fmt.Println(fmt.Sprintf("Transaction went ok : %v", ok))

// Get all documents in the collection
var all []animal
err = animals.FindAll(bson.M{}, &all)
if err != nil { /* Handle error */
}

// Get all hedgehogs
// The type bson.M is provided by mgo/bson, it is an alias for map[string]interface{}
// To learn how to make a proper query, just refer to mongoDB documentation
var hedgehogs []animal
err = animals.FindAll(bson.M{"race": "Hedgehog"}, &hedgehogs)
if err != nil { /* Handle error */
}

// Fetch Tails, Eggman and Silver
var tailsEggmanSilver []animal
names := make([]string, 3)
names[0] = "Tails"
names[1] = "Eggman"
names[2] = "Silver"
err = animals.FindAll(bson.M{"_id": bson.M{"$in": names}}, &tailsEggmanSilver)
if err != nil { /* Handle error */
}

// Update all animals with age > 12 and decrement by one
// The first argument is used to select some documents, and the second argument contains the modification to apply
count, _ := animals.UpdateAll(bson.M{"age": bson.M{"$gt": 12}}, bson.M{"$inc": bson.M{"age": -1}})
fmt.Println(fmt.Sprintf("%d animals were uodated", count))

// UpdateAll animals with race = 'Robot' and change it to 'Machine'
count, _ = animals.UpdateAll(bson.M{"race": "Robot"}, bson.M{"$set": bson.M{"race": "Machine"}})
fmt.Println(fmt.Sprintf("%d animals were uodated", count))

// Delete all hedgehogs
count, _ = animals.DeleteAll(bson.M{"race": "Hedgehog"})
fmt.Println(fmt.Sprintf("%d animals were uodated", count))

// Drop all the collection
// Be careful when using this
err = animals.Drop()
if err != nil { /* Handle error */
}
Output:

func NewManager

func NewManager(uri string) (*MongoManager, error)

NewManager a new Manager, the parameter `uri` needs to be set up with mongo uri, else it throws an error

func (*MongoManager) Close

func (m *MongoManager) Close()

Close closes the current connection Be careful, you won't be able to query the Collections anymore

func (*MongoManager) Get

func (m *MongoManager) Get(Collection string) *MongoCollection

Get returns a MongoCollection over a specified Collection The Collections are cached when they are called at least once

Jump to

Keyboard shortcuts

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