1616
1717package com .google .datastore .snippets ;
1818
19+ import static java .util .Calendar .DECEMBER ;
20+ import static java .util .Calendar .JANUARY ;
1921import static org .junit .Assert .assertEquals ;
2022import static org .junit .Assert .assertFalse ;
2123import static org .junit .Assert .assertNotNull ;
2224import static org .junit .Assert .assertNull ;
2325
24- import com .google .common .collect .HashMultimap ;
2526import com .google .common .collect .ImmutableList ;
27+ import com .google .common .collect .ImmutableSet ;
2628import com .google .common .collect .Iterators ;
27- import com .google .common .collect .Multimap ;
28- import com .google .gcloud .datastore .Batch ;
2929import com .google .gcloud .datastore .Cursor ;
3030import com .google .gcloud .datastore .Datastore ;
3131import com .google .gcloud .datastore .DatastoreException ;
4646import com .google .gcloud .datastore .StructuredQuery ;
4747import com .google .gcloud .datastore .StructuredQuery .CompositeFilter ;
4848import com .google .gcloud .datastore .StructuredQuery .OrderBy ;
49+ import com .google .gcloud .datastore .StructuredQuery .Projection ;
4950import com .google .gcloud .datastore .StructuredQuery .PropertyFilter ;
5051import com .google .gcloud .datastore .Transaction ;
5152import com .google .gcloud .datastore .Value ;
6162import java .io .IOException ;
6263import java .util .ArrayList ;
6364import java .util .Calendar ;
65+ import java .util .Collection ;
66+ import java .util .Collections ;
67+ import java .util .HashMap ;
68+ import java .util .HashSet ;
6469import java .util .Iterator ;
6570import java .util .LinkedList ;
6671import java .util .List ;
72+ import java .util .Map ;
6773import java .util .TimeZone ;
6874
6975/**
@@ -121,11 +127,11 @@ public void setUp() {
121127 taskKey = keyFactory .newKey ("some-arbitrary-key" );
122128 testEntity = Entity .builder (taskKey , TEST_FULL_ENTITY ).build ();
123129 Calendar calendar = Calendar .getInstance (TimeZone .getTimeZone ("UTC" ));
124- calendar .set (1990 , 1 , 1 );
130+ calendar .set (1990 , JANUARY , 1 );
125131 startDate = DateTime .copyFrom (calendar );
126- calendar .set (2000 , 1 , 1 );
132+ calendar .set (2000 , JANUARY , 1 );
127133 endDate = DateTime .copyFrom (calendar );
128- calendar .set (1999 , 12 , 31 );
134+ calendar .set (1999 , DECEMBER , 31 );
129135 includedDate = DateTime .copyFrom (calendar );
130136 }
131137
@@ -158,18 +164,18 @@ public void testIncompleteKey() {
158164 @ Test
159165 public void testNamedKey () {
160166 // [START named_key]
161- KeyFactory keyFactory = datastore .newKeyFactory ().kind ("Task" );
162- Key taskKey = keyFactory .newKey ("sampleTask" );
167+ Key taskKey = datastore .newKeyFactory ().kind ("Task" ).newKey ("sampleTask" );
163168 // [END named_key]
164169 assertValidKey (taskKey );
165170 }
166171
167172 @ Test
168173 public void testKeyWithParent () {
169174 // [START key_with_parent]
170- KeyFactory keyFactory =
171- datastore .newKeyFactory ().ancestors (PathElement .of ("TaskList" , "default" )).kind ("Task" );
172- Key taskKey = keyFactory .newKey ("sampleTask" );
175+ Key taskKey = datastore .newKeyFactory ()
176+ .ancestors (PathElement .of ("TaskList" , "default" ))
177+ .kind ("Task" )
178+ .newKey ("sampleTask" );
173179 // [END key_with_parent]
174180 assertValidKey (taskKey );
175181 }
@@ -249,8 +255,7 @@ public void testBasicEntity() {
249255 @ Test
250256 public void testUpsert () {
251257 // [START upsert]
252- Key taskKey = datastore .allocateId (keyFactory .newKey ());
253- Entity task = Entity .builder (taskKey ).build ();
258+ Entity task = Entity .builder (keyFactory .newKey ("sampleTask" )).build ();
254259 datastore .put (task );
255260 // [END upsert]
256261 assertEquals (task , datastore .get (task .key ()));
@@ -259,10 +264,9 @@ public void testUpsert() {
259264 @ Test
260265 public void testInsert () {
261266 // [START insert]
262- Entity task = Entity .builder (taskKey ).build ();
263- Key taskKey = datastore .add (task ).key ();
267+ Key taskKey = datastore .add (FullEntity .builder (keyFactory .newKey ()).build ()).key ();
264268 // [END insert]
265- assertEquals (task , datastore .get (taskKey ));
269+ assertEquals (FullEntity . builder ( taskKey ). build () , datastore .get (taskKey ));
266270 }
267271
268272 @ Test
@@ -325,13 +329,12 @@ public void testBatchUpsert() {
325329 .set ("priority" , 5 )
326330 .set ("description" , "Integrate Cloud Datastore" )
327331 .build ();
328- Batch batch = datastore .newBatch ();
329- batch .addWithDeferredIdAllocation (task1 , task2 );
330- Batch .Response response = batch .submit ();
331- List <Key > taskKeys = response .generatedKeys (); // keys listed in order of insertion
332+ List <Entity > tasks = datastore .add (task1 , task2 );
333+ Key taskKey1 = tasks .get (0 ).key ();
334+ Key taskKey2 = tasks .get (1 ).key ();
332335 // [END batch_upsert]
333- assertEquals (Entity .builder (taskKeys . get ( 0 ) , task1 ).build (), datastore .get (taskKeys . get ( 0 ) ));
334- assertEquals (Entity .builder (taskKeys . get ( 1 ) , task2 ).build (), datastore .get (taskKeys . get ( 1 ) ));
336+ assertEquals (Entity .builder (taskKey1 , task1 ).build (), datastore .get (taskKey1 ));
337+ assertEquals (Entity .builder (taskKey2 , task2 ).build (), datastore .get (taskKey2 ));
335338 }
336339
337340 @ Test
@@ -352,27 +355,26 @@ public void testBatchDelete() {
352355 Key taskKey2 = keyFactory .newKey (2 );
353356 setUpBatchTests (taskKey1 , taskKey2 );
354357 // [START batch_delete]
355- Batch batch = datastore .newBatch ();
356- batch .delete (taskKey1 , taskKey2 );
357- batch .submit ();
358+ datastore .delete (taskKey1 , taskKey2 );
358359 // [END batch_delete]
359360 assertNull (datastore .get (taskKey1 ));
360361 assertNull (datastore .get (taskKey2 ));
361362 }
362363
363364 private void setUpQueryTests () {
364- KeyFactory keyFactory =
365- datastore .newKeyFactory ().kind ("Task" ).ancestors (PathElement .of ("TaskList" , "default" ));
366- datastore .put (Entity .builder (keyFactory .newKey ("someTask" ))
365+ Key taskKey = datastore .newKeyFactory ()
366+ .kind ("Task" )
367+ .ancestors (PathElement .of ("TaskList" , "default" ))
368+ .newKey ("someTask" );
369+ datastore .put (Entity .builder (taskKey )
367370 .set ("type" , "Personal" )
368371 .set ("done" , false )
369372 .set ("completed" , false )
370373 .set ("priority" , 4 )
371374 .set ("created" , includedDate )
372375 .set ("percent_complete" , 10.0 )
373376 .set ("description" , StringValue .builder ("Learn Cloud Datastore" ).indexed (false ).build ())
374- .set ("tag" , ImmutableList .of (StringValue .of ("fun" ), StringValue .of ("l" ),
375- StringValue .of ("programming" )))
377+ .set ("tag" , StringValue .of ("fun" ), StringValue .of ("l" ), StringValue .of ("programming" ))
376378 .build ());
377379 }
378380
@@ -510,9 +512,7 @@ public void testProjectionQuery() {
510512 // [START projection_query]
511513 Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
512514 .kind ("Task" )
513- .projection (
514- StructuredQuery .Projection .property ("priority" ),
515- StructuredQuery .Projection .property ("percent_complete" ))
515+ .projection (Projection .property ("priority" ), Projection .property ("percent_complete" ))
516516 .build ();
517517 // [END projection_query]
518518 assertValidQuery (query );
@@ -523,13 +523,11 @@ public void testRunProjectionQuery() {
523523 setUpQueryTests ();
524524 Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
525525 .kind ("Task" )
526- .projection (
527- StructuredQuery .Projection .property ("priority" ),
528- StructuredQuery .Projection .property ("percent_complete" ))
526+ .projection (Projection .property ("priority" ), Projection .property ("percent_complete" ))
529527 .build ();
528+ // [START run_query_projection]
530529 List <Long > priorities = new LinkedList <>();
531530 List <Double > percentCompletes = new LinkedList <>();
532- // [START run_query_projection]
533531 QueryResults <ProjectionEntity > tasks = datastore .run (query );
534532 while (tasks .hasNext ()) {
535533 ProjectionEntity task = tasks .next ();
@@ -567,8 +565,7 @@ public void testDistinctQuery() {
567565 // [START distinct_query]
568566 Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
569567 .kind ("Task" )
570- .projection (StructuredQuery .Projection .property ("type" ),
571- StructuredQuery .Projection .property ("priority" ))
568+ .projection (Projection .property ("type" ), Projection .property ("priority" ))
572569 .groupBy ("type" , "priority" )
573570 .orderBy (OrderBy .asc ("type" ), OrderBy .asc ("priority" ))
574571 .build ();
@@ -582,8 +579,7 @@ public void testDistinctOnQuery() {
582579 // [START distinct_on_query]
583580 Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
584581 .kind ("Task" )
585- .projection (StructuredQuery .Projection .property ("type" ),
586- StructuredQuery .Projection .first ("priority" ))
582+ .projection (Projection .property ("type" ), Projection .first ("priority" ))
587583 .groupBy ("type" )
588584 .orderBy (OrderBy .asc ("type" ), OrderBy .asc ("priority" ))
589585 .build ();
@@ -719,17 +715,12 @@ private Cursor cursorPaging(int pageSize, Cursor pageCursor) {
719715 queryBuilder .startCursor (pageCursor );
720716 }
721717 QueryResults <Entity > tasks = datastore .run (queryBuilder .build ());
722- Entity task = null ;
718+ Entity task ;
723719 while (tasks .hasNext ()) {
724720 task = tasks .next ();
725721 // do something with the task
726722 }
727- Cursor nextPageCursor = null ;
728- if (task != null && tasks .cursorAfter () != null ) {
729- nextPageCursor = tasks .cursorAfter ();
730- // Call nextPageCursor.toUrlSafe() if you want an encoded cursor that can be used as part of a
731- // URL.
732- }
723+ Cursor nextPageCursor = tasks .cursorAfter ();
733724 // [END cursor_paging]
734725 return nextPageCursor ;
735726 }
@@ -792,10 +783,11 @@ public void testTransactionalUpdate() {
792783 void transferFunds (Key fromKey , Key toKey , long amount ) {
793784 Transaction txn = datastore .newTransaction ();
794785 try {
795- Entity from = txn .get (fromKey );
786+ List <Entity > entities = txn .fetch (fromKey , toKey );
787+ Entity from = entities .get (0 );
796788 Entity updatedFrom =
797789 Entity .builder (from ).set ("balance" , from .getLong ("balance" ) - amount ).build ();
798- Entity to = txn .get (toKey );
790+ Entity to = entities .get (1 );
799791 Entity updatedTo = Entity .builder (to ).set ("balance" , to .getLong ("balance" ) + amount ).build ();
800792 txn .put (updatedFrom , updatedTo );
801793 txn .commit ();
@@ -825,6 +817,7 @@ public void testTransactionalRetry() {
825817 --retries ;
826818 }
827819 }
820+ // Retry handling can also be configured and automatically applied using gcloud-java.
828821 // [END transactional_retry]
829822 assertSuccessfulTransfer (keys .get (0 ), keys .get (1 ));
830823 }
@@ -835,9 +828,8 @@ public void testTransactionalGetOrCreate() {
835828 Entity task ;
836829 Transaction txn = datastore .newTransaction ();
837830 try {
838- try {
839- task = txn .get (taskKey );
840- } catch (DatastoreException e ) {
831+ task = txn .get (taskKey );
832+ if (task == null ) {
841833 task = Entity .builder (taskKey ).build ();
842834 txn .put (task );
843835 txn .commit ();
@@ -922,22 +914,22 @@ public void testPropertyRunQuery() {
922914 // [START property_run_query]
923915 Query <Key > query = Query .keyQueryBuilder ().kind ("__property__" ).build ();
924916 QueryResults <Key > results = datastore .run (query );
925- Multimap <String , String > propertiesByKind = HashMultimap . create ();
917+ Map <String , Collection < String >> propertiesByKind = new HashMap <> ();
926918 while (results .hasNext ()) {
927919 Key property = results .next ();
928920 String kind = property .ancestors ().get (property .ancestors ().size () - 1 ).name ();
929921 String propertyName = property .name ();
930- propertiesByKind .put (kind , propertyName );
922+ if (!propertiesByKind .containsKey (kind )) {
923+ propertiesByKind .put (kind , new HashSet <String >());
924+ }
925+ propertiesByKind .get (kind ).add (propertyName );
931926 }
932927 // [END property_run_query]
933- Multimap <String , String > expected = HashMultimap .create ();
934- expected .put ("Task" , "type" );
935- expected .put ("Task" , "done" );
936- expected .put ("Task" , "completed" );
937- expected .put ("Task" , "priority" );
938- expected .put ("Task" , "created" );
939- expected .put ("Task" , "percent_complete" );
940- expected .put ("Task" , "tag" );
928+ Map <String , Collection <String >> expected = new HashMap <>();
929+ expected .put (
930+ "Task" ,
931+ ImmutableSet .of (
932+ "done" , "type" , "done" , "completed" , "priority" , "created" , "percent_complete" , "tag" ));
941933 assertEquals (expected , propertiesByKind );
942934 }
943935
@@ -951,24 +943,27 @@ public void testPropertyByKindRunQuery() {
951943 .filter (PropertyFilter .hasAncestor (key ))
952944 .build ();
953945 QueryResults <Entity > results = datastore .run (query );
954- Multimap <String , String > representationsByProperty = HashMultimap . create ();
946+ Map <String , Collection < String >> representationsByProperty = new HashMap <> ();
955947 while (results .hasNext ()) {
956948 Entity property = results .next ();
957949 String propertyName = property .key ().name ();
958950 List <? extends Value <?>> representations = property .getList ("property_representation" );
951+ if (!representationsByProperty .containsKey (propertyName )) {
952+ representationsByProperty .put (propertyName , new HashSet <String >());
953+ }
959954 for (Value <?> value : representations ) {
960- representationsByProperty .put (propertyName , (String ) value .get ());
955+ representationsByProperty .get (propertyName ). add ( (String ) value .get ());
961956 }
962957 }
963958 // [END property_by_kind_run_query]
964- Multimap <String , String > expected = HashMultimap . create ();
965- expected .put ("type" , "STRING" );
966- expected .put ("done" , "BOOLEAN" );
967- expected .put ("completed" , "BOOLEAN" );
968- expected .put ("priority" , "INT64" );
969- expected .put ("created" , "INT64" );
970- expected .put ("percent_complete" , "DOUBLE" );
971- expected .put ("tag" , "STRING" );
959+ Map <String , Collection < String >> expected = new HashMap <> ();
960+ expected .put ("type" , Collections . singleton ( "STRING" ) );
961+ expected .put ("done" , Collections . singleton ( "BOOLEAN" ) );
962+ expected .put ("completed" , Collections . singleton ( "BOOLEAN" ) );
963+ expected .put ("priority" , Collections . singleton ( "INT64" ) );
964+ expected .put ("created" , Collections . singleton ( "INT64" ) );
965+ expected .put ("percent_complete" , Collections . singleton ( "DOUBLE" ) );
966+ expected .put ("tag" , Collections . singleton ( "STRING" ) );
972967 assertEquals (expected , representationsByProperty );
973968 }
974969
@@ -985,19 +980,20 @@ public void testPropertyFilteringRunQuery() {
985980 .kind ("__property__" )
986981 .filter (PropertyFilter .ge ("__key__" , key ))
987982 .build ();
988- Multimap <String , String > propertiesByKind = HashMultimap . create ();
983+ Map <String , Collection < String >> propertiesByKind = new HashMap <> ();
989984 QueryResults <Key > results = datastore .run (query );
990985 while (results .hasNext ()) {
991986 Key property = results .next ();
992987 String kind = property .ancestors ().get (property .ancestors ().size () - 1 ).name ();
993988 String propertyName = property .name ();
994- propertiesByKind .put (kind , propertyName );
989+ if (!propertiesByKind .containsKey (kind )) {
990+ propertiesByKind .put (kind , new HashSet <String >());
991+ }
992+ propertiesByKind .get (kind ).add (propertyName );
995993 }
996994 // [END property_filtering_run_query]
997- Multimap <String , String > expected = HashMultimap .create ();
998- expected .put ("Task" , "priority" );
999- expected .put ("Task" , "tag" );
1000- expected .put ("Task" , "type" );
995+ Map <String , Collection <String >> expected = new HashMap <>();
996+ expected .put ("Task" , ImmutableSet .of ("priority" , "tag" , "type" ));
1001997 assertEquals (expected , propertiesByKind );
1002998 }
1003999
0 commit comments