.setSchemaFormat(SchemaFormat.UID));
// Fetch all the layout history:
final List<KijiTableLayout> layouts =
getTableLayoutVersions(tableName, HConstants.ALL_VERSIONS);
final KijiTableLayout currentLayout = layouts.isEmpty() ? null : layouts.get(0);
final KijiTableLayout tableLayout = KijiTableLayout.createUpdatedLayout(update, currentLayout);
Preconditions.checkArgument(tableName.equals(tableLayout.getName()));
// Set of all the former layout IDs:
final Set<String> layoutIDs = Sets.newHashSet();
for (KijiTableLayout layout : layouts) {
layoutIDs.add(layout.getDesc().getLayoutId());
}
final String refLayoutIdStr = update.getReferenceLayout();
final boolean hasCurrentLayout = (null != currentLayout);
final boolean hasRefLayoutId = (null != refLayoutIdStr);
if (hasCurrentLayout && !hasRefLayoutId) {
throw new IOException(String.format(
"Layout for table '%s' does not specify reference layout ID.", tableName));
}
if (!hasCurrentLayout && hasRefLayoutId) {
throw new IOException(String.format(
"Initial layout for table '%s' must not specify reference layout ID.", tableName));
}
final String layoutId = tableLayout.getDesc().getLayoutId();
if (layoutIDs.contains(layoutId)) {
throw new InvalidLayoutException(tableLayout,
String.format("Layout ID '%s' already exists", layoutId));
}
// Construct the Put request to write the layout to the HTable.
final byte[] tableNameBytes = Bytes.toBytes(tableName);
final Put put = new Put(tableNameBytes)
.add(mFamilyBytes, QUALIFIER_UPDATE_BYTES, encodeTableLayoutDesc(update))
.add(mFamilyBytes, QUALIFIER_LAYOUT_BYTES, encodeTableLayoutDesc(tableLayout.getDesc()))
.add(mFamilyBytes, QUALIFIER_LAYOUT_ID_BYTES, Bytes.toBytes(layoutId));
// Flush the writer schema for the Avro table layout first so other readers can see it.
mSchemaTable.flush();