// Package inmem provides in-memory implementations of all the domain repositories. package inmem import ( "sync" shipping "github.com/longjoy/micro-go-course/section19/cargo/model" ) type cargoRepository struct { mtx sync.RWMutex cargos map[shipping.TrackingID]*shipping.Cargo } func (r *cargoRepository) Store(c *shipping.Cargo) (bool, error) { r.mtx.Lock() defer r.mtx.Unlock() r.cargos[c.TrackingID] = c return true, nil } func (r *cargoRepository) Find(id shipping.TrackingID) (*shipping.Cargo, error) { r.mtx.RLock() defer r.mtx.RUnlock() if val, ok := r.cargos[id]; ok { return val, nil } return nil, shipping.ErrUnknownCargo } func (r *cargoRepository) FindAll() []*shipping.Cargo { r.mtx.RLock() defer r.mtx.RUnlock() c := make([]*shipping.Cargo, 0, len(r.cargos)) for _, val := range r.cargos { c = append(c, val) } return c } // NewCargoRepository returns a new instance of a in-memory cargo repository. func NewCargoRepository() shipping.CargoRepository { return &cargoRepository{ cargos: make(map[shipping.TrackingID]*shipping.Cargo), } } type locationRepository struct { locations map[shipping.UNLocode]*shipping.Location } func (r *locationRepository) Find(locode shipping.UNLocode) (*shipping.Location, error) { if l, ok := r.locations[locode]; ok { return l, nil } return nil, shipping.ErrUnknownLocation } func (r *locationRepository) FindAll() []*shipping.Location { l := make([]*shipping.Location, 0, len(r.locations)) for _, val := range r.locations { l = append(l, val) } return l } // NewLocationRepository returns a new instance of a in-memory location repository. func NewLocationRepository() shipping.LocationRepository { r := &locationRepository{ locations: make(map[shipping.UNLocode]*shipping.Location), } r.locations[shipping.SESTO] = shipping.Stockholm r.locations[shipping.AUMEL] = shipping.Melbourne r.locations[shipping.CNHKG] = shipping.Hongkong r.locations[shipping.JNTKO] = shipping.Tokyo r.locations[shipping.NLRTM] = shipping.Rotterdam r.locations[shipping.DEHAM] = shipping.Hamburg return r } type voyageRepository struct { voyages map[shipping.VoyageNumber]*shipping.Voyage } func (r *voyageRepository) Find(voyageNumber shipping.VoyageNumber) (*shipping.Voyage, error) { if v, ok := r.voyages[voyageNumber]; ok { return v, nil } return nil, shipping.ErrUnknownVoyage } // NewVoyageRepository returns a new instance of a in-memory voyage repository. func NewVoyageRepository() shipping.VoyageRepository { r := &voyageRepository{ voyages: make(map[shipping.VoyageNumber]*shipping.Voyage), } r.voyages[shipping.V100.VoyageNumber] = shipping.V100 r.voyages[shipping.V300.VoyageNumber] = shipping.V300 r.voyages[shipping.V400.VoyageNumber] = shipping.V400 r.voyages[shipping.V0100S.VoyageNumber] = shipping.V0100S r.voyages[shipping.V0200T.VoyageNumber] = shipping.V0200T r.voyages[shipping.V0300A.VoyageNumber] = shipping.V0300A r.voyages[shipping.V0301S.VoyageNumber] = shipping.V0301S r.voyages[shipping.V0400S.VoyageNumber] = shipping.V0400S return r } type handlingEventRepository struct { mtx sync.RWMutex events map[shipping.TrackingID][]shipping.HandlingEvent } func (r *handlingEventRepository) Store(e shipping.HandlingEvent) { r.mtx.Lock() defer r.mtx.Unlock() // Make array if it's the first event with this tracking ID. if _, ok := r.events[e.TrackingID]; !ok { r.events[e.TrackingID] = make([]shipping.HandlingEvent, 0) } r.events[e.TrackingID] = append(r.events[e.TrackingID], e) } func (r *handlingEventRepository) QueryHandlingHistory(id shipping.TrackingID) shipping.HandlingHistory { r.mtx.RLock() defer r.mtx.RUnlock() return shipping.HandlingHistory{HandlingEvents: r.events[id]} } // NewHandlingEventRepository returns a new instance of a in-memory handling event repository. func NewHandlingEventRepository() shipping.HandlingEventRepository { return &handlingEventRepository{ events: make(map[shipping.TrackingID][]shipping.HandlingEvent), } }