16
16
17
17
package com .google .datastore .snippets ;
18
18
19
+ import static java .util .Calendar .DECEMBER ;
20
+ import static java .util .Calendar .JANUARY ;
19
21
import static org .junit .Assert .assertEquals ;
20
22
import static org .junit .Assert .assertFalse ;
21
23
import static org .junit .Assert .assertNotNull ;
22
24
import static org .junit .Assert .assertNull ;
23
25
24
- import com .google .common .collect .HashMultimap ;
25
26
import com .google .common .collect .ImmutableList ;
27
+ import com .google .common .collect .ImmutableSet ;
26
28
import com .google .common .collect .Iterators ;
27
- import com .google .common .collect .Multimap ;
28
- import com .google .gcloud .datastore .Batch ;
29
29
import com .google .gcloud .datastore .Cursor ;
30
30
import com .google .gcloud .datastore .Datastore ;
31
31
import com .google .gcloud .datastore .DatastoreException ;
46
46
import com .google .gcloud .datastore .StructuredQuery ;
47
47
import com .google .gcloud .datastore .StructuredQuery .CompositeFilter ;
48
48
import com .google .gcloud .datastore .StructuredQuery .OrderBy ;
49
+ import com .google .gcloud .datastore .StructuredQuery .Projection ;
49
50
import com .google .gcloud .datastore .StructuredQuery .PropertyFilter ;
50
51
import com .google .gcloud .datastore .Transaction ;
51
52
import com .google .gcloud .datastore .Value ;
61
62
import java .io .IOException ;
62
63
import java .util .ArrayList ;
63
64
import java .util .Calendar ;
65
+ import java .util .Collection ;
66
+ import java .util .Collections ;
67
+ import java .util .HashMap ;
68
+ import java .util .HashSet ;
64
69
import java .util .Iterator ;
65
70
import java .util .LinkedList ;
66
71
import java .util .List ;
72
+ import java .util .Map ;
67
73
import java .util .TimeZone ;
68
74
69
75
/**
@@ -121,11 +127,11 @@ public void setUp() {
121
127
taskKey = keyFactory .newKey ("some-arbitrary-key" );
122
128
testEntity = Entity .builder (taskKey , TEST_FULL_ENTITY ).build ();
123
129
Calendar calendar = Calendar .getInstance (TimeZone .getTimeZone ("UTC" ));
124
- calendar .set (1990 , 1 , 1 );
130
+ calendar .set (1990 , JANUARY , 1 );
125
131
startDate = DateTime .copyFrom (calendar );
126
- calendar .set (2000 , 1 , 1 );
132
+ calendar .set (2000 , JANUARY , 1 );
127
133
endDate = DateTime .copyFrom (calendar );
128
- calendar .set (1999 , 12 , 31 );
134
+ calendar .set (1999 , DECEMBER , 31 );
129
135
includedDate = DateTime .copyFrom (calendar );
130
136
}
131
137
@@ -158,18 +164,18 @@ public void testIncompleteKey() {
158
164
@ Test
159
165
public void testNamedKey () {
160
166
// [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" );
163
168
// [END named_key]
164
169
assertValidKey (taskKey );
165
170
}
166
171
167
172
@ Test
168
173
public void testKeyWithParent () {
169
174
// [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" );
173
179
// [END key_with_parent]
174
180
assertValidKey (taskKey );
175
181
}
@@ -249,8 +255,7 @@ public void testBasicEntity() {
249
255
@ Test
250
256
public void testUpsert () {
251
257
// [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 ();
254
259
datastore .put (task );
255
260
// [END upsert]
256
261
assertEquals (task , datastore .get (task .key ()));
@@ -259,10 +264,9 @@ public void testUpsert() {
259
264
@ Test
260
265
public void testInsert () {
261
266
// [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 ();
264
268
// [END insert]
265
- assertEquals (task , datastore .get (taskKey ));
269
+ assertEquals (FullEntity . builder ( taskKey ). build () , datastore .get (taskKey ));
266
270
}
267
271
268
272
@ Test
@@ -325,13 +329,12 @@ public void testBatchUpsert() {
325
329
.set ("priority" , 5 )
326
330
.set ("description" , "Integrate Cloud Datastore" )
327
331
.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 ();
332
335
// [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 ));
335
338
}
336
339
337
340
@ Test
@@ -352,27 +355,26 @@ public void testBatchDelete() {
352
355
Key taskKey2 = keyFactory .newKey (2 );
353
356
setUpBatchTests (taskKey1 , taskKey2 );
354
357
// [START batch_delete]
355
- Batch batch = datastore .newBatch ();
356
- batch .delete (taskKey1 , taskKey2 );
357
- batch .submit ();
358
+ datastore .delete (taskKey1 , taskKey2 );
358
359
// [END batch_delete]
359
360
assertNull (datastore .get (taskKey1 ));
360
361
assertNull (datastore .get (taskKey2 ));
361
362
}
362
363
363
364
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 )
367
370
.set ("type" , "Personal" )
368
371
.set ("done" , false )
369
372
.set ("completed" , false )
370
373
.set ("priority" , 4 )
371
374
.set ("created" , includedDate )
372
375
.set ("percent_complete" , 10.0 )
373
376
.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" ))
376
378
.build ());
377
379
}
378
380
@@ -510,9 +512,7 @@ public void testProjectionQuery() {
510
512
// [START projection_query]
511
513
Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
512
514
.kind ("Task" )
513
- .projection (
514
- StructuredQuery .Projection .property ("priority" ),
515
- StructuredQuery .Projection .property ("percent_complete" ))
515
+ .projection (Projection .property ("priority" ), Projection .property ("percent_complete" ))
516
516
.build ();
517
517
// [END projection_query]
518
518
assertValidQuery (query );
@@ -523,13 +523,11 @@ public void testRunProjectionQuery() {
523
523
setUpQueryTests ();
524
524
Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
525
525
.kind ("Task" )
526
- .projection (
527
- StructuredQuery .Projection .property ("priority" ),
528
- StructuredQuery .Projection .property ("percent_complete" ))
526
+ .projection (Projection .property ("priority" ), Projection .property ("percent_complete" ))
529
527
.build ();
528
+ // [START run_query_projection]
530
529
List <Long > priorities = new LinkedList <>();
531
530
List <Double > percentCompletes = new LinkedList <>();
532
- // [START run_query_projection]
533
531
QueryResults <ProjectionEntity > tasks = datastore .run (query );
534
532
while (tasks .hasNext ()) {
535
533
ProjectionEntity task = tasks .next ();
@@ -567,8 +565,7 @@ public void testDistinctQuery() {
567
565
// [START distinct_query]
568
566
Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
569
567
.kind ("Task" )
570
- .projection (StructuredQuery .Projection .property ("type" ),
571
- StructuredQuery .Projection .property ("priority" ))
568
+ .projection (Projection .property ("type" ), Projection .property ("priority" ))
572
569
.groupBy ("type" , "priority" )
573
570
.orderBy (OrderBy .asc ("type" ), OrderBy .asc ("priority" ))
574
571
.build ();
@@ -582,8 +579,7 @@ public void testDistinctOnQuery() {
582
579
// [START distinct_on_query]
583
580
Query <ProjectionEntity > query = Query .projectionEntityQueryBuilder ()
584
581
.kind ("Task" )
585
- .projection (StructuredQuery .Projection .property ("type" ),
586
- StructuredQuery .Projection .first ("priority" ))
582
+ .projection (Projection .property ("type" ), Projection .first ("priority" ))
587
583
.groupBy ("type" )
588
584
.orderBy (OrderBy .asc ("type" ), OrderBy .asc ("priority" ))
589
585
.build ();
@@ -719,17 +715,12 @@ private Cursor cursorPaging(int pageSize, Cursor pageCursor) {
719
715
queryBuilder .startCursor (pageCursor );
720
716
}
721
717
QueryResults <Entity > tasks = datastore .run (queryBuilder .build ());
722
- Entity task = null ;
718
+ Entity task ;
723
719
while (tasks .hasNext ()) {
724
720
task = tasks .next ();
725
721
// do something with the task
726
722
}
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 ();
733
724
// [END cursor_paging]
734
725
return nextPageCursor ;
735
726
}
@@ -792,10 +783,11 @@ public void testTransactionalUpdate() {
792
783
void transferFunds (Key fromKey , Key toKey , long amount ) {
793
784
Transaction txn = datastore .newTransaction ();
794
785
try {
795
- Entity from = txn .get (fromKey );
786
+ List <Entity > entities = txn .fetch (fromKey , toKey );
787
+ Entity from = entities .get (0 );
796
788
Entity updatedFrom =
797
789
Entity .builder (from ).set ("balance" , from .getLong ("balance" ) - amount ).build ();
798
- Entity to = txn .get (toKey );
790
+ Entity to = entities .get (1 );
799
791
Entity updatedTo = Entity .builder (to ).set ("balance" , to .getLong ("balance" ) + amount ).build ();
800
792
txn .put (updatedFrom , updatedTo );
801
793
txn .commit ();
@@ -825,6 +817,7 @@ public void testTransactionalRetry() {
825
817
--retries ;
826
818
}
827
819
}
820
+ // Retry handling can also be configured and automatically applied using gcloud-java.
828
821
// [END transactional_retry]
829
822
assertSuccessfulTransfer (keys .get (0 ), keys .get (1 ));
830
823
}
@@ -835,9 +828,8 @@ public void testTransactionalGetOrCreate() {
835
828
Entity task ;
836
829
Transaction txn = datastore .newTransaction ();
837
830
try {
838
- try {
839
- task = txn .get (taskKey );
840
- } catch (DatastoreException e ) {
831
+ task = txn .get (taskKey );
832
+ if (task == null ) {
841
833
task = Entity .builder (taskKey ).build ();
842
834
txn .put (task );
843
835
txn .commit ();
@@ -922,22 +914,22 @@ public void testPropertyRunQuery() {
922
914
// [START property_run_query]
923
915
Query <Key > query = Query .keyQueryBuilder ().kind ("__property__" ).build ();
924
916
QueryResults <Key > results = datastore .run (query );
925
- Multimap <String , String > propertiesByKind = HashMultimap . create ();
917
+ Map <String , Collection < String >> propertiesByKind = new HashMap <> ();
926
918
while (results .hasNext ()) {
927
919
Key property = results .next ();
928
920
String kind = property .ancestors ().get (property .ancestors ().size () - 1 ).name ();
929
921
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 );
931
926
}
932
927
// [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" ));
941
933
assertEquals (expected , propertiesByKind );
942
934
}
943
935
@@ -951,24 +943,27 @@ public void testPropertyByKindRunQuery() {
951
943
.filter (PropertyFilter .hasAncestor (key ))
952
944
.build ();
953
945
QueryResults <Entity > results = datastore .run (query );
954
- Multimap <String , String > representationsByProperty = HashMultimap . create ();
946
+ Map <String , Collection < String >> representationsByProperty = new HashMap <> ();
955
947
while (results .hasNext ()) {
956
948
Entity property = results .next ();
957
949
String propertyName = property .key ().name ();
958
950
List <? extends Value <?>> representations = property .getList ("property_representation" );
951
+ if (!representationsByProperty .containsKey (propertyName )) {
952
+ representationsByProperty .put (propertyName , new HashSet <String >());
953
+ }
959
954
for (Value <?> value : representations ) {
960
- representationsByProperty .put (propertyName , (String ) value .get ());
955
+ representationsByProperty .get (propertyName ). add ( (String ) value .get ());
961
956
}
962
957
}
963
958
// [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" ) );
972
967
assertEquals (expected , representationsByProperty );
973
968
}
974
969
@@ -985,19 +980,20 @@ public void testPropertyFilteringRunQuery() {
985
980
.kind ("__property__" )
986
981
.filter (PropertyFilter .ge ("__key__" , key ))
987
982
.build ();
988
- Multimap <String , String > propertiesByKind = HashMultimap . create ();
983
+ Map <String , Collection < String >> propertiesByKind = new HashMap <> ();
989
984
QueryResults <Key > results = datastore .run (query );
990
985
while (results .hasNext ()) {
991
986
Key property = results .next ();
992
987
String kind = property .ancestors ().get (property .ancestors ().size () - 1 ).name ();
993
988
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 );
995
993
}
996
994
// [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" ));
1001
997
assertEquals (expected , propertiesByKind );
1002
998
}
1003
999
0 commit comments