Select Git revision
options.go 20.36 KiB
package items
import (
"maps"
"slices"
"git.perx.ru/perxis/perxis-go/pkg/options"
pb "git.perx.ru/perxis/perxis-go/proto/items"
)
type Options struct {
Env map[string]interface{}
Filter []string
PermissionsFilter []string
}
func MergeOptions(opts ...Options) Options {
o := Options{
Env: make(map[string]interface{}),
Filter: make([]string, 0),
}
for _, opt := range opts {
for k, v := range opt.Env {
o.Env[k] = v
}
o.Filter = append(o.Filter, opt.Filter...)
o.PermissionsFilter = append(o.PermissionsFilter, opt.PermissionsFilter...)
}
return o
}
type CreateOptions struct {
Options
UpdateAttrs bool
}
func MergeCreateOptions(opts ...*CreateOptions) *CreateOptions {
o := &CreateOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
func CreateOptionsToProto(opts ...*CreateOptions) *pb.CreateOptions {
if opts == nil {
return nil
}
o := MergeCreateOptions(opts...)
return &pb.CreateOptions{
UpdateAttrs: o.UpdateAttrs,
}
}
func CreateOptionsFromProto(opts *pb.CreateOptions) *CreateOptions {
if opts == nil {
return nil
}
return &CreateOptions{
UpdateAttrs: opts.UpdateAttrs,
}
}
type IntrospectOptions struct {
Options
}
func MergeIntrospectOptions(opts ...*IntrospectOptions) *IntrospectOptions {
o := &IntrospectOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type GetOptions struct {
Options
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func MergeGetOptions(opts ...*GetOptions) *GetOptions {
o := &GetOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func GetOptionsToProto(opts ...*GetOptions) *pb.GetOptions {
if opts == nil {
return nil
}
o := MergeGetOptions(opts...)
return &pb.GetOptions{
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
}
}
func GetOptionsFromProto(opts *pb.GetOptions) *GetOptions {
if opts == nil {
return nil
}
return &GetOptions{
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
}
type FindOptions struct {
Options
options.FindOptions
Deleted bool
Regular bool
Hidden bool
Templates bool
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func NewFindOptions(opts ...interface{}) *FindOptions {
fo := &FindOptions{}
fo.FindOptions = *options.MergeFindOptions(opts...)
return fo
}
func MergeFindOptions(opts ...*FindOptions) *FindOptions {
o := NewFindOptions()
for _, opt := range opts {
if opt == nil {
continue
}
o.Regular = o.Regular || opt.Regular
o.Templates = o.Templates || opt.Templates
o.Hidden = o.Hidden || opt.Hidden
o.Deleted = o.Deleted || opt.Deleted
o.Options = MergeOptions(o.Options, opt.Options)
o.FindOptions = *options.MergeFindOptions(&o.FindOptions, &opt.FindOptions)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func FindOptionsToProto(opts ...*FindOptions) *pb.FindOptions {
if opts == nil {
return nil
}
o := MergeFindOptions(opts...)
return &pb.FindOptions{
Deleted: o.Deleted,
Regular: o.Regular,
Hidden: o.Hidden,
Templates: o.Templates,
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
Options: options.FindOptionsToPB(&o.FindOptions),
}
}
func FindOptionsFromProto(opts *pb.FindOptions) *FindOptions {
if opts == nil {
return nil
}
o := &FindOptions{
Deleted: opts.Deleted,
Regular: opts.Regular,
Hidden: opts.Hidden,
Templates: opts.Templates,
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
if fo := options.FindOptionsFromPB(opts.Options); fo != nil {
o.FindOptions = *fo
}
return o
}
type UpdateOptions struct {
Options
UpdateAttrs bool
}
func MergeUpdateOptions(opts ...*UpdateOptions) *UpdateOptions {
o := &UpdateOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
func UpdateOptionsToProto(opts ...*UpdateOptions) *pb.UpdateOptions {
if opts == nil {
return nil
}
o := MergeUpdateOptions(opts...)
return &pb.UpdateOptions{
UpdateAttrs: o.UpdateAttrs,
}
}
func UpdateOptionsFromProto(opts *pb.UpdateOptions) *UpdateOptions {
if opts == nil {
return nil
}
return &UpdateOptions{
UpdateAttrs: opts.UpdateAttrs,
}
}
type DeleteOptions struct {
Options
UpdateAttrs bool
Erase bool
}
func MergeDeleteOptions(options ...*DeleteOptions) *DeleteOptions {
o := &DeleteOptions{}
for _, opt := range options {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
if opt.Erase {
o.Erase = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
func DeleteOptionsToProto(opts ...*DeleteOptions) *pb.DeleteOptions {
if opts == nil {
return nil
}
o := MergeDeleteOptions(opts...)
return &pb.DeleteOptions{
UpdateAttrs: o.UpdateAttrs,
Erase: o.Erase,
}
}
func DeleteOptionsFromProto(opts *pb.DeleteOptions) *DeleteOptions {
if opts == nil {
return nil
}
return &DeleteOptions{
UpdateAttrs: opts.UpdateAttrs,
Erase: opts.Erase,
}
}
type SoftDeleteOptions struct {
Options
}
func MergeSoftDeleteOptions(opts ...*SoftDeleteOptions) *SoftDeleteOptions {
o := &SoftDeleteOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type UndeleteOptions struct {
Options
UpdateAttrs bool
}
func MergeUndeleteOptions(opts ...*UndeleteOptions) *UndeleteOptions {
o := &UndeleteOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type PublishOptions struct {
Options
UpdateAttrs bool
}
func MergePublishOptions(opts ...*PublishOptions) *PublishOptions {
o := &PublishOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type UnpublishOptions struct {
UpdateAttrs bool
Options
}
func MergeUnpublishOptions(opts ...*UnpublishOptions) *UnpublishOptions {
o := &UnpublishOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
if opt.UpdateAttrs {
o.UpdateAttrs = true
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type GetPublishedOptions struct {
Options
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func (opts *GetPublishedOptions) ToGetOptions() *GetOptions {
return &GetOptions{
Options: MergeOptions(opts.Options),
LocaleID: opts.LocaleID,
TranslationsIDs: slices.Clone(opts.TranslationsIDs),
}
}
func NewGetPublishedOptions(oo ...interface{}) *GetPublishedOptions {
fo := &GetPublishedOptions{}
for _, o := range oo {
switch o := o.(type) {
case string:
fo.LocaleID = o
case []string:
fo.TranslationsIDs = o
}
}
return fo
}
func MergeGetPublishedOptions(opts ...*GetPublishedOptions) *GetPublishedOptions {
o := &GetPublishedOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func GetPublishedOptionsToProto(opts ...*GetPublishedOptions) *pb.GetPublishedOptions {
if opts == nil {
return nil
}
o := MergeGetPublishedOptions(opts...)
return &pb.GetPublishedOptions{
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
}
}
func GetPublishedOptionsFromProto(opts *pb.GetPublishedOptions) *GetPublishedOptions {
if opts == nil {
return nil
}
return &GetPublishedOptions{
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
}
type FindPublishedOptions struct {
Options
options.FindOptions
Deleted bool
Regular bool
Hidden bool
Templates bool
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func (opts *FindPublishedOptions) ToFindOptions() *FindOptions {
return &FindOptions{
Options: MergeOptions(opts.Options),
FindOptions: *options.MergeFindOptions(opts.FindOptions),
Deleted: opts.Deleted,
Regular: opts.Regular,
Hidden: opts.Hidden,
Templates: opts.Templates,
LocaleID: opts.LocaleID,
TranslationsIDs: slices.Clone(opts.TranslationsIDs),
}
}
func NewFindPublishedOptions(opts ...interface{}) *FindPublishedOptions {
fo := &FindPublishedOptions{}
for _, o := range opts {
switch o := o.(type) {
case string:
fo.LocaleID = o
}
}
fo.FindOptions = *options.MergeFindOptions(opts...)
return fo
}
func MergeFindPublishedOptions(opts ...*FindPublishedOptions) *FindPublishedOptions {
o := NewFindPublishedOptions()
for _, opt := range opts {
if opt == nil {
continue
}
o.Regular = o.Regular || opt.Regular
o.Templates = o.Templates || opt.Templates
o.Hidden = o.Hidden || opt.Hidden
o.Options = MergeOptions(o.Options, opt.Options)
o.FindOptions = *options.MergeFindOptions(&o.FindOptions, &opt.FindOptions)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func FindPublishedOptionsToProto(opts ...*FindPublishedOptions) *pb.FindPublishedOptions {
if opts == nil {
return nil
}
o := MergeFindPublishedOptions(opts...)
return &pb.FindPublishedOptions{
Regular: o.Regular,
Hidden: o.Hidden,
Templates: o.Templates,
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
Options: options.FindOptionsToPB(&o.FindOptions),
}
}
func FindPublishedOptionsFromProto(opts *pb.FindPublishedOptions) *FindPublishedOptions {
if opts == nil {
return nil
}
o := &FindPublishedOptions{
Regular: opts.Regular,
Hidden: opts.Hidden,
Templates: opts.Templates,
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
if fo := options.FindOptionsFromPB(opts.Options); fo != nil {
o.FindOptions = *fo
}
return o
}
type GetRevisionOptions struct {
Options
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func MergeGetRevisionOptions(opts ...*GetRevisionOptions) *GetRevisionOptions {
o := &GetRevisionOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func GetRevisionOptionsToProto(opts ...*GetRevisionOptions) *pb.GetRevisionOptions {
if opts == nil {
return nil
}
o := MergeGetRevisionOptions(opts...)
return &pb.GetRevisionOptions{
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
}
}
func GetRevisionOptionsFromProto(opts *pb.GetRevisionOptions) *GetRevisionOptions {
if opts == nil {
return nil
}
o := &GetRevisionOptions{
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
return o
}
type ListRevisionsOptions struct {
Options
options.FindOptions
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func MergeListRevisionsOptions(opts ...*ListRevisionsOptions) *ListRevisionsOptions {
o := &ListRevisionsOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
o.FindOptions = *options.MergeFindOptions(&o.FindOptions, &opt.FindOptions)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func ListRevisionsOptionsToProto(opts ...*ListRevisionsOptions) *pb.ListRevisionsOptions {
if opts == nil {
return nil
}
o := MergeListRevisionsOptions(opts...)
return &pb.ListRevisionsOptions{
Offset: int32(o.Offset),
Limit: int32(o.Limit),
Fields: o.Fields,
ExcludeFields: o.ExcludeFields,
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
}
}
func ListRevisionsOptionsFromProto(opts *pb.ListRevisionsOptions) *ListRevisionsOptions {
if opts == nil {
return nil
}
fo := options.New(int(opts.Offset), int(opts.Limit))
fo.FieldOptions = options.FieldOptions{
Fields: opts.Fields,
ExcludeFields: opts.ExcludeFields,
}
return &ListRevisionsOptions{
FindOptions: *fo,
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
}
type ArchiveOptions struct {
Options
}
func MergeArchiveOptions(opts ...*ArchiveOptions) *ArchiveOptions {
o := &ArchiveOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type FindArchivedOptions struct {
Options
options.FindOptions
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func NewFindArchivedOptions(oo ...interface{}) *FindArchivedOptions {
fo := &FindArchivedOptions{}
fo.FindOptions = *options.MergeFindOptions(oo...)
return fo
}
func MergeFindArchivedOptions(opts ...*FindArchivedOptions) *FindArchivedOptions {
o := NewFindArchivedOptions()
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
o.FindOptions = *options.MergeFindOptions(o.FindOptions, opt.FindOptions)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func FindArchivedOptionsToProto(opts ...*FindArchivedOptions) *pb.FindArchivedOptions {
if opts == nil {
return nil
}
o := MergeFindArchivedOptions(opts...)
return &pb.FindArchivedOptions{
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
Options: options.FindOptionsToPB(&o.FindOptions),
}
}
func FindArchivedOptionsFromProto(opts *pb.FindArchivedOptions) *FindArchivedOptions {
if opts == nil {
return nil
}
o := &FindArchivedOptions{
LocaleID: opts.LocaleId,
TranslationsIDs: opts.TranslationsIds,
}
if fo := options.FindOptionsFromPB(opts.Options); fo != nil {
o.FindOptions = *fo
}
return o
}
type GetArchivedOptions struct {
Options
// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
LocaleID string
// Список идентификаторов переводов/локалей, которых должны быть включены в результат
TranslationsIDs []string
}
func MergeGetArchivedOptions(opts ...*GetArchivedOptions) *GetArchivedOptions {
o := &GetArchivedOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
if opt.LocaleID != "" {
o.LocaleID = opt.LocaleID
}
o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
}
return o
}
func GetArchivedOptionsToProto(opts ...*GetArchivedOptions) *pb.GetArchivedOptions {
if opts == nil {
return nil
}
o := MergeGetArchivedOptions(opts...)
return &pb.GetArchivedOptions{
LocaleId: o.LocaleID,
TranslationsIds: o.TranslationsIDs,
}
}
func GetArchivedOptionsFromProto(opts *pb.GetArchivedOptions) *GetArchivedOptions {
if opts == nil {
return nil
}
o := &GetArchivedOptions{
LocaleID: opts.GetLocaleId(),
TranslationsIDs: opts.GetTranslationsIds(),
}
return o
}
type UnarchiveOptions struct {
Options
}
func MergeUnarchiveOptions(opts ...*UnarchiveOptions) *UnarchiveOptions {
o := &UnarchiveOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
}
return o
}
type AggregateOptions struct {
Options
options.SortOptions
// Fields поля которые должны быть возвращены или вычислены в результате.
// Ключ (string) - имя поля под которым будет добавляться результат.
// Значение (string) - является выражением, вычисление которого сформирует результат
// Функции для выражений (для поля F, типа T):
// - distinct(F) - все значения поля, тип результат []T
// - min(F) - минимальное значение поля, тип результат T
// - max(F) - максимальное значение поля, тип результат T
// - avg(F) - среднее значения поля, тип результат T
// - sum(F) - сумма значений поля, тип результат T
// - count() - число записей, тип результат int
Fields map[string]string
}
func MergeAggregateOptions(opts ...*AggregateOptions) *AggregateOptions {
o := &AggregateOptions{}
for _, opt := range opts {
if opt == nil {
continue
}
o.Options = MergeOptions(o.Options, opt.Options)
if o.Fields == nil {
o.Fields = opt.Fields
continue
}
for k, v := range opt.Fields {
o.Fields[k] = v
}
}
return o
}
type AggregatePublishedOptions AggregateOptions
func (opts *AggregatePublishedOptions) ToAggregateOptions() *AggregateOptions {
return &AggregateOptions{
Options: MergeOptions(opts.Options),
SortOptions: options.MergeSortOptions(opts.SortOptions),
Fields: maps.Clone(opts.Fields),
}
}
func MergeAggregatePublishedOptions(opts ...*AggregatePublishedOptions) *AggregatePublishedOptions {
ao := make([]*AggregateOptions, len(opts))
for i, opt := range opts {
ao[i] = (*AggregateOptions)(opt)
}
merged := MergeAggregateOptions(ao...)
return (*AggregatePublishedOptions)(merged)
}