go.mercari.io/datastore@v1.8.2/clouddatastore/query.go (about) 1 package clouddatastore 2 3 import ( 4 "context" 5 6 "cloud.google.com/go/datastore" 7 w "go.mercari.io/datastore" 8 "go.mercari.io/datastore/internal/shared" 9 ) 10 11 var _ w.Query = (*queryImpl)(nil) 12 var _ w.Iterator = (*iteratorImpl)(nil) 13 var _ w.Cursor = (*cursorImpl)(nil) 14 15 type queryImpl struct { 16 ctx context.Context 17 q *datastore.Query 18 19 dump *w.QueryDump 20 21 firstError error 22 } 23 24 type iteratorImpl struct { 25 client *datastoreImpl 26 q *queryImpl 27 qDump *w.QueryDump 28 t *datastore.Iterator 29 cacheInfo *w.MiddlewareInfo 30 31 firstError error 32 } 33 34 type cursorImpl struct { 35 cursor datastore.Cursor 36 } 37 38 func (q *queryImpl) clone() *queryImpl { 39 x := *q 40 d := *q.dump 41 d.Filter = d.Filter[:] 42 d.Order = d.Order[:] 43 d.Project = d.Project[:] 44 x.dump = &d 45 return &x 46 } 47 48 func (q *queryImpl) Ancestor(ancestor w.Key) w.Query { 49 q = q.clone() 50 q.q = q.q.Ancestor(toOriginalKey(ancestor)) 51 q.dump.Ancestor = ancestor 52 return q 53 } 54 55 func (q *queryImpl) EventualConsistency() w.Query { 56 q = q.clone() 57 q.q = q.q.EventualConsistency() 58 q.dump.EventualConsistency = true 59 return q 60 } 61 62 func (q *queryImpl) Namespace(ns string) w.Query { 63 q = q.clone() 64 q.q = q.q.Namespace(ns) 65 q.dump.Namespace = ns 66 return q 67 } 68 69 func (q *queryImpl) Transaction(t w.Transaction) w.Query { 70 q = q.clone() 71 q.q = q.q.Transaction(toOriginalTransaction(t)) 72 q.dump.Transaction = t 73 return q 74 } 75 76 func (q *queryImpl) Filter(filterStr string, value interface{}) w.Query { 77 q = q.clone() 78 var err error 79 if pt, ok := value.(w.PropertyTranslator); ok { 80 value, err = pt.ToPropertyValue(q.ctx) 81 if err != nil { 82 if q.firstError == nil { 83 q.firstError = err 84 } 85 return q 86 } 87 } 88 origV := toOriginalValue(value) 89 q.q = q.q.Filter(filterStr, origV) 90 q.dump.Filter = append(q.dump.Filter, &w.QueryFilterCondition{ 91 Filter: filterStr, 92 Value: value, 93 }) 94 return q 95 } 96 97 func (q *queryImpl) Order(fieldName string) w.Query { 98 q = q.clone() 99 q.q = q.q.Order(fieldName) 100 q.dump.Order = append(q.dump.Order, fieldName) 101 return q 102 } 103 104 func (q *queryImpl) Project(fieldNames ...string) w.Query { 105 q = q.clone() 106 q.q = q.q.Project(fieldNames...) 107 q.dump.Project = append([]string(nil), fieldNames...) 108 return q 109 } 110 111 func (q *queryImpl) DistinctOn(fieldNames ...string) w.Query { 112 q = q.clone() 113 q.q = q.q.DistinctOn(fieldNames...) 114 q.dump.DistinctOn = append([]string(nil), fieldNames...) 115 return q 116 } 117 118 func (q *queryImpl) Distinct() w.Query { 119 q = q.clone() 120 q.q = q.q.Distinct() 121 q.dump.Distinct = true 122 return q 123 } 124 125 func (q *queryImpl) KeysOnly() w.Query { 126 q = q.clone() 127 q.q = q.q.KeysOnly() 128 q.dump.KeysOnly = true 129 return q 130 } 131 132 func (q *queryImpl) Limit(limit int) w.Query { 133 q = q.clone() 134 q.q = q.q.Limit(limit) 135 q.dump.Limit = limit 136 return q 137 } 138 139 func (q *queryImpl) Offset(offset int) w.Query { 140 q = q.clone() 141 q.q = q.q.Offset(offset) 142 q.dump.Offset = offset 143 return q 144 } 145 146 func (q *queryImpl) Start(c w.Cursor) w.Query { 147 q = q.clone() 148 curImpl := c.(*cursorImpl) 149 q.q = q.q.Start(curImpl.cursor) 150 q.dump.Start = c 151 return q 152 } 153 154 func (q *queryImpl) End(c w.Cursor) w.Query { 155 q = q.clone() 156 curImpl := c.(*cursorImpl) 157 q.q = q.q.End(curImpl.cursor) 158 q.dump.End = c 159 return q 160 } 161 162 func (q *queryImpl) Dump() *w.QueryDump { 163 return q.dump 164 } 165 166 func (t *iteratorImpl) Next(dst interface{}) (w.Key, error) { 167 if t.firstError != nil { 168 return nil, t.firstError 169 } 170 171 cb := shared.NewCacheBridge(t.cacheInfo, &originalClientBridgeImpl{t.client}, nil, &originalIteratorBridgeImpl{t.qDump}, t.client.middlewares) 172 return shared.NextOps(t.client.ctx, t.qDump, dst, func(dst *w.PropertyList) (w.Key, error) { 173 return cb.Next(t.cacheInfo, t.q, t.qDump, t, dst) 174 }) 175 } 176 177 func (t *iteratorImpl) Cursor() (w.Cursor, error) { 178 if t.firstError != nil { 179 return nil, t.firstError 180 } 181 182 cur, err := t.t.Cursor() 183 if err != nil { 184 return nil, toWrapperError(err) 185 } 186 187 return &cursorImpl{cursor: cur}, nil 188 } 189 190 func (cur *cursorImpl) String() string { 191 if cur == nil { 192 return "" 193 } 194 return cur.cursor.String() 195 }