List<KijiColumnName> columns,
TimestampMode tsMode,
Long timestamp)
throws Exception {
final KijiTableWriter writer = table.openTableWriter();
try {
if (columns.isEmpty()) {
// Row wide delete:
switch (tsMode) {
case UPTO: {
if (mayProceed("Are you sure you want to delete all cells with timestamp <= %d"
+ " from row '%s' in table '%s'?",
timestamp, entityId, table.getURI())) {
writer.deleteRow(entityId, timestamp);
}
return SUCCESS;
}
case ALL: {
if (mayProceed("Are you sure you want to delete row '%s' from table '%s'?",
entityId, table.getURI())) {
writer.deleteRow(entityId);
}
return SUCCESS;
}
case EXACT:
case LATEST:
throw new IllegalArgumentException(
"Row-wide delete with exact or latest timestamp are not implemented.");
default:
throw new RuntimeException("Unhandled timestamp mode: " + tsMode);
}
} else {
// Targeting a set of columns:
// Normalize the columns, and partition families vs individual columns.
final Set<String> families = Sets.newTreeSet();
for (KijiColumnName column : columns) {
if (!column.isFullyQualified()) {
families.add(column.getFamily());
}
}
final Set<KijiColumnName> groupColumns = Sets.newTreeSet();
for (KijiColumnName column : columns) {
// Do not include columns whose family is already specified for deletion:
if (column.isFullyQualified() && !families.contains(column.getFamily())) {
groupColumns.add(column);
}
}
Preconditions.checkArgument(families.isEmpty()
|| ((tsMode != TimestampMode.EXACT) && (tsMode != TimestampMode.LATEST)),
"Family-wide delete with exact or latest timestamp are not implemented.");
switch (tsMode) {
case EXACT: {
Preconditions.checkState(families.isEmpty());
if (!mayProceed("Are you sure you want to delete cell with timestamp %d of columns %s "
+ "from row '%s' in table '%s'?",
timestamp, Joiner.on(",").join(columns), entityId, table.getURI())) {
return SUCCESS;
}
for (KijiColumnName column : groupColumns) {
writer.deleteCell(entityId, column.getFamily(), column.getQualifier(), timestamp);
}
break;
}
case LATEST: {
Preconditions.checkState(families.isEmpty());
if (!mayProceed("Are you sure you want to delete the most recent cells of columns %s "
+ "from row '%s' in table '%s'?",
timestamp, Joiner.on(",").join(columns), entityId, table.getURI())) {
return SUCCESS;
}
for (KijiColumnName column : groupColumns) {
writer.deleteCell(
entityId, column.getFamily(), column.getQualifier(), HConstants.LATEST_TIMESTAMP);
}
break;
}
case UPTO: {
if (!mayProceed("Are you sure you want to delete all cells of columns %s "
+ "with timestamp <= %d from row '%s' in table '%s'?",
Joiner.on(",").join(columns), timestamp, entityId, table.getURI())) {
return SUCCESS;
}
for (String family : families) {
writer.deleteFamily(entityId, family, timestamp);
}
for (KijiColumnName column : groupColumns) {
writer.deleteColumn(entityId, column.getFamily(), column.getQualifier(), timestamp);
}
break;
}
case ALL: {
if (!mayProceed("Are you sure you want to delete columns %s from row '%s' in table '%s'?",
Joiner.on(",").join(columns), entityId, table.getURI())) {
return SUCCESS;
}
for (String family : families) {
writer.deleteFamily(entityId, family);
}
for (KijiColumnName column : groupColumns) {
writer.deleteColumn(entityId, column.getFamily(), column.getQualifier());
}
break;
}
default:
throw new RuntimeException("Unhandled timestamp mode: " + tsMode);
}
return SUCCESS;
}
} finally {
writer.close();
}
}