/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.lealone.plugins.sqlline; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Random; import java.util.stream.Collectors; import org.jline.reader.impl.completer.StringsCompleter; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; import org.lealone.common.logging.Logger; import org.lealone.common.logging.LoggerFactory; import org.lealone.common.util.Utils; import org.lealone.db.Constants; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import sqlline.Application; import sqlline.CommandHandler; import sqlline.ConnectionMetadata; import sqlline.OutputFormat; import sqlline.PromptHandler; import sqlline.ReflectiveCommandHandler; import sqlline.SqlLine; import sqlline.SqlLineOpts; //改编自org.apache.drill.exec.client.DrillSqlLineApplication public class SqlLineApplication extends Application { public static void main(String[] args) throws IOException { StringBuilder buff = new StringBuilder(100); buff.append(Constants.URL_PREFIX).append(Constants.URL_TCP).append("//").append(Constants.DEFAULT_HOST) .append(':').append(Constants.DEFAULT_TCP_PORT).append('/').append(Constants.PROJECT_NAME); String url = buff.toString(); logger.info("jdbc url: " + url); String[] args2 = { "-ac", SqlLineApplication.class.getName(), // "-u", url, // "-n", "root" }; sqlline.SqlLine.main(args2); } private static final Logger logger = LoggerFactory.getLogger(SqlLineApplication.class); private static final String LEALONE_SQLLINE_CONF = "lealone-sqlline.conf"; private static final String LEALONE_SQLLINE_OVERRIDE_CONF = "lealone-sqlline-override.conf"; private static final String INFO_MESSAGE_TEMPLATE_CONF = "lealone.sqlline.info_message_template"; private static final String QUOTES_CONF = "lealone.sqlline.quotes"; private static final String DRIVERS_CONF = "lealone.sqlline.drivers"; private static final String CONNECTION_URL_EXAMPLES_CONF = "lealone.sqlline.connection_url_examples"; private static final String COMMANDS_TO_EXCLUDE_CONF = "lealone.sqlline.commands.exclude"; private static final String OPTS_CONF = "lealone.sqlline.opts"; private static final String PROMPT_WITH_SCHEMA = "lealone.sqlline.prompt.with_schema"; private final Config config; public SqlLineApplication() { this(LEALONE_SQLLINE_CONF, LEALONE_SQLLINE_OVERRIDE_CONF); } public SqlLineApplication(String configName, String overrideConfigName) { this.config = overrideConfig(overrideConfigName, loadConfig(configName)); if (config.isEmpty()) { logger.warn("Was unable to find / load [{}]. Will use default SqlLine configuration.", configName); } } public Config getConfig() { return config; } @Override public String getInfoMessage() { if (config.hasPath(INFO_MESSAGE_TEMPLATE_CONF)) { String quote = ""; if (config.hasPath(QUOTES_CONF)) { List<String> quotes = config.getStringList(QUOTES_CONF); quote = quotes.get(new Random().nextInt(quotes.size())); } return String.format(config.getString(INFO_MESSAGE_TEMPLATE_CONF), getVersion(), quote); } return super.getInfoMessage(); } @Override public String getVersion() { return "Lealone version: " + Utils.getReleaseVersionString(); } @Override public List<String> allowedDrivers() { if (config.hasPath(DRIVERS_CONF)) { return config.getStringList(DRIVERS_CONF); } return super.allowedDrivers(); } @Override public Map<String, OutputFormat> getOutputFormats(SqlLine sqlLine) { return sqlLine.getOutputFormats(); } @Override public Collection<String> getConnectionUrlExamples() { if (config.hasPath(CONNECTION_URL_EXAMPLES_CONF)) { return config.getStringList(CONNECTION_URL_EXAMPLES_CONF); } return super.getConnectionUrlExamples(); } @Override public Collection<CommandHandler> getCommandHandlers(SqlLine sqlLine) { List<String> commandsToExclude = new ArrayList<>(); // exclude connect command and then add it back to ensure connection url examples are updated boolean reloadConnect = config.hasPath(CONNECTION_URL_EXAMPLES_CONF); if (reloadConnect) { commandsToExclude.add("connect"); } if (config.hasPath(COMMANDS_TO_EXCLUDE_CONF)) { commandsToExclude.addAll(config.getStringList(COMMANDS_TO_EXCLUDE_CONF)); } if (commandsToExclude.isEmpty()) { return sqlLine.getCommandHandlers(); } List<CommandHandler> commandHandlers = sqlLine.getCommandHandlers().stream() .filter(c -> c.getNames().stream().noneMatch(commandsToExclude::contains)).collect(Collectors.toList()); if (reloadConnect) { commandHandlers.add(new ReflectiveCommandHandler(sqlLine, new StringsCompleter(getConnectionUrlExamples()), "connect", "open")); } return commandHandlers; } @Override public SqlLineOpts getOpts(SqlLine sqlLine) { SqlLineOpts opts = sqlLine.getOpts(); if (config.hasPath(OPTS_CONF)) { Config optsConfig = config.getConfig(OPTS_CONF); optsConfig.entrySet().forEach(e -> { String key = e.getKey(); String value = String.valueOf(e.getValue().unwrapped()); if (!opts.set(key, value, true)) { logger.warn("Unable to set SqlLine property [{}] to [{}].", key, value); } }); } return opts; } @Override public PromptHandler getPromptHandler(SqlLine sqlLine) { if (config.hasPath(PROMPT_WITH_SCHEMA) && config.getBoolean(PROMPT_WITH_SCHEMA)) { return new PromptHandler(sqlLine) { @Override protected AttributedString getDefaultPrompt(int connectionIndex, String url, String defaultPrompt) { AttributedStringBuilder builder = new AttributedStringBuilder(); builder.style(resolveStyle("f:y")); builder.append("lealone"); ConnectionMetadata meta = sqlLine.getConnectionMetadata(); String currentSchema = meta.getCurrentSchema(); if (currentSchema != null) { builder.append(" (").append(currentSchema).append(")"); } return builder.style(resolveStyle("default")).append("> ").toAttributedString(); } }; } return super.getPromptHandler(sqlLine); } private Config loadConfig(String configName) { URL url = SqlLineApplication.class.getClassLoader().getResource(configName); if (url == null) return ConfigFactory.empty(); try { if (logger.isDebugEnabled()) logger.debug("Parsing [{}] for the url: [{}].", configName, url.getPath()); return ConfigFactory.parseURL(url); } catch (Exception e) { logger.warn("Was unable to parse [{}].", url.getPath(), e); return ConfigFactory.empty(); } } private Config overrideConfig(String configName, Config config) { Config overrideConfig = loadConfig(configName); return overrideConfig.withFallback(config).resolve(); } }