package models import ( "database/sql" "fmt" "log" "net/url" "strconv" "time" ) type SameBookingError struct{} func (e SameBookingError) Error() string { return "the same booking already exists!" } type Booking struct { CardID string `json:"cardID"` ReaderID string `json:"readerID"` BookingType int `json:"bookingType"` LoggedTime time.Time `json:"loggedTime"` Id int `json:"id"` } var DB *sql.DB func (b Booking) New(card_id string, reader_id string, booking_type int) Booking { return Booking{ CardID: card_id, ReaderID: reader_id, BookingType: booking_type, } } func (b *Booking) FromUrlParams(params url.Values) Booking { bookingType, err := strconv.Atoi(params.Get("bookingType")) if err != nil { log.Println("Error parsing bookingType: ", err) return b.New("", "", 0) } cardID := params.Get("cardID") readerID := params.Get("readerID") return Booking{BookingType: bookingType, CardID: cardID, ReaderID: readerID} } func (b Booking) Verify() bool { if b.CardID == "" || b.ReaderID == "" || b.BookingType == 0 { return false } return true } func (b *Booking) Insert() error { if !checkLastBooking(*b) { return SameBookingError{} } stmt, err := DB.Prepare((`INSERT INTO zeiten (card_id, reader_id, booking_type) VALUES ($1, $2, $3) RETURNING id, logged_time`)) if err != nil { return err } err = stmt.QueryRow(b.CardID, b.ReaderID, b.BookingType).Scan(&b.Id, &b.LoggedTime) if err != nil { return err } return nil } func (b *Booking) GetBookingById(booking_id int) (Booking, error) { var booking Booking qStr, err := DB.Prepare((`SELECT id, logged_time, card_id, reader_id, booking_type FROM zeiten WHERE id = $1`)) if err != nil { return booking, err } err = qStr.QueryRow(booking_id).Scan(&booking.Id, &booking.LoggedTime, &booking.CardID, &booking.ReaderID, &booking.BookingType) if err != nil { return booking, err } if !booking.Verify() { fmt.Printf("Booking verification failed") return booking, nil } return booking, nil } func (b *Booking) GetBookingsByCardID(card_id string) ([]Booking, error) { qStr, err := DB.Prepare((`SELECT id, logged_time, card_id, reader_id, booking_type FROM zeiten WHERE card_id = $1`)) if err != nil { return nil, err } var bookings []Booking rows, err := qStr.Query(card_id) if err == sql.ErrNoRows { return bookings, err } if err != nil { return nil, err } defer rows.Close() for rows.Next() { var booking Booking if err := rows.Scan(&booking.Id, &booking.LoggedTime, &booking.CardID, &booking.ReaderID, &booking.BookingType); err != nil { return bookings, err } bookings = append(bookings, booking) } if err = rows.Err(); err != nil { return bookings, err } return bookings, nil } func (b Booking) Save() { qStr, err := DB.Prepare((`UPDATE "zeiten" SET "id" = $1, "card_id" = $2, "reader_id" = $3, "booking_type" = $4 WHERE "id" = $1;`)) if err != nil { log.Fatalf("Error preparing query: %v", err) return } _, err = qStr.Query(b.Id, b.CardID, b.ReaderID, b.BookingType) if err != nil { log.Fatalf("Error executing query: %v", err) return } } func (b *Booking) Update(nb Booking) { if b.BookingType != nb.BookingType && nb.BookingType != 0 { b.BookingType = nb.BookingType } if b.CardID != nb.CardID && nb.CardID != "" { b.CardID = nb.CardID } if b.ReaderID != nb.ReaderID && nb.ReaderID != "" { b.ReaderID = nb.ReaderID } } func checkLastBooking(b Booking) bool { var booking_type int stmt, err := DB.Prepare((`SELECT booking_type FROM "zeiten" WHERE "card_id" = $1 ORDER BY "logged_time" DESC LIMIT 1;`)) if err != nil { log.Fatalf("Error preparing query: %v", err) return false } err = stmt.QueryRow(b.CardID).Scan(&booking_type) if err == sql.ErrNoRows { return true } if err != nil { log.Println("Error checking last booking: ", err) return false } if booking_type == b.BookingType { return false } return true }