Skip to content

Commit

Permalink
Merge pull request #1190 from schemacrawler/chatgpt
Browse files Browse the repository at this point in the history
New function got table relationships
  • Loading branch information
sualeh committed Jul 3, 2023
2 parents 991eb39 + 7e4b55c commit 704e9f9
Show file tree
Hide file tree
Showing 14 changed files with 419 additions and 2 deletions.
@@ -0,0 +1,62 @@
/*
========================================================================
SchemaCrawler
http://www.schemacrawler.com
Copyright (c) 2000-2023, Sualeh Fatehi <sualeh@hotmail.com>.
All rights reserved.
------------------------------------------------------------------------
SchemaCrawler is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
SchemaCrawler and the accompanying materials are made available under
the terms of the Eclipse Public License v1.0, GNU General Public License
v3 or GNU Lesser General Public License v3.
You may elect to redistribute this code under any of these licenses.
The Eclipse Public License is available at:
http://www.eclipse.org/legal/epl-v10.html
The GNU General Public License v3 and the GNU Lesser General Public
License v3 are available at:
http://www.gnu.org/licenses/
========================================================================
*/

package schemacrawler.tools.command.chatgpt.functions;

import java.util.Optional;
import java.util.function.Function;
import schemacrawler.schema.Table;

public final class TableReferencesFunctionDefinition
extends AbstractFunctionDefinition<TableReferencesFunctionParameters> {

public TableReferencesFunctionDefinition() {
super(
"get-table-references",
"Gets the relationships of a database table, either child tables or parent tables. "
+ "Child tables are also known as referencing tables or foreign key tables. "
+ "Parent tables are also known as referenced tables, or primary key tables.",
TableReferencesFunctionParameters.class);
}

@Override
public Function<TableReferencesFunctionParameters, FunctionReturn> getExecutor() {
return args -> {
final String regex = String.format("(?i).*%s.*", args.getTableNameContains());
final Optional<Table> firstMatchedTable =
catalog.getTables().stream().filter(table -> table.getName().matches(regex)).findFirst();

if (firstMatchedTable.isPresent()) {
final Table table = firstMatchedTable.get();
return new TableReferencesFunctionReturn(table, args.getTableReferenceType());
} else {
return new NoResultsReturn();
}
};
}
}
@@ -0,0 +1,44 @@
package schemacrawler.tools.command.chatgpt.functions;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
public class TableReferencesFunctionParameters implements FunctionParameters {

public enum TableReferenceType {
all,
parent,
child;
}

@JsonPropertyDescription(
"Part of the name of database table to find. For example, 'ABC' is a part of 'QWEABCXYZ'.")
@JsonProperty(required = true)
private String tableNameContains;

@JsonPropertyDescription(
"The type of related tables requested - either child tables or parent tables, or both types (all relationships).")
private TableReferenceType tableReferenceType;

public String getTableNameContains() {
return tableNameContains;
}

public TableReferenceType getTableReferenceType() {
if (tableReferenceType == null) {
return TableReferenceType.all;
}
return tableReferenceType;
}

public void setTableNameContains(final String tableNameContains) {
this.tableNameContains = tableNameContains;
}

public void setTableReferenceType(final TableReferenceType tableReferenceType) {
this.tableReferenceType = tableReferenceType;
}
}
@@ -0,0 +1,133 @@
/*
========================================================================
SchemaCrawler
http://www.schemacrawler.com
Copyright (c) 2000-2023, Sualeh Fatehi <sualeh@hotmail.com>.
All rights reserved.
------------------------------------------------------------------------
SchemaCrawler is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
SchemaCrawler and the accompanying materials are made available under
the terms of the Eclipse Public License v1.0, GNU General Public License
v3 or GNU Lesser General Public License v3.
You may elect to redistribute this code under any of these licenses.
The Eclipse Public License is available at:
http://www.eclipse.org/legal/epl-v10.html
The GNU General Public License v3 and the GNU Lesser General Public
License v3 are available at:
http://www.gnu.org/licenses/
========================================================================
*/

package schemacrawler.tools.command.chatgpt.functions;

import static java.util.Objects.requireNonNull;
import java.util.Collection;
import java.util.Collections;
import schemacrawler.schema.Table;
import schemacrawler.schema.TableRelationshipType;
import schemacrawler.schema.View;
import schemacrawler.schemacrawler.IdentifierQuotingStrategy;
import schemacrawler.schemacrawler.Identifiers;
import schemacrawler.schemacrawler.IdentifiersBuilder;
import schemacrawler.tools.command.chatgpt.functions.TableReferencesFunctionParameters.TableReferenceType;

public class TableReferencesFunctionReturn implements FunctionReturn {

private static final String NEW_LINE = String.format("%n");
private static final Identifiers identifiers =
IdentifiersBuilder.builder()
.withIdentifierQuotingStrategy(IdentifierQuotingStrategy.quote_all)
.toOptions();
private final Table table;
private final TableReferenceType tableReferenceType;

protected TableReferencesFunctionReturn(final Table table, final TableReferenceType scope) {
this.table = requireNonNull(table, "Table not provided");
this.tableReferenceType = requireNonNull(scope, "Table description scope not provided");
}

@Override
public String render() {
switch (tableReferenceType) {
case parent:
return renderTableRelationships(TableReferenceType.parent);
case child:
return renderTableRelationships(TableReferenceType.child);
case all:
// Fall-through
default:
return renderTableRelationships(TableReferenceType.parent)
+ NEW_LINE
+ renderTableRelationships(TableReferenceType.child);
}
}

private String noData(final TableReferenceType tableReferenceType) {
final StringBuilder buffer = new StringBuilder();
if (table instanceof View) {
buffer.append("View ");
} else {
buffer.append("Table ");
}
buffer
.append(identifiers.quoteFullName(table))
.append(" has no ")
.append(tableReferenceType.name())
.append(" relationships.")
.append(NEW_LINE);
return buffer.toString();
}

private String renderTableRelationships(final TableReferenceType tableReferenceType) {
requireNonNull(tableReferenceType, "No table relationship type specified");

final Collection<Table> referencedTables;
switch (tableReferenceType) {
case parent:
referencedTables = table.getRelatedTables(TableRelationshipType.parent);
break;
case child:
referencedTables = table.getRelatedTables(TableRelationshipType.child);
break;
default:
referencedTables = Collections.emptyList();
}

if (referencedTables.isEmpty()) {
return noData(tableReferenceType);
}

final StringBuilder buffer = new StringBuilder();
tableName(buffer, tableReferenceType);

for (final Table referencedTable : referencedTables) {
buffer
.append(String.format("- %s", identifiers.quoteFullName(referencedTable)))
.append(NEW_LINE);
}
return buffer.toString();
}

private void tableName(final StringBuilder buffer, final TableReferenceType tableReferenceType) {
requireNonNull(buffer);
if (table instanceof View) {
buffer.append("View ");
} else {
buffer.append("Table ");
}
buffer
.append(identifiers.quoteFullName(table))
.append(" has the following ")
.append(tableReferenceType.name())
.append(" tables:")
.append(NEW_LINE);
}
}
@@ -1,3 +1,4 @@
schemacrawler.tools.command.chatgpt.functions.DatabaseObjectListFunctionDefinition
schemacrawler.tools.command.chatgpt.functions.TableDecriptionFunctionDefinition
schemacrawler.tools.command.chatgpt.functions.TableReferencesFunctionDefinition
schemacrawler.tools.command.chatgpt.functions.ExitFunctionDefinition
Expand Up @@ -18,6 +18,6 @@ public void utility() throws Exception {
final Catalog catalog = mock(Catalog.class);
final FunctionExecutor functionExecutor = ChatGPTUtility.newFunctionExecutor(catalog);
assertThat(functionExecutor, is(not(nullValue())));
assertThat(functionExecutor.getFunctions(), hasSize(3));
assertThat(functionExecutor.getFunctions(), hasSize(4));
}
}
Expand Up @@ -11,6 +11,7 @@
import schemacrawler.tools.command.chatgpt.functions.FunctionDefinition;
import schemacrawler.tools.command.chatgpt.functions.FunctionDefinitionRegistry;
import schemacrawler.tools.command.chatgpt.functions.TableDecriptionFunctionDefinition;
import schemacrawler.tools.command.chatgpt.functions.TableReferencesFunctionDefinition;

public class FunctionDefinitionRegistryTest {

Expand All @@ -27,12 +28,13 @@ public void testCommandPlugin() throws Exception {
final FunctionDefinitionRegistry registry =
FunctionDefinitionRegistry.getFunctionDefinitionRegistry();
final Collection<FunctionDefinition> functions = convertIterableToCollection(registry);
assertThat(functions, hasSize(3));
assertThat(functions, hasSize(4));
assertThat(
functions,
containsInAnyOrder(
new DatabaseObjectListFunctionDefinition(),
new TableDecriptionFunctionDefinition(),
new TableReferencesFunctionDefinition(),
new ExitFunctionDefinition()));
}
}

0 comments on commit 704e9f9

Please sign in to comment.