text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package runtime exposes information about the resource usage of the application.
It also provides a way to run code in a new background context of a module.

This package does not work on App Engine "flexible environment".
*/
package runtime // import "google.golang.org/appengine/runtime"

import (
	"net/http"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/system"
)

// Statistics represents the system's statistics.
type Statistics struct {
	// CPU records the CPU consumed by this instance, in megacycles.
	CPU struct {
		Total   float64
		Rate1M  float64 // consumption rate over one minute
		Rate10M float64 // consumption rate over ten minutes
	}
	// RAM records the memory used by the instance, in megabytes.
	RAM struct {
		Current    float64
		Average1M  float64 // average usage over one minute
		Average10M float64 // average usage over ten minutes
	}
}

func Stats(c context.Context) (*Statistics, error) {
	req := &pb.GetSystemStatsRequest{}
	res := &pb.GetSystemStatsResponse{}
	if err := internal.Call(c, "system", "GetSystemStats", req, res); err != nil {
		return nil, err
	}
	s := &Statistics{}
	if res.Cpu != nil {
		s.CPU.Total = res.Cpu.GetTotal()
		s.CPU.Rate1M = res.Cpu.GetRate1M()
		s.CPU.Rate10M = res.Cpu.GetRate10M()
	}
	if res.Memory != nil {
		s.RAM.Current = res.Memory.GetCurrent()
		s.RAM.Average1M = res.Memory.GetAverage1M()
		s.RAM.Average10M = res.Memory.GetAverage10M()
	}
	return s, nil
}

/*
RunInBackground makes an API call that triggers an /_ah/background request.

There are two independent code paths that need to make contact:
the RunInBackground code, and the /_ah/background handler. The matchmaker
loop arranges for the two paths to meet. The RunInBackground code passes
a send to the matchmaker, the /_ah/background passes a recv to the matchmaker,
and the matchmaker hooks them up.
*/

func init() {
	http.HandleFunc("/_ah/background", handleBackground)

	sc := make(chan send)
	rc := make(chan recv)
	sendc, recvc = sc, rc
	go matchmaker(sc, rc)
}

var (
	sendc chan<- send // RunInBackground sends to this
	recvc chan<- recv // handleBackground sends to this
)

type send struct {
	id string
	f  func(context.Context)
}

type recv struct {
	id string
	ch chan<- func(context.Context)
}

func matchmaker(sendc <-chan send, recvc <-chan recv) {
	// When one side of the match arrives before the other
	// it is inserted in the corresponding map.
	waitSend := make(map[string]send)
	waitRecv := make(map[string]recv)

	for {
		select {
		case s := <-sendc:
			if r, ok := waitRecv[s.id]; ok {
				// meet!
				delete(waitRecv, s.id)
				r.ch <- s.f
			} else {
				// waiting for r
				waitSend[s.id] = s
			}
		case r := <-recvc:
			if s, ok := waitSend[r.id]; ok {
				// meet!
				delete(waitSend, r.id)
				r.ch <- s.f
			} else {
				// waiting for s
				waitRecv[r.id] = r
			}
		}
	}
}

var newContext = appengine.NewContext // for testing

func handleBackground(w http.ResponseWriter, req *http.Request) {
	id := req.Header.Get("X-AppEngine-BackgroundRequest")

	ch := make(chan func(context.Context))
	recvc <- recv{id, ch}
	(<-ch)(newContext(req))
}

// RunInBackground runs f in a background goroutine in this process.
// f is provided a context that may outlast the context provided to RunInBackground.
// This is only valid to invoke from a service set to basic or manual scaling.
func RunInBackground(c context.Context, f func(c context.Context)) error {
	req := &pb.StartBackgroundRequestRequest{}
	res := &pb.StartBackgroundRequestResponse{}
	if err := internal.Call(c, "system", "StartBackgroundRequest", req, res); err != nil {
		return err
	}
	sendc <- send{res.GetRequestId(), f}
	return nil
}

func init() {
	internal.RegisterErrorCodeMap("system", pb.SystemServiceError_ErrorCode_name)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package taskqueue provides a client for App Engine's taskqueue service.
Using this service, applications may perform work outside a user's request.

A Task may be constructed manually; alternatively, since the most common
taskqueue operation is to add a single POST task, NewPOSTTask makes it easy.

	t := taskqueue.NewPOSTTask("/worker", url.Values{
		"key": {key},
	})
	taskqueue.Add(c, t, "") // add t to the default queue
*/
package taskqueue // import "google.golang.org/appengine/taskqueue"

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"time"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	dspb "google.golang.org/appengine/internal/datastore"
	pb "google.golang.org/appengine/internal/taskqueue"
)

var (
	// ErrTaskAlreadyAdded is the error returned by Add and AddMulti when a task has already been added with a particular name.
	ErrTaskAlreadyAdded = errors.New("taskqueue: task has already been added")
)

// RetryOptions let you control whether to retry a task and the backoff intervals between tries.
type RetryOptions struct {
	// Number of tries/leases after which the task fails permanently and is deleted.
	// If AgeLimit is also set, both limits must be exceeded for the task to fail permanently.
	RetryLimit int32

	// Maximum time allowed since the task's first try before the task fails permanently and is deleted (only for push tasks).
	// If RetryLimit is also set, both limits must be exceeded for the task to fail permanently.
	AgeLimit time.Duration

	// Minimum time between successive tries (only for push tasks).
	MinBackoff time.Duration

	// Maximum time between successive tries (only for push tasks).
	MaxBackoff time.Duration

	// Maximum number of times to double the interval between successive tries before the intervals increase linearly (only for push tasks).
	MaxDoublings int32

	// If MaxDoublings is zero, set ApplyZeroMaxDoublings to true to override the default non-zero value.
	// Otherwise a zero MaxDoublings is ignored and the default is used.
	ApplyZeroMaxDoublings bool
}

// toRetryParameter converts RetryOptions to pb.TaskQueueRetryParameters.
func (opt *RetryOptions) toRetryParameters() *pb.TaskQueueRetryParameters {
	params := &pb.TaskQueueRetryParameters{}
	if opt.RetryLimit > 0 {
		params.RetryLimit = proto.Int32(opt.RetryLimit)
	}
	if opt.AgeLimit > 0 {
		params.AgeLimitSec = proto.Int64(int64(opt.AgeLimit.Seconds()))
	}
	if opt.MinBackoff > 0 {
		params.MinBackoffSec = proto.Float64(opt.MinBackoff.Seconds())
	}
	if opt.MaxBackoff > 0 {
		params.MaxBackoffSec = proto.Float64(opt.MaxBackoff.Seconds())
	}
	if opt.MaxDoublings > 0 || (opt.MaxDoublings == 0 && opt.ApplyZeroMaxDoublings) {
		params.MaxDoublings = proto.Int32(opt.MaxDoublings)
	}
	return params
}

// A Task represents a task to be executed.
type Task struct {
	// Path is the worker URL for the task.
	// If unset, it will default to /_ah/queue/<queue_name>.
	Path string

	// Payload is the data for the task.
	// This will be delivered as the HTTP request body.
	// It is only used when Method is POST, PUT or PULL.
	// url.Values' Encode method may be used to generate this for POST requests.
	Payload []byte

	// Additional HTTP headers to pass at the task's execution time.
	// To schedule the task to be run with an alternate app version
	// or backend, set the "Host" header.
	Header http.Header

	// Method is the HTTP method for the task ("GET", "POST", etc.),
	// or "PULL" if this is task is destined for a pull-based queue.
	// If empty, this defaults to "POST".
	Method string

	// A name for the task.
	// If empty, a name will be chosen.
	Name string

	// Delay specifies the duration the task queue service must wait
	// before executing the task.
	// Either Delay or ETA may be set, but not both.
	Delay time.Duration

	// ETA specifies the earliest time a task may be executed (push queues)
	// or leased (pull queues).
	// Either Delay or ETA may be set, but not both.
	ETA time.Time

	// The number of times the task has been dispatched or leased.
	RetryCount int32

	// Tag for the task. Only used when Method is PULL.
	Tag string

	// Retry options for this task. May be nil.
	RetryOptions *RetryOptions
}

func (t *Task) method() string {
	if t.Method == "" {
		return "POST"
	}
	return t.Method
}

// NewPOSTTask creates a Task that will POST to a path with the given form data.
func NewPOSTTask(path string, params url.Values) *Task {
	h := make(http.Header)
	h.Set("Content-Type", "application/x-www-form-urlencoded")
	return &Task{
		Path:    path,
		Payload: []byte(params.Encode()),
		Header:  h,
		Method:  "POST",
	}
}

var (
	currentNamespace = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
	defaultNamespace = http.CanonicalHeaderKey("X-AppEngine-Default-Namespace")
)

func getDefaultNamespace(ctx context.Context) string {
	return internal.IncomingHeaders(ctx).Get(defaultNamespace)
}

func newAddReq(c context.Context, task *Task, queueName string) (*pb.TaskQueueAddRequest, error) {
	if queueName == "" {
		queueName = "default"
	}
	path := task.Path
	if path == "" {
		path = "/_ah/queue/" + queueName
	}
	eta := task.ETA
	if eta.IsZero() {
		eta = time.Now().Add(task.Delay)
	} else if task.Delay != 0 {
		panic("taskqueue: both Delay and ETA are set")
	}
	req := &pb.TaskQueueAddRequest{
		QueueName: []byte(queueName),
		TaskName:  []byte(task.Name),
		EtaUsec:   proto.Int64(eta.UnixNano() / 1e3),
	}
	method := task.method()
	if method == "PULL" {
		// Pull-based task
		req.Body = task.Payload
		req.Mode = pb.TaskQueueMode_PULL.Enum()
		if task.Tag != "" {
			req.Tag = []byte(task.Tag)
		}
	} else {
		// HTTP-based task
		if v, ok := pb.TaskQueueAddRequest_RequestMethod_value[method]; ok {
			req.Method = pb.TaskQueueAddRequest_RequestMethod(v).Enum()
		} else {
			return nil, fmt.Errorf("taskqueue: bad method %q", method)
		}
		req.Url = []byte(path)
		for k, vs := range task.Header {
			for _, v := range vs {
				req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
					Key:   []byte(k),
					Value: []byte(v),
				})
			}
		}
		if method == "POST" || method == "PUT" {
			req.Body = task.Payload
		}

		// Namespace headers.
		if _, ok := task.Header[currentNamespace]; !ok {
			// Fetch the current namespace of this request.
			ns := internal.NamespaceFromContext(c)
			req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
				Key:   []byte(currentNamespace),
				Value: []byte(ns),
			})
		}
		if _, ok := task.Header[defaultNamespace]; !ok {
			// Fetch the X-AppEngine-Default-Namespace header of this request.
			if ns := getDefaultNamespace(c); ns != "" {
				req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
					Key:   []byte(defaultNamespace),
					Value: []byte(ns),
				})
			}
		}
	}

	if task.RetryOptions != nil {
		req.RetryParameters = task.RetryOptions.toRetryParameters()
	}

	return req, nil
}

var alreadyAddedErrors = map[pb.TaskQueueServiceError_ErrorCode]bool{
	pb.TaskQueueServiceError_TASK_ALREADY_EXISTS: true,
	pb.TaskQueueServiceError_TOMBSTONED_TASK:     true,
}

// Add adds the task to a named queue.
// An empty queue name means that the default queue will be used.
// Add returns an equivalent Task with defaults filled in, including setting
// the task's Name field to the chosen name if the original was empty.
func Add(c context.Context, task *Task, queueName string) (*Task, error) {
	req, err := newAddReq(c, task, queueName)
	if err != nil {
		return nil, err
	}
	res := &pb.TaskQueueAddResponse{}
	if err := internal.Call(c, "taskqueue", "Add", req, res); err != nil {
		apiErr, ok := err.(*internal.APIError)
		if ok && alreadyAddedErrors[pb.TaskQueueServiceError_ErrorCode(apiErr.Code)] {
			return nil, ErrTaskAlreadyAdded
		}
		return nil, err
	}
	resultTask := *task
	resultTask.Method = task.method()
	if task.Name == "" {
		resultTask.Name = string(res.ChosenTaskName)
	}
	return &resultTask, nil
}

// AddMulti adds multiple tasks to a named queue.
// An empty queue name means that the default queue will be used.
// AddMulti returns a slice of equivalent tasks with defaults filled in, including setting
// each task's Name field to the chosen name if the original was empty.
// If a given task is badly formed or could not be added, an appengine.MultiError is returned.
func AddMulti(c context.Context, tasks []*Task, queueName string) ([]*Task, error) {
	req := &pb.TaskQueueBulkAddRequest{
		AddRequest: make([]*pb.TaskQueueAddRequest, len(tasks)),
	}
	me, any := make(appengine.MultiError, len(tasks)), false
	for i, t := range tasks {
		req.AddRequest[i], me[i] = newAddReq(c, t, queueName)
		any = any || me[i] != nil
	}
	if any {
		return nil, me
	}
	res := &pb.TaskQueueBulkAddResponse{}
	if err := internal.Call(c, "taskqueue", "BulkAdd", req, res); err != nil {
		return nil, err
	}
	if len(res.Taskresult) != len(tasks) {
		return nil, errors.New("taskqueue: server error")
	}
	tasksOut := make([]*Task, len(tasks))
	for i, tr := range res.Taskresult {
		tasksOut[i] = new(Task)
		*tasksOut[i] = *tasks[i]
		tasksOut[i].Method = tasksOut[i].method()
		if tasksOut[i].Name == "" {
			tasksOut[i].Name = string(tr.ChosenTaskName)
		}
		if *tr.Result != pb.TaskQueueServiceError_OK {
			if alreadyAddedErrors[*tr.Result] {
				me[i] = ErrTaskAlreadyAdded
			} else {
				me[i] = &internal.APIError{
					Service: "taskqueue",
					Code:    int32(*tr.Result),
				}
			}
			any = true
		}
	}
	if any {
		return tasksOut, me
	}
	return tasksOut, nil
}

// Delete deletes a task from a named queue.
func Delete(c context.Context, task *Task, queueName string) error {
	err := DeleteMulti(c, []*Task{task}, queueName)
	if me, ok := err.(appengine.MultiError); ok {
		return me[0]
	}
	return err
}

// DeleteMulti deletes multiple tasks from a named queue.
// If a given task could not be deleted, an appengine.MultiError is returned.
func DeleteMulti(c context.Context, tasks []*Task, queueName string) error {
	taskNames := make([][]byte, len(tasks))
	for i, t := range tasks {
		taskNames[i] = []byte(t.Name)
	}
	if queueName == "" {
		queueName = "default"
	}
	req := &pb.TaskQueueDeleteRequest{
		QueueName: []byte(queueName),
		TaskName:  taskNames,
	}
	res := &pb.TaskQueueDeleteResponse{}
	if err := internal.Call(c, "taskqueue", "Delete", req, res); err != nil {
		return err
	}
	if a, b := len(req.TaskName), len(res.Result); a != b {
		return fmt.Errorf("taskqueue: internal error: requested deletion of %d tasks, got %d results", a, b)
	}
	me, any := make(appengine.MultiError, len(res.Result)), false
	for i, ec := range res.Result {
		if ec != pb.TaskQueueServiceError_OK {
			me[i] = &internal.APIError{
				Service: "taskqueue",
				Code:    int32(ec),
			}
			any = true
		}
	}
	if any {
		return me
	}
	return nil
}

func lease(c context.Context, maxTasks int, queueName string, leaseTime int, groupByTag bool, tag []byte) ([]*Task, error) {
	if queueName == "" {
		queueName = "default"
	}
	req := &pb.TaskQueueQueryAndOwnTasksRequest{
		QueueName:    []byte(queueName),
		LeaseSeconds: proto.Float64(float64(leaseTime)),
		MaxTasks:     proto.Int64(int64(maxTasks)),
		GroupByTag:   proto.Bool(groupByTag),
		Tag:          tag,
	}
	res := &pb.TaskQueueQueryAndOwnTasksResponse{}
	if err := internal.Call(c, "taskqueue", "QueryAndOwnTasks", req, res); err != nil {
		return nil, err
	}
	tasks := make([]*Task, len(res.Task))
	for i, t := range res.Task {
		tasks[i] = &Task{
			Payload:    t.Body,
			Name:       string(t.TaskName),
			Method:     "PULL",
			ETA:        time.Unix(0, *t.EtaUsec*1e3),
			RetryCount: *t.RetryCount,
			Tag:        string(t.Tag),
		}
	}
	return tasks, nil
}

// Lease leases tasks from a queue.
// leaseTime is in seconds.
// The number of tasks fetched will be at most maxTasks.
func Lease(c context.Context, maxTasks int, queueName string, leaseTime int) ([]*Task, error) {
	return lease(c, maxTasks, queueName, leaseTime, false, nil)
}

// LeaseByTag leases tasks from a queue, grouped by tag.
// If tag is empty, then the returned tasks are grouped by the tag of the task with earliest ETA.
// leaseTime is in seconds.
// The number of tasks fetched will be at most maxTasks.
func LeaseByTag(c context.Context, maxTasks int, queueName string, leaseTime int, tag string) ([]*Task, error) {
	return lease(c, maxTasks, queueName, leaseTime, true, []byte(tag))
}

// Purge removes all tasks from a queue.
func Purge(c context.Context, queueName string) error {
	if queueName == "" {
		queueName = "default"
	}
	req := &pb.TaskQueuePurgeQueueRequest{
		QueueName: []byte(queueName),
	}
	res := &pb.TaskQueuePurgeQueueResponse{}
	return internal.Call(c, "taskqueue", "PurgeQueue", req, res)
}

// ModifyLease modifies the lease of a task.
// Used to request more processing time, or to abandon processing.
// leaseTime is in seconds and must not be negative.
func ModifyLease(c context.Context, task *Task, queueName string, leaseTime int) error {
	if queueName == "" {
		queueName = "default"
	}
	req := &pb.TaskQueueModifyTaskLeaseRequest{
		QueueName:    []byte(queueName),
		TaskName:     []byte(task.Name),
		EtaUsec:      proto.Int64(task.ETA.UnixNano() / 1e3), // Used to verify ownership.
		LeaseSeconds: proto.Float64(float64(leaseTime)),
	}
	res := &pb.TaskQueueModifyTaskLeaseResponse{}
	if err := internal.Call(c, "taskqueue", "ModifyTaskLease", req, res); err != nil {
		return err
	}
	task.ETA = time.Unix(0, *res.UpdatedEtaUsec*1e3)
	return nil
}

// QueueStatistics represents statistics about a single task queue.
type QueueStatistics struct {
	Tasks     int       // may be an approximation
	OldestETA time.Time // zero if there are no pending tasks

	Executed1Minute int     // tasks executed in the last minute
	InFlight        int     // tasks executing now
	EnforcedRate    float64 // requests per second
}

// QueueStats retrieves statistics about queues.
func QueueStats(c context.Context, queueNames []string) ([]QueueStatistics, error) {
	req := &pb.TaskQueueFetchQueueStatsRequest{
		QueueName: make([][]byte, len(queueNames)),
	}
	for i, q := range queueNames {
		if q == "" {
			q = "default"
		}
		req.QueueName[i] = []byte(q)
	}
	res := &pb.TaskQueueFetchQueueStatsResponse{}
	if err := internal.Call(c, "taskqueue", "FetchQueueStats", req, res); err != nil {
		return nil, err
	}
	qs := make([]QueueStatistics, len(res.Queuestats))
	for i, qsg := range res.Queuestats {
		qs[i] = QueueStatistics{
			Tasks: int(*qsg.NumTasks),
		}
		if eta := *qsg.OldestEtaUsec; eta > -1 {
			qs[i].OldestETA = time.Unix(0, eta*1e3)
		}
		if si := qsg.ScannerInfo; si != nil {
			qs[i].Executed1Minute = int(*si.ExecutedLastMinute)
			qs[i].InFlight = int(si.GetRequestsInFlight())
			qs[i].EnforcedRate = si.GetEnforcedRate()
		}
	}
	return qs, nil
}

func setTransaction(x *pb.TaskQueueAddRequest, t *dspb.Transaction) {
	x.Transaction = t
}

func init() {
	internal.RegisterErrorCodeMap("taskqueue", pb.TaskQueueServiceError_ErrorCode_name)

	// Datastore error codes are shifted by DATASTORE_ERROR when presented through taskqueue.
	dsCode := int32(pb.TaskQueueServiceError_DATASTORE_ERROR) + int32(dspb.Error_TIMEOUT)
	internal.RegisterTimeoutErrorCode("taskqueue", dsCode)

	// Transaction registration.
	internal.RegisterTransactionSetter(setTransaction)
	internal.RegisterTransactionSetter(func(x *pb.TaskQueueBulkAddRequest, t *dspb.Transaction) {
		for _, req := range x.AddRequest {
			setTransaction(req, t)
		}
	})
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package taskqueue

import (
	"errors"
	"fmt"
	"reflect"
	"testing"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/taskqueue"
)

func TestAddErrors(t *testing.T) {
	var tests = []struct {
		err, want error
		sameErr   bool // if true, should return err exactly
	}{
		{
			err: &internal.APIError{
				Service: "taskqueue",
				Code:    int32(pb.TaskQueueServiceError_TASK_ALREADY_EXISTS),
			},
			want: ErrTaskAlreadyAdded,
		},
		{
			err: &internal.APIError{
				Service: "taskqueue",
				Code:    int32(pb.TaskQueueServiceError_TOMBSTONED_TASK),
			},
			want: ErrTaskAlreadyAdded,
		},
		{
			err: &internal.APIError{
				Service: "taskqueue",
				Code:    int32(pb.TaskQueueServiceError_UNKNOWN_QUEUE),
			},
			want:    errors.New("not used"),
			sameErr: true,
		},
	}
	for _, tc := range tests {
		c := aetesting.FakeSingleContext(t, "taskqueue", "Add", func(req *pb.TaskQueueAddRequest, res *pb.TaskQueueAddResponse) error {
			// don't fill in any of the response
			return tc.err
		})
		task := &Task{Path: "/worker", Method: "PULL"}
		_, err := Add(c, task, "a-queue")
		want := tc.want
		if tc.sameErr {
			want = tc.err
		}
		if err != want {
			t.Errorf("Add with tc.err = %v, got %#v, want = %#v", tc.err, err, want)
		}
	}
}

func TestAddMulti(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "taskqueue", "BulkAdd", func(req *pb.TaskQueueBulkAddRequest, res *pb.TaskQueueBulkAddResponse) error {
		res.Taskresult = []*pb.TaskQueueBulkAddResponse_TaskResult{
			{
				Result: pb.TaskQueueServiceError_OK.Enum(),
			},
			{
				Result: pb.TaskQueueServiceError_TASK_ALREADY_EXISTS.Enum(),
			},
			{
				Result: pb.TaskQueueServiceError_TOMBSTONED_TASK.Enum(),
			},
			{
				Result: pb.TaskQueueServiceError_INTERNAL_ERROR.Enum(),
			},
		}
		return nil
	})
	tasks := []*Task{
		{Path: "/worker", Method: "PULL"},
		{Path: "/worker", Method: "PULL"},
		{Path: "/worker", Method: "PULL"},
		{Path: "/worker", Method: "PULL"},
	}
	r, err := AddMulti(c, tasks, "a-queue")
	if len(r) != len(tasks) {
		t.Fatalf("AddMulti returned %d tasks, want %d", len(r), len(tasks))
	}
	want := appengine.MultiError{
		nil,
		ErrTaskAlreadyAdded,
		ErrTaskAlreadyAdded,
		&internal.APIError{
			Service: "taskqueue",
			Code:    int32(pb.TaskQueueServiceError_INTERNAL_ERROR),
		},
	}
	if !reflect.DeepEqual(err, want) {
		t.Errorf("AddMulti got %v, wanted %v", err, want)
	}
}

func TestAddWithEmptyPath(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "taskqueue", "Add", func(req *pb.TaskQueueAddRequest, res *pb.TaskQueueAddResponse) error {
		if got, want := string(req.Url), "/_ah/queue/a-queue"; got != want {
			return fmt.Errorf("req.Url = %q; want %q", got, want)
		}
		return nil
	})
	if _, err := Add(c, &Task{}, "a-queue"); err != nil {
		t.Fatalf("Add: %v", err)
	}
}


text:
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package cloudsql exposes access to Google Cloud SQL databases.

This package does not work in App Engine "flexible environment".

This package is intended for MySQL drivers to make App Engine-specific
connections. Applications should use this package through database/sql:
Select a pure Go MySQL driver that supports this package, and use sql.Open
with protocol "cloudsql" and an address of the Cloud SQL instance.

A Go MySQL driver that has been tested to work well with Cloud SQL
is the go-sql-driver:
	import "database/sql"
	import _ "github.com/go-sql-driver/mysql"

	db, err := sql.Open("mysql", "user@cloudsql(project-id:instance-name)/dbname")

Another driver that works well with Cloud SQL is the mymysql driver:
	import "database/sql"
	import _ "github.com/ziutek/mymysql/godrv"

	db, err := sql.Open("mymysql", "cloudsql:instance-name*dbname/user/password")

Using either of these drivers, you can perform a standard SQL query.
This example assumes there is a table named 'users' with
columns 'first_name' and 'last_name':

	rows, err := db.Query("SELECT first_name, last_name FROM users")
	if err != nil {
		log.Errorf(ctx, "db.Query: %v", err)
	}
	defer rows.Close()

	for rows.Next() {
		var firstName string
		var lastName string
		if err := rows.Scan(&firstName, &lastName); err != nil {
			log.Errorf(ctx, "rows.Scan: %v", err)
			continue
		}
		log.Infof(ctx, "First: %v - Last: %v", firstName, lastName)
	}
	if err := rows.Err(); err != nil {
		log.Errorf(ctx, "Row error: %v", err)
	}
*/
package cloudsql

import (
	"net"
)

// Dial connects to the named Cloud SQL instance.
func Dial(instance string) (net.Conn, error) {
	return connect(instance)
}


text:
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build appengine

package cloudsql

import (
	"net"

	"appengine/cloudsql"
)

func connect(instance string) (net.Conn, error) {
	return cloudsql.Dial(instance)
}


text:
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package cloudsql

import (
	"errors"
	"net"
)

func connect(instance string) (net.Conn, error) {
	return nil, errors.New(`cloudsql: not supported in App Engine "flexible environment"`)
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// Package file provides helper functions for using Google Cloud Storage.
package file

import (
	"fmt"

	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
	aipb "google.golang.org/appengine/internal/app_identity"
)

// DefaultBucketName returns the name of this application's
// default Google Cloud Storage bucket.
func DefaultBucketName(c context.Context) (string, error) {
	req := &aipb.GetDefaultGcsBucketNameRequest{}
	res := &aipb.GetDefaultGcsBucketNameResponse{}

	err := internal.Call(c, "app_identity_service", "GetDefaultGcsBucketName", req, res)
	if err != nil {
		return "", fmt.Errorf("file: no default bucket name returned in RPC response: %v", res)
	}
	return res.GetDefaultGcsBucketName(), nil
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// This example only works on App Engine "flexible environment".
// +build !appengine

package main

import (
	"html/template"
	"net/http"
	"time"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
)

var initTime = time.Now()

func main() {
	http.HandleFunc("/", handle)
	appengine.Main()
}

func handle(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}

	ctx := appengine.NewContext(r)
	log.Infof(ctx, "Serving the front page.")

	tmpl.Execute(w, time.Since(initTime))
}

var tmpl = template.Must(template.New("front").Parse(`

Hello, World! 세상아 안녕!

This instance has been running for {{.}}.

`))


text:
runtime: go
api_version: go1
vm: true

handlers:
- url: /favicon.ico
  static_files: favicon.ico
  upload: favicon.ico
- url: /.*
  script: _go_app


text:
# Demo application for App Engine "flexible environment".
runtime: go
vm: true
api_version: go1

handlers:
# Favicon.  Without this, the browser hits this once per page view.
- url: /favicon.ico
  static_files: favicon.ico
  upload: favicon.ico

# Main app.  All the real work is here.
- url: /.*
  script: _go_app


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// This example only works on App Engine "flexible environment".
// +build !appengine

package main

import (
	"html/template"
	"net/http"
	"time"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"
)

var initTime time.Time

type Greeting struct {
	Author  string
	Content string
	Date    time.Time
}

func main() {
	http.HandleFunc("/", handleMainPage)
	http.HandleFunc("/sign", handleSign)
	appengine.Main()
}

// guestbookKey returns the key used for all guestbook entries.
func guestbookKey(ctx context.Context) *datastore.Key {
	// The string "default_guestbook" here could be varied to have multiple guestbooks.
	return datastore.NewKey(ctx, "Guestbook", "default_guestbook", 0, nil)
}

var tpl = template.Must(template.ParseGlob("templates/*.html"))

func handleMainPage(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "GET requests only", http.StatusMethodNotAllowed)
		return
	}
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}

	ctx := appengine.NewContext(r)
	tic := time.Now()
	q := datastore.NewQuery("Greeting").Ancestor(guestbookKey(ctx)).Order("-Date").Limit(10)
	var gg []*Greeting
	if _, err := q.GetAll(ctx, &gg); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Errorf(ctx, "GetAll: %v", err)
		return
	}
	log.Infof(ctx, "Datastore lookup took %s", time.Since(tic).String())
	log.Infof(ctx, "Rendering %d greetings", len(gg))

	var email, logout, login string
	if u := user.Current(ctx); u != nil {
		logout, _ = user.LogoutURL(ctx, "/")
		email = u.Email
	} else {
		login, _ = user.LoginURL(ctx, "/")
	}
	data := struct {
		Greetings            []*Greeting
		Login, Logout, Email string
	}{
		Greetings: gg,
		Login:     login,
		Logout:    logout,
		Email:     email,
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if err := tpl.ExecuteTemplate(w, "guestbook.html", data); err != nil {
		log.Errorf(ctx, "%v", err)
	}
}

func handleSign(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "POST requests only", http.StatusMethodNotAllowed)
		return
	}
	ctx := appengine.NewContext(r)
	g := &Greeting{
		Content: r.FormValue("content"),
		Date:    time.Now(),
	}
	if u := user.Current(ctx); u != nil {
		g.Author = u.String()
	}
	key := datastore.NewIncompleteKey(ctx, "Greeting", guestbookKey(ctx))
	if _, err := datastore.Put(ctx, key, g); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// Redirect with 303 which causes the subsequent request to use GET.
	http.Redirect(w, r, "/", http.StatusSeeOther)
}


text:
indexes:

- kind: Greeting
  ancestor: yes
  properties:
  - name: Date
    direction: desc


text:
<!DOCTYPE html>

    <title>Guestbook Demo</title>

      {{with .Email}}You are currently logged in as {{.}}.{{end}}
      {{with .Login}}Sign in{{end}}
      {{with .Logout}}Sign out{{end}}

    {{range .Greetings }}

      {{with .Author}}{{.}}{{else}}An anonymous person{{end}}
      on {{.Date.Format "3:04pm, Mon 2 Jan"}}
      wrote
{{.Content}}

    {{end}}

    <form action="/sign" method="post">

<textarea name="content" rows="3" cols="60"></textarea>

<input type="submit" value="Sign Guestbook">

    </form>


text:
// Copyright 2011 Google Inc. All Rights Reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"testing"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine/internal"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/datastore"
)

var (
	path1 = &pb.Path{
		Element: []*pb.Path_Element{
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(6),
			},
		},
	}
	path2 = &pb.Path{
		Element: []*pb.Path_Element{
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(6),
			},
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(8),
			},
		},
	}
)

func fakeRunQuery(in *pb.Query, out *pb.QueryResult) error {
	expectedIn := &pb.Query{
		App:     proto.String("dev~fake-app"),
		Kind:    proto.String("Gopher"),
		Compile: proto.Bool(true),
	}
	if !proto.Equal(in, expectedIn) {
		return fmt.Errorf("unsupported argument: got %v want %v", in, expectedIn)
	}
	*out = pb.QueryResult{
		Result: []*pb.EntityProto{
			{
				Key: &pb.Reference{
					App:  proto.String("s~test-app"),
					Path: path1,
				},
				EntityGroup: path1,
				Property: []*pb.Property{
					{
						Meaning: pb.Property_TEXT.Enum(),
						Name:    proto.String("Name"),
						Value: &pb.PropertyValue{
							StringValue: proto.String("George"),
						},
					},
					{
						Name: proto.String("Height"),
						Value: &pb.PropertyValue{
							Int64Value: proto.Int64(32),
						},
					},
				},
			},
			{
				Key: &pb.Reference{
					App:  proto.String("s~test-app"),
					Path: path2,
				},
				EntityGroup: path1, // ancestor is George
				Property: []*pb.Property{
					{
						Meaning: pb.Property_TEXT.Enum(),
						Name:    proto.String("Name"),
						Value: &pb.PropertyValue{
							StringValue: proto.String("Rufus"),
						},
					},
					// No height for Rufus.
				},
			},
		},
		MoreResults: proto.Bool(false),
	}
	return nil
}

type StructThatImplementsPLS struct{}

func (StructThatImplementsPLS) Load(p []Property) error   { return nil }
func (StructThatImplementsPLS) Save() ([]Property, error) { return nil, nil }

var _ PropertyLoadSaver = StructThatImplementsPLS{}

type StructPtrThatImplementsPLS struct{}

func (*StructPtrThatImplementsPLS) Load(p []Property) error   { return nil }
func (*StructPtrThatImplementsPLS) Save() ([]Property, error) { return nil, nil }

var _ PropertyLoadSaver = &StructPtrThatImplementsPLS{}

type PropertyMap map[string]Property

func (m PropertyMap) Load(props []Property) error {
	for _, p := range props {
		if p.Multiple {
			return errors.New("PropertyMap does not support multiple properties")
		}
		m[p.Name] = p
	}
	return nil
}

func (m PropertyMap) Save() ([]Property, error) {
	props := make([]Property, 0, len(m))
	for _, p := range m {
		if p.Multiple {
			return nil, errors.New("PropertyMap does not support multiple properties")
		}
		props = append(props, p)
	}
	return props, nil
}

var _ PropertyLoadSaver = PropertyMap{}

type Gopher struct {
	Name   string
	Height int
}

// typeOfEmptyInterface is the type of interface{}, but we can't use
// reflect.TypeOf((interface{})(nil)) directly because TypeOf takes an
// interface{}.
var typeOfEmptyInterface = reflect.TypeOf((*interface{})(nil)).Elem()

func TestCheckMultiArg(t *testing.T) {
	testCases := []struct {
		v        interface{}
		mat      multiArgType
		elemType reflect.Type
	}{
		// Invalid cases.
		{nil, multiArgTypeInvalid, nil},
		{Gopher{}, multiArgTypeInvalid, nil},
		{&Gopher{}, multiArgTypeInvalid, nil},
		{PropertyList{}, multiArgTypeInvalid, nil}, // This is a special case.
		{PropertyMap{}, multiArgTypeInvalid, nil},
		{[]*PropertyList(nil), multiArgTypeInvalid, nil},
		{[]*PropertyMap(nil), multiArgTypeInvalid, nil},
		{[]**Gopher(nil), multiArgTypeInvalid, nil},
		{[]*interface{}(nil), multiArgTypeInvalid, nil},
		// Valid cases.
		{
			[]PropertyList(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(PropertyList{}),
		},
		{
			[]PropertyMap(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(PropertyMap{}),
		},
		{
			[]StructThatImplementsPLS(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(StructThatImplementsPLS{}),
		},
		{
			[]StructPtrThatImplementsPLS(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(StructPtrThatImplementsPLS{}),
		},
		{
			[]Gopher(nil),
			multiArgTypeStruct,
			reflect.TypeOf(Gopher{}),
		},
		{
			[]*Gopher(nil),
			multiArgTypeStructPtr,
			reflect.TypeOf(Gopher{}),
		},
		{
			[]interface{}(nil),
			multiArgTypeInterface,
			typeOfEmptyInterface,
		},
	}
	for _, tc := range testCases {
		mat, elemType := checkMultiArg(reflect.ValueOf(tc.v))
		if mat != tc.mat || elemType != tc.elemType {
			t.Errorf("checkMultiArg(%T): got %v, %v want %v, %v",
				tc.v, mat, elemType, tc.mat, tc.elemType)
		}
	}
}

func TestSimpleQuery(t *testing.T) {
	struct1 := Gopher{Name: "George", Height: 32}
	struct2 := Gopher{Name: "Rufus"}
	pList1 := PropertyList{
		{
			Name:  "Name",
			Value: "George",
		},
		{
			Name:  "Height",
			Value: int64(32),
		},
	}
	pList2 := PropertyList{
		{
			Name:  "Name",
			Value: "Rufus",
		},
	}
	pMap1 := PropertyMap{
		"Name": Property{
			Name:  "Name",
			Value: "George",
		},
		"Height": Property{
			Name:  "Height",
			Value: int64(32),
		},
	}
	pMap2 := PropertyMap{
		"Name": Property{
			Name:  "Name",
			Value: "Rufus",
		},
	}

	testCases := []struct {
		dst  interface{}
		want interface{}
	}{
		// The destination must have type *[]P, *[]S or *[]*S, for some non-interface
		// type P such that *P implements PropertyLoadSaver, or for some struct type S.
		{new([]Gopher), &[]Gopher{struct1, struct2}},
		{new([]*Gopher), &[]*Gopher{&struct1, &struct2}},
		{new([]PropertyList), &[]PropertyList{pList1, pList2}},
		{new([]PropertyMap), &[]PropertyMap{pMap1, pMap2}},

		// Any other destination type is invalid.
		{0, nil},
		{Gopher{}, nil},
		{PropertyList{}, nil},
		{PropertyMap{}, nil},
		{[]int{}, nil},
		{[]Gopher{}, nil},
		{[]PropertyList{}, nil},
		{new(int), nil},
		{new(Gopher), nil},
		{new(PropertyList), nil}, // This is a special case.
		{new(PropertyMap), nil},
		{new([]int), nil},
		{new([]map[int]int), nil},
		{new([]map[string]Property), nil},
		{new([]map[string]interface{}), nil},
		{new([]*int), nil},
		{new([]*map[int]int), nil},
		{new([]*map[string]Property), nil},
		{new([]*map[string]interface{}), nil},
		{new([]**Gopher), nil},
		{new([]*PropertyList), nil},
		{new([]*PropertyMap), nil},
	}
	for _, tc := range testCases {
		nCall := 0
		c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
			nCall++
			return fakeRunQuery(in, out)
		})
		c = internal.WithAppIDOverride(c, "dev~fake-app")

		var (
			expectedErr   error
			expectedNCall int
		)
		if tc.want == nil {
			expectedErr = ErrInvalidEntityType
		} else {
			expectedNCall = 1
		}
		keys, err := NewQuery("Gopher").GetAll(c, tc.dst)
		if err != expectedErr {
			t.Errorf("dst type %T: got error [%v], want [%v]", tc.dst, err, expectedErr)
			continue
		}
		if nCall != expectedNCall {
			t.Errorf("dst type %T: Context.Call was called an incorrect number of times: got %d want %d", tc.dst, nCall, expectedNCall)
			continue
		}
		if err != nil {
			continue
		}

		key1 := NewKey(c, "Gopher", "", 6, nil)
		expectedKeys := []*Key{
			key1,
			NewKey(c, "Gopher", "", 8, key1),
		}
		if l1, l2 := len(keys), len(expectedKeys); l1 != l2 {
			t.Errorf("dst type %T: got %d keys, want %d keys", tc.dst, l1, l2)
			continue
		}
		for i, key := range keys {
			if key.AppID() != "s~test-app" {
				t.Errorf(`dst type %T: Key #%d's AppID = %q, want "s~test-app"`, tc.dst, i, key.AppID())
				continue
			}
			if !keysEqual(key, expectedKeys[i]) {
				t.Errorf("dst type %T: got key #%d %v, want %v", tc.dst, i, key, expectedKeys[i])
				continue
			}
		}

		if !reflect.DeepEqual(tc.dst, tc.want) {
			t.Errorf("dst type %T: Entities got %+v, want %+v", tc.dst, tc.dst, tc.want)
			continue
		}
	}
}

// keysEqual is like (*Key).Equal, but ignores the App ID.
func keysEqual(a, b *Key) bool {
	for a != nil && b != nil {
		if a.Kind() != b.Kind() || a.StringID() != b.StringID() || a.IntID() != b.IntID() {
			return false
		}
		a, b = a.Parent(), b.Parent()
	}
	return a == b
}

func TestQueriesAreImmutable(t *testing.T) {
	// Test that deriving q2 from q1 does not modify q1.
	q0 := NewQuery("foo")
	q1 := NewQuery("foo")
	q2 := q1.Offset(2)
	if !reflect.DeepEqual(q0, q1) {
		t.Errorf("q0 and q1 were not equal")
	}
	if reflect.DeepEqual(q1, q2) {
		t.Errorf("q1 and q2 were equal")
	}

	// Test that deriving from q4 twice does not conflict, even though
	// q4 has a long list of order clauses. This tests that the arrays
	// backed by a query's slice of orders are not shared.
	f := func() *Query {
		q := NewQuery("bar")
		// 47 is an ugly number that is unlikely to be near a re-allocation
		// point in repeated append calls. For example, it's not near a power
		// of 2 or a multiple of 10.
		for i := 0; i < 47; i++ {
			q = q.Order(fmt.Sprintf("x%d", i))
		}
		return q
	}
	q3 := f().Order("y")
	q4 := f()
	q5 := q4.Order("y")
	q6 := q4.Order("z")
	if !reflect.DeepEqual(q3, q5) {
		t.Errorf("q3 and q5 were not equal")
	}
	if reflect.DeepEqual(q5, q6) {
		t.Errorf("q5 and q6 were equal")
	}
}

func TestFilterParser(t *testing.T) {
	testCases := []struct {
		filterStr     string
		wantOK        bool
		wantFieldName string
		wantOp        operator
	}{
		// Supported ops.
		{"x<", true, "x", lessThan},
		{"x <", true, "x", lessThan},
		{"x  <", true, "x", lessThan},
		{"   x   <  ", true, "x", lessThan},
		{"x <=", true, "x", lessEq},
		{"x =", true, "x", equal},
		{"x >=", true, "x", greaterEq},
		{"x >", true, "x", greaterThan},
		{"in >", true, "in", greaterThan},
		{"in>", true, "in", greaterThan},
		// Valid but (currently) unsupported ops.
		{"x!=", false, "", 0},
		{"x !=", false, "", 0},
		{" x  !=  ", false, "", 0},
		{"x IN", false, "", 0},
		{"x in", false, "", 0},
		// Invalid ops.
		{"x EQ", false, "", 0},
		{"x lt", false, "", 0},
		{"x <>", false, "", 0},
		{"x >>", false, "", 0},
		{"x ==", false, "", 0},
		{"x =<", false, "", 0},
		{"x =>", false, "", 0},
		{"x !", false, "", 0},
		{"x ", false, "", 0},
		{"x", false, "", 0},
	}
	for _, tc := range testCases {
		q := NewQuery("foo").Filter(tc.filterStr, 42)
		if ok := q.err == nil; ok != tc.wantOK {
			t.Errorf("%q: ok=%t, want %t", tc.filterStr, ok, tc.wantOK)
			continue
		}
		if !tc.wantOK {
			continue
		}
		if len(q.filter) != 1 {
			t.Errorf("%q: len=%d, want %d", tc.filterStr, len(q.filter), 1)
			continue
		}
		got, want := q.filter[0], filter{tc.wantFieldName, tc.wantOp, 42}
		if got != want {
			t.Errorf("%q: got %v, want %v", tc.filterStr, got, want)
			continue
		}
	}
}

func TestQueryToProto(t *testing.T) {
	// The context is required to make Keys for the test cases.
	var got *pb.Query
	NoErr := errors.New("No error")
	c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
		got = in
		return NoErr // return a non-nil error so Run doesn't keep going.
	})
	c = internal.WithAppIDOverride(c, "dev~fake-app")

	testCases := []struct {
		desc  string
		query *Query
		want  *pb.Query
		err   string
	}{
		{
			desc:  "empty",
			query: NewQuery(""),
			want:  &pb.Query{},
		},
		{
			desc:  "standard query",
			query: NewQuery("kind").Order("-I").Filter("I >", 17).Filter("U =", "Dave").Limit(7).Offset(42),
			want: &pb.Query{
				Kind: proto.String("kind"),
				Filter: []*pb.Query_Filter{
					{
						Op: pb.Query_Filter_GREATER_THAN.Enum(),
						Property: []*pb.Property{
							{
								Name:     proto.String("I"),
								Value:    &pb.PropertyValue{Int64Value: proto.Int64(17)},
								Multiple: proto.Bool(false),
							},
						},
					},
					{
						Op: pb.Query_Filter_EQUAL.Enum(),
						Property: []*pb.Property{
							{
								Name:     proto.String("U"),
								Value:    &pb.PropertyValue{StringValue: proto.String("Dave")},
								Multiple: proto.Bool(false),
							},
						},
					},
				},
				Order: []*pb.Query_Order{
					{
						Property:  proto.String("I"),
						Direction: pb.Query_Order_DESCENDING.Enum(),
					},
				},
				Limit:  proto.Int32(7),
				Offset: proto.Int32(42),
			},
		},
		{
			desc:  "ancestor",
			query: NewQuery("").Ancestor(NewKey(c, "kind", "Mummy", 0, nil)),
			want: &pb.Query{
				Ancestor: &pb.Reference{
					App: proto.String("dev~fake-app"),
					Path: &pb.Path{
						Element: []*pb.Path_Element{{Type: proto.String("kind"), Name: proto.String("Mummy")}},
					},
				},
			},
		},
		{
			desc:  "projection",
			query: NewQuery("").Project("A", "B"),
			want: &pb.Query{
				PropertyName: []string{"A", "B"},
			},
		},
		{
			desc:  "projection with distinct",
			query: NewQuery("").Project("A", "B").Distinct(),
			want: &pb.Query{
				PropertyName:        []string{"A", "B"},
				GroupByPropertyName: []string{"A", "B"},
			},
		},
		{
			desc:  "keys only",
			query: NewQuery("").KeysOnly(),
			want: &pb.Query{
				KeysOnly:           proto.Bool(true),
				RequirePerfectPlan: proto.Bool(true),
			},
		},
		{
			desc:  "empty filter",
			query: NewQuery("kind").Filter("=", 17),
			err:   "empty query filter field nam",
		},
		{
			desc:  "bad filter type",
			query: NewQuery("kind").Filter("M =", map[string]bool{}),
			err:   "bad query filter value type",
		},
		{
			desc:  "bad filter operator",
			query: NewQuery("kind").Filter("I <<=", 17),
			err:   `invalid operator "<<=" in filter "I <<="`,
		},
		{
			desc:  "empty order",
			query: NewQuery("kind").Order(""),
			err:   "empty order",
		},
		{
			desc:  "bad order direction",
			query: NewQuery("kind").Order("+I"),
			err:   `invalid order: "+I`,
		},
	}

	for _, tt := range testCases {
		got = nil
		if _, err := tt.query.Run(c).Next(nil); err != NoErr {
			if tt.err == "" || !strings.Contains(err.Error(), tt.err) {
				t.Errorf("%s: error %v, want %q", tt.desc, err, tt.err)
			}
			continue
		}
		if tt.err != "" {
			t.Errorf("%s: no error, want %q", tt.desc, tt.err)
			continue
		}
		// Fields that are common to all protos.
		tt.want.App = proto.String("dev~fake-app")
		tt.want.Compile = proto.Bool(true)
		if !proto.Equal(got, tt.want) {
			t.Errorf("%s:\ngot  %v\nwant %v", tt.desc, got, tt.want)
		}
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"errors"

	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/datastore"
)

func init() {
	internal.RegisterTransactionSetter(func(x *pb.Query, t *pb.Transaction) {
		x.Transaction = t
	})
	internal.RegisterTransactionSetter(func(x *pb.GetRequest, t *pb.Transaction) {
		x.Transaction = t
	})
	internal.RegisterTransactionSetter(func(x *pb.PutRequest, t *pb.Transaction) {
		x.Transaction = t
	})
	internal.RegisterTransactionSetter(func(x *pb.DeleteRequest, t *pb.Transaction) {
		x.Transaction = t
	})
}

// ErrConcurrentTransaction is returned when a transaction is rolled back due
// to a conflict with a concurrent transaction.
var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction")

// RunInTransaction runs f in a transaction. It calls f with a transaction
// context tc that f should use for all App Engine operations.
//
// If f returns nil, RunInTransaction attempts to commit the transaction,
// returning nil if it succeeds. If the commit fails due to a conflicting
// transaction, RunInTransaction retries f, each time with a new transaction
// context. It gives up and returns ErrConcurrentTransaction after three
// failed attempts. The number of attempts can be configured by specifying
// TransactionOptions.Attempts.
//
// If f returns non-nil, then any datastore changes will not be applied and
// RunInTransaction returns that same error. The function f is not retried.
//
// Note that when f returns, the transaction is not yet committed. Calling code
// must be careful not to assume that any of f's changes have been committed
// until RunInTransaction returns nil.
//
// Since f may be called multiple times, f should usually be idempotent.
// datastore.Get is not idempotent when unmarshaling slice fields.
//
// Nested transactions are not supported; c may not be a transaction context.
func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error {
	xg := false
	if opts != nil {
		xg = opts.XG
	}
	attempts := 3
	if opts != nil && opts.Attempts > 0 {
		attempts = opts.Attempts
	}
	for i := 0; i < attempts; i++ {
		if err := internal.RunTransactionOnce(c, f, xg); err != internal.ErrConcurrentTransaction {
			return err
		}
	}
	return ErrConcurrentTransaction
}

// TransactionOptions are the options for running a transaction.
type TransactionOptions struct {
	// XG is whether the transaction can cross multiple entity groups. In
	// comparison, a single group transaction is one where all datastore keys
	// used have the same root key. Note that cross group transactions do not
	// have the same behavior as single group transactions. In particular, it
	// is much more likely to see partially applied transactions in different
	// entity groups, in global queries.
	// It is valid to set XG to true even if the transaction is within a
	// single entity group.
	XG bool
	// Attempts controls the number of retries to perform when commits fail
	// due to a conflicting transaction. If omitted, it defaults to 3.
	Attempts int
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"errors"
	"fmt"
	"reflect"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/datastore"
)

var (
	// ErrInvalidEntityType is returned when functions like Get or Next are
	// passed a dst or src argument of invalid type.
	ErrInvalidEntityType = errors.New("datastore: invalid entity type")
	// ErrInvalidKey is returned when an invalid key is presented.
	ErrInvalidKey = errors.New("datastore: invalid key")
	// ErrNoSuchEntity is returned when no entity was found for a given key.
	ErrNoSuchEntity = errors.New("datastore: no such entity")
)

// ErrFieldMismatch is returned when a field is to be loaded into a different
// type than the one it was stored from, or when a field is missing or
// unexported in the destination struct.
// StructType is the type of the struct pointed to by the destination argument
// passed to Get or to Iterator.Next.
type ErrFieldMismatch struct {
	StructType reflect.Type
	FieldName  string
	Reason     string
}

func (e *ErrFieldMismatch) Error() string {
	return fmt.Sprintf("datastore: cannot load field %q into a %q: %s",
		e.FieldName, e.StructType, e.Reason)
}

// protoToKey converts a Reference proto to a *Key.
func protoToKey(r *pb.Reference) (k *Key, err error) {
	appID := r.GetApp()
	namespace := r.GetNameSpace()
	for _, e := range r.Path.Element {
		k = &Key{
			kind:      e.GetType(),
			stringID:  e.GetName(),
			intID:     e.GetId(),
			parent:    k,
			appID:     appID,
			namespace: namespace,
		}
		if !k.valid() {
			return nil, ErrInvalidKey
		}
	}
	return
}

// keyToProto converts a *Key to a Reference proto.
func keyToProto(defaultAppID string, k *Key) *pb.Reference {
	appID := k.appID
	if appID == "" {
		appID = defaultAppID
	}
	n := 0
	for i := k; i != nil; i = i.parent {
		n++
	}
	e := make([]*pb.Path_Element, n)
	for i := k; i != nil; i = i.parent {
		n--
		e[n] = &pb.Path_Element{
			Type: &i.kind,
		}
		// At most one of {Name,Id} should be set.
		// Neither will be set for incomplete keys.
		if i.stringID != "" {
			e[n].Name = &i.stringID
		} else if i.intID != 0 {
			e[n].Id = &i.intID
		}
	}
	var namespace *string
	if k.namespace != "" {
		namespace = proto.String(k.namespace)
	}
	return &pb.Reference{
		App:       proto.String(appID),
		NameSpace: namespace,
		Path: &pb.Path{
			Element: e,
		},
	}
}

// multiKeyToProto is a batch version of keyToProto.
func multiKeyToProto(appID string, key []*Key) []*pb.Reference {
	ret := make([]*pb.Reference, len(key))
	for i, k := range key {
		ret[i] = keyToProto(appID, k)
	}
	return ret
}

// multiValid is a batch version of Key.valid. It returns an error, not a
// []bool.
func multiValid(key []*Key) error {
	invalid := false
	for _, k := range key {
		if !k.valid() {
			invalid = true
			break
		}
	}
	if !invalid {
		return nil
	}
	err := make(appengine.MultiError, len(key))
	for i, k := range key {
		if !k.valid() {
			err[i] = ErrInvalidKey
		}
	}
	return err
}

// It's unfortunate that the two semantically equivalent concepts pb.Reference
// and pb.PropertyValue_ReferenceValue aren't the same type. For example, the
// two have different protobuf field numbers.

// referenceValueToKey is the same as protoToKey except the input is a
// PropertyValue_ReferenceValue instead of a Reference.
func referenceValueToKey(r *pb.PropertyValue_ReferenceValue) (k *Key, err error) {
	appID := r.GetApp()
	namespace := r.GetNameSpace()
	for _, e := range r.Pathelement {
		k = &Key{
			kind:      e.GetType(),
			stringID:  e.GetName(),
			intID:     e.GetId(),
			parent:    k,
			appID:     appID,
			namespace: namespace,
		}
		if !k.valid() {
			return nil, ErrInvalidKey
		}
	}
	return
}

// keyToReferenceValue is the same as keyToProto except the output is a
// PropertyValue_ReferenceValue instead of a Reference.
func keyToReferenceValue(defaultAppID string, k *Key) *pb.PropertyValue_ReferenceValue {
	ref := keyToProto(defaultAppID, k)
	pe := make([]*pb.PropertyValue_ReferenceValue_PathElement, len(ref.Path.Element))
	for i, e := range ref.Path.Element {
		pe[i] = &pb.PropertyValue_ReferenceValue_PathElement{
			Type: e.Type,
			Id:   e.Id,
			Name: e.Name,
		}
	}
	return &pb.PropertyValue_ReferenceValue{
		App:         ref.App,
		NameSpace:   ref.NameSpace,
		Pathelement: pe,
	}
}

type multiArgType int

const (
	multiArgTypeInvalid multiArgType = iota
	multiArgTypePropertyLoadSaver
	multiArgTypeStruct
	multiArgTypeStructPtr
	multiArgTypeInterface
)

// checkMultiArg checks that v has type []S, []*S, []I, or []P, for some struct
// type S, for some interface type I, or some non-interface non-pointer type P
// such that P or *P implements PropertyLoadSaver.
//
// It returns what category the slice's elements are, and the reflect.Type
// that represents S, I or P.
//
// As a special case, PropertyList is an invalid type for v.
func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) {
	if v.Kind() != reflect.Slice {
		return multiArgTypeInvalid, nil
	}
	if v.Type() == typeOfPropertyList {
		return multiArgTypeInvalid, nil
	}
	elemType = v.Type().Elem()
	if reflect.PtrTo(elemType).Implements(typeOfPropertyLoadSaver) {
		return multiArgTypePropertyLoadSaver, elemType
	}
	switch elemType.Kind() {
	case reflect.Struct:
		return multiArgTypeStruct, elemType
	case reflect.Interface:
		return multiArgTypeInterface, elemType
	case reflect.Ptr:
		elemType = elemType.Elem()
		if elemType.Kind() == reflect.Struct {
			return multiArgTypeStructPtr, elemType
		}
	}
	return multiArgTypeInvalid, nil
}

// Get loads the entity stored for k into dst, which must be a struct pointer
// or implement PropertyLoadSaver. If there is no such entity for the key, Get
// returns ErrNoSuchEntity.
//
// The values of dst's unmatched struct fields are not modified, and matching
// slice-typed fields are not reset before appending to them. In particular, it
// is recommended to pass a pointer to a zero valued struct on each Get call.
//
// ErrFieldMismatch is returned when a field is to be loaded into a different
// type than the one it was stored from, or when a field is missing or
// unexported in the destination struct. ErrFieldMismatch is only returned if
// dst is a struct pointer.
func Get(c context.Context, key *Key, dst interface{}) error {
	if dst == nil { // GetMulti catches nil interface; we need to catch nil ptr here
		return ErrInvalidEntityType
	}
	err := GetMulti(c, []*Key{key}, []interface{}{dst})
	if me, ok := err.(appengine.MultiError); ok {
		return me[0]
	}
	return err
}

// GetMulti is a batch version of Get.
//
// dst must be a []S, []*S, []I or []P, for some struct type S, some interface
// type I, or some non-interface non-pointer type P such that P or *P
// implements PropertyLoadSaver. If an []I, each element must be a valid dst
// for Get: it must be a struct pointer or implement PropertyLoadSaver.
//
// As a special case, PropertyList is an invalid type for dst, even though a
// PropertyList is a slice of structs. It is treated as invalid to avoid being
// mistakenly passed when []PropertyList was intended.
func GetMulti(c context.Context, key []*Key, dst interface{}) error {
	v := reflect.ValueOf(dst)
	multiArgType, _ := checkMultiArg(v)
	if multiArgType == multiArgTypeInvalid {
		return errors.New("datastore: dst has invalid type")
	}
	if len(key) != v.Len() {
		return errors.New("datastore: key and dst slices have different length")
	}
	if len(key) == 0 {
		return nil
	}
	if err := multiValid(key); err != nil {
		return err
	}
	req := &pb.GetRequest{
		Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
	}
	res := &pb.GetResponse{}
	if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil {
		return err
	}
	if len(key) != len(res.Entity) {
		return errors.New("datastore: internal error: server returned the wrong number of entities")
	}
	multiErr, any := make(appengine.MultiError, len(key)), false
	for i, e := range res.Entity {
		if e.Entity == nil {
			multiErr[i] = ErrNoSuchEntity
		} else {
			elem := v.Index(i)
			if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
				elem = elem.Addr()
			}
			if multiArgType == multiArgTypeStructPtr && elem.IsNil() {
				elem.Set(reflect.New(elem.Type().Elem()))
			}
			multiErr[i] = loadEntity(elem.Interface(), e.Entity)
		}
		if multiErr[i] != nil {
			any = true
		}
	}
	if any {
		return multiErr
	}
	return nil
}

// Put saves the entity src into the datastore with key k. src must be a struct
// pointer or implement PropertyLoadSaver; if a struct pointer then any
// unexported fields of that struct will be skipped. If k is an incomplete key,
// the returned key will be a unique key generated by the datastore.
func Put(c context.Context, key *Key, src interface{}) (*Key, error) {
	k, err := PutMulti(c, []*Key{key}, []interface{}{src})
	if err != nil {
		if me, ok := err.(appengine.MultiError); ok {
			return nil, me[0]
		}
		return nil, err
	}
	return k[0], nil
}

// PutMulti is a batch version of Put.
//
// src must satisfy the same conditions as the dst argument to GetMulti.
func PutMulti(c context.Context, key []*Key, src interface{}) ([]*Key, error) {
	v := reflect.ValueOf(src)
	multiArgType, _ := checkMultiArg(v)
	if multiArgType == multiArgTypeInvalid {
		return nil, errors.New("datastore: src has invalid type")
	}
	if len(key) != v.Len() {
		return nil, errors.New("datastore: key and src slices have different length")
	}
	if len(key) == 0 {
		return nil, nil
	}
	appID := internal.FullyQualifiedAppID(c)
	if err := multiValid(key); err != nil {
		return nil, err
	}
	req := &pb.PutRequest{}
	for i := range key {
		elem := v.Index(i)
		if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
			elem = elem.Addr()
		}
		sProto, err := saveEntity(appID, key[i], elem.Interface())
		if err != nil {
			return nil, err
		}
		req.Entity = append(req.Entity, sProto)
	}
	res := &pb.PutResponse{}
	if err := internal.Call(c, "datastore_v3", "Put", req, res); err != nil {
		return nil, err
	}
	if len(key) != len(res.Key) {
		return nil, errors.New("datastore: internal error: server returned the wrong number of keys")
	}
	ret := make([]*Key, len(key))
	for i := range ret {
		var err error
		ret[i], err = protoToKey(res.Key[i])
		if err != nil || ret[i].Incomplete() {
			return nil, errors.New("datastore: internal error: server returned an invalid key")
		}
	}
	return ret, nil
}

// Delete deletes the entity for the given key.
func Delete(c context.Context, key *Key) error {
	err := DeleteMulti(c, []*Key{key})
	if me, ok := err.(appengine.MultiError); ok {
		return me[0]
	}
	return err
}

// DeleteMulti is a batch version of Delete.
func DeleteMulti(c context.Context, key []*Key) error {
	if len(key) == 0 {
		return nil
	}
	if err := multiValid(key); err != nil {
		return err
	}
	req := &pb.DeleteRequest{
		Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
	}
	res := &pb.DeleteResponse{}
	return internal.Call(c, "datastore_v3", "Delete", req, res)
}

func namespaceMod(m proto.Message, namespace string) {
	// pb.Query is the only type that has a name_space field.
	// All other namespace support in datastore is in the keys.
	switch m := m.(type) {
	case *pb.Query:
		if m.NameSpace == nil {
			m.NameSpace = &namespace
		}
	}
}

func init() {
	internal.NamespaceMods["datastore_v3"] = namespaceMod
	internal.RegisterErrorCodeMap("datastore_v3", pb.Error_ErrorCode_name)
	internal.RegisterTimeoutErrorCode("datastore_v3", int32(pb.Error_TIMEOUT))
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"fmt"
	"reflect"
	"time"

	"google.golang.org/appengine"
	pb "google.golang.org/appengine/internal/datastore"
)

var (
	typeOfBlobKey    = reflect.TypeOf(appengine.BlobKey(""))
	typeOfByteSlice  = reflect.TypeOf([]byte(nil))
	typeOfByteString = reflect.TypeOf(ByteString(nil))
	typeOfGeoPoint   = reflect.TypeOf(appengine.GeoPoint{})
	typeOfTime       = reflect.TypeOf(time.Time{})
)

// typeMismatchReason returns a string explaining why the property p could not
// be stored in an entity field of type v.Type().
func typeMismatchReason(p Property, v reflect.Value) string {
	entityType := "empty"
	switch p.Value.(type) {
	case int64:
		entityType = "int"
	case bool:
		entityType = "bool"
	case string:
		entityType = "string"
	case float64:
		entityType = "float"
	case *Key:
		entityType = "*datastore.Key"
	case time.Time:
		entityType = "time.Time"
	case appengine.BlobKey:
		entityType = "appengine.BlobKey"
	case appengine.GeoPoint:
		entityType = "appengine.GeoPoint"
	case ByteString:
		entityType = "datastore.ByteString"
	case []byte:
		entityType = "[]byte"
	}
	return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type())
}

type propertyLoader struct {
	// m holds the number of times a substruct field like "Foo.Bar.Baz" has
	// been seen so far. The map is constructed lazily.
	m map[string]int
}

func (l *propertyLoader) load(codec *structCodec, structValue reflect.Value, p Property, requireSlice bool) string {
	var v reflect.Value
	// Traverse a struct's struct-typed fields.
	for name := p.Name; ; {
		decoder, ok := codec.byName[name]
		if !ok {
			return "no such struct field"
		}
		v = structValue.Field(decoder.index)
		if !v.IsValid() {
			return "no such struct field"
		}
		if !v.CanSet() {
			return "cannot set struct field"
		}

		if decoder.substructCodec == nil {
			break
		}

		if v.Kind() == reflect.Slice {
			if l.m == nil {
				l.m = make(map[string]int)
			}
			index := l.m[p.Name]
			l.m[p.Name] = index + 1
			for v.Len() <= index {
				v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem()))
			}
			structValue = v.Index(index)
			requireSlice = false
		} else {
			structValue = v
		}
		// Strip the "I." from "I.X".
		name = name[len(codec.byIndex[decoder.index].name):]
		codec = decoder.substructCodec
	}

	var slice reflect.Value
	if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
		slice = v
		v = reflect.New(v.Type().Elem()).Elem()
	} else if requireSlice {
		return "multiple-valued property requires a slice field type"
	}

	// Convert indexValues to a Go value with a meaning derived from the
	// destination type.
	pValue := p.Value
	if iv, ok := pValue.(indexValue); ok {
		meaning := pb.Property_NO_MEANING
		switch v.Type() {
		case typeOfBlobKey:
			meaning = pb.Property_BLOBKEY
		case typeOfByteSlice:
			meaning = pb.Property_BLOB
		case typeOfByteString:
			meaning = pb.Property_BYTESTRING
		case typeOfGeoPoint:
			meaning = pb.Property_GEORSS_POINT
		case typeOfTime:
			meaning = pb.Property_GD_WHEN
		}
		var err error
		pValue, err = propValue(iv.value, meaning)
		if err != nil {
			return err.Error()
		}
	}

	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		x, ok := pValue.(int64)
		if !ok && pValue != nil {
			return typeMismatchReason(p, v)
		}
		if v.OverflowInt(x) {
			return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
		}
		v.SetInt(x)
	case reflect.Bool:
		x, ok := pValue.(bool)
		if !ok && pValue != nil {
			return typeMismatchReason(p, v)
		}
		v.SetBool(x)
	case reflect.String:
		switch x := pValue.(type) {
		case appengine.BlobKey:
			v.SetString(string(x))
		case ByteString:
			v.SetString(string(x))
		case string:
			v.SetString(x)
		default:
			if pValue != nil {
				return typeMismatchReason(p, v)
			}
		}
	case reflect.Float32, reflect.Float64:
		x, ok := pValue.(float64)
		if !ok && pValue != nil {
			return typeMismatchReason(p, v)
		}
		if v.OverflowFloat(x) {
			return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
		}
		v.SetFloat(x)
	case reflect.Ptr:
		x, ok := pValue.(*Key)
		if !ok && pValue != nil {
			return typeMismatchReason(p, v)
		}
		if _, ok := v.Interface().(*Key); !ok {
			return typeMismatchReason(p, v)
		}
		v.Set(reflect.ValueOf(x))
	case reflect.Struct:
		switch v.Type() {
		case typeOfTime:
			x, ok := pValue.(time.Time)
			if !ok && pValue != nil {
				return typeMismatchReason(p, v)
			}
			v.Set(reflect.ValueOf(x))
		case typeOfGeoPoint:
			x, ok := pValue.(appengine.GeoPoint)
			if !ok && pValue != nil {
				return typeMismatchReason(p, v)
			}
			v.Set(reflect.ValueOf(x))
		default:
			return typeMismatchReason(p, v)
		}
	case reflect.Slice:
		x, ok := pValue.([]byte)
		if !ok {
			if y, yok := pValue.(ByteString); yok {
				x, ok = []byte(y), true
			}
		}
		if !ok && pValue != nil {
			return typeMismatchReason(p, v)
		}
		if v.Type().Elem().Kind() != reflect.Uint8 {
			return typeMismatchReason(p, v)
		}
		v.SetBytes(x)
	default:
		return typeMismatchReason(p, v)
	}
	if slice.IsValid() {
		slice.Set(reflect.Append(slice, v))
	}
	return ""
}

// loadEntity loads an EntityProto into PropertyLoadSaver or struct pointer.
func loadEntity(dst interface{}, src *pb.EntityProto) (err error) {
	props, err := protoToProperties(src)
	if err != nil {
		return err
	}
	if e, ok := dst.(PropertyLoadSaver); ok {
		return e.Load(props)
	}
	return LoadStruct(dst, props)
}

func (s structPLS) Load(props []Property) error {
	var fieldName, reason string
	var l propertyLoader
	for _, p := range props {
		if errStr := l.load(s.codec, s.v, p, p.Multiple); errStr != "" {
			// We don't return early, as we try to load as many properties as possible.
			// It is valid to load an entity into a struct that cannot fully represent it.
			// That case returns an error, but the caller is free to ignore it.
			fieldName, reason = p.Name, errStr
		}
	}
	if reason != "" {
		return &ErrFieldMismatch{
			StructType: s.v.Type(),
			FieldName:  fieldName,
			Reason:     reason,
		}
	}
	return nil
}

func protoToProperties(src *pb.EntityProto) ([]Property, error) {
	props, rawProps := src.Property, src.RawProperty
	out := make([]Property, 0, len(props)+len(rawProps))
	for {
		var (
			x       *pb.Property
			noIndex bool
		)
		if len(props) > 0 {
			x, props = props[0], props[1:]
		} else if len(rawProps) > 0 {
			x, rawProps = rawProps[0], rawProps[1:]
			noIndex = true
		} else {
			break
		}

		var value interface{}
		if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE {
			value = indexValue{x.Value}
		} else {
			var err error
			value, err = propValue(x.Value, x.GetMeaning())
			if err != nil {
				return nil, err
			}
		}
		out = append(out, Property{
			Name:     x.GetName(),
			Value:    value,
			NoIndex:  noIndex,
			Multiple: x.GetMultiple(),
		})
	}
	return out, nil
}

// propValue returns a Go value that combines the raw PropertyValue with a
// meaning. For example, an Int64Value with GD_WHEN becomes a time.Time.
func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) {
	switch {
	case v.Int64Value != nil:
		if m == pb.Property_GD_WHEN {
			return fromUnixMicro(*v.Int64Value), nil
		} else {
			return *v.Int64Value, nil
		}
	case v.BooleanValue != nil:
		return *v.BooleanValue, nil
	case v.StringValue != nil:
		if m == pb.Property_BLOB {
			return []byte(*v.StringValue), nil
		} else if m == pb.Property_BLOBKEY {
			return appengine.BlobKey(*v.StringValue), nil
		} else if m == pb.Property_BYTESTRING {
			return ByteString(*v.StringValue), nil
		} else {
			return *v.StringValue, nil
		}
	case v.DoubleValue != nil:
		return *v.DoubleValue, nil
	case v.Referencevalue != nil:
		key, err := referenceValueToKey(v.Referencevalue)
		if err != nil {
			return nil, err
		}
		return key, nil
	case v.Pointvalue != nil:
		// NOTE: Strangely, latitude maps to X, longitude to Y.
		return appengine.GeoPoint{Lat: v.Pointvalue.GetX(), Lng: v.Pointvalue.GetY()}, nil
	}
	return nil, nil
}

// indexValue is a Property value that is created when entities are loaded from
// an index, such as from a projection query.
//
// Such Property values do not contain all of the metadata required to be
// faithfully represented as a Go value, and are instead represented as an
// opaque indexValue. Load the properties into a concrete struct type (e.g. by
// passing a struct pointer to Iterator.Next) to reconstruct actual Go values
// of type int, string, time.Time, etc.
type indexValue struct {
	value *pb.PropertyValue
}


text:
// Copyright 2012 Google Inc. All Rights Reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"testing"
	"time"
)

func TestUnixMicro(t *testing.T) {
	// Test that all these time.Time values survive a round trip to unix micros.
	testCases := []time.Time{
		{},
		time.Date(2, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(23, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(234, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(1600, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(1700, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(1800, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Unix(-1e6, -1000),
		time.Unix(-1e6, 0),
		time.Unix(-1e6, +1000),
		time.Unix(-60, -1000),
		time.Unix(-60, 0),
		time.Unix(-60, +1000),
		time.Unix(-1, -1000),
		time.Unix(-1, 0),
		time.Unix(-1, +1000),
		time.Unix(0, -3000),
		time.Unix(0, -2000),
		time.Unix(0, -1000),
		time.Unix(0, 0),
		time.Unix(0, +1000),
		time.Unix(0, +2000),
		time.Unix(+60, -1000),
		time.Unix(+60, 0),
		time.Unix(+60, +1000),
		time.Unix(+1e6, -1000),
		time.Unix(+1e6, 0),
		time.Unix(+1e6, +1000),
		time.Date(1999, 12, 31, 23, 59, 59, 999000, time.UTC),
		time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(2006, 1, 2, 15, 4, 5, 678000, time.UTC),
		time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC),
		time.Date(3456, 1, 1, 0, 0, 0, 0, time.UTC),
	}
	for _, tc := range testCases {
		got := fromUnixMicro(toUnixMicro(tc))
		if !got.Equal(tc) {
			t.Errorf("got %q, want %q", got, tc)
		}
	}

	// Test that a time.Time that isn't an integral number of microseconds
	// is not perfectly reconstructed after a round trip.
	t0 := time.Unix(0, 123)
	t1 := fromUnixMicro(toUnixMicro(t0))
	if t1.Nanosecond()%1000 != 0 || t0.Nanosecond()%1000 == 0 {
		t.Errorf("quantization to µs: got %q with %d ns, started with %d ns", t1, t1.Nanosecond(), t0.Nanosecond())
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"encoding/base64"
	"errors"
	"fmt"
	"math"
	"reflect"
	"strings"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/datastore"
)

type operator int

const (
	lessThan operator = iota
	lessEq
	equal
	greaterEq
	greaterThan
)

var operatorToProto = map[operator]*pb.Query_Filter_Operator{
	lessThan:    pb.Query_Filter_LESS_THAN.Enum(),
	lessEq:      pb.Query_Filter_LESS_THAN_OR_EQUAL.Enum(),
	equal:       pb.Query_Filter_EQUAL.Enum(),
	greaterEq:   pb.Query_Filter_GREATER_THAN_OR_EQUAL.Enum(),
	greaterThan: pb.Query_Filter_GREATER_THAN.Enum(),
}

// filter is a conditional filter on query results.
type filter struct {
	FieldName string
	Op        operator
	Value     interface{}
}

type sortDirection int

const (
	ascending sortDirection = iota
	descending
)

var sortDirectionToProto = map[sortDirection]*pb.Query_Order_Direction{
	ascending:  pb.Query_Order_ASCENDING.Enum(),
	descending: pb.Query_Order_DESCENDING.Enum(),
}

// order is a sort order on query results.
type order struct {
	FieldName string
	Direction sortDirection
}

// NewQuery creates a new Query for a specific entity kind.
//
// An empty kind means to return all entities, including entities created and
// managed by other App Engine features, and is called a kindless query.
// Kindless queries cannot include filters or sort orders on property values.
func NewQuery(kind string) *Query {
	return &Query{
		kind:  kind,
		limit: -1,
	}
}

// Query represents a datastore query.
type Query struct {
	kind       string
	ancestor   *Key
	filter     []filter
	order      []order
	projection []string

	distinct bool
	keysOnly bool
	eventual bool
	limit    int32
	offset   int32
	start    *pb.CompiledCursor
	end      *pb.CompiledCursor

	err error
}

func (q *Query) clone() *Query {
	x := *q
	// Copy the contents of the slice-typed fields to a new backing store.
	if len(q.filter) > 0 {
		x.filter = make([]filter, len(q.filter))
		copy(x.filter, q.filter)
	}
	if len(q.order) > 0 {
		x.order = make([]order, len(q.order))
		copy(x.order, q.order)
	}
	return &x
}

// Ancestor returns a derivative query with an ancestor filter.
// The ancestor should not be nil.
func (q *Query) Ancestor(ancestor *Key) *Query {
	q = q.clone()
	if ancestor == nil {
		q.err = errors.New("datastore: nil query ancestor")
		return q
	}
	q.ancestor = ancestor
	return q
}

// EventualConsistency returns a derivative query that returns eventually
// consistent results.
// It only has an effect on ancestor queries.
func (q *Query) EventualConsistency() *Query {
	q = q.clone()
	q.eventual = true
	return q
}

// Filter returns a derivative query with a field-based filter.
// The filterStr argument must be a field name followed by optional space,
// followed by an operator, one of ">", "<", ">=", "<=", or "=".
// Fields are compared against the provided value using the operator.
// Multiple filters are AND'ed together.
func (q *Query) Filter(filterStr string, value interface{}) *Query {
	q = q.clone()
	filterStr = strings.TrimSpace(filterStr)
	if len(filterStr) < 1 {
		q.err = errors.New("datastore: invalid filter: " + filterStr)
		return q
	}
	f := filter{
		FieldName: strings.TrimRight(filterStr, " ><=!"),
		Value:     value,
	}
	switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op {
	case "<=":
		f.Op = lessEq
	case ">=":
		f.Op = greaterEq
	case "<":
		f.Op = lessThan
	case ">":
		f.Op = greaterThan
	case "=":
		f.Op = equal
	default:
		q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr)
		return q
	}
	q.filter = append(q.filter, f)
	return q
}

// Order returns a derivative query with a field-based sort order. Orders are
// applied in the order they are added. The default order is ascending; to sort
// in descending order prefix the fieldName with a minus sign (-).
func (q *Query) Order(fieldName string) *Query {
	q = q.clone()
	fieldName = strings.TrimSpace(fieldName)
	o := order{
		Direction: ascending,
		FieldName: fieldName,
	}
	if strings.HasPrefix(fieldName, "-") {
		o.Direction = descending
		o.FieldName = strings.TrimSpace(fieldName[1:])
	} else if strings.HasPrefix(fieldName, "+") {
		q.err = fmt.Errorf("datastore: invalid order: %q", fieldName)
		return q
	}
	if len(o.FieldName) == 0 {
		q.err = errors.New("datastore: empty order")
		return q
	}
	q.order = append(q.order, o)
	return q
}

// Project returns a derivative query that yields only the given fields. It
// cannot be used with KeysOnly.
func (q *Query) Project(fieldNames ...string) *Query {
	q = q.clone()
	q.projection = append([]string(nil), fieldNames...)
	return q
}

// Distinct returns a derivative query that yields de-duplicated entities with
// respect to the set of projected fields. It is only used for projection
// queries.
func (q *Query) Distinct() *Query {
	q = q.clone()
	q.distinct = true
	return q
}

// KeysOnly returns a derivative query that yields only keys, not keys and
// entities. It cannot be used with projection queries.
func (q *Query) KeysOnly() *Query {
	q = q.clone()
	q.keysOnly = true
	return q
}

// Limit returns a derivative query that has a limit on the number of results
// returned. A negative value means unlimited.
func (q *Query) Limit(limit int) *Query {
	q = q.clone()
	if limit < math.MinInt32 || limit > math.MaxInt32 {
		q.err = errors.New("datastore: query limit overflow")
		return q
	}
	q.limit = int32(limit)
	return q
}

// Offset returns a derivative query that has an offset of how many keys to
// skip over before returning results. A negative value is invalid.
func (q *Query) Offset(offset int) *Query {
	q = q.clone()
	if offset < 0 {
		q.err = errors.New("datastore: negative query offset")
		return q
	}
	if offset > math.MaxInt32 {
		q.err = errors.New("datastore: query offset overflow")
		return q
	}
	q.offset = int32(offset)
	return q
}

// Start returns a derivative query with the given start point.
func (q *Query) Start(c Cursor) *Query {
	q = q.clone()
	if c.cc == nil {
		q.err = errors.New("datastore: invalid cursor")
		return q
	}
	q.start = c.cc
	return q
}

// End returns a derivative query with the given end point.
func (q *Query) End(c Cursor) *Query {
	q = q.clone()
	if c.cc == nil {
		q.err = errors.New("datastore: invalid cursor")
		return q
	}
	q.end = c.cc
	return q
}

// toProto converts the query to a protocol buffer.
func (q *Query) toProto(dst *pb.Query, appID string) error {
	if len(q.projection) != 0 && q.keysOnly {
		return errors.New("datastore: query cannot both project and be keys-only")
	}
	dst.Reset()
	dst.App = proto.String(appID)
	if q.kind != "" {
		dst.Kind = proto.String(q.kind)
	}
	if q.ancestor != nil {
		dst.Ancestor = keyToProto(appID, q.ancestor)
		if q.eventual {
			dst.Strong = proto.Bool(false)
		}
	}
	if q.projection != nil {
		dst.PropertyName = q.projection
		if q.distinct {
			dst.GroupByPropertyName = q.projection
		}
	}
	if q.keysOnly {
		dst.KeysOnly = proto.Bool(true)
		dst.RequirePerfectPlan = proto.Bool(true)
	}
	for _, qf := range q.filter {
		if qf.FieldName == "" {
			return errors.New("datastore: empty query filter field name")
		}
		p, errStr := valueToProto(appID, qf.FieldName, reflect.ValueOf(qf.Value), false)
		if errStr != "" {
			return errors.New("datastore: bad query filter value type: " + errStr)
		}
		xf := &pb.Query_Filter{
			Op:       operatorToProto[qf.Op],
			Property: []*pb.Property{p},
		}
		if xf.Op == nil {
			return errors.New("datastore: unknown query filter operator")
		}
		dst.Filter = append(dst.Filter, xf)
	}
	for _, qo := range q.order {
		if qo.FieldName == "" {
			return errors.New("datastore: empty query order field name")
		}
		xo := &pb.Query_Order{
			Property:  proto.String(qo.FieldName),
			Direction: sortDirectionToProto[qo.Direction],
		}
		if xo.Direction == nil {
			return errors.New("datastore: unknown query order direction")
		}
		dst.Order = append(dst.Order, xo)
	}
	if q.limit >= 0 {
		dst.Limit = proto.Int32(q.limit)
	}
	if q.offset != 0 {
		dst.Offset = proto.Int32(q.offset)
	}
	dst.CompiledCursor = q.start
	dst.EndCompiledCursor = q.end
	dst.Compile = proto.Bool(true)
	return nil
}

// Count returns the number of results for the query.
//
// The running time and number of API calls made by Count scale linearly with
// the sum of the query's offset and limit. Unless the result count is
// expected to be small, it is best to specify a limit; otherwise Count will
// continue until it finishes counting or the provided context expires.
func (q *Query) Count(c context.Context) (int, error) {
	// Check that the query is well-formed.
	if q.err != nil {
		return 0, q.err
	}

	// Run a copy of the query, with keysOnly true (if we're not a projection,
	// since the two are incompatible), and an adjusted offset. We also set the
	// limit to zero, as we don't want any actual entity data, just the number
	// of skipped results.
	newQ := q.clone()
	newQ.keysOnly = len(newQ.projection) == 0
	newQ.limit = 0
	if q.limit < 0 {
		// If the original query was unlimited, set the new query's offset to maximum.
		newQ.offset = math.MaxInt32
	} else {
		newQ.offset = q.offset + q.limit
		if newQ.offset < 0 {
			// Do the best we can, in the presence of overflow.
			newQ.offset = math.MaxInt32
		}
	}
	req := &pb.Query{}
	if err := newQ.toProto(req, internal.FullyQualifiedAppID(c)); err != nil {
		return 0, err
	}
	res := &pb.QueryResult{}
	if err := internal.Call(c, "datastore_v3", "RunQuery", req, res); err != nil {
		return 0, err
	}

	// n is the count we will return. For example, suppose that our original
	// query had an offset of 4 and a limit of 2008: the count will be 2008,
	// provided that there are at least 2012 matching entities. However, the
	// RPCs will only skip 1000 results at a time. The RPC sequence is:
	//   call RunQuery with (offset, limit) = (2012, 0)  // 2012 == newQ.offset
	//   response has (skippedResults, moreResults) = (1000, true)
	//   n += 1000  // n == 1000
	//   call Next     with (offset, limit) = (1012, 0)  // 1012 == newQ.offset - n
	//   response has (skippedResults, moreResults) = (1000, true)
	//   n += 1000  // n == 2000
	//   call Next     with (offset, limit) = (12, 0)    // 12 == newQ.offset - n
	//   response has (skippedResults, moreResults) = (12, false)
	//   n += 12    // n == 2012
	//   // exit the loop
	//   n -= 4     // n == 2008
	var n int32
	for {
		// The QueryResult should have no actual entity data, just skipped results.
		if len(res.Result) != 0 {
			return 0, errors.New("datastore: internal error: Count request returned too much data")
		}
		n += res.GetSkippedResults()
		if !res.GetMoreResults() {
			break
		}
		if err := callNext(c, res, newQ.offset-n, 0); err != nil {
			return 0, err
		}
	}
	n -= q.offset
	if n < 0 {
		// If the offset was greater than the number of matching entities,
		// return 0 instead of negative.
		n = 0
	}
	return int(n), nil
}

// callNext issues a datastore_v3/Next RPC to advance a cursor, such as that
// returned by a query with more results.
func callNext(c context.Context, res *pb.QueryResult, offset, limit int32) error {
	if res.Cursor == nil {
		return errors.New("datastore: internal error: server did not return a cursor")
	}
	req := &pb.NextRequest{
		Cursor: res.Cursor,
	}
	if limit >= 0 {
		req.Count = proto.Int32(limit)
	}
	if offset != 0 {
		req.Offset = proto.Int32(offset)
	}
	if res.CompiledCursor != nil {
		req.Compile = proto.Bool(true)
	}
	res.Reset()
	return internal.Call(c, "datastore_v3", "Next", req, res)
}

// GetAll runs the query in the given context and returns all keys that match
// that query, as well as appending the values to dst.
//
// dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non-
// interface, non-pointer type P such that P or *P implements PropertyLoadSaver.
//
// As a special case, *PropertyList is an invalid type for dst, even though a
// PropertyList is a slice of structs. It is treated as invalid to avoid being
// mistakenly passed when *[]PropertyList was intended.
//
// The keys returned by GetAll will be in a 1-1 correspondence with the entities
// added to dst.
//
// If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys.
//
// The running time and number of API calls made by GetAll scale linearly with
// with the sum of the query's offset and limit. Unless the result count is
// expected to be small, it is best to specify a limit; otherwise GetAll will
// continue until it finishes collecting results or the provided context
// expires.
func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) {
	var (
		dv               reflect.Value
		mat              multiArgType
		elemType         reflect.Type
		errFieldMismatch error
	)
	if !q.keysOnly {
		dv = reflect.ValueOf(dst)
		if dv.Kind() != reflect.Ptr || dv.IsNil() {
			return nil, ErrInvalidEntityType
		}
		dv = dv.Elem()
		mat, elemType = checkMultiArg(dv)
		if mat == multiArgTypeInvalid || mat == multiArgTypeInterface {
			return nil, ErrInvalidEntityType
		}
	}

	var keys []*Key
	for t := q.Run(c); ; {
		k, e, err := t.next()
		if err == Done {
			break
		}
		if err != nil {
			return keys, err
		}
		if !q.keysOnly {
			ev := reflect.New(elemType)
			if elemType.Kind() == reflect.Map {
				// This is a special case. The zero values of a map type are
				// not immediately useful; they have to be make'd.
				//
				// Funcs and channels are similar, in that a zero value is not useful,
				// but even a freshly make'd channel isn't useful: there's no fixed
				// channel buffer size that is always going to be large enough, and
				// there's no goroutine to drain the other end. Theoretically, these
				// types could be supported, for example by sniffing for a constructor
				// method or requiring prior registration, but for now it's not a
				// frequent enough concern to be worth it. Programmers can work around
				// it by explicitly using Iterator.Next instead of the Query.GetAll
				// convenience method.
				x := reflect.MakeMap(elemType)
				ev.Elem().Set(x)
			}
			if err = loadEntity(ev.Interface(), e); err != nil {
				if _, ok := err.(*ErrFieldMismatch); ok {
					// We continue loading entities even in the face of field mismatch errors.
					// If we encounter any other error, that other error is returned. Otherwise,
					// an ErrFieldMismatch is returned.
					errFieldMismatch = err
				} else {
					return keys, err
				}
			}
			if mat != multiArgTypeStructPtr {
				ev = ev.Elem()
			}
			dv.Set(reflect.Append(dv, ev))
		}
		keys = append(keys, k)
	}
	return keys, errFieldMismatch
}

// Run runs the query in the given context.
func (q *Query) Run(c context.Context) *Iterator {
	if q.err != nil {
		return &Iterator{err: q.err}
	}
	t := &Iterator{
		c:      c,
		limit:  q.limit,
		q:      q,
		prevCC: q.start,
	}
	var req pb.Query
	if err := q.toProto(&req, internal.FullyQualifiedAppID(c)); err != nil {
		t.err = err
		return t
	}
	if err := internal.Call(c, "datastore_v3", "RunQuery", &req, &t.res); err != nil {
		t.err = err
		return t
	}
	offset := q.offset - t.res.GetSkippedResults()
	for offset > 0 && t.res.GetMoreResults() {
		t.prevCC = t.res.CompiledCursor
		if err := callNext(t.c, &t.res, offset, t.limit); err != nil {
			t.err = err
			break
		}
		skip := t.res.GetSkippedResults()
		if skip < 0 {
			t.err = errors.New("datastore: internal error: negative number of skipped_results")
			break
		}
		offset -= skip
	}
	if offset < 0 {
		t.err = errors.New("datastore: internal error: query offset was overshot")
	}
	return t
}

// Iterator is the result of running a query.
type Iterator struct {
	c   context.Context
	err error
	// res is the result of the most recent RunQuery or Next API call.
	res pb.QueryResult
	// i is how many elements of res.Result we have iterated over.
	i int
	// limit is the limit on the number of results this iterator should return.
	// A negative value means unlimited.
	limit int32
	// q is the original query which yielded this iterator.
	q *Query
	// prevCC is the compiled cursor that marks the end of the previous batch
	// of results.
	prevCC *pb.CompiledCursor
}

// Done is returned when a query iteration has completed.
var Done = errors.New("datastore: query has no more results")

// Next returns the key of the next result. When there are no more results,
// Done is returned as the error.
//
// If the query is not keys only and dst is non-nil, it also loads the entity
// stored for that key into the struct pointer or PropertyLoadSaver dst, with
// the same semantics and possible errors as for the Get function.
func (t *Iterator) Next(dst interface{}) (*Key, error) {
	k, e, err := t.next()
	if err != nil {
		return nil, err
	}
	if dst != nil && !t.q.keysOnly {
		err = loadEntity(dst, e)
	}
	return k, err
}

func (t *Iterator) next() (*Key, *pb.EntityProto, error) {
	if t.err != nil {
		return nil, nil, t.err
	}

	// Issue datastore_v3/Next RPCs as necessary.
	for t.i == len(t.res.Result) {
		if !t.res.GetMoreResults() {
			t.err = Done
			return nil, nil, t.err
		}
		t.prevCC = t.res.CompiledCursor
		if err := callNext(t.c, &t.res, 0, t.limit); err != nil {
			t.err = err
			return nil, nil, t.err
		}
		if t.res.GetSkippedResults() != 0 {
			t.err = errors.New("datastore: internal error: iterator has skipped results")
			return nil, nil, t.err
		}
		t.i = 0
		if t.limit >= 0 {
			t.limit -= int32(len(t.res.Result))
			if t.limit < 0 {
				t.err = errors.New("datastore: internal error: query returned more results than the limit")
				return nil, nil, t.err
			}
		}
	}

	// Extract the key from the t.i'th element of t.res.Result.
	e := t.res.Result[t.i]
	t.i++
	if e.Key == nil {
		return nil, nil, errors.New("datastore: internal error: server did not return a key")
	}
	k, err := protoToKey(e.Key)
	if err != nil || k.Incomplete() {
		return nil, nil, errors.New("datastore: internal error: server returned an invalid key")
	}
	return k, e, nil
}

// Cursor returns a cursor for the iterator's current location.
func (t *Iterator) Cursor() (Cursor, error) {
	if t.err != nil && t.err != Done {
		return Cursor{}, t.err
	}
	// If we are at either end of the current batch of results,
	// return the compiled cursor at that end.
	skipped := t.res.GetSkippedResults()
	if t.i == 0 && skipped == 0 {
		if t.prevCC == nil {
			// A nil pointer (of type *pb.CompiledCursor) means no constraint:
			// passing it as the end cursor of a new query means unlimited results
			// (glossing over the integer limit parameter for now).
			// A non-nil pointer to an empty pb.CompiledCursor means the start:
			// passing it as the end cursor of a new query means 0 results.
			// If prevCC was nil, then the original query had no start cursor, but
			// Iterator.Cursor should return "the start" instead of unlimited.
			return Cursor{&zeroCC}, nil
		}
		return Cursor{t.prevCC}, nil
	}
	if t.i == len(t.res.Result) {
		return Cursor{t.res.CompiledCursor}, nil
	}
	// Otherwise, re-run the query offset to this iterator's position, starting from
	// the most recent compiled cursor. This is done on a best-effort basis, as it
	// is racy; if a concurrent process has added or removed entities, then the
	// cursor returned may be inconsistent.
	q := t.q.clone()
	q.start = t.prevCC
	q.offset = skipped + int32(t.i)
	q.limit = 0
	q.keysOnly = len(q.projection) == 0
	t1 := q.Run(t.c)
	_, _, err := t1.next()
	if err != Done {
		if err == nil {
			err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results")
		}
		return Cursor{}, err
	}
	return Cursor{t1.res.CompiledCursor}, nil
}

var zeroCC pb.CompiledCursor

// Cursor is an iterator's position. It can be converted to and from an opaque
// string. A cursor can be used from different HTTP requests, but only with a
// query with the same kind, ancestor, filter and order constraints.
type Cursor struct {
	cc *pb.CompiledCursor
}

// String returns a base-64 string representation of a cursor.
func (c Cursor) String() string {
	if c.cc == nil {
		return ""
	}
	b, err := proto.Marshal(c.cc)
	if err != nil {
		// The only way to construct a Cursor with a non-nil cc field is to
		// unmarshal from the byte representation. We panic if the unmarshal
		// succeeds but the marshaling of the unchanged protobuf value fails.
		panic(fmt.Sprintf("datastore: internal error: malformed cursor: %v", err))
	}
	return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
}

// Decode decodes a cursor from its base-64 string representation.
func DecodeCursor(s string) (Cursor, error) {
	if s == "" {
		return Cursor{&zeroCC}, nil
	}
	if n := len(s) % 4; n != 0 {
		s += strings.Repeat("=", 4-n)
	}
	b, err := base64.URLEncoding.DecodeString(s)
	if err != nil {
		return Cursor{}, err
	}
	cc := &pb.CompiledCursor{}
	if err := proto.Unmarshal(b, cc); err != nil {
		return Cursor{}, err
	}
	return Cursor{cc}, nil
}