/** * @param Query $query * * @return string * * @throws QueryException */ public static function getExecutableSql(Query $query) { $parserResult = static::parseQuery($query); $sql = $parserResult->getSqlExecutor()->getSqlStatements(); list($params, $types) = QueryUtils::processParameterMappings($query, $parserResult->getParameterMappings()); list($sql, $params, $types) = SQLParserUtils::expandListParameters($sql, $params, $types); $paramPos = SQLParserUtils::getPlaceholderPositions($sql); for ($i = count($paramPos) - 1; $i >= 0; $i--) { $sql = substr_replace($sql, $query->getEntityManager()->getConnection()->quote($params[$i], $types[$i]), $paramPos[$i], 1); } return $sql; }
public function startQuery($sql, array $params = null, array $types = null) { if ($this->logger) { $this->logger->startQuery($sql, $params, $types); } // Store select queries for later use if (substr($sql, 0, 6) == 'SELECT') { if ($params) { // Attempt to replace placeholders so that we can log a final SQL query for profiler's EXPLAIN statement // (this is not perfect-- getPlaceholderPositions has some flaws-- but it should generally work with ORM-generated queries) $is_positional = is_numeric(key($params)); list($sql, $params, $types) = \Doctrine\DBAL\SQLParserUtils::expandListParameters($sql, $params, $types); if (empty($types)) { $types = array(); } $placeholders = \Doctrine\DBAL\SQLParserUtils::getPlaceholderPositions($sql, $is_positional); if ($is_positional) { $map = array_flip($placeholders); } else { $map = array(); foreach ($placeholders as $name => $positions) { foreach ($positions as $pos) { $map[$pos] = $name; } } } ksort($map); $src_pos = 0; $final_sql = ''; $first_param_index = key($params); foreach ($map as $pos => $replace_name) { $final_sql .= substr($sql, $src_pos, $pos - $src_pos); if ($sql[$pos] == ':') { $src_pos = $pos + strlen($replace_name); $index = trim($replace_name, ':'); } else { $src_pos = $pos + 1; $index = $replace_name + $first_param_index; } $final_sql .= \D::manager()->getConnection()->quote($params[$index], \Arr::get($types, $index)); } $final_sql .= substr($sql, $src_pos); $this->queries[] = $final_sql; } else { $this->queries[] = $sql; } } }
/** * @dataProvider dataGetPlaceholderPositions * @param type $query * @param type $isPositional * @param type $expectedParamPos */ public function testGetPlaceholderPositions($query, $isPositional, $expectedParamPos) { $actualParamPos = SQLParserUtils::getPlaceholderPositions($query, $isPositional); $this->assertEquals($expectedParamPos, $actualParamPos); }
private function extractParameterPsitions($query) { return \Doctrine\DBAL\SQLParserUtils::getPlaceholderPositions($query, false); }