getName2TableOutputFormatStyle() {
return BuiltInTableOutputFormatStyles.BY_NAME;
}
+
+ /**
+ * Override this method to modify available script engine names.
+ *
+ * If method is not overridden, current set of engine names will
+ * contain first non intersected values (ordered by abc).
+ *
+ * @return Set of available script engine names
+ */
+ public Set getAvailableScriptEngineNames() {
+ final Set result = new HashSet<>();
+ final Map> fName2Aliases = new HashMap<>();
+ final List factories =
+ new ScriptEngineManager().getEngineFactories();
+ for (ScriptEngineFactory factory: factories) {
+ fName2Aliases.put(factory.getEngineName(),
+ new HashSet<>(factory.getNames()));
+ }
+ for (Map.Entry> fEntry: fName2Aliases.entrySet()) {
+ Set aliases = new TreeSet<>(fEntry.getValue());
+ for (Map.Entry> fEntry2: fName2Aliases.entrySet()) {
+ if (fEntry.getKey().equals(fEntry2.getKey())) {
+ continue;
+ }
+ aliases.removeAll(fEntry2.getValue());
+ }
+ if (!aliases.isEmpty()) {
+ result.add(aliases.iterator().next());
+ }
+ }
+ return result;
+ }
}
// End Application.java
diff --git a/src/main/java/sqlline/BuiltInProperty.java b/src/main/java/sqlline/BuiltInProperty.java
index c2a2c146..4f524f20 100644
--- a/src/main/java/sqlline/BuiltInProperty.java
+++ b/src/main/java/sqlline/BuiltInProperty.java
@@ -87,6 +87,8 @@ public enum BuiltInProperty implements SqlLineProperty {
RIGHT_PROMPT("rightPrompt", Type.STRING, ""),
ROW_LIMIT("rowLimit", Type.INTEGER, 0),
SHOW_ELAPSED_TIME("showElapsedTime", Type.BOOLEAN, true),
+ SCRIPT_ENGINE("scriptEngine", Type.STRING, "nashorn", true, false,
+ new Application().getAvailableScriptEngineNames()),
SHOW_COMPLETION_DESCR("showCompletionDesc", Type.BOOLEAN, true),
SHOW_HEADER("showHeader", Type.BOOLEAN, true),
SHOW_LINE_NUMBERS("showLineNumbers", Type.BOOLEAN, false),
diff --git a/src/main/java/sqlline/PromptHandler.java b/src/main/java/sqlline/PromptHandler.java
index 479bf8a9..098e5f1d 100644
--- a/src/main/java/sqlline/PromptHandler.java
+++ b/src/main/java/sqlline/PromptHandler.java
@@ -61,11 +61,26 @@ public class PromptHandler {
protected final SqlLine sqlLine;
- static final Supplier SCRIPT_ENGINE_SUPPLIER =
- new MemoizingSupplier<>(() -> {
- final ScriptEngineManager engineManager = new ScriptEngineManager();
- return engineManager.getEngineByName("nashorn");
- });
+ final Supplier scriptEngineSupplier =
+ getEngineSupplier();
+
+ MemoizingSupplier getEngineSupplier() {
+ return new MemoizingSupplier<>(() -> {
+ final ScriptEngineManager engineManager = new ScriptEngineManager();
+ String engineName = sqlLine.getOpts().get(BuiltInProperty.SCRIPT_ENGINE);
+ ScriptEngine scriptEngine = engineManager.getEngineByName(engineName);
+ if (scriptEngine == null) {
+ if (engineManager.getEngineFactories().isEmpty()) {
+ sqlLine.error(sqlLine.loc("not-supported-script-engine-no-available",
+ engineName));
+ } else {
+ sqlLine.error(sqlLine.loc("not-supported-script-engine",
+ engineName, BuiltInProperty.SCRIPT_ENGINE.getAvailableValues()));
+ }
+ }
+ return scriptEngine;
+ });
+ }
public PromptHandler(SqlLine sqlLine) {
this.sqlLine = sqlLine;
@@ -112,16 +127,20 @@ public AttributedString getPrompt() {
private String getPromptFromScript(SqlLine sqlLine,
String promptScript) {
try {
- final ScriptEngine engine = SCRIPT_ENGINE_SUPPLIER.get();
- final Bindings bindings = new SimpleBindings();
- final ConnectionMetadata meta = sqlLine.getConnectionMetadata();
- bindings.put("connectionIndex", meta.getIndex());
- bindings.put("databaseProductName", meta.getDatabaseProductName());
- bindings.put("userName", meta.getUserName());
- bindings.put("url", meta.getUrl());
- bindings.put("currentSchema", meta.getCurrentSchema());
- final Object o = engine.eval(promptScript, bindings);
- return String.valueOf(o);
+ final ScriptEngine engine = scriptEngineSupplier.get();
+ if (engine == null) {
+ return ">";
+ } else {
+ final Bindings bindings = new SimpleBindings();
+ final ConnectionMetadata meta = sqlLine.getConnectionMetadata();
+ bindings.put("connectionIndex", meta.getIndex());
+ bindings.put("databaseProductName", meta.getDatabaseProductName());
+ bindings.put("userName", meta.getUserName());
+ bindings.put("url", meta.getUrl());
+ bindings.put("currentSchema", meta.getCurrentSchema());
+ final Object o = engine.eval(promptScript, bindings);
+ return String.valueOf(o);
+ }
} catch (ScriptException e) {
e.printStackTrace();
return ">";
diff --git a/src/main/java/sqlline/SqlLineOpts.java b/src/main/java/sqlline/SqlLineOpts.java
index 7ab5d183..510d3d1f 100644
--- a/src/main/java/sqlline/SqlLineOpts.java
+++ b/src/main/java/sqlline/SqlLineOpts.java
@@ -23,6 +23,8 @@
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
import org.jline.builtins.Completers;
import org.jline.keymap.KeyMap;
@@ -75,6 +77,7 @@
import static sqlline.BuiltInProperty.PROPERTIES_FILE;
import static sqlline.BuiltInProperty.RIGHT_PROMPT;
import static sqlline.BuiltInProperty.ROW_LIMIT;
+import static sqlline.BuiltInProperty.SCRIPT_ENGINE;
import static sqlline.BuiltInProperty.SHOW_COMPLETION_DESCR;
import static sqlline.BuiltInProperty.SHOW_ELAPSED_TIME;
import static sqlline.BuiltInProperty.SHOW_HEADER;
@@ -130,6 +133,7 @@ public class SqlLineOpts implements Completer {
put(NUMBER_FORMAT, SqlLineOpts.this::setNumberFormat);
put(OUTPUT_FORMAT, SqlLineOpts.this::setOutputFormat);
put(PROPERTIES_FILE, SqlLineOpts.this::setPropertiesFile);
+ put(SCRIPT_ENGINE, SqlLineOpts.this::setScriptEngine);
put(SHOW_COMPLETION_DESCR,
SqlLineOpts.this::setShowCompletionDesc);
put(TABLE_STYLE, SqlLineOpts.this::setTableStyle);
@@ -523,7 +527,8 @@ public void set(SqlLineProperty key, Object value) {
? (String) value : String.valueOf(value);
valueToSet = DEFAULT.equalsIgnoreCase(strValue)
? key.defaultValue() : value;
- if (!key.getAvailableValues().isEmpty()
+ if (!DEFAULT.equalsIgnoreCase(strValue)
+ && !key.getAvailableValues().isEmpty()
&& !key.getAvailableValues().contains(valueToSet.toString())) {
sqlLine.error(
sqlLine.loc("unknown-value",
@@ -1083,6 +1088,24 @@ public Pattern getCompiledConfirmPattern() {
public String getHistoryFlags() {
return get(HISTORY_FLAGS);
}
+
+ public String getScriptEngine() {
+ return get(SCRIPT_ENGINE);
+ }
+
+ public void setScriptEngine(String engineName) {
+ if (DEFAULT.equalsIgnoreCase(engineName)) {
+ set(SCRIPT_ENGINE, SCRIPT_ENGINE.defaultValue());
+ return;
+ }
+ final ScriptEngineManager engineManager = new ScriptEngineManager();
+ ScriptEngine scriptEngine = engineManager.getEngineByName(engineName);
+ if (scriptEngine == null && engineManager.getEngineFactories().isEmpty()) {
+ sqlLine.error(sqlLine.loc("not-supported-script-engine-no-available",
+ engineName));
+ }
+ set(SCRIPT_ENGINE, engineName);
+ }
}
// End SqlLineOpts.java
diff --git a/src/main/resources/sqlline/SqlLine.properties b/src/main/resources/sqlline/SqlLine.properties
index 0cc90799..ef94eae0 100644
--- a/src/main/resources/sqlline/SqlLine.properties
+++ b/src/main/resources/sqlline/SqlLine.properties
@@ -37,6 +37,8 @@ column: Column
new-size-after-resize: New size: height = {0}, width = {1}
empty-value-not-supported: Empty value for type {0} not supported
no-file: File {0} does not exist or is a directory
+not-supported-script-engine: Not found script engine "{0}", available values: {1}
+not-supported-script-engine-no-available: Not found script engine "{0}", no available script engines
jdbc-level: JDBC level
compliant: Compliant
@@ -151,6 +153,7 @@ variables:\
\nrightPrompt pattern Format right prompt\
\nrowLimit integer Maximum number of rows returned from a query; zero\
\n means no limit\
+\nscriptEngine String Script engine name\
\nshowCompletionDesc true/false Display help for completions\
\nshowElapsedTime true/false Display execution time when verbose\
\nshowHeader true/false Show column names in query results\
@@ -340,6 +343,7 @@ cmd-usage: Usage: java sqlline.SqlLine \n \
\ --autoCommit=[true/false] enable/disable automatic transaction commit\n \
\ --readOnly=[true/false] enable/disable readonly connection\n \
\ --verbose=[true/false] show verbose error messages and debug info\n \
+\ --scriptEngine=[string] script engine name\n \
\ --showCompletionDesc=[true/false] display help for completions\n \
\ --showLineNumbers=[true/false] show line numbers while multiline queries\n \
\ --showTime=[true/false] display execution time when verbose\n \
diff --git a/src/main/resources/sqlline/manual.txt b/src/main/resources/sqlline/manual.txt
index 04625df5..810394fa 100644
--- a/src/main/resources/sqlline/manual.txt
+++ b/src/main/resources/sqlline/manual.txt
@@ -104,6 +104,8 @@ schemas
schemas — List all the schemas in the database
script
script — Save executed commands to a file
+scriptengine
+scriptengine - script engine name
set
set — Set a preference
showconfconnections
@@ -258,6 +260,8 @@ scan
scan — Scan class path for JDBC drivers
script
script — Save executed commands to a file
+scriptengine
+scriptengine - script engine name
set
set — Set a preference
showconfconnections
@@ -502,6 +506,8 @@ scan
scan — Scan class path for JDBC drivers
script
script — Save executed commands to a file
+scriptengine
+scriptengine - script engine name
set
set — Set a preference
showconfconnections
@@ -1223,6 +1229,7 @@ propertiesFile path File from which SQLLine reads properties on
rightPrompt pattern Format right prompt
rowLimit integer Maximum number of rows returned from a query; zero
means no limit
+scriptEngine string Script engine name
showCompletionDesc true/false Display help for completions
showElapsedTime true/false Display execution time when verbose
showHeader true/false Show column names in query results
@@ -2411,6 +2418,10 @@ rowlimit
The maximum number of rows to fetch per query. Defaults to 0, which is interpreted as fetching all rows.
+scriptengine
+
+A script engine to use to evaluate scripts for instance from promptScript. Defaults to nashorn.
+
showheader
If true, display the names of the columns when displaying results. Defaults to true.
diff --git a/src/test/java/sqlline/PromptTest.java b/src/test/java/sqlline/PromptTest.java
index 6f2ebd12..12f35975 100644
--- a/src/test/java/sqlline/PromptTest.java
+++ b/src/test/java/sqlline/PromptTest.java
@@ -15,6 +15,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
+import javax.script.ScriptEngineManager;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStringBuilder;
@@ -221,8 +222,9 @@ public void testPromptWithSchema() {
* The `promptscript` property is broken on JDK 15 and higher. */
@Test
public void testPromptScript() {
- Assumptions.assumeTrue(getJavaMajorVersion() < 15,
- "promptscript fails on JDK 15 and higher; "
+ Assumptions.assumeTrue(
+ !new ScriptEngineManager().getEngineFactories().isEmpty(),
+ "promptscript fails if there is no script engines; "
+ "see ");
sqlLine.getOpts().set(BuiltInProperty.PROMPT_SCRIPT, "'hel' + 'lo'");