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 { | |
iannucci
2016/01/13 19:12:20
I would consider making the Property and Descendin
nishanths (utexas)
2016/01/14 21:12:56
Good idea. Will create a separate issue for these
| |
56 var m map[string]string | |
57 | |
58 if err := unmarshal(&m); err != nil { | |
59 return err | |
60 } | |
61 | |
62 i.Property = m["name"] | |
iannucci
2016/01/13 19:12:20
should return an error if there's somehow no name
nishanths (utexas)
2016/01/14 21:12:56
Done.
| |
63 i.Descending = false // default direction is "asc" | |
64 | |
65 if v, ok := m["direction"]; ok && v == "desc" { | |
66 i.Descending = true | |
67 } | |
68 | |
69 return nil | |
70 } | |
71 | |
72 // MarshalYAML serializes an IndexColumn into a index.yml `property`. | |
73 func (i *IndexColumn) MarshalYAML() (interface{}, error) { | |
74 direction := "asc" | |
75 | |
76 if i.Descending { | |
77 direction = "desc" | |
78 } | |
79 | |
80 return yaml.Marshal(map[string]string{ | |
81 "name": i.Property, | |
82 "direction": direction, | |
83 }) | |
84 } | |
85 | |
52 // String returns a human-readable version of this IndexColumn which is | 86 // String returns a human-readable version of this IndexColumn which is |
53 // compatible with ParseIndexColumn. | 87 // compatible with ParseIndexColumn. |
54 func (i IndexColumn) String() string { | 88 func (i IndexColumn) String() string { |
55 ret := "" | 89 ret := "" |
56 if i.Descending { | 90 if i.Descending { |
57 ret = "-" | 91 ret = "-" |
58 } | 92 } |
59 return ret + i.Property | 93 return ret + i.Property |
60 } | 94 } |
61 | 95 |
62 // GQL returns a correctly formatted Cloud Datastore GQL literal which | 96 // GQL returns a correctly formatted Cloud Datastore GQL literal which |
63 // is valid for the `ORDER BY` clause. | 97 // is valid for the `ORDER BY` clause. |
64 // | 98 // |
65 // The flavor of GQL that this emits is defined here: | 99 // The flavor of GQL that this emits is defined here: |
66 // https://cloud.google.com/datastore/docs/apis/gql/gql_reference | 100 // https://cloud.google.com/datastore/docs/apis/gql/gql_reference |
67 func (i IndexColumn) GQL() string { | 101 func (i IndexColumn) GQL() string { |
68 if i.Descending { | 102 if i.Descending { |
69 return gqlQuoteName(i.Property) + " DESC" | 103 return gqlQuoteName(i.Property) + " DESC" |
70 } | 104 } |
71 return gqlQuoteName(i.Property) | 105 return gqlQuoteName(i.Property) |
72 } | 106 } |
73 | 107 |
74 // IndexDefinition holds the parsed definition of a datastore index definition. | 108 // IndexDefinition holds the parsed definition of a datastore index definition. |
75 type IndexDefinition struct { | 109 type IndexDefinition struct { |
76 » Kind string | 110 » Kind string `yaml:"kind"` |
77 » Ancestor bool | 111 » Ancestor bool `yaml:"ancestor"` |
78 » SortBy []IndexColumn | 112 » SortBy []IndexColumn `yaml:"properties"` |
113 } | |
114 | |
115 // MarshalYAML serializes an IndexDefinition into a index.yml `index`. | |
116 func (id *IndexDefinition) MarshalYAML() (interface{}, error) { | |
117 » if id.Builtin() || !id.Compound() { | |
118 » » return nil, fmt.Errorf("cannot generate YAML for %s", id) | |
119 » } | |
120 | |
121 » return yaml.Marshal(map[string]interface{}{ | |
122 » » "kind": id.Kind, | |
123 » » "ancestor": id.Ancestor, | |
124 » » "properties": id.SortBy, | |
125 » }) | |
79 } | 126 } |
80 | 127 |
81 // Equal returns true if the two IndexDefinitions are equivalent. | 128 // Equal returns true if the two IndexDefinitions are equivalent. |
82 func (id *IndexDefinition) Equal(o *IndexDefinition) bool { | 129 func (id *IndexDefinition) Equal(o *IndexDefinition) bool { |
83 if id.Kind != o.Kind || id.Ancestor != o.Ancestor || len(id.SortBy) != l en(o.SortBy) { | 130 if id.Kind != o.Kind || id.Ancestor != o.Ancestor || len(id.SortBy) != l en(o.SortBy) { |
84 return false | 131 return false |
85 } | 132 } |
86 for i, col := range id.SortBy { | 133 for i, col := range id.SortBy { |
87 if col != o.SortBy[i] { | 134 if col != o.SortBy[i] { |
88 return false | 135 return false |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 } | 338 } |
292 for _, sb := range id.SortBy { | 339 for _, sb := range id.SortBy { |
293 wr('/') | 340 wr('/') |
294 if sb.Descending { | 341 if sb.Descending { |
295 wr('-') | 342 wr('-') |
296 } | 343 } |
297 ws(sb.Property) | 344 ws(sb.Property) |
298 } | 345 } |
299 return ret.String() | 346 return ret.String() |
300 } | 347 } |
OLD | NEW |