-
Notifications
You must be signed in to change notification settings - Fork 380
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
### What changes were proposed in this pull request? Add the ability to create a table via the Gravitino CLI. ### Why are the changes needed? so we can create tables via the CLI. Fix: #5383 ### Does this PR introduce _any_ user-facing change? No, but it expands on CLI commands. ### How was this patch tested? Tested locally.
- Loading branch information
1 parent
7759d0b
commit 054c6f7
Showing
13 changed files
with
522 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
clients/cli/src/main/java/org/apache/gravitino/cli/ReadTableCSV.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you 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 org.apache.gravitino.cli; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.apache.commons.csv.CSVFormat; | ||
import org.apache.commons.csv.CSVParser; | ||
import org.apache.commons.csv.CSVRecord; | ||
import org.apache.gravitino.rel.Column; | ||
|
||
public class ReadTableCSV { | ||
|
||
private enum ExpectedColumns { | ||
NAME("Name"), | ||
DATATYPE("Datatype"), | ||
COMMENT("Comment"), | ||
NULLABLE("Nullable"), | ||
AUTOINCREMENT("AutoIncrement"), | ||
DEFAULTVALUE("DefaultValue"), | ||
DEFAULTTYPE("DefaultType"); | ||
|
||
private final String name; | ||
|
||
ExpectedColumns(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} | ||
|
||
public Column[] columns(Map<String, List<String>> tableData) { | ||
List<String> names = tableData.get(ExpectedColumns.NAME.getName()); | ||
List<String> datatypes = tableData.get(ExpectedColumns.DATATYPE.getName()); | ||
List<String> comments = tableData.get(ExpectedColumns.COMMENT.getName()); | ||
List<String> nullables = tableData.get(ExpectedColumns.NULLABLE.getName()); | ||
List<String> autoIncs = tableData.get(ExpectedColumns.AUTOINCREMENT.getName()); | ||
List<String> defaultTypes = tableData.get(ExpectedColumns.DEFAULTTYPE.getName()); | ||
List<String> defaulValues = tableData.get(ExpectedColumns.DEFAULTVALUE.getName()); | ||
int size = names.size(); | ||
Column[] columns = new Column[size]; | ||
|
||
for (int i = 0; i < size; i++) { | ||
String columnName = names.get(i); | ||
String datatype = datatypes.get(i); | ||
String comment = comments.get(i); | ||
boolean nullable = nullables.get(i).equals("true"); | ||
boolean auto = autoIncs.get(i).equals("true"); | ||
String defaultValue = defaulValues.get(i); | ||
String defaultType = defaultTypes.get(i); | ||
|
||
if (defaultType == null || defaultType.isEmpty()) { | ||
defaultType = datatype; | ||
} | ||
|
||
Column column = | ||
Column.of( | ||
columnName, | ||
ParseType.toType(datatype), | ||
comment, | ||
nullable, | ||
auto, | ||
DefaultConverter.convert(defaultValue, defaultType)); | ||
columns[i] = column; | ||
} | ||
|
||
return columns; | ||
} | ||
|
||
public Map<String, List<String>> parse(String csvFile) { | ||
|
||
// Initialize a Map to store each column's values in a list | ||
HashMap<String, List<String>> tableData = new HashMap<>(); | ||
for (ExpectedColumns column : ExpectedColumns.values()) { | ||
tableData.put(column.getName(), new ArrayList<>()); | ||
} | ||
|
||
try (BufferedReader reader = | ||
Files.newBufferedReader(Paths.get(csvFile), StandardCharsets.UTF_8)) { | ||
CSVParser csvParser = | ||
new CSVParser( | ||
reader, | ||
CSVFormat.Builder.create() | ||
.setHeader( | ||
Arrays.stream(ExpectedColumns.values()) | ||
.map(ExpectedColumns::getName) | ||
.toArray(String[]::new)) | ||
.setIgnoreHeaderCase(true) | ||
.setSkipHeaderRecord(true) | ||
.setTrim(true) | ||
.setIgnoreEmptyLines(true) | ||
.build()); | ||
for (CSVRecord cvsRecord : csvParser) { | ||
String defaultValue = null; | ||
String value = null; | ||
|
||
for (ExpectedColumns column : ExpectedColumns.values()) { | ||
switch (column) { | ||
case NULLABLE: | ||
defaultValue = "true"; | ||
break; | ||
case AUTOINCREMENT: | ||
defaultValue = "false"; | ||
break; | ||
default: | ||
defaultValue = null; | ||
break; | ||
} | ||
|
||
try { | ||
value = cvsRecord.get(column.getName()); | ||
} catch (IllegalArgumentException exp) { | ||
value = defaultValue; // missing value | ||
} | ||
|
||
tableData.get(column.getName()).add(value); | ||
} | ||
} | ||
} catch (IOException exp) { | ||
System.err.println(exp.getMessage()); | ||
} | ||
|
||
return tableData; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you 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 org.apache.gravitino.cli.commands; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import org.apache.gravitino.NameIdentifier; | ||
import org.apache.gravitino.cli.ErrorMessages; | ||
import org.apache.gravitino.cli.ReadTableCSV; | ||
import org.apache.gravitino.client.GravitinoClient; | ||
import org.apache.gravitino.exceptions.NoSuchCatalogException; | ||
import org.apache.gravitino.exceptions.NoSuchMetalakeException; | ||
import org.apache.gravitino.exceptions.NoSuchSchemaException; | ||
import org.apache.gravitino.exceptions.TableAlreadyExistsException; | ||
import org.apache.gravitino.rel.Column; | ||
|
||
public class CreateTable extends Command { | ||
protected final String metalake; | ||
protected final String catalog; | ||
protected final String schema; | ||
protected final String table; | ||
protected final String columnFile; | ||
protected final String comment; | ||
|
||
/** | ||
* Create a new table. | ||
* | ||
* @param url The URL of the Gravitino server. | ||
* @param ignoreVersions If true don't check the client/server versions match. | ||
* @param metalake The name of the metalake. | ||
* @param catalog The name of the catalog. | ||
* @param schema The name of the schema. | ||
* @param table The name of the table. | ||
* @param columnFile The file name containing the CSV column info. | ||
* @param comment The table's comment. | ||
*/ | ||
public CreateTable( | ||
String url, | ||
boolean ignoreVersions, | ||
String metalake, | ||
String catalog, | ||
String schema, | ||
String table, | ||
String columnFile, | ||
String comment) { | ||
super(url, ignoreVersions); | ||
this.metalake = metalake; | ||
this.catalog = catalog; | ||
this.schema = schema; | ||
this.table = table; | ||
this.columnFile = columnFile; | ||
this.comment = comment; | ||
} | ||
|
||
/** Create a new table. */ | ||
@Override | ||
public void handle() { | ||
NameIdentifier tableName; | ||
GravitinoClient client; | ||
ReadTableCSV readTableCSV = new ReadTableCSV(); | ||
Map<String, List<String>> tableData; | ||
Column[] columns; | ||
|
||
try { | ||
tableName = NameIdentifier.of(schema, table); | ||
client = buildClient(metalake); | ||
} catch (NoSuchMetalakeException err) { | ||
System.err.println(ErrorMessages.UNKNOWN_METALAKE); | ||
return; | ||
} catch (Exception exp) { | ||
System.err.println("Error initializing client or table name: " + exp.getMessage()); | ||
return; | ||
} | ||
|
||
try { | ||
tableData = readTableCSV.parse(columnFile); | ||
columns = readTableCSV.columns(tableData); | ||
} catch (Exception exp) { | ||
System.err.println("Error reading or parsing column file: " + exp.getMessage()); | ||
return; | ||
} | ||
|
||
try { | ||
client.loadCatalog(catalog).asTableCatalog().createTable(tableName, columns, comment, null); | ||
} catch (NoSuchCatalogException err) { | ||
System.err.println(ErrorMessages.UNKNOWN_CATALOG); | ||
return; | ||
} catch (NoSuchSchemaException err) { | ||
System.err.println(ErrorMessages.UNKNOWN_SCHEMA); | ||
return; | ||
} catch (TableAlreadyExistsException err) { | ||
System.err.println(ErrorMessages.TABLE_EXISTS); | ||
return; | ||
} catch (Exception exp) { | ||
System.err.println(exp.getMessage()); | ||
return; | ||
} | ||
|
||
System.out.println(table + " created"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.