@@ -161,6 +161,12 @@ public static class AnnotatedRecordStartAtNegativeOne {
161161 public void setAttribute (String attribute ) { this .attribute = attribute ; }
162162 }
163163
164+
165+ private static final int CUSTOM_START_AT = 10 ;
166+ private static final int CUSTOM_INCREMENT_BY = 2 ;
167+ private static final long ANNOTATED_START_AT = 5L ;
168+ private static final long ANNOTATED_INCREMENT_BY = 3L ;
169+
164170 private DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient .builder ()
165171 .dynamoDbClient (getDynamoDbClient ())
166172 .extensions (VersionedRecordExtension .builder ().build ())
@@ -186,6 +192,16 @@ public static class AnnotatedRecordStartAtNegativeOne {
186192 )
187193 .build ();
188194
195+ private DynamoDbEnhancedClient startAtNegativeOneIncrementByTwoClient = DynamoDbEnhancedClient .builder ()
196+ .dynamoDbClient (getDynamoDbClient ())
197+ .extensions (VersionedRecordExtension
198+ .builder ()
199+ .startAt (-1L )
200+ .incrementBy (2L )
201+ .build ()
202+ )
203+ .build ();
204+
189205 private DynamoDbTable <Record > mappedTable = enhancedClient .table (getConcreteTableName ("table-name" ), TABLE_SCHEMA );
190206
191207 private DynamoDbTable <Record > mappedCustomVersionedTable = customVersionedEnhancedClient
@@ -194,6 +210,9 @@ public static class AnnotatedRecordStartAtNegativeOne {
194210 private DynamoDbTable <Record > startAtNegativeOneTable = startAtNegativeOneClient
195211 .table (getConcreteTableName ("startAt-neg-one-table" ), TABLE_SCHEMA );
196212
213+ private DynamoDbTable <Record > startAtNegativeOneIncrementByTwoTable = startAtNegativeOneIncrementByTwoClient
214+ .table (getConcreteTableName ("startAt-neg-one-inc-two-table" ), TABLE_SCHEMA );
215+
197216
198217 private static final TableSchema <AnnotatedRecord > ANNOTATED_TABLE_SCHEMA =
199218 TableSchema .fromBean (AnnotatedRecord .class );
@@ -219,6 +238,7 @@ public void createTable() {
219238 mappedCustomVersionedTable .createTable (r -> r .provisionedThroughput (getDefaultProvisionedThroughput ()));
220239 annotatedTable .createTable (r -> r .provisionedThroughput (getDefaultProvisionedThroughput ()));
221240 startAtNegativeOneTable .createTable (r -> r .provisionedThroughput (getDefaultProvisionedThroughput ()));
241+ startAtNegativeOneIncrementByTwoTable .createTable (r -> r .provisionedThroughput (getDefaultProvisionedThroughput ()));
222242 annotatedStartAtNegativeOneTable .createTable (r -> r .provisionedThroughput (getDefaultProvisionedThroughput ()));
223243 }
224244
@@ -240,6 +260,10 @@ public void deleteTable() {
240260 .tableName (getConcreteTableName ("startAt-neg-one-table" ))
241261 .build ());
242262
263+ getDynamoDbClient ().deleteTable (DeleteTableRequest .builder ()
264+ .tableName (getConcreteTableName ("startAt-neg-one-inc-two-table" ))
265+ .build ());
266+
243267 getDynamoDbClient ().deleteTable (DeleteTableRequest .builder ()
244268 .tableName (getConcreteTableName ("annotated-startAt-neg-one-table" ))
245269 .build ());
@@ -434,12 +458,12 @@ public void customStartAtValueIsUsedForFirstRecord() {
434458 mappedCustomVersionedTable .putItem (r -> r .item (new Record ().setId ("custom-start" ).setAttribute ("test" )));
435459
436460 Record record = mappedCustomVersionedTable .getItem (r -> r .key (k -> k .partitionValue ("custom-start" )));
437- assertThat (record .getVersion (), is (12 ));
461+ assertThat (record .getVersion (), is (CUSTOM_START_AT + CUSTOM_INCREMENT_BY ));
438462 }
439463
440464 @ Test (expected = ConditionalCheckFailedException .class )
441465 public void recordWithVersionBetweenStartAtAndFirstVersionFails () {
442- Record invalidRecord = new Record ().setId ("invalid-version" ).setAttribute ("test" ).setVersion (11 );
466+ Record invalidRecord = new Record ().setId ("invalid-version" ).setAttribute ("test" ).setVersion (CUSTOM_START_AT + 1 );
443467 mappedCustomVersionedTable .putItem (r -> r .item (invalidRecord ));
444468 }
445469
@@ -449,14 +473,14 @@ public void annotationBasedCustomVersioningWorks() {
449473
450474 AnnotatedRecord result = annotatedTable .getItem (r -> r .key (k -> k .partitionValue ("annotated" )));
451475
452- assertThat (result .getVersion (), is (8L ));
476+ assertThat (result .getVersion (), is (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY ));
453477
454478 AnnotatedRecord updated = annotatedTable .updateItem (r -> r .item (new AnnotatedRecord ()
455479 .setId ("annotated" )
456480 .setAttribute ("updated" )
457- .setVersion (8L )));
481+ .setVersion (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY )));
458482
459- assertThat (updated .getVersion (), is (11L ));
483+ assertThat (updated .getVersion (), is (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY + ANNOTATED_INCREMENT_BY ));
460484 }
461485
462486 @ Test
@@ -478,45 +502,45 @@ public void updateItem_existingRecordWithVersionZero_defaultStartAt_shouldSuccee
478502 public void updateItem_existingRecordWithVersionEqualToBuilderStartAt_shouldSucceed () {
479503 Map <String , AttributeValue > item = new HashMap <>();
480504 item .put ("id" , stringValue ("version-ten" ));
481- item .put ("version" , AttributeValue .builder ().n ("10" ).build ());
505+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( CUSTOM_START_AT ) ).build ());
482506
483507 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("table-name2" )).item (item ));
484508
485509 Record retrieved = mappedCustomVersionedTable .getItem (r -> r .key (k -> k .partitionValue ("version-ten" )));
486- assertThat (retrieved .getVersion (), is (10 ));
510+ assertThat (retrieved .getVersion (), is (CUSTOM_START_AT ));
487511
488512 Record updated = mappedCustomVersionedTable .updateItem (retrieved );
489- assertThat (updated .getVersion (), is (12 ));
513+ assertThat (updated .getVersion (), is (CUSTOM_START_AT + CUSTOM_INCREMENT_BY ));
490514 }
491515
492516 @ Test
493517 public void updateItem_existingRecordWithVersionEqualToAnnotationStartAt_shouldSucceed () {
494518 Map <String , AttributeValue > item = new HashMap <>();
495519 item .put ("id" , stringValue ("version-five" ));
496- item .put ("version" , AttributeValue .builder ().n ("5" ).build ());
520+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( ANNOTATED_START_AT ) ).build ());
497521
498522 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("annotated-table" )).item (item ));
499523
500524 AnnotatedRecord retrieved = annotatedTable .getItem (r -> r .key (k -> k .partitionValue ("version-five" )));
501- assertThat (retrieved .getVersion (), is (5L ));
525+ assertThat (retrieved .getVersion (), is (ANNOTATED_START_AT ));
502526
503527 AnnotatedRecord updated = annotatedTable .updateItem (retrieved );
504- assertThat (updated .getVersion (), is (8L ));
528+ assertThat (updated .getVersion (), is (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY ));
505529 }
506530
507531 @ Test
508532 public void putItem_existingRecordWithVersionEqualToStartAt_shouldSucceed () {
509533 Map <String , AttributeValue > item = new HashMap <>();
510534 item .put ("id" , stringValue ("put-version-ten" ));
511- item .put ("version" , AttributeValue .builder ().n ("10" ).build ());
535+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( CUSTOM_START_AT ) ).build ());
512536
513537 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("table-name2" )).item (item ));
514538
515- Record overwrite = new Record ().setId ("put-version-ten" ).setVersion (10 );
539+ Record overwrite = new Record ().setId ("put-version-ten" ).setVersion (CUSTOM_START_AT );
516540 mappedCustomVersionedTable .putItem (overwrite );
517541
518542 Record retrieved = mappedCustomVersionedTable .getItem (r -> r .key (k -> k .partitionValue ("put-version-ten" )));
519- assertThat (retrieved .getVersion (), is (12 ));
543+ assertThat (retrieved .getVersion (), is (CUSTOM_START_AT + CUSTOM_INCREMENT_BY ));
520544 }
521545
522546 @ Test
@@ -567,43 +591,43 @@ public void updateItem_bothBuilderAndAnnotationWithVersionEqualToStartAt_shouldS
567591 Map <String , AttributeValue > item = new HashMap <>();
568592 item .put ("id" , stringValue ("both-config" ));
569593 item .put ("attribute" , stringValue ("initial" ));
570- item .put ("version" , AttributeValue .builder ().n ("5" ).build ());
594+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( ANNOTATED_START_AT ) ).build ());
571595 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("annotated-table" )).item (item ));
572596
573597 AnnotatedRecord retrieved = annotatedTable .getItem (r -> r .key (k -> k .partitionValue ("both-config" )));
574- assertThat (retrieved .getVersion (), is (5L ));
598+ assertThat (retrieved .getVersion (), is (ANNOTATED_START_AT ));
575599
576600 retrieved .setAttribute ("updated" );
577601 AnnotatedRecord updated = annotatedTable .updateItem (retrieved );
578- assertThat (updated .getVersion (), is (8L ));
602+ assertThat (updated .getVersion (), is (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY ));
579603 }
580604
581605 @ Test
582606 public void putItem_annotationConfigWithVersionEqualToStartAt_shouldSucceed () {
583607 Map <String , AttributeValue > item = new HashMap <>();
584608 item .put ("id" , stringValue ("annotation-put" ));
585609 item .put ("attribute" , stringValue ("initial" ));
586- item .put ("version" , AttributeValue .builder ().n ("5" ).build ());
610+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( ANNOTATED_START_AT ) ).build ());
587611 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("annotated-table" )).item (item ));
588612
589- AnnotatedRecord overwrite = new AnnotatedRecord ().setId ("annotation-put" ).setAttribute ("overwritten" ).setVersion (5L );
613+ AnnotatedRecord overwrite = new AnnotatedRecord ().setId ("annotation-put" ).setAttribute ("overwritten" ).setVersion (ANNOTATED_START_AT );
590614 annotatedTable .putItem (overwrite );
591615
592616 AnnotatedRecord retrieved = annotatedTable .getItem (r -> r .key (k -> k .partitionValue ("annotation-put" )));
593617 assertThat (retrieved .getAttribute (), is ("overwritten" ));
594- assertThat (retrieved .getVersion (), is (8L ));
618+ assertThat (retrieved .getVersion (), is (ANNOTATED_START_AT + ANNOTATED_INCREMENT_BY ));
595619 }
596620
597621 @ Test
598622 public void deleteItem_builderConfigWithVersionEqualToStartAt_shouldSucceed () {
599623 Map <String , AttributeValue > item = new HashMap <>();
600624 item .put ("id" , stringValue ("delete-builder" ));
601625 item .put ("attribute" , stringValue ("test" ));
602- item .put ("version" , AttributeValue .builder ().n ("10" ).build ());
626+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( CUSTOM_START_AT ) ).build ());
603627 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("table-name2" )).item (item ));
604628
605629 Record toDelete = mappedCustomVersionedTable .getItem (r -> r .key (k -> k .partitionValue ("delete-builder" )));
606- assertThat (toDelete .getVersion (), is (10 ));
630+ assertThat (toDelete .getVersion (), is (CUSTOM_START_AT ));
607631
608632 mappedCustomVersionedTable .deleteItem (toDelete );
609633
@@ -616,11 +640,11 @@ public void deleteItem_annotationConfigWithVersionEqualToStartAt_shouldSucceed()
616640 Map <String , AttributeValue > item = new HashMap <>();
617641 item .put ("id" , stringValue ("delete-annotation" ));
618642 item .put ("attribute" , stringValue ("test" ));
619- item .put ("version" , AttributeValue .builder ().n ("5" ).build ());
643+ item .put ("version" , AttributeValue .builder ().n (String . valueOf ( ANNOTATED_START_AT ) ).build ());
620644 getDynamoDbClient ().putItem (r -> r .tableName (getConcreteTableName ("annotated-table" )).item (item ));
621645
622646 AnnotatedRecord toDelete = annotatedTable .getItem (r -> r .key (k -> k .partitionValue ("delete-annotation" )));
623- assertThat (toDelete .getVersion (), is (5L ));
647+ assertThat (toDelete .getVersion (), is (ANNOTATED_START_AT ));
624648
625649 annotatedTable .deleteItem (toDelete );
626650
@@ -648,6 +672,26 @@ public void updateItem_startAtNegativeOne_incrementsFromZero() {
648672 assertThat (result .getVersion (), is (1 ));
649673 }
650674
675+ @ Test
676+ public void putItem_startAtNegativeOne_incrementByTwo_firstVersionIsOne () {
677+ startAtNegativeOneIncrementByTwoTable .putItem (r -> r .item (new Record ().setId ("test-id" ).setAttribute ("value" )));
678+
679+ Record result = startAtNegativeOneIncrementByTwoTable .getItem (r -> r .key (k -> k .partitionValue ("test-id" )));
680+ assertThat (result .getVersion (), is (1 ));
681+ }
682+
683+ @ Test
684+ public void updateItem_startAtNegativeOne_incrementByTwo_incrementsByTwo () {
685+ startAtNegativeOneIncrementByTwoTable .putItem (r -> r .item (new Record ().setId ("test-id-2" ).setAttribute ("value" )));
686+
687+ Record recordToUpdate = startAtNegativeOneIncrementByTwoTable .getItem (r -> r .key (k -> k .partitionValue ("test-id-2" )));
688+ recordToUpdate .setAttribute ("updated" );
689+ startAtNegativeOneIncrementByTwoTable .updateItem (r -> r .item (recordToUpdate ));
690+
691+ Record result = startAtNegativeOneIncrementByTwoTable .getItem (r -> r .key (k -> k .partitionValue ("test-id-2" )));
692+ assertThat (result .getVersion (), is (3 ));
693+ }
694+
651695 @ Test
652696 public void updateItem_startAtNegativeOne_versionMatchesStartAt_shouldSucceed () {
653697 Map <String , AttributeValue > item = new HashMap <>();
@@ -662,6 +706,14 @@ public void updateItem_startAtNegativeOne_versionMatchesStartAt_shouldSucceed()
662706 assertThat (result .getVersion (), is (0 ));
663707 }
664708
709+ @ Test (expected = IllegalArgumentException .class )
710+ public void builder_startAtNegativeTwo_throwsException () {
711+ VersionedRecordExtension .builder ()
712+ .startAt (-2L )
713+ .incrementBy (1L )
714+ .build ();
715+ }
716+
665717 @ Test
666718 public void annotatedRecord_startAtNegativeOne_firstVersionIsZero () {
667719 AnnotatedRecordStartAtNegativeOne record = new AnnotatedRecordStartAtNegativeOne ();
0 commit comments