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 "strings" | 9 "strings" |
10 "testing" | 10 "testing" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 ), | 63 ), |
64 pmap("$key", key("Kind", 3, "Child", "seven"), Next, | 64 pmap("$key", key("Kind", 3, "Child", "seven"), Next, |
65 "Interesting", 28, Next, | 65 "Interesting", 28, Next, |
66 "Extra", "hello", | 66 "Extra", "hello", |
67 ), | 67 ), |
68 pmap("$key", key("Unique", 1), Next, | 68 pmap("$key", key("Unique", 1), Next, |
69 "Derp", 39, | 69 "Derp", 39, |
70 ), | 70 ), |
71 } | 71 } |
72 | 72 |
73 var stage1Data3Enc = pmap("$key", key("Kind", 6), Next, | |
74 "Val", 5, 3, 2, Next, | |
75 "When", 946688461000000, Next, | |
76 "Extra", "waffle", | |
77 ) | |
78 | |
73 var stage2Data = []ds.PropertyMap{ | 79 var stage2Data = []ds.PropertyMap{ |
74 pmap("$key", key("Kind", 3, "Kind", 1), Next, | 80 pmap("$key", key("Kind", 3, "Kind", 1), Next, |
75 "Val", 2, 4, 28, Next, | 81 "Val", 2, 4, 28, Next, |
76 "Extra", "hello", "waffle", | 82 "Extra", "hello", "waffle", |
77 ), | 83 ), |
78 pmap("$key", key("Kind", 3, "Kind", 2), Next, | 84 pmap("$key", key("Kind", 3, "Kind", 2), Next, |
79 "Val", 3, 4, Next, | 85 "Val", 3, 4, Next, |
80 "Extra", "hello", "waffle", | 86 "Extra", "hello", "waffle", |
81 ), | 87 ), |
82 pmap("$key", key("Kind", 3, "Kind", 3), Next, | 88 pmap("$key", key("Kind", 3, "Kind", 3), Next, |
83 "Val", 3, 4, 2, 1, Next, | 89 "Val", 3, 4, 2, 1, Next, |
84 "Extra", "nuts", | 90 "Extra", "nuts", |
85 ), | 91 ), |
86 } | 92 } |
87 | 93 |
94 var timeData = []ds.PropertyMap{ | |
95 pmap("$key", key("Kind", 1), Next, | |
96 "Date", time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC), Next, | |
97 ), | |
98 pmap("$key", key("Kind", 2), Next, | |
99 "Date", time.Date(2000, time.March, 1, 1, 1, 1, 1, time.UTC), Ne xt, | |
100 ), | |
101 } | |
102 | |
88 var queryExecutionTests = []qExTest{ | 103 var queryExecutionTests = []qExTest{ |
89 {"basic", []qExStage{ | 104 {"basic", []qExStage{ |
90 { | 105 { |
91 addIdxs: []*ds.IndexDefinition{ | 106 addIdxs: []*ds.IndexDefinition{ |
92 indx("Unrelated", "-thing", "bob", "-__key__"), | 107 indx("Unrelated", "-thing", "bob", "-__key__"), |
93 indx("Wat", "deep", "opt", "other"), | 108 indx("Wat", "deep", "opt", "other"), |
94 indx("Wat", "meep", "opt", "other"), | 109 indx("Wat", "meep", "opt", "other"), |
95 }, | 110 }, |
96 }, | 111 }, |
97 | 112 |
(...skipping 25 matching lines...) Expand all Loading... | |
123 | 138 |
124 { | 139 { |
125 putEnts: stage2Data, | 140 putEnts: stage2Data, |
126 delEnts: []*ds.Key{key("Unique", 1)}, | 141 delEnts: []*ds.Key{key("Unique", 1)}, |
127 addIdxs: []*ds.IndexDefinition{ | 142 addIdxs: []*ds.IndexDefinition{ |
128 indx("Kind!", "-Extra", "-Val"), | 143 indx("Kind!", "-Extra", "-Val"), |
129 indx("Kind!", "-Extra", "-Val", "-__key__"), | 144 indx("Kind!", "-Extra", "-Val", "-__key__"), |
130 indx("Kind!", "Bogus", "Extra", "-Val"), | 145 indx("Kind!", "Bogus", "Extra", "-Val"), |
131 }, | 146 }, |
132 expect: []qExpect{ | 147 expect: []qExpect{ |
133 » » » » {q: nq("Kind"), get: stage1Data[:4]}, | 148 » » » » {q: nq("Kind"), get: []ds.PropertyMap{ |
149 » » » » » stage1Data[0], stage1Data[1], stage1Data [2], stage1Data3Enc, | |
150 » » » » }}, | |
134 | 151 |
135 {q: nq("Kind").Offset(2).Limit(1), get: []ds.Pro pertyMap{ | 152 {q: nq("Kind").Offset(2).Limit(1), get: []ds.Pro pertyMap{ |
136 stage1Data[2], | 153 stage1Data[2], |
137 }}, | 154 }}, |
138 | 155 |
139 {q: nq("Missing"), get: []ds.PropertyMap{}}, | 156 {q: nq("Missing"), get: []ds.PropertyMap{}}, |
140 | 157 |
141 {q: nq("Missing").Eq("Bogus", 3), get: []ds.Prop ertyMap{}}, | 158 {q: nq("Missing").Eq("Bogus", 3), get: []ds.Prop ertyMap{}}, |
142 | 159 |
143 {q: nq("Kind").Eq("Extra", "waffle"), get: []ds. PropertyMap{ | 160 {q: nq("Kind").Eq("Extra", "waffle"), get: []ds. PropertyMap{ |
144 » » » » » stage1Data[2], stage1Data[3], | 161 » » » » » stage1Data[2], stage1Data3Enc, |
145 }}, | 162 }}, |
146 | 163 |
147 // get ziggy with it | 164 // get ziggy with it |
148 {q: nq("Kind").Eq("Extra", "waffle").Eq("Val", 1 00), get: []ds.PropertyMap{ | 165 {q: nq("Kind").Eq("Extra", "waffle").Eq("Val", 1 00), get: []ds.PropertyMap{ |
149 stage1Data[2], | 166 stage1Data[2], |
150 }}, | 167 }}, |
151 | 168 |
152 {q: nq("Child").Eq("Interesting", 28).Eq("Extra" , "hello"), get: []ds.PropertyMap{ | 169 {q: nq("Child").Eq("Interesting", 28).Eq("Extra" , "hello"), get: []ds.PropertyMap{ |
153 stage1Data[4], | 170 stage1Data[4], |
154 }}, | 171 }}, |
155 | 172 |
156 {q: nq("Kind").Eq("Val", 2, 3), get: []ds.Proper tyMap{ | 173 {q: nq("Kind").Eq("Val", 2, 3), get: []ds.Proper tyMap{ |
157 stage1Data[0], | 174 stage1Data[0], |
158 » » » » » stage1Data[3], | 175 » » » » » stage1Data3Enc, |
159 }}, | 176 }}, |
160 | 177 |
161 // note the kind :) | 178 // note the kind :) |
162 {q: (nq("Kind").Ancestor(key("Kind", 3)). | 179 {q: (nq("Kind").Ancestor(key("Kind", 3)). |
163 Start(curs("__key__", key("Kind", 3))). | 180 Start(curs("__key__", key("Kind", 3))). |
164 End(curs("__key__", key("Kind", 3, "Zeta ", "woot")))), | 181 End(curs("__key__", key("Kind", 3, "Zeta ", "woot")))), |
165 keys: []*ds.Key{ | 182 keys: []*ds.Key{ |
166 key("Kind", 3), | 183 key("Kind", 3), |
167 key("Kind", 3, "Kind", 1), | 184 key("Kind", 3, "Kind", 1), |
168 key("Kind", 3, "Kind", 2), | 185 key("Kind", 3, "Kind", 2), |
(...skipping 29 matching lines...) Expand all Loading... | |
198 key("Kind", 3, "Kind", 2), | 215 key("Kind", 3, "Kind", 2), |
199 key("Kind", 3, "Kind", 3), | 216 key("Kind", 3, "Kind", 3), |
200 }, | 217 }, |
201 get: []ds.PropertyMap{ | 218 get: []ds.PropertyMap{ |
202 stage2Data[1], | 219 stage2Data[1], |
203 stage2Data[2], | 220 stage2Data[2], |
204 }, | 221 }, |
205 }, | 222 }, |
206 | 223 |
207 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5), get: []ds.PropertyMap{ | 224 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5), get: []ds.PropertyMap{ |
208 » » » » » stage1Data[0], stage1Data[3], | 225 » » » » » stage1Data[0], stage1Data3Enc, |
209 }}, | 226 }}, |
210 | 227 |
211 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5).Order( "-Val"), get: []ds.PropertyMap{ | 228 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5).Order( "-Val"), get: []ds.PropertyMap{ |
212 » » » » » stage1Data[3], stage1Data[0], | 229 » » » » » stage1Data3Enc, stage1Data[0], |
213 }}, | 230 }}, |
214 | 231 |
215 {q: nq("").Gt("__key__", key("Kind", 2)), | 232 {q: nq("").Gt("__key__", key("Kind", 2)), |
216 // count counts from the index with Keys Only and so counts the deleted | 233 // count counts from the index with Keys Only and so counts the deleted |
217 // entity Unique/1. | 234 // entity Unique/1. |
218 count: 8, | 235 count: 8, |
219 get: []ds.PropertyMap{ | 236 get: []ds.PropertyMap{ |
220 // TODO(riannucci): determine if the real datastore shows metadata | 237 // TODO(riannucci): determine if the real datastore shows metadata |
221 // during kindless queries. The documentation seems to imply so, but | 238 // during kindless queries. The documentation seems to imply so, but |
222 // I'd like to be sure. | 239 // I'd like to be sure. |
223 pmap("$key", key("Kind", 2, "__e ntity_group__", 1), Next, | 240 pmap("$key", key("Kind", 2, "__e ntity_group__", 1), Next, |
224 "__version__", 1), | 241 "__version__", 1), |
225 stage1Data[2], | 242 stage1Data[2], |
226 stage1Data[4], | 243 stage1Data[4], |
227 // this is 5 because the value i s retrieved from HEAD and not from | 244 // this is 5 because the value i s retrieved from HEAD and not from |
228 // the index snapshot! | 245 // the index snapshot! |
229 pmap("$key", key("Kind", 3, "__e ntity_group__", 1), Next, | 246 pmap("$key", key("Kind", 3, "__e ntity_group__", 1), Next, |
230 "__version__", 5), | 247 "__version__", 5), |
231 » » » » » » stage1Data[3], | 248 » » » » » » stage1Data3Enc, |
232 pmap("$key", key("Kind", 6, "__e ntity_group__", 1), Next, | 249 pmap("$key", key("Kind", 6, "__e ntity_group__", 1), Next, |
233 "__version__", 1), | 250 "__version__", 1), |
234 pmap("$key", key("Unique", 1, "_ _entity_group__", 1), Next, | 251 pmap("$key", key("Unique", 1, "_ _entity_group__", 1), Next, |
235 "__version__", 2), | 252 "__version__", 2), |
236 }}, | 253 }}, |
237 | 254 |
238 {q: (nq("Kind"). | 255 {q: (nq("Kind"). |
239 Gt("Val", 2).Eq("Extra", "waffle"). | 256 Gt("Val", 2).Eq("Extra", "waffle"). |
240 Order("-Val"). | 257 Order("-Val"). |
241 Ancestor(key("Kind", 3))), | 258 Ancestor(key("Kind", 3))), |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 "When", 27), | 322 "When", 27), |
306 pmap("$key", key("Kind", 6), Next, | 323 pmap("$key", key("Kind", 6), Next, |
307 "When", 946688461000000), | 324 "When", 946688461000000), |
308 pmap("$key", key("Kind", 3), Next, | 325 pmap("$key", key("Kind", 3), Next, |
309 "When", 996688461000000), | 326 "When", 996688461000000), |
310 }}, | 327 }}, |
311 | 328 |
312 // Original (complex) types are retained when ge tting the full value. | 329 // Original (complex) types are retained when ge tting the full value. |
313 {q: nq("Kind").Order("When"), get: []ds.Property Map{ | 330 {q: nq("Kind").Order("When"), get: []ds.Property Map{ |
314 stage1Data[1], | 331 stage1Data[1], |
315 » » » » » stage1Data[3], | 332 » » » » » stage1Data3Enc, |
316 stage1Data[2], | 333 stage1Data[2], |
317 }}, | 334 }}, |
318 }, | 335 }, |
319 | 336 |
320 extraFns: []func(context.Context){ | 337 extraFns: []func(context.Context){ |
321 func(c context.Context) { | 338 func(c context.Context) { |
322 data := ds.Get(c) | 339 data := ds.Get(c) |
323 curs := ds.Cursor(nil) | 340 curs := ds.Cursor(nil) |
324 | 341 |
325 q := nq("").Gt("__key__", key("Kind", 2) ) | 342 q := nq("").Gt("__key__", key("Kind", 2) ) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")), | 395 {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")), |
379 keys: []*ds.Key{key("Unique", 1)}, | 396 keys: []*ds.Key{key("Unique", 1)}, |
380 get: []ds.PropertyMap{}}, | 397 get: []ds.PropertyMap{}}, |
381 | 398 |
382 {q: nq("Kind").Eq("Val", 1, 3), get: []ds.Proper tyMap{ | 399 {q: nq("Kind").Eq("Val", 1, 3), get: []ds.Proper tyMap{ |
383 stage1Data[0], stage2Data[2], | 400 stage1Data[0], stage2Data[2], |
384 }}, | 401 }}, |
385 }, | 402 }, |
386 }, | 403 }, |
387 }}, | 404 }}, |
405 {"time range", []qExStage{ | |
406 { | |
407 addIdxs: []*ds.IndexDefinition{ | |
408 indx("Kind!", "Date"), | |
iannucci
2015/12/29 18:29:20
I think ! is shorthand for ancestor here, which yo
| |
409 }, | |
410 }, | |
411 { | |
412 putEnts: timeData, | |
413 }, | |
414 { | |
415 expect: []qExpect{ | |
416 { | |
417 q: nq("Kind").Lte("Date", time.Date(2000 , time.February, 1, 1, 1, 1, 1, time.UTC)), | |
418 get: []ds.PropertyMap{ | |
419 pmap("$key", key("Kind", 1), Nex t, | |
420 "Date", 946688461000000, Next, | |
421 ), | |
422 }, | |
423 }, | |
424 }, | |
425 }, | |
426 }}, | |
388 } | 427 } |
389 | 428 |
390 func TestQueryExecution(t *testing.T) { | 429 func TestQueryExecution(t *testing.T) { |
391 t.Parallel() | 430 t.Parallel() |
392 | 431 |
393 Convey("Test query execution", t, func() { | 432 Convey("Test query execution", t, func() { |
394 c, err := info.Get(Use(context.Background())).Namespace("ns") | 433 c, err := info.Get(Use(context.Background())).Namespace("ns") |
395 if err != nil { | 434 if err != nil { |
396 panic(err) | 435 panic(err) |
397 } | 436 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 err := r unner(func(c context.Context) error { | 500 err := r unner(func(c context.Context) error { |
462 data := ds.Get(c) | 501 data := ds.Get(c) |
463 count, err := data.Count(expect.q) | 502 count, err := data.Count(expect.q) |
464 So(err, ShouldBeNil) | 503 So(err, ShouldBeNil) |
465 So(count, ShouldEqual, expect.count) | 504 So(count, ShouldEqual, expect.count) |
466 | 505 |
467 rslt := []ds.PropertyMap(nil) | 506 rslt := []ds.PropertyMap(nil) |
468 So(data.GetAll(expect.q, &rslt), ShouldBeNil) | 507 So(data.GetAll(expect.q, &rslt), ShouldBeNil) |
469 So(len(rslt), ShouldEqual, len(expect.get)) | 508 So(len(rslt), ShouldEqual, len(expect.get)) |
470 for i, r := range rslt { | 509 for i, r := range rslt { |
471 » » » » » » » » » » » So(r, ShouldResemble, expect.get[i]) | 510 » » » » » » » » » » » So(r, ShouldResembleV, expect.get[i]) |
472 } | 511 } |
473 return nil | 512 return nil |
474 }, &ds.T ransactionOptions{XG: true}) | 513 }, &ds.T ransactionOptions{XG: true}) |
475 So(err, ShouldBeNil) | 514 So(err, ShouldBeNil) |
476 }) | 515 }) |
477 } | 516 } |
478 } | 517 } |
479 | 518 |
480 for j, fn := range stage.extraFn s { | 519 for j, fn := range stage.extraFn s { |
481 Convey(fmt.Sprintf("extr aFn %d", j), func() { | 520 Convey(fmt.Sprintf("extr aFn %d", j), func() { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 count, err := data.Count(q) | 552 count, err := data.Count(q) |
514 So(err, ShouldErrLike, "Insufficient indexes") | 553 So(err, ShouldErrLike, "Insufficient indexes") |
515 | 554 |
516 testing.AutoIndex(true) | 555 testing.AutoIndex(true) |
517 | 556 |
518 count, err = data.Count(q) | 557 count, err = data.Count(q) |
519 So(err, ShouldBeNil) | 558 So(err, ShouldBeNil) |
520 So(count, ShouldEqual, 2) | 559 So(count, ShouldEqual, 2) |
521 }) | 560 }) |
522 } | 561 } |
OLD | NEW |