github.com/ravendb/ravendb-go-client@v0.0.0-20240229102137-4474ee7aa0fa/lazy_starts_with_operation.go (about)

     1  package ravendb
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  )
     8  
     9  var _ ILazyOperation = &LazyStartsWithOperation{}
    10  
    11  // LazyStartsWithOperation represents lazy starts with operation
    12  type LazyStartsWithOperation struct {
    13  	idPrefix          string
    14  	matches           string
    15  	exclude           string
    16  	start             int
    17  	pageSize          int
    18  	sessionOperations *InMemoryDocumentSessionOperations
    19  	startAfter        string
    20  
    21  	// results is map[string]*Struct
    22  	queryResult   *QueryResult
    23  	requiresRetry bool
    24  	rawResult     *GetDocumentsResult
    25  }
    26  
    27  // NewLazyStartsWithOperation returns new LazyStartsWithOperation
    28  // TODO: convert to use StartsWithArgs
    29  func NewLazyStartsWithOperation(idPrefix string, matches string, exclude string, start int, pageSize int, sessionOperations *InMemoryDocumentSessionOperations, startAfter string) *LazyStartsWithOperation {
    30  	return &LazyStartsWithOperation{
    31  		idPrefix:          idPrefix,
    32  		matches:           matches,
    33  		exclude:           exclude,
    34  		start:             start,
    35  		pageSize:          pageSize,
    36  		sessionOperations: sessionOperations,
    37  		startAfter:        startAfter,
    38  	}
    39  }
    40  
    41  // needed for ILazyOperation
    42  func (o *LazyStartsWithOperation) createRequest() *getRequest {
    43  	pageSize := o.pageSize
    44  	if pageSize == 0 {
    45  		pageSize = 25
    46  	}
    47  	q := fmt.Sprintf("?startsWith=%s&matches=%s&exclude=%s&start=%d&pageSize=%d&startAfter=%s",
    48  		urlUtilsEscapeDataString(o.idPrefix),
    49  		urlUtilsEscapeDataString(o.matches),
    50  		urlUtilsEscapeDataString(o.exclude),
    51  		o.start,
    52  		pageSize,
    53  		o.startAfter)
    54  
    55  	request := &getRequest{
    56  		url:   "/docs",
    57  		query: q,
    58  	}
    59  
    60  	return request
    61  }
    62  
    63  // needed for ILazyOperation
    64  // results should be map[string]*<type>
    65  func (o *LazyStartsWithOperation) getResult(results interface{}) error {
    66  	var tp reflect.Type
    67  	var ok bool
    68  	if tp, ok = isMapStringToPtrStruct(reflect.TypeOf(results)); !ok {
    69  		return fmt.Errorf("expected o.results to be of type map[string]*struct, got %T", results)
    70  	}
    71  
    72  	finalResult := reflect.ValueOf(results)
    73  
    74  	for _, document := range o.rawResult.Results {
    75  		newDocumentInfo := getNewDocumentInfo(document)
    76  		o.sessionOperations.documentsByID.add(newDocumentInfo)
    77  
    78  		if newDocumentInfo.id == "" {
    79  			continue // is this possible?
    80  		}
    81  
    82  		id := strings.ToLower(newDocumentInfo.id)
    83  
    84  		key := reflect.ValueOf(id)
    85  		if o.sessionOperations.IsDeleted(newDocumentInfo.id) {
    86  			nilPtr := reflect.New(tp)
    87  			finalResult.SetMapIndex(key, reflect.ValueOf(nilPtr))
    88  			continue
    89  		}
    90  		doc := o.sessionOperations.documentsByID.getValue(newDocumentInfo.id)
    91  		if doc != nil {
    92  			v := reflect.New(tp).Interface()
    93  			if err := o.sessionOperations.TrackEntityInDocumentInfo(v, doc); err != nil {
    94  				return err
    95  			}
    96  			finalResult.SetMapIndex(key, reflect.ValueOf(v).Elem())
    97  			continue
    98  		}
    99  		nilPtr := reflect.New(tp)
   100  		finalResult.SetMapIndex(key, reflect.ValueOf(nilPtr))
   101  	}
   102  	return nil
   103  }
   104  
   105  // needed for ILazyOperation
   106  func (o *LazyStartsWithOperation) getQueryResult() *QueryResult {
   107  	return o.queryResult
   108  }
   109  
   110  // needed for ILazyOperation
   111  func (o *LazyStartsWithOperation) isRequiresRetry() bool {
   112  	return o.requiresRetry
   113  }
   114  
   115  // needed for ILazyOperation
   116  func (o *LazyStartsWithOperation) handleResponse(response *GetResponse) error {
   117  	var getDocumentResult *GetDocumentsResult
   118  	if err := jsonUnmarshal(response.Result, &getDocumentResult); err != nil {
   119  		return err
   120  	}
   121  	o.rawResult = getDocumentResult
   122  	return nil
   123  }