diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/client/Client.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/client/Client.java index 53011f092d7..da8b610b79f 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/client/Client.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/client/Client.java @@ -100,7 +100,8 @@ public Client(MutableList replExtensions, MutableList e.initialize(this)); - this.printDebug("[DEV] Legend REPL v" + DeploymentStateAndVersions.sdlc.buildVersion + " (" + DeploymentStateAndVersions.sdlc.commitIdAbbreviated + ")"); + this.printDebug("[DEV] REPL v" + DeploymentStateAndVersions.sdlc.buildVersion + " (" + DeploymentStateAndVersions.sdlc.commitIdAbbreviated + ")"); + this.printDebug("[DEV] REPL dir: " + this.getHomeDir().toUri()); if (System.getProperty("legend.repl.initializationMessage") != null) { this.printDebug(StringEscapeUtils.unescapeJava(System.getProperty("legend.repl.initializationMessage"))); diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/core/commands/Execute.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/core/commands/Execute.java index 95a45176468..1c42a14b087 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/core/commands/Execute.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/core/commands/Execute.java @@ -31,6 +31,7 @@ import org.jline.reader.ParsedLine; import static org.finos.legend.engine.repl.shared.ExecutionHelper.executeCode; +import static org.finos.legend.engine.repl.shared.ExecutionHelper.printExecutionTime; import static org.finos.legend.engine.repl.shared.REPLHelper.ansiGreen; public class Execute implements Command @@ -51,7 +52,9 @@ public String documentation() @Override public boolean process(String line) throws Exception { + long startTime = System.currentTimeMillis(); this.client.println(execute(line)); + this.client.println(printExecutionTime(startTime)); return true; } diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/shared/ExecutionHelper.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/shared/ExecutionHelper.java index ce92100b332..22384b8fb73 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/shared/ExecutionHelper.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-client/src/main/java/org/finos/legend/engine/repl/shared/ExecutionHelper.java @@ -100,6 +100,11 @@ public static ExecutionHelper.ExecuteResultSummary executeCode(String txt, Clien return resultHandler.value(res, pmcd, pureModel, execPlan); } + public static String printExecutionTime(long startTime) + { + return String.format("%.1f", (float) (System.currentTimeMillis() - startTime) / 1000) + "s"; + } + public static class ExecuteResultSummary { public final PureModelContextData pureModelContextData; diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/client/DataCubeClient.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/client/DataCubeClient.java index 8a7e3667d29..574a731755d 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/client/DataCubeClient.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/client/DataCubeClient.java @@ -14,6 +14,7 @@ package org.finos.legend.engine.repl.dataCube.client; +import org.apache.commons.io.FileUtils; import org.eclipse.collections.impl.factory.Lists; import org.finos.legend.engine.plan.execution.PlanExecutor; import org.finos.legend.engine.repl.client.Client; @@ -21,10 +22,15 @@ import org.finos.legend.engine.repl.relational.RelationalReplExtension; import org.finos.legend.engine.repl.relational.autocomplete.RelationalCompleterExtension; +import java.nio.file.Paths; + public class DataCubeClient { public static void main(String[] args) throws Exception { + // NOTE: this is exclusively used for development of DataCube when we need to boot multiple instances + // of the REPL at the same time and want to avoid locking on the DuckDB instances + String DEV__homeDir = System.getProperty("legend.repl.dataCube.devHomeDir"); Client client = new Client( Lists.mutable.with( new DataCubeReplExtension(), @@ -33,7 +39,8 @@ public static void main(String[] args) throws Exception Lists.mutable.with( new RelationalCompleterExtension() ), - PlanExecutor.newPlanExecutorBuilder().withAvailableStoreExecutors().build() + PlanExecutor.newPlanExecutorBuilder().withAvailableStoreExecutors().build(), + DEV__homeDir != null ? Paths.get(DEV__homeDir) : FileUtils.getUserDirectory().toPath().resolve(".legend/repl") ); client.loop(); } diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/commands/DataCube__DEV__runDuckDBSelectSQL.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/commands/DataCube__DEV__runDuckDBSelectSQL.java index f85cd75da61..6cf2211c234 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/commands/DataCube__DEV__runDuckDBSelectSQL.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/commands/DataCube__DEV__runDuckDBSelectSQL.java @@ -30,6 +30,7 @@ import java.util.List; import static org.finos.legend.engine.plan.execution.stores.relational.result.RelationalResultGridPrintUtility.prettyGridPrint; +import static org.finos.legend.engine.repl.shared.ExecutionHelper.printExecutionTime; public class DataCube__DEV__runDuckDBSelectSQL implements Command { @@ -79,6 +80,7 @@ public boolean process(String line) throws Exception { try (Statement statement = connection.createStatement()) { + long startTime = System.currentTimeMillis(); ResultSet result = statement.executeQuery(expression); List columnNames = Lists.mutable.empty(); List columnTypes = Lists.mutable.empty(); @@ -89,6 +91,7 @@ public boolean process(String line) throws Exception } this.client.println("Executed SELECT SQL: '" + expression + "'"); this.client.println(prettyGridPrint(result, columnNames, columnNames, 40, 60)); + this.client.println(printExecutionTime(startTime)); } } diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/server/REPLServerHelpers.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/server/REPLServerHelpers.java index 78f0ec301cc..22ccbe5464d 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/server/REPLServerHelpers.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-data-cube/src/main/java/org/finos/legend/engine/repl/dataCube/server/REPLServerHelpers.java @@ -119,7 +119,7 @@ private void initialize(PureModelContextData pureModelContextData, Listfrom(), only one is expected"); + throw new RuntimeException("Can't launch DataCube. Source query contains multiple different ->from(), only one is expected"); } runtime = newRuntime; } @@ -130,7 +130,7 @@ else if (fn.parameters.size() == 3) String newRuntime = ((PackageableElementPtr) fn.parameters.get(2)).fullPath; if ((mapping != null && !mapping.equals(newMapping)) || (runtime != null && !runtime.equals(newRuntime))) { - throw new RuntimeException("Can't initialize DataCube. Source query contains multiple different ->from(), only one is expected"); + throw new RuntimeException("Can't launch DataCube. Source query contains multiple different ->from(), only one is expected"); } mapping = newMapping; runtime = newRuntime; @@ -183,7 +183,7 @@ public void initializeFromTable(PureModelContextData pureModelContextData) } catch (Exception e) { - throw new RuntimeException("Can't initialize DataCube: expected to get a relation type"); + throw new RuntimeException("Can't launch DataCube: expected to get a relation type"); } this.initialize(pureModelContextData, ListIterate.collect(RelationTypeHelper.convert(relationType).columns, col -> new DataCubeQueryColumn(col.name, col.type))); } @@ -192,7 +192,7 @@ public void initializeWithREPLExecutedQuery(ExecutionHelper.ExecuteResultSummary { if (!(executeResultSummary.result instanceof RelationalResult) || !(((RelationalResult) executeResultSummary.result).builder instanceof TDSBuilder)) { - throw new RuntimeException("Can't initialize DataCube: last executed query did not produce a TDS (i.e. data-grid), try a different query..."); + throw new RuntimeException("Can't launch DataCube: last executed query did not produce a TDS (i.e. data-grid), try a different query..."); } RelationType relationType; @@ -202,7 +202,7 @@ public void initializeWithREPLExecutedQuery(ExecutionHelper.ExecuteResultSummary } catch (Exception e) { - throw new RuntimeException("Can't initialize DataCube: last executed query must return a relation type, try a different query..."); + throw new RuntimeException("Can't launch DataCube: last executed query must return a relation type, try a different query..."); } boolean isDynamic = false; @@ -220,7 +220,7 @@ public void initializeWithREPLExecutedQuery(ExecutionHelper.ExecuteResultSummary } if (isDynamic) { - throw new RuntimeException("Can't initialize DataCube: last executed query produced dynamic result, try casting the result with cast(@" + M3Paths.Relation + "<(...)>) syntax or use 'cache' command to dump the data out to a table and query against that table instead..."); + throw new RuntimeException("Can't launch DataCube: last executed query produced dynamic result, try casting the result with cast(@" + M3Paths.Relation + "<(...)>) syntax or use 'cache' command to dump the data out to a table and query against that table instead..."); } RelationalResult result = (RelationalResult) executeResultSummary.result; diff --git a/legend-engine-config/legend-engine-repl/legend-engine-repl-relational/src/main/java/org/finos/legend/engine/repl/relational/commands/Cache.java b/legend-engine-config/legend-engine-repl/legend-engine-repl-relational/src/main/java/org/finos/legend/engine/repl/relational/commands/Cache.java index f8d9a71d106..61fe2eae5ba 100644 --- a/legend-engine-config/legend-engine-repl/legend-engine-repl-relational/src/main/java/org/finos/legend/engine/repl/relational/commands/Cache.java +++ b/legend-engine-config/legend-engine-repl/legend-engine-repl-relational/src/main/java/org/finos/legend/engine/repl/relational/commands/Cache.java @@ -46,6 +46,7 @@ import static org.finos.legend.engine.repl.relational.schema.MetadataReader.getTables; import static org.finos.legend.engine.repl.shared.ExecutionHelper.executeCode; +import static org.finos.legend.engine.repl.shared.ExecutionHelper.printExecutionTime; public class Cache implements Command { @@ -91,6 +92,7 @@ public boolean process(String line) throws Exception try { + long startTime = System.currentTimeMillis(); executeCode(expression, this.client, (Result res, PureModelContextData pmcd, PureModel pureModel, SingleExecutionPlan plan) -> { if (res instanceof RelationalResult) @@ -117,6 +119,7 @@ public boolean process(String line) throws Exception { statement.executeUpdate(DatabaseManager.fromString(databaseConnection.type.name()).relationalDatabaseSupport().load(tableName, tempFile.getTemporaryPathForFile(), relationalResultColumns)); this.client.println("Cached into table: '" + tableName + "'"); + this.client.println(printExecutionTime(startTime)); } } catch (SQLException e)