github.com/altipla-consulting/ravendb-go-client@v0.1.3/get_revision_operation.go (about)

     1  package ravendb
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  // GetRevisionOperation represents "get revisions" operation
     8  type GetRevisionOperation struct {
     9  	session *InMemoryDocumentSessionOperations
    10  
    11  	result  *JSONArrayResult
    12  	command *GetRevisionsCommand
    13  }
    14  
    15  func NewGetRevisionOperationWithChangeVectors(session *InMemoryDocumentSessionOperations, changeVectors []string) *GetRevisionOperation {
    16  	return &GetRevisionOperation{
    17  		session: session,
    18  		command: NewGetRevisionsCommand(changeVectors, false),
    19  	}
    20  }
    21  
    22  func NewGetRevisionOperationRange(session *InMemoryDocumentSessionOperations, id string, start int, pageSize int, metadataOnly bool) (*GetRevisionOperation, error) {
    23  	if session == nil {
    24  		return nil, newIllegalArgumentError("session cannot be null")
    25  	}
    26  	if id == "" {
    27  		return nil, newIllegalArgumentError("Id cannot be null")
    28  	}
    29  	return &GetRevisionOperation{
    30  		session: session,
    31  		command: NewGetRevisionsCommandRange(id, start, pageSize, metadataOnly),
    32  	}, nil
    33  }
    34  
    35  func (o *GetRevisionOperation) createRequest() (*GetRevisionsCommand, error) {
    36  	return o.command, nil
    37  }
    38  
    39  func (o *GetRevisionOperation) setResult(result *JSONArrayResult) {
    40  	o.result = result
    41  }
    42  
    43  // Note: in Java it's getRevision
    44  func (o *GetRevisionOperation) GetRevisionWithDocument(result interface{}, document map[string]interface{}) error {
    45  	if document == nil {
    46  		return nil
    47  	}
    48  
    49  	var metadata map[string]interface{}
    50  	id := ""
    51  	if v, ok := document[MetadataKey]; ok {
    52  		metadata = v.(map[string]interface{})
    53  		id, _ = jsonGetAsText(metadata, MetadataID)
    54  	}
    55  	var changeVector *string
    56  
    57  	if metadata != nil {
    58  		changeVector = jsonGetAsTextPointer(metadata, MetadataChangeVector)
    59  	}
    60  	err := o.session.getEntityToJSON().convertToEntity2(result, id, document)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	documentInfo := &documentInfo{}
    65  	documentInfo.id = id
    66  	documentInfo.changeVector = changeVector
    67  	documentInfo.document = document
    68  	documentInfo.metadata = metadata
    69  	documentInfo.setEntity(result)
    70  	setDocumentInfo(&o.session.documentsByEntity, documentInfo)
    71  	return nil
    72  }
    73  
    74  // results should be *[]*<type>
    75  func (o *GetRevisionOperation) GetRevisionsFor(results interface{}) error {
    76  
    77  	a := o.result.getResults()
    78  	if len(a) == 0 {
    79  		return nil
    80  	}
    81  	// TODO: optimize by creating pre-allocated slice of size len(a)
    82  	slice, err := makeSliceForResults(results)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	sliceElemType := reflect.TypeOf(results).Elem().Elem()
    87  
    88  	tmpSlice := slice
    89  	for _, document := range a {
    90  		// creates a pointer to value e.g. **Foo
    91  		resultV := reflect.New(sliceElemType)
    92  		err = o.GetRevisionWithDocument(resultV.Interface(), document)
    93  		if err != nil {
    94  			return err
    95  		}
    96  		// append *Foo to the slice
    97  		tmpSlice = reflect.Append(tmpSlice, resultV.Elem())
    98  	}
    99  
   100  	if slice != tmpSlice {
   101  		slice.Set(tmpSlice)
   102  	}
   103  	return nil
   104  }
   105  
   106  func (o *GetRevisionOperation) GetRevisionsMetadataFor() []*MetadataAsDictionary {
   107  	resultsCount := len(o.result.getResults())
   108  	results := make([]*MetadataAsDictionary, resultsCount)
   109  	for i := 0; i < resultsCount; i++ {
   110  		document := o.result.getResults()[i]
   111  
   112  		var metadata map[string]interface{}
   113  		if v, ok := document[MetadataKey]; ok {
   114  			metadata = v.(map[string]interface{})
   115  		}
   116  		results[i] = NewMetadataAsDictionaryWithSource(metadata)
   117  	}
   118  	return results
   119  }
   120  
   121  func (o *GetRevisionOperation) GetRevision(result interface{}) error {
   122  	if o.result == nil {
   123  		return nil
   124  	}
   125  
   126  	document := o.result.getResults()[0]
   127  	return o.GetRevisionWithDocument(result, document)
   128  }
   129  
   130  // result should be map[string]<type>
   131  func (o *GetRevisionOperation) GetRevisions(results interface{}) error {
   132  	// Maybe: Java uses case-insensitive keys, but keys are change vectors
   133  	// so that shouldn't matter
   134  
   135  	rv := reflect.ValueOf(results)
   136  	elemType, ok := isMapStringToPtrStruct(rv.Type())
   137  	if !ok {
   138  		return newIllegalArgumentError("results should be of type map[string]*<struct>, is %T", results)
   139  	}
   140  
   141  	for i := 0; i < len(o.command.GetChangeVectors()); i++ {
   142  		changeVector := o.command.GetChangeVectors()[i]
   143  		if changeVector == "" {
   144  			continue
   145  		}
   146  
   147  		v := o.result.getResults()[i]
   148  		// resultV is **Foo
   149  		resultV := reflect.New(elemType)
   150  		err := o.GetRevisionWithDocument(resultV.Interface(), v)
   151  		if err != nil {
   152  			return err
   153  		}
   154  		key := reflect.ValueOf(changeVector)
   155  		rv.SetMapIndex(key, resultV.Elem())
   156  	}
   157  
   158  	return nil
   159  }