| 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 |