当我们启动cli环境后,其实是启动了一个java程序,只不过这个程序是从console里读取命令进行交互,就跟shell一样的。
好,那么当我们启动之后,敲入命令"CREATE DATABASE financials;"之后,到底发生了什么?程序背后又是怎么做的呢?
就让我们跟着源码一起来分析下。
-------------------------------------------------------------------------------------
首先代码CliDriver.java的main函数很简单,如下:
public static void main(String[] args) throws Exception {
int ret = run(args);
System.exit(ret);
}
所以需要继续跟踪run函数。
-------------------------------------------------------------------------------------
OptionsProcessor oproc = new OptionsProcessor();---生成了这么一个对象,
private final Options options = new Options();---内部变量,属于commons-cli类
然后紧接着就加入了若干对象
// -e 'quoted-query-string'
options.addOption(OptionBuilder
.hasArg()
.withArgName("quoted-query-string")
.withDescription("SQL from command line")
.create('e'));
// -f <query-file>
options.addOption(OptionBuilder
.hasArg()
.withArgName("filename")
.withDescription("SQL from files")
.create('f'));
// -i <init-query-file>
options.addOption(OptionBuilder
.hasArg()
.withArgName("filename")
.withDescription("Initialization SQL file")
.create('i'));
// -hiveconf x=y
options.addOption(OptionBuilder
.withValueSeparator()
.hasArgs(2)
.withArgName("property=value")
.withLongOpt("hiveconf")
.withDescription("Use value for given property")
.create());
// -h hostname/ippaddress
options.addOption(OptionBuilder
.hasArg()
.withArgName("hostname")
.withDescription("connecting to Hive Server on remote host")
.create('h'));
// -p port
options.addOption(OptionBuilder
.hasArg()
.withArgName("port")
.withDescription("connecting to Hive Server on port number")
.create('p'));
// Substitution option -d, --define
options.addOption(OptionBuilder
.withValueSeparator()
.hasArgs(2)
.withArgName("key=value")
.withLongOpt("define")
.withDescription("Variable subsitution to apply to hive commands. e.g. -d A=B or --define A=B")
.create('d'));
// Substitution option --hivevar
options.addOption(OptionBuilder
.withValueSeparator()
.hasArgs(2)
.withArgName("key=value")
.withLongOpt("hivevar")
.withDescription("Variable subsitution to apply to hive commands. e.g. --hivevar A=B")
.create());
// [-S|--silent]
options.addOption(new Option("S", "silent", false, "Silent mode in interactive shell"));
// [-v|--verbose]
options.addOption(new Option("v", "verbose", false, "Verbose mode (echo executed SQL to the console)"));
// [-H|--help]
options.addOption(new Option("H", "help", false, "Print help information"));
---这个没啥好说的,继续,初始化完之后,就开始使用了
if (!oproc.process_stage1(args)) {
return 1;
}
那么process_stage1内部究竟做了什么事情呢?--
public boolean process_stage1(String[] argv) {
// 看到这里了
try {
commandLine = new GnuParser().parse(options, argv);// 依赖commons-cli第三方的包来解析参数
Properties confProps = commandLine.getOptionProperties("hiveconf");//---解析hiveconf的属性
for (String propKey : confProps.stringPropertyNames()) {---解析hiveconf的属性
System.setProperty(propKey, confProps.getProperty(propKey));
}
Properties hiveVars = commandLine.getOptionProperties("define");---解析define 的属性
for (String propKey : hiveVars.stringPropertyNames()) {
hiveVariables.put(propKey, hiveVars.getProperty(propKey));
}
Properties hiveVars2 = commandLine.getOptionProperties("hivevar");---解析 hivevar的属性
for (String propKey : hiveVars2.stringPropertyNames()) {
hiveVariables.put(propKey, hiveVars2.getProperty(propKey));
}
} catch (ParseException e) {
System.err.println(e.getMessage());
printUsage();
return false;
}
return true;---返回true.
}
到目前为止,一切都很简单,就是解析了args 里的几个参数而已。
接下来是设置log4j
boolean logInitFailed = false;// ---设置日志属性,hive-log4j.properties
String logInitDetailMessage;
try {
logInitDetailMessage = LogUtils.initHiveLog4j();
} catch (LogInitializationException e) {
logInitFailed = true;
logInitDetailMessage = e.getMessage();
}
很简单
------