package store import ( "git.gm6.ru/icewind/seadoc/models" "github.com/google/uuid" "gorm.io/gorm" ) type IDBManager interface { GetMaster() *gorm.DB GetReplica() *gorm.DB } // GormStorage реализует интерфейс VersionStorage через GORM type GormStorage struct { manager IDBManager } func NewGormStorage(manager IDBManager) *GormStorage { return &GormStorage{manager: manager} } func (s *GormStorage) CreateDocument(doc *models.Document) error { err := s.manager.GetMaster().Create(&doc).Error return err } func (s *GormStorage) GetDocument(id uuid.UUID) (*models.Document, error) { var d models.Document if err := s.manager.GetReplica().First(&d, "id = ?", id).Error; err != nil { return nil, err } return &d, nil } func (s *GormStorage) UpdateLatestVersion(docID, versionID uuid.UUID) error { return s.manager.GetMaster().Model(&models.Document{}). Where("id = ?", docID). Update("latest_version", versionID).Error } func (s *GormStorage) CreateVersion(v *models.Version) error { return s.manager.GetMaster().Create(v).Error } func (s *GormStorage) GetLatestVersion(docID uuid.UUID) (*models.Version, error) { var v models.Version err := s.manager.GetReplica(). Where("document_id = ?", docID). Order("created_at desc"). First(&v).Error if err == gorm.ErrRecordNotFound { return nil, nil } return &v, err } func (s *GormStorage) GetVersionByID(id uuid.UUID) (*models.Version, error) { var v models.Version if err := s.manager.GetReplica().First(&v, "id = ?", id).Error; err != nil { return nil, err } return &v, nil } func (s *GormStorage) GetParentVersion(v *models.Version) (*models.Version, error) { if v.ParentID == nil { return nil, nil } var parent models.Version if err := s.manager.GetReplica().First(&parent, "id = ?", v.ParentID).Error; err != nil { return nil, err } return &parent, nil } // CountSinceLastSnapshot возвращает количество версий (включая текущую) // с момента последнего snapshot func (s *GormStorage) CountSinceLastSnapshot(docID uuid.UUID) (int, error) { // Получаем последнюю версию v, err := s.GetLatestVersion(docID) if err != nil { return 0, err } if v == nil { return 0, nil } count := 0 for v != nil { count++ // Если это снапшот, считать больше не нужно if v.IsSnapshot { break } // Переходим к родителю if v.ParentID == nil { break } v, err = s.GetVersionByID(*v.ParentID) if err != nil { return count, err } } return count, nil }