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 }