blob: 01670f236671525efd659c580127dceb4e78268f [file] [log] [blame]
// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package model
import (
"context"
"time"
"github.com/golang/protobuf/proto"
ds "go.chromium.org/gae/service/datastore"
"go.chromium.org/luci/common/clock"
google_pb "go.chromium.org/luci/common/proto/google"
dm "go.chromium.org/luci/dm/api/service/v1"
)
// NewQuest builds a new Quest object with a correct ID given the current
// contents of the Quest_Desc. It returns an error if the Desc is invalid.
//
// Desc must already be Normalize()'d
func NewQuest(c context.Context, desc *dm.Quest_Desc) *Quest {
return &Quest{ID: desc.QuestID(), Desc: *desc, Created: clock.Now(c).UTC()}
}
// Quest is the model for a job-to-run. Its questPayload should fully
// describe the job to be done.
type Quest struct {
// ID is the base64 sha256 of questPayload
ID string `gae:"$id"`
Desc dm.Quest_Desc `gae:",noindex"`
BuiltBy TemplateInfo `gae:",noindex"`
Created time.Time `gae:",noindex"`
}
// Equals is true if q and a and equal.
func (q *Quest) Equals(a *Quest) bool {
return q == a || (q.ID == a.ID &&
proto.Equal(&q.Desc, &a.Desc) &&
q.BuiltBy.Equals(a.BuiltBy) &&
q.Created.Equal(a.Created))
}
// QueryAttemptsForQuest returns all Attempt objects that exist for this Quest.
func QueryAttemptsForQuest(c context.Context, qid string) *ds.Query {
from := ds.MakeKey(c, "Attempt", qid+"|")
to := ds.MakeKey(c, "Attempt", qid+"~")
return ds.NewQuery("Attempt").Gt("__key__", from).Lt("__key__", to)
}
// ToProto converts this Quest into its display equivalent.
func (q *Quest) ToProto() *dm.Quest {
return &dm.Quest{
Id: dm.NewQuestID(q.ID),
Data: q.DataProto(),
}
}
// DataProto gets the Quest.Data proto message for this Quest.
func (q *Quest) DataProto() *dm.Quest_Data {
spec := make([]*dm.Quest_TemplateSpec, len(q.BuiltBy))
for i := range q.BuiltBy {
spec[i] = &q.BuiltBy[i]
}
return &dm.Quest_Data{
Created: google_pb.NewTimestamp(q.Created),
Desc: &q.Desc,
BuiltBy: spec,
}
}