OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package datastore | 5 package datastore |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
10 "strings" | 10 "strings" |
| 11 |
| 12 "gopkg.in/yaml.v2" |
11 ) | 13 ) |
12 | 14 |
13 // IndexColumn represents a sort order for a single entity field. | 15 // IndexColumn represents a sort order for a single entity field. |
14 type IndexColumn struct { | 16 type IndexColumn struct { |
15 Property string | 17 Property string |
16 Descending bool | 18 Descending bool |
17 } | 19 } |
18 | 20 |
19 // ParseIndexColumn takes a spec in the form of /\s*-?\s*.+\s*/, and | 21 // ParseIndexColumn takes a spec in the form of /\s*-?\s*.+\s*/, and |
20 // returns an IndexColumn. Examples are: | 22 // returns an IndexColumn. Examples are: |
(...skipping 21 matching lines...) Expand all Loading... |
42 func (i IndexColumn) cmp(o IndexColumn) int { | 44 func (i IndexColumn) cmp(o IndexColumn) int { |
43 // sort ascending first | 45 // sort ascending first |
44 if !i.Descending && o.Descending { | 46 if !i.Descending && o.Descending { |
45 return -1 | 47 return -1 |
46 } else if i.Descending && !o.Descending { | 48 } else if i.Descending && !o.Descending { |
47 return 1 | 49 return 1 |
48 } | 50 } |
49 return cmpString(i.Property, o.Property)() | 51 return cmpString(i.Property, o.Property)() |
50 } | 52 } |
51 | 53 |
| 54 // UnmarshalYAML deserializes a index.yml `property` into an IndexColumn. |
| 55 func (i *IndexColumn) UnmarshalYAML(unmarshal func(interface{}) error) error { |
| 56 var m map[string]string |
| 57 if err := unmarshal(&m); err != nil { |
| 58 return err |
| 59 } |
| 60 |
| 61 name, ok := m["name"] |
| 62 if !ok { |
| 63 return fmt.Errorf("datastore: missing required key `name`: %v",
m) |
| 64 } |
| 65 i.Property = name |
| 66 |
| 67 i.Descending = false // default direction is "asc" |
| 68 if v, ok := m["direction"]; ok && v == "desc" { |
| 69 i.Descending = true |
| 70 } |
| 71 |
| 72 return nil |
| 73 } |
| 74 |
| 75 // MarshalYAML serializes an IndexColumn into a index.yml `property`. |
| 76 func (i *IndexColumn) MarshalYAML() (interface{}, error) { |
| 77 direction := "asc" |
| 78 |
| 79 if i.Descending { |
| 80 direction = "desc" |
| 81 } |
| 82 |
| 83 return yaml.Marshal(map[string]string{ |
| 84 "name": i.Property, |
| 85 "direction": direction, |
| 86 }) |
| 87 } |
| 88 |
52 // String returns a human-readable version of this IndexColumn which is | 89 // String returns a human-readable version of this IndexColumn which is |
53 // compatible with ParseIndexColumn. | 90 // compatible with ParseIndexColumn. |
54 func (i IndexColumn) String() string { | 91 func (i IndexColumn) String() string { |
55 ret := "" | 92 ret := "" |
56 if i.Descending { | 93 if i.Descending { |
57 ret = "-" | 94 ret = "-" |
58 } | 95 } |
59 return ret + i.Property | 96 return ret + i.Property |
60 } | 97 } |
61 | 98 |
62 // GQL returns a correctly formatted Cloud Datastore GQL literal which | 99 // GQL returns a correctly formatted Cloud Datastore GQL literal which |
63 // is valid for the `ORDER BY` clause. | 100 // is valid for the `ORDER BY` clause. |
64 // | 101 // |
65 // The flavor of GQL that this emits is defined here: | 102 // The flavor of GQL that this emits is defined here: |
66 // https://cloud.google.com/datastore/docs/apis/gql/gql_reference | 103 // https://cloud.google.com/datastore/docs/apis/gql/gql_reference |
67 func (i IndexColumn) GQL() string { | 104 func (i IndexColumn) GQL() string { |
68 if i.Descending { | 105 if i.Descending { |
69 return gqlQuoteName(i.Property) + " DESC" | 106 return gqlQuoteName(i.Property) + " DESC" |
70 } | 107 } |
71 return gqlQuoteName(i.Property) | 108 return gqlQuoteName(i.Property) |
72 } | 109 } |
73 | 110 |
74 // IndexDefinition holds the parsed definition of a datastore index definition. | 111 // IndexDefinition holds the parsed definition of a datastore index definition. |
75 type IndexDefinition struct { | 112 type IndexDefinition struct { |
76 » Kind string | 113 » Kind string `yaml:"kind"` |
77 » Ancestor bool | 114 » Ancestor bool `yaml:"ancestor"` |
78 » SortBy []IndexColumn | 115 » SortBy []IndexColumn `yaml:"properties"` |
| 116 } |
| 117 |
| 118 // MarshalYAML serializes an IndexDefinition into a index.yml `index`. |
| 119 func (id *IndexDefinition) MarshalYAML() (interface{}, error) { |
| 120 » if id.Builtin() || !id.Compound() { |
| 121 » » return nil, fmt.Errorf("cannot generate YAML for %s", id) |
| 122 » } |
| 123 |
| 124 » return yaml.Marshal(map[string]interface{}{ |
| 125 » » "kind": id.Kind, |
| 126 » » "ancestor": id.Ancestor, |
| 127 » » "properties": id.SortBy, |
| 128 » }) |
79 } | 129 } |
80 | 130 |
81 // Equal returns true if the two IndexDefinitions are equivalent. | 131 // Equal returns true if the two IndexDefinitions are equivalent. |
82 func (id *IndexDefinition) Equal(o *IndexDefinition) bool { | 132 func (id *IndexDefinition) Equal(o *IndexDefinition) bool { |
83 if id.Kind != o.Kind || id.Ancestor != o.Ancestor || len(id.SortBy) != l
en(o.SortBy) { | 133 if id.Kind != o.Kind || id.Ancestor != o.Ancestor || len(id.SortBy) != l
en(o.SortBy) { |
84 return false | 134 return false |
85 } | 135 } |
86 for i, col := range id.SortBy { | 136 for i, col := range id.SortBy { |
87 if col != o.SortBy[i] { | 137 if col != o.SortBy[i] { |
88 return false | 138 return false |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 } | 341 } |
292 for _, sb := range id.SortBy { | 342 for _, sb := range id.SortBy { |
293 wr('/') | 343 wr('/') |
294 if sb.Descending { | 344 if sb.Descending { |
295 wr('-') | 345 wr('-') |
296 } | 346 } |
297 ws(sb.Property) | 347 ws(sb.Property) |
298 } | 348 } |
299 return ret.String() | 349 return ret.String() |
300 } | 350 } |
OLD | NEW |