| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 | package mongoimport (	"gopkg.in/mgo.v2"	"gopkg.in/mgo.v2/bson"	shipping "github.com/longjoy/micro-go-course/section19/cargo/model")type cargoRepository struct {	db      string	session *mgo.Session}func (r *cargoRepository) Store(cargo *shipping.Cargo) (bool, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("cargo")	_, err := c.Upsert(bson.M{"trackingid": cargo.TrackingID}, bson.M{"$set": cargo})	return true, err}func (r *cargoRepository) Find(id shipping.TrackingID) (*shipping.Cargo, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("cargo")	var result shipping.Cargo	if err := c.Find(bson.M{"trackingid": id}).One(&result); err != nil {		if err == mgo.ErrNotFound {			return nil, shipping.ErrUnknownCargo		}		return nil, err	}	return &result, nil}func (r *cargoRepository) FindAll() []*shipping.Cargo {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("cargo")	var result []*shipping.Cargo	if err := c.Find(bson.M{}).All(&result); err != nil {		return []*shipping.Cargo{}	}	return result}// NewCargoRepository returns a new instance of a MongoDB cargo repository.func NewCargoRepository(db string, session *mgo.Session) (shipping.CargoRepository, error) {	r := &cargoRepository{		db:      db,		session: session,	}	index := mgo.Index{		Key:        []string{"trackingid"},		Unique:     true,		DropDups:   true,		Background: true,		Sparse:     true,	}	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("cargo")	if err := c.EnsureIndex(index); err != nil {		return nil, err	}	return r, nil}type locationRepository struct {	db      string	session *mgo.Session}func (r *locationRepository) Find(locode shipping.UNLocode) (*shipping.Location, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("location")	var result shipping.Location	if err := c.Find(bson.M{"unlocode": locode}).One(&result); err != nil {		if err == mgo.ErrNotFound {			return nil, shipping.ErrUnknownLocation		}		return nil, err	}	return &result, nil}func (r *locationRepository) FindAll() []*shipping.Location {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("location")	var result []*shipping.Location	if err := c.Find(bson.M{}).All(&result); err != nil {		return []*shipping.Location{}	}	return result}func (r *locationRepository) store(l *shipping.Location) (bool, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("location")	_, err := c.Upsert(bson.M{"unlocode": l.UNLocode}, bson.M{"$set": l})	return true, err}// NewLocationRepository returns a new instance of a MongoDB location repository.func NewLocationRepository(db string, session *mgo.Session) (shipping.LocationRepository, error) {	r := &locationRepository{		db:      db,		session: session,	}	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("location")	index := mgo.Index{		Key:        []string{"unlocode"},		Unique:     true,		DropDups:   true,		Background: true,		Sparse:     true,	}	if err := c.EnsureIndex(index); err != nil {		return nil, err	}	initial := []*shipping.Location{		shipping.Stockholm,		shipping.Melbourne,		shipping.Hongkong,		shipping.Tokyo,		shipping.Rotterdam,		shipping.Hamburg,	}	for _, l := range initial {		r.store(l)	}	return r, nil}type voyageRepository struct {	db      string	session *mgo.Session}func (r *voyageRepository) Find(voyageNumber shipping.VoyageNumber) (*shipping.Voyage, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("voyage")	var result shipping.Voyage	if err := c.Find(bson.M{"number": voyageNumber}).One(&result); err != nil {		if err == mgo.ErrNotFound {			return nil, shipping.ErrUnknownVoyage		}		return nil, err	}	return &result, nil}func (r *voyageRepository) store(v *shipping.Voyage) (bool, error) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("voyage")	_, err := c.Upsert(bson.M{"number": v.VoyageNumber}, bson.M{"$set": v})	return true, err}// NewVoyageRepository returns a new instance of a MongoDB voyage repository.func NewVoyageRepository(db string, session *mgo.Session) (shipping.VoyageRepository, error) {	r := &voyageRepository{		db:      db,		session: session,	}	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("voyage")	index := mgo.Index{		Key:        []string{"number"},		Unique:     true,		DropDups:   true,		Background: true,		Sparse:     true,	}	if err := c.EnsureIndex(index); err != nil {		return nil, err	}	initial := []*shipping.Voyage{		shipping.V100,		shipping.V300,		shipping.V400,		shipping.V0100S,		shipping.V0200T,		shipping.V0300A,		shipping.V0301S,		shipping.V0400S,	}	for _, v := range initial {		r.store(v)	}	return r, nil}type handlingEventRepository struct {	db      string	session *mgo.Session}func (r *handlingEventRepository) Store(e shipping.HandlingEvent) {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("handling_event")	_ = c.Insert(e)}func (r *handlingEventRepository) QueryHandlingHistory(id shipping.TrackingID) shipping.HandlingHistory {	sess := r.session.Copy()	defer sess.Close()	c := sess.DB(r.db).C("handling_event")	var result []shipping.HandlingEvent	_ = c.Find(bson.M{"trackingid": id}).All(&result)	return shipping.HandlingHistory{HandlingEvents: result}}// NewHandlingEventRepository returns a new instance of a MongoDB handling event repository.func NewHandlingEventRepository(db string, session *mgo.Session) shipping.HandlingEventRepository {	return &handlingEventRepository{		db:      db,		session: session,	}}
 |