graze /
morphism
| 1 | <?php |
||
| 2 | namespace Graze\Morphism\Parse; |
||
| 3 | |||
| 4 | use LogicException; |
||
| 5 | use RuntimeException; |
||
| 6 | |||
| 7 | /** |
||
| 8 | * Represents the definition of an check, this is currently only parsed but not added back to any schema. Checks are |
||
| 9 | * added automatically by MySQL, excluding them allows morphism to be backwards compatible with MySQL < 8. |
||
| 10 | */ |
||
| 11 | class CheckDefinition |
||
| 12 | { |
||
| 13 | /** @var string|null */ |
||
| 14 | public $name = null; |
||
| 15 | |||
| 16 | /** @var string */ |
||
| 17 | public $expression; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Parses an check definition from $stream |
||
| 21 | * |
||
| 22 | * If the optional preceding CONSTRAINT clause was parsed, you should supply its optional $name. |
||
| 23 | * |
||
| 24 | * @param TokenStream $stream |
||
| 25 | * @param string|null $name name supplied in optional CONSTRAINT clause |
||
| 26 | */ |
||
| 27 | public function parse(TokenStream $stream, $name = null) |
||
| 28 | { |
||
| 29 | $this->name = $name; |
||
| 30 | |||
| 31 | $this->expression = $this->parseExpressionBetweenBrackets($stream); |
||
| 32 | |||
| 33 | $mark = $stream->getMark(); |
||
| 34 | $token = $stream->nextToken(); |
||
| 35 | |||
| 36 | // Check for [NOT] ENFORCED |
||
| 37 | if ($token->eq(Token::IDENTIFIER, 'NOT')) { |
||
| 38 | $stream->expect(Token::IDENTIFIER, 'ENFORCED'); |
||
| 39 | $this->expression .= ' NOT ENFORCED'; |
||
| 40 | } elseif ($token->eq(Token::IDENTIFIER, 'ENFORCED')) { |
||
| 41 | $this->expression .= ' ENFORCED'; |
||
| 42 | } else { |
||
| 43 | $stream->rewind($mark); |
||
| 44 | } |
||
| 45 | } |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Parses an expression between brackets, the next token is expected to be a bracket. |
||
| 49 | * |
||
| 50 | * @param TokenStream $stream |
||
| 51 | * @return string |
||
| 52 | */ |
||
| 53 | private function parseExpressionBetweenBrackets(TokenStream $stream) |
||
| 54 | { |
||
| 55 | $stream->expectOpenParen(); |
||
| 56 | |||
| 57 | $expression = '('; |
||
| 58 | $previousToken = null; |
||
|
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
| 59 | $token = null; |
||
| 60 | |||
| 61 | while (true) { |
||
| 62 | $mark = $stream->getMark(); |
||
| 63 | $previousToken = $token; |
||
| 64 | $token = $stream->nextToken(); |
||
| 65 | |||
| 66 | if ($token->eq(Token::SYMBOL, '(')) { |
||
| 67 | // Nested expression found. |
||
| 68 | $stream->rewind($mark); |
||
| 69 | |||
| 70 | if ($previousToken && $previousToken->type != Token::SYMBOL) { |
||
| 71 | $expression .= ' '; |
||
| 72 | } |
||
| 73 | |||
| 74 | $expression .= $this->parseExpressionBetweenBrackets($stream); |
||
| 75 | } elseif ($token->eq(Token::SYMBOL, ')')) { |
||
| 76 | // Ending bracket found, stop parsing. |
||
| 77 | $expression .= ')'; |
||
| 78 | break; |
||
| 79 | } elseif ($token->isEof()) { |
||
| 80 | throw new RuntimeException("Unexpected end-of-file"); |
||
| 81 | } else { |
||
| 82 | if ($previousToken && $previousToken->type != Token::SYMBOL && $token->type != Token::SYMBOL) { |
||
| 83 | $expression .= ' '; |
||
| 84 | } |
||
| 85 | $expression .= $token->text; |
||
| 86 | } |
||
| 87 | } |
||
| 88 | |||
| 89 | return $expression; |
||
| 90 | } |
||
| 91 | } |
||
| 92 |