finish pgc impl
This commit is contained in:
parent
f20f256313
commit
cec183b416
@ -194,6 +194,17 @@ func (q *Queries) AllRooms(ctx context.Context) ([]Room, error) {
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const deleteBlockByID = `-- name: DeleteBlockByID :exec
|
||||
DELETE FROM room_restrictions
|
||||
WHERE
|
||||
id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteBlockByID(ctx context.Context, id int32) error {
|
||||
_, err := q.db.Exec(ctx, deleteBlockByID, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteReservation = `-- name: DeleteReservation :exec
|
||||
DELETE FROM reservations
|
||||
WHERE
|
||||
@ -264,6 +275,64 @@ func (q *Queries) GetReservationByID(ctx context.Context, id int32) (GetReservat
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getRestrictionsForRoomByDate = `-- name: GetRestrictionsForRoomByDate :many
|
||||
SELECT
|
||||
id,
|
||||
coalesce(reservation_id, 0),
|
||||
restriction_id,
|
||||
room_id,
|
||||
start_date,
|
||||
end_date
|
||||
FROM
|
||||
room_restrictions
|
||||
WHERE
|
||||
$1 < end_date
|
||||
AND $2 >= start_date
|
||||
AND room_id = $3
|
||||
`
|
||||
|
||||
type GetRestrictionsForRoomByDateParams struct {
|
||||
EndDate pgtype.Date
|
||||
StartDate pgtype.Date
|
||||
RoomID int32
|
||||
}
|
||||
|
||||
type GetRestrictionsForRoomByDateRow struct {
|
||||
ID int32
|
||||
ReservationID int32
|
||||
RestrictionID int32
|
||||
RoomID int32
|
||||
StartDate pgtype.Date
|
||||
EndDate pgtype.Date
|
||||
}
|
||||
|
||||
func (q *Queries) GetRestrictionsForRoomByDate(ctx context.Context, arg GetRestrictionsForRoomByDateParams) ([]GetRestrictionsForRoomByDateRow, error) {
|
||||
rows, err := q.db.Query(ctx, getRestrictionsForRoomByDate, arg.EndDate, arg.StartDate, arg.RoomID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetRestrictionsForRoomByDateRow
|
||||
for rows.Next() {
|
||||
var i GetRestrictionsForRoomByDateRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ReservationID,
|
||||
&i.RestrictionID,
|
||||
&i.RoomID,
|
||||
&i.StartDate,
|
||||
&i.EndDate,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getRoomById = `-- name: GetRoomById :one
|
||||
SELECT
|
||||
id,
|
||||
@ -342,6 +411,41 @@ func (q *Queries) GetUserCred(ctx context.Context, email string) (GetUserCredRow
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertBlockForRoom = `-- name: InsertBlockForRoom :exec
|
||||
INSERT INTO
|
||||
room_restrictions (
|
||||
start_date,
|
||||
end_date,
|
||||
room_id,
|
||||
restriction_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6)
|
||||
`
|
||||
|
||||
type InsertBlockForRoomParams struct {
|
||||
StartDate pgtype.Date
|
||||
EndDate pgtype.Date
|
||||
RoomID int32
|
||||
RestrictionID int32
|
||||
CreatedAt pgtype.Timestamp
|
||||
UpdatedAt pgtype.Timestamp
|
||||
}
|
||||
|
||||
func (q *Queries) InsertBlockForRoom(ctx context.Context, arg InsertBlockForRoomParams) error {
|
||||
_, err := q.db.Exec(ctx, insertBlockForRoom,
|
||||
arg.StartDate,
|
||||
arg.EndDate,
|
||||
arg.RoomID,
|
||||
arg.RestrictionID,
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const insertReservation = `-- name: InsertReservation :one
|
||||
INSERT INTO
|
||||
reservations (
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"database/sql"
|
||||
"go-udemy-web-1/internal/config"
|
||||
"go-udemy-web-1/internal/repository"
|
||||
"go-udemy-web-1/internal/repository/db"
|
||||
)
|
||||
|
||||
type postgresDBRepo struct {
|
||||
@ -11,6 +12,11 @@ type postgresDBRepo struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
type pgcDBRepo struct {
|
||||
App *config.AppConfig
|
||||
Q *db.Queries
|
||||
}
|
||||
|
||||
type testDBRepo struct {
|
||||
App *config.AppConfig
|
||||
DB *sql.DB
|
||||
@ -28,3 +34,10 @@ func NewTestingRepo(a *config.AppConfig) repository.DatabaseRepo {
|
||||
App: a,
|
||||
}
|
||||
}
|
||||
|
||||
func NewPgcRepo(q *db.Queries, a *config.AppConfig) repository.DatabaseRepo {
|
||||
return &pgcDBRepo{
|
||||
App: a,
|
||||
Q: q,
|
||||
}
|
||||
}
|
||||
|
414
internal/repository/dbrepo/pgc.go
Normal file
414
internal/repository/dbrepo/pgc.go
Normal file
@ -0,0 +1,414 @@
|
||||
package dbrepo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"go-udemy-web-1/internal/models"
|
||||
"go-udemy-web-1/internal/repository/db"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func (m *pgcDBRepo) AllUsers() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// InsertReservation inserts a reservation into the database
|
||||
func (m *pgcDBRepo) InsertReservation(res models.Reservation) (int, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var newId int32
|
||||
newId, err := m.Q.InsertReservation(ctx, db.InsertReservationParams{
|
||||
FirstName: res.FirstName,
|
||||
LastName: res.LastName,
|
||||
Email: res.Email,
|
||||
Phone: res.Phone,
|
||||
StartDate: pgtype.Date{Time: res.StartDate, Valid: true},
|
||||
EndDate: pgtype.Date{Time: res.EndDate, Valid: true},
|
||||
RoomID: int32(res.Room.ID),
|
||||
CreatedAt: pgtype.Timestamp{Time: res.CreatedAt, Valid: true},
|
||||
UpdatedAt: pgtype.Timestamp{Time: res.UpdatedAt, Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(newId), nil
|
||||
}
|
||||
|
||||
// InsertRoomRestriction inserts a room restriction into the database
|
||||
func (m *pgcDBRepo) InsertRoomRestriction(r models.RoomRestriction) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.InsertRoomRestriction(ctx, db.InsertRoomRestrictionParams{
|
||||
StartDate: pgtype.Date{Time: r.StartDate, Valid: true},
|
||||
EndDate: pgtype.Date{Time: r.EndDate, Valid: true},
|
||||
RoomID: int32(r.Room.ID),
|
||||
ReservationID: pgtype.Int4{Int32: int32(r.ID), Valid: true},
|
||||
RestrictionID: int32(r.RestrictionID),
|
||||
CreatedAt: pgtype.Timestamp{Time: r.CreatedAt, Valid: true},
|
||||
UpdatedAt: pgtype.Timestamp{Time: r.UpdatedAt, Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SearchAvailabilityByDatesByRoomID returns true if availability exists for roomID, and false if no availability
|
||||
func (m *pgcDBRepo) SearchAvailabilityByDatesByRoomID(start, end time.Time, roomID int) (bool, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
numRows, err := m.Q.SearchAvailabilityByDatesByRoomID(ctx, db.SearchAvailabilityByDatesByRoomIDParams{
|
||||
RoomID: int32(roomID),
|
||||
EndDate: pgtype.Date{Time: start, Valid: true},
|
||||
StartDate: pgtype.Date{Time: end, Valid: false},
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if numRows == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// SearchAvailabilityForAllRooms returns a slice of rooms, if any, for given date range
|
||||
func (m *pgcDBRepo) SearchAvailabilityForAllRooms(start, end time.Time) ([]models.Room, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var rooms []models.Room
|
||||
|
||||
rows, err := m.Q.SearchAvailabilityForAllRooms(ctx, db.SearchAvailabilityForAllRoomsParams{
|
||||
EndDate: pgtype.Date{Time: start, Valid: true},
|
||||
StartDate: pgtype.Date{Time: start, Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
room := models.Room{
|
||||
RoomName: row.RoomName,
|
||||
ID: int(row.ID),
|
||||
}
|
||||
rooms = append(rooms, room)
|
||||
}
|
||||
|
||||
return rooms, nil
|
||||
}
|
||||
|
||||
// GetRoomById gets a room by id
|
||||
func (m *pgcDBRepo) GetRoomById(id int) (models.Room, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var room models.Room
|
||||
|
||||
row, err := m.Q.GetRoomById(ctx, int32(id))
|
||||
if err != nil {
|
||||
return room, err
|
||||
}
|
||||
room = models.Room{
|
||||
ID: int(row.ID),
|
||||
RoomName: row.RoomName,
|
||||
}
|
||||
|
||||
return room, nil
|
||||
}
|
||||
|
||||
// GetUserByID gets a user by id
|
||||
func (m *pgcDBRepo) GetUserByID(id int) (models.User, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var u models.User
|
||||
|
||||
row, err := m.Q.GetUserByID(ctx, int32(id))
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
|
||||
u = models.User{
|
||||
ID: int(row.ID),
|
||||
FirstName: row.FirstName,
|
||||
LastName: row.LastName,
|
||||
Email: row.Email,
|
||||
Password: row.Password,
|
||||
AccessLevel: int(row.AccessLevel),
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// UpdateUser updates a user in the database
|
||||
func (m *pgcDBRepo) UpdateUser(u models.User) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.UpdateUser(ctx, db.UpdateUserParams{
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Email: u.Email,
|
||||
AccessLevel: int32(u.AccessLevel),
|
||||
UpdatedAt: pgtype.Timestamp{Time: u.UpdatedAt, Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Authenticate authenticates a user
|
||||
func (m *pgcDBRepo) Authenticate(email, testPassword string) (int, string, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var id int
|
||||
var hashedPassword string
|
||||
|
||||
row, err := m.Q.GetUserCred(ctx, email)
|
||||
if err != nil {
|
||||
return id, "", err
|
||||
}
|
||||
id = int(row.ID)
|
||||
hashedPassword = row.Password
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(testPassword))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
return 0, "", errors.New("incorrect password")
|
||||
} else if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
return id, hashedPassword, nil
|
||||
}
|
||||
|
||||
// AllReservations returns a slice of all reservations
|
||||
func (m *pgcDBRepo) AllReservations() ([]models.Reservation, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var reservations []models.Reservation
|
||||
|
||||
rows, err := m.Q.AllReservations(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
r := models.Reservation{
|
||||
StartDate: row.StartDate.Time,
|
||||
EndDate: row.EndDate.Time,
|
||||
FirstName: row.FirstName,
|
||||
LastName: row.LastName,
|
||||
Email: row.Email,
|
||||
Phone: row.Phone,
|
||||
Room: models.Room{ID: int(row.RoomID), RoomName: row.RoomName.String},
|
||||
ID: int(row.ID),
|
||||
RoomID: int(row.RoomID),
|
||||
Processed: int(row.Processed),
|
||||
}
|
||||
|
||||
reservations = append(reservations, r)
|
||||
}
|
||||
|
||||
return reservations, nil
|
||||
}
|
||||
|
||||
// AllNewReservations returns a slice of all new reservations
|
||||
func (m *pgcDBRepo) AllNewReservations() ([]models.Reservation, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var reservations []models.Reservation
|
||||
|
||||
rows, err := m.Q.AllNewReservations(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
r := models.Reservation{
|
||||
StartDate: row.StartDate.Time,
|
||||
EndDate: row.EndDate.Time,
|
||||
FirstName: row.FirstName,
|
||||
LastName: row.LastName,
|
||||
Email: row.Email,
|
||||
Phone: row.Phone,
|
||||
Room: models.Room{ID: int(row.RoomID), RoomName: row.RoomName.String},
|
||||
ID: int(row.ID),
|
||||
RoomID: int(row.RoomID),
|
||||
Processed: int(row.Processed),
|
||||
}
|
||||
|
||||
reservations = append(reservations, r)
|
||||
}
|
||||
|
||||
return reservations, nil
|
||||
}
|
||||
|
||||
// GetReservationByID returns one reservation by ID
|
||||
func (m *pgcDBRepo) GetReservationByID(id int) (models.Reservation, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var res models.Reservation
|
||||
|
||||
row, err := m.Q.GetReservationByID(ctx, int32(id))
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res = models.Reservation{
|
||||
StartDate: row.StartDate.Time,
|
||||
EndDate: row.EndDate.Time,
|
||||
FirstName: row.FirstName,
|
||||
LastName: row.LastName,
|
||||
Email: row.Email,
|
||||
Phone: row.Phone,
|
||||
Room: models.Room{ID: int(row.RoomID), RoomName: row.RoomName.String},
|
||||
ID: int(row.ID),
|
||||
RoomID: int(row.RoomID),
|
||||
Processed: int(row.Processed),
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// UpdateReservation updates a user in the database
|
||||
func (m *pgcDBRepo) UpdateReservation(r models.Reservation) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.UpdateReservation(ctx, db.UpdateReservationParams{
|
||||
ID: int32(r.ID),
|
||||
FirstName: r.FirstName,
|
||||
LastName: r.LastName,
|
||||
Email: r.Email,
|
||||
Phone: r.Phone,
|
||||
UpdatedAt: pgtype.Timestamp{Time: r.UpdatedAt, Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *pgcDBRepo) DeleteReservation(id int) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.DeleteReservation(ctx, int32(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProcessedForReservation set processed for a reservation
|
||||
func (m *pgcDBRepo) UpdateProcessedForReservation(id, processed int) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.UpdateProcessedForReservation(ctx, db.UpdateProcessedForReservationParams{
|
||||
Processed: int32(processed),
|
||||
ID: int32(id),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *pgcDBRepo) AllRooms() ([]models.Room, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var rooms []models.Room
|
||||
|
||||
rows, err := m.Q.AllRooms(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
room := models.Room{
|
||||
RoomName: row.RoomName,
|
||||
ID: int(row.ID),
|
||||
}
|
||||
rooms = append(rooms, room)
|
||||
}
|
||||
return rooms, nil
|
||||
}
|
||||
|
||||
// GetRestrictionsForRoomByDate returns restrictions for a room by date range
|
||||
func (m *pgcDBRepo) GetRestrictionsForRoomByDate(roomId int, start, end time.Time) ([]models.RoomRestriction, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var restrictions []models.RoomRestriction
|
||||
|
||||
rows, err := m.Q.GetRestrictionsForRoomByDate(ctx, db.GetRestrictionsForRoomByDateParams{
|
||||
EndDate: pgtype.Date{Time: end, Valid: true},
|
||||
StartDate: pgtype.Date{Time: start, Valid: true},
|
||||
RoomID: int32(roomId),
|
||||
})
|
||||
if err != nil {
|
||||
return restrictions, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
r := models.RoomRestriction{
|
||||
StartDate: row.StartDate.Time,
|
||||
EndDate: row.EndDate.Time,
|
||||
ID: int(row.ID),
|
||||
RoomID: int(row.RoomID),
|
||||
ReservationID: int(row.ReservationID),
|
||||
RestrictionID: int(row.RestrictionID),
|
||||
}
|
||||
restrictions = append(restrictions, r)
|
||||
}
|
||||
|
||||
return restrictions, nil
|
||||
}
|
||||
|
||||
// InsertBlockForRoom inserts a room restriction
|
||||
func (m *pgcDBRepo) InsertBlockForRoom(id int, startDate time.Time) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.InsertBlockForRoom(ctx, db.InsertBlockForRoomParams{
|
||||
StartDate: pgtype.Date{Time: startDate, Valid: true},
|
||||
EndDate: pgtype.Date{Time: startDate.AddDate(0, 0, 1)},
|
||||
RoomID: int32(id),
|
||||
RestrictionID: 2,
|
||||
CreatedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
UpdatedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteBlockByID deletes a block by ID
|
||||
func (m *pgcDBRepo) DeleteBlockByID(id int) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := m.Q.DeleteBlockByID(ctx, int32(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -199,3 +199,36 @@ FROM
|
||||
rooms
|
||||
ORDER BY
|
||||
room_name;
|
||||
|
||||
-- name: GetRestrictionsForRoomByDate :many
|
||||
SELECT
|
||||
id,
|
||||
coalesce(reservation_id, 0),
|
||||
restriction_id,
|
||||
room_id,
|
||||
start_date,
|
||||
end_date
|
||||
FROM
|
||||
room_restrictions
|
||||
WHERE
|
||||
$1 < end_date
|
||||
AND $2 >= start_date
|
||||
AND room_id = $3;
|
||||
|
||||
-- name: InsertBlockForRoom :exec
|
||||
INSERT INTO
|
||||
room_restrictions (
|
||||
start_date,
|
||||
end_date,
|
||||
room_id,
|
||||
restriction_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
|
||||
-- name: DeleteBlockByID :exec
|
||||
DELETE FROM room_restrictions
|
||||
WHERE
|
||||
id = $1;
|
||||
|
Loading…
Reference in New Issue
Block a user