Skip to content

Commit

Permalink
Merge pull request #77 from myyrakle/feat/#69
Browse files Browse the repository at this point in the history
[#69] 트랜잭션 명령어 파서 구현
  • Loading branch information
wHoIsDReAmer authored Mar 19, 2024
2 parents eb54dd9 + a7e67b1 commit 12abf3f
Show file tree
Hide file tree
Showing 14 changed files with 241 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ pub enum SQLStatement {
DCL(DCLStatement),
TCL(TCLStatement),
Other(OtherStatement),
None,
}

impl Default for SQLStatement {
fn default() -> Self {
SQLStatement::None
}
}

#[derive(Clone, Debug, PartialEq)]
Expand Down
8 changes: 8 additions & 0 deletions src/ast/tcl/begin_transaction.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
use crate::ast::{SQLStatement, TCLStatement};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BeginTransactionQuery {}

impl From<BeginTransactionQuery> for SQLStatement {
fn from(value: BeginTransactionQuery) -> SQLStatement {
SQLStatement::TCL(TCLStatement::BeginTransaction(value))
}
}
8 changes: 8 additions & 0 deletions src/ast/tcl/commit.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
use crate::ast::{SQLStatement, TCLStatement};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CommitQuery {}

impl From<CommitQuery> for SQLStatement {
fn from(value: CommitQuery) -> SQLStatement {
SQLStatement::TCL(TCLStatement::Commit(value))
}
}
8 changes: 8 additions & 0 deletions src/ast/tcl/rollback.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
use crate::ast::{SQLStatement, TCLStatement};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RollbackQuery {}

impl From<RollbackQuery> for SQLStatement {
fn from(value: RollbackQuery) -> SQLStatement {
SQLStatement::TCL(TCLStatement::Rollback(value))
}
}
4 changes: 4 additions & 0 deletions src/lexer/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ impl Tokenizer {
"NULLS" => Token::Nulls,
"FIRST" => Token::First,
"LAST" => Token::Last,
"BEGIN" => Token::Begin,
"TRANSACTION" => Token::Transaction,
"COMMIT" => Token::Commit,
"ROLLBACK" => Token::Rollback,
_ => Token::Identifier(identifier),
};

Expand Down
6 changes: 6 additions & 0 deletions src/lexer/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ pub enum Token {
Default,
Data,

// TCL
Begin,
Transaction,
Commit,
Rollback,

// ETC
// Analyze,
CodeComment(String),
Expand Down
1 change: 1 addition & 0 deletions src/parser/implements/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod ddl;
pub mod debug;
pub mod dml;
pub mod other;
pub mod tcl;
pub mod utils;
26 changes: 26 additions & 0 deletions src/parser/implements/tcl/begin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::error::Error;

use crate::ast::tcl::BeginTransactionQuery;
use crate::ast::SQLStatement;
use crate::errors::predule::ParsingError;
use crate::lexer::tokens::Token;
use crate::parser::predule::{Parser, ParserContext};

impl Parser {
pub(crate) fn parse_begin_query(
&mut self,
_context: ParserContext,
) -> Result<SQLStatement, Box<dyn Error + Send>> {
if !self.has_next_token() {
return Err(ParsingError::boxed("E2001 need more tokens"));
}

let current_token = self.get_next_token();

if current_token != Token::Transaction {
return Err(ParsingError::boxed("E2002 Expected BEGIN"));
}

Ok(BeginTransactionQuery {}.into())
}
}
14 changes: 14 additions & 0 deletions src/parser/implements/tcl/commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::error::Error;

use crate::ast::tcl::CommitQuery;
use crate::ast::SQLStatement;
use crate::parser::predule::{Parser, ParserContext};

impl Parser {
pub(crate) fn parse_commit_query(
&mut self,
_context: ParserContext,
) -> Result<SQLStatement, Box<dyn Error + Send>> {
Ok(CommitQuery {}.into())
}
}
3 changes: 3 additions & 0 deletions src/parser/implements/tcl/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod begin;
pub mod commit;
pub mod rollback;
14 changes: 14 additions & 0 deletions src/parser/implements/tcl/rollback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::error::Error;

use crate::ast::tcl::RollbackQuery;
use crate::ast::SQLStatement;
use crate::parser::predule::{Parser, ParserContext};

impl Parser {
pub(crate) fn parse_rollback_query(
&mut self,
_context: ParserContext,
) -> Result<SQLStatement, Box<dyn Error + Send>> {
Ok(RollbackQuery {}.into())
}
}
12 changes: 12 additions & 0 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ impl Parser {
let query = self.parse_desc_query(context.clone())?;
statements.push(query);
}
Token::Begin => {
let query = self.parse_begin_query(context.clone())?;
statements.push(query);
}
Token::Commit => {
let query = self.parse_commit_query(context.clone())?;
statements.push(query);
}
Token::Rollback => {
let query = self.parse_rollback_query(context.clone())?;
statements.push(query);
}
_ => {
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/parser/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ pub(crate) mod select;
pub(crate) mod update;

pub(crate) mod other;

pub(crate) mod tcl;
128 changes: 128 additions & 0 deletions src/parser/test/tcl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#![cfg(test)]

use crate::{
ast::{
tcl::{BeginTransactionQuery, CommitQuery, RollbackQuery},
SQLStatement,
},
parser::predule::{Parser, ParserContext},
};

#[test]
pub fn begin_transaction() {
struct TestCase {
name: String,
input: String,
expected: SQLStatement,
want_err: bool,
}

let test_cases = vec![
TestCase {
name: "정상적인 트랜잭션 시작".to_owned(),
input: "BEGIN TRANSACTION;".to_owned(),
expected: BeginTransactionQuery {}.into(),
want_err: false,
},
TestCase {
name: "begin만 있는 경우".to_owned(),
input: "BEGIN;".to_owned(),
expected: Default::default(),
want_err: true,
},
TestCase {
name: "begin 이후에 기대하지 않은 입력이 있는 경우".to_owned(),
input: "BEGIN TRANSITION;".to_owned(),
expected: Default::default(),
want_err: true,
},
];

for tc in test_cases {
let mut parser = Parser::new(tc.input).unwrap();

let result = parser.parse(ParserContext::default());

if tc.want_err {
assert!(
result.is_err(),
"{} - expected error, got {:?}",
tc.name,
result
);
continue;
}

assert_eq!(result.unwrap(), vec![tc.expected], "{}", tc.name);
}
}

#[test]
pub fn commit() {
struct TestCase {
name: String,
input: String,
expected: SQLStatement,
want_err: bool,
}

let test_cases = vec![TestCase {
name: "정상적인 Commit 명령".to_owned(),
input: "COMMIT;".to_owned(),
expected: CommitQuery {}.into(),
want_err: false,
}];

for tc in test_cases {
let mut parser = Parser::new(tc.input).unwrap();

let result = parser.parse(ParserContext::default());

if tc.want_err {
assert!(
result.is_err(),
"{} - expected error, got {:?}",
tc.name,
result
);
continue;
}

assert_eq!(result.unwrap(), vec![tc.expected], "{}", tc.name);
}
}

#[test]
pub fn rollback() {
struct TestCase {
name: String,
input: String,
expected: SQLStatement,
want_err: bool,
}

let test_cases = vec![TestCase {
name: "정상적인 ROLLBACK 명령".to_owned(),
input: "ROLLBACK;".to_owned(),
expected: RollbackQuery {}.into(),
want_err: false,
}];

for tc in test_cases {
let mut parser = Parser::new(tc.input).unwrap();

let result = parser.parse(ParserContext::default());

if tc.want_err {
assert!(
result.is_err(),
"{} - expected error, got {:?}",
tc.name,
result
);
continue;
}

assert_eq!(result.unwrap(), vec![tc.expected], "{}", tc.name);
}
}

0 comments on commit 12abf3f

Please sign in to comment.