go.mercari.io/datastore@v1.8.2/example_test.go (about) 1 package datastore_test 2 3 import ( 4 "context" 5 "fmt" 6 7 "go.mercari.io/datastore" 8 "go.mercari.io/datastore/clouddatastore" 9 "go.mercari.io/datastore/internal/testutils" 10 ) 11 12 func Example_clientGet() { 13 ctx := context.Background() 14 client, err := clouddatastore.FromContext(ctx) 15 if err != nil { 16 panic(err) 17 } 18 defer client.Close() 19 defer testutils.CleanUpAllEntities(ctx, client) 20 21 type Data struct { 22 Name string 23 } 24 25 key := client.IncompleteKey("Data", nil) 26 entity := &Data{Name: "mercari"} 27 key, err = client.Put(ctx, key, entity) 28 if err != nil { 29 panic(err) 30 } 31 32 entity = &Data{} 33 err = client.Get(ctx, key, entity) 34 if err != nil { 35 panic(err) 36 } 37 38 fmt.Println(entity.Name) 39 // Output: mercari 40 } 41 42 func Example_batch() { 43 ctx := context.Background() 44 client, err := clouddatastore.FromContext(ctx) 45 if err != nil { 46 panic(err) 47 } 48 defer client.Close() 49 defer testutils.CleanUpAllEntities(ctx, client) 50 51 type Comment struct { 52 Message string 53 } 54 type Post struct { 55 Content string 56 CommentIDs []int64 `json:"-"` 57 Comments []*Comment `datastore:"-"` 58 } 59 60 // preparing entities 61 for i := 0; i < 4; i++ { 62 post := &Post{Content: fmt.Sprintf("post #%d", i+1)} 63 key, err := client.Put(ctx, client.IncompleteKey("Post", nil), post) 64 if err != nil { 65 panic(err) 66 } 67 68 for j := 0; j < 5; j++ { 69 comment := &Comment{Message: fmt.Sprintf("comment #%d", j+1)} 70 cKey, err := client.Put(ctx, client.IncompleteKey("Comment", nil), comment) 71 if err != nil { 72 panic(err) 73 } 74 75 post.CommentIDs = append(post.CommentIDs, cKey.ID()) 76 } 77 _, err = client.Put(ctx, key, post) 78 if err != nil { 79 panic(err) 80 } 81 } 82 83 // start fetching... 84 posts := make([]*Post, 0) 85 _, err = client.GetAll(ctx, client.NewQuery("Post").Order("Content"), &posts) 86 if err != nil { 87 panic(err) 88 } 89 90 // Let's batch get! 91 bt := client.Batch() 92 93 for _, post := range posts { 94 comments := make([]*Comment, 0) 95 for _, id := range post.CommentIDs { 96 comment := &Comment{} 97 bt.Get(client.IDKey("Comment", id, nil), comment, nil) 98 comments = append(comments, comment) 99 } 100 post.Comments = comments 101 } 102 103 err = bt.Exec(ctx) 104 if err != nil { 105 panic(err) 106 } 107 108 // check result 109 for _, post := range posts { 110 fmt.Println("Post", post.Content) 111 for _, comment := range post.Comments { 112 fmt.Println("Comment", comment.Message) 113 } 114 } 115 116 // Output: 117 // Post post #1 118 // Comment comment #1 119 // Comment comment #2 120 // Comment comment #3 121 // Comment comment #4 122 // Comment comment #5 123 // Post post #2 124 // Comment comment #1 125 // Comment comment #2 126 // Comment comment #3 127 // Comment comment #4 128 // Comment comment #5 129 // Post post #3 130 // Comment comment #1 131 // Comment comment #2 132 // Comment comment #3 133 // Comment comment #4 134 // Comment comment #5 135 // Post post #4 136 // Comment comment #1 137 // Comment comment #2 138 // Comment comment #3 139 // Comment comment #4 140 // Comment comment #5 141 } 142 143 func Example_batchWithBatchErrHandler() { 144 ctx := context.Background() 145 client, err := clouddatastore.FromContext(ctx) 146 if err != nil { 147 panic(err) 148 } 149 defer client.Close() 150 defer testutils.CleanUpAllEntities(ctx, client) 151 152 type Comment struct { 153 Message string 154 } 155 156 // preparing entities... 157 // Put ID: 2, 4 into Datastore. 158 var keys []datastore.Key 159 for i := 1; i <= 5; i++ { 160 key := client.IDKey("Comment", int64(i), nil) 161 keys = append(keys, key) 162 163 comment := &Comment{Message: fmt.Sprintf("comment #%d", i)} 164 if i%2 == 0 { 165 _, err = client.Put(ctx, key, comment) 166 if err != nil { 167 panic(err) 168 } 169 } 170 } 171 172 // Let's batch get! 173 bt := client.Batch() 174 175 var comments []*Comment 176 for _, key := range keys { 177 comment := &Comment{} 178 179 bt.Get(key, comment, func(err error) error { 180 if err == datastore.ErrNoSuchEntity { 181 // ignore ErrNoSuchEntity 182 return nil 183 } else if err != nil { 184 return err 185 } 186 187 comments = append(comments, comment) 188 189 return nil 190 }) 191 } 192 193 err = bt.Exec(ctx) 194 if err != nil { 195 panic(err) 196 } 197 198 // check result 199 for _, comment := range comments { 200 fmt.Println("Comment", comment.Message) 201 } 202 203 // Output: 204 // Comment comment #2 205 // Comment comment #4 206 } 207 208 var _ datastore.PropertyTranslator = UserID(0) 209 var _ datastore.PropertyTranslator = UserIDs(nil) 210 211 type UserID int64 212 type UserIDs []UserID 213 214 type contextClient struct{} 215 216 func (id UserID) ToPropertyValue(ctx context.Context) (interface{}, error) { 217 // When putting to Datastore, convert to datastore.Key 218 client := ctx.Value(contextClient{}).(datastore.Client) 219 key := client.IDKey("User", int64(id), nil) 220 return key, nil 221 } 222 223 func (id UserID) FromPropertyValue(ctx context.Context, p datastore.Property) (dst interface{}, err error) { 224 // When getting from Datastore, convert from datastore.Key 225 key, ok := p.Value.(datastore.Key) 226 if !ok { 227 return nil, datastore.ErrInvalidEntityType 228 } 229 return UserID(key.ID()), nil 230 } 231 232 func (ids UserIDs) ToPropertyValue(ctx context.Context) (interface{}, error) { 233 // When putting to Datastore, convert to []datastore.Key 234 client := ctx.Value(contextClient{}).(datastore.Client) 235 keys := make([]datastore.Key, 0, len(ids)) 236 for _, id := range ids { 237 keys = append(keys, client.IDKey("User", int64(id), nil)) 238 } 239 return keys, nil 240 } 241 242 func (ids UserIDs) FromPropertyValue(ctx context.Context, p datastore.Property) (dst interface{}, err error) { 243 // When getting from Datastore, convert from datastore.Key 244 keys, ok := p.Value.([]datastore.Key) 245 if !ok { 246 return nil, datastore.ErrInvalidEntityType 247 } 248 newIDs := make(UserIDs, 0, len(keys)) 249 for _, key := range keys { 250 newIDs = append(ids, UserID(key.ID())) 251 } 252 return newIDs, nil 253 } 254 255 func ExamplePropertyTranslator() { 256 ctx := context.Background() 257 client, err := clouddatastore.FromContext(ctx) 258 if err != nil { 259 panic(err) 260 } 261 defer client.Close() 262 defer testutils.CleanUpAllEntities(ctx, client) 263 264 ctx = context.WithValue(ctx, contextClient{}, client) 265 266 // Each fields are saved as datastore.Key and [] datastore.Key on Datastore. 267 type Group struct { 268 OwnerID UserID 269 MemberIDs UserIDs 270 } 271 272 entity, err := datastore.SaveEntity( 273 ctx, client.IncompleteKey("Group", nil), 274 &Group{ 275 OwnerID: 147, 276 MemberIDs: UserIDs{147, 258, 369}, 277 }, 278 ) 279 if err != nil { 280 panic(err) 281 } 282 283 if key, ok := entity.Properties[0].Value.(datastore.Key); !ok { 284 panic("unexpected state") 285 } else { 286 fmt.Println("OwnerID", key.ID()) 287 } 288 if keys, ok := entity.Properties[1].Value.([]datastore.Key); !ok { 289 panic("unexpected state") 290 } else { 291 for _, key := range keys { 292 fmt.Println("MemberID", key.ID()) 293 } 294 } 295 296 // Output: OwnerID 147 297 // MemberID 147 298 // MemberID 258 299 // MemberID 369 300 }