package top.guoziyang.mydb.backend.parser;
import java.util.ArrayList;
import java.util.List;
import top.guoziyang.mydb.backend.parser.statement.Abort;
import top.guoziyang.mydb.backend.parser.statement.Begin;
import top.guoziyang.mydb.backend.parser.statement.Commit;
import top.guoziyang.mydb.backend.parser.statement.Create;
import top.guoziyang.mydb.backend.parser.statement.Delete;
import top.guoziyang.mydb.backend.parser.statement.Drop;
import top.guoziyang.mydb.backend.parser.statement.Insert;
import top.guoziyang.mydb.backend.parser.statement.Select;
import top.guoziyang.mydb.backend.parser.statement.Show;
import top.guoziyang.mydb.backend.parser.statement.SingleExpression;
import top.guoziyang.mydb.backend.parser.statement.Update;
import top.guoziyang.mydb.backend.parser.statement.Where;
import top.guoziyang.mydb.common.Error;
public class Parser {
public static Object Parse(byte[] statement) throws Exception {
Tokenizer tokenizer = new Tokenizer(statement);
String token = tokenizer.peek();
tokenizer.pop();
Object stat = null;
Exception statErr = null;
try {
switch(token) {
case "begin":
stat = parseBegin(tokenizer);
break;
case "commit":
stat = parseCommit(tokenizer);
break;
case "abort":
stat = parseAbort(tokenizer);
break;
case "create":
stat = parseCreate(tokenizer);
break;
case "drop":
stat = parseDrop(tokenizer);
break;
case "select":
stat = parseSelect(tokenizer);
break;
case "insert":
stat = parseInsert(tokenizer);
break;
case "delete":
stat = parseDelete(tokenizer);
break;
case "update":
stat = parseUpdate(tokenizer);
break;
case "show":
stat = parseShow(tokenizer);
break;
default:
throw Error.InvalidCommandException;
}
} catch(Exception e) {
statErr = e;
}
try {
String next = tokenizer.peek();
if(!"".equals(next)) {
byte[] errStat = tokenizer.errStat();
statErr = new RuntimeException("Invalid statement: " + new String(errStat));
}
} catch(Exception e) {
e.printStackTrace();
byte[] errStat = tokenizer.errStat();
statErr = new RuntimeException("Invalid statement: " + new String(errStat));
}
if(statErr != null) {
throw statErr;
}
return stat;
}
private static Show parseShow(Tokenizer tokenizer) throws Exception {
String tmp = tokenizer.peek();
if("".equals(tmp)) {
return new Show();
}
throw Error.InvalidCommandException;
}
private static Update parseUpdate(Tokenizer tokenizer) throws Exception {
Update update = new Update();
update.tableName = tokenizer.peek();
tokenizer.pop();
if(!"set".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
update.fieldName = tokenizer.peek();
tokenizer.pop();
if(!"=".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
update.value = tokenizer.peek();
tokenizer.pop();
String tmp = tokenizer.peek();
if("".equals(tmp)) {
update.where = null;
return update;
}
update.where = parseWhere(tokenizer);
return update;
}
private static Delete parseDelete(Tokenizer tokenizer) throws Exception {
Delete delete = new Delete();
if(!"from".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
String tableName = tokenizer.peek();
if(!isName(tableName)) {
throw Error.InvalidCommandException;
}
delete.tableName = tableName;
tokenizer.pop();
delete.where = parseWhere(tokenizer);
return delete;
}
private static Insert parseInsert(Tokenizer tokenizer) throws Exception {
Insert insert = new Insert();
if(!"into".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
String tableName = tokenizer.peek();
if(!isName(tableName)) {
throw Error.InvalidCommandException;
}
insert.tableName = tableName;
tokenizer.pop();
if(!"values".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
List<String> values = new ArrayList<>();
while(true) {
tokenizer.pop();
String value = tokenizer.peek();
if("".equals(value)) {
break;
} else {
values.add(value);
}
}
insert.values = values.toArray(new String[values.size()]);
return insert;
}
private static Select parseSelect(Tokenizer tokenizer) throws Exception {
Select read = new Select();
List<String> fields = new ArrayList<>();
String asterisk = tokenizer.peek();
if("*".equals(asterisk)) {
fields.add(asterisk);
tokenizer.pop();
} else {
while(true) {
String field = tokenizer.peek();
if(!isName(field)) {
throw Error.InvalidCommandException;
}
fields.add(field);
tokenizer.pop();
if(",".equals(tokenizer.peek())) {
tokenizer.pop();
} else {
break;
}
}
}
read.fields = fields.toArray(new String[fields.size()]);
if(!"from".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
String tableName = tokenizer.peek();
if(!isName(tableName)) {
throw Error.InvalidCommandException;
}
read.tableName = tableName;
tokenizer.pop();
String tmp = tokenizer.peek();
if("".equals(tmp)) {
read.where = null;
return read;
}
read.where = parseWhere(tokenizer);
return read;
}
private static Where parseWhere(Tokenizer tokenizer) throws Exception {
Where where = new Where();
if(!"where".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
tokenizer.pop();
SingleExpression exp1 = parseSingleExp(tokenizer);
where.singleExp1 = exp1;
String logicOp = tokenizer.peek();
if("".equals(logicOp)) {
where.logicOp = logicOp;
return where;
}
if(!isLogicOp(logicOp)) {
throw Error.InvalidCommandException;
}
where.logicOp = logicOp;
tokenizer.pop();
SingleExpression exp2 = parseSingleExp(tokenizer);
where.singleExp2 = exp2;
if(!"".equals(tokenizer.peek())) {
throw Error.InvalidCommandException;
}
return where;
}
private static SingleExpression parseSingleExp(Tokenizer tokenizer) throws Exception {
SingleExpression exp = new SingleExpression();
String field = tokenizer.peek();
if(!isName(field)) {
throw Error.InvalidCommandException;
}
exp.field = fi
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
MYDB 是一个 Java 实现的简单的数据库,部分原理参照自 MySQL、PostgreSQL 和 SQLite。实现了以下功能: 数据的可靠性和数据恢复 两段锁协议(2PL)实现可串行化调度 MVCC 两种事务隔离级别(读提交和可重复读) 死锁处理 简单的表和字段管理 简陋的 SQL 解析(因为懒得写词法分析和自动机,就弄得比较简陋) 基于 socket 的 server 和 client
资源推荐
资源详情
资源评论
收起资源包目录
MYDB-master.zip (83个子文件)
MYDB-master
pom.xml 1KB
src
test
java
top
guoziyang
mydb
backend
im
BPlusTreeTest.java 1KB
dm
MockDataManager.java 2KB
pageCache
PageCacheTest.java 6KB
MockPageCache.java 1KB
dataItem
MockDataItem.java 2KB
DataManagerTest.java 6KB
pageIndex
PageIndexTest.java 717B
logger
LoggerTest.java 1KB
page
MockPage.java 912B
parser
ParserTest.java 4KB
common
MockCache.java 319B
CacheTest.java 1KB
tm
TransactionManagerTest.java 3KB
MockTransactionManager.java 576B
vm
LockTableTest.java 2KB
server
ExecutorTest.java 3KB
transport
PackagerTest.java 1KB
main
java
top
guoziyang
mydb
backend
tbm
FieldCalRes.java 115B
BeginRes.java 114B
Table.java 10KB
TableManagerImpl.java 5KB
Field.java 7KB
TableManager.java 1KB
Booter.java 3KB
im
Node.java 9KB
BPlusTree.java 5KB
dm
pageCache
PageCache.java 2KB
PageCacheImpl.java 4KB
dataItem
DataItemImpl.java 2KB
DataItem.java 2KB
DataManagerImpl.java 5KB
pageIndex
PageInfo.java 239B
PageIndex.java 1KB
logger
Logger.java 2KB
LoggerImpl.java 6KB
Recover.java 8KB
page
PageImpl.java 998B
PageOne.java 1KB
PageX.java 2KB
Page.java 231B
DataManager.java 1KB
utils
ParseStringRes.java 226B
Parser.java 2KB
Panic.java 173B
RandomUtil.java 313B
Types.java 235B
parser
Tokenizer.java 4KB
Parser.java 13KB
statement
Delete.java 131B
SingleExpression.java 167B
Update.java 185B
Create.java 196B
Abort.java 82B
Commit.java 83B
Drop.java 105B
Insert.java 135B
Select.java 159B
Show.java 81B
Where.java 184B
Begin.java 114B
common
AbstractCache.java 4KB
SubArray.java 285B
tm
TransactionManagerImpl.java 5KB
TransactionManager.java 2KB
vm
Transaction.java 923B
VersionManagerImpl.java 5KB
Visibility.java 2KB
VersionManager.java 597B
Entry.java 3KB
LockTable.java 5KB
server
Executor.java 3KB
Server.java 3KB
Launcher.java 3KB
client
Client.java 659B
Shell.java 863B
RoundTripper.java 482B
Launcher.java 682B
common
Error.java 3KB
transport
Transporter.java 1KB
Packager.java 618B
Package.java 323B
Encoder.java 1KB
共 83 条
- 1
资源评论
博士僧小星
- 粉丝: 1731
- 资源: 5850
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功