From ded279a489631651943b5b65cdb3acb6764cf288 Mon Sep 17 00:00:00 2001 From: leshe4ka46 Date: Tue, 28 Oct 2025 13:42:55 +0300 Subject: unmarshal all formats, merge them in the single table, users are truly unique --- pkg/store/db.go | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) (limited to 'pkg/store') diff --git a/pkg/store/db.go b/pkg/store/db.go index 6853563..38bdbaa 100644 --- a/pkg/store/db.go +++ b/pkg/store/db.go @@ -20,8 +20,8 @@ type Store struct { func NewStore(dsn string) (*Store, error) { db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ - SkipDefaultTransaction: true, // you can wrap outside for big imports - PrepareStmt: true, // statement cache + SkipDefaultTransaction: true, + PrepareStmt: true, DisableNestedTransaction: true, Logger: logger.Default.LogMode(logger.Silent), }) @@ -35,8 +35,6 @@ func (s *Store) AutoMigrate() error { return s.DB.AutoMigrate(&model.User{}, &model.Card{}, &model.Flight{}) } -/* ============================= Users ============================= */ - func (s *Store) SaveUser(ctx context.Context, in *model.User) (*model.User, error) { if in == nil { return nil, errors.New("nil user") @@ -52,7 +50,7 @@ func (s *Store) SaveUser(ctx context.Context, in *model.User) (*model.User, erro out := &model.User{} err := s.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - // 1) Try by Nick + // try by Nick if in.Nick != "" { if err := tx.Where("nick = ?", in.Nick).First(out).Error; err == nil { return nil @@ -60,7 +58,7 @@ func (s *Store) SaveUser(ctx context.Context, in *model.User) (*model.User, erro return err } } - // 2) Fallback by identity tuple + // fallback by identity tuple q := tx.Where("name = ? AND surname = ?", in.Name, in.Surname) if in.Fathersname != "" { q = q.Where("fathersname = ?", in.Fathersname) @@ -76,7 +74,7 @@ func (s *Store) SaveUser(ctx context.Context, in *model.User) (*model.User, erro return err } - // 3) Not found → create + // create if err := tx.Create(in).Error; err != nil { return err } @@ -86,9 +84,6 @@ func (s *Store) SaveUser(ctx context.Context, in *model.User) (*model.User, erro return out, err } -/* ============================= Cards ============================= */ -/* Card→User is a plain FK (cards.user_id). Keep it. */ - func (s *Store) SaveCard(ctx context.Context, in *model.Card) (*model.Card, error) { if in == nil { return nil, errors.New("nil card") @@ -104,14 +99,14 @@ func (s *Store) SaveCard(ctx context.Context, in *model.Card) (*model.Card, erro // find by unique triple if err := tx.Where("prefix = ? AND number = ? AND bonusprogramm = ?", in.Prefix, in.Number, in.Bonusprogramm).First(out).Error; err == nil { - // Link to user once if requested and not yet linked + // link to user once if requested and not yet linked if in.UserID != 0 && out.UserID == 0 { if err := tx.Model(out).Update("user_id", in.UserID).Error; err != nil { return err } out.UserID = in.UserID } - // refuse stealing if different user already set + // refuse stealing if in.UserID != 0 && out.UserID != 0 && out.UserID != in.UserID { return errors.New("card already linked to another user") } @@ -120,7 +115,7 @@ func (s *Store) SaveCard(ctx context.Context, in *model.Card) (*model.Card, erro return err } - // not found → create (includes FK if provided) + // not found → create if err := tx.Create(in).Error; err != nil { return err } @@ -130,15 +125,6 @@ func (s *Store) SaveCard(ctx context.Context, in *model.Card) (*model.Card, erro return out, err } -/* ============================= Flights ============================= */ -/* - Find/create by (number, from, to, date). Do NOT write user_id/card_id columns. - Use associations to link: - - flight.Users ↔ user_flights - - flight.Cards ↔ card_flights - This avoids “raw IDs” on the flight row and uses the relations instead. -*/ - func (s *Store) SaveFlight(ctx context.Context, in *model.Flight) (*model.Flight, error) { if in == nil { return nil, errors.New("nil flight") @@ -147,12 +133,12 @@ func (s *Store) SaveFlight(ctx context.Context, in *model.Flight) (*model.Flight out := &model.Flight{} err := s.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - // Try to find existing + // try to find existing if err := tx.Where(`"number" = ? AND "from" = ? AND "to" = ? AND "date" = ?`, in.Number, in.From, in.To, in.Date).First(out).Error; err == nil { - // found: do NOT update columns; only link relations below + // found } else if errors.Is(err, gorm.ErrRecordNotFound) { - // Not found → create (no user_id/card_id columns are written) + // not found → create cre := model.Flight{ Number: in.Number, From: in.From, @@ -162,7 +148,7 @@ func (s *Store) SaveFlight(ctx context.Context, in *model.Flight) (*model.Flight if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&cre).Error; err != nil { return err } - // If conflict, fetch the existing one + // on conflict, fetch the existing one if cre.ID == 0 { if err := tx.Where(`"number" = ? AND "from" = ? AND "to" = ? AND "date" = ?`, in.Number, in.From, in.To, in.Date).First(&cre).Error; err != nil { @@ -174,16 +160,14 @@ func (s *Store) SaveFlight(ctx context.Context, in *model.Flight) (*model.Flight return err } - // ---- Link relations via associations (no raw IDs in the row) ---- - // Link to User (many-to-many) if caller provided a UserID + // many-to-many user-flight if in.UserID != 0 { u := model.User{ID: in.UserID} - // Avoid dup join rows by adding a unique index on (user_id, flight_id). if err := tx.Model(out).Association("Users").Append(&u); err != nil { return err } } - // Link to Card (many-to-many) + // many-to-many flight-card if in.CardID != 0 { c := model.Card{ID: in.CardID} if err := tx.Model(out).Association("Cards").Append(&c); err != nil { -- cgit v1.2.3