com.palantir.atlasdb.table.description.render.TableClassRendererV2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlasdb-client Show documentation
Show all versions of atlasdb-client Show documentation
Palantir open source project
/*
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.palantir.atlasdb.table.description.render;
import static com.palantir.atlasdb.AtlasDbConstants.SCHEMA_V2_TABLE_NAME;
import static com.palantir.atlasdb.table.description.render.ColumnRenderers.VarName;
import static com.palantir.atlasdb.table.description.render.Renderers.CamelCase;
import static com.palantir.atlasdb.table.description.render.Renderers.addParametersFromRowComponents;
import static com.palantir.atlasdb.table.description.render.Renderers.getArgumentsFromRowComponents;
import static com.palantir.atlasdb.table.description.render.Renderers.getColumnClass;
import static com.palantir.atlasdb.table.description.render.Renderers.getColumnClassForGenericTypeParameter;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.palantir.atlasdb.encoding.PtBytes;
import com.palantir.atlasdb.keyvalue.api.Cell;
import com.palantir.atlasdb.keyvalue.api.ColumnSelection;
import com.palantir.atlasdb.keyvalue.api.Namespace;
import com.palantir.atlasdb.keyvalue.api.RangeRequest;
import com.palantir.atlasdb.keyvalue.api.RowResult;
import com.palantir.atlasdb.keyvalue.api.TableReference;
import com.palantir.atlasdb.table.description.NameComponentDescription;
import com.palantir.atlasdb.table.description.NamedColumnDescription;
import com.palantir.atlasdb.table.description.Schemas;
import com.palantir.atlasdb.table.description.TableDefinition;
import com.palantir.atlasdb.table.description.TableMetadata;
import com.palantir.atlasdb.table.generation.ColumnValues;
import com.palantir.atlasdb.transaction.api.Transaction;
import com.palantir.common.base.BatchingVisitableView;
import com.palantir.common.persist.Persistables;
import com.palantir.goethe.Goethe;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.processing.Generated;
import javax.lang.model.element.Modifier;
public class TableClassRendererV2 {
private final String packageName;
private final Namespace namespace;
private final TableMetadata tableMetadata;
private final String rawTableName;
private final String tableName;
private final String tableClassName;
private final ClassName tableType;
private final String rowClassName;
private final ClassName rowType;
private final String rowResultClassName;
private final ClassName rowResultType;
private final String simpleTableName;
private final ClassName simpleTableType;
public TableClassRendererV2(String packageName, Namespace namespace, String rawTableName, TableDefinition table) {
Preconditions.checkArgument(Schemas.isTableNameValid(rawTableName), "Invalid table name %s", rawTableName);
this.packageName = packageName;
this.namespace = namespace;
this.rawTableName = rawTableName;
this.tableName = Renderers.getClassTableName(rawTableName, table);
this.tableMetadata = table.toTableMetadata();
this.simpleTableName = this.tableName + SCHEMA_V2_TABLE_NAME;
this.tableClassName = this.tableName + "Table";
this.rowClassName = this.tableName + "Row";
this.rowResultClassName = this.tableName + "RowResult";
this.tableType = ClassName.get(packageName, this.tableClassName);
this.simpleTableType = ClassName.get(packageName, this.simpleTableName);
this.rowType = this.tableType.nestedClass(this.rowClassName);
this.rowResultType = this.tableType.nestedClass(this.rowResultClassName);
}
public String render() {
JavaFile javaFile = JavaFile.builder(packageName, this.buildTypeSpec())
.skipJavaLangImports(true)
.indent(" ")
.build();
return Goethe.formatAsString(javaFile);
}
private TypeSpec buildTypeSpec() {
TypeSpec.Builder tableBuilder = TypeSpec.classBuilder(this.simpleTableName)
.addAnnotation(AnnotationSpec.builder(Generated.class)
.addMember("value", "$S", TableRendererV2.class.getName())
.build())
.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class)
.addMember("value", "$S", "all")
.addMember("value", "$S", "deprecation")
.build())
.addModifiers(Modifier.PUBLIC);
getFields().forEach(tableBuilder::addField);
getConstructors().forEach(tableBuilder::addMethod);
getStaticFactories().forEach(tableBuilder::addMethod);
getMethods().forEach(tableBuilder::addMethod);
return tableBuilder.build();
}
private List getFields() {
List results = new ArrayList<>();
results.add(FieldSpec.builder(Transaction.class, "t")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.build());
results.add(FieldSpec.builder(String.class, "rawTableName")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
.initializer("$S", rawTableName)
.build());
results.add(FieldSpec.builder(TableReference.class, "tableRef")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.build());
return results;
}
private List getConstructors() {
List results = new ArrayList<>();
results.add(MethodSpec.constructorBuilder()
.addModifiers(Modifier.PRIVATE)
.addParameter(Transaction.class, "t")
.addParameter(Namespace.class, "namespace")
.addStatement("this.tableRef = $T.create(namespace, rawTableName)", TableReference.class)
.addStatement("this.t = t")
.build());
return results;
}
private List getStaticFactories() {
List results = new ArrayList<>();
results.add(MethodSpec.methodBuilder("of")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(Transaction.class, "t")
.addParameter(Namespace.class, "namespace")
.returns(simpleTableType)
.addStatement("return new $T($L, $L)", simpleTableType, "t", "namespace")
.build());
return results;
}
private List getMethods() {
List results = new ArrayList<>();
results.add(renderGetRawTableName());
results.add(renderGetTableRef());
results.add(renderGetTableName());
results.add(renderGetNamespace());
if (!tableMetadata.getColumns().hasDynamicColumns()) {
results.addAll(renderNamedGet());
results.addAll(renderNamedDelete());
results.addAll(renderNamedPutAndUpdate());
}
return results;
}
private MethodSpec renderGetRawTableName() {
return MethodSpec.methodBuilder("getRawTableName")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addStatement("return rawTableName")
.returns(String.class)
.build();
}
private MethodSpec renderGetTableName() {
return MethodSpec.methodBuilder("getTableName")
.addModifiers(Modifier.PUBLIC)
.addStatement("return tableRef.getQualifiedName()")
.returns(String.class)
.build();
}
private MethodSpec renderGetTableRef() {
return MethodSpec.methodBuilder("getTableRef")
.addModifiers(Modifier.PUBLIC)
.addStatement("return tableRef")
.returns(TableReference.class)
.build();
}
private MethodSpec renderGetNamespace() {
return MethodSpec.methodBuilder("getNamespace")
.addModifiers(Modifier.PUBLIC)
.addStatement("return tableRef.getNamespace()")
.returns(Namespace.class)
.build();
}
private List renderNamedGet() {
List getterResults = new ArrayList<>();
for (NamedColumnDescription col : ColumnRenderers.namedColumns(tableMetadata)) {
getterResults.add(renderNamedGetColumn(col));
if (tableMetadata.getRowMetadata().getRowParts().size() == 1) {
getterResults.add(renderNamedGetSeveralRows(col));
if (tableMetadata.isRangeScanAllowed()) {
getterResults.add(renderNamedGetRangeColumn(col));
getterResults.add(renderNamedGetRangeStartEnd(col));
getterResults.add(renderNamedGetRangeColumnLimit(col));
}
} else {
getterResults.add(renderNamedGetSeveralRowObjects(col));
if (tableMetadata.isRangeScanAllowed()) {
getterResults.add(renderNamedGetRangeColumnRowObjects(col));
getterResults.add(renderNamedGetRangeColumnRowObjectsLimit(col));
}
}
}
return getterResults;
}
private MethodSpec renderNamedGetColumn(NamedColumnDescription col) {
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("get" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc("Returns the value for column $L and specified row components.", VarName(col));
getterBuilder = addParametersFromRowComponents(getterBuilder, tableMetadata);
getterBuilder.returns(ParameterizedTypeName.get(
ClassName.get(Optional.class), TypeName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement("$T row = $T.of($L)", rowType, rowType, getArgumentsFromRowComponents(tableMetadata))
.addStatement("byte[] bytes = row.persistToBytes()")
.addStatement(
"$T colSelection = \n" + "$T.create($T.of($T.toCachedBytes($S)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
col.getShortName())
.addCode("\n")
.addStatement(
"$T rowResult = t.getRows(tableRef, $T.of(bytes), colSelection).get(bytes)",
RowResult.class,
ImmutableSet.class)
.addCode(
"if (rowResult == null) {\n"
+ " return $T.empty();\n"
+ "} else {\n"
+ " return $T.of($T.of(rowResult).get$L());\n"
+ "}\n",
Optional.class,
Optional.class,
rowResultType,
VarName(col));
return getterBuilder.build();
}
private MethodSpec renderNamedGetSeveralRows(NamedColumnDescription col) {
com.palantir.logsafe.Preconditions.checkArgument(
tableMetadata.getRowMetadata().getRowParts().size() == 1);
NameComponentDescription rowComponent =
tableMetadata.getRowMetadata().getRowParts().get(0);
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("get" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from the specified row keys to their value at column $L.\n"
+ "As the $L values are all loaded in memory, do not use for large amounts of data.\n"
+ "If the column does not exist for a key, the entry will be omitted from the map.",
VarName(col),
VarName(col))
.addParameter(
ParameterizedTypeName.get(
ClassName.get(Iterable.class),
ClassName.get(rowComponent.getType().getJavaClass())),
"rowKeys");
getterBuilder.returns(ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(rowComponent.getType().getJavaClass()),
TypeName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection = \n " + "$T.create($T.of($T.toCachedBytes($S)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
col.getShortName())
.addStatement(
"$T<$T> rows = $T\n"
+ ".newArrayList(rowKeys)\n"
+ ".stream()\n"
+ ".map($T::of)\n"
+ ".collect($T.toList())",
List.class,
rowType,
Lists.class,
rowType,
Collectors.class)
.addCode("\n")
.addStatement(
"$T> results = " + "t.getRows(tableRef, $T.persistAll(rows), colSelection)",
NavigableMap.class,
RowResult.class,
Persistables.class)
.addStatement(
"return results\n"
+ ".values()\n"
+ ".stream()\n"
+ ".map(entry -> $T.of(entry))\n"
+ ".collect($T.toMap(\n"
+ " entry -> entry.getRowName().get$L(), \n"
+ " $T::get$L))",
rowResultType,
Collectors.class,
CamelCase(rowComponent.getComponentName()),
rowResultType,
VarName(col));
return getterBuilder.build();
}
private MethodSpec renderNamedGetSeveralRowObjects(NamedColumnDescription col) {
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("get" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from the specified row objects to their value at column $L.\n"
+ "As the $L values are all loaded in memory, do not use for large amounts of data.\n"
+ "If the column does not exist for a key, the entry will be omitted from the map.",
VarName(col),
VarName(col))
.addParameter(ParameterizedTypeName.get(ClassName.get(Iterable.class), rowType), "rowKeys");
getterBuilder.returns(ParameterizedTypeName.get(
ClassName.get(Map.class), rowType, TypeName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection = \n " + "$T.create($T.of($T.toCachedBytes($S)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
col.getShortName())
.addCode("\n")
.addStatement(
"$T> results = "
+ "t.getRows(tableRef, $T.persistAll(rowKeys), colSelection)",
NavigableMap.class,
RowResult.class,
Persistables.class)
.addStatement(
"return results\n"
+ ".values()\n"
+ ".stream()\n"
+ ".map(entry -> $T.of(entry))\n"
+ ".collect($T.toMap(\n"
+ " entry -> entry.getRowName(), \n"
+ " $T::get$L))",
rowResultType,
Collectors.class,
rowResultType,
VarName(col));
return getterBuilder.build();
}
private MethodSpec renderNamedGetRangeColumn(NamedColumnDescription col) {
com.palantir.logsafe.Preconditions.checkArgument(
tableMetadata.getRowMetadata().getRowParts().size() == 1);
NameComponentDescription rowComponent =
tableMetadata.getRowMetadata().getRowParts().get(0);
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("getSmallRowRange" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from all the row keys in a rangeRequest to their value at column $L\n"
+ "(if that column exists for the row-key). As the $L values are all loaded in memory,\n"
+ "do not use for large amounts of data. The order of results is preserved in the map.",
VarName(col),
VarName(col))
.addParameter(RangeRequest.class, "rangeRequest")
.returns(ParameterizedTypeName.get(
ClassName.get(LinkedHashMap.class),
ClassName.get(rowComponent.getType().getJavaClass()),
ClassName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection =\n" + "$T.create($T.of($T.toCachedBytes($L)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
ColumnRenderers.short_name(col))
.addStatement("rangeRequest = rangeRequest.getBuilder().retainColumns(colSelection).build()")
.addStatement(
"$T.checkArgument(rangeRequest.getColumnNames().size() <= 1,\n$S)",
Preconditions.class,
"Must not request columns other than " + VarName(col) + ".")
.addCode("\n")
.addStatement(
"$T<$T, $T> resultsMap = new $T<>()",
LinkedHashMap.class,
rowComponent.getType().getJavaClass(),
getColumnClassForGenericTypeParameter(col),
LinkedHashMap.class)
.addStatement(
"$T.of(t.getRange(tableRef, rangeRequest))\n"
+ ".immutableCopy().forEach(entry -> {\n"
+ " $T resultEntry =\n "
+ " $T.of(entry);\n"
+ " resultsMap.put(resultEntry.getRowName().get$L(), resultEntry.get$L());\n"
+ "})",
BatchingVisitableView.class,
rowResultType,
rowResultType,
CamelCase(rowComponent.getComponentName()),
VarName(col))
.addStatement("return resultsMap");
return getterBuilder.build();
}
private MethodSpec renderNamedGetRangeStartEnd(NamedColumnDescription col) {
com.palantir.logsafe.Preconditions.checkArgument(
tableMetadata.getRowMetadata().getRowParts().size() == 1);
NameComponentDescription rowComponent =
tableMetadata.getRowMetadata().getRowParts().get(0);
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("getSmallRowRange" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from all the row keys in a range to their value at column $L\n"
+ "(if that column exists for the row-key). As the $L values are all loaded in memory,\n"
+ "do not use for large amounts of data. The order of results is preserved in the map.",
VarName(col),
VarName(col))
.addParameter(rowComponent.getType().getJavaClass(), "startInclusive")
.addParameter(rowComponent.getType().getJavaClass(), "endExclusive")
.returns(ParameterizedTypeName.get(
ClassName.get(LinkedHashMap.class),
ClassName.get(rowComponent.getType().getJavaClass()),
ClassName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T rangeRequest = $T.builder()\n"
+ ".startRowInclusive($T.of(startInclusive).persistToBytes())\n"
+ ".endRowExclusive($T.of(endExclusive).persistToBytes())\n"
+ ".build()",
RangeRequest.class,
RangeRequest.class,
rowType,
rowType)
.addStatement("return getSmallRowRange$L(rangeRequest)", VarName(col));
return getterBuilder.build();
}
private MethodSpec renderNamedGetRangeColumnLimit(NamedColumnDescription col) {
com.palantir.logsafe.Preconditions.checkArgument(
tableMetadata.getRowMetadata().getRowParts().size() == 1);
NameComponentDescription rowComponent =
tableMetadata.getRowMetadata().getRowParts().get(0);
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("getSmallRowRange" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from the first sizeLimit row keys in a rangeRequest to their value\n"
+ "at column $L (if that column exists). As the $L entries are all loaded in memory,\n"
+ "do not use for large values of sizeLimit. The order of results is preserved in the"
+ " map.",
VarName(col),
VarName(col))
.addParameter(RangeRequest.class, "rangeRequest")
.addParameter(int.class, "sizeLimit")
.returns(ParameterizedTypeName.get(
ClassName.get(LinkedHashMap.class),
ClassName.get(rowComponent.getType().getJavaClass()),
ClassName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection =\n" + "$T.create($T.of($T.toCachedBytes($L)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
ColumnRenderers.short_name(col))
.addStatement("rangeRequest = rangeRequest.getBuilder()."
+ "retainColumns(colSelection).batchHint(sizeLimit).build()")
.addStatement(
"$T.checkArgument(rangeRequest.getColumnNames().size() <= 1,\n$S)",
Preconditions.class,
"Must not request columns other than " + VarName(col) + ".")
.addCode("\n")
.addStatement(
"$T<$T, $T> resultsMap = new $T<>()",
LinkedHashMap.class,
rowComponent.getType().getJavaClass(),
getColumnClassForGenericTypeParameter(col),
LinkedHashMap.class)
.addStatement(
"$T.of(t.getRange(tableRef, rangeRequest))\n"
+ ".batchAccept(sizeLimit, batch -> {\n"
+ " batch.forEach(entry -> {\n"
+ " $T resultEntry =\n "
+ " $T.of(entry);\n"
+ " resultsMap.put(resultEntry.getRowName().get$L(), resultEntry.get$L());\n"
+ " });\n"
+ " return false; // stops the traversal after the first batch\n"
+ "})",
BatchingVisitableView.class,
rowResultType,
rowResultType,
CamelCase(rowComponent.getComponentName()),
VarName(col))
.addStatement("return resultsMap");
return getterBuilder.build();
}
private MethodSpec renderNamedGetRangeColumnRowObjects(NamedColumnDescription col) {
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("getSmallRowRange" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from all the rows in a RangeRequest to their value at column $L\n"
+ "(if that column exists for the row). As the $L values are all loaded in memory, \n"
+ "do not use for large amounts of data. The order of results is preserved in the map.",
VarName(col),
VarName(col))
.addParameter(RangeRequest.class, "rangeRequest")
.returns(ParameterizedTypeName.get(
ClassName.get(LinkedHashMap.class),
rowType,
ClassName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection =\n" + "$T.create($T.of($T.toCachedBytes($L)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
ColumnRenderers.short_name(col))
.addStatement("rangeRequest = rangeRequest.getBuilder().retainColumns(colSelection).build()")
.addStatement(
"$T.checkArgument(rangeRequest.getColumnNames().size() <= 1,\n$S)",
Preconditions.class,
"Must not request additional columns.")
.addCode("\n")
.addStatement(
"$T<$T, $T> resultsMap = new $T<>()",
LinkedHashMap.class,
rowType,
getColumnClassForGenericTypeParameter(col),
LinkedHashMap.class)
.addStatement(
"$T.of(t.getRange(tableRef, rangeRequest))\n"
+ ".immutableCopy().forEach(entry -> {\n"
+ " $T resultEntry =\n "
+ " $T.of(entry);\n"
+ " resultsMap.put(resultEntry.getRowName(), resultEntry.get$L());\n"
+ "})",
BatchingVisitableView.class,
rowResultType,
rowResultType,
VarName(col))
.addStatement("return resultsMap");
return getterBuilder.build();
}
private MethodSpec renderNamedGetRangeColumnRowObjectsLimit(NamedColumnDescription col) {
MethodSpec.Builder getterBuilder = MethodSpec.methodBuilder("getSmallRowRange" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc(
"Returns a mapping from the first sizeLimit rows in a rangeRequest to their value\n"
+ "at column $L (if that column exists). As the $L entries are all loaded in memory,\n"
+ "do not use for large values of sizeLimit. The order of results is preserved in the"
+ " map.",
VarName(col),
VarName(col))
.addParameter(RangeRequest.class, "rangeRequest")
.addParameter(int.class, "sizeLimit")
.returns(ParameterizedTypeName.get(
ClassName.get(LinkedHashMap.class),
rowType,
ClassName.get(getColumnClassForGenericTypeParameter(col))));
getterBuilder
.addStatement(
"$T colSelection =\n" + "$T.create($T.of($T.toCachedBytes($L)))",
ColumnSelection.class,
ColumnSelection.class,
ImmutableList.class,
PtBytes.class,
ColumnRenderers.short_name(col))
.addStatement("rangeRequest = rangeRequest.getBuilder()."
+ "retainColumns(colSelection).batchHint(sizeLimit).build()")
.addStatement(
"$T.checkArgument(rangeRequest.getColumnNames().size() <= 1,\n$S)",
Preconditions.class,
"Must not request columns other than " + VarName(col) + ".")
.addCode("\n")
.addStatement(
"$T<$T, $T> resultsMap = new $T<>()",
LinkedHashMap.class,
rowType,
getColumnClassForGenericTypeParameter(col),
LinkedHashMap.class)
.addStatement(
"$T.of(t.getRange(tableRef, rangeRequest))\n"
+ ".batchAccept(sizeLimit, batch -> {\n"
+ " batch.forEach(entry -> {\n"
+ " $T resultEntry =\n "
+ " $T.of(entry);\n"
+ " resultsMap.put(resultEntry.getRowName(), resultEntry.get$L());\n"
+ " });\n"
+ " return false; // stops the traversal after the first batch\n"
+ "})",
BatchingVisitableView.class,
rowResultType,
rowResultType,
VarName(col))
.addStatement("return resultsMap");
return getterBuilder.build();
}
private List renderNamedDelete() {
List deleteResults = new ArrayList<>();
deleteResults.add(renderNamedDeleteRow());
for (NamedColumnDescription col : ColumnRenderers.namedColumns(tableMetadata)) {
deleteResults.add(renderNamedDeleteColumn(col));
}
return deleteResults;
}
private MethodSpec renderNamedDeleteRow() {
MethodSpec.Builder deleteRowBuilder = MethodSpec.methodBuilder("deleteRow")
.addModifiers(Modifier.PUBLIC)
.addJavadoc("Delete all columns for specified row components.");
deleteRowBuilder = addParametersFromRowComponents(deleteRowBuilder, tableMetadata);
SortedSet namedColumns = ColumnRenderers.namedColumns(tableMetadata);
deleteRowBuilder
.addStatement("$T row = $T.of($L)", rowType, rowType, getArgumentsFromRowComponents(tableMetadata))
.addStatement("byte[] rowBytes = row.persistToBytes()", Persistables.class)
.addStatement(
"$T<$T> cells = $T.newHashSetWithExpectedSize($L)",
Set.class,
Cell.class,
Sets.class,
namedColumns.size());
for (NamedColumnDescription col : namedColumns) {
deleteRowBuilder.addStatement(
"cells.add($T.create(rowBytes, $T.toCachedBytes($L)))",
Cell.class,
PtBytes.class,
ColumnRenderers.short_name(col));
}
deleteRowBuilder.addStatement("t.delete(tableRef, cells)");
return deleteRowBuilder.build();
}
private MethodSpec renderNamedDeleteColumn(NamedColumnDescription col) {
MethodSpec.Builder deleteColumnBuilder = MethodSpec.methodBuilder("delete" + VarName(col))
.addModifiers(Modifier.PUBLIC)
.addJavadoc("Delete the value at column $L (if it exists) for the specified row-key.", VarName(col));
deleteColumnBuilder = addParametersFromRowComponents(deleteColumnBuilder, tableMetadata);
return deleteColumnBuilder
.addStatement("$T row = $T.of($L)", rowType, rowType, getArgumentsFromRowComponents(tableMetadata))
.addStatement("byte[] rowBytes = row.persistToBytes()", Persistables.class)
.addStatement(
"$T<$T> cells = $T.of($T.create(rowBytes, $T.toCachedBytes($L)))",
Set.class,
Cell.class,
ImmutableSet.class,
Cell.class,
PtBytes.class,
ColumnRenderers.short_name(col))
.addStatement("t.delete(tableRef, cells)")
.build();
}
private List renderNamedPutAndUpdate() {
List putAndUpdateResults = new ArrayList<>();
for (NamedColumnDescription col : ColumnRenderers.namedColumns(tableMetadata)) {
putAndUpdateResults.add(renderNamedPutColumn(col));
putAndUpdateResults.add(renderNamedUpdateColumn(col));
}
return putAndUpdateResults;
}
private MethodSpec renderNamedPutColumn(NamedColumnDescription col) {
MethodSpec.Builder putColumnBuilder = MethodSpec.methodBuilder("put" + VarName(col))
.addJavadoc("Takes the row-keys and a value to be inserted at column $L.", VarName(col))
.addModifiers(Modifier.PUBLIC);
putColumnBuilder = addParametersFromRowComponents(putColumnBuilder, tableMetadata);
TypeName columnValueType = tableType.nestedClass(VarName(col));
putColumnBuilder.addParameter(getColumnClass(col), col.getLongName());
putColumnBuilder
.addStatement("$T row = $T.of($L)", rowType, rowType, getArgumentsFromRowComponents(tableMetadata))
.addStatement(
"t.put(tableRef, $T.toCellValues($T.of(row, $T.of($L))))",
ColumnValues.class,
ImmutableMultimap.class,
columnValueType,
col.getLongName());
return putColumnBuilder.build();
}
private MethodSpec renderNamedUpdateColumn(NamedColumnDescription col) {
MethodSpec.Builder updateColumnIfExistsBuilder = MethodSpec.methodBuilder("update" + VarName(col))
.addJavadoc(
"Takes a function that would update the value at column $L, for the specified row\n"
+ "components. No effect if there is no value at that column. Doesn't do an additional\n"
+ "write if the new value is the same as the old one.",
VarName(col))
.addModifiers(Modifier.PUBLIC);
updateColumnIfExistsBuilder = addParametersFromRowComponents(updateColumnIfExistsBuilder, tableMetadata);
updateColumnIfExistsBuilder.addParameter(
ParameterizedTypeName.get(
ClassName.get(Function.class),
TypeName.get(getColumnClassForGenericTypeParameter(col)),
TypeName.get(getColumnClassForGenericTypeParameter(col))),
"processor");
String args = getArgumentsFromRowComponents(tableMetadata);
updateColumnIfExistsBuilder
.addStatement(
"$T<$T> result = get$L($L)",
Optional.class,
getColumnClassForGenericTypeParameter(col),
VarName(col),
args)
.beginControlFlow("if (result.isPresent())")
.addStatement("$T newValue = processor.apply(result.get())", getColumnClassForGenericTypeParameter(col))
.beginControlFlow("if ($T.equals(newValue, result.get()) == false)", Objects.class)
.addStatement("put$L($L, processor.apply(result.get()))", VarName(col), args)
.endControlFlow()
.endControlFlow();
return updateColumnIfExistsBuilder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy