package postgres import ( "context" "database/sql" "errors" "time" "datarush/internal/auth/domain" sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" ) const ( usersTable = "users" ) var psql = sq.StatementBuilder.PlaceholderFormat(sq.Dollar) type UserRepository struct { db *sqlx.DB } func NewUserRepository(db *sqlx.DB) *UserRepository { return &UserRepository{db: db} } func (r *UserRepository) Create(ctx context.Context, user *domain.User) error { now := time.Now() user.CreatedAt = now user.UpdatedAt = now query := psql.Insert(usersTable). Columns("id", "email", "username", "password", "created_at", "updated_at"). Values(user.ID.String(), user.Email, user.Username, user.Password, user.CreatedAt, user.UpdatedAt) _, err := query.RunWith(r.db).ExecContext(ctx) return err } func (r *UserRepository) GetByEmail(ctx context.Context, email string) (*domain.User, error) { query := psql.Select("id", "email", "username", "password", "created_at", "updated_at"). From(usersTable). Where(sq.Eq{"email": email}) sqlQuery, args, err := query.ToSql() if err != nil { return nil, err } var user domain.User err = r.db.GetContext(ctx, &user, sqlQuery, args...) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, domain.ErrUserNotFound } return nil, err } return &user, nil } func (r *UserRepository) GetByID(ctx context.Context, id domain.ID) (*domain.User, error) { query := psql.Select("id", "email", "username", "password", "created_at", "updated_at"). From(usersTable). Where(sq.Eq{"id": id.String()}) sqlQuery, args, err := query.ToSql() if err != nil { return nil, err } var user domain.User err = r.db.GetContext(ctx, &user, sqlQuery, args...) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, domain.ErrUserNotFound } return nil, err } return &user, nil } func (r *UserRepository) Update(ctx context.Context, user *domain.User) error { user.UpdatedAt = time.Now() query := psql.Update(usersTable). Set("email", user.Email). Set("username", user.Username). Set("password", user.Password). Set("updated_at", user.UpdatedAt). Where(sq.Eq{"id": user.ID.String()}) _, err := query.RunWith(r.db).ExecContext(ctx) return err } func (r *UserRepository) Delete(ctx context.Context, id domain.ID) error { query := psql.Delete(usersTable). Where(sq.Eq{"id": id.String()}) _, err := query.RunWith(r.db).ExecContext(ctx) return err }