Files
2026-03-26 16:27:14 +00:00

121 lines
3.3 KiB
Go

package database
import (
"context"
"errors"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"gitea.hostxtra.co.uk/mrhid6/notely/backend/internal/domain/entities"
)
// UserRepository implements the user repository interface
type UserRepository struct {
collection *mongo.Collection
}
// NewUserRepository creates a new user repository
func NewUserRepository(db *mongo.Database) *UserRepository {
return &UserRepository{
collection: db.Collection("users"),
}
}
// CreateUser creates a new user
func (r *UserRepository) CreateUser(ctx context.Context, user *entities.User) error {
user.ID = bson.NewObjectID()
user.CreatedAt = time.Now()
user.UpdatedAt = time.Now()
_, err := r.collection.InsertOne(ctx, user)
return err
}
// GetUserByID retrieves a user by ID
func (r *UserRepository) GetUserByID(ctx context.Context, id bson.ObjectID) (*entities.User, error) {
var user entities.User
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&user)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// GetUserByEmail retrieves a user by email
func (r *UserRepository) GetUserByEmail(ctx context.Context, email string) (*entities.User, error) {
var user entities.User
err := r.collection.FindOne(ctx, bson.M{"email": email}).Decode(&user)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// GetUserByUsername retrieves a user by username
func (r *UserRepository) GetUserByUsername(ctx context.Context, username string) (*entities.User, error) {
var user entities.User
err := r.collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// UpdateUser updates a user
func (r *UserRepository) UpdateUser(ctx context.Context, user *entities.User) error {
user.UpdatedAt = time.Now()
_, err := r.collection.ReplaceOne(ctx, bson.M{"_id": user.ID}, user)
return err
}
// DeleteUser deletes a user
func (r *UserRepository) DeleteUser(ctx context.Context, id bson.ObjectID) error {
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
return err
}
// ListAllUsers retrieves all users sorted by creation date descending
func (r *UserRepository) ListAllUsers(ctx context.Context) ([]*entities.User, error) {
opts := options.Find().SetSort(bson.D{bson.E{Key: "created_at", Value: -1}})
cursor, err := r.collection.Find(ctx, bson.M{}, opts)
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
var users []*entities.User
if err := cursor.All(ctx, &users); err != nil {
return nil, err
}
return users, nil
}
// EnsureIndexes creates necessary indexes for users collection
func (r *UserRepository) EnsureIndexes(ctx context.Context) error {
indexModel := []mongo.IndexModel{
{
Keys: bson.D{bson.E{Key: "email", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{bson.E{Key: "username", Value: 1}},
Options: options.Index().SetUnique(true),
},
}
_, err := r.collection.Indexes().CreateMany(ctx, indexModel)
return err
}