一、概述
sqlite的前端是一个SQL 编译器,能够将我们的字符串解析成字节码,传给VM;VM负责字节码的执行。
将编译,执行分离的优点:
- 减少了每一步的复杂性(VM不用处理语法错误啦)
- 编译一次,执行多次(缓存字节码)
二、代码实现
-
类似于
.exit
的非SQL语句我们将它称为“meta-commands”,实现的时候先检查这些非SQL语句,然后用单独模块处理。 -
第二步,将我们输入的语句进行预处理。(显然之后还要处理)
-
最后,我们将上述锁的的预处理语句传给
execute_statement
这个函数最终会当做我们的VM
相关定义:
错误处理模块的封装:
MetaCommandResult: 有两个常量,表示0的SUCCESS和表示1的EXCEPTION。
(程序的可扩展行,这个error code之后还可以添加)
PreparedResult :枚举类, 将语句进行预处理,现在有两种情况:预处理成功,语句未定义
StatementType:枚举类,枚举定义语句的种类(select,insert等等)
Statement:结构体,(类型,参数)
相关函数:
do_meta_command
封装函数,用于做非sql语句的执行
prepared_statement
我们的“SQL Compiler”,输入语句,输出预处理的结果
PreparedResult prepared_statement(InputBuffer* inputBuffer,Statement* statement)
executed_statement
execute_statement(Statement* statement)
MetaCommandResult do_meta_command(InputBuffer* inputBuffer){
if(strcmp(inputBuffer->buffer,".exit")==0){
exit(EXIT_SUCCESS);
}
else{
return META_COMMAND_UNRECOGNIZED_COMMAND;
}
}
// prepare statement,and output statement
PrepareResult prepare_statement(InputBuffer* inputBuffer,Statement* statement){
if(strncmp(inputBuffer->buffer,"insert",6)==0){
statement->type=STATEMENT_INSERT;
return PREPARE_SUCCESS;
}
if(strncmp(inputBuffer->buffer,"select",6)==0){
statement->type=STATEMENT_INSERT;
return PREPARE_SUCCESS;
}
return PREPARE_UNRECOGNIZED_STATEMENT;
}
void execute_statement(Statement* statement){
switch (statement->type) {
case(STATEMENT_INSERT):
printf("do insert\n");
break;
case (STATEMENT_SELECT):
printf("do select\n");
break;
case(STATEMENT_DELETE):
printf("do delete\n");
break;
case(STATEMENT_UPDATE):
printf("do update\n");
break;
}
}
typedef enum{
META_COMMAND_SUCCESS,
META_COMMAND_UNRECOGNIZED_COMMAND
}MetaCommandResult;
typedef enum{
PREPARE_SUCCESS,
PREPARE_UNRECOGNIZED_STATEMENT
}PrepareResult;
typedef enum {
STATEMENT_INSERT,
STATEMENT_SELECT,
STATEMENT_UPDATE,
STATEMENT_DELETE
}StatementType;