Skip to content
Snippets Groups Projects
Select Git revision
  • 3d2d5439d6baaf57722abb239e3836c79c54f483
  • master default protected
  • feature/PRXS-3383-CollectionsRankSortAPI
  • fix/PRXS-3401-ValidateValidationOpts
  • feature/3149-LocaleCodeAsID-Feature
  • feature/PRXS-3383-CollectionsSort
  • feature/3109-SerializeFeature
  • release/0.33
  • feature/3109-RecoverySchema
  • feature/3109-feature
  • fix/PRXS-3369-ValidateFields
  • refactor/PRXS-3306-MovePkgGroup1
  • refactor/6-pkg-refactor-expr
  • fix/PRXS-3360-TemplateBuilderPatch
  • feature/3293-MongoV2
  • feature/3272-GoVersionUp
  • feature/PRXS-3218-HideTemplateActions
  • feature/PRXS-3234-PruneIdents
  • feature/3146-UpdateItemStorageInterface
  • feature/3274-ObjectIndexesFixes
  • feature/PRXS-3143-3235-ReferenceOptions
  • v0.33.1
  • v0.32.0
  • v0.31.1
  • v0.31.0
  • v0.30.0
  • v0.29.0
  • v0.28.0
  • v0.27.0-alpha.1+16
  • v0.27.0-alpha.1+15
  • v0.27.0-alpha.1+14
  • v0.27.0-alpha.1+13
  • v0.27.0-alpha.1+12
  • v0.27.0-alpha.1+11
  • v0.27.0-alpha.1+10
  • v0.27.0-alpha.1+9
  • v0.27.0-alpha.1+8
  • v0.27.0-alpha.1+7
  • v0.27.0-alpha.1+6
  • v0.27.0-alpha.1+5
  • v0.27.0-alpha.1+4
41 results

collection.go

Blame
  • collection.go 6.40 KiB
    package setup
    
    import (
    	"context"
    	"reflect"
    	"strings"
    
    	"git.perx.ru/perxis/perxis-go/pkg/collections"
    	"git.perx.ru/perxis/perxis-go/pkg/environments"
    	"git.perx.ru/perxis/perxis-go/pkg/errors"
    	"go.uber.org/zap"
    )
    
    var (
    	ErrCheckCollections     = errors.New("collections check error")
    	ErrInstallCollections   = errors.New("failed to install collections")
    	ErrUninstallCollections = errors.New("failed to uninstall collections")
    )
    
    type CollectionsOption func(c *CollectionConfig)
    type UpdateCollectionFn func(s *Setup, exist, new *collections.Collection) (coll *collections.Collection, upd bool, setSchema bool)
    type DeleteCollectionFn func(s *Setup, col *collections.Collection) bool
    
    type CollectionConfig struct {
    	collection *collections.Collection
    	UpdateFn   UpdateCollectionFn
    	DeleteFn   DeleteCollectionFn
    }
    
    func NewCollectionConfig(collection *collections.Collection, opt ...CollectionsOption) CollectionConfig {
    	c := CollectionConfig{collection: collection}
    
    	UpdateExistingCollection()(&c)
    	DeleteCollectionIfRemove()(&c)
    
    	for _, o := range opt {
    		o(&c)
    	}
    
    	return c
    }
    
    func OverwriteCollection() CollectionsOption {
    	return func(c *CollectionConfig) {
    		c.UpdateFn = func(s *Setup, old, new *collections.Collection) (*collections.Collection, bool, bool) {
    			return new, true, true
    		}
    	}
    }
    
    func KeepExistingCollection() CollectionsOption {
    	return func(c *CollectionConfig) {
    		c.UpdateFn = func(s *Setup, old, new *collections.Collection) (*collections.Collection, bool, bool) {
    			return old, false, false
    		}
    	}
    }
    
    func DeleteCollection() CollectionsOption {
    	return func(c *CollectionConfig) {
    		c.DeleteFn = func(s *Setup, collection *collections.Collection) bool { return true }
    	}
    }
    
    func DeleteCollectionIfRemove() CollectionsOption {
    	return func(c *CollectionConfig) {
    		c.DeleteFn = func(s *Setup, collection *collections.Collection) bool { return s.IsRemove() }
    	}
    }
    
    func UpdateExistingCollection() CollectionsOption {
    	return func(c *CollectionConfig) {
    		c.UpdateFn = func(s *Setup, exist, collection *collections.Collection) (*collections.Collection, bool, bool) {
    			if len(exist.Tags) > 0 {
    				collection.Tags = append(exist.Tags, collection.Tags...)
    			}
    
    			return collection, true, !collection.IsView() && !reflect.DeepEqual(exist.Schema, collection.Schema)
    		}
    	}
    }
    
    func (s *Setup) InstallCollections(ctx context.Context) (err error) {
    	if len(s.Collections) == 0 {
    		return nil
    	}
    
    	s.logger.Debug("Install collections", zap.Int("Collections", len(s.Collections)))
    
    	var migrate, setSchema bool
    
    	for _, c := range s.Collections {
    		setSchema, err = s.InstallCollection(ctx, c)
    		if err != nil {
    			s.logger.Error("Failed to install collection",
    				zap.String("Collection ID", c.collection.ID),
    				zap.String("Collection Name", c.collection.Name),
    				zap.Error(err),
    			)
    			return errors.WithDetailf(errors.Wrap(err, "failed to install collection"), "Возникла ошибка при настройке коллекции %s(%s)", c.collection.Name, c.collection.ID)
    		}
    		if setSchema {
    			migrate = true
    		}
    	}
    
    	if migrate {
    		if err = s.content.Environments.Migrate(ctx, s.SpaceID, s.EnvironmentID, &environments.MigrateOptions{Wait: true}); err != nil {
    			s.logger.Error(
    				"Failed to migrate environment",
    				zap.String("Space ID", s.SpaceID),
    				zap.String("Environment ID", s.EnvironmentID),
    				zap.Error(err),
    			)
    
    			return errors.Wrap(errors.WithDetail(err, "Возникла ошибка при миграции коллекций"), "migrate environment")
    		}
    	}
    
    	return nil
    }
    
    func (s *Setup) InstallCollection(ctx context.Context, c CollectionConfig) (setSchema bool, err error) {
    	collection := c.collection
    	collection.SpaceID, collection.EnvID = s.SpaceID, s.EnvironmentID
    
    	var exist *collections.Collection
    	// isForce - не удалять коллекцию, если она уже существует
    	exist, err = s.content.Collections.Get(ctx, collection.SpaceID, collection.EnvID, collection.ID)
    	if err != nil && !strings.Contains(err.Error(), collections.ErrNotFound.Error()) {
    		return false, err
    	}
    
    	if exist == nil {
    		setSchema = !collection.IsView()
    		exist, err = s.content.Collections.Create(ctx, collection)
    		if err != nil {
    			return false, err
    		}
    	} else {
    		var upd bool
    		collection, upd, setSchema = c.UpdateFn(s, exist, c.collection)
    		if upd {
    			if err = s.content.Collections.Update(ctx, collection); err != nil {
    				return false, err
    			}
    		}
    	}
    
    	if setSchema {
    		err = s.content.Collections.SetSchema(ctx, collection.SpaceID, collection.EnvID, collection.ID, collection.Schema)
    		if err != nil {
    			return false, err
    		}
    	}
    
    	return setSchema, nil
    }
    
    func (s *Setup) CheckCollections(ctx context.Context) error {
    	if len(s.Collections) == 0 {
    		return nil
    	}
    
    	s.logger.Debug("Check collections", zap.Int("Collections", len(s.Collections)))
    
    	var errs []error
    	for _, c := range s.Collections {
    		if err := s.CheckCollection(ctx, c); err != nil {
    			errs = append(errs, errors.WithDetailf(err, "Не найдена коллекция %s(%s)", c.collection.ID, c.collection.Name))
    		}
    	}
    
    	if len(errs) > 0 {
    		return errors.WithErrors(ErrCheckCollections, errs...)
    	}
    
    	return nil
    }
    
    func (s *Setup) CheckCollection(ctx context.Context, c CollectionConfig) (err error) {
    	_, err = s.content.Collections.Get(ctx, s.SpaceID, s.EnvironmentID, c.collection.ID)
    	return err
    }
    
    func (s *Setup) UninstallCollections(ctx context.Context) error {
    	if len(s.Collections) == 0 {
    		return nil
    	}
    
    	s.logger.Debug("Uninstall collections", zap.Int("Collections", len(s.Collections)))
    
    	for _, c := range s.Collections {
    		if err := s.UninstallCollection(ctx, c); err != nil {
    			s.logger.Error("Failed to uninstall collection",
    				zap.String("Collection ID", c.collection.ID),
    				zap.String("Collection Name", c.collection.Name),
    				zap.Error(err),
    			)
    			return errors.WithDetailf(errors.Wrap(err, "failed to uninstall collection"), "Возникла ошибка при удалении коллекции %s(%s)", c.collection.Name, c.collection.ID)
    		}
    	}
    
    	return nil
    }
    
    func (s *Setup) UninstallCollection(ctx context.Context, c CollectionConfig) error {
    	if c.DeleteFn(s, c.collection) {
    		if err := s.content.Collections.Delete(ctx, s.SpaceID, s.EnvironmentID, c.collection.ID); err != nil && !strings.Contains(err.Error(), collections.ErrNotFound.Error()) {
    			return err
    		}
    		s.removeItems(c.collection.ID) // после удаления коллекции нет смысла удалять ее элементы
    	}
    	return nil
    }