Chromium Code Reviews| 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 |