Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,20 @@ public static class RowToInsert implements Serializable {
private final Map<String, Object> content;

RowToInsert(String id, Map<String, ?> content) {
this(id, content, true);
}

private RowToInsert(String id, Map<String, ?> content, boolean defensiveCopy) {
this.id = id;

if (content instanceof ImmutableMap) {
this.content = ImmutableMap.copyOf(content);
} else {
} else if (content.isEmpty()) {
this.content = ImmutableMap.of();
} else if (defensiveCopy) {
this.content = Collections.unmodifiableMap(new HashMap<>(content));
} else {
this.content = Collections.unmodifiableMap(content);
}
}

Expand Down Expand Up @@ -153,6 +161,34 @@ public static RowToInsert of(String id, Map<String, ?> content) {
public static RowToInsert of(Map<String, ?> content) {
return new RowToInsert(null, checkNotNull(content));
}

/**
* Creates a row to be inserted with associated id without defensively copying {@code content}.
*
* <p>The caller must not mutate {@code content} after passing it to this method. The returned
* row wraps {@code content} in an unmodifiable view when it is not already an {@link
* ImmutableMap}.
*
* @param id id of the row, used to identify duplicates
* @param content the actual content of the row
*/
public static RowToInsert ofWithoutCopy(String id, Map<String, ?> content) {
return new RowToInsert(checkNotNull(id), checkNotNull(content), false);
}

/**
* Creates a row to be inserted without associated id and without defensively copying {@code
* content}.
*
* <p>The caller must not mutate {@code content} after passing it to this method. The returned
* row wraps {@code content} in an unmodifiable view when it is not already an {@link
* ImmutableMap}.
*
* @param content the actual content of the row
*/
public static RowToInsert ofWithoutCopy(Map<String, ?> content) {
return new RowToInsert(null, checkNotNull(content), false);
}
}

public static final class Builder {
Expand Down Expand Up @@ -243,6 +279,27 @@ public Builder addRow(Map<String, ?> content) {
return this;
}

/**
* Adds a row to be inserted with associated id without defensively copying {@code content}.
*
* <p>The caller must not mutate {@code content} after passing it to this method.
*/
public Builder addRowWithoutCopy(String id, Map<String, ?> content) {
addRow(RowToInsert.ofWithoutCopy(id, content));
return this;
}

/**
* Adds a row to be inserted without an associated id and without defensively copying {@code
* content}.
*
* <p>The caller must not mutate {@code content} after passing it to this method.
*/
public Builder addRowWithoutCopy(Map<String, ?> content) {
addRow(RowToInsert.ofWithoutCopy(content));
return this;
}

/**
* Sets whether to insert all valid rows of a request, even if invalid rows exist. If not set
* the entire insert request will fail if it contains an invalid row.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,44 @@ public void testNullOK() {
assertThat(row.getContent()).containsExactly("foo", null);
}

@Test
public void testWithoutCopy() {
Map<String, Object> map1 = new HashMap<>();
map1.put("key", "val1");
Map<String, Object> map2 = new HashMap<>();
map2.put("key", "val2");

InsertAllRequest.RowToInsert rowWithoutId = InsertAllRequest.RowToInsert.ofWithoutCopy(map1);
assertThat(rowWithoutId.getId()).isNull();
assertThat(rowWithoutId.getContent()).isEqualTo(CONTENT1);
assertThrows(
UnsupportedOperationException.class, () -> rowWithoutId.getContent().put("k", "v"));

InsertAllRequest.RowToInsert rowWithId =
InsertAllRequest.RowToInsert.ofWithoutCopy("id1", map1);
assertThat(rowWithId.getId()).isEqualTo("id1");
assertThat(rowWithId.getContent()).isEqualTo(CONTENT1);
assertThrows(UnsupportedOperationException.class, () -> rowWithId.getContent().put("k", "v"));

InsertAllRequest requestWithoutId =
InsertAllRequest.newBuilder(TABLE_ID)
.addRowWithoutCopy(map1)
.addRowWithoutCopy(map2)
.setIgnoreUnknownValues(IGNORE_UNKNOWN_VALUES)
.setSkipInvalidRows(SKIP_INVALID_ROWS)
.build();
compareInsertAllRequest(INSERT_ALL_REQUEST1, requestWithoutId);

InsertAllRequest requestWithId =
InsertAllRequest.newBuilder(TABLE_ID)
.addRowWithoutCopy("id1", map1)
.addRowWithoutCopy("id2", map2)
.setIgnoreUnknownValues(IGNORE_UNKNOWN_VALUES)
.setSkipInvalidRows(SKIP_INVALID_ROWS)
.build();
compareInsertAllRequest(INSERT_ALL_REQUEST3, requestWithId);
}

private void compareInsertAllRequest(InsertAllRequest expected, InsertAllRequest value) {
assertThat(expected).isEqualTo(value);
assertThat(expected.toString()).isEqualTo(value.toString());
Expand Down
Loading