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  }