query.go 22 KB

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