-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrepository.go
156 lines (133 loc) · 4.31 KB
/
repository.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Interact with MongoDB database
package main
import (
"context"
"log"
pb "github.com/cedrickchee/neocargo/neocargo-service-shipment/proto/shipment"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
// Datastore models
// Shipment model
type Shipment struct {
ID string `json:"id"`
Weight int32 `json:"weight"`
Description string `json:"description"`
Containers Containers `json:"containers"`
VesselID string `json:"vessel_id"`
}
// Container model
type Container struct {
ID string `json:"id"`
CustomerID string `json:"customer_id"`
UserID string `json:"user_id"`
}
// Containers is a list of shipping container
type Containers []*Container
// Marshalling and unmarshalling functions
//
// Convert between the protobuf definition generated structs, and our internal
// datastore models.
//
// You can in theory use the generated structs as your models also, but this
// isn't neccessarily recommended from a software design perspective. As you are
// now coupling your data model, to your delivery layer. It's good to maintain
// these boundaries between the various responsibilities in your software.
// It may seem like additional overhead, but this is important for the
// extensibility of your software.
// MarshalContainerCollection ...
func MarshalContainerCollection(containers []*pb.Container) []*Container {
collection := make([]*Container, 0)
for _, container := range containers {
collection = append(collection, MarshalContainer(container))
}
return collection
}
// UnmarshalContainerCollection ...
func UnmarshalContainerCollection(containers []*Container) []*pb.Container {
collection := make([]*pb.Container, 0)
for _, container := range containers {
collection = append(collection, UnmarshalContainer(container))
}
return collection
}
// UnmarshalShipmentCollection ...
func UnmarshalShipmentCollection(shipments []*Shipment) []*pb.Shipment {
collection := make([]*pb.Shipment, 0)
for _, shipment := range shipments {
collection = append(collection, UnmarshalShipment(shipment))
}
return collection
}
// UnmarshalContainer ...
func UnmarshalContainer(container *Container) *pb.Container {
return &pb.Container{
Id: container.ID,
CustomerId: container.CustomerID,
UserId: container.UserID,
}
}
// MarshalContainer ...
func MarshalContainer(container *pb.Container) *Container {
return &Container{
ID: container.Id,
CustomerID: container.CustomerId,
UserID: container.UserId,
}
}
// MarshalShipment marshals an input shipment type to a shipment model
func MarshalShipment(shipment *pb.Shipment) *Shipment {
containers := MarshalContainerCollection(shipment.Containers)
return &Shipment{
ID: shipment.Id,
Weight: shipment.Weight,
Description: shipment.Description,
Containers: containers,
VesselID: shipment.VesselId,
}
}
// UnmarshalShipment ...
func UnmarshalShipment(shipment *Shipment) *pb.Shipment {
return &pb.Shipment{
Id: shipment.ID,
Weight: shipment.Weight,
Description: shipment.Description,
Containers: UnmarshalContainerCollection(shipment.Containers),
VesselId: shipment.VesselID,
}
}
type repository interface {
Create(ctx context.Context, shipment *Shipment) error
GetAll(ctx context.Context) ([]*Shipment, error)
}
// MongoRepository implementation
type MongoRepository struct {
collection *mongo.Collection
}
// Create creates a shipment collection
func (repository *MongoRepository) Create(ctx context.Context, shipment *Shipment) error {
_, err := repository.collection.InsertOne(ctx, shipment)
return err
}
// GetAll gets all shipment collection
func (repository *MongoRepository) GetAll(ctx context.Context) ([]*Shipment, error) {
log.Println("Shipment repo.GetAll")
cur, err := repository.collection.Find(ctx, bson.D{}, nil)
if err != nil {
log.Printf("Shipment repo.collection.Find err: %v\n", err)
return nil, err
}
log.Printf("Shipment repo.collection.Find OK. cur: %v", cur)
var shipments []*Shipment
for cur.Next(ctx) {
var shipment *Shipment
log.Println("Shipment repo cursor")
if err := cur.Decode(&shipment); err != nil {
log.Printf("Shipment repo Decode err: %v\n", err)
return nil, err
}
shipments = append(shipments, shipment)
}
log.Printf("Shipment repo shipments: %v\n", shipments)
return shipments, err
}