package info.globalcode.sql.dk;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author Ing. František Kučera (frantovo.cz)
*/
public class CLIParser {
public static final String TYPE_NAME_SEPARATOR = ":";
private final Map<String, Integer> types;
public CLIParser() {
Map<String, Integer> m = new HashMap<>();
m.put("int", Types.INTEGER);
m.put("string", Types.VARCHAR);
m.put("boolean", Types.BOOLEAN);
/**
* TODO: more types
*/
types = Collections.unmodifiableMap(m);
}
public CLIOptions parseOptions(String[] args) {
CLIOptions options = new CLIOptions();
List<Integer> numberedTypes = new ArrayList<>();
Map<String, Integer> namedTypes = new HashMap<>();
for (int i = 0; i < args.length; i++) {
String arg = args[i];
switch (arg) {
case Tokens.TYPES:
String typesString = args[++i];
for (String oneType : typesString.split("\\s*,\\s*")) {
int sepatratorIndex = oneType.indexOf(TYPE_NAME_SEPARATOR);
if (sepatratorIndex == -1) {
numberedTypes.add(getType(oneType));
} else {
String namePart = oneType.substring(0, sepatratorIndex);
String typePart = oneType.substring(sepatratorIndex + TYPE_NAME_SEPARATOR.length(), oneType.length());
namedTypes.put(namePart, getType(typePart));
}
}
break;
case Tokens.NAME_PREFIX:
options.setNamePrefix(args[++i]);
break;
case Tokens.DB:
options.setDatabaseName(args[++i]);
break;
case Tokens.SQL:
options.setSql(args[++i]);
options.setCommandType(CLIOptions.COMMAND_TYPE.QUERY);
break;
case Tokens.SQL_UPDATE:
case Tokens.SQL_INSERT:
options.setSql(args[++i]);
options.setCommandType(CLIOptions.COMMAND_TYPE.UPDATE);
break;
case Tokens.BATCH:
options.setBatch(true);
break;
case Tokens.DATA: // --data is the last option
for (i++; i < args.length; i++) {
arg = args[i];
if (arg.startsWith(options.getNamePrefix())) {
String paramName = arg.substring(options.getNamePrefix().length());
String paramValue = args[++i];
options.addNamedParameter(new NamedParameter(paramName, paramValue, namedTypes.get(paramName)));
} else {
int paramIndex = options.getNumberedParameters().size();
int paramType;
try {
paramType = numberedTypes.get(paramIndex);
} catch (IndexOutOfBoundsException e) {
throw new IllegalArgumentException("Missing type for parameter #" + paramIndex, e);
} catch (NullPointerException e) {
throw new IllegalArgumentException("Invalid type definition for parameter #" + paramIndex, e);
}
options.addNumberedParameter(new Parameter(arg, paramType));
}
}
break;
default:
throw new IllegalArgumentException("Unknown option: " + arg);
}
}
return options;
}
public static class Tokens {
public static final String DB = "--db";
public static final String SQL = "--sql";
public static final String SQL_UPDATE = "--sql-update";
public static final String SQL_INSERT = "--sql-insert";
public static final String BATCH = "--batch";
public static final String DATA = "--data";
public static final String NAME_PREFIX = "--name-prefix";
public static final String TYPES = "--types";
private Tokens() {
}
}
private Integer getType(String typeString) {
return types.get(typeString);
}
}