From 3ddcd0a5d9fe7cd7a8b9fd6608774cc734452585 Mon Sep 17 00:00:00 2001 From: Tsimafei Labanovich Date: Thu, 14 May 2026 10:30:56 +0200 Subject: [PATCH 1/3] dbeaver/dbvr#94 Fix meta ddl message --- .../cli/sql/meta/ddl/AbstractDDLCommand.java | 31 +++++++----- .../cli/sql/meta/ddl/DatabaseDDLCommand.java | 47 ++++++++++++++++++- .../org/dbvr/test/MetaLocalCommandTest.java | 26 +++++++++- 3 files changed, 90 insertions(+), 14 deletions(-) diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java index 8d931b0..f67fa92 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java @@ -57,20 +57,20 @@ protected abstract DBSObjectContainer getBaseContainer( @Override public void run() throws CLIException { + getParentCommand().executeWithMonitor("Get " + getObjectTypeName() + " DDL", this::execute); + } + + protected void execute(@NotNull DBRProgressMonitor monitor) throws DBException { AbstractMetaObjectCommand parent = getParentCommand(); + DBPDataSource dataSource = connectDataSource(); + checkDDLSupported(monitor, dataSource); String objectName = getTargetObjectName(); if (CommonUtils.isEmpty(objectName)) { throw new CLIException( - "Object name is not specified", + getObjectTypeName() + " name is not specified", CLIConstants.EXIT_CODE_ILLEGAL_ARGUMENTS ); } - parent.executeWithMonitor("Get " + getObjectTypeName() + " DDL", monitor -> execute(monitor, objectName)); - } - - protected void execute(@NotNull DBRProgressMonitor monitor, @NotNull String objectName) throws DBException { - AbstractMetaObjectCommand parent = getParentCommand(); - DBPDataSource dataSource = connectDataSource(); DBSObjectContainer container = getBaseContainer(monitor, dataSource); if (container == null) { return; @@ -90,10 +90,19 @@ protected void execute(@NotNull DBRProgressMonitor monitor, @NotNull String obje context().addResult(ddl.trim()); context().setPostAction(CLIProcessResult.PostAction.SHUTDOWN); } else { - throw new CLIException( - getObjectTypeName() + " '" + objectName + "' does not support DDL", - CLIConstants.EXIT_CODE_ERROR - ); + throw new CLIException(getUnsupportedDDLMessage(objectName), CLIConstants.EXIT_CODE_ERROR); } } + + protected void checkDDLSupported( + @NotNull DBRProgressMonitor monitor, + @NotNull DBPDataSource dataSource + ) throws DBException { + // supported by default + } + + @NotNull + protected String getUnsupportedDDLMessage(@NotNull String objectName) { + return getObjectTypeName() + " '" + objectName + "' does not support DDL"; + } } diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java index 3e2da2b..1e28c25 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java @@ -23,13 +23,22 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.DBPDataSource; +import org.jkiss.dbeaver.model.cli.CLIConstants; +import org.jkiss.dbeaver.model.cli.CLIException; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSObjectContainer; +import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog; import picocli.CommandLine; +import java.util.Collection; + @CommandLine.Command(name = "ddl", description = "Get database DDL") public class DatabaseDDLCommand extends AbstractDDLCommand { + private static final String UNSUPPORTED_MESSAGE = "Database DDL is not supported for this database type. " + + "Try a lower-level DDL command, such as 'meta schema ddl' or 'meta table ddl'."; + @CommandLine.ParentCommand private DatabaseCommand parent; @@ -60,6 +69,42 @@ protected DBSObjectContainer getBaseContainer( @NotNull DBRProgressMonitor monitor, @NotNull DBPDataSource dataSource ) throws DBException { - return parent.getBaseContainer(monitor, dataSource, containerOptions.getDatabaseName(), null); + // The database is the target object itself, so the datasource is the base container to search in. + return parent.getBaseContainer(monitor, dataSource, null, null); + } + + @Override + protected void checkDDLSupported( + @NotNull DBRProgressMonitor monitor, + @NotNull DBPDataSource dataSource + ) throws DBException { + if (!hasDatabases(monitor, dataSource)) { + throw new CLIException(UNSUPPORTED_MESSAGE, CLIConstants.EXIT_CODE_ERROR); + } + } + + @NotNull + @Override + protected String getUnsupportedDDLMessage(@NotNull String objectName) { + return UNSUPPORTED_MESSAGE; + } + + private boolean hasDatabases( + @NotNull DBRProgressMonitor monitor, + @NotNull DBPDataSource dataSource + ) throws DBException { + if (!(dataSource instanceof DBSObjectContainer container)) { + return false; + } + Collection children = container.getChildren(monitor); + if (children == null) { + return false; + } + for (DBSObject child : children) { + if (child instanceof DBSCatalog) { + return true; + } + } + return false; } } diff --git a/test/org.dbvr.test.platform/src/org/dbvr/test/MetaLocalCommandTest.java b/test/org.dbvr.test.platform/src/org/dbvr/test/MetaLocalCommandTest.java index de92a64..64edefc 100644 --- a/test/org.dbvr.test.platform/src/org/dbvr/test/MetaLocalCommandTest.java +++ b/test/org.dbvr.test.platform/src/org/dbvr/test/MetaLocalCommandTest.java @@ -222,9 +222,31 @@ public void testDatabaseDDL() throws Exception { CLIProcessResult ddlResult = cmd.executeCommandLineCommands(null, false, false, ddlArgs); Assert.assertNotNull(ddlResult); String ddlOutput = ddlResult.getOutput() != null ? String.join("\n", ddlResult.getOutput()) : ""; - Assert.assertEquals(CLIConstants.EXIT_CODE_OK, ddlResult.getExitCode()); + Assert.assertEquals(CLIConstants.EXIT_CODE_ERROR, ddlResult.getExitCode()); Assert.assertTrue( - ddlOutput.contains("Database doesn't support databases/catalogs") + ddlOutput.contains("Database DDL is not supported for this database type") + ); + } finally { + h2Ds.getRegistry().removeDataSource(h2Ds); + } + } + + @Test + public void testDatabaseDDLNoDatabaseName() throws Exception { + DBPDataSourceContainer h2Ds = createFakeDataSource("h2-test-db-ddl-noname"); + try { + var cmd = DBVRTestSuite.getApplication().createCommandLine(); + var ddlArgs = new String[] { + "meta", "database", "ddl", + "--datasource=" + h2Ds.getName() + }; + CLIProcessResult ddlResult = cmd.executeCommandLineCommands(null, false, false, ddlArgs); + Assert.assertNotNull(ddlResult); + String ddlOutput = ddlResult.getOutput() != null ? String.join("\n", ddlResult.getOutput()) : ""; + Assert.assertEquals(CLIConstants.EXIT_CODE_ERROR, ddlResult.getExitCode()); + Assert.assertTrue( + "Output should explain that database DDL is unsupported, but was: " + ddlOutput, + ddlOutput.contains("Database DDL is not supported for this database type") ); } finally { h2Ds.getRegistry().removeDataSource(h2Ds); From 380163152705a9f6db6122600efcecc844c0332e Mon Sep 17 00:00:00 2001 From: Tsimafei Labanovich Date: Mon, 18 May 2026 10:45:12 +0200 Subject: [PATCH 2/3] dbeaver/dbvr#94 Extract meta command names to constants --- .../src/org/dbvr/cli/sql/meta/DatabaseCommand.java | 3 ++- .../src/org/dbvr/cli/sql/meta/SchemaCommand.java | 3 ++- .../src/org/dbvr/cli/sql/meta/TableCommand.java | 3 ++- .../org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java | 2 ++ .../org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java | 11 +++++++++-- .../org/dbvr/cli/sql/meta/ddl/SchemaDDLCommand.java | 2 +- .../org/dbvr/cli/sql/meta/ddl/TableDDLCommand.java | 2 +- 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/DatabaseCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/DatabaseCommand.java index 3429c33..96181bc 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/DatabaseCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/DatabaseCommand.java @@ -30,12 +30,13 @@ import picocli.CommandLine; -@CommandLine.Command(name = "database", description = "Database (catalog) operations", +@CommandLine.Command(name = DatabaseCommand.COMMAND_NAME, description = "Database (catalog) operations", subcommands = { DatabaseListCommand.class, DatabaseDDLCommand.class }) public class DatabaseCommand extends AbstractMetaObjectCommand { + public static final String COMMAND_NAME = "database"; @Override public boolean isRelevantObject(@NotNull DBSObject object) { diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/SchemaCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/SchemaCommand.java index 650c92b..fa575be 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/SchemaCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/SchemaCommand.java @@ -29,12 +29,13 @@ import org.jkiss.dbeaver.model.struct.rdb.DBSSchema; import picocli.CommandLine; -@CommandLine.Command(name = "schema", description = "Schema operations", +@CommandLine.Command(name = SchemaCommand.COMMAND_NAME, description = "Schema operations", subcommands = { SchemaListCommand.class, SchemaDDLCommand.class }) public class SchemaCommand extends AbstractMetaObjectCommand { + public static final String COMMAND_NAME = "schema"; @Override public boolean isRelevantObject(@NotNull DBSObject object) { diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/TableCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/TableCommand.java index 7d307c8..274b11a 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/TableCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/TableCommand.java @@ -29,12 +29,13 @@ import org.jkiss.dbeaver.model.struct.DBSObjectContainer; import picocli.CommandLine; -@CommandLine.Command(name = "table", description = "Table meta operations", +@CommandLine.Command(name = TableCommand.COMMAND_NAME, description = "Table meta operations", subcommands = { TableListCommand.class, TableDDLCommand.class }) public class TableCommand extends AbstractMetaObjectCommand { + public static final String COMMAND_NAME = "table"; @Override public boolean isRelevantObject(@NotNull DBSObject object) { diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java index f67fa92..96a347c 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/AbstractDDLCommand.java @@ -37,6 +37,8 @@ public abstract class AbstractDDLCommand extends AbstractMetaCommand { + public static final String COMMAND_NAME = "ddl"; + @CommandLine.Option(names = {"--full"}, description = "Show full DDL") protected boolean fullDDL; diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java index 1e28c25..88158c9 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java @@ -18,7 +18,10 @@ import org.dbvr.cli.sql.meta.AbstractMetaObjectCommand; import org.dbvr.cli.sql.meta.DatabaseCommand; +import org.dbvr.cli.sql.meta.MetaCommand; import org.dbvr.cli.sql.meta.MetaDatabaseOptions; +import org.dbvr.cli.sql.meta.SchemaCommand; +import org.dbvr.cli.sql.meta.TableCommand; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; @@ -33,11 +36,15 @@ import java.util.Collection; -@CommandLine.Command(name = "ddl", description = "Get database DDL") +@CommandLine.Command(name = AbstractDDLCommand.COMMAND_NAME, description = "Get database DDL") public class DatabaseDDLCommand extends AbstractDDLCommand { private static final String UNSUPPORTED_MESSAGE = "Database DDL is not supported for this database type. " + - "Try a lower-level DDL command, such as 'meta schema ddl' or 'meta table ddl'."; + "Try a lower-level DDL command, such as '" + + MetaCommand.COMMAND_NAME + " " + SchemaCommand.COMMAND_NAME + " " + AbstractDDLCommand.COMMAND_NAME + + "' or '" + + MetaCommand.COMMAND_NAME + " " + TableCommand.COMMAND_NAME + " " + AbstractDDLCommand.COMMAND_NAME + + "'."; @CommandLine.ParentCommand private DatabaseCommand parent; diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/SchemaDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/SchemaDDLCommand.java index 29f2e94..fe96cd7 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/SchemaDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/SchemaDDLCommand.java @@ -27,7 +27,7 @@ import org.jkiss.dbeaver.model.struct.DBSObjectContainer; import picocli.CommandLine; -@CommandLine.Command(name = "ddl", description = "Get schema DDL") +@CommandLine.Command(name = AbstractDDLCommand.COMMAND_NAME, description = "Get schema DDL") public class SchemaDDLCommand extends AbstractDDLCommand { @CommandLine.ParentCommand diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/TableDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/TableDDLCommand.java index 955ddc2..7f444a7 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/TableDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/TableDDLCommand.java @@ -27,7 +27,7 @@ import org.jkiss.dbeaver.model.struct.DBSObjectContainer; import picocli.CommandLine; -@CommandLine.Command(name = "ddl", description = "Get table DDL") +@CommandLine.Command(name = AbstractDDLCommand.COMMAND_NAME, description = "Get table DDL") public class TableDDLCommand extends AbstractDDLCommand { @CommandLine.ParentCommand From 2edd02f49b39b707e0b87974517707d4951cf8c8 Mon Sep 17 00:00:00 2001 From: Tsimafei Labanovich Date: Mon, 18 May 2026 12:51:34 +0200 Subject: [PATCH 3/3] dbeaver/dbvr#94 Remove comment --- .../src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java index 88158c9..d22f1b2 100644 --- a/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java +++ b/bundles/org.dbvr.cli.sql/src/org/dbvr/cli/sql/meta/ddl/DatabaseDDLCommand.java @@ -16,12 +16,7 @@ */ package org.dbvr.cli.sql.meta.ddl; -import org.dbvr.cli.sql.meta.AbstractMetaObjectCommand; -import org.dbvr.cli.sql.meta.DatabaseCommand; -import org.dbvr.cli.sql.meta.MetaCommand; -import org.dbvr.cli.sql.meta.MetaDatabaseOptions; -import org.dbvr.cli.sql.meta.SchemaCommand; -import org.dbvr.cli.sql.meta.TableCommand; +import org.dbvr.cli.sql.meta.*; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; @@ -76,7 +71,6 @@ protected DBSObjectContainer getBaseContainer( @NotNull DBRProgressMonitor monitor, @NotNull DBPDataSource dataSource ) throws DBException { - // The database is the target object itself, so the datasource is the base container to search in. return parent.getBaseContainer(monitor, dataSource, null, null); }