franta-hg@16: /** franta-hg@16: * SQL-DK franta-hg@16: * Copyright © 2013 František Kučera (frantovo.cz) franta-hg@16: * franta-hg@16: * This program is free software: you can redistribute it and/or modify franta-hg@16: * it under the terms of the GNU General Public License as published by franta-hg@16: * the Free Software Foundation, either version 3 of the License, or franta-hg@16: * (at your option) any later version. franta-hg@16: * franta-hg@16: * This program is distributed in the hope that it will be useful, franta-hg@16: * but WITHOUT ANY WARRANTY; without even the implied warranty of franta-hg@16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the franta-hg@16: * GNU General Public License for more details. franta-hg@16: * franta-hg@16: * You should have received a copy of the GNU General Public License franta-hg@16: * along with this program. If not, see . franta-hg@16: */ franta-hg@1: package info.globalcode.sql.dk; franta-hg@1: franta-hg@1: import static info.globalcode.sql.dk.Functions.isNotEmpty; franta-hg@14: import static info.globalcode.sql.dk.Functions.equalz; franta-hg@69: import info.globalcode.sql.dk.InfoLister.InfoType; franta-hg@104: import info.globalcode.sql.dk.configuration.Properties; franta-hg@104: import info.globalcode.sql.dk.configuration.Property; franta-hg@146: import java.io.InputStream; franta-hg@34: import java.io.OutputStream; franta-hg@1: import java.util.ArrayList; franta-hg@1: import java.util.Collection; franta-hg@14: import java.util.EnumSet; franta-hg@162: import java.util.LinkedHashSet; franta-hg@1: import java.util.List; franta-hg@74: import java.util.Set; franta-hg@63: import java.util.regex.Pattern; franta-hg@63: import java.util.regex.PatternSyntaxException; franta-hg@1: franta-hg@1: /** franta-hg@155: * Holds options from command line, validates them, combines with configuration and provides derived franta-hg@155: * objects. franta-hg@1: * franta-hg@1: * @author Ing. František Kučera (frantovo.cz) franta-hg@1: */ franta-hg@1: public class CLIOptions { franta-hg@1: franta-hg@3: public static final String DEFAULT_NAME_PREFIX = ":"; franta-hg@54: public static final String DEFAULT_NAME_SUFFIX = "(?=([^\\w]|$))"; franta-hg@1: private String sql; franta-hg@1: private String databaseName; franta-hg@162: private Set databaseNamesToTest = new LinkedHashSet<>(); franta-hg@162: private Set databaseNamesToListProperties = new LinkedHashSet<>(); franta-hg@3: private String namePrefix = DEFAULT_NAME_PREFIX; franta-hg@44: private String nameSuffix = DEFAULT_NAME_SUFFIX; franta-hg@14: private String formatterName; franta-hg@1: private boolean batch; franta-hg@104: private Properties formatterProperties = new Properties(); franta-hg@104: private Properties databaseProperties = new Properties(); franta-hg@2: franta-hg@2: public enum MODE { franta-hg@2: franta-hg@2: QUERY_NOW, franta-hg@2: PREPARE_BATCH, franta-hg@14: EXECUTE_BATCH, franta-hg@14: JUST_SHOW_INFO franta-hg@14: } franta-hg@34: private final List namedParameters = new ArrayList<>(); franta-hg@1: private final List numberedParameters = new ArrayList<>(); franta-hg@69: private final EnumSet showInfo = EnumSet.noneOf(InfoType.class); franta-hg@1: franta-hg@1: public void validate() throws InvalidOptionsException { franta-hg@1: InvalidOptionsException e = new InvalidOptionsException(); franta-hg@1: franta-hg@14: MODE mode = getMode(); franta-hg@14: if (mode == null) { franta-hg@1: e.addProblem(new InvalidOptionsException.OptionProblem("Invalid combination of DB, SQL and BATCH – please specify just 2 of this 3 options")); franta-hg@14: } else if (mode == MODE.JUST_SHOW_INFO) { franta-hg@14: if (!namedParameters.isEmpty()) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not use named parameters if just showing info.")); franta-hg@14: } franta-hg@14: if (!numberedParameters.isEmpty()) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not use numbered parameters if just showing info.")); franta-hg@14: } franta-hg@14: if (isNotEmpty(sql, false)) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify SQL if just showing info.")); franta-hg@14: } franta-hg@14: if (isNotEmpty(databaseName, false)) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify database if just showing info.")); franta-hg@14: } franta-hg@14: if (batch) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify batch if just showing info.")); franta-hg@14: } franta-hg@14: if (!equalz(namePrefix, DEFAULT_NAME_PREFIX)) { franta-hg@14: e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify name prefix if just showing info.")); franta-hg@14: } franta-hg@44: if (!equalz(nameSuffix, DEFAULT_NAME_SUFFIX)) { franta-hg@44: e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify name suffix if just showing info.")); franta-hg@44: } franta-hg@155: if (showInfo.contains(InfoType.CONNECTION) && databaseNamesToTest.isEmpty()) { franta-hg@15: e.addProblem(new InvalidOptionsException.OptionProblem("Please specify which database should be tested.")); franta-hg@15: } franta-hg@159: if (showInfo.contains(InfoType.JDBC_PROPERTIES) && databaseNamesToListProperties.isEmpty()) { franta-hg@159: e.addProblem(new InvalidOptionsException.OptionProblem("Please specify for which database the properties should be listed.")); franta-hg@159: } franta-hg@1: } franta-hg@1: franta-hg@1: if (!namedParameters.isEmpty() && !numberedParameters.isEmpty()) { franta-hg@1: e.addProblem(new InvalidOptionsException.OptionProblem("Named and numbered parameters can not be used together in one command.")); franta-hg@1: } franta-hg@1: franta-hg@63: try { franta-hg@63: Pattern.compile(namePrefix + "test" + nameSuffix); franta-hg@63: } catch (PatternSyntaxException regexException) { franta-hg@63: e.addProblem(new InvalidOptionsException.OptionProblem("Ivalid regular expression in name prefix or suffix", regexException)); franta-hg@63: } franta-hg@1: franta-hg@1: if (e.hasProblems()) { franta-hg@1: throw e; franta-hg@1: } franta-hg@1: } franta-hg@1: franta-hg@2: private boolean hasSql() { franta-hg@2: return isNotEmpty(getSql(), true); franta-hg@1: } franta-hg@1: franta-hg@2: private boolean hasDb() { franta-hg@2: return isNotEmpty(getDatabaseName(), true); franta-hg@1: } franta-hg@1: franta-hg@2: /** franta-hg@2: * Depends on options: DB, BATCH, SQL franta-hg@2: * franta-hg@2: * @return mode | or null if options are not yet initialized or combination of options is franta-hg@2: * invalid franta-hg@2: */ franta-hg@2: public MODE getMode() { franta-hg@2: if (hasDb() && !batch && hasSql()) { franta-hg@2: return MODE.QUERY_NOW; franta-hg@2: } else if (!hasDb() && batch && hasSql()) { franta-hg@2: return MODE.PREPARE_BATCH; franta-hg@2: } else if (hasDb() && batch && !hasSql()) { franta-hg@2: return MODE.EXECUTE_BATCH; franta-hg@2: } else { franta-hg@14: return showInfo.isEmpty() ? null : MODE.JUST_SHOW_INFO; franta-hg@2: } franta-hg@2: } franta-hg@2: franta-hg@2: public String getSql() { franta-hg@2: return sql; franta-hg@2: } franta-hg@2: franta-hg@2: public void setSql(String sql) { franta-hg@2: this.sql = sql; franta-hg@2: } franta-hg@2: franta-hg@2: public String getDatabaseName() { franta-hg@2: return databaseName; franta-hg@2: } franta-hg@2: franta-hg@2: public void setDatabaseName(String databaseName) { franta-hg@2: this.databaseName = databaseName; franta-hg@2: } franta-hg@2: franta-hg@2: public void setBatch(boolean batch) { franta-hg@2: this.batch = batch; franta-hg@2: } franta-hg@2: franta-hg@2: public Collection getNamedParameters() { franta-hg@2: return namedParameters; franta-hg@2: } franta-hg@2: franta-hg@2: public List getNumberedParameters() { franta-hg@2: return numberedParameters; franta-hg@2: } franta-hg@2: franta-hg@2: public void addNumberedParameter(Parameter p) { franta-hg@2: numberedParameters.add(p); franta-hg@2: } franta-hg@2: franta-hg@2: public void addNamedParameter(NamedParameter p) { franta-hg@2: namedParameters.add(p); franta-hg@1: } franta-hg@3: franta-hg@104: public Properties getDatabaseProperties() { franta-hg@104: return databaseProperties; franta-hg@104: } franta-hg@104: franta-hg@104: public Properties getFormatterProperties() { franta-hg@104: return formatterProperties; franta-hg@104: } franta-hg@104: franta-hg@104: public void addDatabaseProperty(Property p) { franta-hg@104: databaseProperties.add(p); franta-hg@104: } franta-hg@104: franta-hg@104: public void addFormatterProperty(Property p) { franta-hg@104: formatterProperties.add(p); franta-hg@104: } franta-hg@104: franta-hg@54: /** franta-hg@54: * @return regular expression describing the name prefix franta-hg@54: */ franta-hg@3: public String getNamePrefix() { franta-hg@3: return namePrefix; franta-hg@3: } franta-hg@3: franta-hg@54: /** franta-hg@54: * @see #getNamePrefix() franta-hg@54: */ franta-hg@3: public void setNamePrefix(String namePrefix) { franta-hg@3: this.namePrefix = namePrefix; franta-hg@3: } franta-hg@14: franta-hg@54: /** franta-hg@54: * @return regular expression describing the name prefix franta-hg@54: */ franta-hg@44: public String getNameSuffix() { franta-hg@44: return nameSuffix; franta-hg@44: } franta-hg@44: franta-hg@54: /** franta-hg@54: * @see #getNameSuffix() franta-hg@54: */ franta-hg@44: public void setNameSuffix(String nameSuffix) { franta-hg@44: this.nameSuffix = nameSuffix; franta-hg@44: } franta-hg@44: franta-hg@14: public String getFormatterName() { franta-hg@14: return formatterName; franta-hg@14: } franta-hg@14: franta-hg@14: public void setFormatterName(String formatterName) { franta-hg@14: this.formatterName = formatterName; franta-hg@14: } franta-hg@14: franta-hg@69: public void addShowInfo(InfoType info) { franta-hg@14: showInfo.add(info); franta-hg@14: } franta-hg@14: franta-hg@69: public EnumSet getShowInfo() { franta-hg@14: return showInfo; franta-hg@14: } franta-hg@15: franta-hg@155: public Set getDatabaseNamesToTest() { franta-hg@155: return databaseNamesToTest; franta-hg@15: } franta-hg@15: franta-hg@159: public void addDatabaseNameToTest(String name) { franta-hg@159: databaseNamesToTest.add(name); franta-hg@15: } franta-hg@34: franta-hg@159: public Set getDatabaseNamesToListProperties() { franta-hg@159: return databaseNamesToListProperties; franta-hg@159: } franta-hg@159: franta-hg@159: public void addDatabaseNameToListProperties(String name) { franta-hg@159: databaseNamesToListProperties.add(name); franta-hg@159: } franta-hg@159: franta-hg@34: public SQLCommand getSQLCommand() { franta-hg@34: if (namedParameters.isEmpty()) { franta-hg@37: return new SQLCommandNumbered(sql, numberedParameters); franta-hg@34: } else { franta-hg@47: return new SQLCommandNamed(sql, namedParameters, namePrefix, nameSuffix); franta-hg@34: } franta-hg@34: } franta-hg@34: franta-hg@34: public OutputStream getOutputStream() { franta-hg@34: return System.out; franta-hg@34: } franta-hg@146: franta-hg@146: public InputStream getInputStream() { franta-hg@146: return System.in; franta-hg@146: } franta-hg@1: }