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 memory | 5 package memory |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "testing" | 9 "testing" |
| 10 "time" | 10 "time" |
| 11 | 11 |
| 12 ds "github.com/luci/gae/service/datastore" | 12 ds "github.com/luci/gae/service/datastore" |
| 13 "github.com/luci/gae/service/info" | 13 "github.com/luci/gae/service/info" |
| 14 . "github.com/luci/luci-go/common/testing/assertions" | 14 . "github.com/luci/luci-go/common/testing/assertions" |
| 15 . "github.com/smartystreets/goconvey/convey" | 15 . "github.com/smartystreets/goconvey/convey" |
| 16 "golang.org/x/net/context" | 16 "golang.org/x/net/context" |
| 17 ) | 17 ) |
| 18 | 18 |
| 19 type qExpect struct { | 19 type qExpect struct { |
| 20 » q ds.Query | 20 » q *ds.Query |
| 21 inTxn bool | 21 inTxn bool |
| 22 | 22 |
| 23 get []ds.PropertyMap | 23 get []ds.PropertyMap |
| 24 » keys []ds.Key | 24 » keys []*ds.Key |
| 25 } | 25 } |
| 26 | 26 |
| 27 type qExStage struct { | 27 type qExStage struct { |
| 28 addIdxs []*ds.IndexDefinition | 28 addIdxs []*ds.IndexDefinition |
| 29 putEnts []ds.PropertyMap | 29 putEnts []ds.PropertyMap |
| 30 » delEnts []ds.Key | 30 » delEnts []*ds.Key |
| 31 | 31 |
| 32 expect []qExpect | 32 expect []qExpect |
| 33 | 33 |
| 34 extraFns []func(context.Context) | 34 extraFns []func(context.Context) |
| 35 } | 35 } |
| 36 | 36 |
| 37 type qExTest struct { | 37 type qExTest struct { |
| 38 name string | 38 name string |
| 39 test []qExStage | 39 test []qExStage |
| 40 } | 40 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 52 pmap("$key", key("Kind", 3), NEXT, | 52 pmap("$key", key("Kind", 3), NEXT, |
| 53 "Val", 1, 2, 2, 100, NEXT, | 53 "Val", 1, 2, 2, 100, NEXT, |
| 54 "When", 996688461000000, NEXT, | 54 "When", 996688461000000, NEXT, |
| 55 "Extra", "waffle", | 55 "Extra", "waffle", |
| 56 ), | 56 ), |
| 57 pmap("$key", key("Kind", 6), NEXT, | 57 pmap("$key", key("Kind", 6), NEXT, |
| 58 "Val", 5, NEXT, | 58 "Val", 5, NEXT, |
| 59 "When", time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC), NEXT, | 59 "When", time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC), NEXT, |
| 60 "Extra", "waffle", | 60 "Extra", "waffle", |
| 61 ), | 61 ), |
| 62 » pmap("$key", key("Child", "seven", key("Kind", 3)), NEXT, | 62 » pmap("$key", key("Kind", 3, "Child", "seven"), NEXT, |
| 63 "Interesting", 28, NEXT, | 63 "Interesting", 28, NEXT, |
| 64 "Extra", "hello", | 64 "Extra", "hello", |
| 65 ), | 65 ), |
| 66 pmap("$key", key("Unique", 1), NEXT, | 66 pmap("$key", key("Unique", 1), NEXT, |
| 67 "Derp", 39, | 67 "Derp", 39, |
| 68 ), | 68 ), |
| 69 } | 69 } |
| 70 | 70 |
| 71 var stage2Data = []ds.PropertyMap{ | 71 var stage2Data = []ds.PropertyMap{ |
| 72 » pmap("$key", key("Kind", 1, key("Kind", 3)), NEXT, | 72 » pmap("$key", key("Kind", 3, "Kind", 1), NEXT, |
| 73 "Val", 2, 4, 28, NEXT, | 73 "Val", 2, 4, 28, NEXT, |
| 74 "Extra", "hello", "waffle", | 74 "Extra", "hello", "waffle", |
| 75 ), | 75 ), |
| 76 » pmap("$key", key("Kind", 2, key("Kind", 3)), NEXT, | 76 » pmap("$key", key("Kind", 3, "Kind", 2), NEXT, |
| 77 "Val", 3, 4, NEXT, | 77 "Val", 3, 4, NEXT, |
| 78 "Extra", "hello", "waffle", | 78 "Extra", "hello", "waffle", |
| 79 ), | 79 ), |
| 80 » pmap("$key", key("Kind", 3, key("Kind", 3)), NEXT, | 80 » pmap("$key", key("Kind", 3, "Kind", 3), NEXT, |
| 81 "Val", 3, 4, 2, 1, NEXT, | 81 "Val", 3, 4, 2, 1, NEXT, |
| 82 "Extra", "nuts", | 82 "Extra", "nuts", |
| 83 ), | 83 ), |
| 84 } | 84 } |
| 85 | 85 |
| 86 var queryExecutionTests = []qExTest{ | 86 var queryExecutionTests = []qExTest{ |
| 87 {"basic", []qExStage{ | 87 {"basic", []qExStage{ |
| 88 { | 88 { |
| 89 addIdxs: []*ds.IndexDefinition{ | 89 addIdxs: []*ds.IndexDefinition{ |
| 90 indx("Unrelated", "-thing", "bob", "-__key__"), | 90 indx("Unrelated", "-thing", "bob", "-__key__"), |
| 91 indx("Wat", "deep", "opt", "other"), | 91 indx("Wat", "deep", "opt", "other"), |
| 92 indx("Wat", "meep", "opt", "other"), | 92 indx("Wat", "meep", "opt", "other"), |
| 93 }, | 93 }, |
| 94 }, | 94 }, |
| 95 | 95 |
| 96 { | 96 { |
| 97 expect: []qExpect{ | 97 expect: []qExpect{ |
| 98 // tests the case where the query has indexes to fulfill it, but there | 98 // tests the case where the query has indexes to fulfill it, but there |
| 99 // are no actual entities in the datastore. | 99 // are no actual entities in the datastore. |
| 100 » » » » {q: nq("Wat").Filter("meep =", 1).Filter("deep = ", 2).Order("opt").Order("other"), | 100 » » » » {q: nq("Wat").Eq("meep", 1).Eq("deep", 2).Order( "opt", "other"), |
| 101 get: []ds.PropertyMap{}}, | 101 get: []ds.PropertyMap{}}, |
| 102 }, | 102 }, |
| 103 }, | 103 }, |
| 104 | 104 |
| 105 { | 105 { |
| 106 putEnts: stage1Data, | 106 putEnts: stage1Data, |
| 107 expect: []qExpect{ | 107 expect: []qExpect{ |
| 108 {q: nq("Kind"), get: []ds.PropertyMap{}}, | 108 {q: nq("Kind"), get: []ds.PropertyMap{}}, |
| 109 » » » » {q: nq("Child").Ancestor(key("Kind", 3)), keys: []ds.Key{ | 109 » » » » {q: nq("Child").Ancestor(key("Kind", 3)), keys: []*ds.Key{ |
| 110 » » » » » key("Child", "seven", key("Kind", 3)), | 110 » » » » » key("Kind", 3, "Child", "seven"), |
| 111 }}, | 111 }}, |
| 112 }, | 112 }, |
| 113 }, | 113 }, |
| 114 | 114 |
| 115 { | 115 { |
| 116 putEnts: stage2Data, | 116 putEnts: stage2Data, |
| 117 » » » delEnts: []ds.Key{key("Unique", 1)}, | 117 » » » delEnts: []*ds.Key{key("Unique", 1)}, |
| 118 addIdxs: []*ds.IndexDefinition{ | 118 addIdxs: []*ds.IndexDefinition{ |
| 119 indx("Kind!", "-Extra", "-Val"), | 119 indx("Kind!", "-Extra", "-Val"), |
| 120 indx("Kind!", "-Extra", "-Val", "-__key__"), | 120 indx("Kind!", "-Extra", "-Val", "-__key__"), |
| 121 indx("Kind!", "Bogus", "Extra", "-Val"), | 121 indx("Kind!", "Bogus", "Extra", "-Val"), |
| 122 }, | 122 }, |
| 123 expect: []qExpect{ | 123 expect: []qExpect{ |
| 124 {q: nq("Kind"), get: stage1Data[:4]}, | 124 {q: nq("Kind"), get: stage1Data[:4]}, |
| 125 | 125 |
| 126 {q: nq("Kind").Offset(2).Limit(1), get: []ds.Pro pertyMap{ | 126 {q: nq("Kind").Offset(2).Limit(1), get: []ds.Pro pertyMap{ |
| 127 stage1Data[2], | 127 stage1Data[2], |
| 128 }}, | 128 }}, |
| 129 | 129 |
| 130 {q: nq("Missing"), get: []ds.PropertyMap{}}, | 130 {q: nq("Missing"), get: []ds.PropertyMap{}}, |
| 131 | 131 |
| 132 » » » » {q: nq("Missing").Filter("Id <", 2).Filter("Id > ", 2), get: []ds.PropertyMap{}}, | 132 » » » » {q: nq("Missing").Lt("Id", 2).Gt("Id", 2), get: []ds.PropertyMap{}}, |
| 133 | 133 |
| 134 » » » » {q: nq("Missing").Filter("Bogus =", 3), get: []d s.PropertyMap{}}, | 134 » » » » {q: nq("Missing").Eq("Bogus", 3), get: []ds.Prop ertyMap{}}, |
| 135 | 135 |
| 136 » » » » {q: nq("Kind").Filter("Extra =", "waffle"), get: []ds.PropertyMap{ | 136 » » » » {q: nq("Kind").Eq("Extra", "waffle"), get: []ds. PropertyMap{ |
| 137 stage1Data[2], stage1Data[3], | 137 stage1Data[2], stage1Data[3], |
| 138 }}, | 138 }}, |
| 139 | 139 |
| 140 // get ziggy with it | 140 // get ziggy with it |
| 141 » » » » {q: nq("Kind").Filter("Extra =", "waffle").Filte r("Val =", 100), get: []ds.PropertyMap{ | 141 » » » » {q: nq("Kind").Eq("Extra", "waffle").Eq("Val", 1 00), get: []ds.PropertyMap{ |
| 142 stage1Data[2], | 142 stage1Data[2], |
| 143 }}, | 143 }}, |
| 144 » » » » {q: nq("Child").Filter("Interesting =", 28).Filt er("Extra =", "hello"), get: []ds.PropertyMap{ | 144 |
| 145 » » » » {q: nq("Child").Eq("Interesting", 28).Eq("Extra" , "hello"), get: []ds.PropertyMap{ | |
| 145 stage1Data[4], | 146 stage1Data[4], |
| 146 }}, | 147 }}, |
| 147 | 148 |
| 148 {q: (nq("Kind").Ancestor(key("Kind", 3)).Order(" Val"). | 149 {q: (nq("Kind").Ancestor(key("Kind", 3)).Order(" Val"). |
| 149 Start(curs("Val", 1, "__key__", key("Kin d", 3))). | 150 Start(curs("Val", 1, "__key__", key("Kin d", 3))). |
| 150 » » » » » End(curs("Val", 90, "__key__", key("Zeta ", "woot", key("Kind", 3))))), keys: []ds.Key{}, | 151 » » » » » End(curs("Val", 90, "__key__", key("Kind ", 3, "Zeta", "woot")))), keys: []*ds.Key{}, |
| 151 }, | 152 }, |
| 152 | 153 |
| 153 » » » » {q: nq("Kind").Filter("Val >", 2).Filter("Val <= ", 5), get: []ds.PropertyMap{ | 154 » » » » {q: nq("Kind").Gt("Val", 2).Lte("Val", 5), get: []ds.PropertyMap{ |
| 154 stage1Data[0], stage1Data[3], | 155 stage1Data[0], stage1Data[3], |
| 155 }}, | 156 }}, |
| 156 | 157 |
| 157 » » » » {q: nq("Kind").Filter("Val >", 2).Filter("Val <= ", 5).Order("-Val"), get: []ds.PropertyMap{ | 158 » » » » {q: nq("Kind").Gt("Val", 2).Lte("Val", 5).Order( "-Val"), get: []ds.PropertyMap{ |
| 158 stage1Data[3], stage1Data[0], | 159 stage1Data[3], stage1Data[0], |
| 159 }}, | 160 }}, |
| 160 | 161 |
| 161 » » » » {q: nq("").Filter("__key__ >", key("Kind", 2)), get: []ds.PropertyMap{ | 162 » » » » {q: nq("").Gt("__key__", key("Kind", 2)), get: [ ]ds.PropertyMap{ |
| 162 // TODO(riannucci): determine if the rea l datastore shows metadata | 163 // TODO(riannucci): determine if the rea l datastore shows metadata |
| 163 // during kindless queries. The document ation seems to imply so, but | 164 // during kindless queries. The document ation seems to imply so, but |
| 164 // I'd like to be sure. | 165 // I'd like to be sure. |
| 165 » » » » » pmap("$key", key("__entity_group__", 1, key("Kind", 2)), NEXT, | 166 » » » » » pmap("$key", key("Kind", 2, "__entity_gr oup__", 1), NEXT, |
| 166 "__version__", 1), | 167 "__version__", 1), |
| 167 stage1Data[2], | 168 stage1Data[2], |
| 168 stage1Data[4], | 169 stage1Data[4], |
| 169 // this is 5 because the value is retrie ved from HEAD and not from | 170 // this is 5 because the value is retrie ved from HEAD and not from |
| 170 // the index snapshot! | 171 // the index snapshot! |
| 171 » » » » » pmap("$key", key("__entity_group__", 1, key("Kind", 3)), NEXT, | 172 » » » » » pmap("$key", key("Kind", 3, "__entity_gr oup__", 1), NEXT, |
| 172 "__version__", 5), | 173 "__version__", 5), |
| 173 stage1Data[3], | 174 stage1Data[3], |
| 174 » » » » » pmap("$key", key("__entity_group__", 1, key("Kind", 6)), NEXT, | 175 » » » » » pmap("$key", key("Kind", 6, "__entity_gr oup__", 1), NEXT, |
| 175 "__version__", 1), | 176 "__version__", 1), |
| 176 » » » » » pmap("$key", key("__entity_group__", 1, key("Unique", 1)), NEXT, | 177 » » » » » pmap("$key", key("Unique", 1, "__entity_ group__", 1), NEXT, |
| 177 "__version__", 2), | 178 "__version__", 2), |
| 178 }}, | 179 }}, |
| 179 | 180 |
| 180 {q: (nq("Kind"). | 181 {q: (nq("Kind"). |
| 181 » » » » » Filter("Val >", 2).Filter("Extra =", "wa ffle"). | 182 » » » » » Gt("Val", 2).Eq("Extra", "waffle"). |
| 182 Order("-Val"). | 183 Order("-Val"). |
| 183 Ancestor(key("Kind", 3))), | 184 Ancestor(key("Kind", 3))), |
| 184 get: []ds.PropertyMap{ | 185 get: []ds.PropertyMap{ |
| 185 stage1Data[2], | 186 stage1Data[2], |
| 186 stage2Data[0], | 187 stage2Data[0], |
| 187 stage2Data[1], | 188 stage2Data[1], |
| 188 }}, | 189 }}, |
| 189 | 190 |
| 190 {q: (nq("Kind"). | 191 {q: (nq("Kind"). |
| 191 » » » » » Filter("Val >", 2).Filter("Extra =", "wa ffle"). | 192 » » » » » Gt("Val", 2).Eq("Extra", "waffle"). |
| 192 » » » » » Order("-Val").Order("-__key__"). | 193 » » » » » Order("-Val", "-__key__"). |
| 193 Ancestor(key("Kind", 3))), | 194 Ancestor(key("Kind", 3))), |
| 194 get: []ds.PropertyMap{ | 195 get: []ds.PropertyMap{ |
| 195 stage1Data[2], | 196 stage1Data[2], |
| 196 stage2Data[0], | 197 stage2Data[0], |
| 197 stage2Data[1], | 198 stage2Data[1], |
| 198 }}, | 199 }}, |
| 199 | 200 |
| 200 {q: (nq("Kind"). | 201 {q: (nq("Kind"). |
| 201 » » » » » Filter("Val >", 2).Filter("Extra =", "wa ffle"). | 202 » » » » » Gt("Val", 2).Eq("Extra", "waffle"). |
| 202 Order("-Val"). | 203 Order("-Val"). |
| 203 Ancestor(key("Kind", 3)).Project("Val")) , | 204 Ancestor(key("Kind", 3)).Project("Val")) , |
| 204 get: []ds.PropertyMap{ | 205 get: []ds.PropertyMap{ |
| 205 pmap("$key", key("Kind", 3), NEX T, | 206 pmap("$key", key("Kind", 3), NEX T, |
| 206 "Val", 100), | 207 "Val", 100), |
| 207 » » » » » » pmap("$key", key("Kind", 1, key( "Kind", 3)), NEXT, | 208 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 1), NEXT, |
| 208 "Val", 28), | 209 "Val", 28), |
| 209 » » » » » » pmap("$key", key("Kind", 1, key( "Kind", 3)), NEXT, | 210 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 1), NEXT, |
| 210 "Val", 4), | 211 "Val", 4), |
| 211 » » » » » » pmap("$key", key("Kind", 2, key( "Kind", 3)), NEXT, | 212 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 2), NEXT, |
| 212 "Val", 4), | 213 "Val", 4), |
| 213 » » » » » » pmap("$key", key("Kind", 2, key( "Kind", 3)), NEXT, | 214 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 2), NEXT, |
| 214 "Val", 3), | 215 "Val", 3), |
| 215 }}, | 216 }}, |
| 216 | 217 |
| 217 {q: (nq("Kind"). | 218 {q: (nq("Kind"). |
| 218 » » » » » Filter("Val >", 2).Filter("Extra =", "wa ffle"). | 219 » » » » » Gt("Val", 2).Eq("Extra", "waffle"). |
| 219 Order("-Val"). | 220 Order("-Val"). |
| 220 » » » » » Ancestor(key("Kind", 3)).Project("Val"). Distinct()), | 221 » » » » » Ancestor(key("Kind", 3)).Project("Val"). Distinct(true)), |
| 221 get: []ds.PropertyMap{ | 222 get: []ds.PropertyMap{ |
| 222 pmap("$key", key("Kind", 3), NEX T, | 223 pmap("$key", key("Kind", 3), NEX T, |
| 223 "Val", 100), | 224 "Val", 100), |
| 224 » » » » » » pmap("$key", key("Kind", 1, key( "Kind", 3)), NEXT, | 225 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 1), NEXT, |
| 225 "Val", 28), | 226 "Val", 28), |
| 226 » » » » » » pmap("$key", key("Kind", 1, key( "Kind", 3)), NEXT, | 227 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 1), NEXT, |
| 227 "Val", 4), | 228 "Val", 4), |
| 228 » » » » » » pmap("$key", key("Kind", 2, key( "Kind", 3)), NEXT, | 229 » » » » » » pmap("$key", key("Kind", 3, "Kin d", 2), NEXT, |
| 229 "Val", 3), | 230 "Val", 3), |
| 230 }}, | 231 }}, |
| 231 | 232 |
| 232 // Projecting a complex type (time), gets the in dex type (int64) | 233 // Projecting a complex type (time), gets the in dex type (int64) |
| 233 // instead. Additionally, mixed-types within the same index type are | 234 // instead. Additionally, mixed-types within the same index type are |
| 234 // smooshed together in the result. | 235 // smooshed together in the result. |
| 235 {q: nq("Kind").Project("When"), get: []ds.Proper tyMap{ | 236 {q: nq("Kind").Project("When"), get: []ds.Proper tyMap{ |
| 236 pmap("$key", key("Kind", 2), NEXT, | 237 pmap("$key", key("Kind", 2), NEXT, |
| 237 "When", 27), | 238 "When", 27), |
| 238 pmap("$key", key("Kind", 6), NEXT, | 239 pmap("$key", key("Kind", 6), NEXT, |
| 239 "When", 946688461000000), | 240 "When", 946688461000000), |
| 240 pmap("$key", key("Kind", 3), NEXT, | 241 pmap("$key", key("Kind", 3), NEXT, |
| 241 "When", 996688461000000), | 242 "When", 996688461000000), |
| 242 }}, | 243 }}, |
| 243 | 244 |
| 244 // Original (complex) types are retained when ge tting the full value. | 245 // Original (complex) types are retained when ge tting the full value. |
| 245 {q: nq("Kind").Order("When"), get: []ds.Property Map{ | 246 {q: nq("Kind").Order("When"), get: []ds.Property Map{ |
| 246 stage1Data[1], | 247 stage1Data[1], |
| 247 stage1Data[3], | 248 stage1Data[3], |
| 248 stage1Data[2], | 249 stage1Data[2], |
| 249 }}, | 250 }}, |
| 250 }, | 251 }, |
| 251 | 252 |
| 252 extraFns: []func(context.Context){ | 253 extraFns: []func(context.Context){ |
| 253 func(c context.Context) { | 254 func(c context.Context) { |
| 254 data := ds.Get(c) | 255 data := ds.Get(c) |
| 255 curs := ds.Cursor(nil) | 256 curs := ds.Cursor(nil) |
| 256 | 257 |
| 257 » » » » » q := nq("").Filter("__key__ >", key("Kin d", 2)) | 258 » » » » » q := nq("").Gt("__key__", key("Kind", 2) ) |
| 258 | 259 |
| 259 err := data.Run(q, func(pm ds.PropertyMa p, gc ds.CursorCB) bool { | 260 err := data.Run(q, func(pm ds.PropertyMa p, gc ds.CursorCB) bool { |
| 260 So(pm, ShouldResemble, pmap( | 261 So(pm, ShouldResemble, pmap( |
| 261 » » » » » » » "$key", key("__entity_gr oup__", 1, key("Kind", 2)), NEXT, | 262 » » » » » » » "$key", key("Kind", 2, " __entity_group__", 1), NEXT, |
|
iannucci
2015/09/18 04:31:52
key (which is an alias for datastore.MakeKey above
| |
| 262 "__version__", 1)) | 263 "__version__", 1)) |
| 263 | 264 |
| 264 err := error(nil) | 265 err := error(nil) |
| 265 curs, err = gc() | 266 curs, err = gc() |
| 266 So(err, ShouldBeNil) | 267 So(err, ShouldBeNil) |
| 267 return false | 268 return false |
| 268 }) | 269 }) |
| 269 So(err, ShouldBeNil) | 270 So(err, ShouldBeNil) |
| 270 | 271 |
| 271 err = data.Run(q.Start(curs), func(pm ds .PropertyMap, gc ds.CursorCB) bool { | 272 err = data.Run(q.Start(curs), func(pm ds .PropertyMap, gc ds.CursorCB) bool { |
| 272 So(pm, ShouldResemble, stage1Dat a[2]) | 273 So(pm, ShouldResemble, stage1Dat a[2]) |
| 273 return false | 274 return false |
| 274 }) | 275 }) |
| 275 So(err, ShouldBeNil) | 276 So(err, ShouldBeNil) |
| 276 }, | 277 }, |
| 277 | 278 |
| 278 func(c context.Context) { | 279 func(c context.Context) { |
| 279 data := ds.Get(c) | 280 data := ds.Get(c) |
| 280 » » » » » q := nq("Something").Filter("Does =", 2) .Order("Not").Order("Work") | 281 » » » » » q := nq("Something").Eq("Does", 2).Order ("Not", "Work") |
|
iannucci
2015/09/18 04:31:52
I made Order accept multiples, just like Project.
| |
| 281 So(data.Run(q, func(ds.Key, ds.CursorCB) bool { | 282 So(data.Run(q, func(ds.Key, ds.CursorCB) bool { |
| 282 return true | 283 return true |
| 283 }), ShouldErrLike, "Try adding:\n C:Som ething/Does/Not/Work") | 284 }), ShouldErrLike, "Try adding:\n C:Som ething/Does/Not/Work") |
| 284 }, | 285 }, |
| 285 }, | 286 }, |
| 286 }, | 287 }, |
| 287 | 288 |
| 288 { | 289 { |
| 289 expect: []qExpect{ | 290 expect: []qExpect{ |
| 290 // eventual consistency; Unique/1 is deleted at HEAD. Keysonly finds it, | 291 // eventual consistency; Unique/1 is deleted at HEAD. Keysonly finds it, |
| 291 // but 'normal' doesn't. | 292 // but 'normal' doesn't. |
| 292 » » » » {q: nq("Unique").Filter("__key__ >", key("AKind" , 5)).Filter("__key__ <=", key("Zeta", "prime")), | 293 » » » » {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")), |
| 293 » » » » » keys: []ds.Key{key("Unique", 1)}, | 294 » » » » » keys: []*ds.Key{key("Unique", 1)}, |
| 294 get: []ds.PropertyMap{}}, | 295 get: []ds.PropertyMap{}}, |
| 295 | 296 |
| 296 » » » » {q: nq("Kind").Filter("Val =", 1).Filter("Val =" , 3), get: []ds.PropertyMap{ | 297 » » » » {q: nq("Kind").Eq("Val", 1, 3), get: []ds.Proper tyMap{ |
|
iannucci
2015/09/18 04:31:52
Eq can accept multiples too.
| |
| 297 stage1Data[0], stage2Data[2], | 298 stage1Data[0], stage2Data[2], |
| 298 }}, | 299 }}, |
| 299 }, | 300 }, |
| 300 }, | 301 }, |
| 301 }}, | 302 }}, |
| 302 } | 303 } |
| 303 | 304 |
| 304 func TestQueryExecution(t *testing.T) { | 305 func TestQueryExecution(t *testing.T) { |
| 305 t.Parallel() | 306 t.Parallel() |
| 306 | 307 |
| 307 Convey("Test query execution", t, func() { | 308 Convey("Test query execution", t, func() { |
| 308 c, err := info.Get(Use(context.Background())).Namespace("ns") | 309 c, err := info.Get(Use(context.Background())).Namespace("ns") |
| 309 if err != nil { | 310 if err != nil { |
| 310 panic(err) | 311 panic(err) |
| 311 } | 312 } |
| 312 | 313 |
| 314 So(info.Get(c).FullyQualifiedAppID(), ShouldEqual, "dev~app") | |
| 315 So(info.Get(c).GetNamespace(), ShouldEqual, "ns") | |
| 316 | |
| 313 data := ds.Get(c) | 317 data := ds.Get(c) |
| 314 testing := data.Testable() | 318 testing := data.Testable() |
| 315 | 319 |
| 316 for _, tc := range queryExecutionTests { | 320 for _, tc := range queryExecutionTests { |
| 317 Convey(tc.name, func() { | 321 Convey(tc.name, func() { |
| 318 for i, stage := range tc.test { | 322 for i, stage := range tc.test { |
| 319 // outside of Convey, since these must a lways happen | 323 // outside of Convey, since these must a lways happen |
| 320 testing.CatchupIndexes() | 324 testing.CatchupIndexes() |
| 321 | 325 |
| 322 testing.AddIndexes(stage.addIdxs...) | 326 testing.AddIndexes(stage.addIdxs...) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 336 return f(c) | 340 return f(c) |
| 337 } | 341 } |
| 338 if expect.inTxn { | 342 if expect.inTxn { |
| 339 runner = data.Ru nInTransaction | 343 runner = data.Ru nInTransaction |
| 340 } | 344 } |
| 341 | 345 |
| 342 if expect.keys != nil { | 346 if expect.keys != nil { |
| 343 runner(func(c co ntext.Context) error { | 347 runner(func(c co ntext.Context) error { |
| 344 data := ds.Get(c) | 348 data := ds.Get(c) |
| 345 Convey(f mt.Sprintf("expect %d (keys)", j), func() { | 349 Convey(f mt.Sprintf("expect %d (keys)", j), func() { |
| 346 » » » » » » » » » » rslt := []ds.Key(nil) | 350 » » » » » » » » » » rslt := []*ds.Key(nil) |
| 347 So(data.GetAll(expect.q, &rslt), ShouldBeNil) | 351 So(data.GetAll(expect.q, &rslt), ShouldBeNil) |
| 348 So(len(rslt), ShouldEqual, len(expect.keys)) | 352 So(len(rslt), ShouldEqual, len(expect.keys)) |
| 349 for i, r := range rslt { | 353 for i, r := range rslt { |
| 350 So(r, ShouldResemble, expect.keys[i]) | 354 So(r, ShouldResemble, expect.keys[i]) |
| 351 } | 355 } |
| 352 }) | 356 }) |
| 353 return n il | 357 return n il |
| 354 }, &ds.Transacti onOptions{XG: true}) | 358 }, &ds.Transacti onOptions{XG: true}) |
| 355 } | 359 } |
| 356 | 360 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 373 Convey(fmt.Sprintf("extr aFn %d", j), func() { | 377 Convey(fmt.Sprintf("extr aFn %d", j), func() { |
| 374 fn(c) | 378 fn(c) |
| 375 }) | 379 }) |
| 376 } | 380 } |
| 377 }) | 381 }) |
| 378 } | 382 } |
| 379 }) | 383 }) |
| 380 } | 384 } |
| 381 }) | 385 }) |
| 382 } | 386 } |
| OLD | NEW |