Skip to content

Commit

Permalink
[apache#6493] feat(CLI): Support table format output for Schema and T…
Browse files Browse the repository at this point in the history
…able command

fix some bugs.
  • Loading branch information
Abyss-lord committed Feb 24, 2025
1 parent 2f12d06 commit 6b45438
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ protected <T extends GravitinoClientBase> Builder<T> constructClient(Builder<T>
* @param entity The entity to output.
* @param <T> The type of entity.
*/
protected <T> void output(T entity) {
private <T> void output(T entity) {
if (outputFormat == null) {
PlainFormat.output(entity, context);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.apache.gravitino.cli.commands;

import org.apache.gravitino.Catalog;
import org.apache.gravitino.Schema;
import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
Expand Down Expand Up @@ -48,9 +50,13 @@ public ListSchema(CommandContext context, String metalake, String catalog) {
@Override
public void handle() {
String[] schemas = new String[0];
GravitinoClient client;
Catalog gCatalog = null;

try {
GravitinoClient client = buildClient(metalake);
schemas = client.loadCatalog(catalog).asSchemas().listSchemas();
client = buildClient(metalake);
gCatalog = client.loadCatalog(catalog);
schemas = gCatalog.asSchemas().listSchemas();
} catch (NoSuchMetalakeException err) {
exitWithError(ErrorMessages.UNKNOWN_METALAKE);
} catch (NoSuchCatalogException err) {
Expand All @@ -59,11 +65,16 @@ public void handle() {
exitWithError(exp.getMessage());
}

Schema[] schemaObjects = new Schema[schemas.length];
for (int i = 0; i < schemas.length; i++) {
schemaObjects[i] = gCatalog.asSchemas().loadSchema(schemas[i]);
}

if (schemas.length == 0) {
printInformation("No schemas exist.");
return;
}

printResults(schemas);
printResults(schemaObjects);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

package org.apache.gravitino.cli.commands;

import java.util.ArrayList;
import java.util.List;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.Namespace;
import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.rel.Table;
import org.apache.gravitino.rel.TableCatalog;

/** List the names of all tables in a schema. */
public class ListTables extends TableCommand {
Expand All @@ -48,22 +48,25 @@ public ListTables(CommandContext context, String metalake, String catalog, Strin
public void handle() {
NameIdentifier[] tables = null;
Namespace name = Namespace.of(schema);
TableCatalog gCatalog = null;

try {
tables = tableCatalog().listTables(name);
gCatalog = tableCatalog();
tables = gCatalog.listTables(name);
} catch (Exception exp) {
exitWithError(exp.getMessage());
}

List<String> tableNames = new ArrayList<>();
for (int i = 0; i < tables.length; i++) {
tableNames.add(tables[i].name());
}

if (tableNames.isEmpty()) {
if (tables.length == 0) {
printInformation("No tables exist.");
return;
}

printResults(tableNames.toArray(new String[0]));
Table[] gTables = new Table[tables.length];
for (int i = 0; i < tables.length; i++) {
gTables[i] = gCatalog.loadTable(tables[i]);
}

printResults(gTables);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ public static void output(Object entity, CommandContext context) {
new CatalogListTableFormat(context).output((Catalog[]) entity);
} else if (entity instanceof Schema) {
new SchemaTableFormat(context).output((Schema) entity);
} else if (entity instanceof Schema[]) {
new SchemaListTableFormat(context).output((Schema[]) entity);
} else if (entity instanceof Table) {
new TableDetailsTableFormat(context).output((Table) entity);
} else if (entity instanceof String[]) {
new ListTableFormat(context).output((String[]) entity);
} else if (entity instanceof Table[]) {
new TableListTableFormat(context).output((Table[]) entity);
} else {
throw new IllegalArgumentException("Unsupported object type");
}
Expand Down Expand Up @@ -495,7 +497,7 @@ public MetalakeListTableFormat(CommandContext context) {
@Override
public String getOutput(Metalake[] metalakes) {

Column columnName = new Column(context, "Name");
Column columnName = new Column(context, "metalake");
Arrays.stream(metalakes).forEach(metalake -> columnName.addCell(metalake.name()));

return getTableFormat(columnName);
Expand Down Expand Up @@ -542,7 +544,7 @@ public CatalogListTableFormat(CommandContext context) {
/** {@inheritDoc} */
@Override
public String getOutput(Catalog[] catalogs) {
Column columnName = new Column(context, "Name");
Column columnName = new Column(context, "catalog");
Arrays.stream(catalogs).forEach(metalake -> columnName.addCell(metalake.name()));

return getTableFormat(columnName);
Expand Down Expand Up @@ -571,6 +573,25 @@ public String getOutput(Schema schema) {
}
}

/**
* Formats an array of Schemas into a single-column table display. Lists all schema names in a
* vertical format.
*/
static final class SchemaListTableFormat extends TableFormat<Schema[]> {
public SchemaListTableFormat(CommandContext context) {
super(context);
}

/** {@inheritDoc} */
@Override
public String getOutput(Schema[] schemas) {
Column column = new Column(context, "schema");
Arrays.stream(schemas).forEach(schema -> column.addCell(schema.name()));

return getTableFormat(column);
}
}

/**
* Formats a single {@link Table} instance into a two-column table display. Displays table details
* including name and comment information.
Expand Down Expand Up @@ -604,21 +625,20 @@ public String getOutput(Table table) {
}
}

static final class ListTableFormat extends TableFormat<String[]> {
/**
* Creates a new {@link TableFormat} with the specified properties.
*
* @param context the command context.
*/
public ListTableFormat(CommandContext context) {
/**
* Formats an array of {@link Table} into a single-column table display. Lists all table names in
* a vertical format.
*/
static final class TableListTableFormat extends TableFormat<Table[]> {
public TableListTableFormat(CommandContext context) {
super(context);
}

/** {@inheritDoc} */
@Override
public String getOutput(String[] entities) {
Column column = new Column(context, "name");
Arrays.stream(entities).forEach(column::addCell);
public String getOutput(Table[] tables) {
Column column = new Column(context, "table");
Arrays.stream(tables).forEach(table -> column.addCell(table.name()));

return getTableFormat(column);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public void testMetalakeListCommand() {
String output = new String(outputStream.toByteArray(), StandardCharsets.UTF_8).trim();
assertEquals(
"+-------------+\n"
+ "| Name |\n"
+ "| Metalake |\n"
+ "+-------------+\n"
+ "| my_metalake |\n"
+ "+-------------+",
Expand Down Expand Up @@ -170,7 +170,7 @@ public void testCatalogListCommand() {
String output = new String(outputStream.toByteArray(), StandardCharsets.UTF_8).trim();
assertEquals(
"+-----------+\n"
+ "| Name |\n"
+ "| Catalog |\n"
+ "+-----------+\n"
+ "| postgres |\n"
+ "| postgres2 |\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ void testListMetalakeWithTableFormat() {
String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
Assertions.assertEquals(
"+-----------+\n"
+ "| Name |\n"
+ "| Metalake |\n"
+ "+-----------+\n"
+ "| metalake1 |\n"
+ "| metalake2 |\n"
Expand All @@ -282,11 +282,19 @@ void testCatalogDetailsWithTableFormat() {
@Test
void testListCatalogWithTableFormat() {
CommandContext mockContext = getMockContext();
TableFormat.output(new String[] {"catalog1", "catalog2"}, mockContext);
Catalog mockCatalog1 =
getMockCatalog(
"catalog1", Catalog.Type.RELATIONAL, "demo_provider", "This is a demo catalog");
Catalog mockCatalog2 =
getMockCatalog(
"catalog2", Catalog.Type.RELATIONAL, "demo_provider", "This is another demo catalog");

TableFormat.output(new Catalog[] {mockCatalog1, mockCatalog2}, mockContext);

String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
Assertions.assertEquals(
"+----------+\n"
+ "| Name |\n"
+ "| Catalog |\n"
+ "+----------+\n"
+ "| catalog1 |\n"
+ "| catalog2 |\n"
Expand All @@ -313,15 +321,19 @@ void testSchemaDetailsWithTableFormat() {
@Test
void testListSchemaWithTableFormat() {
CommandContext mockContext = getMockContext();
TableFormat.output(new String[] {"schema1", "schema2"}, mockContext);
Schema mockSchema1 = getMockSchema("demo_schema1", "This is a demo schema");
Schema mockSchema2 = getMockSchema("demo_schema2", "This is another demo schema");

TableFormat.output(new Schema[] {mockSchema1, mockSchema2}, mockContext);

String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
Assertions.assertEquals(
"+---------+\n"
+ "| Name |\n"
+ "+---------+\n"
+ "| schema1 |\n"
+ "| schema2 |\n"
+ "+---------+",
"+--------------+\n"
+ "| Schema |\n"
+ "+--------------+\n"
+ "| demo_schema1 |\n"
+ "| demo_schema2 |\n"
+ "+--------------+",
output);
}

Expand All @@ -346,11 +358,14 @@ void testTableDetailsWithTableFormat() {
void testListTableWithTableFormat() {
CommandContext mockContext = getMockContext();

TableFormat.output(new String[] {"table1", "table2"}, mockContext);
Table mockTable1 = getMockTable("table1", "This is a demo table");
Table mockTable2 = getMockTable("table2", "This is another demo table");
TableFormat.output(new Table[] {mockTable1, mockTable2}, mockContext);

String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
Assertions.assertEquals(
"+--------+\n"
+ "| Name |\n"
+ "| Table |\n"
+ "+--------+\n"
+ "| table1 |\n"
+ "| table2 |\n"
Expand Down

0 comments on commit 6b45438

Please sign in to comment.