*/ private array $data = []; public function __construct(private readonly ResponseRenderer $response, private readonly SimulateDml $simulateDml) { } public function __invoke(ServerRequest $request): Response { $sqlDelimiter = $request->getParsedBodyParamAsString('sql_delimiter', ''); $parser = $this->createParser(Current::$sqlQuery, $sqlDelimiter); $this->process($parser); if ($this->error !== '') { $this->response->addJSON('message', Message::rawError($this->error)); $this->response->addJSON('sql_data', false); return $this->response->response(); } $this->response->addJSON('sql_data', $this->data); return $this->response->response(); } private function createParser(string $query, string $delimiter): Parser { $lexer = new Lexer($query, false, $delimiter); $list = new TokensList(array_values(array_filter( $lexer->list->tokens, static function ($token): bool { return $token->type !== TokenType::Comment; }, ))); return new Parser($list); } private function process(Parser $parser): void { foreach ($parser->statements as $statement) { if ( ! $statement instanceof UpdateStatement && ! $statement instanceof DeleteStatement || ! empty($statement->join) || count(Query::getTables($statement)) > 1 ) { $this->error = __('Only single-table UPDATE and DELETE queries can be simulated.'); break; } // Get the matched rows for the query. $result = $this->simulateDml->getMatchedRows($parser, $statement); $this->error = $this->simulateDml->getError(); if ($this->error !== '') { break; } $this->data[] = $result; } } }