use crate::parser::ast::*;
use crate::parser::error::{Expected, ParseResult};
use crate::parser::state::Parser;
use crate::parser::token::Keyword;
pub fn parse_open_cursor(parser: &mut Parser) -> ParseResult<Statement> {
if let Some(Token::Identifier(id)) = parser.next() {
Ok(Statement::Cursor(CursorStatement::Open(id.clone())))
} else {
parser.backtrack(Expected::Description("cursor name"))
}
}
pub fn parse_close_cursor(parser: &mut Parser) -> ParseResult<Statement> {
if let Some(Token::Identifier(id)) = parser.next() {
Ok(Statement::Cursor(CursorStatement::Close(id.clone())))
} else {
parser.backtrack(Expected::Description("cursor name"))
}
}
pub fn parse_deallocate_cursor(parser: &mut Parser) -> ParseResult<Statement> {
if let Some(Token::Identifier(id)) = parser.next() {
Ok(Statement::Cursor(CursorStatement::Deallocate(id.clone())))
} else {
parser.backtrack(Expected::Description("cursor name"))
}
}
pub fn parse_fetch_cursor(parser: &mut Parser) -> ParseResult<Statement> {
let mut direction = FetchDirection::Next;
if let Some(Token::Keyword(k)) = parser.peek() {
match *k {
Keyword::Next => {
let _ = parser.next();
direction = FetchDirection::Next;
}
Keyword::Prior => {
let _ = parser.next();
direction = FetchDirection::Prior;
}
Keyword::First => {
let _ = parser.next();
direction = FetchDirection::First;
}
Keyword::Last => {
let _ = parser.next();
direction = FetchDirection::Last;
}
Keyword::Absolute => {
let _ = parser.next();
direction = FetchDirection::Absolute(
crate::parser::parse::expressions::parse_expr(parser)?,
);
}
Keyword::Relative => {
let _ = parser.next();
direction = FetchDirection::Relative(
crate::parser::parse::expressions::parse_expr(parser)?,
);
}
_ => {}
}
}
if matches!(parser.peek(), Some(Token::Keyword(Keyword::From))) {
let _ = parser.next();
}
let name = if let Some(Token::Identifier(id)) = parser.next() {
id.clone()
} else {
return parser.backtrack(Expected::Description("cursor name"));
};
let mut into_vars = None;
if matches!(parser.peek(), Some(Token::Keyword(Keyword::Into))) {
let _ = parser.next();
into_vars = Some(crate::parser::parse::expressions::parse_comma_list(
parser,
|p| {
if let Some(Token::Variable(v)) = p.next() {
Ok(v.clone())
} else {
p.backtrack(Expected::Description("variable"))
}
},
)?);
}
Ok(Statement::Cursor(CursorStatement::Fetch {
name,
direction,
into_vars,
}))
}