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 }