Skip to content

Commit 205bdeb

Browse files
committed
WIP
1 parent 2fe1f90 commit 205bdeb

10 files changed

Lines changed: 318 additions & 51 deletions

File tree

document-store/src/integrationTest/java/org/hypertrace/core/documentstore/FlatCollectionWriteTest.java

Lines changed: 123 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,115 @@ void testBulkCreateOrReplaceIgnoreDocumentStrategy() throws Exception {
17041704
assertEquals(200, rs.getInt("price"));
17051705
});
17061706
}
1707+
1708+
@Test
1709+
@DisplayName("Should bulk createOrReplace and return older documents with JSONB and arrays")
1710+
void testBulkCreateOrReplaceReturnOlderDocuments() throws Exception {
1711+
String docId1 = "bulk-replace-return-1";
1712+
String docId2 = "bulk-replace-return-2";
1713+
1714+
String initial1Json = readFileFromResource(
1715+
"create/bulk_replace_initial_doc1.json").orElseThrow();
1716+
String initial2Json = readFileFromResource(
1717+
"create/bulk_replace_initial_doc2.json").orElseThrow();
1718+
String updated1Json = readFileFromResource(
1719+
"create/bulk_replace_updated_doc1.json").orElseThrow();
1720+
String updated2Json = readFileFromResource(
1721+
"create/bulk_replace_updated_doc2.json").orElseThrow();
1722+
1723+
flatCollection.createOrReplace(
1724+
new SingleValueKey(DEFAULT_TENANT, docId1), new JSONDocument(initial1Json));
1725+
flatCollection.createOrReplace(
1726+
new SingleValueKey(DEFAULT_TENANT, docId2), new JSONDocument(initial2Json));
1727+
1728+
Map<Key, Document> bulkMap = new LinkedHashMap<>();
1729+
bulkMap.put(new SingleValueKey(DEFAULT_TENANT, docId1), new JSONDocument(updated1Json));
1730+
bulkMap.put(new SingleValueKey(DEFAULT_TENANT, docId2), new JSONDocument(updated2Json));
1731+
1732+
// Get older documents before replacement
1733+
CloseableIterator<Document> olderDocs =
1734+
flatCollection.bulkCreateOrReplaceReturnOlderDocuments(bulkMap);
1735+
1736+
// Collect older documents
1737+
Map<String, JsonNode> olderDocsMap = new HashMap<>();
1738+
while (olderDocs.hasNext()) {
1739+
Document doc = olderDocs.next();
1740+
JsonNode json = OBJECT_MAPPER.readTree(doc.toJson());
1741+
olderDocsMap.put(json.get("id").asText(), json);
1742+
}
1743+
olderDocs.close();
1744+
1745+
// Verify we got the older documents with original values including JSONB and arrays
1746+
String key1 = new SingleValueKey(DEFAULT_TENANT, docId1).toString();
1747+
String key2 = new SingleValueKey(DEFAULT_TENANT, docId2).toString();
1748+
assertEquals(2, olderDocsMap.size());
1749+
assertTrue(olderDocsMap.containsKey(key1));
1750+
assertTrue(olderDocsMap.containsKey(key2));
1751+
1752+
// Verify doc1 original values
1753+
JsonNode expectedDoc1 = OBJECT_MAPPER.readTree(initial1Json);
1754+
JsonNode oldDoc1 = olderDocsMap.get(key1);
1755+
assertEquals(expectedDoc1, oldDoc1);
1756+
1757+
// Verify doc2 original values
1758+
JsonNode expectedDoc2 = OBJECT_MAPPER.readTree(initial2Json);
1759+
JsonNode oldDoc2 = olderDocsMap.get(key2);
1760+
assertEquals(expectedDoc2, oldDoc2);
1761+
1762+
// Verify the documents were actually replaced with new values
1763+
String expectedResult1Json = readFileFromResource(
1764+
"expected/bulk_replace_result_doc1.json").orElseThrow();
1765+
String expectedResult2Json = readFileFromResource(
1766+
"expected/bulk_replace_result_doc2.json").orElseThrow();
1767+
1768+
Query query1 = Query.builder()
1769+
.setFilter(
1770+
RelationalExpression.of(
1771+
IdentifierExpression.of("id"),
1772+
RelationalOperator.EQ,
1773+
ConstantExpression.of(new SingleValueKey(DEFAULT_TENANT, docId1).toString())))
1774+
.build();
1775+
try (CloseableIterator<Document> iter = flatCollection.find(query1)) {
1776+
assertTrue(iter.hasNext());
1777+
JsonNode actualDoc1 = OBJECT_MAPPER.readTree(iter.next().toJson());
1778+
JsonNode expectedResultDoc1 = OBJECT_MAPPER.readTree(expectedResult1Json);
1779+
assertEquals(expectedResultDoc1, actualDoc1);
1780+
}
1781+
1782+
Query query2 = Query.builder()
1783+
.setFilter(
1784+
RelationalExpression.of(
1785+
IdentifierExpression.of("id"),
1786+
RelationalOperator.EQ,
1787+
ConstantExpression.of(new SingleValueKey(DEFAULT_TENANT, docId2).toString())))
1788+
.build();
1789+
try (CloseableIterator<Document> iter = flatCollection.find(query2)) {
1790+
assertTrue(iter.hasNext());
1791+
JsonNode actualDoc2 = OBJECT_MAPPER.readTree(iter.next().toJson());
1792+
JsonNode expectedResultDoc2 = OBJECT_MAPPER.readTree(expectedResult2Json);
1793+
assertEquals(expectedResultDoc2, actualDoc2);
1794+
}
1795+
}
1796+
1797+
@Test
1798+
@DisplayName(
1799+
"Should return empty iterator for empty map in bulkCreateOrReplaceReturnOlderDocuments")
1800+
void testBulkCreateOrReplaceReturnOlderDocumentsEmptyMap() throws Exception {
1801+
CloseableIterator<Document> result =
1802+
flatCollection.bulkCreateOrReplaceReturnOlderDocuments(Collections.emptyMap());
1803+
assertFalse(result.hasNext());
1804+
result.close();
1805+
}
1806+
1807+
@Test
1808+
@DisplayName(
1809+
"Should return empty iterator for null map in bulkCreateOrReplaceReturnOlderDocuments")
1810+
void testBulkCreateOrReplaceReturnOlderDocumentsNullMap() throws Exception {
1811+
CloseableIterator<Document> result =
1812+
flatCollection.bulkCreateOrReplaceReturnOlderDocuments(null);
1813+
assertFalse(result.hasNext());
1814+
result.close();
1815+
}
17071816
}
17081817

17091818
@Nested
@@ -2128,15 +2237,15 @@ void testSetAllFieldTypes() throws Exception {
21282237
SubDocumentUpdate.of("rating", 4.5f),
21292238
SubDocumentUpdate.of("weight", 123.456),
21302239
// Case 2: Top-level arrays
2131-
SubDocumentUpdate.of("tags", new String[] {"tag4", "tag5", "tag6"}),
2132-
SubDocumentUpdate.of("numbers", new Integer[] {10, 20, 30}),
2133-
SubDocumentUpdate.of("scores", new Double[] {1.1, 2.2, 3.3}),
2134-
SubDocumentUpdate.of("flags", new Boolean[] {true, false, true}),
2240+
SubDocumentUpdate.of("tags", new String[]{"tag4", "tag5", "tag6"}),
2241+
SubDocumentUpdate.of("numbers", new Integer[]{10, 20, 30}),
2242+
SubDocumentUpdate.of("scores", new Double[]{1.1, 2.2, 3.3}),
2243+
SubDocumentUpdate.of("flags", new Boolean[]{true, false, true}),
21352244
// Case 3 & 4: One nested path in JSONB (props) - tests nested primitive
21362245
SubDocumentUpdate.of("props.brand", "NewBrand"),
21372246
// Use 'sales' JSONB column for nested array test
21382247
SubDocumentUpdate.of(
2139-
"sales.regions", SubDocumentValue.of(new String[] {"US", "EU", "APAC"})));
2248+
"sales.regions", SubDocumentValue.of(new String[]{"US", "EU", "APAC"})));
21402249

21412250
UpdateOptions options =
21422251
UpdateOptions.builder().returnDocumentType(ReturnDocumentType.AFTER_UPDATE).build();
@@ -2346,7 +2455,7 @@ void testSetMultipleNestedPathsInSameJsonbColumn() throws Exception {
23462455
SubDocumentUpdate.of("props.size", "XL"),
23472456
SubDocumentUpdate.of("props.newField", "newValue"),
23482457
SubDocumentUpdate.of(
2349-
"props.owners", SubDocumentValue.of(new String[] {"owner1", "owner2"})));
2458+
"props.owners", SubDocumentValue.of(new String[]{"owner1", "owner2"})));
23502459

23512460
UpdateOptions options =
23522461
UpdateOptions.builder().returnDocumentType(ReturnDocumentType.AFTER_UPDATE).build();
@@ -2652,7 +2761,7 @@ void testAddArrayValue() {
26522761
SubDocumentUpdate.builder()
26532762
.subDocument("price")
26542763
.operator(UpdateOperator.ADD)
2655-
.subDocumentValue(SubDocumentValue.of(new Integer[] {1, 2, 3}))
2764+
.subDocumentValue(SubDocumentValue.of(new Integer[]{1, 2, 3}))
26562765
.build());
26572766

26582767
UpdateOptions options =
@@ -2699,19 +2808,19 @@ void testAppendToListAllCases() throws Exception {
26992808
SubDocumentUpdate.builder()
27002809
.subDocument("tags")
27012810
.operator(UpdateOperator.APPEND_TO_LIST)
2702-
.subDocumentValue(SubDocumentValue.of(new String[] {"newTag1", "newTag2"}))
2811+
.subDocumentValue(SubDocumentValue.of(new String[]{"newTag1", "newTag2"}))
27032812
.build(),
27042813
// Nested JSONB array: append to existing props.colors
27052814
SubDocumentUpdate.builder()
27062815
.subDocument("props.colors")
27072816
.operator(UpdateOperator.APPEND_TO_LIST)
2708-
.subDocumentValue(SubDocumentValue.of(new String[] {"green", "yellow"}))
2817+
.subDocumentValue(SubDocumentValue.of(new String[]{"green", "yellow"}))
27092818
.build(),
27102819
// Nested JSONB: append to non-existent array (creates it)
27112820
SubDocumentUpdate.builder()
27122821
.subDocument("sales.regions")
27132822
.operator(UpdateOperator.APPEND_TO_LIST)
2714-
.subDocumentValue(SubDocumentValue.of(new String[] {"US", "EU"}))
2823+
.subDocumentValue(SubDocumentValue.of(new String[]{"US", "EU"}))
27152824
.build());
27162825

27172826
UpdateOptions options =
@@ -2790,13 +2899,13 @@ void testAddToListIfAbsentAllCases() throws Exception {
27902899
SubDocumentUpdate.builder()
27912900
.subDocument("tags")
27922901
.operator(UpdateOperator.ADD_TO_LIST_IF_ABSENT)
2793-
.subDocumentValue(SubDocumentValue.of(new String[] {"existing1", "newTag"}))
2902+
.subDocumentValue(SubDocumentValue.of(new String[]{"existing1", "newTag"}))
27942903
.build(),
27952904
// Nested JSONB: 'red' exists, 'green' is new → adds only 'green'
27962905
SubDocumentUpdate.builder()
27972906
.subDocument("props.colors")
27982907
.operator(UpdateOperator.ADD_TO_LIST_IF_ABSENT)
2799-
.subDocumentValue(SubDocumentValue.of(new String[] {"red", "green"}))
2908+
.subDocumentValue(SubDocumentValue.of(new String[]{"red", "green"}))
28002909
.build());
28012910

28022911
UpdateOptions options =
@@ -2867,13 +2976,13 @@ void testRemoveAllFromListAllCases() throws Exception {
28672976
SubDocumentUpdate.builder()
28682977
.subDocument("tags")
28692978
.operator(UpdateOperator.REMOVE_ALL_FROM_LIST)
2870-
.subDocumentValue(SubDocumentValue.of(new String[] {"tag1"}))
2979+
.subDocumentValue(SubDocumentValue.of(new String[]{"tag1"}))
28712980
.build(),
28722981
// Nested JSONB: remove 'red' and 'blue' → leaves green
28732982
SubDocumentUpdate.builder()
28742983
.subDocument("props.colors")
28752984
.operator(UpdateOperator.REMOVE_ALL_FROM_LIST)
2876-
.subDocumentValue(SubDocumentValue.of(new String[] {"red", "blue"}))
2985+
.subDocumentValue(SubDocumentValue.of(new String[]{"red", "blue"}))
28772986
.build());
28782987

28792988
UpdateOptions options =

0 commit comments

Comments
 (0)