query.go 21 KB

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