func createFinalResult(ctx context.Context, w http.ResponseWriter, resultKey *datastore.Key, result model.Result) (int, error) { go computeFinalScore(ctx, result) var challenge model.Challenge if err := datastore.Get(ctx, result.Challenge, &challenge); err != nil { return http.StatusInternalServerError, nil } var taskKey *datastore.Key for _, taskKey = range challenge.Tasks { switch taskKey.Kind() { case model.CodeTaskKind: var submissions model.CodeSubmissions keys, err := doQuery(ctx, model.NewQueryForCodeSubmission(), resultKey, taskKey, submissions) if err != nil { return http.StatusInternalServerError, nil } if len(keys) == 0 { // Most likely the authenticated user called this endpoint // before finishing the challenge return http.StatusUnauthorized, nil } result.FinalSubmissions = append(result.FinalSubmissions, keys[0]) //TODO(pbochis, vbalan, flowlo): Add more cases when more task kinds are added. default: return http.StatusBadRequest, errors.New("Unknown submission kind.") } } key, err := result.Save(ctx, resultKey) if err != nil { return http.StatusInternalServerError, err } json.NewEncoder(w).Encode(result.Key(key)) return http.StatusOK, nil }
func ktoi(key *datastore.Key) id { return id{ kind: key.Kind(), stringID: key.StringID(), intID: key.IntID(), appID: key.AppID(), namespace: key.Namespace(), } }
func buildKey(req *wcg.Request, key *datastore.Key) *datastore.Key { kind := entities.FindKind(key.Kind(), key.Namespace()) if kind == nil { return nil } if key.Parent() != nil { return kind.NewKey(req, key.StringID(), buildKey(req, key.Parent())) } return kind.NewKey(req, key.StringID(), nil) }
func buildDatastoreKey(key *datastore.Key) (map[string]bigquery.JsonValue, error) { if key == nil { return map[string]bigquery.JsonValue{ "namespace": "", "app": "", "path": "", "kind": "", "name": "", "id": 0, }, nil } var workKey = key var keys []*datastore.Key keys = append(keys, key) for { if workKey.Parent() == nil { break } keys = append(keys, workKey.Parent()) workKey = workKey.Parent() } var buf bytes.Buffer for i := len(keys) - 1; i >= 0; i-- { if buf.Len() > 0 { _, err := buf.WriteString(", ") if err != nil { return map[string]bigquery.JsonValue{}, nil } } key := keys[i] if len(key.StringID()) < 1 { _, err := buf.WriteString(fmt.Sprintf(`"%s", "%s"`, keys[i].Kind(), keys[i].IntID())) if err != nil { return map[string]bigquery.JsonValue{}, nil } } else { _, err := buf.WriteString(fmt.Sprintf(`"%s", "%s"`, keys[i].Kind(), keys[i].StringID())) if err != nil { return map[string]bigquery.JsonValue{}, nil } } } return map[string]bigquery.JsonValue{ "namespace": key.Namespace(), "app": key.AppID(), "path": buf.String(), "kind": key.Kind(), "name": key.StringID(), "id": key.IntID(), }, nil }
func nameObject(key *datastore.Key) string { name := "" for key != nil { id := key.StringID() if id == "" { id = strconv.FormatInt(key.IntID(), 10) } name = "/" + key.Kind() + "/" + id + name key = key.Parent() } // NOTE: The name of a GCS object must not be prefixed "/", // this will give you a major headache. return name[1:] }
// createQuery builds a range query using start and end. It works // for [start,end[, [start,nil] and [start,start] intervals. The // returned query is sorted by __key__ and limited to BatchSize. func createQuery(start, end *datastore.Key, cur datastore.Cursor) *datastore.Query { q := datastore.NewQuery(start.Kind()) if start.Equal(end) { q = q.Filter("__key__ =", start) } else { q = q.Filter("__key__ >=", start) if end != nil { q = q.Filter("__key__ <", end) } } if cur.String() != "" { q = q.Start(cur) } q = q.Order("__key__") return q }
// cmpKey compares k and other, returning -1, 0 or 1 if k is // less than, equal or grather than other. The algorithm doesn't // takes into account any ancestors in the two keys. The order // of comparision is AppID, Kind, IntID and StringID. Keys with // integer identifiers are smaller than string identifiers. func cmpKey(k, other *datastore.Key) int { if k == other { return 0 } if r := cmpStr(k.AppID(), other.AppID()); r != 0 { return r } if r := cmpStr(k.Kind(), other.Kind()); r != 0 { return r } if k.IntID() != 0 { if other.IntID() == 0 { return -1 } return cmpInt(k.IntID(), other.IntID()) } if other.IntID() != 0 { return 1 } return cmpStr(k.StringID(), other.StringID()) }
func ParseEntityFromKey(ctx context.Context, key *datastore.Key) (DataModel, error) { ty := key.Kind() var err error switch ty { case "Category": var m Category err = datastore.Get(ctx, key, &m) return m, nil case "Location": var m Location err = datastore.Get(ctx, key, &m) return m, nil case "Post": var p Post err = datastore.Get(ctx, key, &p) return p, nil } if err != nil { return nil, err } return nil, nil }
// dsR2F (DS real-to-fake) converts an SDK Key to a ds.Key func dsR2F(k *datastore.Key) *ds.Key { if k == nil { return nil } aid := k.AppID() ns := k.Namespace() count := 0 for nk := k; nk != nil; nk = nk.Parent() { count++ } toks := make([]ds.KeyTok, count) for ; k != nil; k = k.Parent() { count-- toks[count].Kind = k.Kind() toks[count].StringID = k.StringID() toks[count].IntID = k.IntID() } return ds.NewKeyToks(aid, ns, toks) }
func (g *Goon) setStructKey(src interface{}, key *datastore.Key) error { v := reflect.ValueOf(src) t := v.Type() k := t.Kind() if k != reflect.Ptr { return fmt.Errorf("goon: Expected pointer to struct, got instead: %v", k) } v = reflect.Indirect(v) t = v.Type() k = t.Kind() if k != reflect.Struct { return fmt.Errorf(fmt.Sprintf("goon: Expected struct, got instead: %v", k)) } idSet := false kindSet := false parentSet := false for i := 0; i < v.NumField(); i++ { tf := t.Field(i) vf := v.Field(i) if !vf.CanSet() { continue } tag := tf.Tag.Get("goon") tagValues := strings.Split(tag, ",") if len(tagValues) > 0 { tagValue := tagValues[0] if tagValue == "id" { if idSet { return fmt.Errorf("goon: Only one field may be marked id") } switch vf.Kind() { case reflect.Int64: vf.SetInt(key.IntID()) idSet = true case reflect.String: vf.SetString(key.StringID()) idSet = true } } else if tagValue == "kind" { if kindSet { return fmt.Errorf("goon: Only one field may be marked kind") } if vf.Kind() == reflect.String { if (len(tagValues) <= 1 || key.Kind() != tagValues[1]) && g.KindNameResolver(src) != key.Kind() { vf.Set(reflect.ValueOf(key.Kind())) } kindSet = true } } else if tagValue == "parent" { if parentSet { return fmt.Errorf("goon: Only one field may be marked parent") } dskeyType := reflect.TypeOf(&datastore.Key{}) vfType := vf.Type() if vfType.ConvertibleTo(dskeyType) { vf.Set(reflect.ValueOf(key.Parent()).Convert(vfType)) parentSet = true } } } } if !idSet { return fmt.Errorf("goon: Could not set id field") } return nil }