github.com/altipla-consulting/ravendb-go-client@v0.1.3/aggregation_query_base.go (about) 1 package ravendb 2 3 import ( 4 "reflect" 5 "time" 6 ) 7 8 // Note: AggregationQueryBase also includes AggregationDocumentQuery 9 type aggregationQueryBase struct { 10 session *InMemoryDocumentSessionOperations 11 query *IndexQuery 12 startTime time.Time 13 14 // from AggregationDocumentQuery 15 source *abstractDocumentQuery 16 err error 17 } 18 19 func newAggregationQueryBase(source *DocumentQuery) *aggregationQueryBase { 20 res := &aggregationQueryBase{ 21 session: source.getSession(), 22 source: source.abstractDocumentQuery, 23 } 24 res.err = source.err 25 return res 26 } 27 28 func newAggregationDocumentQuery(source *DocumentQuery) *AggregationDocumentQuery { 29 return newAggregationQueryBase(source) 30 } 31 32 func (q *aggregationQueryBase) Execute() (map[string]*FacetResult, error) { 33 if q.err != nil { 34 return nil, q.err 35 } 36 command, err := q.GetCommand() 37 if err != nil { 38 return nil, err 39 } 40 41 q.startTime = time.Now() 42 43 if err = q.session.incrementRequestCount(); err != nil { 44 return nil, err 45 } 46 if err = q.session.GetRequestExecutor().ExecuteCommand(command, nil); err != nil { 47 return nil, err 48 } 49 return q.processResults(command.Result, q.session.GetConventions()) 50 } 51 52 // arg to onEval is map[string]*FacetResult 53 // results is map[string]*FacetResult 54 func (q *aggregationQueryBase) ExecuteLazy() (*Lazy, error) { 55 if q.err != nil { 56 return nil, q.err 57 } 58 59 var err error 60 q.query, err = q.GetIndexQuery() 61 if err != nil { 62 return nil, err 63 } 64 65 afterFn := func(result *QueryResult) { 66 q.invokeAfterQueryExecuted(result) 67 } 68 69 70 processResultFn := func(queryResult *QueryResult, conventions *DocumentConventions) (map[string]*FacetResult, error) { 71 results := map[string]*FacetResult{} 72 res, err := q.processResults(queryResult, conventions) 73 if err != nil { 74 return nil, err 75 } 76 // processResult returns its own map, have to copy it to map provided by 77 // caller as a result 78 for k, v := range res { 79 results[k] = v 80 } 81 return res, nil 82 } 83 op := newLazyAggregationQueryOperation(q.session.Conventions, q.query, afterFn, processResultFn) 84 return q.session.session.addLazyOperation(op, nil, nil), nil 85 } 86 87 /* 88 // abstract 89 func (q *AggregationQueryBase) getIndexQuery() *IndexQuery { 90 return nil 91 } 92 93 // abstract 94 func (q *AggregationQueryBase) invokeAfterQueryExecuted(result *QueryResult) { 95 } 96 */ 97 98 func (q *aggregationQueryBase) processResults(queryResult *QueryResult, conventions *DocumentConventions) (map[string]*FacetResult, error) { 99 q.invokeAfterQueryExecuted(queryResult) 100 101 results := map[string]*FacetResult{} 102 for _, result := range queryResult.Results { 103 res, err := convertValue(result, reflect.TypeOf(&FacetResult{})) 104 if err != nil { 105 return nil, err 106 } 107 facetResult := res.(*FacetResult) 108 results[facetResult.Name] = facetResult 109 } 110 111 err := queryOperationEnsureIsAcceptable(queryResult, q.query.waitForNonStaleResults, q.startTime, q.session) 112 if err != nil { 113 return nil, err 114 } 115 return results, nil 116 } 117 118 func (q *aggregationQueryBase) GetCommand() (*QueryCommand, error) { 119 if q.err != nil { 120 return nil, q.err 121 } 122 var err error 123 q.query, err = q.GetIndexQuery() 124 if err != nil { 125 return nil, err 126 } 127 128 return NewQueryCommand(q.session.GetConventions(), q.query, false, false) 129 } 130 131 func (q *aggregationQueryBase) string() (string, error) { 132 if q.err != nil { 133 return "", q.err 134 } 135 iq, err := q.GetIndexQuery() 136 if err != nil { 137 return "", err 138 } 139 return iq.String(), nil 140 } 141 142 // from AggregationDocumentQuery 143 func (q *AggregationDocumentQuery) AndAggregateByFacet(facet FacetBase) *AggregationDocumentQuery { 144 if q.err != nil { 145 return q 146 } 147 q.err = q.source.aggregateBy(facet) 148 return q 149 } 150 151 func (q *AggregationDocumentQuery) GetIndexQuery() (*IndexQuery, error) { 152 return q.source.GetIndexQuery() 153 } 154 155 func (q *AggregationDocumentQuery) invokeAfterQueryExecuted(result *QueryResult) { 156 q.source.invokeAfterQueryExecuted(result) 157 }