init push
This commit is contained in:
385
internal/repository/mysql/flight_repo.go
Normal file
385
internal/repository/mysql/flight_repo.go
Normal file
@@ -0,0 +1,385 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"wucher/internal/domain/flight"
|
||||
)
|
||||
|
||||
type FlightRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func preloadTakeoverRelations(q *gorm.DB) *gorm.DB {
|
||||
return q.
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.Base.OperationalShiftTimes").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople")
|
||||
}
|
||||
|
||||
func NewFlightRepository(db *gorm.DB) *FlightRepository {
|
||||
return &FlightRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *FlightRepository) Create(ctx context.Context, row *flight.Flight) error {
|
||||
return r.db.WithContext(ctx).Create(row).Error
|
||||
}
|
||||
|
||||
func (r *FlightRepository) GetLatestMissionCodeByPrefix(ctx context.Context, prefix string) (string, error) {
|
||||
var out struct {
|
||||
MissionCode string `gorm:"column:mission_code"`
|
||||
}
|
||||
err := r.db.WithContext(ctx).
|
||||
Table("flights").
|
||||
Select("mission_code").
|
||||
Where("mission_code LIKE ? AND deleted_at IS NULL", prefix+"%").
|
||||
Order("mission_code DESC").
|
||||
Limit(1).
|
||||
Scan(&out).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.MissionCode, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) Update(ctx context.Context, row *flight.Flight) error {
|
||||
return r.db.WithContext(ctx).Save(row).Error
|
||||
}
|
||||
|
||||
func (r *FlightRepository) Delete(ctx context.Context, id []byte, deletedBy []byte) error {
|
||||
now := time.Now().UTC()
|
||||
updates := map[string]any{
|
||||
"deleted_at": now,
|
||||
"deleted_by": deletedBy,
|
||||
"updated_by": deletedBy,
|
||||
}
|
||||
return r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Where("id = ? AND deleted_at IS NULL", id).
|
||||
Updates(updates).Error
|
||||
}
|
||||
|
||||
func (r *FlightRepository) GetByID(ctx context.Context, id []byte) (*flight.Flight, error) {
|
||||
var row flight.Flight
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.Base.OperationalShiftTimes").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Where("flights.id = ? AND flights.deleted_at IS NULL", id).
|
||||
First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return &row, err
|
||||
}
|
||||
|
||||
func (r *FlightRepository) ListByUserID(ctx context.Context, userID []byte, limit, offset int) ([]flight.Flight, int64, error) {
|
||||
rows := make([]flight.Flight, 0)
|
||||
var total int64
|
||||
|
||||
base := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Where("flights.deleted_at IS NULL").
|
||||
Where(
|
||||
`EXISTS (
|
||||
SELECT 1
|
||||
FROM duty_roster_crews c
|
||||
JOIN duty_rosters r ON r.id = c.roster_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.deleted_at IS NULL
|
||||
AND r.deleted_at IS NULL
|
||||
AND r.flight_id = flights.id
|
||||
)`,
|
||||
userID,
|
||||
)
|
||||
|
||||
if err := base.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
query := base.Order("flights.date DESC, flights.created_at DESC")
|
||||
if limit > 0 {
|
||||
query = query.Limit(limit).Offset(offset)
|
||||
}
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return rows, total, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) ListByCreatedBy(ctx context.Context, createdBy []byte, filter string, date string, sort string, limit, offset int) ([]flight.Flight, int64, error) {
|
||||
rows := make([]flight.Flight, 0)
|
||||
var total int64
|
||||
|
||||
base := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Where("flights.deleted_at IS NULL").
|
||||
Where("flights.created_by = ?", createdBy)
|
||||
if filter != "" {
|
||||
like := "%" + filter + "%"
|
||||
base = base.Where("flights.mission_code LIKE ?", like)
|
||||
}
|
||||
if date != "" {
|
||||
base = base.Where("flights.date = ?", date)
|
||||
}
|
||||
|
||||
if err := base.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
query := base
|
||||
if sort != "" {
|
||||
query = query.Order(sort)
|
||||
} else {
|
||||
query = query.Order("flights.date DESC, flights.created_at DESC")
|
||||
}
|
||||
if limit > 0 {
|
||||
query = query.Limit(limit).Offset(offset)
|
||||
}
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return rows, total, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) GetByReserveAcID(ctx context.Context, reserveAcID []byte) (*flight.Flight, error) {
|
||||
var row flight.Flight
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Joins("JOIN takeover_acs ta ON ta.id = flights.takeover_ac_id AND ta.deleted_at IS NULL").
|
||||
Where("ta.reserve_ac_id = ? AND flights.deleted_at IS NULL", reserveAcID).
|
||||
First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return &row, err
|
||||
}
|
||||
|
||||
func (r *FlightRepository) ListByReserveAcID(ctx context.Context, reserveAcID []byte) ([]flight.Flight, error) {
|
||||
rows := make([]flight.Flight, 0)
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Joins("JOIN takeover_acs ta ON ta.id = flights.takeover_ac_id AND ta.deleted_at IS NULL").
|
||||
Where("ta.reserve_ac_id = ? AND flights.deleted_at IS NULL", reserveAcID).
|
||||
Order("flights.created_at ASC, flights.id ASC").
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) GetByTakeoverAcID(ctx context.Context, takeoverAcID []byte) (*flight.Flight, error) {
|
||||
var row flight.Flight
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Where("flights.takeover_ac_id = ? AND flights.deleted_at IS NULL", takeoverAcID).
|
||||
First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return &row, err
|
||||
}
|
||||
|
||||
func (r *FlightRepository) ListByTakeoverAcIDs(ctx context.Context, takeoverAcIDs [][]byte) ([]flight.Flight, error) {
|
||||
if len(takeoverAcIDs) == 0 {
|
||||
return []flight.Flight{}, nil
|
||||
}
|
||||
rows := make([]flight.Flight, 0)
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightListSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Where("flights.takeover_ac_id IN ? AND flights.deleted_at IS NULL", takeoverAcIDs).
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) GetByDutyRosterID(ctx context.Context, dutyRosterID []byte) (*flight.Flight, error) {
|
||||
var row flight.Flight
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightListSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("JOIN duty_rosters dr ON dr.flight_id = flights.id AND dr.deleted_at IS NULL").
|
||||
Where("dr.id = ? AND flights.deleted_at IS NULL", dutyRosterID).
|
||||
First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return &row, err
|
||||
}
|
||||
|
||||
func (r *FlightRepository) ListByDutyRosterIDs(ctx context.Context, dutyRosterIDs [][]byte) ([]flight.Flight, error) {
|
||||
if len(dutyRosterIDs) == 0 {
|
||||
return []flight.Flight{}, nil
|
||||
}
|
||||
rows := make([]flight.Flight, 0)
|
||||
err := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightListSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Joins("JOIN duty_rosters dr ON dr.flight_id = flights.id AND dr.deleted_at IS NULL").
|
||||
Where("dr.id IN ? AND flights.deleted_at IS NULL", dutyRosterIDs).
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (r *FlightRepository) List(ctx context.Context, filter string, date string, sort string, limit, offset int) ([]flight.Flight, int64, error) {
|
||||
rows := make([]flight.Flight, 0)
|
||||
var total int64
|
||||
|
||||
base := r.db.WithContext(ctx).
|
||||
Model(&flight.Flight{}).
|
||||
Select(flightReadSelectSQL()).
|
||||
Preload("Takeover").
|
||||
Preload("Takeover.Base").
|
||||
Preload("Takeover.ReserveAc").
|
||||
Preload("Takeover.ReserveAc.Aircraft").
|
||||
Preload("Takeover.ReserveAc.Inspection").
|
||||
Preload("Takeover.RosterCrews").
|
||||
Preload("Takeover.OtherPeople").
|
||||
Joins("LEFT JOIN users cu ON cu.id = flights.created_by").
|
||||
Joins("LEFT JOIN users uu ON uu.id = flights.updated_by").
|
||||
Where("flights.deleted_at IS NULL")
|
||||
if filter != "" {
|
||||
like := "%" + filter + "%"
|
||||
base = base.Where("flights.mission_code LIKE ?", like)
|
||||
}
|
||||
if date != "" {
|
||||
base = base.Where("flights.date = ?", date)
|
||||
}
|
||||
|
||||
query := base
|
||||
if sort != "" {
|
||||
query = query.Order(sort)
|
||||
}
|
||||
if err := base.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if limit > 0 {
|
||||
query = query.Limit(limit).Offset(offset)
|
||||
}
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return rows, total, nil
|
||||
}
|
||||
|
||||
func flightListSelectSQL() string {
|
||||
// created_by_name / updated_by_name are resolved via correlated subqueries so the list
|
||||
// queries carry the auditor display names without needing extra user JOINs (the read
|
||||
// query joins users; the list variants don't). Keeps get-all in parity with get-by-id.
|
||||
return `flights.*,
|
||||
(SELECT dr.id FROM duty_rosters dr WHERE dr.flight_id = flights.id AND dr.deleted_at IS NULL LIMIT 1) AS duty_roster_id,
|
||||
(SELECT ta.reserve_ac_id FROM takeover_acs ta WHERE ta.id = flights.takeover_ac_id AND ta.deleted_at IS NULL LIMIT 1) AS reserve_ac_id,
|
||||
COALESCE((SELECT NULLIF(TRIM(CONCAT(COALESCE(cu.first_name, ''), ' ', COALESCE(cu.last_name, ''))), '')
|
||||
FROM users cu WHERE cu.id = flights.created_by), '') AS created_by_name,
|
||||
COALESCE((SELECT NULLIF(TRIM(CONCAT(COALESCE(uu.first_name, ''), ' ', COALESCE(uu.last_name, ''))), '')
|
||||
FROM users uu WHERE uu.id = flights.updated_by), '') AS updated_by_name`
|
||||
}
|
||||
|
||||
func flightReadSelectSQL() string {
|
||||
return `flights.*,
|
||||
(SELECT dr.id FROM duty_rosters dr WHERE dr.flight_id = flights.id AND dr.deleted_at IS NULL LIMIT 1) AS duty_roster_id,
|
||||
(SELECT ta.reserve_ac_id FROM takeover_acs ta WHERE ta.id = flights.takeover_ac_id AND ta.deleted_at IS NULL LIMIT 1) AS reserve_ac_id,
|
||||
COALESCE(
|
||||
NULLIF(TRIM(CONCAT(COALESCE(cu.first_name, ''), ' ', COALESCE(cu.last_name, ''))), ''),
|
||||
''
|
||||
) AS created_by_name,
|
||||
COALESCE(
|
||||
NULLIF(TRIM(CONCAT(COALESCE(uu.first_name, ''), ' ', COALESCE(uu.last_name, ''))), ''),
|
||||
''
|
||||
) AS updated_by_name`
|
||||
}
|
||||
Reference in New Issue
Block a user