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 }