github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/state/types.go (about) 1 /* 2 * Copyright (c) 2022-present unTill Pro, Ltd. 3 */ 4 5 package state 6 7 import ( 8 "bytes" 9 "container/list" 10 "context" 11 "fmt" 12 "io" 13 "maps" 14 "net/http" 15 "reflect" 16 "slices" 17 "strings" 18 "time" 19 20 "github.com/voedger/voedger/pkg/appdef" 21 "github.com/voedger/voedger/pkg/iauthnz" 22 "github.com/voedger/voedger/pkg/isecrets" 23 "github.com/voedger/voedger/pkg/istructs" 24 "github.com/voedger/voedger/pkg/itokens" 25 "github.com/voedger/voedger/pkg/utils/federation" 26 ) 27 28 type PartitionIDFunc func() istructs.PartitionID 29 type WSIDFunc func() istructs.WSID 30 type N10nFunc func(view appdef.QName, wsid istructs.WSID, offset istructs.Offset) 31 type AppStructsFunc func() istructs.IAppStructs 32 type CUDFunc func() istructs.ICUD 33 type ObjectBuilderFunc func() istructs.IObjectBuilder 34 type PrincipalsFunc func() []iauthnz.Principal 35 type TokenFunc func() string 36 type PLogEventFunc func() istructs.IPLogEvent 37 type ArgFunc func() istructs.IObject 38 type UnloggedArgFunc func() istructs.IObject 39 type WLogOffsetFunc func() istructs.Offset 40 type FederationFunc func() federation.IFederation 41 type QNameFunc func() appdef.QName 42 type TokensFunc func() itokens.ITokens 43 type ExecQueryCallbackFunc func() istructs.ExecQueryCallback 44 type CommandProcessorStateFactory func(ctx context.Context, appStructsFunc AppStructsFunc, partitionIDFunc PartitionIDFunc, wsidFunc WSIDFunc, secretReader isecrets.ISecretReader, cudFunc CUDFunc, principalPayloadFunc PrincipalsFunc, tokenFunc TokenFunc, intentsLimit int, cmdResultBuilderFunc ObjectBuilderFunc, argFunc ArgFunc, unloggedArgFunc UnloggedArgFunc, wlogOffsetFunc WLogOffsetFunc) IHostState 45 type SyncActualizerStateFactory func(ctx context.Context, appStructsFunc AppStructsFunc, partitionIDFunc PartitionIDFunc, wsidFunc WSIDFunc, n10nFunc N10nFunc, secretReader isecrets.ISecretReader, eventFunc PLogEventFunc, intentsLimit int) IHostState 46 type QueryProcessorStateFactory func(ctx context.Context, appStructsFunc AppStructsFunc, partitionIDFunc PartitionIDFunc, wsidFunc WSIDFunc, secretReader isecrets.ISecretReader, principalPayloadFunc PrincipalsFunc, tokenFunc TokenFunc, itokens itokens.ITokens, argFunc ArgFunc, resultBuilderFunc ObjectBuilderFunc, federation federation.IFederation, queryCallbackFunc ExecQueryCallbackFunc, opts ...QPStateOptFunc) IHostState 47 type AsyncActualizerStateFactory func(ctx context.Context, appStructsFunc AppStructsFunc, partitionIDFunc PartitionIDFunc, wsidFunc WSIDFunc, n10nFunc N10nFunc, secretReader isecrets.ISecretReader, eventFunc PLogEventFunc, tokensFunc itokens.ITokens, federationFunc federation.IFederation, intentsLimit, bundlesLimit int, opts ...ActualizerStateOptFunc) IBundledHostState 48 49 type eventsFunc func() istructs.IEvents 50 type recordsFunc func() istructs.IRecords 51 52 type ApplyBatchItem struct { 53 key istructs.IStateKeyBuilder 54 value istructs.IStateValueBuilder 55 } 56 57 type GetBatchItem struct { 58 key istructs.IStateKeyBuilder 59 value istructs.IStateValue 60 } 61 62 type keyBuilder struct { 63 data map[string]interface{} 64 storage appdef.QName 65 entity appdef.QName 66 } 67 68 func newKeyBuilder(storage, entity appdef.QName) *keyBuilder { 69 return &keyBuilder{ 70 data: make(map[string]interface{}), 71 storage: storage, 72 entity: entity, 73 } 74 } 75 76 func (b *keyBuilder) Storage() appdef.QName { return b.storage } 77 func (b *keyBuilder) Entity() appdef.QName { return b.entity } 78 func (b *keyBuilder) PutInt32(name string, value int32) { b.data[name] = value } 79 func (b *keyBuilder) PutInt64(name string, value int64) { b.data[name] = value } 80 func (b *keyBuilder) PutFloat32(name string, value float32) { b.data[name] = value } 81 func (b *keyBuilder) PutFloat64(name string, value float64) { b.data[name] = value } 82 func (b *keyBuilder) PutBytes(name string, value []byte) { b.data[name] = value } 83 func (b *keyBuilder) PutString(name string, value string) { b.data[name] = value } 84 func (b *keyBuilder) PutQName(name string, value appdef.QName) { b.data[name] = value } 85 func (b *keyBuilder) PutBool(name string, value bool) { b.data[name] = value } 86 func (b *keyBuilder) PutRecordID(name string, value istructs.RecordID) { b.data[name] = value } 87 func (b *keyBuilder) PutNumber(string, float64) { panic(ErrNotSupported) } 88 func (b *keyBuilder) PutChars(string, string) { panic(ErrNotSupported) } 89 func (b *keyBuilder) PutFromJSON(j map[string]any) { maps.Copy(b.data, j) } 90 func (b *keyBuilder) PartitionKey() istructs.IRowWriter { panic(ErrNotSupported) } 91 func (b *keyBuilder) ClusteringColumns() istructs.IRowWriter { panic(ErrNotSupported) } 92 func (b *keyBuilder) Equals(src istructs.IKeyBuilder) bool { 93 kb, ok := src.(*keyBuilder) 94 if !ok { 95 return false 96 } 97 if b.storage != kb.storage { 98 return false 99 } 100 if b.entity != kb.entity { 101 return false 102 } 103 if !maps.Equal(b.data, kb.data) { 104 return false 105 } 106 return true 107 } 108 func (b *keyBuilder) ToBytes(istructs.WSID) ([]byte, []byte, error) { panic(ErrNotSupported) } 109 110 type logKeyBuilder struct { 111 istructs.IStateKeyBuilder 112 offset istructs.Offset 113 count int 114 } 115 116 func (b *logKeyBuilder) PutInt64(name string, value int64) { 117 switch name { 118 case Field_Offset: 119 b.offset = istructs.Offset(value) 120 case Field_Count: 121 b.count = int(value) 122 } 123 } 124 125 type wLogKeyBuilder struct { 126 logKeyBuilder 127 wsid istructs.WSID 128 } 129 130 func (b *wLogKeyBuilder) Storage() appdef.QName { 131 return WLog 132 } 133 134 func (b *wLogKeyBuilder) String() string { 135 return fmt.Sprintf("wlog wsid - %d, offset - %d, count - %d", b.wsid, b.offset, b.count) 136 } 137 138 func (b *wLogKeyBuilder) PutInt64(name string, value int64) { 139 b.logKeyBuilder.PutInt64(name, value) 140 if name == Field_WSID { 141 b.wsid = istructs.WSID(value) 142 } 143 } 144 145 type recordsKeyBuilder struct { 146 istructs.IStateKeyBuilder 147 id istructs.RecordID 148 singleton appdef.QName 149 wsid istructs.WSID 150 entity appdef.QName 151 } 152 153 func (b *recordsKeyBuilder) Equals(src istructs.IKeyBuilder) bool { 154 kb, ok := src.(*recordsKeyBuilder) 155 if !ok { 156 return false 157 } 158 if b.id != kb.id { 159 return false 160 } 161 if b.singleton != kb.singleton { 162 return false 163 } 164 if b.wsid != kb.wsid { 165 return false 166 } 167 return true 168 } 169 170 func (b *recordsKeyBuilder) Storage() appdef.QName { 171 return Record 172 } 173 174 func (b *recordsKeyBuilder) String() string { 175 sb := strings.Builder{} 176 _, _ = sb.WriteString(fmt.Sprintf("- %T", b)) 177 if b.id != istructs.NullRecordID { 178 _, _ = sb.WriteString(fmt.Sprintf(", ID - %d", b.id)) 179 } 180 if b.singleton != appdef.NullQName { 181 _, _ = sb.WriteString(fmt.Sprintf(", singleton - %s", b.singleton)) 182 } 183 _, _ = sb.WriteString(fmt.Sprintf(", WSID - %d", b.wsid)) 184 return sb.String() 185 } 186 187 func (b *recordsKeyBuilder) PutInt64(name string, value int64) { 188 if name == Field_WSID { 189 b.wsid = istructs.WSID(value) 190 return 191 } 192 if name == Field_ID { 193 b.id = istructs.RecordID(value) 194 return 195 } 196 // TODO ??? 197 panic(name) 198 } 199 200 func (b *recordsKeyBuilder) PutRecordID(name string, value istructs.RecordID) { 201 if name == Field_ID { 202 b.id = value 203 return 204 } 205 // TODO ??? 206 panic(name) 207 } 208 209 func (b *recordsKeyBuilder) PutQName(name string, value appdef.QName) { 210 if name == Field_Singleton { 211 b.singleton = value 212 return 213 } 214 // TODO ??? 215 panic(name) 216 } 217 218 type recordsValueBuilder struct { 219 istructs.IStateValueBuilder 220 rw istructs.IRowWriter 221 } 222 223 func (b *recordsValueBuilder) Equal(src istructs.IStateValueBuilder) bool { 224 vb, ok := src.(*recordsValueBuilder) 225 if !ok { 226 return false 227 } 228 return reflect.DeepEqual(b.rw, vb.rw) // TODO: does that work? 229 } 230 func (b *recordsValueBuilder) PutInt32(name string, value int32) { b.rw.PutInt32(name, value) } 231 func (b *recordsValueBuilder) PutInt64(name string, value int64) { b.rw.PutInt64(name, value) } 232 func (b *recordsValueBuilder) PutBytes(name string, value []byte) { b.rw.PutBytes(name, value) } 233 func (b *recordsValueBuilder) PutString(name, value string) { b.rw.PutString(name, value) } 234 func (b *recordsValueBuilder) PutBool(name string, value bool) { b.rw.PutBool(name, value) } 235 func (b *recordsValueBuilder) PutChars(name string, value string) { b.rw.PutChars(name, value) } 236 func (b *recordsValueBuilder) PutFloat32(name string, value float32) { b.rw.PutFloat32(name, value) } 237 func (b *recordsValueBuilder) PutFloat64(name string, value float64) { b.rw.PutFloat64(name, value) } 238 func (b *recordsValueBuilder) PutQName(name string, value appdef.QName) { b.rw.PutQName(name, value) } 239 func (b *recordsValueBuilder) PutNumber(name string, value float64) { b.rw.PutNumber(name, value) } 240 func (b *recordsValueBuilder) PutRecordID(name string, value istructs.RecordID) { 241 b.rw.PutRecordID(name, value) 242 } 243 244 type viewKeyBuilder struct { 245 istructs.IKeyBuilder 246 wsid istructs.WSID 247 view appdef.QName 248 } 249 250 func (b *viewKeyBuilder) PutInt64(name string, value int64) { 251 if name == Field_WSID { 252 b.wsid = istructs.WSID(value) 253 return 254 } 255 b.IKeyBuilder.PutInt64(name, value) 256 } 257 func (b *viewKeyBuilder) PutQName(name string, value appdef.QName) { 258 if name == appdef.SystemField_QName { 259 b.wsid = istructs.NullWSID 260 b.view = value 261 } 262 b.IKeyBuilder.PutQName(name, value) 263 } 264 func (b *viewKeyBuilder) Entity() appdef.QName { 265 return b.view 266 } 267 func (b *viewKeyBuilder) Storage() appdef.QName { 268 return View 269 } 270 func (b *viewKeyBuilder) Equals(src istructs.IKeyBuilder) bool { 271 kb, ok := src.(*viewKeyBuilder) 272 if !ok { 273 return false 274 } 275 if b.wsid != kb.wsid { 276 return false 277 } 278 if b.view != kb.view { 279 return false 280 } 281 return b.IKeyBuilder.Equals(kb.IKeyBuilder) 282 } 283 284 type viewValueBuilder struct { 285 istructs.IValueBuilder 286 offset istructs.Offset 287 entity appdef.QName 288 } 289 290 // used in tests 291 func (b *viewValueBuilder) Equal(src istructs.IStateValueBuilder) bool { 292 bThis, err := b.IValueBuilder.ToBytes() 293 if err != nil { 294 panic(err) 295 } 296 297 bSrc, err := src.ToBytes() 298 if err != nil { 299 panic(err) 300 } 301 302 return reflect.DeepEqual(bThis, bSrc) 303 } 304 305 func (b *viewValueBuilder) PutInt64(name string, value int64) { 306 if name == ColOffset { 307 b.offset = istructs.Offset(value) 308 } 309 b.IValueBuilder.PutInt64(name, value) 310 } 311 func (b *viewValueBuilder) PutQName(name string, value appdef.QName) { 312 if name == appdef.SystemField_QName { 313 b.offset = istructs.NullOffset 314 } 315 b.IValueBuilder.PutQName(name, value) 316 } 317 func (b *viewValueBuilder) Build() istructs.IValue { 318 return b.IValueBuilder.Build() 319 } 320 321 func (b *viewValueBuilder) BuildValue() istructs.IStateValue { 322 return &viewValue{ 323 value: b.Build(), 324 } 325 } 326 327 type recordsValue struct { 328 baseStateValue 329 record istructs.IRecord 330 } 331 332 func (v *recordsValue) AsInt32(name string) int32 { return v.record.AsInt32(name) } 333 func (v *recordsValue) AsInt64(name string) int64 { return v.record.AsInt64(name) } 334 func (v *recordsValue) AsFloat32(name string) float32 { return v.record.AsFloat32(name) } 335 func (v *recordsValue) AsFloat64(name string) float64 { return v.record.AsFloat64(name) } 336 func (v *recordsValue) AsBytes(name string) []byte { return v.record.AsBytes(name) } 337 func (v *recordsValue) AsString(name string) string { return v.record.AsString(name) } 338 func (v *recordsValue) AsQName(name string) appdef.QName { return v.record.AsQName(name) } 339 func (v *recordsValue) AsBool(name string) bool { return v.record.AsBool(name) } 340 func (v *recordsValue) AsRecordID(name string) istructs.RecordID { 341 return v.record.AsRecordID(name) 342 } 343 func (v *recordsValue) AsRecord(string) (record istructs.IRecord) { return v.record } 344 func (v *recordsValue) FieldNames(cb func(fieldName string)) { 345 v.record.FieldNames(cb) 346 } 347 348 type objectArrayContainerValue struct { 349 baseStateValue 350 object istructs.IObject 351 container string 352 } 353 354 func (v *objectArrayContainerValue) GetAsString(int) string { panic(ErrNotSupported) } 355 func (v *objectArrayContainerValue) GetAsBytes(int) []byte { panic(ErrNotSupported) } 356 func (v *objectArrayContainerValue) GetAsInt32(int) int32 { panic(ErrNotSupported) } 357 func (v *objectArrayContainerValue) GetAsInt64(int) int64 { panic(ErrNotSupported) } 358 func (v *objectArrayContainerValue) GetAsFloat32(int) float32 { panic(ErrNotSupported) } 359 func (v *objectArrayContainerValue) GetAsFloat64(int) float64 { panic(ErrNotSupported) } 360 func (v *objectArrayContainerValue) GetAsQName(int) appdef.QName { panic(ErrNotSupported) } 361 func (v *objectArrayContainerValue) GetAsBool(int) bool { panic(ErrNotSupported) } 362 func (v *objectArrayContainerValue) GetAsValue(i int) (result istructs.IStateValue) { 363 index := 0 364 v.object.Children(v.container, func(o istructs.IObject) { 365 if index == i { 366 result = &objectValue{object: o} 367 } 368 index++ 369 }) 370 if result == nil { 371 panic(errIndexOutOfBounds(i)) 372 } 373 return 374 } 375 func (v *objectArrayContainerValue) Length() int { 376 var result int 377 v.object.Children(v.container, func(i istructs.IObject) { 378 result++ 379 }) 380 return result 381 } 382 383 type jsonArrayValue struct { 384 baseStateValue 385 array []interface{} 386 } 387 388 func (v *jsonArrayValue) GetAsString(i int) string { return v.array[i].(string) } 389 func (v *jsonArrayValue) GetAsBytes(i int) []byte { return v.array[i].([]byte) } 390 func (v *jsonArrayValue) GetAsInt32(i int) int32 { return v.array[i].(int32) } 391 func (v *jsonArrayValue) GetAsInt64(i int) int64 { return v.array[i].(int64) } 392 func (v *jsonArrayValue) GetAsFloat32(i int) float32 { return v.array[i].(float32) } 393 func (v *jsonArrayValue) GetAsFloat64(i int) float64 { return v.array[i].(float64) } 394 func (v *jsonArrayValue) GetAsQName(i int) appdef.QName { return v.array[i].(appdef.QName) } 395 func (v *jsonArrayValue) GetAsBool(i int) bool { return v.array[i].(bool) } 396 func (v *jsonArrayValue) GetAsValue(i int) (result istructs.IStateValue) { 397 switch v := v.array[i].(type) { 398 case map[string]interface{}: 399 return &jsonValue{json: v} 400 case []interface{}: 401 return &jsonArrayValue{array: v} 402 default: 403 panic(errUnexpectedType(v)) 404 } 405 } 406 func (v *jsonArrayValue) Length() int { 407 return len(v.array) 408 } 409 410 type jsonValue struct { 411 baseStateValue 412 json map[string]interface{} 413 } 414 415 func (v *jsonValue) AsInt32(name string) int32 { 416 if v, ok := v.json[name]; ok { 417 return v.(int32) 418 } 419 panic(errUndefined(name)) 420 } 421 func (v *jsonValue) AsInt64(name string) int64 { 422 if v, ok := v.json[name]; ok { 423 return v.(int64) 424 } 425 panic(errUndefined(name)) 426 } 427 func (v *jsonValue) AsFloat32(name string) float32 { 428 if v, ok := v.json[name]; ok { 429 return v.(float32) 430 } 431 panic(errUndefined(name)) 432 } 433 func (v *jsonValue) AsFloat64(name string) float64 { 434 if v, ok := v.json[name]; ok { 435 return v.(float64) 436 } 437 panic(errUndefined(name)) 438 } 439 func (v *jsonValue) AsBytes(name string) []byte { 440 if v, ok := v.json[name]; ok { 441 return v.([]byte) 442 } 443 panic(errUndefined(name)) 444 } 445 func (v *jsonValue) AsString(name string) string { 446 if v, ok := v.json[name]; ok { 447 return v.(string) 448 } 449 panic(errUndefined(name)) 450 } 451 func (v *jsonValue) AsQName(name string) appdef.QName { 452 if v, ok := v.json[name]; ok { 453 return v.(appdef.QName) 454 } 455 panic(errUndefined(name)) 456 } 457 func (v *jsonValue) AsBool(name string) bool { 458 if v, ok := v.json[name]; ok { 459 return v.(bool) 460 } 461 panic(errUndefined(name)) 462 } 463 func (v *jsonValue) AsRecordID(name string) istructs.RecordID { 464 if v, ok := v.json[name]; ok { 465 return v.(istructs.RecordID) 466 } 467 panic(errUndefined(name)) 468 } 469 func (v *jsonValue) RecordIDsß(includeNulls bool, cb func(string, istructs.RecordID)) {} 470 func (v *jsonValue) FieldNames(cb func(string)) { 471 for name := range v.json { 472 cb(name) 473 } 474 } 475 func (v *jsonValue) AsValue(name string) (result istructs.IStateValue) { 476 if v, ok := v.json[name]; ok { 477 switch v := v.(type) { 478 case map[string]interface{}: 479 return &jsonValue{json: v} 480 case []interface{}: 481 return &jsonArrayValue{array: v} 482 default: 483 panic(errUnexpectedType(v)) 484 } 485 } 486 panic(errUndefined(name)) 487 } 488 489 type objectValue struct { 490 baseStateValue 491 object istructs.IObject 492 } 493 494 func (v *objectValue) AsInt32(name string) int32 { return v.object.AsInt32(name) } 495 func (v *objectValue) AsInt64(name string) int64 { return v.object.AsInt64(name) } 496 func (v *objectValue) AsFloat32(name string) float32 { return v.object.AsFloat32(name) } 497 func (v *objectValue) AsFloat64(name string) float64 { return v.object.AsFloat64(name) } 498 func (v *objectValue) AsBytes(name string) []byte { return v.object.AsBytes(name) } 499 func (v *objectValue) AsString(name string) string { return v.object.AsString(name) } 500 func (v *objectValue) AsQName(name string) appdef.QName { return v.object.AsQName(name) } 501 func (v *objectValue) AsBool(name string) bool { return v.object.AsBool(name) } 502 func (v *objectValue) AsRecordID(name string) istructs.RecordID { return v.object.AsRecordID(name) } 503 func (v *objectValue) RecordIDs(includeNulls bool, cb func(string, istructs.RecordID)) { 504 v.object.RecordIDs(includeNulls, cb) 505 } 506 func (v *objectValue) FieldNames(cb func(string)) { v.object.FieldNames(cb) } 507 func (v *objectValue) AsValue(name string) (result istructs.IStateValue) { 508 v.object.Containers(func(name string) { 509 result = &objectArrayContainerValue{ 510 object: v.object, 511 container: name, 512 } 513 }) 514 if result == nil { 515 panic(errUndefined(name)) 516 } 517 return 518 } 519 520 type pLogValue struct { 521 baseStateValue 522 event istructs.IPLogEvent 523 offset int64 524 } 525 526 func (v *pLogValue) AsInt64(name string) int64 { 527 switch name { 528 case Field_WLogOffset: 529 return int64(v.event.WLogOffset()) 530 case Field_Workspace: 531 return int64(v.event.Workspace()) 532 case Field_RegisteredAt: 533 return int64(v.event.RegisteredAt()) 534 case Field_DeviceID: 535 return int64(v.event.DeviceID()) 536 case Field_SyncedAt: 537 return int64(v.event.SyncedAt()) 538 case Field_Offset: 539 return v.offset 540 } 541 panic(errUndefined(name)) 542 } 543 func (v *pLogValue) AsBool(name string) bool { 544 if name == Field_Synced { 545 return v.event.Synced() 546 } 547 panic(errUndefined(name)) 548 } 549 func (v *pLogValue) AsRecord(string) istructs.IRecord { 550 return v.event.ArgumentObject().AsRecord() 551 } 552 func (v *pLogValue) AsQName(name string) appdef.QName { 553 if name == Field_QName { 554 return v.event.QName() 555 } 556 panic(errUndefined(name)) 557 } 558 func (v *pLogValue) AsEvent(string) istructs.IDbEvent { return v.event } 559 func (v *pLogValue) AsValue(name string) istructs.IStateValue { 560 if name == Field_CUDs { 561 sv := &cudsValue{} 562 v.event.CUDs(func(rec istructs.ICUDRow) { 563 sv.cuds = append(sv.cuds, rec) 564 }) 565 return sv 566 } 567 if name == Field_Error { 568 return &eventErrorValue{error: v.event.Error()} 569 } 570 if name == Field_ArgumentObject { 571 arg := v.event.ArgumentObject() 572 if arg == nil { 573 return nil 574 } 575 return &objectValue{object: arg} 576 } 577 panic(errUndefined(name)) 578 } 579 580 type wLogValue struct { 581 baseStateValue 582 event istructs.IWLogEvent 583 offset int64 584 } 585 586 func (v *wLogValue) AsInt64(name string) int64 { 587 switch name { 588 case Field_RegisteredAt: 589 return int64(v.event.RegisteredAt()) 590 case Field_DeviceID: 591 return int64(v.event.DeviceID()) 592 case Field_SyncedAt: 593 return int64(v.event.SyncedAt()) 594 case Field_Offset: 595 return v.offset 596 default: 597 return 0 598 } 599 } 600 func (v *wLogValue) AsBool(_ string) bool { return v.event.Synced() } 601 func (v *wLogValue) AsQName(_ string) appdef.QName { return v.event.QName() } 602 func (v *wLogValue) AsEvent(_ string) (event istructs.IDbEvent) { 603 return v.event 604 } 605 func (v *wLogValue) AsRecord(_ string) (record istructs.IRecord) { 606 return v.event.ArgumentObject().AsRecord() 607 } 608 func (v *wLogValue) AsValue(name string) istructs.IStateValue { 609 if name != Field_CUDs { 610 panic(ErrNotSupported) 611 } 612 sv := &cudsValue{} 613 v.event.CUDs(func(rec istructs.ICUDRow) { 614 sv.cuds = append(sv.cuds, rec) 615 }) 616 return sv 617 } 618 619 type sendMailKeyBuilder struct { 620 *keyBuilder 621 to []string 622 cc []string 623 bcc []string 624 } 625 626 func (b *sendMailKeyBuilder) Equals(src istructs.IKeyBuilder) bool { 627 kb, ok := src.(*sendMailKeyBuilder) 628 if !ok { 629 return false 630 } 631 if !slices.Equal(b.to, kb.to) { 632 return false 633 } 634 if !slices.Equal(b.cc, kb.cc) { 635 return false 636 } 637 if !slices.Equal(b.bcc, kb.bcc) { 638 return false 639 } 640 if b.storage != kb.storage { 641 return false 642 } 643 if b.entity != kb.entity { 644 return false 645 } 646 if !maps.Equal(b.data, kb.data) { 647 return false 648 } 649 return true 650 } 651 652 func (b *sendMailKeyBuilder) PutString(name string, value string) { 653 switch name { 654 case Field_To: 655 b.to = append(b.to, value) 656 case Field_CC: 657 b.cc = append(b.cc, value) 658 case Field_BCC: 659 b.bcc = append(b.bcc, value) 660 default: 661 b.keyBuilder.PutString(name, value) 662 } 663 } 664 665 type httpKeyBuilder struct { 666 *keyBuilder 667 headers map[string]string 668 } 669 670 func newHttpKeyBuilder() *httpKeyBuilder { 671 return &httpKeyBuilder{ 672 keyBuilder: newKeyBuilder(Http, appdef.NullQName), 673 headers: make(map[string]string), 674 } 675 } 676 677 func (b *httpKeyBuilder) PutString(name string, value string) { 678 switch name { 679 case Field_Header: 680 trim := func(v string) string { return strings.Trim(v, " \n\r\t") } 681 ss := strings.SplitN(value, ":", 2) 682 b.headers[trim(ss[0])] = trim(ss[1]) 683 default: 684 b.keyBuilder.PutString(name, value) 685 } 686 } 687 688 func (b *httpKeyBuilder) method() string { 689 if v, ok := b.keyBuilder.data[Field_Method]; ok { 690 return v.(string) 691 } 692 return http.MethodGet 693 } 694 func (b *httpKeyBuilder) url() string { 695 if v, ok := b.keyBuilder.data[Field_Url]; ok { 696 return v.(string) 697 } 698 panic(fmt.Errorf("'url': %w", ErrNotFound)) 699 } 700 func (b *httpKeyBuilder) body() io.Reader { 701 if v, ok := b.keyBuilder.data[Field_Body]; ok { 702 return bytes.NewReader(v.([]byte)) 703 } 704 return nil 705 } 706 func (b *httpKeyBuilder) timeout() time.Duration { 707 if v, ok := b.keyBuilder.data[Field_HTTPClientTimeoutMilliseconds]; ok { 708 t := v.(int64) 709 return time.Duration(t) * time.Millisecond 710 } 711 return defaultHTTPClientTimeout 712 } 713 func (b *httpKeyBuilder) String() string { 714 ss := make([]string, 0, httpStorageKeyBuilderStringerSliceCap) 715 ss = append(ss, b.method()) 716 ss = append(ss, b.url()) 717 if v, ok := b.keyBuilder.data[Field_Body]; ok { 718 ss = append(ss, string(v.([]byte))) 719 } 720 return strings.Join(ss, " ") 721 } 722 723 type httpValue struct { 724 istructs.IStateValue 725 body []byte 726 header map[string][]string 727 statusCode int 728 } 729 730 func (v *httpValue) AsBytes(string) []byte { return v.body } 731 func (v *httpValue) AsInt32(string) int32 { return int32(v.statusCode) } 732 func (v *httpValue) AsString(name string) string { 733 if name == Field_Header { 734 var res strings.Builder 735 for k, v := range v.header { 736 if len(v) > 0 { 737 if res.Len() > 0 { 738 res.WriteString("\n") 739 } 740 res.WriteString(fmt.Sprintf("%s: %s", k, v[0])) // FIXME: len(v)>2 ? 741 } 742 } 743 return res.String() 744 } 745 return string(v.body) 746 } 747 748 type appSecretValue struct { 749 baseStateValue 750 content string 751 } 752 753 func (v *appSecretValue) AsString(string) string { return v.content } 754 755 type n10n struct { 756 wsid istructs.WSID 757 view appdef.QName 758 } 759 760 type bundle interface { 761 put(key istructs.IStateKeyBuilder, value ApplyBatchItem) 762 get(key istructs.IStateKeyBuilder) (value ApplyBatchItem, ok bool) 763 containsKeysForSameEntity(key istructs.IStateKeyBuilder) bool 764 values() (values []ApplyBatchItem) 765 size() (size int) 766 clear() 767 } 768 769 type pair struct { 770 key istructs.IStateKeyBuilder 771 value ApplyBatchItem 772 } 773 774 type bundleImpl struct { 775 list *list.List 776 } 777 778 func newBundle() bundle { 779 return &bundleImpl{list: list.New()} 780 } 781 782 func (b *bundleImpl) put(key istructs.IStateKeyBuilder, value ApplyBatchItem) { 783 for el := b.list.Front(); el != nil; el = el.Next() { 784 if el.Value.(*pair).key.Equals(key) { 785 el.Value.(*pair).value = value 786 return 787 } 788 } 789 b.list.PushBack(&pair{key: key, value: value}) 790 } 791 func (b *bundleImpl) get(key istructs.IStateKeyBuilder) (value ApplyBatchItem, ok bool) { 792 for el := b.list.Front(); el != nil; el = el.Next() { 793 if el.Value.(*pair).key.Equals(key) { 794 return el.Value.(*pair).value, true 795 } 796 } 797 return emptyApplyBatchItem, false 798 } 799 func (b *bundleImpl) containsKeysForSameEntity(key istructs.IStateKeyBuilder) bool { 800 var next *list.Element 801 for el := b.list.Front(); el != nil; el = next { 802 next = el.Next() 803 if el.Value.(*pair).key.Entity() == key.Entity() { 804 return true 805 } 806 } 807 return false 808 } 809 func (b *bundleImpl) values() (values []ApplyBatchItem) { 810 for el := b.list.Front(); el != nil; el = el.Next() { 811 values = append(values, el.Value.(*pair).value) 812 } 813 return 814 } 815 func (b *bundleImpl) size() (size int) { return b.list.Len() } 816 func (b *bundleImpl) clear() { b.list = list.New() } 817 818 type key struct { 819 istructs.IKey 820 data map[string]interface{} 821 } 822 823 func (k *key) AsInt64(name string) int64 { return k.data[name].(int64) } 824 825 type requestSubjectValue struct { 826 baseStateValue 827 kind int32 828 profileWSID int64 829 name string 830 token string 831 } 832 833 func (v *requestSubjectValue) AsInt64(name string) int64 { 834 switch name { 835 case Field_ProfileWSID: 836 return v.profileWSID 837 default: 838 return 0 839 } 840 } 841 func (v *requestSubjectValue) AsInt32(name string) int32 { 842 switch name { 843 case Field_Kind: 844 return v.kind 845 default: 846 return 0 847 } 848 } 849 func (v *requestSubjectValue) AsString(name string) string { 850 switch name { 851 case Field_Name: 852 return v.name 853 case Field_Token: 854 return v.token 855 default: 856 return "" 857 } 858 } 859 860 type viewValue struct { 861 baseStateValue 862 value istructs.IValue 863 } 864 865 func (v *viewValue) AsInt32(name string) int32 { return v.value.AsInt32(name) } 866 func (v *viewValue) AsInt64(name string) int64 { return v.value.AsInt64(name) } 867 func (v *viewValue) AsFloat32(name string) float32 { return v.value.AsFloat32(name) } 868 func (v *viewValue) AsFloat64(name string) float64 { return v.value.AsFloat64(name) } 869 func (v *viewValue) AsBytes(name string) []byte { return v.value.AsBytes(name) } 870 func (v *viewValue) AsString(name string) string { return v.value.AsString(name) } 871 func (v *viewValue) AsQName(name string) appdef.QName { return v.value.AsQName(name) } 872 func (v *viewValue) AsBool(name string) bool { return v.value.AsBool(name) } 873 func (v *viewValue) AsRecordID(name string) istructs.RecordID { 874 return v.value.AsRecordID(name) 875 } 876 func (v *viewValue) AsRecord(name string) istructs.IRecord { 877 return v.value.AsRecord(name) 878 } 879 880 type eventErrorValue struct { 881 istructs.IStateValue 882 error istructs.IEventError 883 } 884 885 func (v *eventErrorValue) AsString(name string) string { 886 if name == Field_ErrStr { 887 return v.error.ErrStr() 888 } 889 panic(ErrNotSupported) 890 } 891 892 func (v *eventErrorValue) AsBool(name string) bool { 893 if name == Field_ValidEvent { 894 return v.error.ValidEvent() 895 } 896 panic(ErrNotSupported) 897 } 898 899 func (v *eventErrorValue) AsQName(name string) appdef.QName { 900 if name == Field_QNameFromParams { 901 return v.error.QNameFromParams() 902 } 903 panic(ErrNotSupported) 904 } 905 906 type cudsValue struct { 907 istructs.IStateValue 908 cuds []istructs.ICUDRow 909 } 910 911 func (v *cudsValue) Length() int { return len(v.cuds) } 912 func (v *cudsValue) GetAsValue(index int) istructs.IStateValue { 913 return &cudRowValue{value: v.cuds[index]} 914 } 915 916 type cudRowValue struct { 917 baseStateValue 918 value istructs.ICUDRow 919 } 920 921 func (v *cudRowValue) AsInt32(name string) int32 { return v.value.AsInt32(name) } 922 func (v *cudRowValue) AsInt64(name string) int64 { return v.value.AsInt64(name) } 923 func (v *cudRowValue) AsFloat32(name string) float32 { return v.value.AsFloat32(name) } 924 func (v *cudRowValue) AsFloat64(name string) float64 { return v.value.AsFloat64(name) } 925 func (v *cudRowValue) AsBytes(name string) []byte { return v.value.AsBytes(name) } 926 func (v *cudRowValue) AsString(name string) string { return v.value.AsString(name) } 927 func (v *cudRowValue) AsQName(name string) appdef.QName { return v.value.AsQName(name) } 928 func (v *cudRowValue) AsBool(name string) bool { 929 if name == Field_IsNew { 930 return v.value.IsNew() 931 } 932 return v.value.AsBool(name) 933 } 934 func (v *cudRowValue) AsRecordID(name string) istructs.RecordID { 935 return v.value.AsRecordID(name) 936 } 937 938 type baseStateValue struct{} 939 940 func (v *baseStateValue) AsInt32(string) int32 { panic(errNotImplemented) } 941 func (v *baseStateValue) AsInt64(string) int64 { panic(errNotImplemented) } 942 func (v *baseStateValue) AsFloat32(string) float32 { panic(errNotImplemented) } 943 func (v *baseStateValue) AsFloat64(string) float64 { panic(errNotImplemented) } 944 func (v *baseStateValue) AsBytes(string) []byte { panic(errNotImplemented) } 945 func (v *baseStateValue) AsString(string) string { panic(errNotImplemented) } 946 func (v *baseStateValue) AsQName(string) appdef.QName { panic(errNotImplemented) } 947 func (v *baseStateValue) AsBool(string) bool { panic(errNotImplemented) } 948 func (v *baseStateValue) AsRecordID(string) istructs.RecordID { panic(errNotImplemented) } 949 func (v *baseStateValue) RecordIDs(bool, func(string, istructs.RecordID)) { panic(errNotImplemented) } 950 func (v *baseStateValue) FieldNames(func(string)) { panic(errNotImplemented) } 951 func (v *baseStateValue) AsRecord(string) istructs.IRecord { panic(errNotImplemented) } 952 func (v *baseStateValue) AsEvent(string) istructs.IDbEvent { panic(errNotImplemented) } 953 func (v *baseStateValue) Length() int { panic(errCurrentValueIsNotAnArray) } 954 func (v *baseStateValue) GetAsString(int) string { panic(errCurrentValueIsNotAnArray) } 955 func (v *baseStateValue) GetAsBytes(int) []byte { panic(errCurrentValueIsNotAnArray) } 956 func (v *baseStateValue) GetAsInt32(int) int32 { panic(errCurrentValueIsNotAnArray) } 957 func (v *baseStateValue) GetAsInt64(int) int64 { panic(errCurrentValueIsNotAnArray) } 958 func (v *baseStateValue) GetAsFloat32(int) float32 { panic(errCurrentValueIsNotAnArray) } 959 func (v *baseStateValue) GetAsFloat64(int) float64 { panic(errCurrentValueIsNotAnArray) } 960 func (v *baseStateValue) GetAsQName(int) appdef.QName { panic(errCurrentValueIsNotAnArray) } 961 func (v *baseStateValue) GetAsBool(int) bool { panic(errCurrentValueIsNotAnArray) } 962 func (v *baseStateValue) GetAsValue(int) istructs.IStateValue { 963 panic(errFieldByIndexIsNotAnObjectOrArray) 964 } 965 func (v *baseStateValue) AsValue(string) istructs.IStateValue { 966 panic(errFieldByNameIsNotAnObjectOrArray) 967 } 968 969 type resultKeyBuilder struct { 970 *keyBuilder 971 } 972 973 func newResultKeyBuilder() *resultKeyBuilder { 974 return &resultKeyBuilder{ 975 &keyBuilder{ 976 storage: Result, 977 }, 978 } 979 } 980 func (*resultKeyBuilder) Equals(src istructs.IKeyBuilder) bool { 981 _, ok := src.(*resultKeyBuilder) 982 return ok 983 } 984 985 type resultValueBuilder struct { 986 istructs.IStateValueBuilder 987 resultBuilder istructs.IObjectBuilder 988 } 989 990 func (c *resultValueBuilder) Equal(src istructs.IStateValueBuilder) bool { 991 if _, ok := src.(*resultValueBuilder); !ok { 992 return false 993 } 994 o1, err := c.resultBuilder.Build() 995 if err != nil { 996 panic(err) 997 } 998 o2, err := src.(*resultValueBuilder).resultBuilder.Build() 999 if err != nil { 1000 panic(err) 1001 } 1002 return reflect.DeepEqual(o1, o2) 1003 } 1004 1005 func (c *resultValueBuilder) PutInt32(name string, value int32) { 1006 c.resultBuilder.PutInt32(name, value) 1007 } 1008 1009 func (c *resultValueBuilder) PutInt64(name string, value int64) { 1010 c.resultBuilder.PutInt64(name, value) 1011 } 1012 func (c *resultValueBuilder) PutBytes(name string, value []byte) { 1013 c.resultBuilder.PutBytes(name, value) 1014 } 1015 func (c *resultValueBuilder) PutString(name, value string) { 1016 c.resultBuilder.PutString(name, value) 1017 } 1018 func (c *resultValueBuilder) PutBool(name string, value bool) { 1019 c.resultBuilder.PutBool(name, value) 1020 } 1021 func (c *resultValueBuilder) PutChars(name string, value string) { 1022 c.resultBuilder.PutChars(name, value) 1023 } 1024 func (c *resultValueBuilder) PutFloat32(name string, value float32) { 1025 c.resultBuilder.PutFloat32(name, value) 1026 } 1027 func (c *resultValueBuilder) PutFloat64(name string, value float64) { 1028 c.resultBuilder.PutFloat64(name, value) 1029 } 1030 func (c *resultValueBuilder) PutQName(name string, value appdef.QName) { 1031 c.resultBuilder.PutQName(name, value) 1032 } 1033 func (c *resultValueBuilder) PutNumber(name string, value float64) { 1034 c.resultBuilder.PutNumber(name, value) 1035 } 1036 func (c *resultValueBuilder) PutRecordID(name string, value istructs.RecordID) { 1037 c.resultBuilder.PutRecordID(name, value) 1038 } 1039 1040 type wsTypeKey struct { 1041 wsid istructs.WSID 1042 appQName istructs.AppQName 1043 } 1044 1045 type wsTypeVailidator struct { 1046 appStructsFunc AppStructsFunc 1047 wsidKinds map[wsTypeKey]appdef.QName 1048 } 1049 1050 func newWsTypeValidator(appStructsFunc AppStructsFunc) wsTypeVailidator { 1051 return wsTypeVailidator{ 1052 appStructsFunc: appStructsFunc, 1053 wsidKinds: make(map[wsTypeKey]appdef.QName), 1054 } 1055 } 1056 1057 // Returns NullQName if not found 1058 func (v *wsTypeVailidator) getWSIDKind(wsid istructs.WSID, entity appdef.QName) (appdef.QName, error) { 1059 key := wsTypeKey{wsid: wsid, appQName: v.appStructsFunc().AppQName()} 1060 wsKind, ok := v.wsidKinds[key] 1061 if !ok { 1062 wsDesc, err := v.appStructsFunc().Records().GetSingleton(wsid, qNameCDocWorkspaceDescriptor) 1063 if err != nil { 1064 // notest 1065 return appdef.NullQName, err 1066 } 1067 if wsDesc.QName() == appdef.NullQName { 1068 if v.appStructsFunc().AppDef().WorkspaceByDescriptor(entity) != nil { 1069 // Special case. sys.CreateWorkspace creates WSKind while WorkspaceDescriptor is not applied yet. 1070 return entity, nil 1071 } 1072 return appdef.NullQName, fmt.Errorf("%w: %d", errWorkspaceDescriptorNotFound, wsid) 1073 } 1074 wsKind = wsDesc.AsQName(field_WSKind) 1075 if len(v.wsidKinds) < wsidTypeValidatorCacheSize { 1076 v.wsidKinds[key] = wsKind 1077 } 1078 } 1079 return wsKind, nil 1080 } 1081 1082 func (v *wsTypeVailidator) validate(wsid istructs.WSID, entity appdef.QName) error { 1083 if entity == qNameCDocWorkspaceDescriptor { 1084 return nil // This QName always can be read and write. Otherwise sys.CreateWorkspace is not able to create descriptor. 1085 } 1086 if wsid != istructs.NullWSID && v.appStructsFunc().Records() != nil { // NullWSID only stores actualizer offsets 1087 wsKind, err := v.getWSIDKind(wsid, entity) 1088 if err != nil { 1089 // notest 1090 return err 1091 } 1092 ws := v.appStructsFunc().AppDef().WorkspaceByDescriptor(wsKind) 1093 if ws == nil { 1094 // notest 1095 return errDescriptorForUndefinedWorkspace 1096 } 1097 if ws.TypeByName(entity) == nil { 1098 return typeIsNotDefinedInWorkspaceWithDescriptor(entity, wsKind) 1099 } 1100 } 1101 return nil 1102 } 1103 1104 type baseValueBuilder struct { 1105 istructs.IStateValueBuilder 1106 } 1107 1108 func (b *baseValueBuilder) Equal(src istructs.IStateValueBuilder) bool { 1109 return false 1110 } 1111 func (b *baseValueBuilder) PutInt32(name string, value int32) { panic(errUndefined(name)) } 1112 func (b *baseValueBuilder) PutInt64(name string, value int64) { panic(errUndefined(name)) } 1113 func (b *baseValueBuilder) PutBytes(name string, value []byte) { panic(errUndefined(name)) } 1114 func (b *baseValueBuilder) PutString(name, value string) { panic(errUndefined(name)) } 1115 func (b *baseValueBuilder) PutBool(name string, value bool) { panic(errUndefined(name)) } 1116 func (b *baseValueBuilder) PutChars(name string, value string) { panic(errUndefined(name)) } 1117 func (b *baseValueBuilder) PutFloat32(name string, value float32) { panic(errUndefined(name)) } 1118 func (b *baseValueBuilder) PutFloat64(name string, value float64) { panic(errUndefined(name)) } 1119 func (b *baseValueBuilder) PutQName(name string, value appdef.QName) { panic(errUndefined(name)) } 1120 func (b *baseValueBuilder) PutNumber(name string, value float64) { panic(errUndefined(name)) } 1121 func (b *baseValueBuilder) PutRecordID(name string, value istructs.RecordID) { 1122 panic(errUndefined(name)) 1123 } 1124 func (b *baseValueBuilder) BuildValue() istructs.IStateValue { 1125 panic(errNotImplemented) 1126 }