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

     1  package ravendb
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  type LoadStartingWithOperation struct {
     9  	_session *InMemoryDocumentSessionOperations
    10  
    11  	_startWith  string
    12  	_matches    string
    13  	_start      int
    14  	_pageSize   int
    15  	_exclude    string
    16  	_startAfter string
    17  
    18  	_returnedIds []string
    19  
    20  	Command *GetDocumentsCommand
    21  }
    22  
    23  func NewLoadStartingWithOperation(session *InMemoryDocumentSessionOperations) *LoadStartingWithOperation {
    24  	return &LoadStartingWithOperation{
    25  		_session: session,
    26  	}
    27  }
    28  
    29  func (o *LoadStartingWithOperation) createRequest() (*GetDocumentsCommand, error) {
    30  	if err := o._session.incrementRequestCount(); err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	var err error
    35  	o.Command, err = NewGetDocumentsCommandFull(o._startWith, o._startAfter, o._matches, o._exclude, o._start, o._pageSize, false)
    36  	return o.Command, err
    37  }
    38  
    39  func (o *LoadStartingWithOperation) withStartWith(idPrefix string) {
    40  	o.withStartWithFull(idPrefix, "", 0, 0, "", "")
    41  }
    42  
    43  func (o *LoadStartingWithOperation) withStartWithAndMatches(idPrefix string, matches string) {
    44  	o.withStartWithFull(idPrefix, matches, 0, 0, "", "")
    45  }
    46  
    47  func (o *LoadStartingWithOperation) withStartWithFull(idPrefix string, matches string, start int, pageSize int, exclude string, startAfter string) {
    48  	o._startWith = idPrefix
    49  	o._matches = matches
    50  	o._start = start
    51  	o._pageSize = pageSize
    52  	o._exclude = exclude
    53  	o._startAfter = startAfter
    54  }
    55  
    56  func (o *LoadStartingWithOperation) setResult(result *GetDocumentsResult) {
    57  	documents := result.Results
    58  
    59  	for _, document := range documents {
    60  		newDocumentInfo := getNewDocumentInfo(document)
    61  		o._session.documentsByID.add(newDocumentInfo)
    62  		o._returnedIds = append(o._returnedIds, newDocumentInfo.id)
    63  	}
    64  }
    65  
    66  // results must be *[]*struct. If *results is nil, we create it
    67  func (o *LoadStartingWithOperation) getDocuments(results interface{}) error {
    68  	//fmt.Printf("type of results: %T\n", results)
    69  	rt := reflect.TypeOf(results)
    70  
    71  	if rt.Kind() != reflect.Ptr || rt.Elem().Kind() != reflect.Slice {
    72  		return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %T. rt: %s", results, rt)
    73  	}
    74  	rv := reflect.ValueOf(results)
    75  	sliceV := rv.Elem()
    76  
    77  	// slice element should be a pointer to a struct
    78  	sliceElemPtrType := sliceV.Type().Elem()
    79  	//fmt.Printf("type of sliceElemPtrType: %s\n", sliceElemPtrType.String())
    80  
    81  	if sliceElemPtrType.Kind() != reflect.Ptr {
    82  		return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %T. sliceElemPtrType: %s", results, sliceElemPtrType)
    83  	}
    84  
    85  	sliceElemType := sliceElemPtrType.Elem()
    86  	if sliceElemType.Kind() != reflect.Struct {
    87  		return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %T. sliceElemType: %s", results, sliceElemType)
    88  	}
    89  	// if this is a pointer to nil slice, create a new slice
    90  	// otherwise we use the slice that was provided by the caller
    91  	if sliceV.IsNil() {
    92  		sliceV.Set(reflect.MakeSlice(sliceV.Type(), 0, 0))
    93  	}
    94  
    95  	sliceV2 := sliceV
    96  
    97  	//resultType := reflect.PtrTo(sliceElemPtrType)
    98  	//fmt.Printf("resultType: %s\n", resultType.String())
    99  	for _, id := range o._returnedIds {
   100  		rv := reflect.New(sliceElemPtrType)
   101  		//fmt.Printf("type of rv: %T, %s\n", rv.Interface(), rv.Type().String())
   102  		// rv is **struct and is set to value of *struct inside getDocument()
   103  		err := o.getDocument(rv.Interface(), id)
   104  		if err != nil {
   105  			return err
   106  		}
   107  		// rv.Elem() is *struct
   108  		sliceV2 = reflect.Append(sliceV2, rv.Elem())
   109  	}
   110  
   111  	if sliceV2 != sliceV {
   112  		sliceV.Set(sliceV2)
   113  	}
   114  	return nil
   115  }
   116  
   117  func (o *LoadStartingWithOperation) getDocument(result interface{}, id string) error {
   118  	// TODO: set to default value if not returning anything? Return ErrNotFound?
   119  	if o._session.IsDeleted(id) {
   120  		return nil
   121  	}
   122  
   123  	doc := o._session.documentsByID.getValue(id)
   124  	if doc != nil {
   125  		return o._session.TrackEntityInDocumentInfo(result, doc)
   126  	}
   127  
   128  	return nil
   129  }