idx; // Skip 'CASE' for (; $list->idx < $list->count; ++$list->idx) { /** * Token parsed at this moment. * * @var Token */ $token = $list->tokens[$list->idx]; // Skipping whitespaces and comments. if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT) ) { continue; } if ($state === 0) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'WHEN' ) { ++$list->idx; // Skip 'WHEN' $new_condition = Condition::parse($parser, $list); $type = 1; $state = 1; $ret->conditions[] = $new_condition; } elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'ELSE' ) { ++$list->idx; // Skip 'ELSE' $ret->else_result = Expression::parse($parser, $list); $state = 0; // last clause of CASE expression } elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'END' ) { $state = 3; // end of CASE expression ++$list->idx; break; } elseif ($token->type === Token::TYPE_KEYWORD) { $parser->error('Unexpected keyword.', $token); break; } else { $ret->value = Expression::parse($parser, $list); $type = 0; $state = 1; } } elseif ($state === 1) { if ($type === 0) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'WHEN' ) { ++$list->idx; // Skip 'WHEN' $new_value = Expression::parse($parser, $list); $state = 2; $ret->compare_values[] = $new_value; } elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'ELSE' ) { ++$list->idx; // Skip 'ELSE' $ret->else_result = Expression::parse($parser, $list); $state = 0; // last clause of CASE expression } elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'END' ) { $state = 3; // end of CASE expression ++$list->idx; break; } elseif ($token->type === Token::TYPE_KEYWORD) { $parser->error('Unexpected keyword.', $token); break; } } else { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'THEN' ) { ++$list->idx; // Skip 'THEN' $new_result = Expression::parse($parser, $list); $state = 0; $ret->results[] = $new_result; } elseif ($token->type === Token::TYPE_KEYWORD) { $parser->error('Unexpected keyword.', $token); break; } } } elseif ($state === 2) { if ($type === 0) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'THEN' ) { ++$list->idx; // Skip 'THEN' $new_result = Expression::parse($parser, $list); $ret->results[] = $new_result; $state = 1; } elseif ($token->type === Token::TYPE_KEYWORD) { $parser->error('Unexpected keyword.', $token); break; } } } } if ($state !== 3) { $parser->error( 'Unexpected end of CASE expression', $list->tokens[$list->idx - 1] ); } else { $ret->expr = self::build($ret); } --$list->idx; return $ret; } /** * @param CaseExpression $component the component to be built * @param array $options parameters for building * * @return string */ public static function build($component, array $options = array()) { $ret = 'CASE '; if (isset($component->value)) { // Syntax type 0 $ret .= $component->value . ' '; $val_cnt = count($component->compare_values); $res_cnt = count($component->results); for ($i = 0; $i < $val_cnt && $i < $res_cnt; ++$i) { $ret .= 'WHEN ' . $component->compare_values[$i] . ' '; $ret .= 'THEN ' . $component->results[$i] . ' '; } } else { // Syntax type 1 $val_cnt = count($component->conditions); $res_cnt = count($component->results); for ($i = 0; $i < $val_cnt && $i < $res_cnt; ++$i) { $ret .= 'WHEN ' . Condition::build($component->conditions[$i]) . ' '; $ret .= 'THEN ' . $component->results[$i] . ' '; } } if (isset($component->else_result)) { $ret .= 'ELSE ' . $component->else_result . ' '; } $ret .= 'END'; return $ret; } }