linkrs_query/parser/parsing/
transaction_parser.rs1use crate::parser::ast::stmt::*;
7use crate::parser::core::error::{ParseError, ParseErrorKind};
8use crate::parser::parsing::parse_context::ParseContext;
9use crate::parser::TokenKind;
10
11pub struct TransactionParser;
13
14impl Default for TransactionParser {
15 fn default() -> Self {
16 Self
17 }
18}
19
20impl TransactionParser {
21 pub fn new() -> Self {
22 Self
23 }
24
25 pub fn parse_begin_transaction(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
29 let start_span = ctx.current_span();
30 ctx.expect_token(TokenKind::Begin)?;
31
32 if ctx.check_token(TokenKind::Transaction) {
33 ctx.expect_token(TokenKind::Transaction)?;
34 }
35
36 let mut read_only = None;
37 if ctx.check_token(TokenKind::Read) {
38 ctx.expect_token(TokenKind::Read)?;
39 let mode = if ctx.check_token(TokenKind::Only) {
40 ctx.expect_token(TokenKind::Only)?;
41 true
42 } else if ctx.check_token(TokenKind::Write) {
43 ctx.expect_token(TokenKind::Write)?;
44 false
45 } else {
46 let pos = ctx.current_position();
47 return Err(ParseError::new(
48 ParseErrorKind::UnexpectedToken,
49 format!(
50 "Expected READ ONLY or READ WRITE, found {:?}",
51 ctx.current_token().kind
52 ),
53 pos,
54 )
55 .with_expected_tokens(vec!["READ ONLY".to_string(), "READ WRITE".to_string()]));
56 };
57 read_only = Some(mode);
58 }
59
60 let span = ctx.span_since(start_span.start);
61
62 Ok(Stmt::BeginTransaction(BeginTransactionStmt {
63 span,
64 read_only,
65 }))
66 }
67
68 pub fn parse_commit_transaction(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
70 let start_span = ctx.current_span();
71 ctx.expect_token(TokenKind::Commit)?;
72
73 if ctx.check_token(TokenKind::Transaction) {
74 ctx.expect_token(TokenKind::Transaction)?;
75 }
76
77 let span = ctx.span_since(start_span.start);
78
79 Ok(Stmt::CommitTransaction(CommitTransactionStmt { span }))
80 }
81
82 pub fn parse_rollback_transaction(
89 &mut self,
90 ctx: &mut ParseContext,
91 ) -> Result<Stmt, ParseError> {
92 let start_span = ctx.current_span();
93 ctx.expect_token(TokenKind::Rollback)?;
94
95 if ctx.check_token(TokenKind::Transaction) {
96 ctx.expect_token(TokenKind::Transaction)?;
97 }
98
99 let savepoint_name = if ctx.check_token(TokenKind::To) {
100 ctx.expect_token(TokenKind::To)?;
101 ctx.match_token(TokenKind::Savepoint);
102 Some(ctx.expect_identifier()?)
103 } else {
104 None
105 };
106
107 let span = ctx.span_since(start_span.start);
108
109 Ok(Stmt::RollbackTransaction(RollbackTransactionStmt {
110 span,
111 savepoint_name,
112 }))
113 }
114
115 pub fn parse_savepoint_statement(
119 &mut self,
120 ctx: &mut ParseContext,
121 ) -> Result<Stmt, ParseError> {
122 let start_span = ctx.current_span();
123 ctx.expect_token(TokenKind::Savepoint)?;
124 let name = ctx.expect_identifier()?;
125 let span = ctx.span_since(start_span.start);
126 Ok(Stmt::Savepoint(SavepointStmt { span, name }))
127 }
128
129 pub fn parse_release_savepoint(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
133 let start_span = ctx.current_span();
134 ctx.expect_token(TokenKind::Release)?;
135 ctx.expect_token(TokenKind::Savepoint)?;
136 let name = ctx.expect_identifier()?;
137 let span = ctx.span_since(start_span.start);
138 Ok(Stmt::ReleaseSavepoint(ReleaseSavepointStmt { span, name }))
139 }
140}