github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/state/safestate/impl.go (about)

     1  /*
     2   * Copyright (c) 2024-present unTill Software Development Group B. V.
     3   * @author Michael Saigachenko
     4   */
     5  package safestate
     6  
     7  import (
     8  	"errors"
     9  
    10  	"github.com/voedger/voedger/pkg/appdef"
    11  	"github.com/voedger/voedger/pkg/istructs"
    12  	"github.com/voedger/voedger/pkg/state"
    13  	safe "github.com/voedger/voedger/pkg/state/isafestateapi"
    14  )
    15  
    16  type safeState struct {
    17  	state         state.IState
    18  	keyBuilders   []istructs.IStateKeyBuilder
    19  	keys          []istructs.IKey
    20  	values        []istructs.IStateValue
    21  	valueBuilders []istructs.IStateValueBuilder
    22  }
    23  
    24  func (s *safeState) KeyBuilder(storage, entityFull string) safe.TKeyBuilder {
    25  
    26  	storageQname := appdef.MustParseQName(storage)
    27  	var entityQname appdef.QName
    28  	if entityFull == "" {
    29  		entityQname = appdef.NullQName
    30  	} else {
    31  		entityFullQname := appdef.MustParseFullQName(entityFull)
    32  		entityLocalPkg := s.state.PackageLocalName(entityFullQname.PkgPath())
    33  
    34  		if entityLocalPkg == "" {
    35  			panic(errors.New("undefined package: " + entityFullQname.PkgPath()))
    36  		}
    37  
    38  		entityQname = appdef.NewQName(entityLocalPkg, entityFullQname.Entity())
    39  	}
    40  	skb, err := s.state.KeyBuilder(storageQname, entityQname)
    41  	if err != nil {
    42  		panic(err)
    43  	}
    44  	kb := safe.TKeyBuilder(len(s.keyBuilders))
    45  	s.keyBuilders = append(s.keyBuilders, skb)
    46  	return kb
    47  }
    48  
    49  func (s *safeState) kb(key safe.TKeyBuilder) istructs.IStateKeyBuilder {
    50  	if int(key) >= len(s.keyBuilders) {
    51  		panic(PanicIncorrectKeyBuilder)
    52  	}
    53  	return s.keyBuilders[key]
    54  }
    55  
    56  func (s *safeState) MustGetValue(key safe.TKeyBuilder) safe.TValue {
    57  	sv, err := s.state.MustExist(s.kb(key))
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  	v := safe.TValue(len(s.values))
    62  	s.values = append(s.values, sv)
    63  	return v
    64  }
    65  
    66  func (s *safeState) QueryValue(key safe.TKeyBuilder) (safe.TValue, bool) {
    67  	sv, ok, err := s.state.CanExist(s.kb(key))
    68  	if err != nil {
    69  		panic(err)
    70  	}
    71  	if ok {
    72  		v := safe.TValue(len(s.values))
    73  		s.values = append(s.values, sv)
    74  		return v, true
    75  	}
    76  	return 0, false
    77  }
    78  
    79  func (s *safeState) NewValue(key safe.TKeyBuilder) safe.TIntent {
    80  	svb, err := s.state.NewValue(s.kb(key))
    81  	if err != nil {
    82  		panic(err)
    83  	}
    84  	v := safe.TIntent(len(s.valueBuilders))
    85  	s.valueBuilders = append(s.valueBuilders, svb)
    86  	return v
    87  }
    88  
    89  func (s *safeState) UpdateValue(key safe.TKeyBuilder, existingValue safe.TValue) safe.TIntent {
    90  	svb, err := s.state.UpdateValue(s.kb(key), s.value(existingValue))
    91  	if err != nil {
    92  		panic(err)
    93  	}
    94  	v := safe.TIntent(len(s.valueBuilders))
    95  	s.valueBuilders = append(s.valueBuilders, svb)
    96  	return v
    97  }
    98  
    99  func (s *safeState) ReadValues(kb safe.TKeyBuilder, callback func(safe.TKey, safe.TValue)) {
   100  	first := true
   101  	safeKey := safe.TKey(len(s.keys))
   102  	safeValue := safe.TValue(len(s.values))
   103  	err := s.state.Read(s.kb(kb), func(key istructs.IKey, value istructs.IStateValue) error {
   104  		if first {
   105  			s.keys = append(s.keys, key)
   106  			s.values = append(s.values, value)
   107  			first = false
   108  		} else { // replace
   109  			s.keys[safeKey] = key
   110  			s.values[safeValue] = value
   111  		}
   112  		callback(safeKey, safeValue)
   113  		return nil
   114  	})
   115  	if err != nil {
   116  		panic(err)
   117  	}
   118  	//TODO: cleanup keys and values
   119  }
   120  
   121  // Key Builder
   122  func (s *safeState) KeyBuilderPutInt32(key safe.TKeyBuilder, name string, value int32) {
   123  	s.kb(key).PutInt32(name, value)
   124  }
   125  
   126  func (s *safeState) KeyBuilderPutInt64(key safe.TKeyBuilder, name string, value int64) {
   127  	s.kb(key).PutInt64(name, value)
   128  }
   129  
   130  func (s *safeState) KeyBuilderPutFloat32(key safe.TKeyBuilder, name string, value float32) {
   131  	s.kb(key).PutFloat32(name, value)
   132  }
   133  
   134  func (s *safeState) KeyBuilderPutFloat64(key safe.TKeyBuilder, name string, value float64) {
   135  	s.kb(key).PutFloat64(name, value)
   136  }
   137  
   138  func (s *safeState) KeyBuilderPutString(key safe.TKeyBuilder, name string, value string) {
   139  	s.kb(key).PutString(name, value)
   140  }
   141  
   142  func (s *safeState) KeyBuilderPutBytes(key safe.TKeyBuilder, name string, value []byte) {
   143  	s.kb(key).PutBytes(name, value)
   144  }
   145  
   146  func (s *safeState) KeyBuilderPutQName(key safe.TKeyBuilder, name string, value safe.QName) {
   147  	localpkgName := s.state.PackageLocalName(value.FullPkgName)
   148  	s.kb(key).PutQName(name, appdef.NewQName(localpkgName, value.Entity))
   149  }
   150  
   151  func (s *safeState) KeyBuilderPutBool(key safe.TKeyBuilder, name string, value bool) {
   152  	s.kb(key).PutBool(name, value)
   153  }
   154  
   155  // Value
   156  
   157  func (s *safeState) ValueAsValue(v safe.TValue, name string) (result safe.TValue) {
   158  	sv := s.value(v).AsValue(name)
   159  	result = safe.TValue(len(s.values))
   160  	s.values = append(s.values, sv)
   161  	return result
   162  }
   163  
   164  func (s *safeState) ValueAsInt32(v safe.TValue, name string) int32 {
   165  	return s.value(v).AsInt32(name)
   166  }
   167  
   168  func (s *safeState) ValueAsInt64(v safe.TValue, name string) int64 {
   169  	return s.value(v).AsInt64(name)
   170  }
   171  
   172  func (s *safeState) ValueAsFloat32(v safe.TValue, name string) float32 {
   173  	return s.value(v).AsFloat32(name)
   174  }
   175  
   176  func (s *safeState) ValueAsFloat64(v safe.TValue, name string) float64 {
   177  	return s.value(v).AsFloat64(name)
   178  }
   179  
   180  func (s *safeState) ValueAsBytes(v safe.TValue, name string) []byte {
   181  	return s.value(v).AsBytes(name)
   182  }
   183  
   184  func (s *safeState) ValueAsQName(v safe.TValue, name string) safe.QName {
   185  	qname := s.value(v).AsQName(name)
   186  	return safe.QName{
   187  		FullPkgName: s.state.PackageFullPath(qname.Pkg()),
   188  		Entity:      qname.Entity(),
   189  	}
   190  }
   191  
   192  func (s *safeState) ValueAsBool(v safe.TValue, name string) bool {
   193  	return s.value(v).AsBool(name)
   194  }
   195  
   196  func (s *safeState) ValueAsString(v safe.TValue, name string) string {
   197  	return s.value(v).AsString(name)
   198  }
   199  
   200  func (s *safeState) ValueLen(v safe.TValue) int {
   201  	return s.value(v).Length()
   202  }
   203  
   204  func (s *safeState) ValueGetAsValue(v safe.TValue, index int) (result safe.TValue) {
   205  	sv := s.value(v).GetAsValue(index)
   206  	result = safe.TValue(len(s.values))
   207  	s.values = append(s.values, sv)
   208  	return result
   209  }
   210  
   211  func (s *safeState) ValueGetAsInt32(v safe.TValue, index int) int32 {
   212  	return s.value(v).GetAsInt32(index)
   213  }
   214  
   215  func (s *safeState) ValueGetAsInt64(v safe.TValue, index int) int64 {
   216  	return s.value(v).GetAsInt64(index)
   217  }
   218  
   219  func (s *safeState) ValueGetAsFloat32(v safe.TValue, index int) float32 {
   220  	return s.value(v).GetAsFloat32(index)
   221  }
   222  
   223  func (s *safeState) ValueGetAsFloat64(v safe.TValue, index int) float64 {
   224  	return s.value(v).GetAsFloat64(index)
   225  }
   226  
   227  func (s *safeState) ValueGetAsBytes(v safe.TValue, index int) []byte {
   228  	return s.value(v).GetAsBytes(index)
   229  }
   230  
   231  func (s *safeState) ValueGetAsQName(v safe.TValue, index int) safe.QName {
   232  	qname := s.value(v).GetAsQName(index)
   233  	return safe.QName{
   234  		FullPkgName: s.state.PackageFullPath(qname.Pkg()),
   235  		Entity:      qname.Entity(),
   236  	}
   237  }
   238  
   239  func (s *safeState) ValueGetAsBool(v safe.TValue, index int) bool {
   240  	return s.value(v).GetAsBool(index)
   241  }
   242  
   243  func (s *safeState) ValueGetAsString(v safe.TValue, index int) string {
   244  	return s.value(v).GetAsString(index)
   245  }
   246  
   247  func (s *safeState) value(v safe.TValue) istructs.IStateValue {
   248  	if int(v) >= len(s.values) {
   249  		panic(PanicIncorrectValue)
   250  	}
   251  	return s.values[v]
   252  }
   253  
   254  // Intent
   255  
   256  func (s *safeState) vb(v safe.TIntent) istructs.IStateValueBuilder {
   257  	if int(v) >= len(s.valueBuilders) {
   258  		panic(PanicIncorrectIntent)
   259  	}
   260  	return s.valueBuilders[v]
   261  }
   262  
   263  func (s *safeState) IntentPutInt64(v safe.TIntent, name string, value int64) {
   264  	s.vb(v).PutInt64(name, value)
   265  }
   266  
   267  func (s *safeState) IntentPutBool(v safe.TIntent, name string, value bool) {
   268  	s.vb(v).PutBool(name, value)
   269  }
   270  
   271  func (s *safeState) IntentPutString(v safe.TIntent, name string, value string) {
   272  	s.vb(v).PutString(name, value)
   273  }
   274  
   275  func (s *safeState) IntentPutBytes(v safe.TIntent, name string, value []byte) {
   276  	s.vb(v).PutBytes(name, value)
   277  }
   278  
   279  func (s *safeState) IntentPutQName(v safe.TIntent, name string, value safe.QName) {
   280  	localpkgName := s.state.PackageLocalName(value.FullPkgName)
   281  	s.vb(v).PutQName(name, appdef.NewQName(localpkgName, value.Entity))
   282  }
   283  
   284  func (s *safeState) IntentPutInt32(v safe.TIntent, name string, value int32) {
   285  	s.vb(v).PutInt32(name, value)
   286  }
   287  
   288  func (s *safeState) IntentPutFloat32(v safe.TIntent, name string, value float32) {
   289  	s.vb(v).PutFloat32(name, value)
   290  }
   291  
   292  func (s *safeState) IntentPutFloat64(v safe.TIntent, name string, value float64) {
   293  	s.vb(v).PutFloat64(name, value)
   294  }
   295  
   296  // Key
   297  
   298  func (s *safeState) key(k safe.TKey) istructs.IKey {
   299  	if int(k) >= len(s.keys) {
   300  		panic(PanicIncorrectKey)
   301  	}
   302  	return s.keys[k]
   303  }
   304  
   305  func (s *safeState) KeyAsInt32(k safe.TKey, name string) int32 {
   306  	return s.key(k).AsInt32(name)
   307  }
   308  
   309  func (s *safeState) KeyAsInt64(k safe.TKey, name string) int64 {
   310  	return s.key(k).AsInt64(name)
   311  }
   312  
   313  func (s *safeState) KeyAsFloat32(k safe.TKey, name string) float32 {
   314  	return s.key(k).AsFloat32(name)
   315  }
   316  
   317  func (s *safeState) KeyAsFloat64(k safe.TKey, name string) float64 {
   318  	return s.key(k).AsFloat64(name)
   319  }
   320  
   321  func (s *safeState) KeyAsBytes(k safe.TKey, name string) []byte {
   322  	return s.key(k).AsBytes(name)
   323  }
   324  
   325  func (s *safeState) KeyAsString(k safe.TKey, name string) string {
   326  	return s.key(k).AsString(name)
   327  }
   328  
   329  func (s *safeState) KeyAsQName(k safe.TKey, name string) safe.QName {
   330  	qname := s.key(k).AsQName(name)
   331  	return safe.QName{
   332  		FullPkgName: s.state.PackageFullPath(qname.Pkg()),
   333  		Entity:      qname.Entity(),
   334  	}
   335  }
   336  
   337  func (s *safeState) KeyAsBool(k safe.TKey, name string) bool {
   338  	return s.key(k).AsBool(name)
   339  }