| 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 "fmt" | 8 "fmt" |
| 9 "math" | 9 "math" |
| 10 "testing" | 10 "testing" |
| 11 | 11 |
| 12 » rdsS "github.com/luci/gae/service/rawdatastore" | 12 » dsS "github.com/luci/gae/service/datastore" |
| 13 . "github.com/smartystreets/goconvey/convey" | 13 . "github.com/smartystreets/goconvey/convey" |
| 14 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
| 15 ) | 15 ) |
| 16 | 16 |
| 17 func TestDatastoreKinder(t *testing.T) { | 17 func TestDatastoreKinder(t *testing.T) { |
| 18 t.Parallel() | 18 t.Parallel() |
| 19 | 19 |
| 20 Convey("Datastore keys", t, func() { | 20 Convey("Datastore keys", t, func() { |
| 21 c := Use(context.Background()) | 21 c := Use(context.Background()) |
| 22 » » rds := rdsS.Get(c) | 22 » » ds := dsS.Get(c) |
| 23 » » So(rds, ShouldNotBeNil) | 23 » » So(ds, ShouldNotBeNil) |
| 24 | 24 |
| 25 Convey("implements DSNewKeyer", func() { | 25 Convey("implements DSNewKeyer", func() { |
| 26 Convey("NewKey", func() { | 26 Convey("NewKey", func() { |
| 27 » » » » key := rds.NewKey("nerd", "stringID", 0, nil) | 27 » » » » key := ds.NewKey("nerd", "stringID", 0, nil) |
| 28 So(key, ShouldNotBeNil) | 28 So(key, ShouldNotBeNil) |
| 29 So(key.Kind(), ShouldEqual, "nerd") | 29 So(key.Kind(), ShouldEqual, "nerd") |
| 30 So(key.StringID(), ShouldEqual, "stringID") | 30 So(key.StringID(), ShouldEqual, "stringID") |
| 31 So(key.IntID(), ShouldEqual, 0) | 31 So(key.IntID(), ShouldEqual, 0) |
| 32 So(key.Parent(), ShouldBeNil) | 32 So(key.Parent(), ShouldBeNil) |
| 33 So(key.AppID(), ShouldEqual, "dev~app") | 33 So(key.AppID(), ShouldEqual, "dev~app") |
| 34 So(key.Namespace(), ShouldEqual, "") | 34 So(key.Namespace(), ShouldEqual, "") |
| 35 So(key.String(), ShouldEqual, "/nerd,stringID") | 35 So(key.String(), ShouldEqual, "/nerd,stringID") |
| 36 » » » » So(rdsS.KeyIncomplete(key), ShouldBeFalse) | 36 » » » » So(dsS.KeyIncomplete(key), ShouldBeFalse) |
| 37 » » » » So(rdsS.KeyValid(key, false, "dev~app", ""), Sho
uldBeTrue) | 37 » » » » So(dsS.KeyValid(key, false, "dev~app", ""), Shou
ldBeTrue) |
| 38 }) | 38 }) |
| 39 }) | 39 }) |
| 40 | 40 |
| 41 }) | 41 }) |
| 42 } | 42 } |
| 43 | 43 |
| 44 func testGetMeta(c context.Context, k rdsS.Key) int64 { | 44 type MetaGroup struct { |
| 45 » rds := rdsS.Get(c) | 45 » _id int64 `gae:"$id,1"` |
| 46 » retval := int64(0) | 46 » _kind string `gae:"$kind,__entity_group__"` |
| 47 » err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rds
S.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) { | 47 » Parent dsS.Key `gae:"$parent"` |
| 48 » » if err != nil { | 48 |
| 49 » » » panic(err) | 49 » Version int64 `gae:"__version__"` |
| 50 » » } | 50 } |
| 51 » » retval = val["__version__"][0].Value().(int64) | 51 |
| 52 » }) | 52 func testGetMeta(c context.Context, k dsS.Key) int64 { |
| 53 » if err != nil { | 53 » ds := dsS.Get(c) |
| 54 » mg := &MetaGroup{Parent: dsS.KeyRoot(k)} |
| 55 » if err := ds.Get(mg); err != nil { |
| 54 panic(err) | 56 panic(err) |
| 55 } | 57 } |
| 56 » return retval | 58 » return mg.Version |
| 57 } | 59 } |
| 58 | 60 |
| 59 var pls = rdsS.GetPLS | 61 var pls = dsS.GetPLS |
| 62 |
| 63 type Foo struct { |
| 64 » Id int64 `gae:"$id"` |
| 65 » Parent dsS.Key `gae:"$parent"` |
| 66 |
| 67 » Val int |
| 68 } |
| 60 | 69 |
| 61 func TestDatastoreSingleReadWriter(t *testing.T) { | 70 func TestDatastoreSingleReadWriter(t *testing.T) { |
| 62 t.Parallel() | 71 t.Parallel() |
| 63 | 72 |
| 64 getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMa
p, err error) { | |
| 65 blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.Prop
ertyMap, itmErr error) { | |
| 66 pmap = itmPmap | |
| 67 err = itmErr | |
| 68 }) | |
| 69 So(blankErr, ShouldBeNil) | |
| 70 return | |
| 71 } | |
| 72 | |
| 73 delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) { | |
| 74 blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error)
{ | |
| 75 err = itmErr | |
| 76 }) | |
| 77 So(blankErr, ShouldBeNil) | |
| 78 return | |
| 79 } | |
| 80 | |
| 81 delOne := func(rds rdsS.Interface, key rdsS.Key) { | |
| 82 So(delOneErr(rds, key), ShouldBeNil) | |
| 83 } | |
| 84 | |
| 85 getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) { | |
| 86 pm, err := getOnePM(rds, key) | |
| 87 So(err, ShouldBeNil) | |
| 88 So(pls(dst).Load(pm), ShouldBeNil) | |
| 89 } | |
| 90 | |
| 91 putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (re
tKey rdsS.Key, err error) { | |
| 92 blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSav
er{pls(val)}, func(itmKey rdsS.Key, itmErr error) { | |
| 93 err = itmErr | |
| 94 retKey = itmKey | |
| 95 }) | |
| 96 So(blankErr, ShouldBeNil) | |
| 97 return | |
| 98 } | |
| 99 | |
| 100 putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKe
y rdsS.Key) { | |
| 101 key, err := putOneErr(rds, key, val) | |
| 102 So(err, ShouldBeNil) | |
| 103 return key | |
| 104 } | |
| 105 | |
| 106 Convey("Datastore single reads and writes", t, func() { | 73 Convey("Datastore single reads and writes", t, func() { |
| 107 c := Use(context.Background()) | 74 c := Use(context.Background()) |
| 108 » » rds := rdsS.Get(c) | 75 » » ds := dsS.Get(c) |
| 109 » » So(rds, ShouldNotBeNil) | 76 » » So(ds, ShouldNotBeNil) |
| 110 | 77 |
| 111 Convey("implements DSSingleReadWriter", func() { | 78 Convey("implements DSSingleReadWriter", func() { |
| 112 type Foo struct { | |
| 113 Val int | |
| 114 } | |
| 115 | |
| 116 Convey("getting objects that DNE is an error", func() { | 79 Convey("getting objects that DNE is an error", func() { |
| 117 » » » » _, err := getOnePM(rds, rds.NewKey("Foo", "", 1,
nil)) | 80 » » » » So(ds.Get(&Foo{Id: 1}), ShouldEqual, dsS.ErrNoSu
chEntity) |
| 118 » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | |
| 119 }) | 81 }) |
| 120 | 82 |
| 121 Convey("Can Put stuff", func() { | 83 Convey("Can Put stuff", func() { |
| 122 // with an incomplete key! | 84 // with an incomplete key! |
| 123 k := rds.NewKey("Foo", "", 0, nil) | |
| 124 f := &Foo{Val: 10} | 85 f := &Foo{Val: 10} |
| 125 » » » » k = putOne(rds, k, f) | 86 » » » » So(ds.Put(f), ShouldBeNil) |
| 87 » » » » k := ds.NewKeyObj(f) |
| 126 So(k.String(), ShouldEqual, "/Foo,1") | 88 So(k.String(), ShouldEqual, "/Foo,1") |
| 127 | 89 |
| 128 Convey("and Get it back", func() { | 90 Convey("and Get it back", func() { |
| 129 » » » » » newFoo := &Foo{} | 91 » » » » » newFoo := &Foo{Id: 1} |
| 130 » » » » » getOne(rds, k, newFoo) | 92 » » » » » So(ds.Get(newFoo), ShouldBeNil) |
| 131 So(newFoo, ShouldResemble, f) | 93 So(newFoo, ShouldResemble, f) |
| 132 | 94 |
| 133 Convey("and we can Delete it", func() { | 95 Convey("and we can Delete it", func() { |
| 134 » » » » » » delOne(rds, k) | 96 » » » » » » So(ds.Delete(k), ShouldBeNil) |
| 135 » » » » » » _, err := getOnePM(rds, k) | 97 » » » » » » So(ds.Get(newFoo), ShouldEqual,
dsS.ErrNoSuchEntity) |
| 136 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS
uchEntity) | |
| 137 }) | 98 }) |
| 138 }) | 99 }) |
| 139 Convey("Deleteing with a bogus key is bad", func
() { | 100 Convey("Deleteing with a bogus key is bad", func
() { |
| 140 » » » » » So(delOneErr(rds, rds.NewKey("Foo", "wat
", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey) | 101 » » » » » So(ds.Delete(ds.NewKey("Foo", "wat", 100
, nil)), ShouldEqual, dsS.ErrInvalidKey) |
| 141 }) | 102 }) |
| 142 Convey("Deleteing a DNE entity is fine", func()
{ | 103 Convey("Deleteing a DNE entity is fine", func()
{ |
| 143 » » » » » delOne(rds, rds.NewKey("Foo", "wat", 0,
nil)) | 104 » » » » » So(ds.Delete(ds.NewKey("Foo", "wat", 0,
nil)), ShouldBeNil) |
| 144 }) | 105 }) |
| 145 | 106 |
| 146 Convey("with multiple puts", func() { | 107 Convey("with multiple puts", func() { |
| 147 So(testGetMeta(c, k), ShouldEqual, 1) | 108 So(testGetMeta(c, k), ShouldEqual, 1) |
| 148 | 109 |
| 149 » » » » » keys := []rdsS.Key{} | 110 » » » » » foos := make([]Foo, 10) |
| 150 » » » » » vals := []rdsS.PropertyLoadSaver{} | 111 » » » » » for i := range foos { |
| 151 | 112 » » » » » » foos[i].Val = 10 |
| 152 » » » » » pkey := k | 113 » » » » » » foos[i].Parent = k |
| 153 » » » » » for i := 0; i < 10; i++ { | |
| 154 » » » » » » keys = append(keys, rds.NewKey("
Foo", "", 0, pkey)) | |
| 155 » » » » » » vals = append(vals, pls(&Foo{Val
: 10})) | |
| 156 } | 114 } |
| 157 » » » » » i := 0 | 115 » » » » » So(ds.PutMulti(foos), ShouldBeNil) |
| 158 » » » » » err := rds.PutMulti(keys, vals, func(k r
dsS.Key, err error) { | |
| 159 » » » » » » So(err, ShouldBeNil) | |
| 160 » » » » » » keys[i] = k | |
| 161 » » » » » » i++ | |
| 162 » » » » » }) | |
| 163 » » » » » So(err, ShouldBeNil) | |
| 164 So(testGetMeta(c, k), ShouldEqual, 11) | 116 So(testGetMeta(c, k), ShouldEqual, 11) |
| 165 | 117 |
| 118 keys := make([]dsS.Key, len(foos)) |
| 119 for i, f := range foos { |
| 120 keys[i] = ds.NewKeyObj(&f) |
| 121 } |
| 122 |
| 166 Convey("ensure that group versions persi
st across deletes", func() { | 123 Convey("ensure that group versions persi
st across deletes", func() { |
| 167 » » » » » » keys = append(keys, pkey) | 124 » » » » » » So(ds.DeleteMulti(append(keys, k
)), ShouldBeNil) |
| 168 » » » » » » err := rds.DeleteMulti(keys, fun
c(err error) { | |
| 169 » » » » » » » So(err, ShouldBeNil) | |
| 170 » » » » » » }) | |
| 171 » » » » » » So(err, ShouldBeNil) | |
| 172 | 125 |
| 173 // TODO(riannucci): replace with
a Count query instead of this cast | 126 // TODO(riannucci): replace with
a Count query instead of this cast |
| 174 /* | 127 /* |
| 175 » » » » » » » ents := rds.(*dsImpl).da
ta.store.GetCollection("ents:") | 128 » » » » » » » ents := ds.(*dsImpl).dat
a.store.GetCollection("ents:") |
| 176 num, _ := ents.GetTotals
() | 129 num, _ := ents.GetTotals
() |
| 177 // /__entity_root_ids__,
Foo | 130 // /__entity_root_ids__,
Foo |
| 178 // /Foo,1/__entity_group
__,1 | 131 // /Foo,1/__entity_group
__,1 |
| 179 // /Foo,1/__entity_group
_ids__,1 | 132 // /Foo,1/__entity_group
_ids__,1 |
| 180 So(num, ShouldEqual, 3) | 133 So(num, ShouldEqual, 3) |
| 181 */ | 134 */ |
| 182 | 135 |
| 183 So(testGetMeta(c, k), ShouldEqua
l, 22) | 136 So(testGetMeta(c, k), ShouldEqua
l, 22) |
| 184 | 137 |
| 185 » » » » » » putOne(rds, k, f) | 138 » » » » » » So(ds.Put(&Foo{Id: 1}), ShouldBe
Nil) |
| 186 So(testGetMeta(c, k), ShouldEqua
l, 23) | 139 So(testGetMeta(c, k), ShouldEqua
l, 23) |
| 187 }) | 140 }) |
| 188 | 141 |
| 189 Convey("can Get", func() { | 142 Convey("can Get", func() { |
| 190 » » » » » » vals := []rdsS.PropertyMap{} | 143 » » » » » » vals := make([]dsS.PropertyMap,
len(keys)) |
| 191 » » » » » » err := rds.GetMulti(keys, func(p
m rdsS.PropertyMap, err error) { | 144 » » » » » » for i := range vals { |
| 192 » » » » » » » So(err, ShouldBeNil) | 145 » » » » » » » vals[i] = dsS.PropertyMa
p{} |
| 193 » » » » » » » vals = append(vals, pm) | 146 » » » » » » » vals[i].SetMeta("key", k
eys[i]) |
| 194 » » » » » » }) | 147 » » » » » » } |
| 195 » » » » » » So(err, ShouldBeNil) | 148 » » » » » » So(ds.GetMulti(vals), ShouldBeNi
l) |
| 196 | 149 |
| 197 » » » » » » for _, val := range vals { | 150 » » » » » » for i, val := range vals { |
| 198 » » » » » » » So(val, ShouldResemble,
rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}}) | 151 » » » » » » » So(val, ShouldResemble,
dsS.PropertyMap{ |
| 152 » » » » » » » » "Val": {dsS.MkP
roperty(10)}, |
| 153 » » » » » » » » "$key": {dsS.MkP
ropertyNI(keys[i])}, |
| 154 » » » » » » » }) |
| 199 } | 155 } |
| 200 }) | 156 }) |
| 201 }) | 157 }) |
| 202 }) | 158 }) |
| 203 }) | 159 }) |
| 204 | 160 |
| 205 Convey("implements DSTransactioner", func() { | 161 Convey("implements DSTransactioner", func() { |
| 206 type Foo struct { | |
| 207 Val int | |
| 208 } | |
| 209 Convey("Put", func() { | 162 Convey("Put", func() { |
| 210 f := &Foo{Val: 10} | 163 f := &Foo{Val: 10} |
| 211 » » » » origKey := rds.NewKey("Foo", "", 0, nil) | 164 » » » » So(ds.Put(f), ShouldBeNil) |
| 212 » » » » k := putOne(rds, origKey, f) | 165 » » » » k := ds.NewKeyObj(f) |
| 213 So(k.String(), ShouldEqual, "/Foo,1") | 166 So(k.String(), ShouldEqual, "/Foo,1") |
| 214 | 167 |
| 215 Convey("can Put new entity groups", func() { | 168 Convey("can Put new entity groups", func() { |
| 216 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 169 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 217 » » » » » » rds := rdsS.Get(c) | 170 » » » » » » ds := dsS.Get(c) |
| 218 | 171 |
| 219 » » » » » » f1 := &Foo{Val: 100} | 172 » » » » » » f := &Foo{Val: 100} |
| 220 » » » » » » k := putOne(rds, origKey, f1) | 173 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 221 » » » » » » So(k.String(), ShouldEqual, "/Fo
o,2") | 174 » » » » » » So(f.Id, ShouldEqual, 2) |
| 222 | 175 |
| 223 » » » » » » f2 := &Foo{Val: 200} | 176 » » » » » » f.Id = 0 |
| 224 » » » » » » k = putOne(rds, origKey, f2) | 177 » » » » » » f.Val = 200 |
| 225 » » » » » » So(k.String(), ShouldEqual, "/Fo
o,3") | 178 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 179 » » » » » » So(f.Id, ShouldEqual, 3) |
| 226 | 180 |
| 227 return nil | 181 return nil |
| 228 » » » » » }, &rdsS.TransactionOptions{XG: true}) | 182 » » » » » }, &dsS.TransactionOptions{XG: true}) |
| 229 So(err, ShouldBeNil) | 183 So(err, ShouldBeNil) |
| 230 | 184 |
| 231 » » » » » f := &Foo{} | 185 » » » » » f := &Foo{Id: 2} |
| 232 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, nil
), f) | 186 » » » » » So(ds.Get(f), ShouldBeNil) |
| 233 So(f.Val, ShouldEqual, 100) | 187 So(f.Val, ShouldEqual, 100) |
| 234 | 188 |
| 235 » » » » » getOne(rds, rds.NewKey("Foo", "", 3, nil
), f) | 189 » » » » » f.Id = 3 |
| 190 » » » » » So(ds.Get(f), ShouldBeNil) |
| 236 So(f.Val, ShouldEqual, 200) | 191 So(f.Val, ShouldEqual, 200) |
| 237 }) | 192 }) |
| 238 | 193 |
| 239 Convey("can Put new entities in a current group"
, func() { | 194 Convey("can Put new entities in a current group"
, func() { |
| 240 » » » » » par := k | 195 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 241 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 196 » » » » » » ds := dsS.Get(c) |
| 242 » » » » » » rds := rdsS.Get(c) | |
| 243 » » » » » » So(rds, ShouldNotBeNil) | |
| 244 | 197 |
| 245 » » » » » » f1 := &Foo{Val: 100} | 198 » » » » » » f := &Foo{Val: 100, Parent: k} |
| 246 » » » » » » k := putOne(rds, rds.NewKey("Foo
", "", 0, par), f1) | 199 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 247 » » » » » » So(k.String(), ShouldEqual, "/Fo
o,1/Foo,1") | 200 » » » » » » So(ds.NewKeyObj(f).String(), Sho
uldEqual, "/Foo,1/Foo,1") |
| 248 | 201 |
| 249 » » » » » » f2 := &Foo{Val: 200} | 202 » » » » » » f.Id = 0 |
| 250 » » » » » » k = putOne(rds, rds.NewKey("Foo"
, "", 0, par), f2) | 203 » » » » » » f.Val = 200 |
| 251 » » » » » » So(k.String(), ShouldEqual, "/Fo
o,1/Foo,2") | 204 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 205 » » » » » » So(ds.NewKeyObj(f).String(), Sho
uldEqual, "/Foo,1/Foo,2") |
| 252 | 206 |
| 253 return nil | 207 return nil |
| 254 }, nil) | 208 }, nil) |
| 255 So(err, ShouldBeNil) | 209 So(err, ShouldBeNil) |
| 256 | 210 |
| 257 » » » » » f := &Foo{} | 211 » » » » » f := &Foo{Id: 1, Parent: k} |
| 258 » » » » » getOne(rds, rds.NewKey("Foo", "", 1, k),
f) | 212 » » » » » So(ds.Get(f), ShouldBeNil) |
| 259 So(f.Val, ShouldEqual, 100) | 213 So(f.Val, ShouldEqual, 100) |
| 260 | 214 |
| 261 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, k),
f) | 215 » » » » » f.Id = 2 |
| 216 » » » » » So(ds.Get(f), ShouldBeNil) |
| 262 So(f.Val, ShouldEqual, 200) | 217 So(f.Val, ShouldEqual, 200) |
| 263 }) | 218 }) |
| 264 | 219 |
| 265 Convey("Deletes work too", func() { | 220 Convey("Deletes work too", func() { |
| 266 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 221 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 267 » » » » » » rds := rdsS.Get(c) | 222 » » » » » » return dsS.Get(c).Delete(k) |
| 268 » » » » » » So(rds, ShouldNotBeNil) | |
| 269 » » » » » » delOne(rds, k) | |
| 270 » » » » » » return nil | |
| 271 }, nil) | 223 }, nil) |
| 272 So(err, ShouldBeNil) | 224 So(err, ShouldBeNil) |
| 273 » » » » » _, err = getOnePM(rds, k) | 225 » » » » » So(ds.Get(&Foo{Id: 1}), ShouldEqual, dsS
.ErrNoSuchEntity) |
| 274 » » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntit
y) | |
| 275 }) | 226 }) |
| 276 | 227 |
| 277 Convey("A Get counts against your group count",
func() { | 228 Convey("A Get counts against your group count",
func() { |
| 278 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 229 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 279 » » » » » » rds := rdsS.Get(c) | 230 » » » » » » ds := dsS.Get(c) |
| 280 | 231 |
| 281 » » » » » » _, err := getOnePM(rds, rds.NewK
ey("Foo", "", 20, nil)) | 232 » » » » » » pm := dsS.PropertyMap{} |
| 282 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS
uchEntity) | 233 » » » » » » pm.SetMeta("key", ds.NewKey("Foo
", "", 20, nil)) |
| 234 » » » » » » So(ds.Get(pm), ShouldEqual, dsS.
ErrNoSuchEntity) |
| 283 | 235 |
| 284 » » » » » » err = rds.GetMulti([]rdsS.Key{k}
, func(_ rdsS.PropertyMap, err error) { | 236 » » » » » » pm.SetMeta("key", k) |
| 285 » » » » » » » So(err, ShouldBeNil) | 237 » » » » » » So(ds.Get(pm).Error(), ShouldCon
tainSubstring, "cross-group") |
| 286 » » » » » » }) | |
| 287 » » » » » » So(err.Error(), ShouldContainSub
string, "cross-group") | |
| 288 return nil | 238 return nil |
| 289 }, nil) | 239 }, nil) |
| 290 So(err, ShouldBeNil) | 240 So(err, ShouldBeNil) |
| 291 }) | 241 }) |
| 292 | 242 |
| 293 Convey("Get takes a snapshot", func() { | 243 Convey("Get takes a snapshot", func() { |
| 294 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 244 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 295 » » » » » » txnDS := rdsS.Get(c) | 245 » » » » » » txnDS := dsS.Get(c) |
| 296 » » » » » » So(txnDS, ShouldNotBeNil) | |
| 297 | 246 |
| 298 » » » » » » getOne(txnDS, k, f) | 247 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 299 So(f.Val, ShouldEqual, 10) | 248 So(f.Val, ShouldEqual, 10) |
| 300 | 249 |
| 301 // Don't ever do this in a real
program unless you want to guarantee | 250 // Don't ever do this in a real
program unless you want to guarantee |
| 302 // a failed transaction :) | 251 // a failed transaction :) |
| 303 f.Val = 11 | 252 f.Val = 11 |
| 304 » » » » » » putOne(rds, k, f) | 253 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 305 | 254 |
| 306 » » » » » » getOne(txnDS, k, f) | 255 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 307 So(f.Val, ShouldEqual, 10) | 256 So(f.Val, ShouldEqual, 10) |
| 308 | 257 |
| 309 return nil | 258 return nil |
| 310 }, nil) | 259 }, nil) |
| 311 So(err, ShouldBeNil) | 260 So(err, ShouldBeNil) |
| 312 | 261 |
| 313 » » » » » f := &Foo{} | 262 » » » » » f := &Foo{Id: 1} |
| 314 » » » » » getOne(rds, k, f) | 263 » » » » » So(ds.Get(f), ShouldBeNil) |
| 315 So(f.Val, ShouldEqual, 11) | 264 So(f.Val, ShouldEqual, 11) |
| 316 }) | 265 }) |
| 317 | 266 |
| 318 Convey("and snapshots are consistent even after
Puts", func() { | 267 Convey("and snapshots are consistent even after
Puts", func() { |
| 319 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 268 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 320 » » » » » » txnDS := rdsS.Get(c) | 269 » » » » » » txnDS := dsS.Get(c) |
| 321 » » » » » » So(txnDS, ShouldNotBeNil) | |
| 322 | 270 |
| 323 » » » » » » f := &Foo{} | 271 » » » » » » f := &Foo{Id: 1} |
| 324 » » » » » » getOne(txnDS, k, f) | 272 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 325 So(f.Val, ShouldEqual, 10) | 273 So(f.Val, ShouldEqual, 10) |
| 326 | 274 |
| 327 // Don't ever do this in a real
program unless you want to guarantee | 275 // Don't ever do this in a real
program unless you want to guarantee |
| 328 // a failed transaction :) | 276 // a failed transaction :) |
| 329 f.Val = 11 | 277 f.Val = 11 |
| 330 » » » » » » putOne(rds, k, f) | 278 » » » » » » So(ds.Put(f), ShouldBeNil) |
| 331 | 279 |
| 332 » » » » » » getOne(txnDS, k, f) | 280 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 333 So(f.Val, ShouldEqual, 10) | 281 So(f.Val, ShouldEqual, 10) |
| 334 | 282 |
| 335 f.Val = 20 | 283 f.Val = 20 |
| 336 » » » » » » putOne(txnDS, k, f) | 284 » » » » » » So(txnDS.Put(f), ShouldBeNil) |
| 337 | 285 |
| 338 » » » » » » getOne(txnDS, k, f) | 286 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 339 So(f.Val, ShouldEqual, 10) // st
ill gets 10 | 287 So(f.Val, ShouldEqual, 10) // st
ill gets 10 |
| 340 | 288 |
| 341 return nil | 289 return nil |
| 342 }, nil) | 290 }, nil) |
| 343 So(err.Error(), ShouldContainSubstring,
"concurrent") | 291 So(err.Error(), ShouldContainSubstring,
"concurrent") |
| 344 | 292 |
| 345 » » » » » f := &Foo{} | 293 » » » » » f := &Foo{Id: 1} |
| 346 » » » » » getOne(rds, k, f) | 294 » » » » » So(ds.Get(f), ShouldBeNil) |
| 347 So(f.Val, ShouldEqual, 11) | 295 So(f.Val, ShouldEqual, 11) |
| 348 }) | 296 }) |
| 349 | 297 |
| 350 Convey("Reusing a transaction context is bad new
s", func() { | 298 Convey("Reusing a transaction context is bad new
s", func() { |
| 351 » » » » » k := rds.NewKey("Foo", "", 1, nil) | 299 » » » » » txnDS := dsS.Interface(nil) |
| 352 » » » » » txnDS := rdsS.Interface(nil) | 300 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 353 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 301 » » » » » » txnDS = dsS.Get(c) |
| 354 » » » » » » txnDS = rdsS.Get(c) | 302 » » » » » » So(txnDS.Get(f), ShouldBeNil) |
| 355 » » » » » » getOnePM(txnDS, k) | |
| 356 return nil | 303 return nil |
| 357 }, nil) | 304 }, nil) |
| 358 So(err, ShouldBeNil) | 305 So(err, ShouldBeNil) |
| 359 » » » » » err = txnDS.GetMulti([]rdsS.Key{k}, func
(_ rdsS.PropertyMap, err error) { | 306 » » » » » So(txnDS.Get(f).Error(), ShouldContainSu
bstring, "expired") |
| 360 » » » » » » So(err, ShouldBeNil) | |
| 361 » » » » » }) | |
| 362 » » » » » So(err.Error(), ShouldContainSubstring,
"expired") | |
| 363 }) | 307 }) |
| 364 | 308 |
| 365 Convey("Nested transactions are rejected", func(
) { | 309 Convey("Nested transactions are rejected", func(
) { |
| 366 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 310 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 367 » » » » » » err := rdsS.Get(c).RunInTransact
ion(func(c context.Context) error { | 311 » » » » » » err := dsS.Get(c).RunInTransacti
on(func(c context.Context) error { |
| 368 panic("noooo") | 312 panic("noooo") |
| 369 }, nil) | 313 }, nil) |
| 370 So(err.Error(), ShouldContainSub
string, "nested transactions") | 314 So(err.Error(), ShouldContainSub
string, "nested transactions") |
| 371 return nil | 315 return nil |
| 372 }, nil) | 316 }, nil) |
| 373 So(err, ShouldBeNil) | 317 So(err, ShouldBeNil) |
| 374 }) | 318 }) |
| 375 | 319 |
| 376 Convey("Concurrent transactions only accept one
set of changes", func() { | 320 Convey("Concurrent transactions only accept one
set of changes", func() { |
| 377 // Note: I think this implementation is
actually /slightly/ wrong. | 321 // Note: I think this implementation is
actually /slightly/ wrong. |
| 378 // Accorting to my read of the docs for
appengine, when you open a | 322 // Accorting to my read of the docs for
appengine, when you open a |
| 379 // transaction it actually (essentially)
holds a reference to the | 323 // transaction it actually (essentially)
holds a reference to the |
| 380 // entire datastore. Our implementation
takes a snapshot of the | 324 // entire datastore. Our implementation
takes a snapshot of the |
| 381 // entity group as soon as something obs
erves/affects it. | 325 // entity group as soon as something obs
erves/affects it. |
| 382 // | 326 // |
| 383 // That said... I'm not sure if there's
really a semantic difference. | 327 // That said... I'm not sure if there's
really a semantic difference. |
| 384 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 328 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
| 385 » » » » » » txnDS := rdsS.Get(c) | 329 » » » » » » So(dsS.Get(c).Put(&Foo{Id: 1, Va
l: 21}), ShouldBeNil) |
| 386 » » » » » » f := &Foo{Val: 21} | |
| 387 » » » » » » putOne(txnDS, k, f) | |
| 388 | 330 |
| 389 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 331 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
| 390 » » » » » » » txnDS := rdsS.Get(c) | 332 » » » » » » » So(dsS.Get(c).Put(&Foo{I
d: 1, Val: 27}), ShouldBeNil) |
| 391 » » » » » » » f := &Foo{Val: 27} | |
| 392 » » » » » » » putOne(txnDS, k, f) | |
| 393 return nil | 333 return nil |
| 394 }, nil) | 334 }, nil) |
| 395 So(err, ShouldBeNil) | 335 So(err, ShouldBeNil) |
| 396 | 336 |
| 397 return nil | 337 return nil |
| 398 }, nil) | 338 }, nil) |
| 399 So(err.Error(), ShouldContainSubstring,
"concurrent") | 339 So(err.Error(), ShouldContainSubstring,
"concurrent") |
| 400 | 340 |
| 401 » » » » » f := &Foo{} | 341 » » » » » f := &Foo{Id: 1} |
| 402 » » » » » getOne(rds, k, f) | 342 » » » » » So(ds.Get(f), ShouldBeNil) |
| 403 So(f.Val, ShouldEqual, 27) | 343 So(f.Val, ShouldEqual, 27) |
| 404 }) | 344 }) |
| 405 | 345 |
| 406 Convey("XG", func() { | 346 Convey("XG", func() { |
| 407 Convey("Modifying two groups with XG=fal
se is invalid", func() { | 347 Convey("Modifying two groups with XG=fal
se is invalid", func() { |
| 408 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 348 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
| 409 » » » » » » » rds := rdsS.Get(c) | 349 » » » » » » » ds := dsS.Get(c) |
| 410 » » » » » » » f := &Foo{Val: 200} | 350 » » » » » » » f := &Foo{Id: 1, Val: 20
0} |
| 411 » » » » » » » putOne(rds, k, f) | 351 » » » » » » » So(ds.Put(f), ShouldBeNi
l) |
| 412 | 352 |
| 413 » » » » » » » _, err := putOneErr(rds,
rds.NewKey("Foo", "", 2, nil), f) | 353 » » » » » » » f.Id = 2 |
| 354 » » » » » » » err := ds.Put(f) |
| 414 So(err.Error(), ShouldCo
ntainSubstring, "cross-group") | 355 So(err.Error(), ShouldCo
ntainSubstring, "cross-group") |
| 415 return err | 356 return err |
| 416 }, nil) | 357 }, nil) |
| 417 So(err.Error(), ShouldContainSub
string, "cross-group") | 358 So(err.Error(), ShouldContainSub
string, "cross-group") |
| 418 }) | 359 }) |
| 419 | 360 |
| 420 Convey("Modifying >25 groups with XG=tru
e is invald", func() { | 361 Convey("Modifying >25 groups with XG=tru
e is invald", func() { |
| 421 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 362 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
| 422 » » » » » » » rds := rdsS.Get(c) | 363 » » » » » » » ds := dsS.Get(c) |
| 364 » » » » » » » foos := make([]Foo, 25) |
| 423 for i := int64(1); i < 2
6; i++ { | 365 for i := int64(1); i < 2
6; i++ { |
| 424 » » » » » » » » k := rds.NewKey(
"Foo", "", i, nil) | 366 » » » » » » » » foos[i-1].Id = i |
| 425 » » » » » » » » f := &Foo{Val: 2
00} | 367 » » » » » » » » foos[i-1].Val =
200 |
| 426 » » » » » » » » putOne(rds, k, f
) | |
| 427 } | 368 } |
| 428 » » » » » » » f := &Foo{Val: 200} | 369 » » » » » » » So(ds.PutMulti(foos), Sh
ouldBeNil) |
| 429 » » » » » » » _, err := putOneErr(rds,
rds.NewKey("Foo", "", 27, nil), f) | 370 » » » » » » » err := ds.Put(&Foo{Id: 2
6}) |
| 430 So(err.Error(), ShouldCo
ntainSubstring, "too many entity groups") | 371 So(err.Error(), ShouldCo
ntainSubstring, "too many entity groups") |
| 431 return err | 372 return err |
| 432 » » » » » » }, &rdsS.TransactionOptions{XG:
true}) | 373 » » » » » » }, &dsS.TransactionOptions{XG: t
rue}) |
| 433 So(err.Error(), ShouldContainSub
string, "too many entity groups") | 374 So(err.Error(), ShouldContainSub
string, "too many entity groups") |
| 434 }) | 375 }) |
| 435 }) | 376 }) |
| 436 | 377 |
| 437 Convey("Errors and panics", func() { | 378 Convey("Errors and panics", func() { |
| 438 Convey("returning an error aborts", func
() { | 379 Convey("returning an error aborts", func
() { |
| 439 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 380 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
| 440 » » » » » » » rds := rdsS.Get(c) | 381 » » » » » » » ds := dsS.Get(c) |
| 441 » » » » » » » f := &Foo{Val: 200} | 382 » » » » » » » So(ds.Put(&Foo{Id: 1, Va
l: 200}), ShouldBeNil) |
| 442 » » » » » » » putOne(rds, k, f) | |
| 443 | |
| 444 return fmt.Errorf("thing
y") | 383 return fmt.Errorf("thing
y") |
| 445 }, nil) | 384 }, nil) |
| 446 So(err.Error(), ShouldEqual, "th
ingy") | 385 So(err.Error(), ShouldEqual, "th
ingy") |
| 447 | 386 |
| 448 » » » » » » f := &Foo{} | 387 » » » » » » f := &Foo{Id: 1} |
| 449 » » » » » » getOne(rds, k, f) | 388 » » » » » » So(ds.Get(f), ShouldBeNil) |
| 450 So(f.Val, ShouldEqual, 10) | 389 So(f.Val, ShouldEqual, 10) |
| 451 }) | 390 }) |
| 452 | 391 |
| 453 Convey("panicing aborts", func() { | 392 Convey("panicing aborts", func() { |
| 454 So(func() { | 393 So(func() { |
| 455 » » » » » » » rds.RunInTransaction(fun
c(c context.Context) error { | 394 » » » » » » » ds.RunInTransaction(func
(c context.Context) error { |
| 456 » » » » » » » » rds := rdsS.Get(
c) | 395 » » » » » » » » ds := dsS.Get(c) |
| 457 » » » » » » » » f := &Foo{Val: 2
00} | 396 » » » » » » » » So(ds.Put(&Foo{V
al: 200}), ShouldBeNil) |
| 458 » » » » » » » » putOne(rds, k, f
) | |
| 459 panic("wheeeeee"
) | 397 panic("wheeeeee"
) |
| 460 }, nil) | 398 }, nil) |
| 461 }, ShouldPanic) | 399 }, ShouldPanic) |
| 462 | 400 |
| 463 » » » » » » f := &Foo{} | 401 » » » » » » f := &Foo{Id: 1} |
| 464 » » » » » » getOne(rds, k, f) | 402 » » » » » » So(ds.Get(f), ShouldBeNil) |
| 465 So(f.Val, ShouldEqual, 10) | 403 So(f.Val, ShouldEqual, 10) |
| 466 }) | 404 }) |
| 467 }) | 405 }) |
| 468 }) | 406 }) |
| 469 }) | 407 }) |
| 470 | 408 |
| 471 }) | 409 }) |
| 472 } | 410 } |
| 473 | 411 |
| 474 const MaxUint = ^uint(0) | 412 const MaxUint = ^uint(0) |
| 475 const MaxInt = int(MaxUint >> 1) | 413 const MaxInt = int(MaxUint >> 1) |
| 476 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 | 414 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 |
| 477 | 415 |
| 478 func TestDatastoreQueryer(t *testing.T) { | 416 func TestDatastoreQueryer(t *testing.T) { |
| 479 Convey("Datastore Query suport", t, func() { | 417 Convey("Datastore Query suport", t, func() { |
| 480 c := Use(context.Background()) | 418 c := Use(context.Background()) |
| 481 » » rds := rdsS.Get(c) | 419 » » ds := dsS.Get(c) |
| 482 » » So(rds, ShouldNotBeNil) | 420 » » So(ds, ShouldNotBeNil) |
| 483 | 421 |
| 484 Convey("can create good queries", func() { | 422 Convey("can create good queries", func() { |
| 485 » » » q := rds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) | 423 » » » q := ds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) |
| 486 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab
s")) | 424 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab
s")) |
| 487 So(q, ShouldNotBeNil) | 425 So(q, ShouldNotBeNil) |
| 488 So(q.(*queryImpl).err, ShouldBeNil) | 426 So(q.(*queryImpl).err, ShouldBeNil) |
| 489 qi := q.(*queryImpl).checkCorrectness("", false) | 427 qi := q.(*queryImpl).checkCorrectness("", false) |
| 490 So(qi.err, ShouldBeNil) | 428 So(qi.err, ShouldBeNil) |
| 491 }) | 429 }) |
| 492 | 430 |
| 493 Convey("normalize ensures orders make sense", func() { | 431 Convey("normalize ensures orders make sense", func() { |
| 494 » » » q := rds.NewQuery("Cool") | 432 » » » q := ds.NewQuery("Cool") |
| 495 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob
").Order("bob") | 433 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob
").Order("bob") |
| 496 | 434 |
| 497 Convey("removes dups and equality orders", func() { | 435 Convey("removes dups and equality orders", func() { |
| 498 q = q.Order("wat") | 436 q = q.Order("wat") |
| 499 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 437 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 500 So(qi.err, ShouldBeNil) | 438 So(qi.err, ShouldBeNil) |
| 501 So(qi.order, ShouldResemble, []queryOrder{{"wat"
, qASC}}) | 439 So(qi.order, ShouldResemble, []queryOrder{{"wat"
, qASC}}) |
| 502 }) | 440 }) |
| 503 | 441 |
| 504 Convey("keeps inequality orders", func() { | 442 Convey("keeps inequality orders", func() { |
| 505 q = q.Order("wat") | 443 q = q.Order("wat") |
| 506 q := q.Filter("bob >", 10).Filter("wat <", 29) | 444 q := q.Filter("bob >", 10).Filter("wat <", 29) |
| 507 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 445 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 508 So(qi.order, ShouldResemble, []queryOrder{{"bob"
, qASC}, {"wat", qASC}}) | 446 So(qi.order, ShouldResemble, []queryOrder{{"bob"
, qASC}, {"wat", qASC}}) |
| 509 So(qi.err.Error(), ShouldContainSubstring, "Only
one inequality") | 447 So(qi.err.Error(), ShouldContainSubstring, "Only
one inequality") |
| 510 }) | 448 }) |
| 511 | 449 |
| 512 Convey("if we equality-filter on __key__, order is ditch
ed", func() { | 450 Convey("if we equality-filter on __key__, order is ditch
ed", func() { |
| 513 q = q.Order("wat") | 451 q = q.Order("wat") |
| 514 » » » » q := q.Filter("__key__ =", rds.NewKey("Foo", "wa
t", 0, nil)) | 452 » » » » q := q.Filter("__key__ =", ds.NewKey("Foo", "wat
", 0, nil)) |
| 515 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 453 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 516 So(qi.order, ShouldResemble, []queryOrder(nil)) | 454 So(qi.order, ShouldResemble, []queryOrder(nil)) |
| 517 So(qi.err, ShouldBeNil) | 455 So(qi.err, ShouldBeNil) |
| 518 }) | 456 }) |
| 519 | 457 |
| 520 Convey("if we order by key and something else, key domin
ates", func() { | 458 Convey("if we order by key and something else, key domin
ates", func() { |
| 521 q := q.Order("__key__").Order("wat") | 459 q := q.Order("__key__").Order("wat") |
| 522 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 460 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 523 So(qi.order, ShouldResemble, []queryOrder{{"__ke
y__", qASC}}) | 461 So(qi.order, ShouldResemble, []queryOrder{{"__ke
y__", qASC}}) |
| 524 So(qi.err, ShouldBeNil) | 462 So(qi.err, ShouldBeNil) |
| 525 }) | 463 }) |
| 526 }) | 464 }) |
| 527 | 465 |
| 528 Convey("can create bad queries", func() { | 466 Convey("can create bad queries", func() { |
| 529 » » » q := rds.NewQuery("Foo") | 467 » » » q := ds.NewQuery("Foo") |
| 530 | 468 |
| 531 Convey("bad filter ops", func() { | 469 Convey("bad filter ops", func() { |
| 532 q := q.Filter("Bob !", "value") | 470 q := q.Filter("Bob !", "value") |
| 533 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid operator \"!\"") | 471 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid operator \"!\"") |
| 534 }) | 472 }) |
| 535 Convey("bad filter", func() { | 473 Convey("bad filter", func() { |
| 536 q := q.Filter("Bob", "value") | 474 q := q.Filter("Bob", "value") |
| 537 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid filter") | 475 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid filter") |
| 538 }) | 476 }) |
| 539 Convey("bad order", func() { | 477 Convey("bad order", func() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 560 if !IntIs32Bits { | 498 if !IntIs32Bits { |
| 561 q := q.Offset(MaxInt) | 499 q := q.Offset(MaxInt) |
| 562 So(q.(*queryImpl).err.Error(), ShouldCon
tainSubstring, "query offset overflow") | 500 So(q.(*queryImpl).err.Error(), ShouldCon
tainSubstring, "query offset overflow") |
| 563 } | 501 } |
| 564 }) | 502 }) |
| 565 Convey("Bad cursors", func() { | 503 Convey("Bad cursors", func() { |
| 566 q := q.Start(queryCursor("")).End(queryCursor(""
)) | 504 q := q.Start(queryCursor("")).End(queryCursor(""
)) |
| 567 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid cursor") | 505 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid cursor") |
| 568 }) | 506 }) |
| 569 Convey("Bad ancestors", func() { | 507 Convey("Bad ancestors", func() { |
| 570 » » » » q := q.Ancestor(rds.NewKey("Goop", "wat", 10, ni
l)) | 508 » » » » q := q.Ancestor(ds.NewKey("Goop", "wat", 10, nil
)) |
| 571 So(q, ShouldNotBeNil) | 509 So(q, ShouldNotBeNil) |
| 572 qi := q.(*queryImpl).checkCorrectness("", false) | 510 qi := q.(*queryImpl).checkCorrectness("", false) |
| 573 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) | 511 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey) |
| 574 }) | 512 }) |
| 575 Convey("nil ancestors", func() { | 513 Convey("nil ancestors", func() { |
| 576 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn
ess("", false) | 514 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn
ess("", false) |
| 577 So(qi.err.Error(), ShouldContainSubstring, "nil
query ancestor") | 515 So(qi.err.Error(), ShouldContainSubstring, "nil
query ancestor") |
| 578 }) | 516 }) |
| 579 Convey("Bad key filters", func() { | 517 Convey("Bad key filters", func() { |
| 580 » » » » q := q.Filter("__key__ =", rds.NewKey("Goop", "w
at", 10, nil)) | 518 » » » » q := q.Filter("__key__ =", ds.NewKey("Goop", "wa
t", 10, nil)) |
| 581 qi := q.(*queryImpl).checkCorrectness("", false) | 519 qi := q.(*queryImpl).checkCorrectness("", false) |
| 582 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) | 520 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey) |
| 583 }) | 521 }) |
| 584 Convey("non-ancestor queries in a transaction", func() { | 522 Convey("non-ancestor queries in a transaction", func() { |
| 585 qi := q.(*queryImpl).checkCorrectness("", true) | 523 qi := q.(*queryImpl).checkCorrectness("", true) |
| 586 So(qi.err.Error(), ShouldContainSubstring, "Only
ancestor queries") | 524 So(qi.err.Error(), ShouldContainSubstring, "Only
ancestor queries") |
| 587 }) | 525 }) |
| 588 Convey("absurd numbers of filters are prohibited", func(
) { | 526 Convey("absurd numbers of filters are prohibited", func(
) { |
| 589 » » » » q := q.Ancestor(rds.NewKey("thing", "wat", 0, ni
l)) | 527 » » » » q := q.Ancestor(ds.NewKey("thing", "wat", 0, nil
)) |
| 590 for i := 0; i < 100; i++ { | 528 for i := 0; i < 100; i++ { |
| 591 q = q.Filter("something =", 10) | 529 q = q.Filter("something =", 10) |
| 592 } | 530 } |
| 593 qi := q.(*queryImpl).checkCorrectness("", false) | 531 qi := q.(*queryImpl).checkCorrectness("", false) |
| 594 So(qi.err.Error(), ShouldContainSubstring, "quer
y is too large") | 532 So(qi.err.Error(), ShouldContainSubstring, "quer
y is too large") |
| 595 }) | 533 }) |
| 596 Convey("filters for __key__ that aren't keys", func() { | 534 Convey("filters for __key__ that aren't keys", func() { |
| 597 q := q.Filter("__key__ = ", 10) | 535 q := q.Filter("__key__ = ", 10) |
| 598 qi := q.(*queryImpl).checkCorrectness("", false) | 536 qi := q.(*queryImpl).checkCorrectness("", false) |
| 599 So(qi.err.Error(), ShouldContainSubstring, "must
be a Key") | 537 So(qi.err.Error(), ShouldContainSubstring, "must
be a Key") |
| 600 }) | 538 }) |
| 601 Convey("multiple inequalities", func() { | 539 Convey("multiple inequalities", func() { |
| 602 q := q.Filter("bob > ", 19).Filter("charlie < ",
20) | 540 q := q.Filter("bob > ", 19).Filter("charlie < ",
20) |
| 603 qi := q.(*queryImpl).checkCorrectness("", false) | 541 qi := q.(*queryImpl).checkCorrectness("", false) |
| 604 So(qi.err.Error(), ShouldContainSubstring, "one
inequality filter") | 542 So(qi.err.Error(), ShouldContainSubstring, "one
inequality filter") |
| 605 }) | 543 }) |
| 606 Convey("bad sort orders", func() { | 544 Convey("bad sort orders", func() { |
| 607 q := q.Filter("bob > ", 19).Order("-charlie") | 545 q := q.Filter("bob > ", 19).Order("-charlie") |
| 608 qi := q.(*queryImpl).checkCorrectness("", false) | 546 qi := q.(*queryImpl).checkCorrectness("", false) |
| 609 So(qi.err.Error(), ShouldContainSubstring, "firs
t sort property") | 547 So(qi.err.Error(), ShouldContainSubstring, "firs
t sort property") |
| 610 }) | 548 }) |
| 611 Convey("kindless with non-__key__ filters", func() { | 549 Convey("kindless with non-__key__ filters", func() { |
| 612 » » » » q := rds.NewQuery("").Filter("face <", 25.3) | 550 » » » » q := ds.NewQuery("").Filter("face <", 25.3) |
| 613 qi := q.(*queryImpl).checkCorrectness("", false) | 551 qi := q.(*queryImpl).checkCorrectness("", false) |
| 614 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for non-__key__") | 552 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for non-__key__") |
| 615 }) | 553 }) |
| 616 Convey("kindless with non-__key__ orders", func() { | 554 Convey("kindless with non-__key__ orders", func() { |
| 617 » » » » q := rds.NewQuery("").Order("face") | 555 » » » » q := ds.NewQuery("").Order("face") |
| 618 qi := q.(*queryImpl).checkCorrectness("", false) | 556 qi := q.(*queryImpl).checkCorrectness("", false) |
| 619 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") | 557 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
| 620 }) | 558 }) |
| 621 Convey("kindless with decending-__key__ orders", func()
{ | 559 Convey("kindless with decending-__key__ orders", func()
{ |
| 622 » » » » q := rds.NewQuery("").Order("-__key__") | 560 » » » » q := ds.NewQuery("").Order("-__key__") |
| 623 qi := q.(*queryImpl).checkCorrectness("", false) | 561 qi := q.(*queryImpl).checkCorrectness("", false) |
| 624 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") | 562 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
| 625 }) | 563 }) |
| 626 }) | 564 }) |
| 627 | 565 |
| 628 }) | 566 }) |
| 629 } | 567 } |
| OLD | NEW |