query.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. // Copyright 2014 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package datastore
  15. import (
  16. "encoding/base64"
  17. "errors"
  18. "fmt"
  19. "math"
  20. "reflect"
  21. "strconv"
  22. "strings"
  23. "github.com/golang/protobuf/proto"
  24. "golang.org/x/net/context"
  25. pb "google.golang.org/cloud/internal/datastore"
  26. )
  27. type operator int
  28. const (
  29. lessThan operator = iota
  30. lessEq
  31. equal
  32. greaterEq
  33. greaterThan
  34. keyFieldName = "__key__"
  35. )
  36. var operatorToProto = map[operator]*pb.PropertyFilter_Operator{
  37. lessThan: pb.PropertyFilter_LESS_THAN.Enum(),
  38. lessEq: pb.PropertyFilter_LESS_THAN_OR_EQUAL.Enum(),
  39. equal: pb.PropertyFilter_EQUAL.Enum(),
  40. greaterEq: pb.PropertyFilter_GREATER_THAN_OR_EQUAL.Enum(),
  41. greaterThan: pb.PropertyFilter_GREATER_THAN.Enum(),
  42. }
  43. // filter is a conditional filter on query results.
  44. type filter struct {
  45. FieldName string
  46. Op operator
  47. Value interface{}
  48. }
  49. type sortDirection int
  50. const (
  51. ascending sortDirection = iota
  52. descending
  53. )
  54. var sortDirectionToProto = map[sortDirection]*pb.PropertyOrder_Direction{
  55. ascending: pb.PropertyOrder_ASCENDING.Enum(),
  56. descending: pb.PropertyOrder_DESCENDING.Enum(),
  57. }
  58. // order is a sort order on query results.
  59. type order struct {
  60. FieldName string
  61. Direction sortDirection
  62. }
  63. // NewQuery creates a new Query for a specific entity kind.
  64. //
  65. // An empty kind means to return all entities, including entities created and
  66. // managed by other App Engine features, and is called a kindless query.
  67. // Kindless queries cannot include filters or sort orders on property values.
  68. func NewQuery(kind string) *Query {
  69. return &Query{
  70. kind: kind,
  71. limit: -1,
  72. }
  73. }
  74. // Query represents a datastore query.
  75. type Query struct {
  76. kind string
  77. ancestor *Key
  78. filter []filter
  79. order []order
  80. projection []string
  81. distinct bool
  82. keysOnly bool
  83. eventual bool
  84. limit int32
  85. offset int32
  86. start []byte
  87. end []byte
  88. trans *Transaction
  89. err error
  90. }
  91. func (q *Query) clone() *Query {
  92. x := *q
  93. // Copy the contents of the slice-typed fields to a new backing store.
  94. if len(q.filter) > 0 {
  95. x.filter = make([]filter, len(q.filter))
  96. copy(x.filter, q.filter)
  97. }
  98. if len(q.order) > 0 {
  99. x.order = make([]order, len(q.order))
  100. copy(x.order, q.order)
  101. }
  102. return &x
  103. }
  104. // Ancestor returns a derivative query with an ancestor filter.
  105. // The ancestor should not be nil.
  106. func (q *Query) Ancestor(ancestor *Key) *Query {
  107. q = q.clone()
  108. if ancestor == nil {
  109. q.err = errors.New("datastore: nil query ancestor")
  110. return q
  111. }
  112. q.ancestor = ancestor
  113. return q
  114. }
  115. // EventualConsistency returns a derivative query that returns eventually
  116. // consistent results.
  117. // It only has an effect on ancestor queries.
  118. func (q *Query) EventualConsistency() *Query {
  119. q = q.clone()
  120. q.eventual = true
  121. return q
  122. }
  123. // Transaction returns a derivative query that is associated with the given
  124. // transaction.
  125. //
  126. // All reads performed as part of the transaction will come from a single
  127. // consistent snapshot. Furthermore, if the transaction is set to a
  128. // serializable isolation level, another transaction cannot concurrently modify
  129. // the data that is read or modified by this transaction.
  130. func (q *Query) Transaction(t *Transaction) *Query {
  131. q = q.clone()
  132. q.trans = t
  133. return q
  134. }
  135. // Filter returns a derivative query with a field-based filter.
  136. // The filterStr argument must be a field name followed by optional space,
  137. // followed by an operator, one of ">", "<", ">=", "<=", or "=".
  138. // Fields are compared against the provided value using the operator.
  139. // Multiple filters are AND'ed together.
  140. // Field names which contain spaces, quote marks, or operator characters
  141. // should be passed as quoted Go string literals as returned by strconv.Quote
  142. // or the fmt package's %q verb.
  143. func (q *Query) Filter(filterStr string, value interface{}) *Query {
  144. q = q.clone()
  145. filterStr = strings.TrimSpace(filterStr)
  146. if filterStr == "" {
  147. q.err = fmt.Errorf("datastore: invalid filter %q", filterStr)
  148. return q
  149. }
  150. f := filter{
  151. FieldName: strings.TrimRight(filterStr, " ><=!"),
  152. Value: value,
  153. }
  154. switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op {
  155. case "<=":
  156. f.Op = lessEq
  157. case ">=":
  158. f.Op = greaterEq
  159. case "<":
  160. f.Op = lessThan
  161. case ">":
  162. f.Op = greaterThan
  163. case "=":
  164. f.Op = equal
  165. default:
  166. q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr)
  167. return q
  168. }
  169. var err error
  170. f.FieldName, err = unquote(f.FieldName)
  171. if err != nil {
  172. q.err = fmt.Errorf("datastore: invalid syntax for quoted field name %q", f.FieldName)
  173. return q
  174. }
  175. q.filter = append(q.filter, f)
  176. return q
  177. }
  178. // Order returns a derivative query with a field-based sort order. Orders are
  179. // applied in the order they are added. The default order is ascending; to sort
  180. // in descending order prefix the fieldName with a minus sign (-).
  181. // Field names which contain spaces, quote marks, or the minus sign
  182. // should be passed as quoted Go string literals as returned by strconv.Quote
  183. // or the fmt package's %q verb.
  184. func (q *Query) Order(fieldName string) *Query {
  185. q = q.clone()
  186. fieldName, dir := strings.TrimSpace(fieldName), ascending
  187. if strings.HasPrefix(fieldName, "-") {
  188. fieldName, dir = strings.TrimSpace(fieldName[1:]), descending
  189. } else if strings.HasPrefix(fieldName, "+") {
  190. q.err = fmt.Errorf("datastore: invalid order: %q", fieldName)
  191. return q
  192. }
  193. fieldName, err := unquote(fieldName)
  194. if err != nil {
  195. q.err = fmt.Errorf("datastore: invalid syntax for quoted field name %q", fieldName)
  196. return q
  197. }
  198. if fieldName == "" {
  199. q.err = errors.New("datastore: empty order")
  200. return q
  201. }
  202. q.order = append(q.order, order{
  203. Direction: dir,
  204. FieldName: fieldName,
  205. })
  206. return q
  207. }
  208. // unquote optionally interprets s as a double-quoted or backquoted Go
  209. // string literal if it begins with the relevant character.
  210. func unquote(s string) (string, error) {
  211. if s == "" || (s[0] != '`' && s[0] != '"') {
  212. return s, nil
  213. }
  214. return strconv.Unquote(s)
  215. }
  216. // Project returns a derivative query that yields only the given fields. It
  217. // cannot be used with KeysOnly.
  218. func (q *Query) Project(fieldNames ...string) *Query {
  219. q = q.clone()
  220. q.projection = append([]string(nil), fieldNames...)
  221. return q
  222. }
  223. // Distinct returns a derivative query that yields de-duplicated entities with
  224. // respect to the set of projected fields. It is only used for projection
  225. // queries.
  226. func (q *Query) Distinct() *Query {
  227. q = q.clone()
  228. q.distinct = true
  229. return q
  230. }
  231. // KeysOnly returns a derivative query that yields only keys, not keys and
  232. // entities. It cannot be used with projection queries.
  233. func (q *Query) KeysOnly() *Query {
  234. q = q.clone()
  235. q.keysOnly = true
  236. return q
  237. }
  238. // Limit returns a derivative query that has a limit on the number of results
  239. // returned. A negative value means unlimited.
  240. func (q *Query) Limit(limit int) *Query {
  241. q = q.clone()
  242. if limit < math.MinInt32 || limit > math.MaxInt32 {
  243. q.err = errors.New("datastore: query limit overflow")
  244. return q
  245. }
  246. q.limit = int32(limit)
  247. return q
  248. }
  249. // Offset returns a derivative query that has an offset of how many keys to
  250. // skip over before returning results. A negative value is invalid.
  251. func (q *Query) Offset(offset int) *Query {
  252. q = q.clone()
  253. if offset < 0 {
  254. q.err = errors.New("datastore: negative query offset")
  255. return q
  256. }
  257. if offset > math.MaxInt32 {
  258. q.err = errors.New("datastore: query offset overflow")
  259. return q
  260. }
  261. q.offset = int32(offset)
  262. return q
  263. }
  264. // Start returns a derivative query with the given start point.
  265. func (q *Query) Start(c Cursor) *Query {
  266. q = q.clone()
  267. if c.cc == nil {
  268. q.err = errors.New("datastore: invalid cursor")
  269. return q
  270. }
  271. q.start = c.cc
  272. return q
  273. }
  274. // End returns a derivative query with the given end point.
  275. func (q *Query) End(c Cursor) *Query {
  276. q = q.clone()
  277. if c.cc == nil {
  278. q.err = errors.New("datastore: invalid cursor")
  279. return q
  280. }
  281. q.end = c.cc
  282. return q
  283. }
  284. // toProto converts the query to a protocol buffer.
  285. func (q *Query) toProto(req *pb.RunQueryRequest) error {
  286. dst := pb.Query{}
  287. if len(q.projection) != 0 && q.keysOnly {
  288. return errors.New("datastore: query cannot both project and be keys-only")
  289. }
  290. dst.Reset()
  291. if q.kind != "" {
  292. dst.Kind = []*pb.KindExpression{&pb.KindExpression{Name: proto.String(q.kind)}}
  293. }
  294. if q.projection != nil {
  295. for _, propertyName := range q.projection {
  296. dst.Projection = append(dst.Projection, &pb.PropertyExpression{Property: &pb.PropertyReference{Name: proto.String(propertyName)}})
  297. }
  298. if q.distinct {
  299. for _, propertyName := range q.projection {
  300. dst.GroupBy = append(dst.GroupBy, &pb.PropertyReference{Name: proto.String(propertyName)})
  301. }
  302. }
  303. }
  304. if q.keysOnly {
  305. dst.Projection = []*pb.PropertyExpression{&pb.PropertyExpression{Property: &pb.PropertyReference{Name: proto.String(keyFieldName)}}}
  306. }
  307. var filters []*pb.Filter
  308. for _, qf := range q.filter {
  309. if qf.FieldName == "" {
  310. return errors.New("datastore: empty query filter field name")
  311. }
  312. v, errStr := interfaceToProto(reflect.ValueOf(qf.Value).Interface())
  313. if errStr != "" {
  314. return errors.New("datastore: bad query filter value type: " + errStr)
  315. }
  316. xf := &pb.PropertyFilter{
  317. Operator: operatorToProto[qf.Op],
  318. Property: &pb.PropertyReference{Name: proto.String(qf.FieldName)},
  319. Value: v,
  320. }
  321. if xf.Operator == nil {
  322. return errors.New("datastore: unknown query filter operator")
  323. }
  324. filters = append(filters, &pb.Filter{PropertyFilter: xf})
  325. }
  326. if q.ancestor != nil {
  327. filters = append(filters, &pb.Filter{
  328. PropertyFilter: &pb.PropertyFilter{
  329. Property: &pb.PropertyReference{Name: proto.String("__key__")},
  330. Operator: pb.PropertyFilter_HAS_ANCESTOR.Enum(),
  331. Value: &pb.Value{KeyValue: keyToProto(q.ancestor)},
  332. }})
  333. }
  334. if len(filters) == 1 {
  335. dst.Filter = filters[0]
  336. } else if len(filters) > 1 {
  337. dst.Filter = &pb.Filter{CompositeFilter: &pb.CompositeFilter{
  338. Operator: pb.CompositeFilter_AND.Enum(),
  339. Filter: filters,
  340. }}
  341. }
  342. for _, qo := range q.order {
  343. if qo.FieldName == "" {
  344. return errors.New("datastore: empty query order field name")
  345. }
  346. xo := &pb.PropertyOrder{
  347. Property: &pb.PropertyReference{Name: proto.String(qo.FieldName)},
  348. Direction: sortDirectionToProto[qo.Direction],
  349. }
  350. if xo.Direction == nil {
  351. return errors.New("datastore: unknown query order direction")
  352. }
  353. dst.Order = append(dst.Order, xo)
  354. }
  355. if q.limit >= 0 {
  356. dst.Limit = proto.Int32(q.limit)
  357. }
  358. if q.offset != 0 {
  359. dst.Offset = proto.Int32(q.offset)
  360. }
  361. dst.StartCursor = q.start
  362. dst.EndCursor = q.end
  363. if t := q.trans; t != nil {
  364. if t.id == nil {
  365. return errExpiredTransaction
  366. }
  367. req.ReadOptions = &pb.ReadOptions{Transaction: t.id}
  368. }
  369. req.Query = &dst
  370. return nil
  371. }
  372. // Count returns the number of results for the given query.
  373. func (c *Client) Count(ctx context.Context, q *Query) (int, error) {
  374. // Check that the query is well-formed.
  375. if q.err != nil {
  376. return 0, q.err
  377. }
  378. // Run a copy of the query, with keysOnly true (if we're not a projection,
  379. // since the two are incompatible).
  380. newQ := q.clone()
  381. newQ.keysOnly = len(newQ.projection) == 0
  382. req := &pb.RunQueryRequest{}
  383. if ns := ctxNamespace(ctx); ns != "" {
  384. req.PartitionId = &pb.PartitionId{
  385. Namespace: proto.String(ns),
  386. }
  387. }
  388. if err := newQ.toProto(req); err != nil {
  389. return 0, err
  390. }
  391. res := &pb.RunQueryResponse{}
  392. if err := c.call(ctx, "runQuery", req, res); err != nil {
  393. return 0, err
  394. }
  395. var n int
  396. b := res.Batch
  397. for {
  398. n += len(b.GetEntityResult())
  399. if b.GetMoreResults() != pb.QueryResultBatch_NOT_FINISHED {
  400. break
  401. }
  402. var err error
  403. // TODO(jbd): Support count queries that have a limit and an offset.
  404. if err = callNext(ctx, c, req, res, 0, 0); err != nil {
  405. return 0, err
  406. }
  407. }
  408. return int(n), nil
  409. }
  410. func callNext(ctx context.Context, client *Client, req *pb.RunQueryRequest, res *pb.RunQueryResponse, offset, limit int32) error {
  411. if res.GetBatch().EndCursor == nil {
  412. return errors.New("datastore: internal error: server did not return a cursor")
  413. }
  414. req.Query.StartCursor = res.GetBatch().GetEndCursor()
  415. if limit >= 0 {
  416. req.Query.Limit = proto.Int32(limit)
  417. }
  418. if offset != 0 {
  419. req.Query.Offset = proto.Int32(offset)
  420. }
  421. res.Reset()
  422. return client.call(ctx, "runQuery", req, res)
  423. }
  424. // GetAll runs the provided query in the given context and returns all keys
  425. // that match that query, as well as appending the values to dst.
  426. //
  427. // dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non-
  428. // interface, non-pointer type P such that P or *P implements PropertyLoadSaver.
  429. //
  430. // As a special case, *PropertyList is an invalid type for dst, even though a
  431. // PropertyList is a slice of structs. It is treated as invalid to avoid being
  432. // mistakenly passed when *[]PropertyList was intended.
  433. //
  434. // The keys returned by GetAll will be in a 1-1 correspondence with the entities
  435. // added to dst.
  436. //
  437. // If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys.
  438. func (c *Client) GetAll(ctx context.Context, q *Query, dst interface{}) ([]*Key, error) {
  439. var (
  440. dv reflect.Value
  441. mat multiArgType
  442. elemType reflect.Type
  443. errFieldMismatch error
  444. )
  445. if !q.keysOnly {
  446. dv = reflect.ValueOf(dst)
  447. if dv.Kind() != reflect.Ptr || dv.IsNil() {
  448. return nil, ErrInvalidEntityType
  449. }
  450. dv = dv.Elem()
  451. mat, elemType = checkMultiArg(dv)
  452. if mat == multiArgTypeInvalid || mat == multiArgTypeInterface {
  453. return nil, ErrInvalidEntityType
  454. }
  455. }
  456. var keys []*Key
  457. for t := c.Run(ctx, q); ; {
  458. k, e, err := t.next()
  459. if err == Done {
  460. break
  461. }
  462. if err != nil {
  463. return keys, err
  464. }
  465. if !q.keysOnly {
  466. ev := reflect.New(elemType)
  467. if elemType.Kind() == reflect.Map {
  468. // This is a special case. The zero values of a map type are
  469. // not immediately useful; they have to be make'd.
  470. //
  471. // Funcs and channels are similar, in that a zero value is not useful,
  472. // but even a freshly make'd channel isn't useful: there's no fixed
  473. // channel buffer size that is always going to be large enough, and
  474. // there's no goroutine to drain the other end. Theoretically, these
  475. // types could be supported, for example by sniffing for a constructor
  476. // method or requiring prior registration, but for now it's not a
  477. // frequent enough concern to be worth it. Programmers can work around
  478. // it by explicitly using Iterator.Next instead of the Query.GetAll
  479. // convenience method.
  480. x := reflect.MakeMap(elemType)
  481. ev.Elem().Set(x)
  482. }
  483. if err = loadEntity(ev.Interface(), e); err != nil {
  484. if _, ok := err.(*ErrFieldMismatch); ok {
  485. // We continue loading entities even in the face of field mismatch errors.
  486. // If we encounter any other error, that other error is returned. Otherwise,
  487. // an ErrFieldMismatch is returned.
  488. errFieldMismatch = err
  489. } else {
  490. return keys, err
  491. }
  492. }
  493. if mat != multiArgTypeStructPtr {
  494. ev = ev.Elem()
  495. }
  496. dv.Set(reflect.Append(dv, ev))
  497. }
  498. keys = append(keys, k)
  499. }
  500. return keys, errFieldMismatch
  501. }
  502. // Run runs the given query in the given context.
  503. func (c *Client) Run(ctx context.Context, q *Query) *Iterator {
  504. if q.err != nil {
  505. return &Iterator{err: q.err}
  506. }
  507. t := &Iterator{
  508. ctx: ctx,
  509. client: c,
  510. limit: q.limit,
  511. q: q,
  512. prevCC: q.start,
  513. }
  514. t.req.Reset()
  515. if ns := ctxNamespace(ctx); ns != "" {
  516. t.req.PartitionId = &pb.PartitionId{
  517. Namespace: proto.String(ns),
  518. }
  519. }
  520. if err := q.toProto(&t.req); err != nil {
  521. t.err = err
  522. return t
  523. }
  524. if err := c.call(ctx, "runQuery", &t.req, &t.res); err != nil {
  525. t.err = err
  526. return t
  527. }
  528. b := t.res.GetBatch()
  529. offset := q.offset - b.GetSkippedResults()
  530. for offset > 0 && b.GetMoreResults() == pb.QueryResultBatch_NOT_FINISHED {
  531. t.prevCC = b.GetEndCursor()
  532. var err error
  533. if err = callNext(t.ctx, c, &t.req, &t.res, offset, t.limit); err != nil {
  534. t.err = err
  535. break
  536. }
  537. skip := b.GetSkippedResults()
  538. if skip < 0 {
  539. t.err = errors.New("datastore: internal error: negative number of skipped_results")
  540. break
  541. }
  542. offset -= skip
  543. }
  544. if offset < 0 {
  545. t.err = errors.New("datastore: internal error: query offset was overshot")
  546. }
  547. return t
  548. }
  549. // Iterator is the result of running a query.
  550. type Iterator struct {
  551. ctx context.Context
  552. client *Client
  553. err error
  554. // req is the request we sent previously, we need to keep track of it to resend it
  555. req pb.RunQueryRequest
  556. // res is the result of the most recent RunQuery or Next API call.
  557. res pb.RunQueryResponse
  558. // i is how many elements of res.Result we have iterated over.
  559. i int
  560. // limit is the limit on the number of results this iterator should return.
  561. // A negative value means unlimited.
  562. limit int32
  563. // q is the original query which yielded this iterator.
  564. q *Query
  565. // prevCC is the compiled cursor that marks the end of the previous batch
  566. // of results.
  567. prevCC []byte
  568. }
  569. // Done is returned when a query iteration has completed.
  570. var Done = errors.New("datastore: query has no more results")
  571. // Next returns the key of the next result. When there are no more results,
  572. // Done is returned as the error.
  573. //
  574. // If the query is not keys only and dst is non-nil, it also loads the entity
  575. // stored for that key into the struct pointer or PropertyLoadSaver dst, with
  576. // the same semantics and possible errors as for the Get function.
  577. func (t *Iterator) Next(dst interface{}) (*Key, error) {
  578. k, e, err := t.next()
  579. if err != nil {
  580. return nil, err
  581. }
  582. if dst != nil && !t.q.keysOnly {
  583. err = loadEntity(dst, e)
  584. }
  585. return k, err
  586. }
  587. func (t *Iterator) next() (*Key, *pb.Entity, error) {
  588. if t.err != nil {
  589. return nil, nil, t.err
  590. }
  591. // Issue datastore_v3/Next RPCs as necessary.
  592. b := t.res.GetBatch()
  593. for t.i == len(b.EntityResult) {
  594. if b.GetMoreResults() != pb.QueryResultBatch_NOT_FINISHED {
  595. t.err = Done
  596. return nil, nil, t.err
  597. }
  598. t.prevCC = b.GetEndCursor()
  599. if err := callNext(t.ctx, t.client, &t.req, &t.res, 0, t.limit); err != nil {
  600. t.err = err
  601. return nil, nil, t.err
  602. }
  603. if b.GetSkippedResults() != 0 {
  604. t.err = errors.New("datastore: internal error: iterator has skipped results")
  605. return nil, nil, t.err
  606. }
  607. t.i = 0
  608. if t.limit >= 0 {
  609. t.limit -= int32(len(b.EntityResult))
  610. if t.limit < 0 {
  611. t.err = errors.New("datastore: internal error: query returned more results than the limit")
  612. return nil, nil, t.err
  613. }
  614. }
  615. }
  616. // Extract the key from the t.i'th element of t.res.Result.
  617. e := b.EntityResult[t.i]
  618. t.i++
  619. if e.Entity.Key == nil {
  620. return nil, nil, errors.New("datastore: internal error: server did not return a key")
  621. }
  622. k, err := protoToKey(e.Entity.Key)
  623. if err != nil || k.Incomplete() {
  624. return nil, nil, errors.New("datastore: internal error: server returned an invalid key")
  625. }
  626. return k, e.Entity, nil
  627. }
  628. // Cursor returns a cursor for the iterator's current location.
  629. func (t *Iterator) Cursor() (Cursor, error) {
  630. if t.err != nil && t.err != Done {
  631. return Cursor{}, t.err
  632. }
  633. // If we are at either end of the current batch of results,
  634. // return the compiled cursor at that end.
  635. b := t.res.Batch
  636. skipped := b.GetSkippedResults()
  637. if t.i == 0 && skipped == 0 {
  638. if t.prevCC == nil {
  639. // A nil pointer (of type *pb.CompiledCursor) means no constraint:
  640. // passing it as the end cursor of a new query means unlimited results
  641. // (glossing over the integer limit parameter for now).
  642. // A non-nil pointer to an empty pb.CompiledCursor means the start:
  643. // passing it as the end cursor of a new query means 0 results.
  644. // If prevCC was nil, then the original query had no start cursor, but
  645. // Iterator.Cursor should return "the start" instead of unlimited.
  646. return Cursor{}, nil
  647. }
  648. return Cursor{t.prevCC}, nil
  649. }
  650. if t.i == len(b.EntityResult) {
  651. return Cursor{b.EndCursor}, nil
  652. }
  653. // Otherwise, re-run the query offset to this iterator's position, starting from
  654. // the most recent compiled cursor. This is done on a best-effort basis, as it
  655. // is racy; if a concurrent process has added or removed entities, then the
  656. // cursor returned may be inconsistent.
  657. q := t.q.clone()
  658. q.start = t.prevCC
  659. q.offset = skipped + int32(t.i)
  660. q.limit = 0
  661. q.keysOnly = len(q.projection) == 0
  662. t1 := t.client.Run(t.ctx, t.q)
  663. _, _, err := t1.next()
  664. if err != Done {
  665. if err == nil {
  666. err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results")
  667. }
  668. return Cursor{}, err
  669. }
  670. return Cursor{t1.res.Batch.EndCursor}, nil
  671. }
  672. // Cursor is an iterator's position. It can be converted to and from an opaque
  673. // string. A cursor can be used from different HTTP requests, but only with a
  674. // query with the same kind, ancestor, filter and order constraints.
  675. type Cursor struct {
  676. cc []byte
  677. }
  678. // String returns a base-64 string representation of a cursor.
  679. func (c Cursor) String() string {
  680. if c.cc == nil {
  681. return ""
  682. }
  683. return strings.TrimRight(base64.URLEncoding.EncodeToString(c.cc), "=")
  684. }
  685. // Decode decodes a cursor from its base-64 string representation.
  686. func DecodeCursor(s string) (Cursor, error) {
  687. if s == "" {
  688. return Cursor{}, nil
  689. }
  690. if n := len(s) % 4; n != 0 {
  691. s += strings.Repeat("=", 4-n)
  692. }
  693. b, err := base64.URLEncoding.DecodeString(s)
  694. if err != nil {
  695. return Cursor{}, err
  696. }
  697. return Cursor{b}, nil
  698. }