bill-server-go/internal/city/repository.go
2023-05-05 20:27:33 +08:00

159 lines
3.7 KiB
Go

package city
import (
"context"
"database/sql"
)
// Queries that we will use.
const (
QUERY_GET_CITIES = "SELECT c.id, c.name, c.created, c.modified, u.id, u.name, u.address, u.created, u.modified FROM cities AS c JOIN users AS u ON (c.user = u.id)"
QUERY_GET_CITY = "SELECT c.id, c.name, c.created, c.modified, u.id, u.name, u.address, u.created, u.modified FROM cities AS c JOIN users AS u ON (c.user = u.id) WHERE c.id = ?"
QUERY_CREATE_CITY = "INSERT INTO cities (name, created, modified, user) VALUES (?, ?, ?, ?)"
QUERY_UPDATE_CITY = "UPDATE cities SET name = ?, modified = ?, user = ? WHERE id = ?"
QUERY_DELETE_CITY = "DELETE FROM cities WHERE id = ?"
)
// Represents that we will use MariaDB in order to implement the methods.
type mariaDBRepository struct {
mariadb *sql.DB
}
// Create a new repository with MariaDB as the driver.
func NewCityRepository(mariaDBConnection *sql.DB) CityRepository {
return &mariaDBRepository{
mariadb: mariaDBConnection,
}
}
// Gets all cities in the database.
func (r *mariaDBRepository) GetCities(ctx context.Context) (*[]CityAndUser, error) {
// Initialize variables.
var cities []CityAndUser
// Fetches all cities.
res, err := r.mariadb.QueryContext(ctx, QUERY_GET_CITIES)
if err != nil {
return nil, err
}
defer res.Close()
// Scan all of the cities from the results.
for res.Next() {
city := &CityAndUser{}
err = res.Scan(
&city.ID,
&city.Name,
&city.Created,
&city.Modified,
&city.User.ID,
&city.User.Name,
&city.User.Address,
&city.User.Created,
&city.User.Modified,
)
if err != nil && err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
cities = append(cities, *city)
}
return &cities, nil
}
// Gets a single city in the database.
func (r *mariaDBRepository) GetCity(ctx context.Context, cityID int) (*CityAndUser, error) {
// Initialize variable.
city := &CityAndUser{}
// Prepare SQL to get one city.
stmt, err := r.mariadb.PrepareContext(ctx, QUERY_GET_CITY)
if err != nil {
return nil, err
}
defer stmt.Close()
// Get one city and insert it to the 'city' struct.
// If it's empty, return null.
err = stmt.QueryRowContext(ctx, cityID).Scan(
&city.ID,
&city.Name,
&city.Created,
&city.Modified,
&city.User.ID,
&city.User.Name,
&city.User.Address,
&city.User.Created,
&city.User.Modified,
)
if err != nil && err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
// Return result.
return city, nil
}
// Creates a single city in the database.
func (r *mariaDBRepository) CreateCity(ctx context.Context, city *City) error {
// Prepare context to be used.
stmt, err := r.mariadb.PrepareContext(ctx, QUERY_CREATE_CITY)
if err != nil {
return err
}
defer stmt.Close()
// Insert one city.
_, err = stmt.ExecContext(ctx, city.Name, city.Created, city.Modified, city.User)
if err != nil {
return err
}
// Return empty.
return nil
}
// Updates a single city in the database.
func (r *mariaDBRepository) UpdateCity(ctx context.Context, cityID int, city *City) error {
// Prepare context to be used.
stmt, err := r.mariadb.PrepareContext(ctx, QUERY_UPDATE_CITY)
if err != nil {
return err
}
defer stmt.Close()
// Update one city.
_, err = stmt.ExecContext(ctx, city.Name, city.Modified, city.User, cityID)
if err != nil {
return err
}
// Return empty.
return nil
}
// Deletes a single city in the database.
func (r *mariaDBRepository) DeleteCity(ctx context.Context, cityID int) error {
// Prepare context to be used.
stmt, err := r.mariadb.PrepareContext(ctx, QUERY_DELETE_CITY)
if err != nil {
return err
}
defer stmt.Close()
// Delete one city.
_, err = stmt.ExecContext(ctx, cityID)
if err != nil {
return err
}
// Return empty.
return nil
}