Skip to content
Snippets Groups Projects
Select Git revision
  • ca72ec3589a8e5de5e3add4ffd0088254547f957
  • master default protected
  • feature/PRXS-1869-SuperUser
  • fix/PRXS-3121-SaveFileInfo
  • feature/PRXS-3106-NoCache
  • feature/PRXS-3043-NewURLFormat
  • feature/2781-SpacesLoggingMiddleware
  • feature/PRXS-2974-FillImageDimensions
  • feature/PRXS-3143-3235-ReferenceOptions
  • feature/PRXS-3056-LocalesFromToMap
  • feature/PRXS-3421-ImplementNewRefAPI
  • feature/PRXS-3143-LimitReferenceFields
  • feature/PRXS-3234-FeaturePruneIdents
  • PRXS-3421-RecursiveReferences
  • 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
  • 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

client.go

Blame
  • service.go 6.05 KiB
    package items
    
    import (
    	"context"
    	"regexp"
    
    	"git.perx.ru/perxis/perxis-go/pkg/errors"
    	"git.perx.ru/perxis/perxis-go/pkg/filter"
    	"git.perx.ru/perxis/perxis-go/pkg/schema"
    	"git.perx.ru/perxis/perxis-go/pkg/schema/field"
    )
    
    // @microgen grpc
    // @protobuf git.perx.ru/perxis/perxis-go/proto/items
    // @grpc-addr content.items.Items
    type Items interface {
    	Create(ctx context.Context, item *Item, opts ...*CreateOptions) (created *Item, err error)
    	Introspect(ctx context.Context, item *Item, opts ...*IntrospectOptions) (itm *Item, sch *schema.Schema, err error)
    	Get(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*GetOptions) (item *Item, err error)
    	Find(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*FindOptions) (items []*Item, total int, err error)
    	Update(ctx context.Context, item *Item, options ...*UpdateOptions) (err error)
    
    	// Delete выполняет удаление элемента
    	// Если установлен флаг DeleteOptions.Erase то данные будут полностью удалены из системы.
    	// В противном случае выполняется "мягкое удаление", элемент помечается как удаленный и может быть восстановлен с помощью метода Items.Undelete и получен в Items.Get/Find
    	Delete(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*DeleteOptions) (err error)
    
    	// Undelete восстанавливает элементы после "мягкого удаление"
    	Undelete(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*UndeleteOptions) (err error)
    
    	Publish(ctx context.Context, item *Item, options ...*PublishOptions) (err error)
    	Unpublish(ctx context.Context, item *Item, options ...*UnpublishOptions) (err error)
    	GetPublished(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*GetPublishedOptions) (item *Item, err error)
    	FindPublished(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*FindPublishedOptions) (items []*Item, total int, err error)
    
    	GetRevision(ctx context.Context, spaceId, envId, collectionId, itemId, revisionId string, options ...*GetRevisionOptions) (item *Item, err error)
    	ListRevisions(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*ListRevisionsOptions) (items []*Item, err error)
    
    	Archive(ctx context.Context, item *Item, options ...*ArchiveOptions) (err error)
    	FindArchived(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*FindArchivedOptions) (items []*Item, total int, err error)
    	Unarchive(ctx context.Context, item *Item, options ...*UnarchiveOptions) (err error)
    
    	// Aggregate выполняет агрегацию данных
    	Aggregate(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*AggregateOptions) (result map[string]interface{}, err error)
    	// AggregatePublished выполняет агрегацию опубликованных данных
    	AggregatePublished(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*AggregatePublishedOptions) (result map[string]interface{}, err error)
    }
    
    // PreSaver - интерфейс, который может быть реализован полем, чтобы получать событие PreSave перед сохранением Item в Storage
    type PreSaver interface {
    	PreSave(ctx context.Context, f *field.Field, v interface{}, itemCtx *Context) (interface{}, bool, error)
    }
    
    type Filter struct {
    	ID     []string
    	Data   []*filter.Filter
    	Search string // Поиск, одновременно поддерживается только один запрос
    	Q      []string
    }
    
    func NewFilter(params ...interface{}) *Filter {
    	f := &Filter{}
    	for _, p := range params {
    		switch v := p.(type) {
    		case *filter.Filter:
    			f.Data = append(f.Data, v)
    		case string:
    			f.Q = append(f.Q, v)
    		}
    	}
    	return f
    }
    
    // AggregateExpRe - формат, которому должна соответствовать формула расчета данных
    var AggregateExpRe = regexp.MustCompile(`([a-zA-Z]+)\((.*)\)`)
    
    func ParseAggregateExp(exp string) (string, string, bool) {
    	ss := AggregateExpRe.FindAllStringSubmatch(exp, -1)
    	if len(ss) == 0 || len(ss[0]) < 2 {
    		return "", "", false
    	}
    	return ss[0][1], ss[0][2], true
    }
    
    func DecodeAggregateResult(ctx context.Context, request map[string]string, r map[string]interface{}, s *schema.Schema) (map[string]interface{}, error) {
    	result := make(map[string]interface{}, len(r))
    	for outputField, exp := range request {
    
    		funcName, fldName, ok := ParseAggregateExp(exp)
    		if !ok || fldName == "" {
    			if v, ok := r[outputField]; ok {
    				result[outputField] = v
    			}
    			continue
    		}
    
    		schemaFld := s.GetField(fldName)
    		if schemaFld == nil {
    			if v, ok := r[outputField]; ok {
    				result[outputField] = v
    			}
    			continue
    		}
    
    		if funcName == "distinct" {
    			schemaFld = field.Array(schemaFld)
    		}
    
    		data, err := schema.Decode(ctx, schemaFld, r[outputField])
    		if err != nil {
    			return nil, errors.Wrapf(err, "decode data for field '%s'", outputField)
    		}
    		result[outputField] = data
    	}
    
    	return result, nil
    }
    
    func EncodeAggregateResult(ctx context.Context, request map[string]string, r map[string]interface{}, s *schema.Schema) (map[string]interface{}, error) {
    	result := make(map[string]interface{}, len(r))
    	for outputField, exp := range request {
    
    		funcName, fldName, ok := ParseAggregateExp(exp)
    		if !ok || fldName == "" {
    			if v, ok := r[outputField]; ok {
    				result[outputField] = v
    			}
    			continue
    		}
    
    		schemaFld := s.GetField(fldName)
    		if schemaFld == nil {
    			if v, ok := r[outputField]; ok {
    				result[outputField] = v
    			}
    			continue
    		}
    
    		if funcName == "distinct" {
    			schemaFld = field.Array(schemaFld)
    		}
    
    		data, err := schema.Encode(ctx, schemaFld, r[outputField])
    		if err != nil {
    			return nil, errors.Wrapf(err, "decode data for field '%s'", outputField)
    		}
    		result[outputField] = data
    	}
    
    	return result, nil
    }