query.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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. func (q *Query) Count(c context.Context) (int, error) {
  306. // Check that the query is well-formed.
  307. if q.err != nil {
  308. return 0, q.err
  309. }
  310. // Run a copy of the query, with keysOnly true (if we're not a projection,
  311. // since the two are incompatible), and an adjusted offset. We also set the
  312. // limit to zero, as we don't want any actual entity data, just the number
  313. // of skipped results.
  314. newQ := q.clone()
  315. newQ.keysOnly = len(newQ.projection) == 0
  316. newQ.limit = 0
  317. if q.limit < 0 {
  318. // If the original query was unlimited, set the new query's offset to maximum.
  319. newQ.offset = math.MaxInt32
  320. } else {
  321. newQ.offset = q.offset + q.limit
  322. if newQ.offset < 0 {
  323. // Do the best we can, in the presence of overflow.
  324. newQ.offset = math.MaxInt32
  325. }
  326. }
  327. req := &pb.Query{}
  328. if err := newQ.toProto(req, internal.FullyQualifiedAppID(c)); err != nil {
  329. return 0, err
  330. }
  331. res := &pb.QueryResult{}
  332. if err := internal.Call(c, "datastore_v3", "RunQuery", req, res); err != nil {
  333. return 0, err
  334. }
  335. // n is the count we will return. For example, suppose that our original
  336. // query had an offset of 4 and a limit of 2008: the count will be 2008,
  337. // provided that there are at least 2012 matching entities. However, the
  338. // RPCs will only skip 1000 results at a time. The RPC sequence is:
  339. // call RunQuery with (offset, limit) = (2012, 0) // 2012 == newQ.offset
  340. // response has (skippedResults, moreResults) = (1000, true)
  341. // n += 1000 // n == 1000
  342. // call Next with (offset, limit) = (1012, 0) // 1012 == newQ.offset - n
  343. // response has (skippedResults, moreResults) = (1000, true)
  344. // n += 1000 // n == 2000
  345. // call Next with (offset, limit) = (12, 0) // 12 == newQ.offset - n
  346. // response has (skippedResults, moreResults) = (12, false)
  347. // n += 12 // n == 2012
  348. // // exit the loop
  349. // n -= 4 // n == 2008
  350. var n int32
  351. for {
  352. // The QueryResult should have no actual entity data, just skipped results.
  353. if len(res.Result) != 0 {
  354. return 0, errors.New("datastore: internal error: Count request returned too much data")
  355. }
  356. n += res.GetSkippedResults()
  357. if !res.GetMoreResults() {
  358. break
  359. }
  360. if err := callNext(c, res, newQ.offset-n, 0); err != nil {
  361. return 0, err
  362. }
  363. }
  364. n -= q.offset
  365. if n < 0 {
  366. // If the offset was greater than the number of matching entities,
  367. // return 0 instead of negative.
  368. n = 0
  369. }
  370. return int(n), nil
  371. }
  372. // callNext issues a datastore_v3/Next RPC to advance a cursor, such as that
  373. // returned by a query with more results.
  374. func callNext(c context.Context, res *pb.QueryResult, offset, limit int32) error {
  375. if res.Cursor == nil {
  376. return errors.New("datastore: internal error: server did not return a cursor")
  377. }
  378. req := &pb.NextRequest{
  379. Cursor: res.Cursor,
  380. }
  381. if limit >= 0 {
  382. req.Count = proto.Int32(limit)
  383. }
  384. if offset != 0 {
  385. req.Offset = proto.Int32(offset)
  386. }
  387. if res.CompiledCursor != nil {
  388. req.Compile = proto.Bool(true)
  389. }
  390. res.Reset()
  391. return internal.Call(c, "datastore_v3", "Next", req, res)
  392. }
  393. // GetAll runs the query in the given context and returns all keys that match
  394. // that query, as well as appending the values to dst.
  395. //
  396. // dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non-
  397. // interface, non-pointer type P such that P or *P implements PropertyLoadSaver.
  398. //
  399. // As a special case, *PropertyList is an invalid type for dst, even though a
  400. // PropertyList is a slice of structs. It is treated as invalid to avoid being
  401. // mistakenly passed when *[]PropertyList was intended.
  402. //
  403. // The keys returned by GetAll will be in a 1-1 correspondence with the entities
  404. // added to dst.
  405. //
  406. // If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys.
  407. func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) {
  408. var (
  409. dv reflect.Value
  410. mat multiArgType
  411. elemType reflect.Type
  412. errFieldMismatch error
  413. )
  414. if !q.keysOnly {
  415. dv = reflect.ValueOf(dst)
  416. if dv.Kind() != reflect.Ptr || dv.IsNil() {
  417. return nil, ErrInvalidEntityType
  418. }
  419. dv = dv.Elem()
  420. mat, elemType = checkMultiArg(dv)
  421. if mat == multiArgTypeInvalid || mat == multiArgTypeInterface {
  422. return nil, ErrInvalidEntityType
  423. }
  424. }
  425. var keys []*Key
  426. for t := q.Run(c); ; {
  427. k, e, err := t.next()
  428. if err == Done {
  429. break
  430. }
  431. if err != nil {
  432. return keys, err
  433. }
  434. if !q.keysOnly {
  435. ev := reflect.New(elemType)
  436. if elemType.Kind() == reflect.Map {
  437. // This is a special case. The zero values of a map type are
  438. // not immediately useful; they have to be make'd.
  439. //
  440. // Funcs and channels are similar, in that a zero value is not useful,
  441. // but even a freshly make'd channel isn't useful: there's no fixed
  442. // channel buffer size that is always going to be large enough, and
  443. // there's no goroutine to drain the other end. Theoretically, these
  444. // types could be supported, for example by sniffing for a constructor
  445. // method or requiring prior registration, but for now it's not a
  446. // frequent enough concern to be worth it. Programmers can work around
  447. // it by explicitly using Iterator.Next instead of the Query.GetAll
  448. // convenience method.
  449. x := reflect.MakeMap(elemType)
  450. ev.Elem().Set(x)
  451. }
  452. if err = loadEntity(ev.Interface(), e); err != nil {
  453. if _, ok := err.(*ErrFieldMismatch); ok {
  454. // We continue loading entities even in the face of field mismatch errors.
  455. // If we encounter any other error, that other error is returned. Otherwise,
  456. // an ErrFieldMismatch is returned.
  457. errFieldMismatch = err
  458. } else {
  459. return keys, err
  460. }
  461. }
  462. if mat != multiArgTypeStructPtr {
  463. ev = ev.Elem()
  464. }
  465. dv.Set(reflect.Append(dv, ev))
  466. }
  467. keys = append(keys, k)
  468. }
  469. return keys, errFieldMismatch
  470. }
  471. // Run runs the query in the given context.
  472. func (q *Query) Run(c context.Context) *Iterator {
  473. if q.err != nil {
  474. return &Iterator{err: q.err}
  475. }
  476. t := &Iterator{
  477. c: c,
  478. limit: q.limit,
  479. q: q,
  480. prevCC: q.start,
  481. }
  482. var req pb.Query
  483. if err := q.toProto(&req, internal.FullyQualifiedAppID(c)); err != nil {
  484. t.err = err
  485. return t
  486. }
  487. if err := internal.Call(c, "datastore_v3", "RunQuery", &req, &t.res); err != nil {
  488. t.err = err
  489. return t
  490. }
  491. offset := q.offset - t.res.GetSkippedResults()
  492. for offset > 0 && t.res.GetMoreResults() {
  493. t.prevCC = t.res.CompiledCursor
  494. if err := callNext(t.c, &t.res, offset, t.limit); err != nil {
  495. t.err = err
  496. break
  497. }
  498. skip := t.res.GetSkippedResults()
  499. if skip < 0 {
  500. t.err = errors.New("datastore: internal error: negative number of skipped_results")
  501. break
  502. }
  503. offset -= skip
  504. }
  505. if offset < 0 {
  506. t.err = errors.New("datastore: internal error: query offset was overshot")
  507. }
  508. return t
  509. }
  510. // Iterator is the result of running a query.
  511. type Iterator struct {
  512. c context.Context
  513. err error
  514. // res is the result of the most recent RunQuery or Next API call.
  515. res pb.QueryResult
  516. // i is how many elements of res.Result we have iterated over.
  517. i int
  518. // limit is the limit on the number of results this iterator should return.
  519. // A negative value means unlimited.
  520. limit int32
  521. // q is the original query which yielded this iterator.
  522. q *Query
  523. // prevCC is the compiled cursor that marks the end of the previous batch
  524. // of results.
  525. prevCC *pb.CompiledCursor
  526. }
  527. // Done is returned when a query iteration has completed.
  528. var Done = errors.New("datastore: query has no more results")
  529. // Next returns the key of the next result. When there are no more results,
  530. // Done is returned as the error.
  531. //
  532. // If the query is not keys only and dst is non-nil, it also loads the entity
  533. // stored for that key into the struct pointer or PropertyLoadSaver dst, with
  534. // the same semantics and possible errors as for the Get function.
  535. func (t *Iterator) Next(dst interface{}) (*Key, error) {
  536. k, e, err := t.next()
  537. if err != nil {
  538. return nil, err
  539. }
  540. if dst != nil && !t.q.keysOnly {
  541. err = loadEntity(dst, e)
  542. }
  543. return k, err
  544. }
  545. func (t *Iterator) next() (*Key, *pb.EntityProto, error) {
  546. if t.err != nil {
  547. return nil, nil, t.err
  548. }
  549. // Issue datastore_v3/Next RPCs as necessary.
  550. for t.i == len(t.res.Result) {
  551. if !t.res.GetMoreResults() {
  552. t.err = Done
  553. return nil, nil, t.err
  554. }
  555. t.prevCC = t.res.CompiledCursor
  556. if err := callNext(t.c, &t.res, 0, t.limit); err != nil {
  557. t.err = err
  558. return nil, nil, t.err
  559. }
  560. if t.res.GetSkippedResults() != 0 {
  561. t.err = errors.New("datastore: internal error: iterator has skipped results")
  562. return nil, nil, t.err
  563. }
  564. t.i = 0
  565. if t.limit >= 0 {
  566. t.limit -= int32(len(t.res.Result))
  567. if t.limit < 0 {
  568. t.err = errors.New("datastore: internal error: query returned more results than the limit")
  569. return nil, nil, t.err
  570. }
  571. }
  572. }
  573. // Extract the key from the t.i'th element of t.res.Result.
  574. e := t.res.Result[t.i]
  575. t.i++
  576. if e.Key == nil {
  577. return nil, nil, errors.New("datastore: internal error: server did not return a key")
  578. }
  579. k, err := protoToKey(e.Key)
  580. if err != nil || k.Incomplete() {
  581. return nil, nil, errors.New("datastore: internal error: server returned an invalid key")
  582. }
  583. return k, e, nil
  584. }
  585. // Cursor returns a cursor for the iterator's current location.
  586. func (t *Iterator) Cursor() (Cursor, error) {
  587. if t.err != nil && t.err != Done {
  588. return Cursor{}, t.err
  589. }
  590. // If we are at either end of the current batch of results,
  591. // return the compiled cursor at that end.
  592. skipped := t.res.GetSkippedResults()
  593. if t.i == 0 && skipped == 0 {
  594. if t.prevCC == nil {
  595. // A nil pointer (of type *pb.CompiledCursor) means no constraint:
  596. // passing it as the end cursor of a new query means unlimited results
  597. // (glossing over the integer limit parameter for now).
  598. // A non-nil pointer to an empty pb.CompiledCursor means the start:
  599. // passing it as the end cursor of a new query means 0 results.
  600. // If prevCC was nil, then the original query had no start cursor, but
  601. // Iterator.Cursor should return "the start" instead of unlimited.
  602. return Cursor{&zeroCC}, nil
  603. }
  604. return Cursor{t.prevCC}, nil
  605. }
  606. if t.i == len(t.res.Result) {
  607. return Cursor{t.res.CompiledCursor}, nil
  608. }
  609. // Otherwise, re-run the query offset to this iterator's position, starting from
  610. // the most recent compiled cursor. This is done on a best-effort basis, as it
  611. // is racy; if a concurrent process has added or removed entities, then the
  612. // cursor returned may be inconsistent.
  613. q := t.q.clone()
  614. q.start = t.prevCC
  615. q.offset = skipped + int32(t.i)
  616. q.limit = 0
  617. q.keysOnly = len(q.projection) == 0
  618. t1 := q.Run(t.c)
  619. _, _, err := t1.next()
  620. if err != Done {
  621. if err == nil {
  622. err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results")
  623. }
  624. return Cursor{}, err
  625. }
  626. return Cursor{t1.res.CompiledCursor}, nil
  627. }
  628. var zeroCC pb.CompiledCursor
  629. // Cursor is an iterator's position. It can be converted to and from an opaque
  630. // string. A cursor can be used from different HTTP requests, but only with a
  631. // query with the same kind, ancestor, filter and order constraints.
  632. type Cursor struct {
  633. cc *pb.CompiledCursor
  634. }
  635. // String returns a base-64 string representation of a cursor.
  636. func (c Cursor) String() string {
  637. if c.cc == nil {
  638. return ""
  639. }
  640. b, err := proto.Marshal(c.cc)
  641. if err != nil {
  642. // The only way to construct a Cursor with a non-nil cc field is to
  643. // unmarshal from the byte representation. We panic if the unmarshal
  644. // succeeds but the marshaling of the unchanged protobuf value fails.
  645. panic(fmt.Sprintf("datastore: internal error: malformed cursor: %v", err))
  646. }
  647. return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
  648. }
  649. // Decode decodes a cursor from its base-64 string representation.
  650. func DecodeCursor(s string) (Cursor, error) {
  651. if s == "" {
  652. return Cursor{&zeroCC}, nil
  653. }
  654. if n := len(s) % 4; n != 0 {
  655. s += strings.Repeat("=", 4-n)
  656. }
  657. b, err := base64.URLEncoding.DecodeString(s)
  658. if err != nil {
  659. return Cursor{}, err
  660. }
  661. cc := &pb.CompiledCursor{}
  662. if err := proto.Unmarshal(b, cc); err != nil {
  663. return Cursor{}, err
  664. }
  665. return Cursor{cc}, nil
  666. }