1// Copyright 2016 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package datastore_test 16 17import ( 18 "fmt" 19 "log" 20 "time" 21 22 "cloud.google.com/go/datastore" 23 "golang.org/x/net/context" 24) 25 26type Task struct { 27 Type string 28 Done bool 29 Priority int 30 Description string `datastore:",noindex"` 31 PercentComplete float64 32 Created time.Time 33 Tags []string 34 Collaborators []string 35} 36 37func ExampleNewIncompleteKey() { 38 ctx := context.Background() 39 // [START incomplete_key] 40 taskKey := datastore.NewIncompleteKey(ctx, "Task", nil) 41 // [END incomplete_key] 42 _ = taskKey // Use the task key for datastore operations. 43} 44 45func ExampleNewKey() { 46 ctx := context.Background() 47 // [START named_key] 48 taskKey := datastore.NewKey(ctx, "Task", "sampletask", 0, nil) 49 // [END named_key] 50 _ = taskKey // Use the task key for datastore operations. 51} 52 53func ExampleNewKey_withParent() { 54 ctx := context.Background() 55 // [START key_with_parent] 56 parentKey := datastore.NewKey(ctx, "TaskList", "default", 0, nil) 57 taskKey := datastore.NewKey(ctx, "Task", "sampleTask", 0, parentKey) 58 // [END key_with_parent] 59 _ = taskKey // Use the task key for datastore operations. 60} 61 62func ExampleNewKey_withMultipleParents() { 63 ctx := context.Background() 64 // [START key_with_multilevel_parent] 65 userKey := datastore.NewKey(ctx, "User", "alice", 0, nil) 66 parentKey := datastore.NewKey(ctx, "TaskList", "default", 0, userKey) 67 taskKey := datastore.NewKey(ctx, "Task", "sampleTask", 0, parentKey) 68 // [END key_with_multilevel_parent] 69 _ = taskKey // Use the task key for datastore operations. 70} 71 72func ExampleClient_Put() { 73 ctx := context.Background() 74 client, _ := datastore.NewClient(ctx, "my-proj") 75 // [START entity_with_parent] 76 parentKey := datastore.NewKey(ctx, "TaskList", "default", 0, nil) 77 key := datastore.NewIncompleteKey(ctx, "Task", parentKey) 78 79 task := Task{ 80 Type: "Personal", 81 Done: false, 82 Priority: 4, 83 Description: "Learn Cloud Datastore", 84 } 85 86 // A complete key is assigned to the entity when it is Put. 87 var err error 88 key, err = client.Put(ctx, key, &task) 89 // [END entity_with_parent] 90 _ = err // Make sure you check err. 91} 92 93func Example_properties() { 94 // [START properties] 95 type Task struct { 96 Type string 97 Done bool 98 Priority int 99 Description string `datastore:",noindex"` 100 PercentComplete float64 101 Created time.Time 102 } 103 task := &Task{ 104 Type: "Personal", 105 Done: false, 106 Priority: 4, 107 Description: "Learn Cloud Datastore", 108 PercentComplete: 10.0, 109 Created: time.Now(), 110 } 111 // [END properties] 112 _ = task // Use the task in a datastore Put operation. 113} 114 115func Example_sliceProperties() { 116 // [START array_value] 117 type Task struct { 118 Tags []string 119 Collaborators []string 120 } 121 task := &Task{ 122 Tags: []string{"fun", "programming"}, 123 Collaborators: []string{"alice", "bob"}, 124 } 125 // [END array_value] 126 _ = task // Use the task in a datastore Put operation. 127} 128 129func Example_basicEntity() { 130 // [START basic_entity] 131 type Task struct { 132 Type string 133 Done bool 134 Priority float64 135 Description string `datastore:",noindex"` 136 PercentComplete float64 137 Created time.Time 138 } 139 task := &Task{ 140 Type: "Personal", 141 Done: false, 142 Priority: 4, 143 Description: "Learn Cloud Datastore", 144 PercentComplete: 10.0, 145 Created: time.Now(), 146 } 147 // [END basic_entity] 148 _ = task // Use the task in a datastore Put operation. 149} 150 151func ExampleClient_Put_upsert() { 152 ctx := context.Background() 153 client, _ := datastore.NewClient(ctx, "my-proj") 154 task := &Task{} // Populated with appropriate data. 155 key := datastore.NewIncompleteKey(ctx, "Task", nil) 156 // [START upsert] 157 key, err := client.Put(ctx, key, task) 158 // [END upsert] 159 _ = err // Make sure you check err. 160 _ = key // key is the complete key for the newly stored task 161} 162 163func ExampleTransaction_insert() { 164 ctx := context.Background() 165 client, _ := datastore.NewClient(ctx, "my-proj") 166 task := &Task{} // Populated with appropriate data. 167 taskKey := datastore.NewKey(ctx, "Task", "sampleTask", 0, nil) 168 // [START insert] 169 tx, err := client.NewTransaction(ctx) 170 if err != nil { 171 log.Fatalf("client.NewTransaction: %v", err) 172 } 173 // We first check that there is no entity stored with the given key. 174 if err := tx.Get(taskKey, nil); err != datastore.ErrNoSuchEntity { 175 log.Fatalf("tx.Get returned err %v, want ErrNoSuchEntity", err) 176 } 177 if _, err := tx.Put(taskKey, task); err != nil { 178 log.Fatalf("tx.Put: %v", err) 179 } 180 if _, err := tx.Commit(); err != nil { 181 log.Fatalf("tx.Commit: %v", err) 182 } 183 // [END insert] 184} 185 186func ExampleClient_Get() { 187 ctx := context.Background() 188 client, _ := datastore.NewClient(ctx, "my-proj") 189 taskKey := datastore.NewKey(ctx, "Task", "sampleTask", 0, nil) 190 // [START lookup] 191 var task Task 192 err := client.Get(ctx, taskKey, &task) 193 // [END lookup] 194 _ = err // Make sure you check err. 195} 196 197func ExampleTransaction_update() { 198 ctx := context.Background() 199 client, _ := datastore.NewClient(ctx, "my-proj") 200 taskKey := datastore.NewKey(ctx, "Task", "sampleTask", 0, nil) 201 // [START update] 202 tx, err := client.NewTransaction(ctx) 203 if err != nil { 204 log.Fatalf("client.NewTransaction: %v", err) 205 } 206 var task Task 207 if err := tx.Get(taskKey, &task); err != nil { 208 log.Fatalf("tx.Get: %v", err) 209 } 210 task.Priority = 5 211 if _, err := tx.Put(taskKey, task); err != nil { 212 log.Fatalf("tx.Put: %v", err) 213 } 214 if _, err := tx.Commit(); err != nil { 215 log.Fatalf("tx.Commit: %v", err) 216 } 217 // [END update] 218} 219 220func ExampleClient_Delete() { 221 ctx := context.Background() 222 client, _ := datastore.NewClient(ctx, "my-proj") 223 key := datastore.NewKey(ctx, "Task", "sampletask", 0, nil) 224 // [START delete] 225 err := client.Delete(ctx, key) 226 // [END delete] 227 _ = err // Make sure you check err. 228} 229 230func ExampleClient_PutMulti() { 231 ctx := context.Background() 232 client, _ := datastore.NewClient(ctx, "my-proj") 233 // [START batch_upsert] 234 tasks := []*Task{ 235 { 236 Type: "Personal", 237 Done: false, 238 Priority: 4, 239 Description: "Learn Cloud Datastore", 240 }, 241 { 242 Type: "Personal", 243 Done: false, 244 Priority: 5, 245 Description: "Integrate Cloud Datastore", 246 }, 247 } 248 keys := []*datastore.Key{ 249 datastore.NewIncompleteKey(ctx, "Task", nil), 250 datastore.NewIncompleteKey(ctx, "Task", nil), 251 } 252 253 keys, err := client.PutMulti(ctx, keys, tasks) 254 // [END batch_upsert] 255 _ = err // Make sure you check err. 256 _ = keys // keys now has the complete keys for the newly stored tasks. 257} 258 259func ExampleClient_GetMulti() { 260 ctx := context.Background() 261 client, _ := datastore.NewClient(ctx, "my-proj") 262 var taskKeys []*datastore.Key // Populated with incomplete keys. 263 // [START batch_lookup] 264 var tasks []*Task 265 err := client.GetMulti(ctx, taskKeys, &tasks) 266 // [END batch_lookup] 267 _ = err // Make sure you check err. 268} 269 270func ExampleClient_DeleteMulti() { 271 ctx := context.Background() 272 client, _ := datastore.NewClient(ctx, "my-proj") 273 var taskKeys []*datastore.Key // Populated with incomplete keys. 274 // [START batch_delete] 275 err := client.DeleteMulti(ctx, taskKeys) 276 // [END batch_delete] 277 _ = err // Make sure you check err. 278} 279 280func ExampleQuery_basic() { 281 ctx := context.Background() 282 client, _ := datastore.NewClient(ctx, "my-proj") 283 // [START basic_query] 284 query := datastore.NewQuery("Task"). 285 Filter("Done =", false). 286 Filter("Priority >=", 4). 287 Order("-Priority") 288 // [END basic_query] 289 // [START run_query] 290 it := client.Run(ctx, query) 291 for { 292 var task Task 293 _, err := it.Next(&task) 294 if err == datastore.Done { 295 break 296 } 297 if err != nil { 298 log.Fatalf("Error fetching next task: %v", err) 299 } 300 fmt.Printf("Task %q, Priority %d\n", task.Description, task.Priority) 301 } 302 // [END run_query] 303} 304 305func ExampleQuery_propertyFilter() { 306 // [START property_filter] 307 query := datastore.NewQuery("Task").Filter("Done =", false) 308 // [END property_filter] 309 _ = query // Use client.Run or client.GetAll to execute the query. 310} 311 312func ExampleQuery_compositeFilter() { 313 // [START composite_filter] 314 query := datastore.NewQuery("Task").Filter("Done =", false).Filter("Priority =", 4) 315 // [END composite_filter] 316 _ = query // Use client.Run or client.GetAll to execute the query. 317} 318 319func ExampleQuery_keyFilter() { 320 ctx := context.Background() 321 // [START key_filter] 322 key := datastore.NewKey(ctx, "Task", "someTask", 0, nil) 323 query := datastore.NewQuery("Task").Filter("__key__ >", key) 324 // [END key_filter] 325 _ = query // Use client.Run or client.GetAll to execute the query. 326} 327 328func ExampleQuery_sortAscending() { 329 // [START ascending_sort] 330 query := datastore.NewQuery("Task").Order("created") 331 // [END ascending_sort] 332 _ = query // Use client.Run or client.GetAll to execute the query. 333} 334 335func ExampleQuery_sortDescending() { 336 // [START descending_sort] 337 query := datastore.NewQuery("Task").Order("-created") 338 // [END descending_sort] 339 _ = query // Use client.Run or client.GetAll to execute the query. 340} 341 342func ExampleQuery_sortMulti() { 343 // [START multi_sort] 344 query := datastore.NewQuery("Task").Order("-priority").Order("created") 345 // [END multi_sort] 346 _ = query // Use client.Run or client.GetAll to execute the query. 347} 348 349func ExampleQuery_kindless() { 350 var lastSeenKey *datastore.Key 351 // [START kindless_query] 352 query := datastore.NewQuery("").Filter("__key__ >", lastSeenKey) 353 // [END kindless_query] 354 _ = query // Use client.Run or client.GetAll to execute the query. 355} 356 357func ExampleQuery_Ancestor() { 358 ctx := context.Background() 359 // [START ancestor_query] 360 ancestor := datastore.NewKey(ctx, "TaskList", "default", 0, nil) 361 query := datastore.NewQuery("Task").Ancestor(ancestor) 362 // [END ancestor_query] 363 _ = query // Use client.Run or client.GetAll to execute the query. 364} 365 366func ExampleQuery_Project() { 367 ctx := context.Background() 368 client, _ := datastore.NewClient(ctx, "my-proj") 369 // [START projection_query] 370 query := datastore.NewQuery("Task").Project("Priority", "PercentComplete") 371 // [END projection_query] 372 // [START run_query_projection] 373 var priorities []int 374 var percents []float64 375 it := client.Run(ctx, query) 376 for { 377 var task Task 378 if _, err := it.Next(&task); err == datastore.Done { 379 break 380 } else if err != nil { 381 log.Fatal(err) 382 } 383 priorities = append(priorities, task.Priority) 384 percents = append(percents, task.PercentComplete) 385 } 386 // [END run_query_projection] 387} 388 389func ExampleQuery_KeysOnly() { 390 ctx := context.Background() 391 client, _ := datastore.NewClient(ctx, "my-proj") 392 // [START keys_only_query] 393 query := datastore.NewQuery("Task").KeysOnly() 394 // [END keys_only_query] 395 // [START run_keys_only_query] 396 keys, err := client.GetAll(ctx, query, nil) 397 // [END run_keys_only_query] 398 _ = err // Make sure you check err. 399 _ = keys // Keys contains keys for all stored tasks. 400} 401 402func ExampleQuery_Distinct() { 403 // [START distinct_query] 404 query := datastore.NewQuery("Task"). 405 Project("Priority", "PercentComplete"). 406 Distinct(). 407 Order("Type").Order("Priority") 408 // [END distinct_query] 409 _ = query // Use client.Run or client.GetAll to execute the query. 410 411 // [START distinct_on_query] 412 // DISTINCT ON not supported in Go API 413 // [END distinct_on_query] 414} 415 416func ExampleQuery_Filter_arrayInequality() { 417 // [START array_value_inequality_range] 418 query := datastore.NewQuery("Task"). 419 Filter("Tag >", "learn"). 420 Filter("Tag <", "math") 421 // [END array_value_inequality_range] 422 _ = query // Use client.Run or client.GetAll to execute the query. 423} 424 425func ExampleQuery_Filter_arrayEquality() { 426 // [START array_value_equality] 427 query := datastore.NewQuery("Task"). 428 Filter("Tag =", "fun"). 429 Filter("Tag =", "programming") 430 // [END array_value_equality] 431 _ = query // Use client.Run or client.GetAll to execute the query. 432} 433 434func ExampleQuery_Filter_inequality() { 435 // [START inequality_range] 436 query := datastore.NewQuery("Task"). 437 Filter("Created >", time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC)). 438 Filter("Created <", time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) 439 // [END inequality_range] 440 _ = query // Use client.Run or client.GetAll to execute the query. 441} 442 443func ExampleQuery_Filter_invalidInequality() { 444 // [START inequality_invalid] 445 query := datastore.NewQuery("Task"). 446 Filter("Created >", time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC)). 447 Filter("Priority >", 3) 448 // [END inequality_invalid] 449 _ = query // The query is invalid. 450} 451 452func ExampleQuery_Filter_mixed() { 453 // [START equal_and_inequality_range] 454 query := datastore.NewQuery("Task"). 455 Filter("Priority =", 4). 456 Filter("Done =", false). 457 Filter("Created >", time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC)). 458 Filter("Created <", time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) 459 // [END equal_and_inequality_range] 460 _ = query // Use client.Run or client.GetAll to execute the query. 461} 462 463func ExampleQuery_inequalitySort() { 464 // [START inequality_sort] 465 query := datastore.NewQuery("Task"). 466 Filter("Priority >", 3). 467 Order("Priority"). 468 Order("Created") 469 // [END inequality_sort] 470 _ = query // Use client.Run or client.GetAll to execute the query. 471} 472 473func ExampleQuery_invalidInequalitySortA() { 474 // [START inequality_sort_invalid_not_same] 475 query := datastore.NewQuery("Task"). 476 Filter("Priority >", 3). 477 Order("Created") 478 // [END inequality_sort_invalid_not_same] 479 _ = query // The query is invalid. 480} 481 482func ExampleQuery_invalidInequalitySortB() { 483 // [START inequality_sort_invalid_not_first] 484 query := datastore.NewQuery("Task"). 485 Filter("Priority >", 3). 486 Order("Created"). 487 Order("Priority") 488 // [END inequality_sort_invalid_not_first] 489 _ = query // The query is invalid. 490} 491 492func ExampleQuery_Limit() { 493 // [START limit] 494 query := datastore.NewQuery("Task").Limit(5) 495 // [END limit] 496 _ = query // Use client.Run or client.GetAll to execute the query. 497} 498 499func ExampleIterator_Cursor() { 500 ctx := context.Background() 501 client, _ := datastore.NewClient(ctx, "my-proj") 502 cursorStr := "" 503 // [START cursor_paging] 504 const pageSize = 5 505 query := datastore.NewQuery("Tasks").Limit(pageSize) 506 if cursorStr != "" { 507 cursor, err := datastore.DecodeCursor(cursorStr) 508 if err != nil { 509 log.Fatalf("Bad cursor %q: %v", cursorStr, err) 510 } 511 query = query.Start(cursor) 512 } 513 514 // Read the tasks. 515 var tasks []Task 516 var task Task 517 it := client.Run(ctx, query) 518 _, err := it.Next(&task) 519 for err == nil { 520 tasks = append(tasks, task) 521 _, err = it.Next(&task) 522 } 523 if err != datastore.Done { 524 log.Fatalf("Failed fetching results: %v", err) 525 } 526 527 // Get the cursor for the next page of results. 528 nextCursor, err := it.Cursor() 529 // [END cursor_paging] 530 _ = err // Check the error. 531 _ = nextCursor // Use nextCursor.String as the next page's token. 532} 533 534func ExampleQuery_EventualConsistency() { 535 ctx := context.Background() 536 // [START eventual_consistent_query] 537 ancestor := datastore.NewKey(ctx, "TaskList", "default", 0, nil) 538 query := datastore.NewQuery("Task").Ancestor(ancestor).EventualConsistency() 539 // [END eventual_consistent_query] 540 _ = query // Use client.Run or client.GetAll to execute the query. 541} 542 543func ExampleQuery_unindexed() { 544 // [START unindexed_property_query] 545 query := datastore.NewQuery("Tasks").Filter("Description =", "A task description") 546 // [END unindexed_property_query] 547 _ = query // Use client.Run or client.GetAll to execute the query. 548} 549 550func Example_explodingProperties() { 551 // [START exploding_properties] 552 task := &Task{ 553 Tags: []string{"fun", "programming", "learn"}, 554 Collaborators: []string{"alice", "bob", "charlie"}, 555 Created: time.Now(), 556 } 557 // [END exploding_properties] 558 _ = task // Use the task in a datastore Put operation. 559} 560 561func Example_Transaction() { 562 ctx := context.Background() 563 client, _ := datastore.NewClient(ctx, "my-proj") 564 var to, from *datastore.Key 565 // [START transactional_update] 566 type BankAccount struct { 567 Balance int 568 } 569 570 const amount = 50 571 keys := []*datastore.Key{to, from} 572 tx, err := client.NewTransaction(ctx) 573 if err != nil { 574 log.Fatalf("client.NewTransaction: %v", err) 575 } 576 accs := make([]BankAccount, 2) 577 if err := tx.GetMulti(keys, accs); err != nil { 578 tx.Rollback() 579 log.Fatalf("tx.GetMulti: %v", err) 580 } 581 accs[0].Balance += amount 582 accs[1].Balance -= amount 583 if _, err := tx.PutMulti(keys, accs); err != nil { 584 tx.Rollback() 585 log.Fatalf("tx.PutMulti: %v", err) 586 } 587 if _, err = tx.Commit(); err != nil { 588 log.Fatalf("tx.Commit: %v", err) 589 } 590 // [END transactional_update] 591} 592 593func Example_Client_RunInTransaction() { 594 ctx := context.Background() 595 client, _ := datastore.NewClient(ctx, "my-proj") 596 var to, from *datastore.Key 597 // [START transactional_retry] 598 type BankAccount struct { 599 Balance int 600 } 601 602 const amount = 50 603 _, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error { 604 keys := []*datastore.Key{to, from} 605 accs := make([]BankAccount, 2) 606 if err := tx.GetMulti(keys, accs); err != nil { 607 return err 608 } 609 accs[0].Balance += amount 610 accs[1].Balance -= amount 611 _, err := tx.PutMulti(keys, accs) 612 return err 613 }) 614 // [END transactional_retry] 615 _ = err // Check error. 616} 617 618func ExampleTransaction_getOrCreate() { 619 ctx := context.Background() 620 client, _ := datastore.NewClient(ctx, "my-proj") 621 key := datastore.NewKey(ctx, "Task", "sampletask", 0, nil) 622 // [START transactional_get_or_create] 623 _, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error { 624 var task Task 625 if err := tx.Get(key, &task); err != datastore.ErrNoSuchEntity { 626 return err 627 } 628 _, err := tx.Put(key, &Task{ 629 Type: "Personal", 630 Done: false, 631 Priority: 4, 632 Description: "Learn Cloud Datastore", 633 }) 634 return err 635 }) 636 // [END transactional_get_or_create] 637 _ = err // Check error. 638} 639 640func ExampleTransaction_runQuery() { 641 ctx := context.Background() 642 client, _ := datastore.NewClient(ctx, "my-proj") 643 // [START transactional_single_entity_group_read_only] 644 tx, err := client.NewTransaction(ctx) 645 if err != nil { 646 log.Fatalf("client.NewTransaction: %v", err) 647 } 648 defer tx.Rollback() // Transaction only used for read. 649 650 ancestor := datastore.NewKey(ctx, "TaskList", "default", 0, nil) 651 query := datastore.NewQuery("Task").Ancestor(ancestor).Transaction(tx) 652 var tasks []Task 653 _, err = client.GetAll(ctx, query, &tasks) 654 // [END transactional_single_entity_group_read_only] 655 _ = err // Check error. 656} 657 658func Example_metadataNamespaces() { 659 ctx := context.Background() 660 client, _ := datastore.NewClient(ctx, "my-proj") 661 // [START namespace_run_query] 662 const ( 663 startNamespace = "g" 664 endNamespace = "h" 665 ) 666 query := datastore.NewQuery("__namespace__"). 667 Filter("__key__ >=", startNamespace). 668 Filter("__key__ <", endNamespace). 669 KeysOnly() 670 keys, err := client.GetAll(ctx, query, nil) 671 if err != nil { 672 log.Fatalf("client.GetAll: %v", err) 673 } 674 675 namespaces := make([]string, 0, len(keys)) 676 for _, k := range keys { 677 namespaces = append(namespaces, k.Name()) 678 } 679 // [END namespace_run_query] 680} 681 682func Example_metadataKinds() { 683 ctx := context.Background() 684 client, _ := datastore.NewClient(ctx, "my-proj") 685 // [START kind_run_query] 686 query := datastore.NewQuery("__kind__").KeysOnly() 687 keys, err := client.GetAll(ctx, query, nil) 688 if err != nil { 689 log.Fatalf("client.GetAll: %v", err) 690 } 691 692 kinds := make([]string, 0, len(keys)) 693 for _, k := range keys { 694 kinds = append(kinds, k.Name()) 695 } 696 // [END kind_run_query] 697} 698 699func Example_metadataProperties() { 700 ctx := context.Background() 701 client, _ := datastore.NewClient(ctx, "my-proj") 702 // [START property_run_query] 703 query := datastore.NewQuery("__property__").KeysOnly() 704 keys, err := client.GetAll(ctx, query, nil) 705 if err != nil { 706 log.Fatalf("client.GetAll: %v", err) 707 } 708 709 props := make(map[string][]string) // Map from kind to slice of properties. 710 for _, k := range keys { 711 prop := k.Name() 712 kind := k.Parent().Name() 713 props[kind] = append(props[kind], prop) 714 } 715 // [END property_run_query] 716} 717 718func Example_metadataPropertiesForKind() { 719 ctx := context.Background() 720 client, _ := datastore.NewClient(ctx, "my-proj") 721 // [START property_by_kind_run_query] 722 kindKey := datastore.NewKey(ctx, "__kind__", "Task", 0, nil) 723 query := datastore.NewQuery("__property__").Ancestor(kindKey) 724 725 type Prop struct { 726 Repr []string `datastore:"property_representation"` 727 } 728 729 var props []Prop 730 keys, err := client.GetAll(ctx, query, &props) 731 // [END property_by_kind_run_query] 732 _ = err // Check error. 733 _ = keys // Use keys to find property names, and props for their representations. 734} 735