mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
ed45c77be5
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
181 lines
4.0 KiB
Go
181 lines
4.0 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
// up to you:
|
|
// "go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
type Movie struct {
|
|
ID primitive.ObjectID `json:"_id" bson:"_id"` /* you need the bson:"_id" to be able to retrieve with ID filled */
|
|
Name string `json:"name"`
|
|
Cover string `json:"cover"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
type MovieService interface {
|
|
GetAll(ctx context.Context) ([]Movie, error)
|
|
GetByID(ctx context.Context, id string) (Movie, error)
|
|
Create(ctx context.Context, m *Movie) error
|
|
Update(ctx context.Context, id string, m Movie) error
|
|
Delete(ctx context.Context, id string) error
|
|
}
|
|
|
|
type movieService struct {
|
|
C *mongo.Collection
|
|
}
|
|
|
|
var _ MovieService = (*movieService)(nil)
|
|
|
|
func NewMovieService(collection *mongo.Collection) MovieService {
|
|
// up to you:
|
|
// indexOpts := new(options.IndexOptions)
|
|
// indexOpts.SetName("movieIndex").
|
|
// SetUnique(true).
|
|
// SetBackground(true).
|
|
// SetSparse(true)
|
|
|
|
// collection.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
|
// Keys: []string{"_id", "name"},
|
|
// Options: indexOpts,
|
|
// })
|
|
|
|
return &movieService{C: collection}
|
|
}
|
|
|
|
func (s *movieService) GetAll(ctx context.Context) ([]Movie, error) {
|
|
// Note:
|
|
// The mongodb's go-driver's docs says that you can pass `nil` to "find all" but this gives NilDocument error,
|
|
// probably it's a bug or a documentation's mistake, you have to pass `bson.D{}` instead.
|
|
cur, err := s.C.Find(ctx, bson.D{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cur.Close(ctx)
|
|
|
|
var results []Movie
|
|
|
|
for cur.Next(ctx) {
|
|
if err = cur.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// elem := bson.D{}
|
|
var elem Movie
|
|
err = cur.Decode(&elem)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// results = append(results, Movie{ID: elem[0].Value.(primitive.ObjectID)})
|
|
|
|
results = append(results, elem)
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func matchID(id string) (bson.D, error) {
|
|
objectID, err := primitive.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
filter := bson.D{{Key: "_id", Value: objectID}}
|
|
return filter, nil
|
|
}
|
|
|
|
var ErrNotFound = errors.New("not found")
|
|
|
|
func (s *movieService) GetByID(ctx context.Context, id string) (Movie, error) {
|
|
var movie Movie
|
|
filter, err := matchID(id)
|
|
if err != nil {
|
|
return movie, err
|
|
}
|
|
|
|
err = s.C.FindOne(ctx, filter).Decode(&movie)
|
|
if err == mongo.ErrNoDocuments {
|
|
return movie, ErrNotFound
|
|
}
|
|
return movie, err
|
|
}
|
|
|
|
func (s *movieService) Create(ctx context.Context, m *Movie) error {
|
|
if m.ID.IsZero() {
|
|
m.ID = primitive.NewObjectID()
|
|
}
|
|
|
|
_, err := s.C.InsertOne(ctx, m)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// The following doesn't work if you have the `bson:"_id` on Movie.ID field,
|
|
// therefore we manually generate a new ID (look above).
|
|
// res, err := ...InsertOne
|
|
// objectID := res.InsertedID.(primitive.ObjectID)
|
|
// m.ID = objectID
|
|
return nil
|
|
}
|
|
|
|
func (s *movieService) Update(ctx context.Context, id string, m Movie) error {
|
|
filter, err := matchID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// update := bson.D{
|
|
// {Key: "$set", Value: m},
|
|
// }
|
|
// ^ this will override all fields, you can do that, depending on your design. but let's check each field:
|
|
elem := bson.D{}
|
|
|
|
if m.Name != "" {
|
|
elem = append(elem, bson.E{Key: "name", Value: m.Name})
|
|
}
|
|
|
|
if m.Description != "" {
|
|
elem = append(elem, bson.E{Key: "description", Value: m.Description})
|
|
}
|
|
|
|
if m.Cover != "" {
|
|
elem = append(elem, bson.E{Key: "cover", Value: m.Cover})
|
|
}
|
|
|
|
update := bson.D{
|
|
{Key: "$set", Value: elem},
|
|
}
|
|
|
|
_, err = s.C.UpdateOne(ctx, filter, update)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return ErrNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *movieService) Delete(ctx context.Context, id string) error {
|
|
filter, err := matchID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = s.C.DeleteOne(ctx, filter)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return ErrNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|