From b6ac71ffd587d7e7c76f4ebced34d35f2b7c1259 Mon Sep 17 00:00:00 2001 From: Nikita Makarov Date: Thu, 2 Dec 2021 16:15:45 +0300 Subject: [PATCH 1/3] feat: support SQL query formatting in WebServiceSQL. --- .../service/sql/WebServiceBindingSQL.java | 201 +++++++++--------- .../service/sql/impl/WebServiceSQL.java | 15 +- 2 files changed, 116 insertions(+), 100 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index ca74cb8adf..1aeaaf896f 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -49,108 +49,117 @@ public class WebServiceBindingSQL extends WebServiceBindingBase i @Override public void bindWiring(DBWBindingContext model) throws DBWebException { model.getQueryType() - .dataFetcher("sqlDialectInfo", env -> - getService(env).getDialectInfo(getSQLProcessor(env)) - ) - .dataFetcher("sqlListContexts", env -> - getService(env).listContexts(getWebSession(env), - env.getArgument("connectionId"), - env.getArgument("contextId")) - ) - .dataFetcher("sqlCompletionProposals", env -> - getService(env).getCompletionProposals( - getSQLContext(env), - env.getArgument("query"), - env.getArgument("position"), - env.getArgument("maxResults"), - env.getArgument("simpleMode") + .dataFetcher("sqlDialectInfo", env -> + getService(env).getDialectInfo(getSQLProcessor(env)) + ) + .dataFetcher("sqlListContexts", env -> + getService(env).listContexts(getWebSession(env), + env.getArgument("connectionId"), + env.getArgument("contextId")) + ) + .dataFetcher("sqlCompletionProposals", env -> + getService(env).getCompletionProposals( + getSQLContext(env), + env.getArgument("query"), + env.getArgument("position"), + env.getArgument("maxResults"), + env.getArgument("simpleMode") + ) + ) + .dataFetcher("sqlFormatQuery", env -> + getService(env).formatQuery( + getSQLContext(env), + env.getArgument("query") + ) + ) + .dataFetcher("sqlSupportedOperations", env -> + getService(env).getSupportedOperations( + getSQLContext(env), + env.getArgument("resultsId"), + env.getArgument("attributeIndex")) + ) + .dataFetcher("sqlEntityQueryGenerators", env -> + getService(env).getEntityQueryGenerators( + getWebSession(env), + env.getArgument("nodePathList")) + ) + .dataFetcher("sqlGenerateEntityQuery", env -> + getService(env).generateEntityQuery( + getWebSession(env), + env.getArgument("generatorId"), + env.getArgument("options"), + env.getArgument("nodePathList")) ) - ) - .dataFetcher("sqlSupportedOperations", env -> - getService(env).getSupportedOperations( - getSQLContext(env), - env.getArgument("resultsId"), - env.getArgument("attributeIndex")) - ) - .dataFetcher("sqlEntityQueryGenerators", env -> - getService(env).getEntityQueryGenerators( - getWebSession(env), - env.getArgument("nodePathList")) - ) - .dataFetcher("sqlGenerateEntityQuery", env -> - getService(env).generateEntityQuery( - getWebSession(env), - env.getArgument("generatorId"), - env.getArgument("options"), - env.getArgument("nodePathList")) - ) ; model.getMutationType() - .dataFetcher("sqlContextCreate", env -> getService(env).createContext( - getSQLProcessor(env), - env.getArgument("defaultCatalog"), - env.getArgument("defaultSchema"))) - .dataFetcher("sqlContextDestroy", env -> { getService(env).destroyContext(getSQLContext(env)); return true; } ) - .dataFetcher("sqlContextSetDefaults", env -> { - getService(env).setContextDefaults( - getSQLContext(env), - env.getArgument("defaultCatalog"), - env.getArgument("defaultSchema")); + .dataFetcher("sqlContextCreate", env -> getService(env).createContext( + getSQLProcessor(env), + env.getArgument("defaultCatalog"), + env.getArgument("defaultSchema"))) + .dataFetcher("sqlContextDestroy", env -> { + getService(env).destroyContext(getSQLContext(env)); return true; - }) + }) + .dataFetcher("sqlContextSetDefaults", env -> { + getService(env).setContextDefaults( + getSQLContext(env), + env.getArgument("defaultCatalog"), + env.getArgument("defaultSchema")); + return true; + }) - .dataFetcher("sqlResultClose", env -> - getService(env).closeResult( - getSQLContext(env), - env.getArgument("resultId"))) + .dataFetcher("sqlResultClose", env -> + getService(env).closeResult( + getSQLContext(env), + env.getArgument("resultId"))) - .dataFetcher("updateResultsDataBatch", env -> - getService(env).updateResultsDataBatch( - getSQLContext(env), - env.getArgument("resultsId"), - getResultsRow(env, "updatedRows"), - getResultsRow(env, "deletedRows"), - getResultsRow(env, "addedRows"), - getDataFormat(env))) - .dataFetcher("updateResultsDataBatchScript", env -> - getService(env).updateResultsDataBatchScript( - getSQLContext(env), - env.getArgument("resultsId"), - getResultsRow(env, "updatedRows"), - getResultsRow(env, "deletedRows"), - getResultsRow(env, "addedRows"), - getDataFormat(env))) + .dataFetcher("updateResultsDataBatch", env -> + getService(env).updateResultsDataBatch( + getSQLContext(env), + env.getArgument("resultsId"), + getResultsRow(env, "updatedRows"), + getResultsRow(env, "deletedRows"), + getResultsRow(env, "addedRows"), + getDataFormat(env))) + .dataFetcher("updateResultsDataBatchScript", env -> + getService(env).updateResultsDataBatchScript( + getSQLContext(env), + env.getArgument("resultsId"), + getResultsRow(env, "updatedRows"), + getResultsRow(env, "deletedRows"), + getResultsRow(env, "addedRows"), + getDataFormat(env))) - .dataFetcher("asyncSqlExecuteQuery", env -> - getService(env).asyncExecuteQuery( - getSQLContext(env), - env.getArgument("sql"), - env.getArgument("resultId"), - getDataFilter(env), - getDataFormat(env))) - .dataFetcher("asyncReadDataFromContainer", env -> - getService(env).asyncReadDataFromContainer( - getSQLContext(env), - env.getArgument("containerNodePath"), - env.getArgument("resultId"), - getDataFilter(env), - getDataFormat(env) - )) - .dataFetcher("asyncSqlExecuteResults", env -> - getService(env).asyncGetQueryResults( - getWebSession(env), env.getArgument("taskId") - )) - .dataFetcher("asyncSqlExplainExecutionPlan", env -> - getService(env).asyncSqlExplainExecutionPlan( - getSQLContext(env), - env.getArgument("query"), - env.getArgument("configuration") - )) - .dataFetcher("asyncSqlExplainExecutionPlanResult", env -> - getService(env).asyncSqlExplainExecutionPlanResult( - getWebSession(env), env.getArgument("taskId") - )); + .dataFetcher("asyncSqlExecuteQuery", env -> + getService(env).asyncExecuteQuery( + getSQLContext(env), + env.getArgument("sql"), + env.getArgument("resultId"), + getDataFilter(env), + getDataFormat(env))) + .dataFetcher("asyncReadDataFromContainer", env -> + getService(env).asyncReadDataFromContainer( + getSQLContext(env), + env.getArgument("containerNodePath"), + env.getArgument("resultId"), + getDataFilter(env), + getDataFormat(env) + )) + .dataFetcher("asyncSqlExecuteResults", env -> + getService(env).asyncGetQueryResults( + getWebSession(env), env.getArgument("taskId") + )) + .dataFetcher("asyncSqlExplainExecutionPlan", env -> + getService(env).asyncSqlExplainExecutionPlan( + getSQLContext(env), + env.getArgument("query"), + env.getArgument("configuration") + )) + .dataFetcher("asyncSqlExplainExecutionPlanResult", env -> + getService(env).asyncSqlExplainExecutionPlanResult( + getWebSession(env), env.getArgument("taskId") + )); } @NotNull @@ -199,8 +208,8 @@ public class WebServiceBindingSQL extends WebServiceBindingBase i @Override public void addServlets(CBApplication application, ServletContextHandler servletContextHandler) { servletContextHandler.addServlet( - new ServletHolder("sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl())), - application.getServicesURI() + "sql-result-value/*"); + new ServletHolder("sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl())), + application.getServicesURI() + "sql-result-value/*"); } private static class WebSQLConfiguration { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java index e204b5803f..254446a4b3 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java @@ -35,13 +35,11 @@ import org.jkiss.dbeaver.model.exec.DBCLogicalOperator; import org.jkiss.dbeaver.model.exec.DBExecUtils; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import org.jkiss.dbeaver.model.sql.SQLDialect; -import org.jkiss.dbeaver.model.sql.SQLQuery; -import org.jkiss.dbeaver.model.sql.SQLScriptElement; -import org.jkiss.dbeaver.model.sql.SQLUtils; +import org.jkiss.dbeaver.model.sql.*; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionAnalyzer; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionRequest; +import org.jkiss.dbeaver.model.sql.format.SQLFormatUtils; import org.jkiss.dbeaver.model.sql.generator.SQLGenerator; import org.jkiss.dbeaver.model.sql.parser.SQLParserContext; import org.jkiss.dbeaver.model.sql.parser.SQLScriptParser; @@ -151,6 +149,15 @@ public class WebServiceSQL implements DBWServiceSQL { } } + @NotNull + public String formatQuery(@NotNull WebSQLContextInfo sqlContext, @NotNull String query) throws DBWebException { + DBPDataSource dataSource = sqlContext.getProcessor().getConnection().getDataSourceContainer().getDataSource(); + if (dataSource == null) { + throw new DBWebException("DataSource is null: can't format SQL query"); + } + return SQLFormatUtils.formatSQL(dataSource, query); + } + @Override public DBCLogicalOperator[] getSupportedOperations(@NotNull WebSQLContextInfo contextInfo, @NotNull String resultsId, int attributeIndex) throws DBWebException { WebSQLResultsInfo results = contextInfo.getResults(resultsId); From b9758651e0bd04aeafd5271a450961b37b460e78 Mon Sep 17 00:00:00 2001 From: Nikita Makarov Date: Thu, 2 Dec 2021 16:18:15 +0300 Subject: [PATCH 2/3] feat: support SQL query formatting in WebServiceSQL. --- .../src/io/cloudbeaver/service/sql/DBWServiceSQL.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java index 594b967589..ac9c326f93 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java @@ -49,6 +49,9 @@ public interface DBWServiceSQL extends DBWService { Integer maxResults, Boolean simpleMode) throws DBWebException; + @WebAction + String formatQuery(@NotNull WebSQLContextInfo sqlContext, @NotNull String query) throws DBWebException; + @WebAction DBCLogicalOperator[] getSupportedOperations( @NotNull WebSQLContextInfo contextInfo, From 590af9b23c2f252596dd5634388a4b792e733118 Mon Sep 17 00:00:00 2001 From: Nikita Makarov Date: Thu, 2 Dec 2021 17:13:44 +0300 Subject: [PATCH 3/3] style: fix continuous tab in WebServiceBindingSQL. --- .../service/sql/WebServiceBindingSQL.java | 207 +++++++++--------- 1 file changed, 102 insertions(+), 105 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index 1aeaaf896f..af1b31c0d7 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -49,117 +49,114 @@ public class WebServiceBindingSQL extends WebServiceBindingBase i @Override public void bindWiring(DBWBindingContext model) throws DBWebException { model.getQueryType() - .dataFetcher("sqlDialectInfo", env -> - getService(env).getDialectInfo(getSQLProcessor(env)) + .dataFetcher("sqlDialectInfo", env -> + getService(env).getDialectInfo(getSQLProcessor(env)) + ) + .dataFetcher("sqlListContexts", env -> + getService(env).listContexts(getWebSession(env), + env.getArgument("connectionId"), + env.getArgument("contextId")) + ) + .dataFetcher("sqlCompletionProposals", env -> + getService(env).getCompletionProposals( + getSQLContext(env), + env.getArgument("query"), + env.getArgument("position"), + env.getArgument("maxResults"), + env.getArgument("simpleMode") ) - .dataFetcher("sqlListContexts", env -> - getService(env).listContexts(getWebSession(env), - env.getArgument("connectionId"), - env.getArgument("contextId")) - ) - .dataFetcher("sqlCompletionProposals", env -> - getService(env).getCompletionProposals( - getSQLContext(env), - env.getArgument("query"), - env.getArgument("position"), - env.getArgument("maxResults"), - env.getArgument("simpleMode") - ) - ) - .dataFetcher("sqlFormatQuery", env -> - getService(env).formatQuery( - getSQLContext(env), - env.getArgument("query") - ) - ) - .dataFetcher("sqlSupportedOperations", env -> - getService(env).getSupportedOperations( - getSQLContext(env), - env.getArgument("resultsId"), - env.getArgument("attributeIndex")) - ) - .dataFetcher("sqlEntityQueryGenerators", env -> - getService(env).getEntityQueryGenerators( - getWebSession(env), - env.getArgument("nodePathList")) - ) - .dataFetcher("sqlGenerateEntityQuery", env -> - getService(env).generateEntityQuery( - getWebSession(env), - env.getArgument("generatorId"), - env.getArgument("options"), - env.getArgument("nodePathList")) + ) + .dataFetcher("sqlFormatQuery", env -> + getService(env).formatQuery( + getSQLContext(env), + env.getArgument("query") ) + ) + .dataFetcher("sqlSupportedOperations", env -> + getService(env).getSupportedOperations( + getSQLContext(env), + env.getArgument("resultsId"), + env.getArgument("attributeIndex")) + ) + .dataFetcher("sqlEntityQueryGenerators", env -> + getService(env).getEntityQueryGenerators( + getWebSession(env), + env.getArgument("nodePathList")) + ) + .dataFetcher("sqlGenerateEntityQuery", env -> + getService(env).generateEntityQuery( + getWebSession(env), + env.getArgument("generatorId"), + env.getArgument("options"), + env.getArgument("nodePathList")) + ) ; model.getMutationType() - .dataFetcher("sqlContextCreate", env -> getService(env).createContext( - getSQLProcessor(env), - env.getArgument("defaultCatalog"), - env.getArgument("defaultSchema"))) - .dataFetcher("sqlContextDestroy", env -> { - getService(env).destroyContext(getSQLContext(env)); - return true; - }) - .dataFetcher("sqlContextSetDefaults", env -> { - getService(env).setContextDefaults( - getSQLContext(env), - env.getArgument("defaultCatalog"), - env.getArgument("defaultSchema")); - return true; - }) + .dataFetcher("sqlContextCreate", env -> getService(env).createContext( + getSQLProcessor(env), + env.getArgument("defaultCatalog"), + env.getArgument("defaultSchema"))) + .dataFetcher("sqlContextDestroy", env -> { getService(env).destroyContext(getSQLContext(env)); return true; } ) + .dataFetcher("sqlContextSetDefaults", env -> { + getService(env).setContextDefaults( + getSQLContext(env), + env.getArgument("defaultCatalog"), + env.getArgument("defaultSchema")); + return true; + }) - .dataFetcher("sqlResultClose", env -> - getService(env).closeResult( - getSQLContext(env), - env.getArgument("resultId"))) + .dataFetcher("sqlResultClose", env -> + getService(env).closeResult( + getSQLContext(env), + env.getArgument("resultId"))) - .dataFetcher("updateResultsDataBatch", env -> - getService(env).updateResultsDataBatch( - getSQLContext(env), - env.getArgument("resultsId"), - getResultsRow(env, "updatedRows"), - getResultsRow(env, "deletedRows"), - getResultsRow(env, "addedRows"), - getDataFormat(env))) - .dataFetcher("updateResultsDataBatchScript", env -> - getService(env).updateResultsDataBatchScript( - getSQLContext(env), - env.getArgument("resultsId"), - getResultsRow(env, "updatedRows"), - getResultsRow(env, "deletedRows"), - getResultsRow(env, "addedRows"), - getDataFormat(env))) + .dataFetcher("updateResultsDataBatch", env -> + getService(env).updateResultsDataBatch( + getSQLContext(env), + env.getArgument("resultsId"), + getResultsRow(env, "updatedRows"), + getResultsRow(env, "deletedRows"), + getResultsRow(env, "addedRows"), + getDataFormat(env))) + .dataFetcher("updateResultsDataBatchScript", env -> + getService(env).updateResultsDataBatchScript( + getSQLContext(env), + env.getArgument("resultsId"), + getResultsRow(env, "updatedRows"), + getResultsRow(env, "deletedRows"), + getResultsRow(env, "addedRows"), + getDataFormat(env))) - .dataFetcher("asyncSqlExecuteQuery", env -> - getService(env).asyncExecuteQuery( - getSQLContext(env), - env.getArgument("sql"), - env.getArgument("resultId"), - getDataFilter(env), - getDataFormat(env))) - .dataFetcher("asyncReadDataFromContainer", env -> - getService(env).asyncReadDataFromContainer( - getSQLContext(env), - env.getArgument("containerNodePath"), - env.getArgument("resultId"), - getDataFilter(env), - getDataFormat(env) - )) - .dataFetcher("asyncSqlExecuteResults", env -> - getService(env).asyncGetQueryResults( - getWebSession(env), env.getArgument("taskId") - )) - .dataFetcher("asyncSqlExplainExecutionPlan", env -> - getService(env).asyncSqlExplainExecutionPlan( - getSQLContext(env), - env.getArgument("query"), - env.getArgument("configuration") - )) - .dataFetcher("asyncSqlExplainExecutionPlanResult", env -> - getService(env).asyncSqlExplainExecutionPlanResult( - getWebSession(env), env.getArgument("taskId") - )); + .dataFetcher("asyncSqlExecuteQuery", env -> + getService(env).asyncExecuteQuery( + getSQLContext(env), + env.getArgument("sql"), + env.getArgument("resultId"), + getDataFilter(env), + getDataFormat(env))) + .dataFetcher("asyncReadDataFromContainer", env -> + getService(env).asyncReadDataFromContainer( + getSQLContext(env), + env.getArgument("containerNodePath"), + env.getArgument("resultId"), + getDataFilter(env), + getDataFormat(env) + )) + .dataFetcher("asyncSqlExecuteResults", env -> + getService(env).asyncGetQueryResults( + getWebSession(env), env.getArgument("taskId") + )) + .dataFetcher("asyncSqlExplainExecutionPlan", env -> + getService(env).asyncSqlExplainExecutionPlan( + getSQLContext(env), + env.getArgument("query"), + env.getArgument("configuration") + )) + .dataFetcher("asyncSqlExplainExecutionPlanResult", env -> + getService(env).asyncSqlExplainExecutionPlanResult( + getWebSession(env), env.getArgument("taskId") + )); } @NotNull @@ -208,8 +205,8 @@ public class WebServiceBindingSQL extends WebServiceBindingBase i @Override public void addServlets(CBApplication application, ServletContextHandler servletContextHandler) { servletContextHandler.addServlet( - new ServletHolder("sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl())), - application.getServicesURI() + "sql-result-value/*"); + new ServletHolder("sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl())), + application.getServicesURI() + "sql-result-value/*"); } private static class WebSQLConfiguration {