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 memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 func rootKey(key *datastore.Key) *datastore.Key { | 169 func rootKey(key *datastore.Key) *datastore.Key { |
170 for key.Parent() != nil { | 170 for key.Parent() != nil { |
171 key = key.Parent() | 171 key = key.Parent() |
172 } | 172 } |
173 return key | 173 return key |
174 } | 174 } |
175 | 175 |
176 type keyValidOption bool | 176 type keyValidOption bool |
177 | 177 |
178 const ( | 178 const ( |
179 » // UserKeyOnly is used with KeyValid, and ensures that the key is only o
ne | 179 » // userKeyOnly is used with keyValid, and ensures that the key is only o
ne |
180 // that's valid for a user program to write to. | 180 // that's valid for a user program to write to. |
181 » UserKeyOnly keyValidOption = false | 181 » userKeyOnly keyValidOption = false |
182 | 182 |
183 » // AllowSpecialKeys is used with KeyValid, and allows keys for special | 183 » // allowSpecialKeys is used with keyValid, and allows keys for special |
184 // metadata objects (like "__entity_group__"). | 184 // metadata objects (like "__entity_group__"). |
185 » AllowSpecialKeys = true | 185 » allowSpecialKeys = true |
186 ) | 186 ) |
187 | 187 |
188 // KeyValid checks to see if a key is valid by applying a bunch of constraint | 188 // keyValid checks to see if a key is valid by applying a bunch of constraint |
189 // rules to it (e.g. can't have StringID and IntID set at the same time, can't | 189 // rules to it (e.g. can't have StringID and IntID set at the same time, can't |
190 // have a parent key which is Incomplete(), etc.) | 190 // have a parent key which is Incomplete(), etc.) |
191 // | 191 // |
192 // It verifies that the key is also in the provided namespace. It can also | 192 // It verifies that the key is also in the provided namespace. It can also |
193 // reject keys which are 'special' e.g. have a Kind starting with "__". This | 193 // reject keys which are 'special' e.g. have a Kind starting with "__". This |
194 // behavior is controllable with opt. | 194 // behavior is controllable with opt. |
195 func KeyValid(ns string, k *datastore.Key, opt keyValidOption) bool { | 195 func keyValid(ns string, k *datastore.Key, opt keyValidOption) bool { |
196 // copied from the appengine SDK because why would any user program need
to | 196 // copied from the appengine SDK because why would any user program need
to |
197 // see if a key is valid? /s | 197 // see if a key is valid? /s |
198 if k == nil { | 198 if k == nil { |
199 return false | 199 return false |
200 } | 200 } |
201 // since we do "client-side" validation of namespaces, check this here. | 201 // since we do "client-side" validation of namespaces, check this here. |
202 if k.Namespace() != ns { | 202 if k.Namespace() != ns { |
203 return false | 203 return false |
204 } | 204 } |
205 for ; k != nil; k = k.Parent() { | 205 for ; k != nil; k = k.Parent() { |
206 » » if opt == UserKeyOnly && len(k.Kind()) >= 2 && k.Kind()[:2] == "
__" { // reserve all Kinds starting with __ | 206 » » if opt == userKeyOnly && len(k.Kind()) >= 2 && k.Kind()[:2] == "
__" { // reserve all Kinds starting with __ |
207 return false | 207 return false |
208 } | 208 } |
209 if k.Kind() == "" || k.AppID() == "" { | 209 if k.Kind() == "" || k.AppID() == "" { |
210 return false | 210 return false |
211 } | 211 } |
212 if k.StringID() != "" && k.IntID() != 0 { | 212 if k.StringID() != "" && k.IntID() != 0 { |
213 return false | 213 return false |
214 } | 214 } |
215 if k.Parent() != nil { | 215 if k.Parent() != nil { |
216 if k.Parent().Incomplete() { | 216 if k.Parent().Incomplete() { |
217 return false | 217 return false |
218 } | 218 } |
219 if k.Parent().AppID() != k.AppID() || k.Parent().Namespa
ce() != k.Namespace() { | 219 if k.Parent().AppID() != k.AppID() || k.Parent().Namespa
ce() != k.Namespace() { |
220 return false | 220 return false |
221 } | 221 } |
222 } | 222 } |
223 } | 223 } |
224 return true | 224 return true |
225 } | 225 } |
226 | 226 |
227 // KeyCouldBeValid is like KeyValid, but it allows for the possibility that the | 227 // keyCouldBeValid is like keyValid, but it allows for the possibility that the |
228 // last token of the key is Incomplete(). It returns true if the Key will become | 228 // last token of the key is Incomplete(). It returns true if the Key will become |
229 // valid once it recieves an automatically-assigned ID. | 229 // valid once it recieves an automatically-assigned ID. |
230 func KeyCouldBeValid(ns string, k *datastore.Key, opt keyValidOption) bool { | 230 func keyCouldBeValid(ns string, k *datastore.Key, opt keyValidOption) bool { |
231 // adds an id to k if it's incomplete. | 231 // adds an id to k if it's incomplete. |
232 if k.Incomplete() { | 232 if k.Incomplete() { |
233 k = newKey(ns, k.Kind(), "", 1, k.Parent()) | 233 k = newKey(ns, k.Kind(), "", 1, k.Parent()) |
234 } | 234 } |
235 » return KeyValid(ns, k, opt) | 235 » return keyValid(ns, k, opt) |
236 } | 236 } |
OLD | NEW |