1 package info.globalcode.sql.dk;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.HashMap;
12 * @author Ing. František Kučera (frantovo.cz)
14 public class CLIParser {
16 public static final String TYPE_NAME_SEPARATOR = ":";
17 private final Map<String, Integer> types;
20 Map<String, Integer> m = new HashMap<>();
21 m.put("int", Types.INTEGER);
22 m.put("string", Types.VARCHAR);
23 m.put("boolean", Types.BOOLEAN);
27 types = Collections.unmodifiableMap(m);
30 public CLIOptions parseOptions(String[] args) throws CLIParserException {
31 CLIOptions options = new CLIOptions();
33 List<Integer> numberedTypes = new ArrayList<>();
34 Map<String, Integer> namedTypes = new HashMap<>();
36 for (int i = 0; i < args.length; i++) {
40 String typesString = fetchNext(args, ++i);
42 for (String oneType : typesString.split("\\s*,\\s*")) {
43 int sepatratorIndex = oneType.indexOf(TYPE_NAME_SEPARATOR);
44 if (sepatratorIndex == -1) {
45 numberedTypes.add(getType(oneType));
47 String namePart = oneType.substring(0, sepatratorIndex);
48 String typePart = oneType.substring(sepatratorIndex + TYPE_NAME_SEPARATOR.length(), oneType.length());
49 namedTypes.put(namePart, getType(typePart));
53 case Tokens.NAME_PREFIX:
54 options.setNamePrefix(fetchNext(args, ++i));
57 options.setDatabaseName(fetchNext(args, ++i));
60 options.setSql(fetchNext(args, ++i));
61 options.setCommandType(CLIOptions.COMMAND_TYPE.QUERY);
63 case Tokens.SQL_UPDATE:
64 case Tokens.SQL_INSERT:
65 options.setSql(fetchNext(args, ++i));
66 options.setCommandType(CLIOptions.COMMAND_TYPE.UPDATE);
69 options.setBatch(true);
71 case Tokens.DATA: // --data is the last option
72 for (i++; i < args.length; i++) {
75 if (arg.startsWith(options.getNamePrefix())) { // Named parameters:
76 String paramName = arg.substring(options.getNamePrefix().length());
77 String paramValue = fetchNext(args, ++i);
78 options.addNamedParameter(new NamedParameter(paramName, paramValue, namedTypes.get(paramName)));
79 } else { // Numbered parameters:
81 if (numberedTypes.isEmpty()) {
82 parameter = new Parameter(arg, null);
84 int paramIndex = options.getNumberedParameters().size();
87 paramType = numberedTypes.get(paramIndex);
88 } catch (IndexOutOfBoundsException e) {
89 throw new CLIParserException("Missing type for parameter #" + paramIndex, e);
90 } catch (NullPointerException e) {
91 throw new CLIParserException("Invalid type definition for parameter #" + paramIndex, e);
93 parameter = new Parameter(arg, paramType);
95 options.addNumberedParameter(parameter);
100 throw new CLIParserException("Unknown option: " + arg);
106 private String fetchNext(String[] args, int index) throws CLIParserException {
107 if (index < args.length) {
110 throw new CLIParserException("Expecting value for option: " + args[index - 1]);
114 public static class Tokens {
116 public static final String DB = "--db";
117 public static final String SQL = "--sql";
118 public static final String SQL_UPDATE = "--sql-update";
119 public static final String SQL_INSERT = "--sql-insert";
120 public static final String BATCH = "--batch";
121 public static final String DATA = "--data";
122 public static final String NAME_PREFIX = "--name-prefix";
123 public static final String TYPES = "--types";
129 private int getType(String typeString) throws CLIParserException {
130 Integer type = types.get(typeString);
132 throw new CLIParserException("Unsupported type: " + typeString);