inmem.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Package inmem provides in-memory implementations of all the domain repositories.
  2. package inmem
  3. import (
  4. "sync"
  5. shipping "github.com/longjoy/micro-go-course/section19/cargo/model"
  6. )
  7. type cargoRepository struct {
  8. mtx sync.RWMutex
  9. cargos map[shipping.TrackingID]*shipping.Cargo
  10. }
  11. func (r *cargoRepository) Store(c *shipping.Cargo) (bool, error) {
  12. r.mtx.Lock()
  13. defer r.mtx.Unlock()
  14. r.cargos[c.TrackingID] = c
  15. return true, nil
  16. }
  17. func (r *cargoRepository) Find(id shipping.TrackingID) (*shipping.Cargo, error) {
  18. r.mtx.RLock()
  19. defer r.mtx.RUnlock()
  20. if val, ok := r.cargos[id]; ok {
  21. return val, nil
  22. }
  23. return nil, shipping.ErrUnknownCargo
  24. }
  25. func (r *cargoRepository) FindAll() []*shipping.Cargo {
  26. r.mtx.RLock()
  27. defer r.mtx.RUnlock()
  28. c := make([]*shipping.Cargo, 0, len(r.cargos))
  29. for _, val := range r.cargos {
  30. c = append(c, val)
  31. }
  32. return c
  33. }
  34. // NewCargoRepository returns a new instance of a in-memory cargo repository.
  35. func NewCargoRepository() shipping.CargoRepository {
  36. return &cargoRepository{
  37. cargos: make(map[shipping.TrackingID]*shipping.Cargo),
  38. }
  39. }
  40. type locationRepository struct {
  41. locations map[shipping.UNLocode]*shipping.Location
  42. }
  43. func (r *locationRepository) Find(locode shipping.UNLocode) (*shipping.Location, error) {
  44. if l, ok := r.locations[locode]; ok {
  45. return l, nil
  46. }
  47. return nil, shipping.ErrUnknownLocation
  48. }
  49. func (r *locationRepository) FindAll() []*shipping.Location {
  50. l := make([]*shipping.Location, 0, len(r.locations))
  51. for _, val := range r.locations {
  52. l = append(l, val)
  53. }
  54. return l
  55. }
  56. // NewLocationRepository returns a new instance of a in-memory location repository.
  57. func NewLocationRepository() shipping.LocationRepository {
  58. r := &locationRepository{
  59. locations: make(map[shipping.UNLocode]*shipping.Location),
  60. }
  61. r.locations[shipping.SESTO] = shipping.Stockholm
  62. r.locations[shipping.AUMEL] = shipping.Melbourne
  63. r.locations[shipping.CNHKG] = shipping.Hongkong
  64. r.locations[shipping.JNTKO] = shipping.Tokyo
  65. r.locations[shipping.NLRTM] = shipping.Rotterdam
  66. r.locations[shipping.DEHAM] = shipping.Hamburg
  67. return r
  68. }
  69. type voyageRepository struct {
  70. voyages map[shipping.VoyageNumber]*shipping.Voyage
  71. }
  72. func (r *voyageRepository) Find(voyageNumber shipping.VoyageNumber) (*shipping.Voyage, error) {
  73. if v, ok := r.voyages[voyageNumber]; ok {
  74. return v, nil
  75. }
  76. return nil, shipping.ErrUnknownVoyage
  77. }
  78. // NewVoyageRepository returns a new instance of a in-memory voyage repository.
  79. func NewVoyageRepository() shipping.VoyageRepository {
  80. r := &voyageRepository{
  81. voyages: make(map[shipping.VoyageNumber]*shipping.Voyage),
  82. }
  83. r.voyages[shipping.V100.VoyageNumber] = shipping.V100
  84. r.voyages[shipping.V300.VoyageNumber] = shipping.V300
  85. r.voyages[shipping.V400.VoyageNumber] = shipping.V400
  86. r.voyages[shipping.V0100S.VoyageNumber] = shipping.V0100S
  87. r.voyages[shipping.V0200T.VoyageNumber] = shipping.V0200T
  88. r.voyages[shipping.V0300A.VoyageNumber] = shipping.V0300A
  89. r.voyages[shipping.V0301S.VoyageNumber] = shipping.V0301S
  90. r.voyages[shipping.V0400S.VoyageNumber] = shipping.V0400S
  91. return r
  92. }
  93. type handlingEventRepository struct {
  94. mtx sync.RWMutex
  95. events map[shipping.TrackingID][]shipping.HandlingEvent
  96. }
  97. func (r *handlingEventRepository) Store(e shipping.HandlingEvent) {
  98. r.mtx.Lock()
  99. defer r.mtx.Unlock()
  100. // Make array if it's the first event with this tracking ID.
  101. if _, ok := r.events[e.TrackingID]; !ok {
  102. r.events[e.TrackingID] = make([]shipping.HandlingEvent, 0)
  103. }
  104. r.events[e.TrackingID] = append(r.events[e.TrackingID], e)
  105. }
  106. func (r *handlingEventRepository) QueryHandlingHistory(id shipping.TrackingID) shipping.HandlingHistory {
  107. r.mtx.RLock()
  108. defer r.mtx.RUnlock()
  109. return shipping.HandlingHistory{HandlingEvents: r.events[id]}
  110. }
  111. // NewHandlingEventRepository returns a new instance of a in-memory handling event repository.
  112. func NewHandlingEventRepository() shipping.HandlingEventRepository {
  113. return &handlingEventRepository{
  114. events: make(map[shipping.TrackingID][]shipping.HandlingEvent),
  115. }
  116. }