github.com/ravendb/ravendb-go-client@v0.0.0-20240229102137-4474ee7aa0fa/document_session_cluster_transaction.go (about) 1 package ravendb 2 3 import ( 4 "reflect" 5 ) 6 7 type ClusterTransactionOperations struct { 8 session *InMemoryDocumentSessionOperations 9 state map[string]*CompareExchangeSessionValue 10 } 11 12 func (cto *ClusterTransactionOperations) GetNumberOfTrackedCompareExchangeValues() int { 13 if nil == cto.state { 14 return 0 15 } 16 17 return len(cto.state) 18 } 19 20 func (cto *ClusterTransactionOperations) IsTracked(key string) bool { 21 _, exists := cto.tryGetCompareExchangeValueFromSession(key) 22 return exists 23 } 24 25 func (cto *ClusterTransactionOperations) tryGetCompareExchangeValueFromSession(key string) (*CompareExchangeSessionValue, bool) { 26 value, exists := cto.state[key] 27 return value, exists 28 } 29 30 func (cto *ClusterTransactionOperations) updateState(key string, index int64) (*CompareExchangeSessionValue, bool) { 31 value, exists := cto.tryGetCompareExchangeValueFromSession(key) 32 33 if exists == false { 34 return nil, false 35 } 36 37 value.UpdateState(index) 38 return value, true 39 } 40 41 func (cto *ClusterTransactionOperations) Clear() { 42 cto.state = make(map[string]*CompareExchangeSessionValue) 43 } 44 45 func (cto *ClusterTransactionOperations) CreateCompareExchangeValue(key string, item interface{}) (interface{}, error) { 46 if len(key) == 0 { 47 return nil, newIllegalArgumentError("Key cannot be null or empty") 48 } 49 50 var exists bool 51 var value *CompareExchangeSessionValue 52 value, exists = cto.tryGetCompareExchangeValueFromSession(key) 53 54 if exists == false { 55 var err error 56 value, err = NewCompareExchangeSessionValue(key, 0, compareExchangeValueStateNone) 57 if err != nil { 58 return nil, err 59 } 60 cto.state[key] = value 61 } 62 63 return value.Create(item) 64 } 65 66 func (cto *ClusterTransactionOperations) prepareCompareExchangeEntities(result *saveChangesData) error { 67 if len(cto.state) == 0 { 68 return nil 69 } 70 71 for _, value := range cto.state { 72 command, err := value.GetCommand(cto.session) 73 if err != nil { 74 return err 75 } 76 if command == nil { 77 continue 78 } 79 80 result.addSessionCommandData(command) 81 } 82 83 return nil 84 } 85 86 func (cto *ClusterTransactionOperations) GetCompareExchangeValue(clazz reflect.Type, key string) (*CompareExchangeValue, error) { 87 return cto.getCompareExchangeValueInternal(clazz, key) 88 89 } 90 91 func (cto *ClusterTransactionOperations) GetCompareExchangeValuesWithKeys(clazz reflect.Type, keys []string) (map[string]*CompareExchangeValue, error) { 92 return cto.getCompareExchangeValuesInternalWithKeys(clazz, keys) 93 } 94 95 func (cto *ClusterTransactionOperations) GetCompareExchangeValues(clazz reflect.Type, startsWith string, start int, pageSize int) (map[string]*CompareExchangeValue, error) { 96 return cto.getCompareExchangeValuesInternal(clazz, startsWith, start, pageSize) 97 } 98 func (cto *ClusterTransactionOperations) getCompareExchangeValuesInternal(clazz reflect.Type, startsWith string, start int, pageSize int) (map[string]*CompareExchangeValue, error) { 99 cto.session.incrementRequestCount() 100 101 operation, err := NewGetCompareExchangeValuesOperation(clazz, startsWith, start, pageSize) 102 if err != nil { 103 return nil, err 104 } 105 err = cto.session.GetOperations().Send(operation, cto.session.sessionInfo) 106 if err != nil { 107 return nil, err 108 } 109 110 operationResult := operation.Command.Result 111 results := make(map[string]*CompareExchangeValue) 112 113 for _, value := range operationResult { 114 115 sessionValue, err := cto.registerCompareExchangeValue(value) 116 if err != nil { 117 return nil, err 118 } 119 resultValue, err := sessionValue.GetValue(clazz, cto.session) 120 if err != nil { 121 return nil, err 122 } 123 124 results[value.GetKey()] = resultValue 125 } 126 127 return results, nil 128 } 129 130 func (cto *ClusterTransactionOperations) getCompareExchangeValuesInternalWithKeys(clazz reflect.Type, keys []string) (map[string]*CompareExchangeValue, error) { 131 results, notTracked, err := cto.getCompareExchangeValuesWithKeysFromSessionInternal(clazz, keys) 132 if err != nil { 133 return nil, err 134 } 135 136 if notTracked == nil || len(notTracked) == 0 { 137 return results, nil 138 } 139 140 cto.session.incrementRequestCount() 141 142 operation, err := NewGetCompareExchangeValuesOperationWithKeys(clazz, notTracked) 143 if err != nil { 144 return nil, err 145 } 146 err = cto.session.GetOperations().Send(operation, cto.session.sessionInfo) 147 if err != nil { 148 return nil, err 149 } 150 151 operationResult := operation.Command.Result 152 153 for _, key := range notTracked { 154 value, exists := operationResult[key] 155 156 if exists == false || value == nil { 157 cto.registerMissingCompareExchangeValue(key) 158 results[key] = nil 159 continue 160 } 161 162 sessionValue, err := cto.registerCompareExchangeValue(value) 163 if err != nil { 164 return nil, err 165 } 166 resultValue, err := sessionValue.GetValue(clazz, cto.session) 167 if err != nil { 168 return nil, err 169 } 170 171 results[value.GetKey()] = resultValue 172 } 173 174 return results, nil 175 } 176 177 func (cto *ClusterTransactionOperations) getCompareExchangeValueInternal(clazz reflect.Type, key string) (*CompareExchangeValue, error) { 178 v, notTracked := cto.getCompareExchangeValueFromSessionInternal(clazz, key) 179 if notTracked == false { 180 return v, nil 181 } 182 183 cto.session.incrementRequestCount() 184 185 operation, err := NewGetCompareExchangeValueOperation(clazz, key) 186 if err != nil { 187 return nil, err 188 } 189 190 err = cto.session.GetOperations().Send(operation, cto.session.sessionInfo) 191 if err != nil { 192 return nil, err 193 } 194 195 value := operation.Command.Result 196 if value == nil { 197 cto.registerMissingCompareExchangeValue(key) 198 return nil, nil 199 } 200 201 sessionValue, err := cto.registerCompareExchangeValue(value) 202 203 if err == nil && sessionValue != nil { 204 return sessionValue.GetValue(clazz, cto.session) 205 } 206 207 return nil, err 208 } 209 210 func (cto *ClusterTransactionOperations) registerCompareExchangeValue(value *CompareExchangeValue) (*CompareExchangeSessionValue, error) { 211 if cto.session.noTracking { 212 return NewCompareExchangeSessionValueWithValue(value) 213 } 214 215 var err error 216 sesionValue, exists := cto.state[value.GetKey()] 217 218 if exists == false || sesionValue == nil { 219 sesionValue, err = NewCompareExchangeSessionValueWithValue(value) 220 if err != nil { 221 return nil, err 222 } 223 cto.state[value.GetKey()] = sesionValue 224 return sesionValue, nil 225 } 226 227 err = sesionValue.UpdateValue(value) 228 229 return sesionValue, err 230 } 231 232 func (cto *ClusterTransactionOperations) registerMissingCompareExchangeValue(key string) (*CompareExchangeSessionValue, error) { 233 value, err := NewCompareExchangeSessionValue(key, -1, exchangeValueStateMissing) 234 235 if err != nil { 236 return nil, err 237 } 238 239 if cto.session.noTracking { 240 return value, nil 241 } 242 243 cto.state[key] = value 244 return value, nil 245 } 246 247 func (cto *ClusterTransactionOperations) getCompareExchangeValueFromSessionInternal(clazz reflect.Type, key string) (compareExchangeValue *CompareExchangeValue, notTracked bool) { 248 result, exist := cto.tryGetCompareExchangeValueFromSession(key) 249 250 if exist == false { 251 return nil, true 252 } 253 254 //we've already deserialized, maybe except situation when user wants get deriative type? 255 256 return result.value, false 257 } 258 259 func (cto *ClusterTransactionOperations) getCompareExchangeValuesWithKeysFromSessionInternal(clazz reflect.Type, keys []string) (map[string]*CompareExchangeValue, []string, error) { 260 var results map[string]*CompareExchangeValue 261 results = make(map[string]*CompareExchangeValue) 262 var notTracked []string 263 264 if keys == nil || len(keys) == 0 { 265 return results, nil, nil 266 } 267 268 for _, key := range keys { 269 cev, exists := cto.tryGetCompareExchangeValueFromSession(key) 270 271 if exists { 272 val, err := cev.GetValue(clazz, cto.session) 273 if err != nil { 274 return results, nil, err 275 } 276 results[key] = val 277 continue 278 } 279 280 notTracked = append(notTracked, key) 281 } 282 283 return results, notTracked, nil 284 } 285 286 func (cto *ClusterTransactionOperations) DeleteCompareExchangeValue(item *CompareExchangeValue) error { 287 if item == nil { 288 return newIllegalArgumentError("Item cannot be null") 289 } 290 291 sessionValue, exists := cto.tryGetCompareExchangeValueFromSession(item.GetKey()) 292 if exists == false { 293 sessionValue, _ = NewCompareExchangeSessionValue(item.GetKey(), 0, compareExchangeValueStateNone) 294 cto.state[item.GetKey()] = sessionValue 295 } 296 297 sessionValue.Delete(item.GetIndex()) 298 return nil 299 } 300 301 func (cto *ClusterTransactionOperations) DeleteCompareExchangeValueByKey(key string, index int64) error { 302 if len(key) == 0 { 303 return newIllegalStateError("Key cannot be null nor empty") 304 } 305 306 sessionValue, exists := cto.tryGetCompareExchangeValueFromSession(key) 307 if exists == false { 308 sessionValue, _ = NewCompareExchangeSessionValue(key, 0, compareExchangeValueStateNone) 309 cto.state[key] = sessionValue 310 } 311 312 sessionValue.Delete(index) 313 return nil 314 }