121 lines
3.3 KiB
Go
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
|
|
}
|