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: }