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  }