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 ) | 9 ) |
10 | 10 |
11 const MaxIndexColumns = 64 | 11 const MaxIndexColumns = 64 |
12 | 12 |
13 type IndexDirection bool | 13 type IndexDirection bool |
14 | 14 |
15 const ( | 15 const ( |
16 // ASCENDING is false so that it's the default (zero) value. | 16 // ASCENDING is false so that it's the default (zero) value. |
17 ASCENDING IndexDirection = false | 17 ASCENDING IndexDirection = false |
18 DESCENDING = true | 18 DESCENDING = true |
19 ) | 19 ) |
20 | 20 |
| 21 func (i IndexDirection) String() string { |
| 22 if i == ASCENDING { |
| 23 return "ASCENDING" |
| 24 } |
| 25 return "DESCENDING" |
| 26 } |
| 27 |
21 type IndexColumn struct { | 28 type IndexColumn struct { |
22 Property string | 29 Property string |
23 Direction IndexDirection | 30 Direction IndexDirection |
24 } | 31 } |
25 | 32 |
26 func (i IndexColumn) cmp(o IndexColumn) int { | 33 func (i IndexColumn) cmp(o IndexColumn) int { |
27 // sort ascending first | 34 // sort ascending first |
28 if i.Direction == ASCENDING && o.Direction == DESCENDING { | 35 if i.Direction == ASCENDING && o.Direction == DESCENDING { |
29 return -1 | 36 return -1 |
30 } else if i.Direction == DESCENDING && o.Direction == ASCENDING { | 37 } else if i.Direction == DESCENDING && o.Direction == ASCENDING { |
31 return 1 | 38 return 1 |
32 } | 39 } |
33 return cmpString(i.Property, o.Property)() | 40 return cmpString(i.Property, o.Property)() |
34 } | 41 } |
35 | 42 |
36 type IndexDefinition struct { | 43 type IndexDefinition struct { |
37 Kind string | 44 Kind string |
38 Ancestor bool | 45 Ancestor bool |
39 SortBy []IndexColumn | 46 SortBy []IndexColumn |
40 } | 47 } |
41 | 48 |
| 49 func (id *IndexDefinition) Equal(o *IndexDefinition) bool { |
| 50 if id.Kind != o.Kind || id.Ancestor != o.Ancestor || len(id.SortBy) != l
en(o.SortBy) { |
| 51 return false |
| 52 } |
| 53 for i, col := range id.SortBy { |
| 54 if col != o.SortBy[i] { |
| 55 return false |
| 56 } |
| 57 } |
| 58 return true |
| 59 } |
| 60 |
| 61 // NormalizeOrder returns the normalized SortBy value for this IndexDefinition. |
| 62 // This is just appending __key__ if it's not explicitly the last field in this |
| 63 // IndexDefinition. |
| 64 func (id *IndexDefinition) Normalize() *IndexDefinition { |
| 65 if len(id.SortBy) > 0 && id.SortBy[len(id.SortBy)-1].Property == "__key_
_" { |
| 66 return id |
| 67 } |
| 68 ret := *id |
| 69 ret.SortBy = make([]IndexColumn, len(id.SortBy), len(id.SortBy)+1) |
| 70 copy(ret.SortBy, id.SortBy) |
| 71 ret.SortBy = append(ret.SortBy, IndexColumn{Property: "__key__"}) |
| 72 return &ret |
| 73 } |
| 74 |
| 75 func (id *IndexDefinition) GetFullSortOrder() []IndexColumn { |
| 76 id = id.Normalize() |
| 77 if !id.Ancestor { |
| 78 return id.SortBy |
| 79 } |
| 80 ret := make([]IndexColumn, 0, len(id.SortBy)+1) |
| 81 ret = append(ret, IndexColumn{Property: "__ancestor__"}) |
| 82 return append(ret, id.SortBy...) |
| 83 } |
| 84 |
| 85 func (id *IndexDefinition) PrepForIdxTable() *IndexDefinition { |
| 86 return id.Normalize().Flip() |
| 87 } |
| 88 |
| 89 func (id *IndexDefinition) Flip() *IndexDefinition { |
| 90 ret := *id |
| 91 ret.SortBy = make([]IndexColumn, 0, len(id.SortBy)) |
| 92 for i := len(id.SortBy) - 1; i >= 0; i-- { |
| 93 ret.SortBy = append(ret.SortBy, id.SortBy[i]) |
| 94 } |
| 95 return &ret |
| 96 } |
| 97 |
42 // Yeah who needs templates, right? | 98 // Yeah who needs templates, right? |
43 // <flames>This is fine.</flames> | 99 // <flames>This is fine.</flames> |
44 | 100 |
45 func cmpBool(a, b bool) func() int { | 101 func cmpBool(a, b bool) func() int { |
46 return func() int { | 102 return func() int { |
47 if a == b { | 103 if a == b { |
48 return 0 | 104 return 0 |
49 } | 105 } |
50 if a && !b { // > | 106 if a && !b { // > |
51 return 1 | 107 return 1 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 168 |
113 func (i *IndexDefinition) Builtin() bool { | 169 func (i *IndexDefinition) Builtin() bool { |
114 return !i.Ancestor && len(i.SortBy) <= 1 | 170 return !i.Ancestor && len(i.SortBy) <= 1 |
115 } | 171 } |
116 | 172 |
117 func (i *IndexDefinition) Compound() bool { | 173 func (i *IndexDefinition) Compound() bool { |
118 if i.Kind == "" || len(i.SortBy) <= 1 { | 174 if i.Kind == "" || len(i.SortBy) <= 1 { |
119 return false | 175 return false |
120 } | 176 } |
121 for _, sb := range i.SortBy { | 177 for _, sb := range i.SortBy { |
122 » » if sb.Property == "" { | 178 » » if sb.Property == "" || sb.Property == "__ancestor__" { |
123 return false | 179 return false |
124 } | 180 } |
125 } | 181 } |
126 return true | 182 return true |
127 } | 183 } |
128 | 184 |
129 func (i *IndexDefinition) String() string { | 185 func (i *IndexDefinition) String() string { |
130 ret := &bytes.Buffer{} | 186 ret := &bytes.Buffer{} |
131 if i.Builtin() { | 187 if i.Builtin() { |
132 ret.WriteRune('B') | 188 ret.WriteRune('B') |
133 } else { | 189 } else { |
134 ret.WriteRune('C') | 190 ret.WriteRune('C') |
135 } | 191 } |
136 ret.WriteRune(':') | 192 ret.WriteRune(':') |
137 ret.WriteString(i.Kind) | 193 ret.WriteString(i.Kind) |
138 if i.Ancestor { | 194 if i.Ancestor { |
139 ret.WriteString("|A") | 195 ret.WriteString("|A") |
140 } | 196 } |
141 for _, sb := range i.SortBy { | 197 for _, sb := range i.SortBy { |
142 ret.WriteRune('/') | 198 ret.WriteRune('/') |
143 if sb.Direction == DESCENDING { | 199 if sb.Direction == DESCENDING { |
144 ret.WriteRune('-') | 200 ret.WriteRune('-') |
145 } | 201 } |
146 ret.WriteString(sb.Property) | 202 ret.WriteString(sb.Property) |
147 } | 203 } |
148 return ret.String() | 204 return ret.String() |
149 } | 205 } |
150 | |
151 func IndexBuiltinQueryPrefix() []byte { | |
152 return []byte{0} | |
153 } | |
154 | |
155 func IndexComplexQueryPrefix() []byte { | |
156 return []byte{1} | |
157 } | |
OLD | NEW |