Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

568 righe
13 KiB

  1. // Copyright 2014 Google LLC
  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. package datastore_test
  15. import (
  16. "fmt"
  17. "log"
  18. "time"
  19. "cloud.google.com/go/datastore"
  20. "golang.org/x/net/context"
  21. "google.golang.org/api/iterator"
  22. )
  23. func ExampleNewClient() {
  24. ctx := context.Background()
  25. client, err := datastore.NewClient(ctx, "project-id")
  26. if err != nil {
  27. // TODO: Handle error.
  28. }
  29. _ = client // TODO: Use client.
  30. }
  31. func ExampleClient_Get() {
  32. ctx := context.Background()
  33. client, err := datastore.NewClient(ctx, "project-id")
  34. if err != nil {
  35. // TODO: Handle error.
  36. }
  37. type Article struct {
  38. Title string
  39. Description string
  40. Body string `datastore:",noindex"`
  41. Author *datastore.Key
  42. PublishedAt time.Time
  43. }
  44. key := datastore.NameKey("Article", "articled1", nil)
  45. article := &Article{}
  46. if err := client.Get(ctx, key, article); err != nil {
  47. // TODO: Handle error.
  48. }
  49. }
  50. func ExampleClient_Put() {
  51. ctx := context.Background()
  52. client, err := datastore.NewClient(ctx, "project-id")
  53. if err != nil {
  54. // TODO: Handle error.
  55. }
  56. type Article struct {
  57. Title string
  58. Description string
  59. Body string `datastore:",noindex"`
  60. Author *datastore.Key
  61. PublishedAt time.Time
  62. }
  63. newKey := datastore.IncompleteKey("Article", nil)
  64. _, err = client.Put(ctx, newKey, &Article{
  65. Title: "The title of the article",
  66. Description: "The description of the article...",
  67. Body: "...",
  68. Author: datastore.NameKey("Author", "jbd", nil),
  69. PublishedAt: time.Now(),
  70. })
  71. if err != nil {
  72. // TODO: Handle error.
  73. }
  74. }
  75. func ExampleClient_Put_flatten() {
  76. ctx := context.Background()
  77. client, err := datastore.NewClient(ctx, "project-id")
  78. if err != nil {
  79. log.Fatal(err)
  80. }
  81. type Animal struct {
  82. Name string
  83. Type string
  84. Breed string
  85. }
  86. type Human struct {
  87. Name string
  88. Height int
  89. Pet Animal `datastore:",flatten"`
  90. }
  91. newKey := datastore.IncompleteKey("Human", nil)
  92. _, err = client.Put(ctx, newKey, &Human{
  93. Name: "Susan",
  94. Height: 67,
  95. Pet: Animal{
  96. Name: "Fluffy",
  97. Type: "Cat",
  98. Breed: "Sphynx",
  99. },
  100. })
  101. if err != nil {
  102. log.Fatal(err)
  103. }
  104. }
  105. func ExampleClient_Delete() {
  106. ctx := context.Background()
  107. client, err := datastore.NewClient(ctx, "project-id")
  108. if err != nil {
  109. // TODO: Handle error.
  110. }
  111. key := datastore.NameKey("Article", "articled1", nil)
  112. if err := client.Delete(ctx, key); err != nil {
  113. // TODO: Handle error.
  114. }
  115. }
  116. func ExampleClient_DeleteMulti() {
  117. ctx := context.Background()
  118. client, err := datastore.NewClient(ctx, "project-id")
  119. if err != nil {
  120. // TODO: Handle error.
  121. }
  122. var keys []*datastore.Key
  123. for i := 1; i <= 10; i++ {
  124. keys = append(keys, datastore.IDKey("Article", int64(i), nil))
  125. }
  126. if err := client.DeleteMulti(ctx, keys); err != nil {
  127. // TODO: Handle error.
  128. }
  129. }
  130. type Post struct {
  131. Title string
  132. PublishedAt time.Time
  133. Comments int
  134. }
  135. func ExampleClient_GetMulti() {
  136. ctx := context.Background()
  137. client, err := datastore.NewClient(ctx, "project-id")
  138. if err != nil {
  139. // TODO: Handle error.
  140. }
  141. keys := []*datastore.Key{
  142. datastore.NameKey("Post", "post1", nil),
  143. datastore.NameKey("Post", "post2", nil),
  144. datastore.NameKey("Post", "post3", nil),
  145. }
  146. posts := make([]Post, 3)
  147. if err := client.GetMulti(ctx, keys, posts); err != nil {
  148. // TODO: Handle error.
  149. }
  150. }
  151. func ExampleClient_PutMulti_slice() {
  152. ctx := context.Background()
  153. client, err := datastore.NewClient(ctx, "project-id")
  154. if err != nil {
  155. // TODO: Handle error.
  156. }
  157. keys := []*datastore.Key{
  158. datastore.NameKey("Post", "post1", nil),
  159. datastore.NameKey("Post", "post2", nil),
  160. }
  161. // PutMulti with a Post slice.
  162. posts := []*Post{
  163. {Title: "Post 1", PublishedAt: time.Now()},
  164. {Title: "Post 2", PublishedAt: time.Now()},
  165. }
  166. if _, err := client.PutMulti(ctx, keys, posts); err != nil {
  167. // TODO: Handle error.
  168. }
  169. }
  170. func ExampleClient_PutMulti_interfaceSlice() {
  171. ctx := context.Background()
  172. client, err := datastore.NewClient(ctx, "project-id")
  173. if err != nil {
  174. // TODO: Handle error.
  175. }
  176. keys := []*datastore.Key{
  177. datastore.NameKey("Post", "post1", nil),
  178. datastore.NameKey("Post", "post2", nil),
  179. }
  180. // PutMulti with an empty interface slice.
  181. posts := []interface{}{
  182. &Post{Title: "Post 1", PublishedAt: time.Now()},
  183. &Post{Title: "Post 2", PublishedAt: time.Now()},
  184. }
  185. if _, err := client.PutMulti(ctx, keys, posts); err != nil {
  186. // TODO: Handle error.
  187. }
  188. }
  189. func ExampleNewQuery() {
  190. // Query for Post entities.
  191. q := datastore.NewQuery("Post")
  192. _ = q // TODO: Use the query with Client.Run.
  193. }
  194. func ExampleNewQuery_options() {
  195. // Query to order the posts by the number of comments they have received.
  196. q := datastore.NewQuery("Post").Order("-Comments")
  197. // Start listing from an offset and limit the results.
  198. q = q.Offset(20).Limit(10)
  199. _ = q // TODO: Use the query.
  200. }
  201. func ExampleClient_Count() {
  202. ctx := context.Background()
  203. client, err := datastore.NewClient(ctx, "project-id")
  204. if err != nil {
  205. // TODO: Handle error.
  206. }
  207. // Count the number of the post entities.
  208. q := datastore.NewQuery("Post")
  209. n, err := client.Count(ctx, q)
  210. if err != nil {
  211. // TODO: Handle error.
  212. }
  213. fmt.Printf("There are %d posts.", n)
  214. }
  215. func ExampleClient_Run() {
  216. ctx := context.Background()
  217. client, err := datastore.NewClient(ctx, "project-id")
  218. if err != nil {
  219. // TODO: Handle error.
  220. }
  221. // List the posts published since yesterday.
  222. yesterday := time.Now().Add(-24 * time.Hour)
  223. q := datastore.NewQuery("Post").Filter("PublishedAt >", yesterday)
  224. it := client.Run(ctx, q)
  225. _ = it // TODO: iterate using Next.
  226. }
  227. func ExampleClient_NewTransaction() {
  228. ctx := context.Background()
  229. client, err := datastore.NewClient(ctx, "project-id")
  230. if err != nil {
  231. // TODO: Handle error.
  232. }
  233. const retries = 3
  234. // Increment a counter.
  235. // See https://cloud.google.com/appengine/articles/sharding_counters for
  236. // a more scalable solution.
  237. type Counter struct {
  238. Count int
  239. }
  240. key := datastore.NameKey("counter", "CounterA", nil)
  241. var tx *datastore.Transaction
  242. for i := 0; i < retries; i++ {
  243. tx, err = client.NewTransaction(ctx)
  244. if err != nil {
  245. break
  246. }
  247. var c Counter
  248. if err = tx.Get(key, &c); err != nil && err != datastore.ErrNoSuchEntity {
  249. break
  250. }
  251. c.Count++
  252. if _, err = tx.Put(key, &c); err != nil {
  253. break
  254. }
  255. // Attempt to commit the transaction. If there's a conflict, try again.
  256. if _, err = tx.Commit(); err != datastore.ErrConcurrentTransaction {
  257. break
  258. }
  259. }
  260. if err != nil {
  261. // TODO: Handle error.
  262. }
  263. }
  264. func ExampleClient_RunInTransaction() {
  265. ctx := context.Background()
  266. client, err := datastore.NewClient(ctx, "project-id")
  267. if err != nil {
  268. // TODO: Handle error.
  269. }
  270. // Increment a counter.
  271. // See https://cloud.google.com/appengine/articles/sharding_counters for
  272. // a more scalable solution.
  273. type Counter struct {
  274. Count int
  275. }
  276. var count int
  277. key := datastore.NameKey("Counter", "singleton", nil)
  278. _, err = client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
  279. var x Counter
  280. if err := tx.Get(key, &x); err != nil && err != datastore.ErrNoSuchEntity {
  281. return err
  282. }
  283. x.Count++
  284. if _, err := tx.Put(key, &x); err != nil {
  285. return err
  286. }
  287. count = x.Count
  288. return nil
  289. })
  290. if err != nil {
  291. // TODO: Handle error.
  292. }
  293. // The value of count is only valid once the transaction is successful
  294. // (RunInTransaction has returned nil).
  295. fmt.Printf("Count=%d\n", count)
  296. }
  297. func ExampleClient_AllocateIDs() {
  298. ctx := context.Background()
  299. client, err := datastore.NewClient(ctx, "project-id")
  300. if err != nil {
  301. // TODO: Handle error.
  302. }
  303. var keys []*datastore.Key
  304. for i := 0; i < 10; i++ {
  305. keys = append(keys, datastore.IncompleteKey("Article", nil))
  306. }
  307. keys, err = client.AllocateIDs(ctx, keys)
  308. if err != nil {
  309. // TODO: Handle error.
  310. }
  311. _ = keys // TODO: Use keys.
  312. }
  313. func ExampleKey_Encode() {
  314. key := datastore.IDKey("Article", 1, nil)
  315. encoded := key.Encode()
  316. fmt.Println(encoded)
  317. // Output: EgsKB0FydGljbGUQAQ
  318. }
  319. func ExampleDecodeKey() {
  320. const encoded = "EgsKB0FydGljbGUQAQ"
  321. key, err := datastore.DecodeKey(encoded)
  322. if err != nil {
  323. // TODO: Handle error.
  324. }
  325. fmt.Println(key)
  326. // Output: /Article,1
  327. }
  328. func ExampleIDKey() {
  329. // Key with numeric ID.
  330. k := datastore.IDKey("Article", 1, nil)
  331. _ = k // TODO: Use key.
  332. }
  333. func ExampleNameKey() {
  334. // Key with string ID.
  335. k := datastore.NameKey("Article", "article8", nil)
  336. _ = k // TODO: Use key.
  337. }
  338. func ExampleIncompleteKey() {
  339. k := datastore.IncompleteKey("Article", nil)
  340. _ = k // TODO: Use incomplete key.
  341. }
  342. func ExampleClient_GetAll() {
  343. ctx := context.Background()
  344. client, err := datastore.NewClient(ctx, "project-id")
  345. if err != nil {
  346. // TODO: Handle error.
  347. }
  348. var posts []*Post
  349. keys, err := client.GetAll(ctx, datastore.NewQuery("Post"), &posts)
  350. for i, key := range keys {
  351. fmt.Println(key)
  352. fmt.Println(posts[i])
  353. }
  354. }
  355. func ExampleClient_Mutate() {
  356. ctx := context.Background()
  357. client, err := datastore.NewClient(ctx, "project-id")
  358. if err != nil {
  359. // TODO: Handle error.
  360. }
  361. key1 := datastore.NameKey("Post", "post1", nil)
  362. key2 := datastore.NameKey("Post", "post2", nil)
  363. key3 := datastore.NameKey("Post", "post3", nil)
  364. key4 := datastore.NameKey("Post", "post4", nil)
  365. _, err = client.Mutate(ctx,
  366. datastore.NewInsert(key1, Post{Title: "Post 1"}),
  367. datastore.NewUpsert(key2, Post{Title: "Post 2"}),
  368. datastore.NewUpdate(key3, Post{Title: "Post 3"}),
  369. datastore.NewDelete(key4))
  370. if err != nil {
  371. // TODO: Handle error.
  372. }
  373. }
  374. func ExampleCommit_Key() {
  375. ctx := context.Background()
  376. client, err := datastore.NewClient(ctx, "")
  377. if err != nil {
  378. // TODO: Handle error.
  379. }
  380. var pk1, pk2 *datastore.PendingKey
  381. // Create two posts in a single transaction.
  382. commit, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
  383. var err error
  384. pk1, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 1", PublishedAt: time.Now()})
  385. if err != nil {
  386. return err
  387. }
  388. pk2, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 2", PublishedAt: time.Now()})
  389. if err != nil {
  390. return err
  391. }
  392. return nil
  393. })
  394. if err != nil {
  395. // TODO: Handle error.
  396. }
  397. // Now pk1, pk2 are valid PendingKeys. Let's convert them into real keys
  398. // using the Commit object.
  399. k1 := commit.Key(pk1)
  400. k2 := commit.Key(pk2)
  401. fmt.Println(k1, k2)
  402. }
  403. func ExampleIterator_Next() {
  404. ctx := context.Background()
  405. client, err := datastore.NewClient(ctx, "project-id")
  406. if err != nil {
  407. // TODO: Handle error.
  408. }
  409. it := client.Run(ctx, datastore.NewQuery("Post"))
  410. for {
  411. var p Post
  412. key, err := it.Next(&p)
  413. if err == iterator.Done {
  414. break
  415. }
  416. if err != nil {
  417. // TODO: Handle error.
  418. }
  419. fmt.Println(key, p)
  420. }
  421. }
  422. func ExampleIterator_Cursor() {
  423. ctx := context.Background()
  424. client, err := datastore.NewClient(ctx, "project-id")
  425. if err != nil {
  426. // TODO: Handle error.
  427. }
  428. it := client.Run(ctx, datastore.NewQuery("Post"))
  429. for {
  430. var p Post
  431. _, err := it.Next(&p)
  432. if err == iterator.Done {
  433. break
  434. }
  435. if err != nil {
  436. // TODO: Handle error.
  437. }
  438. fmt.Println(p)
  439. cursor, err := it.Cursor()
  440. if err != nil {
  441. // TODO: Handle error.
  442. }
  443. // When printed, a cursor will display as a string that can be passed
  444. // to datastore.NewCursor.
  445. fmt.Printf("to resume with this post, use cursor %s\n", cursor)
  446. }
  447. }
  448. func ExampleDecodeCursor() {
  449. // See Query.Start for a fuller example of DecodeCursor.
  450. // getCursor represents a function that returns a cursor from a previous
  451. // iteration in string form.
  452. cursorString := getCursor()
  453. cursor, err := datastore.DecodeCursor(cursorString)
  454. if err != nil {
  455. // TODO: Handle error.
  456. }
  457. _ = cursor // TODO: Use the cursor with Query.Start or Query.End.
  458. }
  459. func getCursor() string { return "" }
  460. func ExampleQuery_Start() {
  461. // This example demonstrates how to use cursors and Query.Start
  462. // to resume an iteration.
  463. ctx := context.Background()
  464. client, err := datastore.NewClient(ctx, "project-id")
  465. if err != nil {
  466. // TODO: Handle error.
  467. }
  468. // getCursor represents a function that returns a cursor from a previous
  469. // iteration in string form.
  470. cursorString := getCursor()
  471. cursor, err := datastore.DecodeCursor(cursorString)
  472. if err != nil {
  473. // TODO: Handle error.
  474. }
  475. it := client.Run(ctx, datastore.NewQuery("Post").Start(cursor))
  476. _ = it // TODO: Use iterator.
  477. }
  478. func ExampleLoadStruct() {
  479. type Player struct {
  480. User string
  481. Score int
  482. }
  483. // Normally LoadStruct would only be used inside a custom implementation of
  484. // PropertyLoadSaver; this is for illustrative purposes only.
  485. props := []datastore.Property{
  486. {Name: "User", Value: "Alice"},
  487. {Name: "Score", Value: int64(97)},
  488. }
  489. var p Player
  490. if err := datastore.LoadStruct(&p, props); err != nil {
  491. // TODO: Handle error.
  492. }
  493. fmt.Println(p)
  494. // Output: {Alice 97}
  495. }
  496. func ExampleSaveStruct() {
  497. type Player struct {
  498. User string
  499. Score int
  500. }
  501. p := &Player{
  502. User: "Alice",
  503. Score: 97,
  504. }
  505. props, err := datastore.SaveStruct(p)
  506. if err != nil {
  507. // TODO: Handle error.
  508. }
  509. fmt.Println(props)
  510. // TODO(jba): make this output stable: Output: [{User Alice false} {Score 97 false}]
  511. }