Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (app *application) registerUser(c *gin.Context) {
Password: register.Password,
Name: register.Name,
}

//checking
err = app.models.Users.Insert(user)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
Expand Down
139 changes: 138 additions & 1 deletion cmd/api/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/kunalkumar-1/Evently/internals/database"
)

// create event
// create event handler
func (app *application) createEvent(c *gin.Context) {

var event database.Event
Expand Down Expand Up @@ -144,3 +144,140 @@ func (app *application) deleteEvent(c *gin.Context) {

c.JSON(http.StatusNoContent, nil)
}

func (app *application) addAttendeeToEvent(c *gin.Context) {
eventId, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid event Id",
})
return
}

userId, err := strconv.Atoi(c.Param("userId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid user Id",
})
return
}

event, err := app.models.Events.Get(eventId) //get event by id
if err != nil { // if error in getting event
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to retrieve event",
})
return
}
if event == nil { // if event not found
c.JSON(http.StatusBadRequest, gin.H{
"error": "Event not found",
})
return
}

userToAdd, err := app.models.Users.Get(userId) //get user by id
if err != nil { // if error in getting user
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to retrieve user",
})
return
}
if userToAdd == nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "User not found",
})
return
}

existingAttendee, err := app.models.Attendees.GetByEventAndAttendee(event.Id, userToAdd.Id) //get user by id
if err != nil { // if error in getting user
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to retrieve attendee",
})
return
}
if existingAttendee != nil {
c.JSON(http.StatusConflict, gin.H{
"error": "Attendee already Exists",
})
return
}

attendee := &database.Attendee{
EventId: eventId,
UserId: userToAdd.Id,
}

_, err = app.models.Attendees.Insert(attendee)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "failed to add attendee",
})
return
}

c.JSON(http.StatusCreated, attendee)
}

func (app *application) getAttendeesForEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid event Id",
})
return
}
users, err := app.models.Attendees.GetAttendeeByEvent(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "failed to retrieve Attendees for events",
})
return
}
c.JSON(http.StatusOK, users)
}

func (app *application) deleteAttendeeFromEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id")) //event id
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid event Id",
})
}

userId, err := strconv.Atoi(c.Param("userId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid userId Id",
})
}

err = app.models.Attendees.Delete(userId, id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to delete attendee",
})
}

c.JSON(http.StatusNoContent, nil)
}

func (app *application) getEventsByAttendee(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid attendee Id",
})
return
}
user, err := app.models.Users.Get(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "failed to get events",
})
return
}

c.JSON(http.StatusOK, user)
}
14 changes: 9 additions & 5 deletions cmd/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ func (app *application) routes() http.Handler {

v1 := r.Group("/api/v1")
{
v1.POST("/events", app.createEvent) // create event
v1.GET("/events", app.getAllEvent) // get all events
v1.GET("/events/:id", app.getEvent) // get event by id
v1.PUT("/events/:id", app.updateEvent) // update event by id
v1.DELETE("/events/:id", app.deleteEvent) //delete the event by id
v1.POST("/events", app.createEvent) // create event
v1.GET("/events", app.getAllEvent) // get all events
v1.GET("/events/:id", app.getEvent) // get event by id
v1.PUT("/events/:id", app.updateEvent) // update event by id
v1.DELETE("/events/:id", app.deleteEvent) //delete the event by id
v1.GET("/events/:id/attendees/:userId", app.getAttendeesForEvent) // get attendee to event
v1.POST("/events/:id/attendees/:userId", app.addAttendeeToEvent) // add attendee to event
v1.DELETE("/events/:id/attendees/:userId", app.deleteAttendeeFromEvent) //delete attendee from event
v1.GET("/events/:id/attendees", app.getEventsByAttendee) //get attendees for event

v1.POST("/auth/register", app.registerUser) // register user
}
Expand Down
Binary file modified data.db
Binary file not shown.
113 changes: 112 additions & 1 deletion internals/database/attendee.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package database

import "database/sql"
import (
"context"
"database/sql"
"time"
)

type AttendeeModel struct {
Db *sql.DB
Expand All @@ -11,3 +15,110 @@ type Attendee struct {
EventId int `json:"eventid"`
UserId int `json:"userid"`
}

// Insert a new attendee into the database
func (a *AttendeeModel) Insert(attendee *Attendee) (*Attendee, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `INSERT INTO attendees (event_id, user_id) VALUES($1, $2) RETURNING id`
err := a.Db.QueryRowContext(ctx, query, attendee.EventId, attendee.UserId).Scan(&attendee.Id)

if err != nil {
return nil, err
}
return attendee, nil
}

// GetByEventAndAttendee retrieves an attendee by event ID and user ID
func (a *AttendeeModel) GetByEventAndAttendee(eventId, userId int) (*Attendee, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `SELECT id, event_id, user_id FROM attendees WHERE event_id = $1 AND user_id = $2`

var attendee Attendee
err := a.Db.QueryRowContext(ctx, query, eventId, userId).Scan(&attendee.Id, &attendee.EventId, &attendee.UserId)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}

return nil, err
}
return &attendee, nil
}

func (a *AttendeeModel) GetAttendeeByEvent(eventId int) ([]*User, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `
SELECT u.id, u.name, u.email
FROM users u
JOIN attendees a ON u.id = a.user_id
WHERE a.event_id = $1
`
rows, err := a.Db.QueryContext(ctx, query, eventId)
if err != nil {
return nil, err
}

defer rows.Close()

var users []*User

for rows.Next() { // looping through all the rows
var user User
err := rows.Scan(&user.Id, &user.Name, &user.Email)
if err != nil {
return nil, err
}

users = append(users, &user) // appending the user to the users slice
}

return users, nil
}

func (a *AttendeeModel) Delete(userId, eventId int) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `DELETE FROM attendees WHERE user_id = $1 AND event_id = $2`
_, err := a.Db.ExecContext(ctx, query, userId, eventId)
if err != nil {
return err
}
return nil
}

func (a *AttendeeModel) GetEventsByAttendee(AttendeeId int) ([]*Event, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `
SELECT e.id, e.owner_id, e.name, e.description, e.date, e.location
FROM events e
JOIN attendees a ON e.id = a.event_id
WHERE a.user_id = $1
`
row, err := a.Db.QueryContext(ctx, query, AttendeeId)
if err != nil {
return nil, err
}

defer row.Close()

var events []*Event

for row.Next() {
var event Event
err := row.Scan(&event.Id, &event.OwnerId, &event.Name, &event.Description, &event.Date, &event.Location)
if err != nil {
return nil, err
}
events = append(events, &event)
}
return events, nil
}
16 changes: 16 additions & 0 deletions internals/database/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ func (u *UserModel) Insert(user *User) error {
return u.Db.QueryRowContext(ctx, query, user.Name, user.Email, user.Password).Scan(&user.Id)

}

func (u *UserModel) Get(id int) (*User, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

query := `SELECT * FROM users WHERE id = $1`
var user User
err := u.Db.QueryRowContext(ctx, query, id).Scan(&user.Id, &user.Name, &user.Email, &user.Password)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
return &user, nil
}
2 changes: 1 addition & 1 deletion tmp/build-errors.log
Original file line number Diff line number Diff line change
@@ -1 +1 @@
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
Binary file modified tmp/main
Binary file not shown.