public function testBuildCountQuery_DeleteJoin() { $sql = QuerySplitter::buildCountQuery("DELETE foo.* FROM foo INNER JOIN bar ON foo.id = bar.foo_id WHERE abc = 10"); $this->assertEquals("SELECT COUNT(*) FROM foo INNER JOIN bar ON foo.id = bar.foo_id WHERE abc = 10", $sql); }
/** * Quotes a string so it can be used as a table or column name. * Dots are seen as seperator and are kept out of quotes. * * Doesn't quote expressions without Query::BACKQUOTE_STRICT. This means it is not secure without this option. * * @param string $identifier * @param int $flags Query::BACKQUOTE_% * @return string */ public static function backquote($identifier, $flags = self::BACKQUOTE_STRICT) { return QuerySplitter::backquote($identifier, $flags); }
/** * Extract subqueries from sql query (on for SELECT queries) and replace them with #subX in the main query. * Returns array(main query, subquery1, [subquery2, ...]) * * @param string $sql * @param array $sets Do not use! * @return array * * @todo Extract subsets should only go 1 level deep */ public static function extractSubsets($sql, &$sets = null) { $ret_offset = isset($sets); $sets = (array) $sets; // There are certainly no subqueries if (stripos($sql, 'SELECT', 6) === false) { $offset = array_push($sets, $sql) - 1; return $ret_offset ? $offset : $sets; } // Extract any subqueries $offset = array_push($sets, null) - 1; if (self::getQueryType($sql) === 'INSERT' || self::getQueryType($sql) === 'REPLACE') { $parts = self::split($sql); if (isset($parts['query'])) { self::extractSubsets($parts['query'], $sets); $parts['query'] = '#sub' . ($offset + 1); $sql = self::join($parts); } } if (preg_match('/\\(\\s*SELECT\\b/si', $sql)) { do { $matches = null; preg_match('/(?:`[^`]*+`|"(?:[^"\\\\]++|\\\\.)*+"|\'(?:[^\'\\\\]++|\\\\.)*+\'|\\((\\s*SELECT\\b.*\\).*)|\\w++|[^`"\'\\w])*$/si', $sql, $matches, PREG_OFFSET_CAPTURE); if (isset($matches[1])) { $fn = function ($match) use(&$sets) { return '#sub' . QuerySplitter::extractSubsets($match[0], $sets); }; $sql = substr($sql, 0, $matches[1][1]) . preg_replace_callback('/(?:`[^`]*+`|"(?:[^"\\\\]++|\\\\.)*+"|\'(?:[^\'\\\\]++|\\\\.)*+\'|([^`"\'()]+)|\\((?R)\\))*/si', $fn, substr($sql, $matches[1][1]), 1); } } while (isset($matches[1])); } $sets[$offset] = $sql; return $ret_offset ? $offset : $sets; }