go.mercari.io/datastore@v1.8.2/testsuite/query.go (about) 1 package testsuite 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "testing" 8 "time" 9 10 "go.mercari.io/datastore" 11 "google.golang.org/api/iterator" 12 ) 13 14 func queryCount(ctx context.Context, t *testing.T, client datastore.Client) { 15 defer func() { 16 err := client.Close() 17 if err != nil { 18 t.Fatal(err) 19 } 20 }() 21 22 type Data struct { 23 Str string 24 } 25 26 key1, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "A"}) 27 if err != nil { 28 t.Fatal(err) 29 } 30 key2, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "B"}) 31 if err != nil { 32 t.Fatal(err) 33 } 34 key3, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "B"}) 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 t.Log(key1, key2, key3) 40 41 q := client.NewQuery("Data").Filter("Str =", "B") 42 count, err := client.Count(ctx, q) 43 if err != nil { 44 t.Fatal(err) 45 } 46 47 if count != 2 { 48 t.Errorf("unexpected: %v", count) 49 } 50 } 51 52 func queryGetAll(ctx context.Context, t *testing.T, client datastore.Client) { 53 defer func() { 54 err := client.Close() 55 if err != nil { 56 t.Fatal(err) 57 } 58 }() 59 60 type Data struct { 61 Str string 62 Order int 63 } 64 65 key1, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "A", Order: 1}) 66 if err != nil { 67 t.Fatal(err) 68 } 69 key2, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "B", Order: 2}) 70 if err != nil { 71 t.Fatal(err) 72 } 73 key3, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Str: "B", Order: 3}) 74 if err != nil { 75 t.Fatal(err) 76 } 77 78 t.Log(key1, key2, key3) 79 80 { 81 client.GetMulti(ctx, []datastore.Key{key1, key2, key3}, []interface{}{&Data{}, &Data{}, &Data{}}) 82 } 83 84 q := client.NewQuery("Data").Filter("Str =", "B").Order("Order") 85 var dataList []*Data 86 keys, err := client.GetAll(ctx, q, &dataList) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 if v := len(keys); v != 2 { 92 t.Fatalf("unexpected: %v", v) 93 } 94 95 if v := dataList[0].Order; v != 2 { 96 t.Errorf("unexpected: %v", v) 97 } 98 if v := dataList[1].Order; v != 3 { 99 t.Errorf("unexpected: %v", v) 100 } 101 } 102 103 func queryCursor(ctx context.Context, t *testing.T, client datastore.Client) { 104 defer func() { 105 err := client.Close() 106 if err != nil { 107 t.Fatal(err) 108 } 109 }() 110 111 type Data struct { 112 Str string 113 } 114 115 { 116 var keys []datastore.Key 117 var entities []*Data 118 for i := 0; i < 100; i++ { 119 keys = append(keys, client.IncompleteKey("Data", nil)) 120 entities = append(entities, &Data{Str: fmt.Sprintf("#%d", i+1)}) 121 } 122 var err error 123 _, err = client.PutMulti(ctx, keys, entities) 124 if err != nil { 125 t.Fatal(err) 126 } 127 } 128 129 var cur datastore.Cursor 130 var err error 131 var startCur datastore.Cursor 132 var endCur datastore.Cursor 133 134 var dataList []*Data 135 const limit = 3 136 outer: 137 for { 138 q := client.NewQuery("Data").Order("Str").Limit(limit) 139 if cur != nil { 140 q = q.Start(cur) 141 } 142 it := client.Run(ctx, q) 143 144 count := 0 145 for { 146 obj := &Data{} 147 _, err := it.Next(obj) 148 if err == iterator.Done { 149 break 150 } else if err != nil { 151 t.Fatal(err) 152 } 153 154 dataList = append(dataList, obj) 155 count++ 156 } 157 if count != limit { 158 break 159 } 160 161 cur, err = it.Cursor() 162 if err != nil { 163 t.Fatal(err) 164 } 165 if cur.String() == "" { 166 break outer 167 } 168 if startCur == nil { 169 startCur = cur 170 } else if endCur == nil { 171 endCur = cur 172 } 173 } 174 175 if v := len(dataList); v != 100 { 176 t.Errorf("unexpected: %v", v) 177 } 178 179 q := client.NewQuery("Data").Order("Str").Limit(limit) 180 q = q.Start(startCur).End(endCur).KeysOnly() 181 newKeys, err := client.GetAll(ctx, q, nil) 182 if err != nil { 183 t.Fatal(err) 184 } 185 if v := len(newKeys); v != limit { 186 t.Errorf("unexpected: %v", v) 187 } 188 } 189 190 func queryNextByPropertyList(ctx context.Context, t *testing.T, client datastore.Client) { 191 defer func() { 192 err := client.Close() 193 if err != nil { 194 t.Fatal(err) 195 } 196 }() 197 198 type Data struct { 199 Name string 200 } 201 202 _, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Name: "A"}) 203 if err != nil { 204 t.Fatal(err) 205 } 206 207 q := client.NewQuery("Data") 208 209 { // passed datastore.PropertyList, would be error. 210 iter := client.Run(ctx, q) 211 212 var ps datastore.PropertyList 213 _, err = iter.Next(ps) 214 if err == nil { 215 t.Fatal(err) 216 } 217 } 218 { // ok! *datastore.PropertyList 219 iter := client.Run(ctx, q) 220 221 var ps datastore.PropertyList 222 _, err = iter.Next(&ps) 223 if err != nil { 224 t.Fatal(err) 225 } 226 } 227 } 228 229 func queryGetAllByPropertyListSlice(ctx context.Context, t *testing.T, client datastore.Client) { 230 defer func() { 231 err := client.Close() 232 if err != nil { 233 t.Fatal(err) 234 } 235 }() 236 237 type Data struct { 238 Name string 239 } 240 241 _, err := client.Put(ctx, client.IncompleteKey("Data", nil), &Data{Name: "A"}) 242 if err != nil { 243 t.Fatal(err) 244 } 245 246 q := client.NewQuery("Data") 247 var psList []datastore.PropertyList 248 249 // passed []datastore.PropertyList, would be error. 250 _, err = client.GetAll(ctx, q, psList) 251 if err == nil { 252 t.Fatal(err) 253 } 254 255 // ok! *[]datastore.PropertyList 256 psList = nil 257 _, err = client.GetAll(ctx, q, &psList) 258 if err != nil { 259 t.Fatal(err) 260 } 261 } 262 263 func filterBasic(ctx context.Context, t *testing.T, client datastore.Client) { 264 defer func() { 265 err := client.Close() 266 if err != nil { 267 t.Fatal(err) 268 } 269 }() 270 271 type Data struct { 272 Int int 273 Bool bool 274 String string 275 Float float64 276 Key datastore.Key 277 GeoPoint datastore.GeoPoint 278 Time time.Time 279 } 280 281 now := time.Now() 282 283 obj1 := &Data{ 284 Int: 1, 285 Bool: true, 286 String: "1", 287 Float: 1.1, 288 Key: client.IDKey("Test", 1, nil), 289 GeoPoint: datastore.GeoPoint{Lat: 1.1, Lng: 1.2}, 290 Time: now, 291 } 292 key1, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj1) 293 if err != nil { 294 t.Fatal(err) 295 } 296 297 obj2 := &Data{ 298 Int: 2, 299 Bool: false, 300 String: "2", 301 Float: 2.2, 302 Key: client.IDKey("Test", 2, nil), 303 GeoPoint: datastore.GeoPoint{Lat: 2.1, Lng: 2.2}, 304 Time: now.Add(1 * time.Hour), 305 } 306 key2, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj2) 307 if err != nil { 308 t.Fatal(err) 309 } 310 311 t.Log(key1, key2) 312 313 expects := []struct { 314 Name string 315 Value interface{} 316 }{ 317 {"Int", 1}, 318 {"Bool", true}, 319 {"String", "1"}, 320 {"Float", 1.1}, 321 {"Key", client.IDKey("Test", 1, nil)}, 322 {"GeoPoint", datastore.GeoPoint{Lat: 1.1, Lng: 1.2}}, 323 {"Time", now}, 324 } 325 326 for _, expect := range expects { 327 t.Logf("expect: %#v", expect) 328 filterStr := fmt.Sprintf("%s =", expect.Name) 329 { // Count 330 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 331 cnt, err := client.Count(ctx, q) 332 if err != nil { 333 t.Fatal(err) 334 } 335 if cnt != 1 { 336 t.Errorf("unexpected: %v", cnt) 337 } 338 } 339 { // GetAll 340 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 341 var list []*Data 342 keys, err := client.GetAll(ctx, q, &list) 343 if err != nil { 344 t.Fatal(err) 345 } 346 if v := len(keys); v != 1 { 347 t.Fatalf("unexpected: %v", v) 348 } 349 if v := keys[0]; v.ID() != key1.ID() { 350 t.Errorf("unexpected: %v", v) 351 } 352 if v := len(list); v != 1 { 353 t.Errorf("unexpected: %v", v) 354 } 355 } 356 { // Run 357 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 358 iter := client.Run(ctx, q) 359 cnt := 0 360 for { 361 obj := &Data{} 362 key, err := iter.Next(obj) 363 if err == iterator.Done { 364 break 365 } else if err != nil { 366 t.Fatal(err) 367 } 368 cnt++ 369 if v := key; v.ID() != key1.ID() { 370 t.Errorf("unexpected: %v", v) 371 } 372 } 373 if cnt != 1 { 374 t.Errorf("unexpected: %v", cnt) 375 } 376 } 377 } 378 } 379 380 func filterPropertyTranslater(ctx context.Context, t *testing.T, client datastore.Client) { 381 defer func() { 382 err := client.Close() 383 if err != nil { 384 t.Fatal(err) 385 } 386 }() 387 ctx = context.WithValue(ctx, contextClient{}, client) 388 client.SetContext(ctx) 389 390 type Data struct { 391 UserID userID 392 UnixTime unixTime 393 } 394 395 now := time.Now() 396 397 obj1 := &Data{ 398 UserID: userID(1), 399 UnixTime: unixTime(now), 400 } 401 key1, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj1) 402 if err != nil { 403 t.Fatal(err) 404 } 405 406 obj2 := &Data{ 407 UserID: userID(2), 408 UnixTime: unixTime(now.Add(1 * time.Hour)), 409 } 410 key2, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj2) 411 if err != nil { 412 t.Fatal(err) 413 } 414 415 t.Log(key1, key2) 416 417 expects := []struct { 418 Name string 419 Value interface{} 420 }{ 421 {"UserID", userID(1)}, 422 {"UnixTime", unixTime(now)}, 423 } 424 425 for _, expect := range expects { 426 t.Logf("expect: %#v", expect) 427 filterStr := fmt.Sprintf("%s =", expect.Name) 428 { // Count 429 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 430 cnt, err := client.Count(ctx, q) 431 if err != nil { 432 t.Fatal(err) 433 } 434 if cnt != 1 { 435 t.Errorf("unexpected: %v", cnt) 436 } 437 } 438 { // GetAll 439 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 440 var list []*Data 441 keys, err := client.GetAll(ctx, q, &list) 442 if err != nil { 443 t.Fatal(err) 444 } 445 if v := len(keys); v != 1 { 446 t.Fatalf("unexpected: %v", v) 447 } 448 if v := keys[0]; v.ID() != key1.ID() { 449 t.Errorf("unexpected: %v", v) 450 } 451 if v := len(list); v != 1 { 452 t.Errorf("unexpected: %v", v) 453 } 454 } 455 { // Run 456 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 457 iter := client.Run(ctx, q) 458 cnt := 0 459 for { 460 obj := &Data{} 461 key, err := iter.Next(obj) 462 if err == iterator.Done { 463 break 464 } else if err != nil { 465 t.Fatal(err) 466 } 467 cnt++ 468 if v := key; v.ID() != key1.ID() { 469 t.Errorf("unexpected: %v", v) 470 } 471 } 472 if cnt != 1 { 473 t.Errorf("unexpected: %v", cnt) 474 } 475 } 476 } 477 } 478 479 func filterPropertyTranslaterWithOriginalTypes(ctx context.Context, t *testing.T, client datastore.Client) { 480 defer func() { 481 err := client.Close() 482 if err != nil { 483 t.Fatal(err) 484 } 485 }() 486 ctx = context.WithValue(ctx, contextClient{}, client) 487 client.SetContext(ctx) 488 489 type Data struct { 490 UserID userID 491 UnixTime unixTime 492 } 493 494 now := time.Now() 495 496 obj1 := &Data{ 497 UserID: userID(1), 498 UnixTime: unixTime(now), 499 } 500 key1, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj1) 501 if err != nil { 502 t.Fatal(err) 503 } 504 505 obj2 := &Data{ 506 UserID: userID(2), 507 UnixTime: unixTime(now.Add(1 * time.Hour)), 508 } 509 key2, err := client.Put(ctx, client.IncompleteKey("Data", nil), obj2) 510 if err != nil { 511 t.Fatal(err) 512 } 513 514 t.Log(key1, key2) 515 516 expects := []struct { 517 Name string 518 Value interface{} 519 }{ 520 {"UserID", client.IDKey("User", 1, nil)}, 521 {"UnixTime", now}, 522 } 523 524 for _, expect := range expects { 525 t.Logf("expect: %#v", expect) 526 filterStr := fmt.Sprintf("%s =", expect.Name) 527 { // Count 528 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 529 cnt, err := client.Count(ctx, q) 530 if err != nil { 531 t.Fatal(err) 532 } 533 if cnt != 1 { 534 t.Errorf("unexpected: %v", cnt) 535 } 536 } 537 { // GetAll 538 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 539 var list []*Data 540 keys, err := client.GetAll(ctx, q, &list) 541 if err != nil { 542 t.Fatal(err) 543 } 544 if v := len(keys); v != 1 { 545 t.Fatalf("unexpected: %v", v) 546 } 547 if v := keys[0]; v.ID() != key1.ID() { 548 t.Errorf("unexpected: %v", v) 549 } 550 if v := len(list); v != 1 { 551 t.Errorf("unexpected: %v", v) 552 } 553 } 554 { // Run 555 q := client.NewQuery("Data").Filter(filterStr, expect.Value) 556 iter := client.Run(ctx, q) 557 cnt := 0 558 for { 559 obj := &Data{} 560 key, err := iter.Next(obj) 561 if err == iterator.Done { 562 break 563 } else if err != nil { 564 t.Fatal(err) 565 } 566 cnt++ 567 if v := key; v.ID() != key1.ID() { 568 t.Errorf("unexpected: %v", v) 569 } 570 } 571 if cnt != 1 { 572 t.Errorf("unexpected: %v", cnt) 573 } 574 } 575 } 576 } 577 578 var _ datastore.PropertyTranslator = (*mustReturnsError)(nil) 579 580 type mustReturnsError int 581 582 func (mustReturnsError) ToPropertyValue(ctx context.Context) (interface{}, error) { 583 return nil, errors.New("error from MustReturnsError") 584 } 585 586 func (mustReturnsError) FromPropertyValue(ctx context.Context, p datastore.Property) (dst interface{}, err error) { 587 return nil, errors.New("error from MustReturnsError") 588 } 589 590 func filterPropertyTranslaterMustError(ctx context.Context, t *testing.T, client datastore.Client) { 591 defer func() { 592 err := client.Close() 593 if err != nil { 594 t.Fatal(err) 595 } 596 }() 597 598 type Data struct { 599 TMP int 600 } 601 602 { // Count 603 q := client.NewQuery("Data").Filter("TMP =", mustReturnsError(1)) 604 _, err := client.Count(ctx, q) 605 if err == nil || err.Error() != "error from MustReturnsError" { 606 t.Fatal(err) 607 } 608 } 609 { // GetAll 610 q := client.NewQuery("Data").Filter("TMP =", mustReturnsError(1)) 611 var list []*Data 612 _, err := client.GetAll(ctx, q, &list) 613 if err == nil || err.Error() != "error from MustReturnsError" { 614 t.Fatal(err) 615 } 616 } 617 { // Run 618 q := client.NewQuery("Data").Filter("TMP =", mustReturnsError(1)) 619 iter := client.Run(ctx, q) 620 obj := &Data{} 621 _, err := iter.Next(obj) 622 if err == nil || err.Error() != "error from MustReturnsError" { 623 t.Fatal(err) 624 } 625 } 626 }