1// Copyright 2016 Google Inc. All rights reserved.
2// Use of this source code is governed by the Apache 2.0
3// license that can be found in the LICENSE file.
4
5package datastore
6
7import "golang.org/x/net/context"
8
9// Datastore kinds for the metadata entities.
10const (
11	namespaceKind = "__namespace__"
12	kindKind      = "__kind__"
13	propertyKind  = "__property__"
14)
15
16// Namespaces returns all the datastore namespaces.
17func Namespaces(ctx context.Context) ([]string, error) {
18	// TODO(djd): Support range queries.
19	q := NewQuery(namespaceKind).KeysOnly()
20	keys, err := q.GetAll(ctx, nil)
21	if err != nil {
22		return nil, err
23	}
24	// The empty namespace key uses a numeric ID (==1), but luckily
25	// the string ID defaults to "" for numeric IDs anyway.
26	return keyNames(keys), nil
27}
28
29// Kinds returns the names of all the kinds in the current namespace.
30func Kinds(ctx context.Context) ([]string, error) {
31	// TODO(djd): Support range queries.
32	q := NewQuery(kindKind).KeysOnly()
33	keys, err := q.GetAll(ctx, nil)
34	if err != nil {
35		return nil, err
36	}
37	return keyNames(keys), nil
38}
39
40// keyNames returns a slice of the provided keys' names (string IDs).
41func keyNames(keys []*Key) []string {
42	n := make([]string, 0, len(keys))
43	for _, k := range keys {
44		n = append(n, k.StringID())
45	}
46	return n
47}
48
49// KindProperties returns all the indexed properties for the given kind.
50// The properties are returned as a map of property names to a slice of the
51// representation types. The representation types for the supported Go property
52// types are:
53//   "INT64":     signed integers and time.Time
54//   "DOUBLE":    float32 and float64
55//   "BOOLEAN":   bool
56//   "STRING":    string, []byte and ByteString
57//   "POINT":     appengine.GeoPoint
58//   "REFERENCE": *Key
59//   "USER":      (not used in the Go runtime)
60func KindProperties(ctx context.Context, kind string) (map[string][]string, error) {
61	// TODO(djd): Support range queries.
62	kindKey := NewKey(ctx, kindKind, kind, 0, nil)
63	q := NewQuery(propertyKind).Ancestor(kindKey)
64
65	propMap := map[string][]string{}
66	props := []struct {
67		Repr []string `datastore:"property_representation"`
68	}{}
69
70	keys, err := q.GetAll(ctx, &props)
71	if err != nil {
72		return nil, err
73	}
74	for i, p := range props {
75		propMap[keys[i].StringID()] = p.Repr
76	}
77	return propMap, nil
78}
79