package db import ( "JISQueueing/common" "database/sql" "errors" "time" ) //ErrTicketNotFound indicates that the provided ticket with the id does not belong to any tickets var ErrTicketNotFound = errors.New("ticket id does not exist") func GetAllTickets() []common.Ticket { rows, _ := db.Query("SELECT * FROM tickets") defer rows.Close() return convertIntoTickets(rows) } //GetTicketsByEmail queries all tickets that a specific client has made. func GetTicketsByEmail(email string) []common.Ticket { rows, _ := db.Query("SELECT * FROM tickets WHERE email=? COLLATE NOCASE", email) defer rows.Close() return convertIntoTickets(rows) } func GetTicket(id int) (common.Ticket, error) { rows, _ := db.Query("SELECT * FROM tickets where id=?", id) defer rows.Close() tickets := convertIntoTickets(rows) if len(tickets) == 0 { return common.Ticket{}, ErrTicketNotFound } return tickets[0], nil } //NewTicket generates a ticket with the current timestamp and inserts it into the database. func NewTicket(visitor common.Visitor) common.Ticket { now := time.Now().UTC() result, _ := db.Exec("INSERT INTO tickets (email, name, staff, time_start, time_end) VALUES (?, ?, ?, ?, ?)", visitor.Email, visitor.Name, "{}", now, time.Unix(0, 0).UTC()) lastInsertID, _ := result.LastInsertId() return common.Ticket{ ID: int(lastInsertID), Email: visitor.Email, Name: visitor.Name, Staff: "{}", Start: now, End: time.Unix(0, 0).UTC(), } } //SetClaimer updates the database with the staff user who claims a ticket. func SetClaimer(id int, username string) bool { ticket, ok := GetTicket(id) if ok != nil || ticket.Staff != "{}" { return false } result, _ := db.Exec("UPDATE tickets SET staff=? WHERE id=?", username, id) rowsAffected, _ := result.RowsAffected() return rowsAffected > 0 } //FinishTicket marks a ticket as complete in the database. func FinishTicket(id int) bool { if !isActive(id) { return false } result, _ := db.Exec("UPDATE tickets SET time_end=? WHERE id=?", time.Now().UTC(), id) rowsAffected, _ := result.RowsAffected() return rowsAffected > 0 } //Finish Ticket marks a ticket as cancelled if the user decides to cancel it or does not show up. func CancelTicket(id int) bool { if !isActive(id) { return false } result, _ := db.Exec("UPDATE tickets SET time_start=? WHERE id=?", time.Unix(0, 0), id) rowsAffected, _ := result.RowsAffected() return rowsAffected > 0 } func isActive(id int) bool { ticket, ok := GetTicket(id) if ok != nil { return false } if ticket.Start.Unix() == 0 || ticket.End.Unix() != 0 { println("start", ticket.Start.Unix(),"end", ticket.End.Unix()) return false } return true } //convertIntoTickets converts the result set from a sql query of a rows of visitors into a []common.Visitor. func convertIntoTickets(rows *sql.Rows) []common.Ticket { tickets := make([]common.Ticket, 0) for rows.Next() { var id int var email string var name string var staff string var start time.Time var end time.Time rows.Scan(&id, &email, &name, &staff, &start, &end) ticket := common.Ticket{ ID: id, Email: email, Name: name, Staff: staff, Start: start, End: end, } tickets = append(tickets, ticket) } return tickets }