Initial commit
This commit is contained in:
Executable
+110
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Table Booking</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<script src="script.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Table and Booking Management</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- Section to display and manage tables -->
|
||||
<section id="manage-tables">
|
||||
<h2>Manage Tables</h2>
|
||||
<table id="tables">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name (Number)</th>
|
||||
<th>Max People</th>
|
||||
<th>Room</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Data will be populated here -->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Create/Update Table</h3>
|
||||
<form id="table-form">
|
||||
<label for="table-id">Table ID (leave blank to create new):</label>
|
||||
<input type="number" id="table-id" name="id">
|
||||
|
||||
<label for="table-name">Name (Number):</label>
|
||||
<input type="number" id="table-name" name="name" required>
|
||||
|
||||
<label for="table-max-people">Max People:</label>
|
||||
<input type="number" id="table-max-people" name="max_people" required>
|
||||
|
||||
<label for="table-room">Room:</label>
|
||||
<input type="text" id="table-room" name="room" required>
|
||||
|
||||
<button type="submit">Save Table</button>
|
||||
</form>
|
||||
|
||||
<h3>Find Table by ID</h3>
|
||||
<form id="find-table-form">
|
||||
<label for="find-table-id">Enter Table ID:</label>
|
||||
<input type="number" id="find-table-id" name="id" required>
|
||||
<button type="submit">Find Table</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- Section to display and manage bookings -->
|
||||
<section id="manage-bookings">
|
||||
<h2>Manage Bookings</h2>
|
||||
<table id="bookings">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Table ID</th>
|
||||
<th>Reservation DateTime</th>
|
||||
<th>Time Reserve</th>
|
||||
<th>Who Booked</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Data will be populated here -->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Create/Update Booking</h3>
|
||||
<form id="booking-form">
|
||||
<label for="booking-id">Booking ID (leave blank to create new):</label>
|
||||
<input type="number" id="booking-id" name="id">
|
||||
|
||||
<label for="booking-table-id">Table ID:</label>
|
||||
<input type="number" id="booking-table-id" name="id_tables" required>
|
||||
|
||||
<label for="reservation-datetime">Reservation Date & Time:</label>
|
||||
<input type="datetime-local" id="reservation-datetime" name="reservation" required>
|
||||
|
||||
<label for="time-reserve">Time Reserve:</label>
|
||||
<input type="text" id="time-reserve" name="time_reserve" placeholder="e.g., 2 hours" required>
|
||||
|
||||
<label for="who-booked">Who Booked:</label>
|
||||
<input type="text" id="who-booked" name="who_booked" required>
|
||||
|
||||
<button type="submit">Save Booking</button>
|
||||
</form>
|
||||
|
||||
<!-- Section to find a booking by ID -->
|
||||
<h3>Find Booking by ID</h3>
|
||||
<form id="find-booking-form">
|
||||
<label for="find-booking-id">Enter Booking ID:</label>
|
||||
<input type="number" id="find-booking-id" name="id" required>
|
||||
<button type="submit">Find Booking</button>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Executable
+249
@@ -0,0 +1,249 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const apiUrl = "http://localhost:8080"; // Replace with your actual backend URL
|
||||
|
||||
// Fetch and populate table data
|
||||
function loadTables() {
|
||||
fetch(`${apiUrl}/tables`)
|
||||
.then((response) => response.json())
|
||||
.then((tables) => {
|
||||
const tableBody = document.querySelector("#tables tbody");
|
||||
tableBody.innerHTML = ""; // Clear existing rows
|
||||
|
||||
tables.forEach((table) => {
|
||||
const row = document.createElement("tr");
|
||||
row.innerHTML = `
|
||||
<td>${table.id}</td>
|
||||
<td>${table.name}</td>
|
||||
<td>${table.max_people}</td>
|
||||
<td>${table.room}</td>
|
||||
<td>
|
||||
<button data-id="${table.id}" class="edit">Edit</button>
|
||||
<button data-id="${table.id}" class="delete">Delete</button>
|
||||
</td>
|
||||
`;
|
||||
tableBody.appendChild(row);
|
||||
});
|
||||
})
|
||||
.catch((error) => console.error("Error loading tables:", error));
|
||||
}
|
||||
|
||||
// Handle form submission to create or update a table
|
||||
document.querySelector("#table-form").addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const id = parseInt(document.querySelector("#table-id").value, 10) || undefined;
|
||||
const name = parseInt(document.querySelector("#table-name").value, 10); // Adjusted for name as integer
|
||||
const maxPeople = parseInt(document.querySelector("#table-max-people").value, 10);
|
||||
const room = document.querySelector("#table-room").value;
|
||||
|
||||
const method = id ? "PUT" : "POST";
|
||||
const endpoint = id ? `/table` : `/table`;
|
||||
|
||||
fetch(`${apiUrl}${endpoint}`, {
|
||||
method,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ id, name, max_people: maxPeople, room }),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
return response.text().then((text) => {
|
||||
if (text.trim() === "") {
|
||||
throw new Error("Empty response from server");
|
||||
}
|
||||
try {
|
||||
const errorJson = JSON.parse(text);
|
||||
throw new Error(errorJson.message || "Failed to save table");
|
||||
} catch {
|
||||
throw new Error("Unexpected server response: " + text);
|
||||
}
|
||||
});
|
||||
}
|
||||
return response.text().then((text) => {
|
||||
if (text.trim() === "") {
|
||||
return {}; // Handle empty body for successful responses
|
||||
}
|
||||
return JSON.parse(text);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
document.querySelector("#table-form").reset();
|
||||
loadTables();
|
||||
alert(`Table ${id ? 'updated' : 'created'} successfully.`);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving table:", error);
|
||||
alert(`Failed to save table: ${error.message}`);
|
||||
});
|
||||
});
|
||||
|
||||
// Handle table row actions (edit/delete)
|
||||
document.querySelector("#tables").addEventListener("click", (e) => {
|
||||
const button = e.target;
|
||||
const id = button.dataset.id;
|
||||
|
||||
if (button.classList.contains("edit")) {
|
||||
fetch(`${apiUrl}/table/${id}`)
|
||||
.then((response) => response.json())
|
||||
.then((table) => {
|
||||
document.querySelector("#table-id").value = table.id;
|
||||
document.querySelector("#table-name").value = table.name;
|
||||
document.querySelector("#table-max-people").value = table.max_people;
|
||||
document.querySelector("#table-room").value = table.room;
|
||||
})
|
||||
.catch((error) => console.error("Error fetching table:", error));
|
||||
} else if (button.classList.contains("delete")) {
|
||||
fetch(`${apiUrl}/table/${id}`, { method: "DELETE" })
|
||||
.then(() => loadTables())
|
||||
.catch((error) => console.error("Error deleting table:", error));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle find table by ID
|
||||
document.querySelector("#find-table-form").addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const id = parseInt(document.querySelector("#find-table-id").value, 10);
|
||||
|
||||
fetch(`${apiUrl}/table/${id}`)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Table with ID ${id} not found`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((table) => {
|
||||
alert(`Table ID: ${table.id}\nName (Number): ${table.name}\nMax People: ${table.max_people}\nRoom: ${table.room}`);
|
||||
})
|
||||
.catch((error) => {
|
||||
alert(`Error: ${error.message}`);
|
||||
console.error("Error finding table:", error);
|
||||
});
|
||||
});
|
||||
|
||||
// Initial load
|
||||
loadTables();
|
||||
|
||||
// Fetch and populate booking data
|
||||
function loadBookings() {
|
||||
fetch(`${apiUrl}/bookings`)
|
||||
.then((response) => response.json())
|
||||
.then((bookings) => {
|
||||
const bookingBody = document.querySelector("#bookings tbody");
|
||||
bookingBody.innerHTML = ""; // Clear existing rows
|
||||
|
||||
bookings.forEach((booking) => {
|
||||
const row = document.createElement("tr");
|
||||
row.innerHTML = `
|
||||
<td>${booking.id}</td>
|
||||
<td>${booking.id_tables}</td>
|
||||
<td>${booking.reservation}</td>
|
||||
<td>${booking.time_reserve}</td>
|
||||
<td>${booking.who_booked}</td>
|
||||
<td>
|
||||
<button data-id="${booking.id}" class="edit">Edit</button>
|
||||
<button data-id="${booking.id}" class="delete">Delete</button>
|
||||
</td>
|
||||
`;
|
||||
bookingBody.appendChild(row);
|
||||
});
|
||||
})
|
||||
.catch((error) => console.error("Error loading bookings:", error));
|
||||
}
|
||||
|
||||
// Handle form submission to create or update a booking
|
||||
document.querySelector("#booking-form").addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const id = parseInt(document.querySelector("#booking-id").value, 10) || undefined;
|
||||
const tableId = parseInt(document.querySelector("#booking-table-id").value, 10);
|
||||
const reservationDatetime = String(document.querySelector("#reservation-datetime").value);
|
||||
const timeReserve = document.querySelector("#time-reserve").value;
|
||||
const whoBooked = document.querySelector("#who-booked").value;
|
||||
|
||||
const method = id ? "PUT" : "POST";
|
||||
const endpoint = id ? `/booking` : `/booking`;
|
||||
|
||||
fetch(`${apiUrl}${endpoint}`, {
|
||||
method,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ id, id_tables: tableId, reservation: reservationDatetime, time_reserve: timeReserve, who_booked: whoBooked }),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
return response.text().then((text) => {
|
||||
if (text.trim() === "") {
|
||||
throw new Error("Empty response from server");
|
||||
}
|
||||
try {
|
||||
const errorJson = JSON.parse(text);
|
||||
throw new Error(errorJson.message || "Failed to save table");
|
||||
} catch {
|
||||
throw new Error("Unexpected server response: " + text);
|
||||
}
|
||||
});
|
||||
}
|
||||
return response.text().then((text) => {
|
||||
if (text.trim() === "") {
|
||||
return {}; // Handle empty body for successful responses
|
||||
}
|
||||
return JSON.parse(text);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
document.querySelector("#booking-form").reset();
|
||||
loadBookings();
|
||||
alert(`Booking ${id ? 'updated' : 'created'} successfully.`);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving booking:", error);
|
||||
alert(`Failed to save booking: ${error.message}`);
|
||||
});
|
||||
});
|
||||
|
||||
// Handle booking row actions (edit/delete)
|
||||
document.querySelector("#bookings").addEventListener("click", (e) => {
|
||||
const button = e.target;
|
||||
const id = button.dataset.id;
|
||||
|
||||
if (button.classList.contains("edit")) {
|
||||
fetch(`${apiUrl}/booking/${id}`)
|
||||
.then((response) => response.json())
|
||||
.then((booking) => {
|
||||
document.querySelector("#booking-id").value = booking.id;
|
||||
document.querySelector("#booking-table-id").value = booking.id_tables;
|
||||
document.querySelector("#reservation-datetime").value = booking.reservation;
|
||||
document.querySelector("#time-reserve").value = booking.time_reserve;
|
||||
document.querySelector("#who-booked").value = booking.who_booked;
|
||||
})
|
||||
.catch((error) => console.error("Error fetching booking:", error));
|
||||
} else if (button.classList.contains("delete")) {
|
||||
fetch(`${apiUrl}/booking/${id}`, { method: "DELETE" })
|
||||
.then(() => loadBookings())
|
||||
.catch((error) => console.error("Error deleting booking:", error));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle find booking by ID
|
||||
document.querySelector("#find-booking-form").addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const id = document.querySelector("#find-booking-id").value;
|
||||
|
||||
fetch(`${apiUrl}/booking/${id}`)
|
||||
.then((response) => {
|
||||
if (!response.ok) throw new Error("Booking not found");
|
||||
return response.json();
|
||||
})
|
||||
.then((booking) => {
|
||||
alert(`Booking ID: ${booking.id}\nTable ID: ${booking.id_tables}\nReservation: ${booking.reservation}\nTime Reserve: ${booking.time_reserve}\nWho Booked: ${booking.who_booked}`);
|
||||
})
|
||||
.catch((error) => {
|
||||
alert(`Error: ${error.message}`);
|
||||
console.error("Error finding booking:", error);
|
||||
});
|
||||
});
|
||||
|
||||
// Initial load
|
||||
loadBookings();
|
||||
});
|
||||
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 20px;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
input, select {
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button {
|
||||
padding: 10px 15px;
|
||||
background-color: #007BFF;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"time"
|
||||
)
|
||||
|
||||
var databaseLocationFlag *string
|
||||
|
||||
var forceCreateSchemaFlag *bool
|
||||
|
||||
var createSchemaFlag *bool
|
||||
|
||||
var serverHostFlag *string
|
||||
|
||||
var serverPortFlag *int
|
||||
|
||||
var recordsLimitFlag *int
|
||||
|
||||
var recordsOffsetFlag *int
|
||||
|
||||
// Write timeout in seconds
|
||||
var writeTimeoutFlag *int
|
||||
|
||||
// Read timeout in seconds
|
||||
var readTimeoutFlag *int
|
||||
|
||||
func Init() {
|
||||
databaseLocationFlag = flag.String("file", "SQLiteDatabase.db", "The file contains the sql lite database")
|
||||
|
||||
forceCreateSchemaFlag = flag.Bool("force-new-schema", false, "Force create a new database by erasing the data. Overrides the new flag")
|
||||
|
||||
createSchemaFlag = flag.Bool("new-schema", false, "Create a new database")
|
||||
|
||||
serverHostFlag = flag.String("host", "localhost", "The host for the server")
|
||||
|
||||
serverPortFlag = flag.Int("port", 8080, "The port for the server")
|
||||
|
||||
recordsLimitFlag = flag.Int("limit", 10, "The number of records to return")
|
||||
|
||||
recordsOffsetFlag = flag.Int("offset", 0, "The number of records to skip")
|
||||
|
||||
writeTimeoutFlag = flag.Int("write-timeout", 10, "The write timeout in seconds")
|
||||
|
||||
readTimeoutFlag = flag.Int("read-timeout", 10, "The read timeout in seconds")
|
||||
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func GetForceCreateSchema() bool {
|
||||
return *forceCreateSchemaFlag
|
||||
}
|
||||
|
||||
func GetCreateSchema() bool {
|
||||
return *createSchemaFlag
|
||||
}
|
||||
|
||||
func GetWriteTimeout() time.Duration {
|
||||
result := time.Duration(*writeTimeoutFlag) * time.Second
|
||||
return result
|
||||
}
|
||||
|
||||
func GetReadTimeout() time.Duration {
|
||||
result := time.Duration(*readTimeoutFlag) * time.Second
|
||||
return result
|
||||
}
|
||||
|
||||
func GetServerHost() string {
|
||||
return *serverHostFlag
|
||||
}
|
||||
|
||||
func GetRecordsOffset() int {
|
||||
return *recordsOffsetFlag
|
||||
}
|
||||
|
||||
func GetRecordsLimit() int {
|
||||
return *recordsLimitFlag
|
||||
}
|
||||
|
||||
func GetServerPort() int {
|
||||
return *serverPortFlag
|
||||
}
|
||||
|
||||
func GetDatabaseLocation() string {
|
||||
return *databaseLocationFlag
|
||||
}
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"go_project/internal/configuration"
|
||||
"go_project/pkg/behaivor"
|
||||
)
|
||||
|
||||
func OpenDefault() (db *sqlx.DB, err error) {
|
||||
connectionParameters := configuration.GetDatabaseLocation()
|
||||
return Open(connectionParameters)
|
||||
}
|
||||
|
||||
func Open(connectionParameters string) (db *sqlx.DB, err error) {
|
||||
db, err = sqlx.Open("sqlite3", connectionParameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db, err
|
||||
}
|
||||
|
||||
// Closing the database with error checking
|
||||
func MustClose(db *sqlx.DB) {
|
||||
err := db.Close()
|
||||
behaivor.Anxiety("Database closing error", err)
|
||||
}
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"go_project/internal/models"
|
||||
"log"
|
||||
)
|
||||
|
||||
type (
|
||||
ListBookingParams struct {
|
||||
Limit int `db:"limit" json:"limit"`
|
||||
Offset int `db:"offset" json:"offset"`
|
||||
}
|
||||
|
||||
CreateBookingParams struct {
|
||||
IdTables int `db:"id_tables" json:"id_tables"`
|
||||
Reservation string `db:"reservation" json:"reservation"`
|
||||
TimeReserve string `db:"time_reserve" json:"time_reserve"`
|
||||
WhoBooked string `db:"who_booked" json:"who_booked"`
|
||||
}
|
||||
|
||||
UpdateBookingParams struct {
|
||||
Id int `db:"id" json:"id"`
|
||||
IdTables int `db:"id_tables" json:"id_tables"`
|
||||
Reservation string `db:"reservation" json:"reservation"`
|
||||
TimeReserve string `db:"time_reserve" json:"time_reserve"`
|
||||
WhoBooked string `db:"who_booked" json:"who_booked"`
|
||||
}
|
||||
)
|
||||
|
||||
func BookingById(db *sqlx.DB, id int) (*models.Booking, error) {
|
||||
rows, err := db.Query("SELECT * FROM Bookings WHERE id = ?", id)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if isEmpty := !rows.Next(); isEmpty {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := new(models.Booking)
|
||||
err = rows.Scan(&result.Id, &result.IdTables, &result.ReservationDatetime, &result.TimeReserve, &result.WhoBooked)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func AllBookings(db *sqlx.DB, params ListBookingParams) ([]models.Booking, error) {
|
||||
query := `SELECT * FROM Bookings ORDER BY id LIMIT $1 OFFSET $2`
|
||||
|
||||
rows, err := db.Query(query, params.Limit, params.Offset)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []models.Booking
|
||||
for rows.Next() {
|
||||
var currentBooking models.Booking
|
||||
|
||||
err = rows.Scan(¤tBooking.Id, ¤tBooking.IdTables, ¤tBooking.ReservationDatetime, ¤tBooking.TimeReserve, ¤tBooking.WhoBooked)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, currentBooking)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func CreateBooking(db *sqlx.DB, params CreateBookingParams) (*models.Booking, error) {
|
||||
query := `
|
||||
INSERT INTO Bookings (id_tables, reservation, time_reserve, who_booked)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, id_tables, reservation, time_reserve, who_booked
|
||||
`
|
||||
|
||||
var result models.Booking
|
||||
|
||||
err := db.QueryRow(query,
|
||||
params.IdTables,
|
||||
params.Reservation,
|
||||
params.TimeReserve,
|
||||
params.WhoBooked,
|
||||
).Scan(
|
||||
&result.Id,
|
||||
&result.IdTables,
|
||||
&result.ReservationDatetime,
|
||||
&result.TimeReserve,
|
||||
&result.WhoBooked,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("CreateBooking: Insertion operation of the Bookings object is failed: %v\n", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Println("CreateBooking: Insertion operation of the Bookings object is successful")
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func DeleteBookingById(db *sqlx.DB, id int) (sql.Result, error) {
|
||||
sqlResult, err := db.Exec("DELETE FROM Bookings WHERE id = ?", id)
|
||||
|
||||
if err == nil {
|
||||
log.Println("DeleteBookingById: Deletion operation of the Bookings object is successful")
|
||||
}
|
||||
|
||||
return sqlResult, err
|
||||
}
|
||||
|
||||
func UpdateBooking(db *sqlx.DB, params UpdateBookingParams) (*models.Booking, error) {
|
||||
query := `
|
||||
UPDATE Bookings
|
||||
SET id_tables = $1, reservation = $2, time_reserve = $3
|
||||
WHERE id = $4
|
||||
RETURNING id, id_tables, reservation, time_reserve, who_booked
|
||||
`
|
||||
|
||||
result := &models.Booking{}
|
||||
err := db.QueryRow(query, params.IdTables, params.Reservation, params.TimeReserve, params.Id).
|
||||
Scan(&result.Id, &result.IdTables, &result.ReservationDatetime, &result.TimeReserve, &result.WhoBooked)
|
||||
if err != nil {
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
log.Printf("UpdateBooking: No rows affected for Booking ID %d", params.Id)
|
||||
return nil, errors.New("update failed: no rows affected")
|
||||
default:
|
||||
log.Printf("UpdateBooking: Error executing query for Booking ID %d: %v", params.Id, err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("UpdateBooking: Successfully updated Booking ID %d", result.Id)
|
||||
return result, nil
|
||||
}
|
||||
Executable
+135
@@ -0,0 +1,135 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"go_project/internal/models"
|
||||
"log"
|
||||
)
|
||||
|
||||
type (
|
||||
ListTableParams struct {
|
||||
Limit int `db:"limit" json:"limit"`
|
||||
Offset int `db:"offset" json:"offset"`
|
||||
}
|
||||
|
||||
CreateTableParams struct {
|
||||
Name int `db:"name" json:"name"`
|
||||
MaxPeople int `db:"max_people" json:"max_people"`
|
||||
Room string `db:"room" json:"room"`
|
||||
}
|
||||
|
||||
UpdateTableParams struct {
|
||||
Id int `db:"id" json:"id"`
|
||||
Name int `db:"name" json:"name"`
|
||||
MaxPeople int `db:"max_people" json:"max_people"`
|
||||
Room string `db:"room" json:"room"`
|
||||
}
|
||||
)
|
||||
|
||||
func TableById(db *sqlx.DB, id int) (*models.Table, error) {
|
||||
rows, err := db.Query("SELECT * FROM Tables WHERE id = ?", id)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if isEmpty := !rows.Next(); isEmpty {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := new(models.Table)
|
||||
err = rows.Scan(&result.Id, &result.Name, &result.MaxPeople, &result.Room)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func AllTables(db *sqlx.DB, params ListTableParams) ([]models.Table, error) {
|
||||
query := `SELECT * FROM Tables ORDER BY id LIMIT $1 OFFSET $2`
|
||||
|
||||
rows, err := db.Query(query, params.Limit, params.Offset)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []models.Table
|
||||
for rows.Next() {
|
||||
var currentTable models.Table
|
||||
|
||||
err = rows.Scan(¤tTable.Id, ¤tTable.Name, ¤tTable.MaxPeople, ¤tTable.Room)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, currentTable)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func CreateTable(db *sqlx.DB, params CreateTableParams) (*models.Table, error) {
|
||||
query := `
|
||||
INSERT INTO Tables (name, max_people, room)
|
||||
VALUES (?, ?, ?)
|
||||
RETURNING id, name, max_people, room
|
||||
`
|
||||
|
||||
var table models.Table
|
||||
|
||||
err := db.QueryRow(query, params.Name, params.MaxPeople, params.Room).Scan(
|
||||
&table.Id,
|
||||
&table.Name,
|
||||
&table.MaxPeople,
|
||||
&table.Room,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("CreateTable: Insertion operation of the Tables object is failed: %v\n", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Println("CreateTable: Insertion operation of the Tables object is successful")
|
||||
return &table, nil
|
||||
}
|
||||
|
||||
func DeleteTableById(db *sqlx.DB, id int) (sql.Result, error) {
|
||||
sqlResult, err := db.Exec("DELETE FROM Tables WHERE id = ?", id)
|
||||
|
||||
if err == nil {
|
||||
log.Println("DeleteTableById: Deletion operation of the Tables object is successful")
|
||||
}
|
||||
|
||||
return sqlResult, err
|
||||
}
|
||||
|
||||
func UpdateTable(db *sqlx.DB, params UpdateTableParams) (*models.Table, error) {
|
||||
query := `
|
||||
UPDATE Tables
|
||||
SET name = $1, max_people = $2, room = $3
|
||||
WHERE id = $4
|
||||
RETURNING id, name, max_people, room
|
||||
`
|
||||
|
||||
result := &models.Table{}
|
||||
err := db.QueryRow(query, params.Name, params.MaxPeople, params.Room, params.Id).
|
||||
Scan(&result.Id, &result.Name, &result.MaxPeople, &result.Room)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, sql.ErrNoRows):
|
||||
log.Printf("No rows affected for Table ID %d", params.Id)
|
||||
return nil, errors.New("no rows affected: update failed")
|
||||
default:
|
||||
log.Printf("Query execution error for Table ID %d: %v", params.Id, err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Table ID %d updated successfully", result.Id)
|
||||
return result, nil
|
||||
}
|
||||
Executable
+213
@@ -0,0 +1,213 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/gorilla/mux"
|
||||
"go_project/internal/configuration"
|
||||
"go_project/internal/connection"
|
||||
"go_project/internal/controllers"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetBookingById(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("GetBookingById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
requestVars := mux.Vars(request)
|
||||
bookingIdStringValue := requestVars["id"]
|
||||
|
||||
id, err := strconv.Atoi(bookingIdStringValue)
|
||||
if err != nil {
|
||||
log.Println("Current id string value of the booking record to get: \"" + bookingIdStringValue + "\"")
|
||||
log.Println("Error parse id string value to int:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
booking, err := controllers.BookingById(sqlHandler, id)
|
||||
if err != nil {
|
||||
log.Println("Error getting booking by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
bookingMarshaled, err := json.Marshal(booking)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling booking to json string format:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(bookingMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing booking to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetAllBookings(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("GetAllBookings Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
limit, offset := configuration.GetRecordsLimit(), configuration.GetRecordsOffset()
|
||||
listBookingParams := controllers.ListBookingParams{Limit: limit, Offset: offset}
|
||||
|
||||
allBookings, err := controllers.AllBookings(sqlHandler, listBookingParams)
|
||||
if err != nil {
|
||||
log.Println("Error getting all bookings from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
allBookingsMarshaled, err := json.Marshal(allBookings)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling all bookings:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(allBookingsMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing all bookings to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func CreateBooking(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("CreateBooking Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
var createBookingParams controllers.CreateBookingParams
|
||||
err = json.NewDecoder(request.Body).Decode(&createBookingParams)
|
||||
if err != nil {
|
||||
log.Println("CreateBooking: Values of createBookingParams:", createBookingParams)
|
||||
log.Println("Error unmarshaling booking from json string format:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newBooking, err := controllers.CreateBooking(sqlHandler, createBookingParams)
|
||||
if err != nil {
|
||||
log.Println("Error creating booking:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
newBookingMarshaled, err := json.Marshal(newBooking)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling booking to json string format:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(newBookingMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing booking to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func UpdateBooking(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("UpdateBookingById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
var updateBookingParams controllers.UpdateBookingParams
|
||||
err = json.NewDecoder(request.Body).Decode(&updateBookingParams)
|
||||
if err != nil {
|
||||
log.Println("UpdateBooking: Values of updateBookingParams:", updateBookingParams)
|
||||
log.Println("Error unmarshaling booking from json string format:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newBooking, err := controllers.UpdateBooking(sqlHandler, updateBookingParams)
|
||||
if err != nil {
|
||||
log.Println("Error updating booking by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("SQL result: Updated booking record is:", newBooking)
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func DeleteBookingById(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("DeleteBookingById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != err {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
requestVars := mux.Vars(request)
|
||||
bookingIdStringValue := requestVars["id"]
|
||||
|
||||
id, err := strconv.Atoi(bookingIdStringValue)
|
||||
if err != nil {
|
||||
log.Println("Current id string value of the booking record to delete: \"" + bookingIdStringValue + "\"")
|
||||
log.Println("Error parse id string value to int:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
sqlResult, err := controllers.DeleteBookingById(sqlHandler, id)
|
||||
if err != nil {
|
||||
log.Println("Error deleting booking by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
rowsAffected, err := sqlResult.RowsAffected()
|
||||
if err != nil {
|
||||
log.Println("Error getting number of rows affected by an delete:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("SQL result: Number of rows affected by an delete:", rowsAffected)
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
Executable
+213
@@ -0,0 +1,213 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/gorilla/mux"
|
||||
"go_project/internal/configuration"
|
||||
"go_project/internal/connection"
|
||||
"go_project/internal/controllers"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetAllTables(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("GetAllTables Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
limit, offset := configuration.GetRecordsLimit(), configuration.GetRecordsOffset()
|
||||
listTableParams := controllers.ListTableParams{Limit: limit, Offset: offset}
|
||||
|
||||
allTables, err := controllers.AllTables(sqlHandler, listTableParams)
|
||||
if err != nil {
|
||||
log.Println("Error getting all tables from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
allTablesMarshaled, err := json.Marshal(allTables)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling all tables:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(allTablesMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing all tables to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTableById(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("GetTableById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
requestVars := mux.Vars(request)
|
||||
tableIdStringValue := requestVars["id"]
|
||||
|
||||
id, err := strconv.Atoi(tableIdStringValue)
|
||||
if err != nil {
|
||||
log.Println("Current id string value of the table record to get: \"" + tableIdStringValue + "\"")
|
||||
log.Println("Error parse id string value to int:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
table, err := controllers.TableById(sqlHandler, id)
|
||||
if err != nil {
|
||||
log.Println("Error getting table by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
tableMarshaled, err := json.Marshal(table)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling table to json string format:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(tableMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing table to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func CreateTable(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("CreateTable Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
var createTableParams controllers.CreateTableParams
|
||||
err = json.NewDecoder(request.Body).Decode(&createTableParams)
|
||||
if err != nil {
|
||||
log.Println("CreateTable: Values of createTableParams:", createTableParams)
|
||||
log.Println("Error unmarshaling table from json string format:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newTable, err := controllers.CreateTable(sqlHandler, createTableParams)
|
||||
if err != nil {
|
||||
log.Println("Error creating table:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
newTableMarshaled, err := json.Marshal(newTable)
|
||||
if err != nil {
|
||||
log.Println("Error marshaling table to json string format:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
_, err = response.Write(newTableMarshaled)
|
||||
if err != nil {
|
||||
log.Println("Error writing table to response:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func DeleteTableById(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("DeleteTableById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
requestVars := mux.Vars(request)
|
||||
tableIdStringValue := requestVars["id"]
|
||||
|
||||
id, err := strconv.Atoi(tableIdStringValue)
|
||||
if err != nil {
|
||||
log.Println("Current id string value of the table record to delete: \"" + tableIdStringValue + "\"")
|
||||
log.Println("Error parse id string value to int:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
sqlResult, err := controllers.DeleteTableById(sqlHandler, id)
|
||||
if err != nil {
|
||||
log.Println("Error deleting table by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
rowsAffected, err := sqlResult.RowsAffected()
|
||||
if err != nil {
|
||||
log.Println("Error getting number of rows affected by an delete:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("SQL result: Number of rows affected by an delete:", rowsAffected)
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func UpdateTable(response http.ResponseWriter, request *http.Request) {
|
||||
log.Println("UpdateTableById Serving:", request.URL.Path, "from", request.Host)
|
||||
|
||||
sqlHandler, err := connection.OpenDefault()
|
||||
if err != nil {
|
||||
log.Println("Error opening database connection:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer connection.MustClose(sqlHandler)
|
||||
|
||||
var updateTableParams controllers.UpdateTableParams
|
||||
err = json.NewDecoder(request.Body).Decode(&updateTableParams)
|
||||
if err != nil {
|
||||
log.Println("UpdateTable: Values of updateTableParams:", updateTableParams)
|
||||
log.Println("Error unmarshaling table from json string format:", err)
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newTable, err := controllers.UpdateTable(sqlHandler, updateTableParams)
|
||||
if err != nil {
|
||||
log.Println("Error updating table by id from database:", err)
|
||||
response.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("SQL result: Updated table record is:", newTable)
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
package models
|
||||
|
||||
type (
|
||||
Table struct {
|
||||
Id int64 `db:"id" json:"id"`
|
||||
Name int64 `db:"name" json:"name"`
|
||||
MaxPeople int64 `db:"max_people" json:"max_people"`
|
||||
Room string `db:"room" json:"room"`
|
||||
}
|
||||
|
||||
Booking struct {
|
||||
Id int64 `db:"id" json:"id"`
|
||||
IdTables int64 `db:"id_tables" json:"id_tables"`
|
||||
ReservationDatetime string `db:"reservation" json:"reservation"`
|
||||
TimeReserve string `db:"time_reserve" json:"time_reserve"`
|
||||
WhoBooked string `db:"who_booked" json:"who_booked"`
|
||||
}
|
||||
)
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"go_project/internal/handlers"
|
||||
"go_project/pkg/behaivor"
|
||||
"go_project/pkg/information"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func DefaultRouter() *mux.Router {
|
||||
router := mux.NewRouter()
|
||||
declareRoutes(router)
|
||||
http.Handle("/", router)
|
||||
|
||||
err := router.Walk(information.AboutRoute)
|
||||
behaivor.Anxiety("Error walking routes", err)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
var declareRoutes = func(router *mux.Router) {
|
||||
// End points for Table record
|
||||
router.HandleFunc("/tables", handlers.GetAllTables).Methods("GET")
|
||||
router.HandleFunc("/table/{id:[0-9]+}", handlers.GetTableById).Methods("GET")
|
||||
router.HandleFunc("/table", handlers.CreateTable).Methods("POST")
|
||||
router.HandleFunc("/table", handlers.UpdateTable).Methods("PUT")
|
||||
router.HandleFunc("/table/{id:[0-9]+}", handlers.DeleteTableById).Methods("DELETE")
|
||||
// End points for Booking record
|
||||
router.HandleFunc("/bookings", handlers.GetAllBookings).Methods("GET")
|
||||
router.HandleFunc("/booking/{id:[0-9]+}", handlers.GetBookingById).Methods("GET")
|
||||
router.HandleFunc("/booking", handlers.CreateBooking).Methods("POST")
|
||||
router.HandleFunc("/booking", handlers.UpdateBooking).Methods("PUT")
|
||||
router.HandleFunc("/booking/{id:[0-9]+}", handlers.DeleteBookingById).Methods("DELETE")
|
||||
}
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type schema struct {
|
||||
create string
|
||||
drop string
|
||||
}
|
||||
|
||||
func MustCreate(db *sqlx.DB) {
|
||||
db.MustExec(defaultSchema.create)
|
||||
}
|
||||
|
||||
func MustDrop(db *sqlx.DB) {
|
||||
db.MustExec(defaultSchema.drop)
|
||||
}
|
||||
|
||||
// Type time_reserve stores the reserve time reserve by time
|
||||
// Type TIME(0) has minimal accuracy, counts down by seconds
|
||||
// Type SMALLDATETIME has format'YYYYMMDD hh:mm', for example '20090212 12:30', counts down by minuts
|
||||
var defaultSchema = schema{
|
||||
create: `
|
||||
CREATE TABLE IF NOT EXISTS Tables (
|
||||
id INTEGER
|
||||
CONSTRAINT PK_Tables PRIMARY KEY AUTOINCREMENT,
|
||||
name INTEGER NOT NULL UNIQUE,
|
||||
max_people INTEGER NOT NULL,
|
||||
room TEXT NOT NULL,
|
||||
CONSTRAINT CHK_max_people CHECK (
|
||||
max_people > 0
|
||||
AND max_people < 11
|
||||
)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS Bookings (
|
||||
id INTEGER
|
||||
CONSTRAINT PK_Bookings PRIMARY KEY AUTOINCREMENT,
|
||||
id_tables INTEGER,
|
||||
reservation TEXT NOT NULL,
|
||||
time_reserve TEXT NOT NULL,
|
||||
who_booked TEXT NOT NULL,
|
||||
CONSTRAINT FK_Bookings_Tables FOREIGN KEY (id_tables) REFERENCES Tables (id),
|
||||
CONSTRAINT CHK_min_max_time_reserve CHECK (time_reserve BETWEEN "00:30" AND "12:00")
|
||||
);
|
||||
CREATE TRIGGER IF NOT EXISTS CHK_Bookings_Insert
|
||||
BEFORE INSERT ON Bookings
|
||||
BEGIN
|
||||
SELECT RAISE(
|
||||
FAIL,
|
||||
"Reservation of table is not possible due to the existing reservation"
|
||||
)
|
||||
FROM (
|
||||
SELECT
|
||||
datetime(NEW.reservation) AS new_res_dt,
|
||||
datetime(reservation) AS res_dt,
|
||||
datetime(reservation, time_reserve) AS reserved_until,
|
||||
id_tables
|
||||
FROM Bookings
|
||||
)
|
||||
WHERE
|
||||
(new_res_dt >= res_dt AND new_res_dt < reserved_until)
|
||||
AND id_tables = NEW.id_tables;
|
||||
END;
|
||||
`,
|
||||
}
|
||||
Reference in New Issue
Block a user