github.com/mailru/activerecord@v1.12.2/internal/pkg/ds/app.go (about)

     1  package ds
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/mailru/activerecord/internal/pkg/arerror"
    10  	"github.com/mailru/activerecord/pkg/octopus"
    11  )
    12  
    13  // Описание приложения. Информация необходимая для разметки артефактов
    14  // Остаётся в сгенерированных файлах, что бы было понятно какой версией сгенерированы файлы
    15  type AppInfo struct {
    16  	appName      string
    17  	version      string
    18  	buildTime    string
    19  	buildOS      string
    20  	buildCommit  string
    21  	generateTime string
    22  }
    23  
    24  // Конструктор для AppInfo
    25  func NewAppInfo() *AppInfo {
    26  	return &AppInfo{
    27  		appName:      "argen",
    28  		generateTime: time.Now().Format(time.RFC3339),
    29  	}
    30  }
    31  
    32  // Опции для конструктора, используются для модификации полей структуры
    33  func (i *AppInfo) WithVersion(version string) *AppInfo {
    34  	i.version = version
    35  	return i
    36  }
    37  
    38  func (i *AppInfo) WithBuildTime(buildTime string) *AppInfo {
    39  	i.buildTime = buildTime
    40  	return i
    41  }
    42  
    43  func (i *AppInfo) WithBuildOS(buildOS string) *AppInfo {
    44  	i.buildOS = buildOS
    45  	return i
    46  }
    47  
    48  func (i *AppInfo) WithBuildCommit(commit string) *AppInfo {
    49  	i.buildCommit = commit
    50  	return i
    51  }
    52  
    53  // Строковое представление версии генератора
    54  func (i *AppInfo) String() string {
    55  	return fmt.Sprintf("%s@%s (Commit: %s)", i.appName, i.version, i.buildCommit)
    56  }
    57  
    58  // Структура для описания неймспейса сущности
    59  type NamespaceDeclaration struct {
    60  	ObjectName  string
    61  	PublicName  string
    62  	PackageName string
    63  	ModuleName  string
    64  }
    65  
    66  // Структура для описания конфигурации сервера
    67  // Может быть указан путь к конфигурации `Conf` или параметры подключения напрямую
    68  type ServerDeclaration struct {
    69  	Timeout          int64
    70  	Host, Port, Conf string
    71  }
    72  
    73  type ImportPackage struct {
    74  	Imports      []ImportDeclaration // Список необходимых дополнительных импортов, формируется из директивы import
    75  	ImportMap    map[string]int      // Обратный индекс от имен по импортам
    76  	ImportPkgMap map[string]int      // Обратный индекс от пакетов к импортам
    77  }
    78  
    79  // Структура описывающая отдельную сущность представленную в декларативном файле
    80  type RecordPackage struct {
    81  	ImportPackage
    82  	Server                ServerDeclaration                    // Описание сервера
    83  	Namespace             NamespaceDeclaration                 // Описание неймспейса/таблицы
    84  	Fields                []FieldDeclaration                   // Описание полей, важна последовательность для некоторых хранилищ
    85  	FieldsMap             map[string]int                       // Обратный индекс от имен к полям
    86  	FieldsObjectMap       map[string]FieldObject               // Обратный индекс по имени для ссылок на другие сущности
    87  	Indexes               []IndexDeclaration                   // Список индексов, важна последовательность для некоторых хранилищ
    88  	IndexMap              map[string]int                       // Обратный индекс от имён для индексов
    89  	SelectorMap           map[string]int                       // Список селекторов, используется для контроля дублей
    90  	Backends              []string                             // Список бекендов для которых надо сгенерировать пакеты (сейчас допустим один и только один)
    91  	SerializerMap         map[string]SerializerDeclaration     // Список сериализаторов используемых в этой сущности
    92  	MutatorMap            map[string]MutatorDeclaration        // Список мутаторов используемых в этой сущности
    93  	TriggerMap            map[string]TriggerDeclaration        // Список триггеров используемых в сущности
    94  	FlagMap               map[string]FlagDeclaration           // Список флагов используемых в полях сущности
    95  	ProcInFields          []ProcFieldDeclaration               // Описание входных параметров процедуры, важна последовательность
    96  	ProcOutFields         ProcFieldDeclarations                // Описание выходных параметров процедуры, важна последовательность
    97  	ProcFieldsMap         map[string]int                       // Обратный индекс от имен
    98  	LinkedStructsMap      map[string]LinkedPackageDeclaration  // Описание пакетов связанных типов
    99  	ImportStructFieldsMap map[string][]PartialFieldDeclaration // Описаний структур импортируемых полей сущности
   100  }
   101  
   102  func NewImportPackage() ImportPackage {
   103  	return ImportPackage{
   104  		Imports:      []ImportDeclaration{},
   105  		ImportMap:    map[string]int{},
   106  		ImportPkgMap: map[string]int{},
   107  	}
   108  }
   109  
   110  // Конструктор для RecordPackage, инициализирует ссылочные типы
   111  func NewRecordPackage() *RecordPackage {
   112  	return &RecordPackage{
   113  		ImportPackage: ImportPackage{
   114  			Imports:      []ImportDeclaration{},
   115  			ImportMap:    map[string]int{},
   116  			ImportPkgMap: map[string]int{},
   117  		},
   118  		Server:                ServerDeclaration{},
   119  		Namespace:             NamespaceDeclaration{},
   120  		Fields:                []FieldDeclaration{},
   121  		FieldsMap:             map[string]int{},
   122  		FieldsObjectMap:       map[string]FieldObject{},
   123  		Indexes:               []IndexDeclaration{},
   124  		IndexMap:              map[string]int{},
   125  		SelectorMap:           map[string]int{},
   126  		Backends:              []string{},
   127  		SerializerMap:         map[string]SerializerDeclaration{},
   128  		MutatorMap:            map[string]MutatorDeclaration{},
   129  		TriggerMap:            map[string]TriggerDeclaration{},
   130  		FlagMap:               map[string]FlagDeclaration{},
   131  		ProcFieldsMap:         map[string]int{},
   132  		ProcOutFields:         map[int]ProcFieldDeclaration{},
   133  		LinkedStructsMap:      map[string]LinkedPackageDeclaration{},
   134  		ImportStructFieldsMap: map[string][]PartialFieldDeclaration{},
   135  	}
   136  }
   137  
   138  // Тип и константы для описания направления сортировки индекса
   139  type IndexOrder uint8
   140  
   141  const (
   142  	IndexOrderAsc IndexOrder = iota
   143  	IndexOrderDesc
   144  )
   145  
   146  // Тип для описания поля внутри индекса (номер поля и направление сортировки)
   147  type IndexField struct {
   148  	IndField int
   149  	Order    IndexOrder
   150  }
   151  
   152  // Тип для описания индекса
   153  type IndexDeclaration struct {
   154  	Name      string                // Имя индекса
   155  	Num       uint8                 // Номер индекса в описании спейса
   156  	Selector  string                // Название функции селектора
   157  	Fields    []int                 // Список номеров полей участвующих в индексе (последовательность имеет значение)
   158  	FieldsMap map[string]IndexField // Обратный индекс по именам полей (используется для выявления дублей)
   159  	Primary   bool                  // Признак того, что индекс является первичным ключом
   160  	Unique    bool                  // Признак того, что индекс является уникальным
   161  	Type      string                // Тип индекса, для индексов по одному полю простой тип, для составных индексов собственный тип
   162  	Partial   bool                  // Признак того, что индекс частичный
   163  }
   164  
   165  // Serializer Сериализаторы для поля
   166  type Serializer []string
   167  
   168  // FieldDeclaration Тип описывающий поле в сущности
   169  type FieldDeclaration struct {
   170  	Name       string         // Название поля
   171  	Format     octopus.Format // формат поля
   172  	PrimaryKey bool           // участвует ли поле в первичном ключе (при изменении таких полей необходимо делать delete + insert вместо update)
   173  	Mutators   []string       // список мутаторов (атомарных действий на уровне БД)
   174  	Size       int64          // Размер поля, используется только для строковых значений
   175  	Serializer Serializer     // Сериализаторы для поля
   176  	ObjectLink string         // является ли поле ссылкой на другую сущность
   177  }
   178  
   179  // Name возвращает имя сериализатора, если он установлен, иначе пустую строку
   180  func (s Serializer) Name() string {
   181  	if len(s) > 0 {
   182  		return s[0]
   183  	}
   184  
   185  	return ""
   186  }
   187  
   188  // Params Параметры передаваемые при сериализации. Используется, когда на уровне декларирования
   189  // известно, что сериализатор/десериализатор требует дополнительных константных значений
   190  func (s Serializer) Params() string {
   191  	if len(s) > 1 {
   192  		return `"` + strings.Join(s[1:], `", "`) + `", `
   193  	}
   194  
   195  	return ""
   196  }
   197  
   198  const (
   199  	ProcInputParam  = "input"
   200  	ProcOutputParam = "output"
   201  )
   202  
   203  type ProcParameterType uint8
   204  
   205  func (p ProcParameterType) String() string {
   206  	switch p {
   207  	case IN:
   208  		return ProcInputParam
   209  	case OUT:
   210  		return ProcOutputParam
   211  	case INOUT:
   212  		return fmt.Sprintf("%v/%v", ProcInputParam, ProcOutputParam)
   213  	default:
   214  		return ""
   215  	}
   216  }
   217  
   218  const (
   219  	_     ProcParameterType = iota
   220  	IN                      //тип входного параметра процедуры
   221  	OUT                     //тип выходного параметра процедуры
   222  	INOUT                   //тип одновременно и входного и выходного параметра процедуры
   223  )
   224  
   225  // ProcFieldDeclaration Тип описывающий поле процедуры
   226  type ProcFieldDeclaration struct {
   227  	Name       string            // Название поля
   228  	Format     octopus.Format    // формат поля
   229  	Type       ProcParameterType // тип параметра (IN, OUT, INOUT)
   230  	Size       int64             // Размер поля, используется только для строковых значений
   231  	Serializer Serializer        // Сериализатора для поля
   232  	OrderIndex int               // Порядковый номер параметра в сигнатуре вызова процедуры
   233  }
   234  
   235  // ProcFieldDeclarations Индекс порядкового значения полей процедуры
   236  type ProcFieldDeclarations map[int]ProcFieldDeclaration
   237  
   238  // Add Добавляет декларацию поля процедуры в список.
   239  // Возвращает ошибку, если декларация с таким порядком в [ProcFieldDeclarations] уже существует
   240  func (pfd ProcFieldDeclarations) Add(field ProcFieldDeclaration) error {
   241  	idx := field.OrderIndex
   242  
   243  	if _, ok := pfd[idx]; ok {
   244  		return arerror.ErrProcFieldDuplicateOrderIndex
   245  	}
   246  
   247  	pfd[idx] = field
   248  
   249  	return nil
   250  }
   251  
   252  // List список деклараций процедуры в описанном порядке описания
   253  func (pfd ProcFieldDeclarations) List() []ProcFieldDeclaration {
   254  	out := make([]ProcFieldDeclaration, len(pfd))
   255  	for i := range pfd {
   256  		out[i] = pfd[i]
   257  	}
   258  
   259  	return out
   260  }
   261  
   262  // Validate проверяет корректность декларируемых значений порядкового номера полей процедуры
   263  func (pfd ProcFieldDeclarations) Validate() bool {
   264  	if len(pfd) == 0 {
   265  		return true
   266  	}
   267  
   268  	var maxIdx int
   269  	for idx := range pfd {
   270  		if idx > maxIdx {
   271  			maxIdx = idx
   272  		}
   273  	}
   274  
   275  	return maxIdx < len(pfd)
   276  }
   277  
   278  // Константы описывающие мутаторы для поля
   279  const (
   280  	IncMutator      string = "inc"       // инкремент (только для числовых типов)
   281  	DecMutator      string = "dec"       // декремент (только для числовых типов)
   282  	SetBitMutator   string = "set_bit"   // установка бита (только для целочисленных типов)
   283  	ClearBitMutator string = "clear_bit" // снятие бита (только для целочисленных типов)
   284  	AndMutator      string = "and"       // дизъюнкция (только для целочисленных типов)
   285  	OrMutator       string = "or"        // конъюнкция (только для целочисленных типов)
   286  	XorMutator      string = "xor"       // xor (только для целочисленных типов)
   287  )
   288  
   289  var FieldMutators = [...]string{
   290  	IncMutator,
   291  	DecMutator,
   292  	SetBitMutator,
   293  	ClearBitMutator,
   294  	AndMutator,
   295  	OrMutator,
   296  	XorMutator}
   297  
   298  var fieldMutatorsChecker = map[string]string{}
   299  var FieldMutatorsCheckerOnce sync.Once
   300  
   301  func GetFieldMutatorsChecker() map[string]string {
   302  	FieldMutatorsCheckerOnce.Do(func() {
   303  		for _, f := range FieldMutators {
   304  			fieldMutatorsChecker[f] = f
   305  		}
   306  	})
   307  
   308  	return fieldMutatorsChecker
   309  }
   310  
   311  // Структура для описания ссылочных полей (когда значение одного из полей является ключом для для другой сущности)
   312  type FieldObject struct {
   313  	Name       string // Имя
   314  	Key        string // Название поля во внешней сущности
   315  	ObjectName string // Название внешней сущности
   316  	Field      string // Имя поля в текущей сущности
   317  	Unique     bool   // Признак связки true => один к одному, false => один ко многим
   318  }
   319  
   320  // Структура описывающая сериализатор
   321  type SerializerDeclaration struct {
   322  	Name        string // имя
   323  	Pkg         string // Пакет для импорта
   324  	Type        string // Тип данных
   325  	ImportName  string // Симлинк для импорта
   326  	Marshaler   string // Имя функции маршалера
   327  	Unmarshaler string // Имя функции анмаршаллера
   328  }
   329  
   330  // MutatorDeclaration Структура описывающая мутатор
   331  type MutatorDeclaration struct {
   332  	Name          string // имя
   333  	Pkg           string // Пакет для импорта
   334  	Type          string // Тип данных
   335  	ImportName    string // Симлинк для импорта
   336  	Update        string // Имя функции для параметров обновления
   337  	Replace       string // Имя функции для параметров замены
   338  	PartialFields []PartialFieldDeclaration
   339  }
   340  
   341  // Структура описывающая дополнительный импорты
   342  type ImportDeclaration struct {
   343  	Path       string // Путь к пакету
   344  	ImportName string // Симлинк для пакета при импорте
   345  }
   346  
   347  // Структура описывающая триггеры
   348  type TriggerDeclaration struct {
   349  	Name       string          // Имя
   350  	Pkg        string          // Пакет для импорта
   351  	Func       string          // Имя функции
   352  	ImportName string          // Симлинк для импорта пакета
   353  	Params     map[string]bool // Параметры передаваемые в функцию
   354  }
   355  
   356  // Структура описывающая флаги для поля
   357  type FlagDeclaration struct {
   358  	Name  string   // Имя
   359  	Flags []string // Список имён флагов
   360  }
   361  
   362  type PartialFieldDeclaration struct {
   363  	Name string // Имя части поля
   364  	Type string // Тип части поля
   365  }
   366  
   367  type LinkedPackageDeclaration struct {
   368  	Types  map[string]struct{} // Имена типов связанных структур
   369  	Import ImportPackage       // Описание импорта пакета связанных структур
   370  }