Location: PHPKode > scripts > DBQuery-MySQL > DBQuery-MySQL-1.0.0/docs/source-class-Jasny.MySQL.DBQuery_Splitter.html
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="generator" content="ApiGen 2.8.0" />
	<meta name="robots" content="noindex" />

	<title>File Jasny/MySQL/DBQuery/Splitter.php | DBQuery-MySQL · API documentation</title>

	<script type="text/javascript" src="resources/combined.js?394153670"></script>
	<script type="text/javascript" src="elementlist.js?2873722340"></script>
	<link rel="stylesheet" type="text/css" media="all" href="resources/style.css?3505392360" />

	<script type="text/javascript">
		var _gaq = _gaq || [];
		_gaq.push(['_setAccount', "UA-32388850-2"]);
		_gaq.push(['_trackPageview']);

		(function() {
			var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
			ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
			var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
		})();
	</script>
</head>

<body>
<div id="left">
	<div id="menu">
		<a href="index.html" title="Overview"><span>Overview</span></a>


		<div id="groups">
			<h3>Namespaces</h3>
			<ul>
				<li class="active"><a href="namespace-Jasny.html">Jasny<span></span></a>
						<ul>
				<li class="active"><a href="namespace-Jasny.MySQL.html">MySQL</a>
						</li>
							</ul></li>
			</ul>
		</div>

		<hr />


		<div id="elements">
			<h3>Classes</h3>
			<ul>
				<li><a href="class-Jasny.MySQL.DBQuery.html">DBQuery</a></li>
				<li class="active"><a href="class-Jasny.MySQL.DBQuery_Splitter.html">DBQuery_Splitter</a></li>
			</ul>





		</div>
	</div>
</div>

<div id="splitter"></div>

<div id="right">
<div id="rightInner">
	<form id="search">
		<input type="hidden" name="cx" value="" />
		<input type="hidden" name="ie" value="UTF-8" />
		<input type="text" name="q" class="text" />
		<input type="submit" value="Search" />
	</form>

	<div id="navigation">
		<ul>
			<li>
				<a href="index.html" title="Overview"><span>Overview</span></a>
			</li>
			<li>
				<a href="namespace-Jasny.MySQL.html" title="Summary of Jasny\MySQL"><span>Namespace</span></a>
			</li>
			<li>
				<a href="class-Jasny.MySQL.DBQuery_Splitter.html" title="Summary of Jasny\MySQL\DBQuery_Splitter"><span>Class</span></a>
			</li>
		</ul>
		<ul>
			<li>
				<a href="tree.html" title="Tree view of classes, interfaces, traits and exceptions"><span>Tree</span></a>
			</li>
		</ul>
		<ul>
		</ul>
	</div>

<pre><code><span id="1" class="l"><a class="l" href="#1">  1: </a><span class="xlang">&lt;?php</span>
</span><span id="2" class="l"><a class="l" href="#2">  2: </a>
</span><span id="3" class="l"><a class="l" href="#3">  3: </a><span class="php-comment">/*
</span></span><span id="4" class="l"><a class="l" href="#4">  4: </a><span class="php-comment"> * BEWARE!!!
</span></span><span id="5" class="l"><a class="l" href="#5">  5: </a><span class="php-comment"> *   This class highly depends on complicated PCRE regular expressions. So if your not really really really good at reading/writing these, don't touch this class.
</span></span><span id="6" class="l"><a class="l" href="#6">  6: </a><span class="php-comment"> *   To prevent a regex getting in some crazy (or catastrophic) backtracking loop, use regexbuddy (http://www.regexbuddy.com) or some other step-by-step regex debugger.
</span></span><span id="7" class="l"><a class="l" href="#7">  7: </a><span class="php-comment"> *   The performance of each function is really important, since these functions will be called a lot in 1 page and should be concidered abstraction overhead. The focus is on performance not readability of the code.
</span></span><span id="8" class="l"><a class="l" href="#8">  8: </a><span class="php-comment"> * 
</span></span><span id="9" class="l"><a class="l" href="#9">  9: </a><span class="php-comment"> *   Expression REGEX_VALUES matches all quoted strings, all backquoted identifiers and all words and all non-word chars upto the next keyword.
</span></span><span id="10" class="l"><a class="l" href="#10"> 10: </a><span class="php-comment"> *   It uses atomic groups to look for the next keyword after each quoted string and complete word, not after each char. Atomic groups are also neccesary to prevent catastrophic backtracking when the regex should fail.
</span></span><span id="11" class="l"><a class="l" href="#11"> 11: </a><span class="php-comment"> * 
</span></span><span id="12" class="l"><a class="l" href="#12"> 12: </a><span class="php-comment"> *   Expressions like '/\w+\s*(abc)?\s*\w+z/' should be prevented. If this regex would try to match &quot;ef    ghi&quot;, the regex will first take all 3 spaces for the first \s*. When the regex fails it retries taking the
</span></span><span id="13" class="l"><a class="l" href="#13"> 13: </a><span class="php-comment"> *     first 2 spaces for the first \s* and the 3rd space for the second \s*, etc, etc. This causes the matching to take more than 3 times as long as '/\w+\s*(abc\s*)?\w+z/' would.
</span></span><span id="14" class="l"><a class="l" href="#14"> 14: </a><span class="php-comment"> *   This is the reason why trailing spaces are included with REGEX_VALUES and not automaticly trimmed.
</span></span><span id="15" class="l"><a class="l" href="#15"> 15: </a><span class="php-comment"> */</span>
</span><span id="16" class="l"><a class="l" href="#16"> 16: </a>
</span><span id="17" class="l"><a class="l" href="#17"> 17: </a><span class="php-keyword1">namespace</span> Jasny\<span class="php-keyword2">MySQL</span>;
</span><span id="18" class="l"><a class="l" href="#18"> 18: </a>
</span><span id="19" class="l"><a class="l" href="#19"> 19: </a><span class="php-comment">/**
</span></span><span id="20" class="l"><a class="l" href="#20"> 20: </a><span class="php-comment"> * Break down a mysql query statement to different parts, which can be altered and joined again.
</span></span><span id="21" class="l"><a class="l" href="#21"> 21: </a><span class="php-comment"> * Supported types: SELECT, INSERT, REPLACE, UPDATE, DELETE, TRUNCATE.
</span></span><span id="22" class="l"><a class="l" href="#22"> 22: </a><span class="php-comment"> *
</span></span><span id="23" class="l"><a class="l" href="#23"> 23: </a><span class="php-comment"> * SELECT ... UNION syntax is *not* supported.
</span></span><span id="24" class="l"><a class="l" href="#24"> 24: </a><span class="php-comment"> * DELETE ... USING syntax is *not* supported.
</span></span><span id="25" class="l"><a class="l" href="#25"> 25: </a><span class="php-comment"> * Invalid query statements might give unexpected results. 
</span></span><span id="26" class="l"><a class="l" href="#26"> 26: </a><span class="php-comment"> * 
</span></span><span id="27" class="l"><a class="l" href="#27"> 27: </a><span class="php-comment"> * All methods of this class are static.
</span></span><span id="28" class="l"><a class="l" href="#28"> 28: </a><span class="php-comment"> * 
</span></span><span id="29" class="l"><a class="l" href="#29"> 29: </a><span class="php-comment"> * @package DBQuery
</span></span><span id="30" class="l"><a class="l" href="#30"> 30: </a><span class="php-comment"> * 
</span></span><span id="31" class="l"><a class="l" href="#31"> 31: </a><span class="php-comment"> * @todo It might be possible to use recursion instead of extracting subqueries, using \((SELECT\b)(?R)\). For query other that select, I should do (?:^\s++UPDATE ...|(?&lt;!^)\s++SELECT ...) to match SELECT and not UPDATE statement in recursion.
</span></span><span id="32" class="l"><a class="l" href="#32"> 32: </a><span class="php-comment"> * @todo Implement splitValues to get values of INSERT INTO ... VALUES ... statement
</span></span><span id="33" class="l"><a class="l" href="#33"> 33: </a><span class="php-comment"> */</span>
</span><span id="34" class="l"><a class="l" href="#34"> 34: </a><span class="php-keyword1">class</span> <a id="DBQuery_Splitter" href="#DBQuery_Splitter">DBQuery_Splitter</a>
</span><span id="35" class="l"><a class="l" href="#35"> 35: </a>{
</span><span id="36" class="l"><a class="l" href="#36"> 36: </a>
</span><span id="37" class="l"><a class="l" href="#37"> 37: </a>    <span class="php-keyword1">const</span> <a id="REGEX_VALUES" href="#REGEX_VALUES">REGEX_VALUES</a> = <span class="php-quote">'(?:\w++|`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|\s++|[^`&quot;\'\w\s])*?'</span>;
</span><span id="38" class="l"><a class="l" href="#38"> 38: </a>    <span class="php-keyword1">const</span> <a id="REGEX_IDENTIFIER" href="#REGEX_IDENTIFIER">REGEX_IDENTIFIER</a> = <span class="php-quote">'(?:(?:\w++|`[^`]*+`)(?:\.(?:\w++|`[^`]*+`)){0,2})'</span>;
</span><span id="39" class="l"><a class="l" href="#39"> 39: </a>    <span class="php-keyword1">const</span> <a id="REGEX_QUOTED" href="#REGEX_QUOTED">REGEX_QUOTED</a> = <span class="php-quote">'(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\')'</span>;
</span><span id="40" class="l"><a class="l" href="#40"> 40: </a>
</span><span id="41" class="l"><a class="l" href="#41"> 41: </a>    <span class="php-comment">//------------- Basics -----------------------</span>
</span><span id="42" class="l"><a class="l" href="#42"> 42: </a>
</span><span id="43" class="l"><a class="l" href="#43"> 43: </a>    <span class="php-comment">/**
</span></span><span id="44" class="l"><a class="l" href="#44"> 44: </a><span class="php-comment">     * Quote a value so it can be savely used in a query.
</span></span><span id="45" class="l"><a class="l" href="#45"> 45: </a><span class="php-comment">     * 
</span></span><span id="46" class="l"><a class="l" href="#46"> 46: </a><span class="php-comment">     * @param mixed  $value
</span></span><span id="47" class="l"><a class="l" href="#47"> 47: </a><span class="php-comment">     * @param string $empty  Return $empty if $value is null
</span></span><span id="48" class="l"><a class="l" href="#48"> 48: </a><span class="php-comment">     * @return string
</span></span><span id="49" class="l"><a class="l" href="#49"> 49: </a><span class="php-comment">     */</span>
</span><span id="50" class="l"><a class="l" href="#50"> 50: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_quote" href="#_quote">quote</a>(<span class="php-var">$value</span>, <span class="php-var">$empty</span> = <span class="php-quote">'NULL'</span>)
</span><span id="51" class="l"><a class="l" href="#51"> 51: </a>    {
</span><span id="52" class="l"><a class="l" href="#52"> 52: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_null</span>(<span class="php-var">$value</span>)) <span class="php-keyword1">return</span> <span class="php-var">$empty</span>;
</span><span id="53" class="l"><a class="l" href="#53"> 53: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_bool</span>(<span class="php-var">$value</span>)) <span class="php-keyword1">return</span> <span class="php-var">$value</span> ? <span class="php-quote">'TRUE'</span> : <span class="php-quote">'FALSE'</span>;
</span><span id="54" class="l"><a class="l" href="#54"> 54: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_int</span>(<span class="php-var">$value</span>) || <span class="php-keyword2">is_float</span>(<span class="php-var">$value</span>)) <span class="php-keyword1">return</span> (string)<span class="php-var">$value</span>;
</span><span id="55" class="l"><a class="l" href="#55"> 55: </a>
</span><span id="56" class="l"><a class="l" href="#56"> 56: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$value</span>)) {
</span><span id="57" class="l"><a class="l" href="#57"> 57: </a>            <span class="php-keyword1">foreach</span> (<span class="php-var">$value</span> <span class="php-keyword1">as</span> &amp;<span class="php-var">$v</span>) <span class="php-var">$v</span> = self::quote(<span class="php-var">$v</span>, <span class="php-var">$empty</span>);
</span><span id="58" class="l"><a class="l" href="#58"> 58: </a>            <span class="php-keyword1">return</span> <span class="php-quote">'('</span> . <span class="php-keyword2">join</span>(<span class="php-quote">', '</span>, <span class="php-var">$value</span>) . <span class="php-quote">')'</span>;
</span><span id="59" class="l"><a class="l" href="#59"> 59: </a>        }
</span><span id="60" class="l"><a class="l" href="#60"> 60: </a>
</span><span id="61" class="l"><a class="l" href="#61"> 61: </a>        <span class="php-keyword1">return</span> <span class="php-quote">'&quot;'</span> . <span class="php-keyword2">strtr</span>(<span class="php-var">$value</span>, <span class="php-keyword1">array</span>(<span class="php-quote">'\\'</span> =&gt; <span class="php-quote">'\\\\'</span>, <span class="php-quote">&quot;\0&quot;</span> =&gt; <span class="php-quote">'\\0'</span>, <span class="php-quote">&quot;\r&quot;</span> =&gt; <span class="php-quote">'\\r'</span>, <span class="php-quote">&quot;\n&quot;</span> =&gt; <span class="php-quote">'\\n'</span>, <span class="php-quote">'&quot;'</span> =&gt; <span class="php-quote">'\\&quot;'</span>)) . <span class="php-quote">'&quot;'</span>;
</span><span id="62" class="l"><a class="l" href="#62"> 62: </a>    }
</span><span id="63" class="l"><a class="l" href="#63"> 63: </a>
</span><span id="64" class="l"><a class="l" href="#64"> 64: </a>    <span class="php-comment">/**
</span></span><span id="65" class="l"><a class="l" href="#65"> 65: </a><span class="php-comment">     * Quotes a string so it can be used as a table or column name.
</span></span><span id="66" class="l"><a class="l" href="#66"> 66: </a><span class="php-comment">     * Dots are seen as seperator and are kept out of quotes.
</span></span><span id="67" class="l"><a class="l" href="#67"> 67: </a><span class="php-comment">     * 
</span></span><span id="68" class="l"><a class="l" href="#68"> 68: </a><span class="php-comment">     * Doesn't quote expressions without DBQuery::BACKQUOTE_STRICT. This means it is not secure without this option. 
</span></span><span id="69" class="l"><a class="l" href="#69"> 69: </a><span class="php-comment">     * 
</span></span><span id="70" class="l"><a class="l" href="#70"> 70: </a><span class="php-comment">     * @param string   $identifier
</span></span><span id="71" class="l"><a class="l" href="#71"> 71: </a><span class="php-comment">     * @param int      $flags       DBQuery::BACKQUOTE_%
</span></span><span id="72" class="l"><a class="l" href="#72"> 72: </a><span class="php-comment">     * @return string
</span></span><span id="73" class="l"><a class="l" href="#73"> 73: </a><span class="php-comment">     * 
</span></span><span id="74" class="l"><a class="l" href="#74"> 74: </a><span class="php-comment">     * @todo Cleanup misquoted TRIM function
</span></span><span id="75" class="l"><a class="l" href="#75"> 75: </a><span class="php-comment">     */</span>
</span><span id="76" class="l"><a class="l" href="#76"> 76: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_backquote" href="#_backquote">backquote</a>(<span class="php-var">$identifier</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="77" class="l"><a class="l" href="#77"> 77: </a>    {
</span><span id="78" class="l"><a class="l" href="#78"> 78: </a>        <span class="php-comment">// Strict</span>
</span><span id="79" class="l"><a class="l" href="#79"> 79: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$flags</span> &amp; DBQuery::BACKQUOTE_STRICT) {
</span><span id="80" class="l"><a class="l" href="#80"> 80: </a>            <span class="php-var">$identifier</span> = <span class="php-keyword2">trim</span>(<span class="php-var">$identifier</span>);
</span><span id="81" class="l"><a class="l" href="#81"> 81: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\w++$/'</span>, <span class="php-var">$identifier</span>)) <span class="php-keyword1">return</span> <span class="php-quote">&quot;`</span><span class="php-var">$identifier</span><span class="php-quote">`&quot;</span>;
</span><span id="82" class="l"><a class="l" href="#82"> 82: </a>
</span><span id="83" class="l"><a class="l" href="#83"> 83: </a>            <span class="php-var">$quoted</span> = <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/`[^`]*+`|([^`\.]++)/'</span>, <span class="php-keyword1">array</span>(__CLASS__, <span class="php-quote">'backquote_ab'</span>), <span class="php-var">$identifier</span>);
</span><span id="84" class="l"><a class="l" href="#84"> 84: </a>
</span><span id="85" class="l"><a class="l" href="#85"> 85: </a>            <span class="php-keyword1">if</span> (<span class="php-var">$quoted</span> &amp;&amp; !<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^(?:`[^`]*`\.)*`[^`]*`$/'</span>, <span class="php-var">$quoted</span>)) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to quote '</span><span class="php-var">$identifier</span><span class="php-quote">' safely&quot;</span>);
</span><span id="86" class="l"><a class="l" href="#86"> 86: </a>            <span class="php-keyword1">return</span> <span class="php-var">$quoted</span>;
</span><span id="87" class="l"><a class="l" href="#87"> 87: </a>        }
</span><span id="88" class="l"><a class="l" href="#88"> 88: </a>
</span><span id="89" class="l"><a class="l" href="#89"> 89: </a>        <span class="php-comment">// None</span>
</span><span id="90" class="l"><a class="l" href="#90"> 90: </a>        <span class="php-keyword1">if</span> ((<span class="php-var">$flags</span> &amp; DBQuery::_BACKQUOTE_OPTIONS) == DBQuery::BACKQUOTE_NONE) {
</span><span id="91" class="l"><a class="l" href="#91"> 91: </a>            <span class="php-keyword1">return</span> <span class="php-var">$identifier</span>;
</span><span id="92" class="l"><a class="l" href="#92"> 92: </a>        }
</span><span id="93" class="l"><a class="l" href="#93"> 93: </a>
</span><span id="94" class="l"><a class="l" href="#94"> 94: </a>        <span class="php-comment">// Check if all closing brackets have an opening parenthesis has an opening one to protect against SQL injection</span>
</span><span id="95" class="l"><a class="l" href="#95"> 95: </a>        <span class="php-keyword2">preg_match</span>(<span class="php-quote">'/(?:(?:'</span> . REGEX_QUOTED . <span class="php-quote">'|[^\(\)]+)*\((?:(?:'</span> . REGEX_QUOTED . <span class="php-quote">'|[^\(\)]+)*|(?R))\))*(?:'</span> . REGEX_QUOTED . <span class="php-quote">'|[^\(\)]+)*/'</span>, <span class="php-var">$identifier</span>, <span class="php-var">$match</span>);
</span><span id="96" class="l"><a class="l" href="#96"> 96: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$match</span>[<span class="php-num">0</span>] != <span class="php-var">$identifier</span>) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> Exception(<span class="php-quote">&quot;Unable to quote '</span><span class="php-var">$identifier</span><span class="php-quote">' safely&quot;</span>);
</span><span id="97" class="l"><a class="l" href="#97"> 97: </a>        
</span><span id="98" class="l"><a class="l" href="#98"> 98: </a>        <span class="php-comment">// Words</span>
</span><span id="99" class="l"><a class="l" href="#99"> 99: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$flags</span> &amp; DBQuery::BACKQUOTE_WORDS) {
</span><span id="100" class="l"><a class="l" href="#100">100: </a>            <span class="php-var">$quoted</span> = <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|(?&lt;=^|[\s,])(?:NULL|TRUE|FALSE|DEFAULT|DIV|AND|OR|XOR|(?:NOT\s+)?IN|IS(?:\s+NOT)?|BETWEEN|R?LIKE|REGEXP|SOUNDS\s+LIKE|MATCH|AS|CASE|WHEN|THEN|END|ASC|DESC|BINARY)(?=$|[\s,])|(?&lt;=^|[\s,])COLLATE\s+\w++|(?&lt;=^|[\s,])USING\s+\w++|`[^`]*+`|([^\s,\.`\'&quot;]*[a-z_][^\s,\.`\'&quot;]*)/i'</span>, <span class="php-keyword1">array</span>(__CLASS__, <span class="php-quote">'backquote_ab'</span>), <span class="php-var">$identifier</span>);
</span><span id="101" class="l"><a class="l" href="#101">101: </a>            <span class="php-keyword1">return</span> <span class="php-var">$quoted</span>;
</span><span id="102" class="l"><a class="l" href="#102">102: </a>        }
</span><span id="103" class="l"><a class="l" href="#103">103: </a>
</span><span id="104" class="l"><a class="l" href="#104">104: </a>        <span class="php-comment">// Smart</span>
</span><span id="105" class="l"><a class="l" href="#105">105: </a>        <span class="php-var">$quoted</span> = <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|\b(?:NULL|TRUE|FALSE|DEFAULT|DIV|AND|OR|XOR|(?:NOT\s+)?IN|IS(?:\s+NOT)?|BETWEEN|R?LIKE|REGEXP|SOUNDS\s+LIKE|MATCH|AS|CASE|WHEN|THEN|END|ASC|DESC|BINARY)\b|\bCOLLATE\s+\w++|\bUSING\s+\w++|TRIM\s*\((?:BOTH|LEADING|TRAILING)|`[^`]*+`|(\d*[a-z_]\w*\b)(?!\s*\()/i'</span>, <span class="php-keyword1">array</span>(__CLASS__, <span class="php-quote">'backquote_ab'</span>), <span class="php-var">$identifier</span>);
</span><span id="106" class="l"><a class="l" href="#106">106: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\bCAST\s*\(/i'</span>, <span class="php-var">$quoted</span>)) <span class="php-var">$quoted</span> = self::backquote_castCleanup(<span class="php-var">$quoted</span>);
</span><span id="107" class="l"><a class="l" href="#107">107: </a>        <span class="php-keyword1">return</span> <span class="php-var">$quoted</span>;
</span><span id="108" class="l"><a class="l" href="#108">108: </a>    }
</span><span id="109" class="l"><a class="l" href="#109">109: </a>
</span><span id="110" class="l"><a class="l" href="#110">110: </a>    <span class="php-comment">/**
</span></span><span id="111" class="l"><a class="l" href="#111">111: </a><span class="php-comment">     * Callback function for backquote.
</span></span><span id="112" class="l"><a class="l" href="#112">112: </a><span class="php-comment">     * @ignore
</span></span><span id="113" class="l"><a class="l" href="#113">113: </a><span class="php-comment">     * 
</span></span><span id="114" class="l"><a class="l" href="#114">114: </a><span class="php-comment">     * @param array $match
</span></span><span id="115" class="l"><a class="l" href="#115">115: </a><span class="php-comment">     * @return string
</span></span><span id="116" class="l"><a class="l" href="#116">116: </a><span class="php-comment">     */</span>
</span><span id="117" class="l"><a class="l" href="#117">117: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_backquote_ab" href="#_backquote_ab">backquote_ab</a>(<span class="php-var">$match</span>)
</span><span id="118" class="l"><a class="l" href="#118">118: </a>    {
</span><span id="119" class="l"><a class="l" href="#119">119: </a>        <span class="php-keyword1">return</span> !<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">1</span>]) ? <span class="php-quote">'`'</span> . <span class="php-var">$match</span>[<span class="php-num">1</span>] . <span class="php-quote">'`'</span> : <span class="php-var">$match</span>[<span class="php-num">0</span>];
</span><span id="120" class="l"><a class="l" href="#120">120: </a>    }
</span><span id="121" class="l"><a class="l" href="#121">121: </a>
</span><span id="122" class="l"><a class="l" href="#122">122: </a>    <span class="php-comment">/**
</span></span><span id="123" class="l"><a class="l" href="#123">123: </a><span class="php-comment">     * Unquote up quoted types of CAST function.
</span></span><span id="124" class="l"><a class="l" href="#124">124: </a><span class="php-comment">     * @ignore
</span></span><span id="125" class="l"><a class="l" href="#125">125: </a><span class="php-comment">     * 
</span></span><span id="126" class="l"><a class="l" href="#126">126: </a><span class="php-comment">     * @param string|array $match  Match or identifier
</span></span><span id="127" class="l"><a class="l" href="#127">127: </a><span class="php-comment">     * @return string  
</span></span><span id="128" class="l"><a class="l" href="#128">128: </a><span class="php-comment">     */</span>
</span><span id="129" class="l"><a class="l" href="#129">129: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_backquote_castCleanup" href="#_backquote_castCleanup">backquote_castCleanup</a>(<span class="php-var">$match</span>)
</span><span id="130" class="l"><a class="l" href="#130">130: </a>    {
</span><span id="131" class="l"><a class="l" href="#131">131: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$match</span>) &amp;&amp; !<span class="php-keyword1">isset</span>(<span class="php-var">$match</span>[<span class="php-num">2</span>])) <span class="php-keyword1">return</span> <span class="php-var">$match</span>[<span class="php-num">0</span>];
</span><span id="132" class="l"><a class="l" href="#132">132: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">is_array</span>(<span class="php-var">$match</span>)) <span class="php-var">$match</span> = <span class="php-keyword1">array</span>(<span class="php-num">2</span> =&gt; <span class="php-var">$match</span>);
</span><span id="133" class="l"><a class="l" href="#133">133: </a>
</span><span id="134" class="l"><a class="l" href="#134">134: </a>        <span class="php-var">$match</span>[<span class="php-num">2</span>] = <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/((?:'</span> . self::REGEX_QUOTED . <span class="php-quote">'|[^()`&quot;\']++)*)(?:\(((?R)*)\))?/i'</span>, <span class="php-keyword1">array</span>(__CLASS__, <span class="php-quote">'backquote_castCleanup'</span>), <span class="php-var">$match</span>[<span class="php-num">2</span>]);
</span><span id="135" class="l"><a class="l" href="#135">135: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">1</span>]) &amp;&amp; <span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\CAST\s*$/i'</span>, <span class="php-var">$match</span>[<span class="php-num">1</span>])) <span class="php-var">$match</span>[<span class="php-num">2</span>] = <span class="php-keyword2">preg_replace</span>(<span class="php-quote">'/(\bAS\b\s*)`([^`]++)`(\s*)$/i'</span>, <span class="php-quote">'\1\2\3'</span>, <span class="php-var">$match</span>[<span class="php-num">2</span>]);
</span><span id="136" class="l"><a class="l" href="#136">136: </a>
</span><span id="137" class="l"><a class="l" href="#137">137: </a>        <span class="php-keyword1">return</span> <span class="php-keyword1">isset</span>(<span class="php-var">$match</span>[<span class="php-num">0</span>]) ? <span class="php-quote">&quot;</span><span class="php-var">{$match[1]}</span><span class="php-quote">(</span><span class="php-var">{$match[2]}</span><span class="php-quote">)&quot;</span> : <span class="php-var">$match</span>[<span class="php-num">2</span>];
</span><span id="138" class="l"><a class="l" href="#138">138: </a>    }
</span><span id="139" class="l"><a class="l" href="#139">139: </a>
</span><span id="140" class="l"><a class="l" href="#140">140: </a>    <span class="php-comment">/**
</span></span><span id="141" class="l"><a class="l" href="#141">141: </a><span class="php-comment">     * Check if expression is a field/table name
</span></span><span id="142" class="l"><a class="l" href="#142">142: </a><span class="php-comment">     *
</span></span><span id="143" class="l"><a class="l" href="#143">143: </a><span class="php-comment">     * @param string $name
</span></span><span id="144" class="l"><a class="l" href="#144">144: </a><span class="php-comment">     * @return boolean
</span></span><span id="145" class="l"><a class="l" href="#145">145: </a><span class="php-comment">     */</span>
</span><span id="146" class="l"><a class="l" href="#146">146: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_isIdentifier" href="#_isIdentifier">isIdentifier</a>(<span class="php-var">$name</span>)
</span><span id="147" class="l"><a class="l" href="#147">147: </a>    {
</span><span id="148" class="l"><a class="l" href="#148">148: </a>        <span class="php-keyword1">return</span> (bool)<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^((?:`([^`]*)`|(\d*[a-z_]\w*))\.)*(`([^`]*)`|(\d*[a-z_]\w*))$/i'</span>, <span class="php-keyword2">trim</span>(<span class="php-var">$name</span>));
</span><span id="149" class="l"><a class="l" href="#149">149: </a>    }
</span><span id="150" class="l"><a class="l" href="#150">150: </a>
</span><span id="151" class="l"><a class="l" href="#151">151: </a>    <span class="php-comment">/**
</span></span><span id="152" class="l"><a class="l" href="#152">152: </a><span class="php-comment">     * Insert parameters into SQL query.
</span></span><span id="153" class="l"><a class="l" href="#153">153: </a><span class="php-comment">     * Don't mix unnamed ('?') and named (':key') placeholders.
</span></span><span id="154" class="l"><a class="l" href="#154">154: </a><span class="php-comment">     *
</span></span><span id="155" class="l"><a class="l" href="#155">155: </a><span class="php-comment">     * @param mixed $statement  Query string or DBQuery::Statement object
</span></span><span id="156" class="l"><a class="l" href="#156">156: </a><span class="php-comment">     * @param array $params     Parameters to insert into statement on placeholders
</span></span><span id="157" class="l"><a class="l" href="#157">157: </a><span class="php-comment">     * @return mixed
</span></span><span id="158" class="l"><a class="l" href="#158">158: </a><span class="php-comment">     */</span>
</span><span id="159" class="l"><a class="l" href="#159">159: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_bind" href="#_bind">bind</a>(<span class="php-var">$statement</span>, <span class="php-var">$params</span>)
</span><span id="160" class="l"><a class="l" href="#160">160: </a>    {
</span><span id="161" class="l"><a class="l" href="#161">161: </a>        <span class="php-var">$fn</span> = <span class="php-keyword1">function</span> (<span class="php-var">$match</span>) <span class="php-keyword1">use</span> (&amp;<span class="php-var">$params</span>) {
</span><span id="162" class="l"><a class="l" href="#162">162: </a>                    <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">2</span>]) &amp;&amp; !<span class="php-keyword1">empty</span>(<span class="php-var">$params</span>)) <span class="php-var">$value</span> = <span class="php-keyword2">array_shift</span>(<span class="php-var">$params</span>);
</span><span id="163" class="l"><a class="l" href="#163">163: </a>                    <span class="php-keyword1">elseif</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">3</span>]) &amp;&amp; <span class="php-keyword2">array_key_exists</span>(<span class="php-var">$match</span>[<span class="php-num">3</span>], <span class="php-var">$params</span>)) <span class="php-var">$value</span> = <span class="php-var">$params</span>[<span class="php-var">$match</span>[<span class="php-num">3</span>]];
</span><span id="164" class="l"><a class="l" href="#164">164: </a>                    <span class="php-keyword1">else</span> <span class="php-keyword1">return</span> <span class="php-var">$match</span>[<span class="php-num">0</span>];
</span><span id="165" class="l"><a class="l" href="#165">165: </a>
</span><span id="166" class="l"><a class="l" href="#166">166: </a>                    <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$value</span>) &amp;&amp; (<span class="php-var">$match</span>[<span class="php-num">1</span>] || <span class="php-var">$match</span>[<span class="php-num">4</span>])) <span class="php-var">$value</span> = <span class="php-var">$match</span>[<span class="php-num">1</span>] . <span class="php-var">$value</span> . <span class="php-var">$match</span>[<span class="php-num">4</span>];
</span><span id="167" class="l"><a class="l" href="#167">167: </a>                    <span class="php-keyword1">return</span> DBQuery_Splitter::quote(<span class="php-var">$value</span>);
</span><span id="168" class="l"><a class="l" href="#168">168: </a>                };
</span><span id="169" class="l"><a class="l" href="#169">169: </a>
</span><span id="170" class="l"><a class="l" href="#170">170: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|(%?)(?:(\?)|:(\w++))(%?)/'</span>, <span class="php-var">$fn</span>, <span class="php-var">$statement</span>);
</span><span id="171" class="l"><a class="l" href="#171">171: </a>    }
</span><span id="172" class="l"><a class="l" href="#172">172: </a>
</span><span id="173" class="l"><a class="l" href="#173">173: </a>    <span class="php-comment">/**
</span></span><span id="174" class="l"><a class="l" href="#174">174: </a><span class="php-comment">     * Count the number of placeholders in a statement.
</span></span><span id="175" class="l"><a class="l" href="#175">175: </a><span class="php-comment">     *
</span></span><span id="176" class="l"><a class="l" href="#176">176: </a><span class="php-comment">     * @param string $statement
</span></span><span id="177" class="l"><a class="l" href="#177">177: </a><span class="php-comment">     * @return int
</span></span><span id="178" class="l"><a class="l" href="#178">178: </a><span class="php-comment">     */</span>
</span><span id="179" class="l"><a class="l" href="#179">179: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_countPlaceholders" href="#_countPlaceholders">countPlaceholders</a>(<span class="php-var">$statement</span>)
</span><span id="180" class="l"><a class="l" href="#180">180: </a>    {
</span><span id="181" class="l"><a class="l" href="#181">181: </a>        <span class="php-var">$matches</span> = <span class="php-keyword1">null</span>;
</span><span id="182" class="l"><a class="l" href="#182">182: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match_all</span>(<span class="php-quote">'/`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|(\?|:\w++)/'</span>, <span class="php-var">$statement</span>, <span class="php-var">$matches</span>, PREG_PATTERN_ORDER)) <span class="php-keyword1">return</span> <span class="php-num">0</span>;
</span><span id="183" class="l"><a class="l" href="#183">183: </a>
</span><span id="184" class="l"><a class="l" href="#184">184: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">count</span>(<span class="php-keyword2">array_filter</span>(<span class="php-var">$matches</span>[<span class="php-num">1</span>]));
</span><span id="185" class="l"><a class="l" href="#185">185: </a>    }
</span><span id="186" class="l"><a class="l" href="#186">186: </a>
</span><span id="187" class="l"><a class="l" href="#187">187: </a>    <span class="php-comment">//------------- Split / Build query -----------------------</span>
</span><span id="188" class="l"><a class="l" href="#188">188: </a>
</span><span id="189" class="l"><a class="l" href="#189">189: </a>    <span class="php-comment">/**
</span></span><span id="190" class="l"><a class="l" href="#190">190: </a><span class="php-comment">     * Return the type of the query.
</span></span><span id="191" class="l"><a class="l" href="#191">191: </a><span class="php-comment">     *
</span></span><span id="192" class="l"><a class="l" href="#192">192: </a><span class="php-comment">     * @param string $sql  SQL query statement (or an array with parts)
</span></span><span id="193" class="l"><a class="l" href="#193">193: </a><span class="php-comment">     * @return string
</span></span><span id="194" class="l"><a class="l" href="#194">194: </a><span class="php-comment">     */</span>
</span><span id="195" class="l"><a class="l" href="#195">195: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_getQueryType" href="#_getQueryType">getQueryType</a>(<span class="php-var">$sql</span>)
</span><span id="196" class="l"><a class="l" href="#196">196: </a>    {
</span><span id="197" class="l"><a class="l" href="#197">197: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>)) <span class="php-var">$sql</span> = <span class="php-keyword2">key</span>(<span class="php-var">$sql</span>);
</span><span id="198" class="l"><a class="l" href="#198">198: </a>
</span><span id="199" class="l"><a class="l" href="#199">199: </a>        <span class="php-var">$matches</span> = <span class="php-keyword1">null</span>;
</span><span id="200" class="l"><a class="l" href="#200">200: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*(SELECT|INSERT|REPLACE|UPDATE|DELETE|TRUNCATE|CALL|DO|HANDLER|LOAD\s+(?:DATA|XML)\s+INFILE|(?:ALTER|CREATE|DROP|RENAME)\s+(?:DATABASE|TABLE|VIEW|FUNCTION|PROCEDURE|TRIGGER|INDEX)|PREPARE|EXECUTE|DEALLOCATE\s+PREPARE|DESCRIBE|EXPLAIN|HELP|USE|LOCK\s+TABLES|UNLOCK\s+TABLES|SET|SHOW|START\s+TRANSACTION|BEGIN|COMMIT|ROLLBACK|SAVEPOINT|RELEASE SAVEPOINT|CACHE\s+INDEX|FLUSH|KILL|LOAD|RESET|PURGE\s+BINARY\s+LOGS|START\s+SLAVE|STOP\s+SLAVE)\b/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>)) <span class="php-keyword1">return</span> <span class="php-keyword1">null</span>;
</span><span id="201" class="l"><a class="l" href="#201">201: </a>
</span><span id="202" class="l"><a class="l" href="#202">202: </a>        <span class="php-var">$type</span> = <span class="php-keyword2">strtoupper</span>(<span class="php-keyword2">preg_replace</span>(<span class="php-quote">'/\s++/'</span>, <span class="php-quote">' '</span>, <span class="php-var">$matches</span>[<span class="php-num">1</span>]));
</span><span id="203" class="l"><a class="l" href="#203">203: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$type</span> === <span class="php-quote">'BEGIN'</span>) <span class="php-var">$type</span> = <span class="php-quote">'START TRANSACTION'</span>;
</span><span id="204" class="l"><a class="l" href="#204">204: </a>
</span><span id="205" class="l"><a class="l" href="#205">205: </a>        <span class="php-keyword1">return</span> <span class="php-var">$type</span>;
</span><span id="206" class="l"><a class="l" href="#206">206: </a>    }
</span><span id="207" class="l"><a class="l" href="#207">207: </a>
</span><span id="208" class="l"><a class="l" href="#208">208: </a>    <span class="php-comment">/**
</span></span><span id="209" class="l"><a class="l" href="#209">209: </a><span class="php-comment">     * Add parts to existing statement
</span></span><span id="210" class="l"><a class="l" href="#210">210: </a><span class="php-comment">     * 
</span></span><span id="211" class="l"><a class="l" href="#211">211: </a><span class="php-comment">     * @param array|string $sql  Parts (array) or statement (string)
</span></span><span id="212" class="l"><a class="l" href="#212">212: </a><span class="php-comment">     * @param array        $add  Parts to add as array(key=&gt;array(DBQuery::PREPEND=&gt;array(), DBQuery::APPEND=&gt;array(), ...)
</span></span><span id="213" class="l"><a class="l" href="#213">213: </a><span class="php-comment">     * @return array|string
</span></span><span id="214" class="l"><a class="l" href="#214">214: </a><span class="php-comment">     */</span>
</span><span id="215" class="l"><a class="l" href="#215">215: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_addParts" href="#_addParts">addParts</a>(<span class="php-var">$sql</span>, <span class="php-var">$add</span>)
</span><span id="216" class="l"><a class="l" href="#216">216: </a>    {
</span><span id="217" class="l"><a class="l" href="#217">217: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>)) <span class="php-var">$parts</span> = &amp; <span class="php-var">$sql</span>;
</span><span id="218" class="l"><a class="l" href="#218">218: </a>        <span class="php-keyword1">else</span> <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);;
</span><span id="219" class="l"><a class="l" href="#219">219: </a>
</span><span id="220" class="l"><a class="l" href="#220">220: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$add</span>)) {
</span><span id="221" class="l"><a class="l" href="#221">221: </a>            <span class="php-keyword1">foreach</span> (<span class="php-var">$add</span> <span class="php-keyword1">as</span> <span class="php-var">$key</span> =&gt; &amp;<span class="php-var">$partsAdd</span>) {
</span><span id="222" class="l"><a class="l" href="#222">222: </a>                <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>])) <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = <span class="php-keyword2">trim</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]);
</span><span id="223" class="l"><a class="l" href="#223">223: </a>
</span><span id="224" class="l"><a class="l" href="#224">224: </a>                <span class="php-keyword1">if</span> (<span class="php-var">$key</span> === <span class="php-quote">'columns'</span> || <span class="php-var">$key</span> === <span class="php-quote">'set'</span> || <span class="php-var">$key</span> === <span class="php-quote">'group by'</span> || <span class="php-var">$key</span> === <span class="php-quote">'order by'</span>) {
</span><span id="225" class="l"><a class="l" href="#225">225: </a>                    <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = <span class="php-keyword2">join</span>(<span class="php-quote">', '</span>, <span class="php-keyword2">array_merge</span>(<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) ? <span class="php-var">$partsAdd</span>[DBQuery::PREPEND] : <span class="php-keyword1">array</span>(), !<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-keyword1">array</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) : <span class="php-keyword1">array</span>(), <span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) ? <span class="php-var">$partsAdd</span>[DBQuery::APPEND] : <span class="php-keyword1">array</span>()));
</span><span id="226" class="l"><a class="l" href="#226">226: </a>                } <span class="php-keyword1">elseif</span> (<span class="php-var">$key</span> === <span class="php-quote">'values'</span>) {
</span><span id="227" class="l"><a class="l" href="#227">227: </a>                    <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) ? <span class="php-quote">'('</span> . <span class="php-keyword2">join</span>(<span class="php-quote">'), ('</span>, <span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) . <span class="php-quote">')'</span> : <span class="php-quote">''</span>) . (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) &amp;&amp; !<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-quote">', '</span> : <span class="php-quote">''</span>) . <span class="php-var">$parts</span>[<span class="php-var">$key</span>] . (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) &amp;&amp; !<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-quote">', '</span> : <span class="php-quote">''</span>) . (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) ? <span class="php-quote">'('</span> . <span class="php-keyword2">join</span>(<span class="php-quote">'), ('</span>, <span class="php-var">$partsAdd</span>[DBQuery::APPEND]) . <span class="php-quote">')'</span> : <span class="php-quote">''</span>);
</span><span id="228" class="l"><a class="l" href="#228">228: </a>                } <span class="php-keyword1">elseif</span> (<span class="php-var">$key</span> === <span class="php-quote">'from'</span> || <span class="php-var">$key</span> === <span class="php-quote">'into'</span> || <span class="php-var">$key</span> === <span class="php-quote">'table'</span>) {
</span><span id="229" class="l"><a class="l" href="#229">229: </a>                    <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) &amp;&amp; !<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^(\w+|`.*`)$/'</span>, <span class="php-var">$parts</span>[<span class="php-var">$key</span>])) <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = <span class="php-quote">'('</span> . <span class="php-var">$parts</span>[<span class="php-var">$key</span>] . <span class="php-quote">')'</span>;
</span><span id="230" class="l"><a class="l" href="#230">230: </a>                    <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = <span class="php-keyword2">trim</span>((<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) ? <span class="php-keyword2">join</span>(<span class="php-quote">' '</span>, <span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) . <span class="php-quote">' '</span> : <span class="php-quote">''</span>) . (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-var">$parts</span>[<span class="php-var">$key</span>] : <span class="php-quote">''</span>) . (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) ? <span class="php-quote">' '</span> . <span class="php-keyword2">join</span>(<span class="php-quote">' '</span>, <span class="php-var">$partsAdd</span>[DBQuery::APPEND]) : <span class="php-quote">''</span>), <span class="php-quote">', '</span>);
</span><span id="231" class="l"><a class="l" href="#231">231: </a>                } <span class="php-keyword1">elseif</span> (<span class="php-var">$key</span> === <span class="php-quote">'where'</span> || <span class="php-var">$key</span> === <span class="php-quote">'having'</span>) {
</span><span id="232" class="l"><a class="l" href="#232">232: </a>                    <span class="php-var">$items</span> = <span class="php-keyword2">array_merge</span>(<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) ? <span class="php-var">$partsAdd</span>[DBQuery::PREPEND] : <span class="php-keyword1">array</span>(), !<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-keyword1">array</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) : <span class="php-keyword1">array</span>(), <span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) ? <span class="php-var">$partsAdd</span>[DBQuery::APPEND] : <span class="php-keyword1">array</span>());
</span><span id="233" class="l"><a class="l" href="#233">233: </a>                    <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$items</span>)) <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = <span class="php-keyword2">count</span>(<span class="php-var">$items</span>) == <span class="php-num">1</span> ? <span class="php-keyword2">reset</span>(<span class="php-var">$items</span>) : <span class="php-quote">'('</span> . <span class="php-keyword2">join</span>(<span class="php-quote">') AND ('</span>, <span class="php-var">$items</span>) . <span class="php-quote">')'</span>;
</span><span id="234" class="l"><a class="l" href="#234">234: </a>                } <span class="php-keyword1">else</span> {
</span><span id="235" class="l"><a class="l" href="#235">235: </a>                    <span class="php-var">$parts</span>[<span class="php-var">$key</span>] = (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) ? <span class="php-keyword2">join</span>(<span class="php-quote">' '</span>, <span class="php-var">$partsAdd</span>[DBQuery::PREPEND]) . <span class="php-quote">' '</span> : <span class="php-quote">''</span>) . (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-var">$key</span>]) ? <span class="php-var">$parts</span>[<span class="php-var">$key</span>] : <span class="php-quote">''</span>) . (<span class="php-keyword1">isset</span>(<span class="php-var">$partsAdd</span>[DBQuery::APPEND]) ? <span class="php-quote">' '</span> . <span class="php-keyword2">join</span>(<span class="php-quote">' '</span>, <span class="php-var">$partsAdd</span>[DBQuery::APPEND]) : <span class="php-quote">''</span>);
</span><span id="236" class="l"><a class="l" href="#236">236: </a>                }
</span><span id="237" class="l"><a class="l" href="#237">237: </a>            }
</span><span id="238" class="l"><a class="l" href="#238">238: </a>        }
</span><span id="239" class="l"><a class="l" href="#239">239: </a>
</span><span id="240" class="l"><a class="l" href="#240">240: </a>        <span class="php-keyword1">return</span> <span class="php-var">$parts</span>;
</span><span id="241" class="l"><a class="l" href="#241">241: </a>    }
</span><span id="242" class="l"><a class="l" href="#242">242: </a>
</span><span id="243" class="l"><a class="l" href="#243">243: </a>    <span class="php-comment">/**
</span></span><span id="244" class="l"><a class="l" href="#244">244: </a><span class="php-comment">     * Build a where expression.
</span></span><span id="245" class="l"><a class="l" href="#245">245: </a><span class="php-comment">     * 
</span></span><span id="246" class="l"><a class="l" href="#246">246: </a><span class="php-comment">     * @param mixed $column Expression, column name, column number, expression with placeholders or array(column=&gt;value, ...)
</span></span><span id="247" class="l"><a class="l" href="#247">247: </a><span class="php-comment">     * @param mixed $value  Value or array of values
</span></span><span id="248" class="l"><a class="l" href="#248">248: </a><span class="php-comment">     * @param int   $flags  DBQuery::BACKQUOTE_%
</span></span><span id="249" class="l"><a class="l" href="#249">249: </a><span class="php-comment">     * @return string
</span></span><span id="250" class="l"><a class="l" href="#250">250: </a><span class="php-comment">     */</span>
</span><span id="251" class="l"><a class="l" href="#251">251: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_buildWhere" href="#_buildWhere">buildWhere</a>(<span class="php-var">$column</span>, <span class="php-var">$value</span> = <span class="php-keyword1">null</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="252" class="l"><a class="l" href="#252">252: </a>    {
</span><span id="253" class="l"><a class="l" href="#253">253: </a>        <span class="php-comment">// Build where for each column</span>
</span><span id="254" class="l"><a class="l" href="#254">254: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$column</span>)) {
</span><span id="255" class="l"><a class="l" href="#255">255: </a>            <span class="php-keyword1">foreach</span> (<span class="php-var">$column</span> <span class="php-keyword1">as</span> <span class="php-var">$col</span> =&gt; &amp;<span class="php-var">$value</span>) {
</span><span id="256" class="l"><a class="l" href="#256">256: </a>                <span class="php-var">$value</span> = self::buildWhere(<span class="php-var">$col</span>, <span class="php-var">$value</span>);
</span><span id="257" class="l"><a class="l" href="#257">257: </a>                <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$value</span>)) <span class="php-keyword1">unset</span>(<span class="php-var">$column</span>[<span class="php-var">$col</span>]);
</span><span id="258" class="l"><a class="l" href="#258">258: </a>            }
</span><span id="259" class="l"><a class="l" href="#259">259: </a>
</span><span id="260" class="l"><a class="l" href="#260">260: </a>            <span class="php-keyword1">return</span> !<span class="php-keyword1">empty</span>(<span class="php-var">$column</span>) ? <span class="php-keyword2">join</span>(<span class="php-quote">' AND '</span>, <span class="php-var">$column</span>) : <span class="php-keyword1">null</span>;
</span><span id="261" class="l"><a class="l" href="#261">261: </a>        }
</span><span id="262" class="l"><a class="l" href="#262">262: </a>
</span><span id="263" class="l"><a class="l" href="#263">263: </a>        <span class="php-var">$placeholders</span> = self::countPlaceholders(<span class="php-var">$column</span>);
</span><span id="264" class="l"><a class="l" href="#264">264: </a>        <span class="php-var">$column</span> = self::backquote(<span class="php-var">$column</span>, <span class="php-var">$flags</span>);
</span><span id="265" class="l"><a class="l" href="#265">265: </a>
</span><span id="266" class="l"><a class="l" href="#266">266: </a>        <span class="php-comment">// Simple case</span>
</span><span id="267" class="l"><a class="l" href="#267">267: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$placeholders</span> == <span class="php-num">0</span>) {
</span><span id="268" class="l"><a class="l" href="#268">268: </a>            <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$value</span>) || <span class="php-var">$value</span> === <span class="php-keyword1">array</span>()) <span class="php-keyword1">return</span> self::isIdentifier(<span class="php-var">$column</span>) ? <span class="php-keyword1">null</span> : <span class="php-var">$column</span>;
</span><span id="269" class="l"><a class="l" href="#269">269: </a>            <span class="php-keyword1">return</span> <span class="php-var">$column</span> . (<span class="php-keyword2">is_array</span>(<span class="php-var">$value</span>) ? <span class="php-quote">' IN '</span> : <span class="php-quote">' = '</span>) . self::quote(<span class="php-var">$value</span>);
</span><span id="270" class="l"><a class="l" href="#270">270: </a>        }
</span><span id="271" class="l"><a class="l" href="#271">271: </a>
</span><span id="272" class="l"><a class="l" href="#272">272: </a>        <span class="php-comment">// With placeholder</span>
</span><span id="273" class="l"><a class="l" href="#273">273: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$placeholders</span> == <span class="php-num">1</span>) <span class="php-var">$value</span> = <span class="php-keyword1">array</span>(<span class="php-var">$value</span>);
</span><span id="274" class="l"><a class="l" href="#274">274: </a>        <span class="php-keyword1">return</span> self::bind(<span class="php-var">$column</span>, <span class="php-var">$value</span>);
</span><span id="275" class="l"><a class="l" href="#275">275: </a>    }
</span><span id="276" class="l"><a class="l" href="#276">276: </a>
</span><span id="277" class="l"><a class="l" href="#277">277: </a>    <span class="php-comment">//------------- Extract subsets --------------------</span>
</span><span id="278" class="l"><a class="l" href="#278">278: </a>
</span><span id="279" class="l"><a class="l" href="#279">279: </a>    <span class="php-comment">/**
</span></span><span id="280" class="l"><a class="l" href="#280">280: </a><span class="php-comment">     * Extract subqueries from sql query (on for SELECT queries) and replace them with #subX in the main query.
</span></span><span id="281" class="l"><a class="l" href="#281">281: </a><span class="php-comment">     * Returns array(main query, subquery1, [subquery2, ...])
</span></span><span id="282" class="l"><a class="l" href="#282">282: </a><span class="php-comment">     *
</span></span><span id="283" class="l"><a class="l" href="#283">283: </a><span class="php-comment">     * @param  string $sql
</span></span><span id="284" class="l"><a class="l" href="#284">284: </a><span class="php-comment">     * @param  array  $sets  Do not use!
</span></span><span id="285" class="l"><a class="l" href="#285">285: </a><span class="php-comment">     * @return array
</span></span><span id="286" class="l"><a class="l" href="#286">286: </a><span class="php-comment">     * 
</span></span><span id="287" class="l"><a class="l" href="#287">287: </a><span class="php-comment">     * @todo Extract subsets should only go 1 level deep
</span></span><span id="288" class="l"><a class="l" href="#288">288: </a><span class="php-comment">     */</span>
</span><span id="289" class="l"><a class="l" href="#289">289: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_extractSubsets" href="#_extractSubsets">extractSubsets</a>(<span class="php-var">$sql</span>, &amp;<span class="php-var">$sets</span> = <span class="php-keyword1">null</span>)
</span><span id="290" class="l"><a class="l" href="#290">290: </a>    {
</span><span id="291" class="l"><a class="l" href="#291">291: </a>        <span class="php-var">$ret_offset</span> = <span class="php-keyword1">isset</span>(<span class="php-var">$sets</span>);
</span><span id="292" class="l"><a class="l" href="#292">292: </a>        <span class="php-var">$sets</span> = (<span class="php-keyword1">array</span>)<span class="php-var">$sets</span>;
</span><span id="293" class="l"><a class="l" href="#293">293: </a>
</span><span id="294" class="l"><a class="l" href="#294">294: </a>        <span class="php-comment">// There are certainly no subqueries</span>
</span><span id="295" class="l"><a class="l" href="#295">295: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">stripos</span>(<span class="php-var">$sql</span>, <span class="php-quote">'SELECT'</span>, <span class="php-num">6</span>) === <span class="php-keyword1">false</span>) {
</span><span id="296" class="l"><a class="l" href="#296">296: </a>            <span class="php-var">$offset</span> = <span class="php-keyword2">array_push</span>(<span class="php-var">$sets</span>, <span class="php-var">$sql</span>) - <span class="php-num">1</span>;
</span><span id="297" class="l"><a class="l" href="#297">297: </a>            <span class="php-keyword1">return</span> <span class="php-var">$ret_offset</span> ? <span class="php-var">$offset</span> : <span class="php-var">$sets</span>;
</span><span id="298" class="l"><a class="l" href="#298">298: </a>        }
</span><span id="299" class="l"><a class="l" href="#299">299: </a>
</span><span id="300" class="l"><a class="l" href="#300">300: </a>        <span class="php-comment">// Extract any subqueries</span>
</span><span id="301" class="l"><a class="l" href="#301">301: </a>        <span class="php-var">$offset</span> = <span class="php-keyword2">array_push</span>(<span class="php-var">$sets</span>, <span class="php-keyword1">null</span>) - <span class="php-num">1</span>;
</span><span id="302" class="l"><a class="l" href="#302">302: </a>
</span><span id="303" class="l"><a class="l" href="#303">303: </a>        <span class="php-keyword1">if</span> (self::getQueryType(<span class="php-var">$sql</span>) === <span class="php-quote">'INSERT'</span> || self::getQueryType(<span class="php-var">$sql</span>) === <span class="php-quote">'REPLACE'</span>) {
</span><span id="304" class="l"><a class="l" href="#304">304: </a>            <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="305" class="l"><a class="l" href="#305">305: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'query'</span>])) {
</span><span id="306" class="l"><a class="l" href="#306">306: </a>                self::extractSubsets(<span class="php-var">$parts</span>[<span class="php-quote">'query'</span>], <span class="php-var">$sets</span>);
</span><span id="307" class="l"><a class="l" href="#307">307: </a>                <span class="php-var">$parts</span>[<span class="php-quote">'query'</span>] = <span class="php-quote">'#sub'</span> . (<span class="php-var">$offset</span> + <span class="php-num">1</span>);
</span><span id="308" class="l"><a class="l" href="#308">308: </a>                <span class="php-var">$sql</span> = self::<span class="php-keyword2">join</span>(<span class="php-var">$parts</span>);
</span><span id="309" class="l"><a class="l" href="#309">309: </a>            }
</span><span id="310" class="l"><a class="l" href="#310">310: </a>        }
</span><span id="311" class="l"><a class="l" href="#311">311: </a>
</span><span id="312" class="l"><a class="l" href="#312">312: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\(\s*SELECT\b/si'</span>, <span class="php-var">$sql</span>)) {
</span><span id="313" class="l"><a class="l" href="#313">313: </a>            <span class="php-keyword1">do</span> {
</span><span id="314" class="l"><a class="l" href="#314">314: </a>                <span class="php-var">$matches</span> = <span class="php-keyword1">null</span>;
</span><span id="315" class="l"><a class="l" href="#315">315: </a>                <span class="php-keyword2">preg_match</span>(<span class="php-quote">'/(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|\((\s*SELECT\b.*\).*)|\w++|[^`&quot;\'\w])*$/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>, PREG_OFFSET_CAPTURE);
</span><span id="316" class="l"><a class="l" href="#316">316: </a>                <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$matches</span>[<span class="php-num">1</span>])) {
</span><span id="317" class="l"><a class="l" href="#317">317: </a>                    <span class="php-var">$fn</span> = <span class="php-keyword1">function</span>(<span class="php-var">$match</span>) <span class="php-keyword1">use</span>(&amp;<span class="php-var">$sets</span>) {
</span><span id="318" class="l"><a class="l" href="#318">318: </a>                                <span class="php-keyword1">return</span> <span class="php-quote">'#sub'</span> . DBQuery_Splitter::extractSubsets(<span class="php-var">$match</span>[<span class="php-num">0</span>], <span class="php-var">$sets</span>);
</span><span id="319" class="l"><a class="l" href="#319">319: </a>                            };
</span><span id="320" class="l"><a class="l" href="#320">320: </a>                    <span class="php-var">$sql</span> = <span class="php-keyword2">substr</span>(<span class="php-var">$sql</span>, <span class="php-num">0</span>, <span class="php-var">$matches</span>[<span class="php-num">1</span>][<span class="php-num">1</span>]) . <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|([^`&quot;\'()]+)|\((?R)\))*/si'</span>, <span class="php-var">$fn</span>, <span class="php-keyword2">substr</span>(<span class="php-var">$sql</span>, <span class="php-var">$matches</span>[<span class="php-num">1</span>][<span class="php-num">1</span>]), <span class="php-num">1</span>);
</span><span id="321" class="l"><a class="l" href="#321">321: </a>                }
</span><span id="322" class="l"><a class="l" href="#322">322: </a>            } <span class="php-keyword1">while</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$matches</span>[<span class="php-num">1</span>]));
</span><span id="323" class="l"><a class="l" href="#323">323: </a>        }
</span><span id="324" class="l"><a class="l" href="#324">324: </a>
</span><span id="325" class="l"><a class="l" href="#325">325: </a>        <span class="php-var">$sets</span>[<span class="php-var">$offset</span>] = <span class="php-var">$sql</span>;
</span><span id="326" class="l"><a class="l" href="#326">326: </a>        <span class="php-keyword1">return</span> <span class="php-var">$ret_offset</span> ? <span class="php-var">$offset</span> : <span class="php-var">$sets</span>;
</span><span id="327" class="l"><a class="l" href="#327">327: </a>    }
</span><span id="328" class="l"><a class="l" href="#328">328: </a>
</span><span id="329" class="l"><a class="l" href="#329">329: </a>    <span class="php-comment">/**
</span></span><span id="330" class="l"><a class="l" href="#330">330: </a><span class="php-comment">     * Inject extracted subsets back into main sql query.
</span></span><span id="331" class="l"><a class="l" href="#331">331: </a><span class="php-comment">     *
</span></span><span id="332" class="l"><a class="l" href="#332">332: </a><span class="php-comment">     * @param array $sets  array(main query, subquery, ...) or array(main parts, subparts, ...); may be passed by reference
</span></span><span id="333" class="l"><a class="l" href="#333">333: </a><span class="php-comment">     * @return string|array
</span></span><span id="334" class="l"><a class="l" href="#334">334: </a><span class="php-comment">     */</span>
</span><span id="335" class="l"><a class="l" href="#335">335: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_injectSubsets" href="#_injectSubsets">injectSubsets</a>(<span class="php-var">$sets</span>)
</span><span id="336" class="l"><a class="l" href="#336">336: </a>    {
</span><span id="337" class="l"><a class="l" href="#337">337: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">count</span>(<span class="php-var">$sets</span>) == <span class="php-num">1</span>) <span class="php-keyword1">return</span> <span class="php-keyword2">reset</span>(<span class="php-var">$sets</span>);
</span><span id="338" class="l"><a class="l" href="#338">338: </a>
</span><span id="339" class="l"><a class="l" href="#339">339: </a>        <span class="php-var">$done</span> = <span class="php-keyword1">false</span>;
</span><span id="340" class="l"><a class="l" href="#340">340: </a>        <span class="php-var">$target</span> = &amp; <span class="php-var">$sets</span>[<span class="php-keyword2">min</span>(<span class="php-keyword2">array_keys</span>(<span class="php-var">$sets</span>))];
</span><span id="341" class="l"><a class="l" href="#341">341: </a>
</span><span id="342" class="l"><a class="l" href="#342">342: </a>        <span class="php-var">$fn</span> = <span class="php-keyword1">function</span>(<span class="php-var">$match</span>) <span class="php-keyword1">use</span>(&amp;<span class="php-var">$sets</span>, &amp;<span class="php-var">$done</span>) {
</span><span id="343" class="l"><a class="l" href="#343">343: </a>                    <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">1</span>])) <span class="php-var">$done</span> = <span class="php-keyword1">false</span>;
</span><span id="344" class="l"><a class="l" href="#344">344: </a>                    <span class="php-keyword1">return</span> <span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-num">1</span>]) ? <span class="php-var">$match</span>[<span class="php-num">0</span>] : (<span class="php-keyword2">is_array</span>(<span class="php-var">$sets</span>[<span class="php-var">$match</span>[<span class="php-num">1</span>]]) ? self::<span class="php-keyword2">join</span>(<span class="php-var">$sets</span>[<span class="php-var">$match</span>[<span class="php-num">1</span>]]) : <span class="php-var">$sets</span>[<span class="php-var">$match</span>[<span class="php-num">1</span>]]);
</span><span id="345" class="l"><a class="l" href="#345">345: </a>                };
</span><span id="346" class="l"><a class="l" href="#346">346: </a>
</span><span id="347" class="l"><a class="l" href="#347">347: </a>        <span class="php-keyword1">while</span> (!<span class="php-var">$done</span>) {
</span><span id="348" class="l"><a class="l" href="#348">348: </a>            <span class="php-var">$done</span> = <span class="php-keyword1">true</span>;
</span><span id="349" class="l"><a class="l" href="#349">349: </a>            <span class="php-var">$target</span> = <span class="php-keyword2">preg_replace_callback</span>(<span class="php-quote">'/^'</span> . self::REGEX_QUOTED . <span class="php-quote">'|(?:\#sub(\d+))/'</span>, <span class="php-var">$fn</span>, <span class="php-var">$target</span>);
</span><span id="350" class="l"><a class="l" href="#350">350: </a>        }
</span><span id="351" class="l"><a class="l" href="#351">351: </a>
</span><span id="352" class="l"><a class="l" href="#352">352: </a>        <span class="php-keyword1">return</span> <span class="php-var">$target</span>;
</span><span id="353" class="l"><a class="l" href="#353">353: </a>    }
</span><span id="354" class="l"><a class="l" href="#354">354: </a>
</span><span id="355" class="l"><a class="l" href="#355">355: </a>    <span class="php-comment">//------------- Split query --------------------</span>
</span><span id="356" class="l"><a class="l" href="#356">356: </a>
</span><span id="357" class="l"><a class="l" href="#357">357: </a>    <span class="php-comment">/**
</span></span><span id="358" class="l"><a class="l" href="#358">358: </a><span class="php-comment">     * Split a query.
</span></span><span id="359" class="l"><a class="l" href="#359">359: </a><span class="php-comment">     * If a part is not set whitin the SQL query, the part is an empty string.
</span></span><span id="360" class="l"><a class="l" href="#360">360: </a><span class="php-comment">     *
</span></span><span id="361" class="l"><a class="l" href="#361">361: </a><span class="php-comment">     * @param string $sql  SQL query statement
</span></span><span id="362" class="l"><a class="l" href="#362">362: </a><span class="php-comment">     * @return array
</span></span><span id="363" class="l"><a class="l" href="#363">363: </a><span class="php-comment">     */</span>
</span><span id="364" class="l"><a class="l" href="#364">364: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <span class="php-keyword2">split</span>(<span class="php-var">$sql</span>)
</span><span id="365" class="l"><a class="l" href="#365">365: </a>    {
</span><span id="366" class="l"><a class="l" href="#366">366: </a>        <span class="php-var">$type</span> = self::getQueryType(<span class="php-var">$sql</span>);
</span><span id="367" class="l"><a class="l" href="#367">367: </a>        <span class="php-keyword1">switch</span> (<span class="php-var">$type</span>) {
</span><span id="368" class="l"><a class="l" href="#368">368: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'SELECT'</span>: <span class="php-keyword1">return</span> self::splitSelectQuery(<span class="php-var">$sql</span>);
</span><span id="369" class="l"><a class="l" href="#369">369: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'INSERT'</span>:
</span><span id="370" class="l"><a class="l" href="#370">370: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'REPLACE'</span>: <span class="php-keyword1">return</span> self::splitInsertQuery(<span class="php-var">$sql</span>);
</span><span id="371" class="l"><a class="l" href="#371">371: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'UPDATE'</span>: <span class="php-keyword1">return</span> self::splitUpdateQuery(<span class="php-var">$sql</span>);
</span><span id="372" class="l"><a class="l" href="#372">372: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'DELETE'</span>: <span class="php-keyword1">return</span> self::splitDeleteQuery(<span class="php-var">$sql</span>);
</span><span id="373" class="l"><a class="l" href="#373">373: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'TRUNCATE'</span>: <span class="php-keyword1">return</span> self::splitTruncateQuery(<span class="php-var">$sql</span>);
</span><span id="374" class="l"><a class="l" href="#374">374: </a>            <span class="php-keyword1">case</span> <span class="php-quote">'SET'</span>: <span class="php-keyword1">return</span> self::splitSetQuery(<span class="php-var">$sql</span>);
</span><span id="375" class="l"><a class="l" href="#375">375: </a>        }
</span><span id="376" class="l"><a class="l" href="#376">376: </a>
</span><span id="377" class="l"><a class="l" href="#377">377: </a>        <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split &quot;</span> . (!<span class="php-keyword1">empty</span>(<span class="php-var">$type</span>) ? <span class="php-quote">&quot;</span><span class="php-var">$type</span><span class="php-quote"> &quot;</span> : <span class="php-quote">&quot;&quot;</span>) . <span class="php-quote">&quot;query. </span><span class="php-var">$sql</span><span class="php-quote">&quot;</span>);
</span><span id="378" class="l"><a class="l" href="#378">378: </a>    }
</span><span id="379" class="l"><a class="l" href="#379">379: </a>
</span><span id="380" class="l"><a class="l" href="#380">380: </a>    <span class="php-comment">/**
</span></span><span id="381" class="l"><a class="l" href="#381">381: </a><span class="php-comment">     * Join parts to create a query.
</span></span><span id="382" class="l"><a class="l" href="#382">382: </a><span class="php-comment">     * The parts are joined in the order in which they appear in the array.
</span></span><span id="383" class="l"><a class="l" href="#383">383: </a><span class="php-comment">     * 
</span></span><span id="384" class="l"><a class="l" href="#384">384: </a><span class="php-comment">     * CAUTION: The parts are joined blindly (no validation), so shit in shit out
</span></span><span id="385" class="l"><a class="l" href="#385">385: </a><span class="php-comment">     *
</span></span><span id="386" class="l"><a class="l" href="#386">386: </a><span class="php-comment">     * @param array $parts
</span></span><span id="387" class="l"><a class="l" href="#387">387: </a><span class="php-comment">     * @return string
</span></span><span id="388" class="l"><a class="l" href="#388">388: </a><span class="php-comment">     */</span>
</span><span id="389" class="l"><a class="l" href="#389">389: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <span class="php-keyword2">join</span>(<span class="php-var">$parts</span>)
</span><span id="390" class="l"><a class="l" href="#390">390: </a>    {
</span><span id="391" class="l"><a class="l" href="#391">391: </a>        <span class="php-var">$type</span> = self::getQueryType(<span class="php-var">$parts</span>);
</span><span id="392" class="l"><a class="l" href="#392">392: </a>
</span><span id="393" class="l"><a class="l" href="#393">393: </a>        <span class="php-var">$sql_parts</span> = <span class="php-keyword1">array</span>();
</span><span id="394" class="l"><a class="l" href="#394">394: </a>
</span><span id="395" class="l"><a class="l" href="#395">395: </a>        <span class="php-keyword1">foreach</span> (<span class="php-var">$parts</span> <span class="php-keyword1">as</span> <span class="php-var">$key</span> =&gt; &amp;<span class="php-var">$part</span>) {
</span><span id="396" class="l"><a class="l" href="#396">396: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$part</span>)) <span class="php-var">$part</span> = <span class="php-keyword2">join</span>(<span class="php-quote">&quot;, &quot;</span>, <span class="php-var">$part</span>);
</span><span id="397" class="l"><a class="l" href="#397">397: </a>            <span class="php-keyword1">if</span> (<span class="php-var">$part</span> === <span class="php-quote">''</span>) <span class="php-var">$part</span> = <span class="php-keyword1">null</span>;
</span><span id="398" class="l"><a class="l" href="#398">398: </a>
</span><span id="399" class="l"><a class="l" href="#399">399: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$part</span>) || <span class="php-keyword1">empty</span>(<span class="php-var">$sql_parts</span>)) {
</span><span id="400" class="l"><a class="l" href="#400">400: </a>                <span class="php-keyword1">if</span> (<span class="php-var">$key</span> == <span class="php-quote">'columns'</span> &amp;&amp; (<span class="php-var">$type</span> == <span class="php-quote">'INSERT'</span> || <span class="php-var">$type</span> == <span class="php-quote">'REPLACE'</span>)) <span class="php-var">$part</span> = <span class="php-quote">'('</span> . <span class="php-var">$part</span> . <span class="php-quote">')'</span>;
</span><span id="401" class="l"><a class="l" href="#401">401: </a>                <span class="php-var">$sql_parts</span>[] .= (<span class="php-var">$key</span> === <span class="php-quote">'columns'</span> || <span class="php-var">$key</span> === <span class="php-quote">'query'</span> || <span class="php-var">$key</span> === <span class="php-quote">'table'</span> || <span class="php-var">$key</span> === <span class="php-quote">'options'</span> ? <span class="php-quote">''</span> : <span class="php-keyword2">strtoupper</span>(<span class="php-var">$key</span>) . (<span class="php-keyword1">isset</span>(<span class="php-var">$part</span>) ? <span class="php-quote">&quot; &quot;</span> : <span class="php-quote">&quot;&quot;</span>)) . <span class="php-keyword2">trim</span>(<span class="php-var">$part</span>, <span class="php-quote">&quot; \t\n,&quot;</span>);
</span><span id="402" class="l"><a class="l" href="#402">402: </a>            } <span class="php-keyword1">else</span> {
</span><span id="403" class="l"><a class="l" href="#403">403: </a>                <span class="php-keyword1">unset</span>(<span class="php-var">$sql_parts</span>[<span class="php-var">$key</span>]);
</span><span id="404" class="l"><a class="l" href="#404">404: </a>            }
</span><span id="405" class="l"><a class="l" href="#405">405: </a>        }
</span><span id="406" class="l"><a class="l" href="#406">406: </a>
</span><span id="407" class="l"><a class="l" href="#407">407: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">join</span>(<span class="php-quote">' '</span>, <span class="php-var">$sql_parts</span>);
</span><span id="408" class="l"><a class="l" href="#408">408: </a>    }
</span><span id="409" class="l"><a class="l" href="#409">409: </a>
</span><span id="410" class="l"><a class="l" href="#410">410: </a>    <span class="php-comment">/**
</span></span><span id="411" class="l"><a class="l" href="#411">411: </a><span class="php-comment">     * Split select query.
</span></span><span id="412" class="l"><a class="l" href="#412">412: </a><span class="php-comment">     * NOTE: Splitting a query with a subquery is considerably slower.
</span></span><span id="413" class="l"><a class="l" href="#413">413: </a><span class="php-comment">     *
</span></span><span id="414" class="l"><a class="l" href="#414">414: </a><span class="php-comment">     * @param string $sql  SQL SELECT query statement
</span></span><span id="415" class="l"><a class="l" href="#415">415: </a><span class="php-comment">     * @return array
</span></span><span id="416" class="l"><a class="l" href="#416">416: </a><span class="php-comment">     */</span>
</span><span id="417" class="l"><a class="l" href="#417">417: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitSelectQuery" href="#_splitSelectQuery">splitSelectQuery</a>(<span class="php-var">$sql</span>)
</span><span id="418" class="l"><a class="l" href="#418">418: </a>    {
</span><span id="419" class="l"><a class="l" href="#419">419: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\(\s*SELECT\b/i'</span>, <span class="php-var">$sql</span>)) {
</span><span id="420" class="l"><a class="l" href="#420">420: </a>            <span class="php-var">$sets</span> = self::extractSubsets(<span class="php-var">$sql</span>);
</span><span id="421" class="l"><a class="l" href="#421">421: </a>            <span class="php-var">$sql</span> = <span class="php-var">$sets</span>[<span class="php-num">0</span>];
</span><span id="422" class="l"><a class="l" href="#422">422: </a>        }
</span><span id="423" class="l"><a class="l" href="#423">423: </a>
</span><span id="424" class="l"><a class="l" href="#424">424: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="425" class="l"><a class="l" href="#425">425: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="426" class="l"><a class="l" href="#426">426: </a>                        <span class="php-quote">'SELECT\b((?:\s+(?:ALL|DISTINCT|DISTINCTROW|HIGH_PRIORITY|STRAIGHT_JOIN|SQL_SMALL_RESULT|SQL_BIG_RESULT|SQL_BUFFER_RESULT|SQL_CACHE|SQL_NO_CACHE|SQL_CALC_FOUND_ROWS)\b)*)\s*('</span> . self::REGEX_VALUES . <span class="php-quote">')'</span> .
</span><span id="427" class="l"><a class="l" href="#427">427: </a>                        <span class="php-quote">'(?:'</span> .
</span><span id="428" class="l"><a class="l" href="#428">428: </a>                        <span class="php-quote">'(?:\bFROM\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="429" class="l"><a class="l" href="#429">429: </a>                        <span class="php-quote">'(?:\bWHERE\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="430" class="l"><a class="l" href="#430">430: </a>                        <span class="php-quote">'(?:\bGROUP\s+BY\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="431" class="l"><a class="l" href="#431">431: </a>                        <span class="php-quote">'(?:\bHAVING\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="432" class="l"><a class="l" href="#432">432: </a>                        <span class="php-quote">'(?:\bORDER\s+BY\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="433" class="l"><a class="l" href="#433">433: </a>                        <span class="php-quote">'(?:\bLIMIT\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="434" class="l"><a class="l" href="#434">434: </a>                        <span class="php-quote">'(\b(?:PROCEDURE|INTO|FOR\s+UPDATE|LOCK\s+IN\s+SHARE\s*MODE|CASCADE\s*ON)\b.*?)?'</span> .
</span><span id="435" class="l"><a class="l" href="#435">435: </a>                        <span class="php-quote">')?'</span> .
</span><span id="436" class="l"><a class="l" href="#436">436: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="437" class="l"><a class="l" href="#437">437: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">'Unable to split SELECT query, invalid syntax:\n'</span> . <span class="php-var">$sql</span>);
</span><span id="438" class="l"><a class="l" href="#438">438: </a>        }
</span><span id="439" class="l"><a class="l" href="#439">439: </a>
</span><span id="440" class="l"><a class="l" href="#440">440: </a>
</span><span id="441" class="l"><a class="l" href="#441">441: </a>        <span class="php-keyword2">array_shift</span>(<span class="php-var">$parts</span>);
</span><span id="442" class="l"><a class="l" href="#442">442: </a>        <span class="php-var">$parts</span> = <span class="php-keyword2">array_combine</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'select'</span>, <span class="php-quote">'columns'</span>, <span class="php-quote">'from'</span>, <span class="php-quote">'where'</span>, <span class="php-quote">'group by'</span>, <span class="php-quote">'having'</span>, <span class="php-quote">'order by'</span>, <span class="php-quote">'limit'</span>, <span class="php-quote">'options'</span>), <span class="php-var">$parts</span> + <span class="php-keyword2">array_fill</span>(<span class="php-num">0</span>, <span class="php-num">9</span>, <span class="php-quote">''</span>));
</span><span id="443" class="l"><a class="l" href="#443">443: </a>
</span><span id="444" class="l"><a class="l" href="#444">444: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$sets</span>) &amp;&amp; <span class="php-keyword2">count</span>(<span class="php-var">$sets</span>) &gt; <span class="php-num">1</span>) {
</span><span id="445" class="l"><a class="l" href="#445">445: </a>            <span class="php-var">$sets</span>[<span class="php-num">0</span>] = &amp; <span class="php-var">$parts</span>;
</span><span id="446" class="l"><a class="l" href="#446">446: </a>            <span class="php-var">$parts</span> = self::injectSubsets(<span class="php-var">$sets</span>);
</span><span id="447" class="l"><a class="l" href="#447">447: </a>        }
</span><span id="448" class="l"><a class="l" href="#448">448: </a>
</span><span id="449" class="l"><a class="l" href="#449">449: </a>        <span class="php-keyword1">return</span> <span class="php-var">$parts</span>;
</span><span id="450" class="l"><a class="l" href="#450">450: </a>    }
</span><span id="451" class="l"><a class="l" href="#451">451: </a>
</span><span id="452" class="l"><a class="l" href="#452">452: </a>    <span class="php-comment">/**
</span></span><span id="453" class="l"><a class="l" href="#453">453: </a><span class="php-comment">     * Split insert/replace query.
</span></span><span id="454" class="l"><a class="l" href="#454">454: </a><span class="php-comment">     *
</span></span><span id="455" class="l"><a class="l" href="#455">455: </a><span class="php-comment">     * @param string $sql  SQL INSERT query statement
</span></span><span id="456" class="l"><a class="l" href="#456">456: </a><span class="php-comment">     * @return array
</span></span><span id="457" class="l"><a class="l" href="#457">457: </a><span class="php-comment">     */</span>
</span><span id="458" class="l"><a class="l" href="#458">458: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitInsertQuery" href="#_splitInsertQuery">splitInsertQuery</a>(<span class="php-var">$sql</span>)
</span><span id="459" class="l"><a class="l" href="#459">459: </a>    {
</span><span id="460" class="l"><a class="l" href="#460">460: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="461" class="l"><a class="l" href="#461">461: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="462" class="l"><a class="l" href="#462">462: </a>                        <span class="php-quote">'(INSERT|REPLACE)\b((?:\s+(?:LOW_PRIORITY|DELAYED|HIGH_PRIORITY|IGNORE)\b)*)\s*'</span> .
</span><span id="463" class="l"><a class="l" href="#463">463: </a>                        <span class="php-quote">'(?:\bINTO\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="464" class="l"><a class="l" href="#464">464: </a>                        <span class="php-quote">'(?:\((\s*'</span> . self::REGEX_VALUES . <span class="php-quote">')\)\s*)?'</span> .
</span><span id="465" class="l"><a class="l" href="#465">465: </a>                        <span class="php-quote">'(?:\bSET\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="466" class="l"><a class="l" href="#466">466: </a>                        <span class="php-quote">'(?:\bVALUES\s*(\(\s*'</span> . self::REGEX_VALUES . <span class="php-quote">'\)\s*(?:,\s*\('</span> . self::REGEX_VALUES . <span class="php-quote">'\)\s*)*))?'</span> .
</span><span id="467" class="l"><a class="l" href="#467">467: </a>                        <span class="php-quote">'(\bSELECT\b\s*'</span> . self::REGEX_VALUES . <span class="php-quote">'|\#sub\d+\s*)?'</span> .
</span><span id="468" class="l"><a class="l" href="#468">468: </a>                        <span class="php-quote">'(?:\bON\s+DUPLICATE\s+KEY\s+UPDATE\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="469" class="l"><a class="l" href="#469">469: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="470" class="l"><a class="l" href="#470">470: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split INSERT/REPLACE query, invalid syntax:\n&quot;</span> . <span class="php-var">$sql</span>);
</span><span id="471" class="l"><a class="l" href="#471">471: </a>        }
</span><span id="472" class="l"><a class="l" href="#472">472: </a>
</span><span id="473" class="l"><a class="l" href="#473">473: </a>        <span class="php-var">$keys</span> = <span class="php-keyword1">array</span>(<span class="php-keyword2">strtolower</span>(<span class="php-var">$parts</span>[<span class="php-num">1</span>]), <span class="php-quote">'into'</span>, <span class="php-quote">'columns'</span>, <span class="php-quote">'set'</span>, <span class="php-quote">'values'</span>, <span class="php-quote">'query'</span>, <span class="php-quote">'on duplicate key update'</span>);
</span><span id="474" class="l"><a class="l" href="#474">474: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">array_combine</span>(<span class="php-var">$keys</span>, <span class="php-keyword2">array_splice</span>(<span class="php-var">$parts</span>, <span class="php-num">2</span>) + <span class="php-keyword2">array_fill</span>(<span class="php-num">0</span>, <span class="php-num">7</span>, <span class="php-quote">''</span>));
</span><span id="475" class="l"><a class="l" href="#475">475: </a>    }
</span><span id="476" class="l"><a class="l" href="#476">476: </a>
</span><span id="477" class="l"><a class="l" href="#477">477: </a>    <span class="php-comment">/**
</span></span><span id="478" class="l"><a class="l" href="#478">478: </a><span class="php-comment">     * Split update query
</span></span><span id="479" class="l"><a class="l" href="#479">479: </a><span class="php-comment">     *
</span></span><span id="480" class="l"><a class="l" href="#480">480: </a><span class="php-comment">     * @param string $sql  SQL UPDATE query statement
</span></span><span id="481" class="l"><a class="l" href="#481">481: </a><span class="php-comment">     * @return array
</span></span><span id="482" class="l"><a class="l" href="#482">482: </a><span class="php-comment">     */</span>
</span><span id="483" class="l"><a class="l" href="#483">483: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitUpdateQuery" href="#_splitUpdateQuery">splitUpdateQuery</a>(<span class="php-var">$sql</span>)
</span><span id="484" class="l"><a class="l" href="#484">484: </a>    {
</span><span id="485" class="l"><a class="l" href="#485">485: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\(\s*SELECT\b/i'</span>, <span class="php-var">$sql</span>)) {
</span><span id="486" class="l"><a class="l" href="#486">486: </a>            <span class="php-var">$sets</span> = self::extractSubsets(<span class="php-var">$sql</span>);
</span><span id="487" class="l"><a class="l" href="#487">487: </a>            <span class="php-var">$sql</span> = <span class="php-var">$sets</span>[<span class="php-num">0</span>];
</span><span id="488" class="l"><a class="l" href="#488">488: </a>        }
</span><span id="489" class="l"><a class="l" href="#489">489: </a>
</span><span id="490" class="l"><a class="l" href="#490">490: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="491" class="l"><a class="l" href="#491">491: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="492" class="l"><a class="l" href="#492">492: </a>                        <span class="php-quote">'UPDATE\b((?:\s+(?:LOW_PRIORITY|DELAYED|HIGH_PRIORITY|IGNORE)\b)*)\s*'</span> .
</span><span id="493" class="l"><a class="l" href="#493">493: </a>                        <span class="php-quote">'('</span> . self::REGEX_VALUES . <span class="php-quote">')?'</span> .
</span><span id="494" class="l"><a class="l" href="#494">494: </a>                        <span class="php-quote">'(?:\bSET\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="495" class="l"><a class="l" href="#495">495: </a>                        <span class="php-quote">'(?:\bWHERE\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="496" class="l"><a class="l" href="#496">496: </a>                        <span class="php-quote">'(?:\bLIMIT\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="497" class="l"><a class="l" href="#497">497: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="498" class="l"><a class="l" href="#498">498: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split UPDATE query, invalid syntax:\n&quot;</span> . <span class="php-var">$sql</span>);
</span><span id="499" class="l"><a class="l" href="#499">499: </a>        }
</span><span id="500" class="l"><a class="l" href="#500">500: </a>
</span><span id="501" class="l"><a class="l" href="#501">501: </a>        <span class="php-keyword2">array_shift</span>(<span class="php-var">$parts</span>);
</span><span id="502" class="l"><a class="l" href="#502">502: </a>        <span class="php-var">$parts</span> = <span class="php-keyword2">array_combine</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'update'</span>, <span class="php-quote">'table'</span>, <span class="php-quote">'set'</span>, <span class="php-quote">'where'</span>, <span class="php-quote">'limit'</span>), <span class="php-var">$parts</span> + <span class="php-keyword2">array_fill</span>(<span class="php-num">0</span>, <span class="php-num">5</span>, <span class="php-quote">''</span>));
</span><span id="503" class="l"><a class="l" href="#503">503: </a>
</span><span id="504" class="l"><a class="l" href="#504">504: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$sets</span>) &amp;&amp; <span class="php-keyword2">count</span>(<span class="php-var">$sets</span>) &gt; <span class="php-num">1</span>) {
</span><span id="505" class="l"><a class="l" href="#505">505: </a>            <span class="php-var">$sets</span>[<span class="php-num">0</span>] = &amp; <span class="php-var">$parts</span>;
</span><span id="506" class="l"><a class="l" href="#506">506: </a>            <span class="php-var">$parts</span> = self::injectSubsets(<span class="php-var">$sets</span>);
</span><span id="507" class="l"><a class="l" href="#507">507: </a>        }
</span><span id="508" class="l"><a class="l" href="#508">508: </a>
</span><span id="509" class="l"><a class="l" href="#509">509: </a>        <span class="php-keyword1">return</span> <span class="php-var">$parts</span>;
</span><span id="510" class="l"><a class="l" href="#510">510: </a>    }
</span><span id="511" class="l"><a class="l" href="#511">511: </a>
</span><span id="512" class="l"><a class="l" href="#512">512: </a>    <span class="php-comment">/**
</span></span><span id="513" class="l"><a class="l" href="#513">513: </a><span class="php-comment">     * Split delete query.
</span></span><span id="514" class="l"><a class="l" href="#514">514: </a><span class="php-comment">     *
</span></span><span id="515" class="l"><a class="l" href="#515">515: </a><span class="php-comment">     * @param string $sql  SQL DELETE query statement
</span></span><span id="516" class="l"><a class="l" href="#516">516: </a><span class="php-comment">     * @return array
</span></span><span id="517" class="l"><a class="l" href="#517">517: </a><span class="php-comment">     */</span>
</span><span id="518" class="l"><a class="l" href="#518">518: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitDeleteQuery" href="#_splitDeleteQuery">splitDeleteQuery</a>(<span class="php-var">$sql</span>)
</span><span id="519" class="l"><a class="l" href="#519">519: </a>    {
</span><span id="520" class="l"><a class="l" href="#520">520: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\(\s*SELECT\b/i'</span>, <span class="php-var">$sql</span>)) {
</span><span id="521" class="l"><a class="l" href="#521">521: </a>            <span class="php-var">$sets</span> = self::extractSubsets(<span class="php-var">$sql</span>);
</span><span id="522" class="l"><a class="l" href="#522">522: </a>            <span class="php-var">$sql</span> = <span class="php-var">$sets</span>[<span class="php-num">0</span>];
</span><span id="523" class="l"><a class="l" href="#523">523: </a>        }
</span><span id="524" class="l"><a class="l" href="#524">524: </a>
</span><span id="525" class="l"><a class="l" href="#525">525: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="526" class="l"><a class="l" href="#526">526: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="527" class="l"><a class="l" href="#527">527: </a>                        <span class="php-quote">'DELETE\b((?:\s+(?:LOW_PRIORITY|QUICK|IGNORE)\b)*)\s*'</span> .
</span><span id="528" class="l"><a class="l" href="#528">528: </a>                        <span class="php-quote">'('</span> . self::REGEX_VALUES . <span class="php-quote">')?'</span> .
</span><span id="529" class="l"><a class="l" href="#529">529: </a>                        <span class="php-quote">'(?:\bFROM\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="530" class="l"><a class="l" href="#530">530: </a>                        <span class="php-quote">'(?:\bWHERE\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="531" class="l"><a class="l" href="#531">531: </a>                        <span class="php-quote">'(?:\bORDER\s+BY\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="532" class="l"><a class="l" href="#532">532: </a>                        <span class="php-quote">'(?:\bLIMIT\b\s*('</span> . self::REGEX_VALUES . <span class="php-quote">'))?'</span> .
</span><span id="533" class="l"><a class="l" href="#533">533: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="534" class="l"><a class="l" href="#534">534: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split DELETE query, invalid syntax:\n&quot;</span> . <span class="php-var">$sql</span>);
</span><span id="535" class="l"><a class="l" href="#535">535: </a>        }
</span><span id="536" class="l"><a class="l" href="#536">536: </a>
</span><span id="537" class="l"><a class="l" href="#537">537: </a>        <span class="php-keyword2">array_shift</span>(<span class="php-var">$parts</span>);
</span><span id="538" class="l"><a class="l" href="#538">538: </a>        <span class="php-var">$parts</span> = <span class="php-keyword2">array_combine</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'delete'</span>, <span class="php-quote">'columns'</span>, <span class="php-quote">'from'</span>, <span class="php-quote">'where'</span>, <span class="php-quote">'order by'</span>, <span class="php-quote">'limit'</span>), <span class="php-var">$parts</span> + <span class="php-keyword2">array_fill</span>(<span class="php-num">0</span>, <span class="php-num">6</span>, <span class="php-quote">''</span>));
</span><span id="539" class="l"><a class="l" href="#539">539: </a>
</span><span id="540" class="l"><a class="l" href="#540">540: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$sets</span>) &amp;&amp; <span class="php-keyword2">count</span>(<span class="php-var">$sets</span>) &gt; <span class="php-num">1</span>) {
</span><span id="541" class="l"><a class="l" href="#541">541: </a>            <span class="php-var">$sets</span>[<span class="php-num">0</span>] = &amp; <span class="php-var">$parts</span>;
</span><span id="542" class="l"><a class="l" href="#542">542: </a>            <span class="php-var">$parts</span> = self::injectSubsets(<span class="php-var">$sets</span>);
</span><span id="543" class="l"><a class="l" href="#543">543: </a>        }
</span><span id="544" class="l"><a class="l" href="#544">544: </a>
</span><span id="545" class="l"><a class="l" href="#545">545: </a>        <span class="php-keyword1">return</span> <span class="php-var">$parts</span>;
</span><span id="546" class="l"><a class="l" href="#546">546: </a>    }
</span><span id="547" class="l"><a class="l" href="#547">547: </a>
</span><span id="548" class="l"><a class="l" href="#548">548: </a>    <span class="php-comment">/**
</span></span><span id="549" class="l"><a class="l" href="#549">549: </a><span class="php-comment">     * Split delete query
</span></span><span id="550" class="l"><a class="l" href="#550">550: </a><span class="php-comment">     *
</span></span><span id="551" class="l"><a class="l" href="#551">551: </a><span class="php-comment">     * @param string $sql  SQL DELETE query statement
</span></span><span id="552" class="l"><a class="l" href="#552">552: </a><span class="php-comment">     * @return array
</span></span><span id="553" class="l"><a class="l" href="#553">553: </a><span class="php-comment">     */</span>
</span><span id="554" class="l"><a class="l" href="#554">554: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitTruncateQuery" href="#_splitTruncateQuery">splitTruncateQuery</a>(<span class="php-var">$sql</span>)
</span><span id="555" class="l"><a class="l" href="#555">555: </a>    {
</span><span id="556" class="l"><a class="l" href="#556">556: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="557" class="l"><a class="l" href="#557">557: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="558" class="l"><a class="l" href="#558">558: </a>                        <span class="php-quote">'TRUNCATE\b(\s+TABLE\b)?\s*'</span> .
</span><span id="559" class="l"><a class="l" href="#559">559: </a>                        <span class="php-quote">'('</span> . self::REGEX_VALUES . <span class="php-quote">')?'</span> .
</span><span id="560" class="l"><a class="l" href="#560">560: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="561" class="l"><a class="l" href="#561">561: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split TRUNCATE query, invalid syntax: </span><span class="php-var">$sql</span><span class="php-quote">&quot;</span>);
</span><span id="562" class="l"><a class="l" href="#562">562: </a>        }
</span><span id="563" class="l"><a class="l" href="#563">563: </a>
</span><span id="564" class="l"><a class="l" href="#564">564: </a>        <span class="php-keyword2">array_shift</span>(<span class="php-var">$parts</span>);
</span><span id="565" class="l"><a class="l" href="#565">565: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">array_combine</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'truncate'</span>, <span class="php-quote">'table'</span>), <span class="php-var">$parts</span>);
</span><span id="566" class="l"><a class="l" href="#566">566: </a>    }
</span><span id="567" class="l"><a class="l" href="#567">567: </a>
</span><span id="568" class="l"><a class="l" href="#568">568: </a>    <span class="php-comment">/**
</span></span><span id="569" class="l"><a class="l" href="#569">569: </a><span class="php-comment">     * Split set query
</span></span><span id="570" class="l"><a class="l" href="#570">570: </a><span class="php-comment">     *
</span></span><span id="571" class="l"><a class="l" href="#571">571: </a><span class="php-comment">     * @param string $sql  SQL SET query statement
</span></span><span id="572" class="l"><a class="l" href="#572">572: </a><span class="php-comment">     * @return array
</span></span><span id="573" class="l"><a class="l" href="#573">573: </a><span class="php-comment">     */</span>
</span><span id="574" class="l"><a class="l" href="#574">574: </a>    <span class="php-keyword1">protected</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitSetQuery" href="#_splitSetQuery">splitSetQuery</a>(<span class="php-var">$sql</span>)
</span><span id="575" class="l"><a class="l" href="#575">575: </a>    {
</span><span id="576" class="l"><a class="l" href="#576">576: </a>        <span class="php-var">$parts</span> = <span class="php-keyword1">null</span>;
</span><span id="577" class="l"><a class="l" href="#577">577: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*'</span> .
</span><span id="578" class="l"><a class="l" href="#578">578: </a>                        <span class="php-quote">'SET\b\s*'</span> .
</span><span id="579" class="l"><a class="l" href="#579">579: </a>                        <span class="php-quote">'('</span> . self::REGEX_VALUES . <span class="php-quote">')?'</span> .
</span><span id="580" class="l"><a class="l" href="#580">580: </a>                        <span class="php-quote">'(?:;|$)/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$parts</span>)) {
</span><span id="581" class="l"><a class="l" href="#581">581: </a>            <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to split SET query, invalid syntax: </span><span class="php-var">$sql</span><span class="php-quote">&quot;</span>);
</span><span id="582" class="l"><a class="l" href="#582">582: </a>        }
</span><span id="583" class="l"><a class="l" href="#583">583: </a>
</span><span id="584" class="l"><a class="l" href="#584">584: </a>        <span class="php-keyword2">array_shift</span>(<span class="php-var">$parts</span>);
</span><span id="585" class="l"><a class="l" href="#585">585: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">array_combine</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'set'</span>), <span class="php-var">$parts</span>);
</span><span id="586" class="l"><a class="l" href="#586">586: </a>    }
</span><span id="587" class="l"><a class="l" href="#587">587: </a>
</span><span id="588" class="l"><a class="l" href="#588">588: </a>    <span class="php-comment">//------------- Split a part --------------------</span>
</span><span id="589" class="l"><a class="l" href="#589">589: </a>
</span><span id="590" class="l"><a class="l" href="#590">590: </a>    <span class="php-comment">/**
</span></span><span id="591" class="l"><a class="l" href="#591">591: </a><span class="php-comment">     * Return the columns of a (partual) query statement.
</span></span><span id="592" class="l"><a class="l" href="#592">592: </a><span class="php-comment">     * 
</span></span><span id="593" class="l"><a class="l" href="#593">593: </a><span class="php-comment">     * @param string $sql    SQL query or 'column, column, ...'
</span></span><span id="594" class="l"><a class="l" href="#594">594: </a><span class="php-comment">     * @param int    $flags  DBQuery::SPLIT_% option
</span></span><span id="595" class="l"><a class="l" href="#595">595: </a><span class="php-comment">     * @return array
</span></span><span id="596" class="l"><a class="l" href="#596">596: </a><span class="php-comment">     */</span>
</span><span id="597" class="l"><a class="l" href="#597">597: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitColumns" href="#_splitColumns">splitColumns</a>(<span class="php-var">$sql</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="598" class="l"><a class="l" href="#598">598: </a>    {
</span><span id="599" class="l"><a class="l" href="#599">599: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) || self::getQueryType(<span class="php-var">$sql</span>)) {
</span><span id="600" class="l"><a class="l" href="#600">600: </a>            <span class="php-var">$parts</span> = <span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) ? <span class="php-var">$sql</span> : self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="601" class="l"><a class="l" href="#601">601: </a>            <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'columns'</span>])) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;It's not possible to extract columns of a &quot;</span> . self::getQueryType(<span class="php-var">$sql</span>) . <span class="php-quote">&quot; query.&quot;</span>);
</span><span id="602" class="l"><a class="l" href="#602">602: </a>
</span><span id="603" class="l"><a class="l" href="#603">603: </a>            <span class="php-var">$sql</span> = <span class="php-keyword2">preg_replace</span>(<span class="php-quote">'/^\(|\)$/'</span>, <span class="php-quote">''</span>, <span class="php-var">$parts</span>[<span class="php-quote">'columns'</span>]);
</span><span id="604" class="l"><a class="l" href="#604">604: </a>        }
</span><span id="605" class="l"><a class="l" href="#605">605: </a>
</span><span id="606" class="l"><a class="l" href="#606">606: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match_all</span>(<span class="php-quote">'/(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*+&quot;|\'(?:[^\'\\\\]++|\\\\.)*+\'|\((?:[^()]++|(?R))*\)|[^`&quot;\'(),]++)++/'</span>, <span class="php-var">$sql</span>, <span class="php-var">$match</span>, PREG_PATTERN_ORDER)) {
</span><span id="607" class="l"><a class="l" href="#607">607: </a>            <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>();
</span><span id="608" class="l"><a class="l" href="#608">608: </a>        }
</span><span id="609" class="l"><a class="l" href="#609">609: </a>
</span><span id="610" class="l"><a class="l" href="#610">610: </a>        <span class="php-var">$columns</span> = &amp; <span class="php-var">$match</span>[<span class="php-num">0</span>];
</span><span id="611" class="l"><a class="l" href="#611">611: </a>
</span><span id="612" class="l"><a class="l" href="#612">612: </a>        <span class="php-keyword1">foreach</span> (<span class="php-var">$columns</span> <span class="php-keyword1">as</span> <span class="php-var">$key</span> =&gt; &amp;<span class="php-var">$column</span>) {
</span><span id="613" class="l"><a class="l" href="#613">613: </a>            <span class="php-var">$column</span> = <span class="php-keyword2">trim</span>(<span class="php-var">$column</span>);
</span><span id="614" class="l"><a class="l" href="#614">614: </a>            <span class="php-keyword1">if</span> (<span class="php-var">$column</span> === <span class="php-quote">''</span>) <span class="php-keyword1">unset</span>(<span class="php-var">$columns</span>[<span class="php-var">$key</span>]);
</span><span id="615" class="l"><a class="l" href="#615">615: </a>        }
</span><span id="616" class="l"><a class="l" href="#616">616: </a>
</span><span id="617" class="l"><a class="l" href="#617">617: </a>        <span class="php-keyword1">return</span> <span class="php-keyword2">array_values</span>(<span class="php-var">$columns</span>);
</span><span id="618" class="l"><a class="l" href="#618">618: </a>    }
</span><span id="619" class="l"><a class="l" href="#619">619: </a>
</span><span id="620" class="l"><a class="l" href="#620">620: </a>    <span class="php-comment">/**
</span></span><span id="621" class="l"><a class="l" href="#621">621: </a><span class="php-comment">     * Return the columns of a (partual) query statement.
</span></span><span id="622" class="l"><a class="l" href="#622">622: </a><span class="php-comment">     * 
</span></span><span id="623" class="l"><a class="l" href="#623">623: </a><span class="php-comment">     * @param string $sql    SQL query or 'column, column, ...'
</span></span><span id="624" class="l"><a class="l" href="#624">624: </a><span class="php-comment">     * @param int    $flags  DBQuery::SPLIT_% option
</span></span><span id="625" class="l"><a class="l" href="#625">625: </a><span class="php-comment">     * @return array
</span></span><span id="626" class="l"><a class="l" href="#626">626: </a><span class="php-comment">     */</span>
</span><span id="627" class="l"><a class="l" href="#627">627: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitSet" href="#_splitSet">splitSet</a>(<span class="php-var">$sql</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="628" class="l"><a class="l" href="#628">628: </a>    {
</span><span id="629" class="l"><a class="l" href="#629">629: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) || self::getQueryType(<span class="php-var">$sql</span>)) {
</span><span id="630" class="l"><a class="l" href="#630">630: </a>            <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="631" class="l"><a class="l" href="#631">631: </a>            <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'set'</span>])) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;It's not possible to extract the set part of a </span><span class="php-var">$type</span><span class="php-quote"> query. </span><span class="php-var">$sql</span><span class="php-quote">&quot;</span>);
</span><span id="632" class="l"><a class="l" href="#632">632: </a>
</span><span id="633" class="l"><a class="l" href="#633">633: </a>            <span class="php-var">$sql</span> = &amp; <span class="php-var">$parts</span>[<span class="php-quote">'set'</span>];
</span><span id="634" class="l"><a class="l" href="#634">634: </a>            <span class="php-keyword1">unset</span>(<span class="php-var">$parts</span>);
</span><span id="635" class="l"><a class="l" href="#635">635: </a>        }
</span><span id="636" class="l"><a class="l" href="#636">636: </a>
</span><span id="637" class="l"><a class="l" href="#637">637: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match_all</span>(<span class="php-quote">'/\s*(?:((?:(?:`[^`]*+`|\w++)\.)*(?:`[^`]*+`|\w++)|@+\w++)\s*+=\s*+)?'</span> .
</span><span id="638" class="l"><a class="l" href="#638">638: </a>                        <span class="php-quote">'('</span> .
</span><span id="639" class="l"><a class="l" href="#639">639: </a>                        <span class="php-quote">'(?:(?:(?:`[^`]*+`|\w++)\.)*(?:`[^`]*+`|\w++)\.)?(?:`[^`]*+`|\w++)\s*+|'</span> .
</span><span id="640" class="l"><a class="l" href="#640">640: </a>                        <span class="php-quote">'(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*&quot;|\'(?:[^\'\\\\]|\\\\.)*\'|\((?:[^()]++|(?R))*\)|\s++|\w++|[^`&quot;\'\w\s(),])+'</span> .
</span><span id="641" class="l"><a class="l" href="#641">641: </a>                        <span class="php-quote">')(?=,|$|\))'</span> .
</span><span id="642" class="l"><a class="l" href="#642">642: </a>                        <span class="php-quote">'/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>, PREG_SET_ORDER)) {
</span><span id="643" class="l"><a class="l" href="#643">643: </a>            <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>();
</span><span id="644" class="l"><a class="l" href="#644">644: </a>        }
</span><span id="645" class="l"><a class="l" href="#645">645: </a>
</span><span id="646" class="l"><a class="l" href="#646">646: </a>        <span class="php-var">$set</span> = <span class="php-keyword1">array</span>();
</span><span id="647" class="l"><a class="l" href="#647">647: </a>        <span class="php-keyword1">foreach</span> (<span class="php-var">$matches</span> <span class="php-keyword1">as</span> &amp;<span class="php-var">$match</span>) {
</span><span id="648" class="l"><a class="l" href="#648">648: </a>            <span class="php-var">$set</span>[<span class="php-keyword2">trim</span>(<span class="php-var">$match</span>[<span class="php-num">1</span>])] = <span class="php-keyword2">trim</span>(<span class="php-var">$match</span>[<span class="php-num">2</span>]);
</span><span id="649" class="l"><a class="l" href="#649">649: </a>        }
</span><span id="650" class="l"><a class="l" href="#650">650: </a>
</span><span id="651" class="l"><a class="l" href="#651">651: </a>        <span class="php-keyword1">return</span> <span class="php-var">$set</span>;
</span><span id="652" class="l"><a class="l" href="#652">652: </a>    }
</span><span id="653" class="l"><a class="l" href="#653">653: </a>
</span><span id="654" class="l"><a class="l" href="#654">654: </a>    <span class="php-comment">/**
</span></span><span id="655" class="l"><a class="l" href="#655">655: </a><span class="php-comment">     * Return the table names of a (partual) query statement.
</span></span><span id="656" class="l"><a class="l" href="#656">656: </a><span class="php-comment">     * 
</span></span><span id="657" class="l"><a class="l" href="#657">657: </a><span class="php-comment">     * @param string $sql    SQL query or FROM part
</span></span><span id="658" class="l"><a class="l" href="#658">658: </a><span class="php-comment">     * @return array  array(alias/name =&gt; table)
</span></span><span id="659" class="l"><a class="l" href="#659">659: </a><span class="php-comment">     */</span>
</span><span id="660" class="l"><a class="l" href="#660">660: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitTables" href="#_splitTables">splitTables</a>(<span class="php-var">$sql</span>)
</span><span id="661" class="l"><a class="l" href="#661">661: </a>    {
</span><span id="662" class="l"><a class="l" href="#662">662: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) || self::getQueryType(<span class="php-var">$sql</span>)) {
</span><span id="663" class="l"><a class="l" href="#663">663: </a>            <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="664" class="l"><a class="l" href="#664">664: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword2">array_key_exists</span>(<span class="php-quote">'from'</span>, <span class="php-var">$parts</span>)) <span class="php-var">$sql</span> = &amp; <span class="php-var">$parts</span>[<span class="php-quote">'from'</span>];
</span><span id="665" class="l"><a class="l" href="#665">665: </a>            <span class="php-keyword1">elseif</span> (<span class="php-keyword2">array_key_exists</span>(<span class="php-quote">'table'</span>, <span class="php-var">$parts</span>)) <span class="php-var">$sql</span> = &amp; <span class="php-var">$parts</span>[<span class="php-quote">'table'</span>];
</span><span id="666" class="l"><a class="l" href="#666">666: </a>            <span class="php-keyword1">elseif</span> (<span class="php-keyword2">array_key_exists</span>(<span class="php-quote">'into'</span>, <span class="php-var">$parts</span>)) <span class="php-var">$sql</span> = &amp; <span class="php-var">$parts</span>[<span class="php-quote">'into'</span>];
</span><span id="667" class="l"><a class="l" href="#667">667: </a>            <span class="php-keyword1">else</span> <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;It's not possible to extract tables of a &quot;</span> . self::getQueryType(<span class="php-var">$sql</span>) . <span class="php-quote">&quot; query.&quot;</span>);
</span><span id="668" class="l"><a class="l" href="#668">668: </a>        }
</span><span id="669" class="l"><a class="l" href="#669">669: </a>
</span><span id="670" class="l"><a class="l" href="#670">670: </a>        <span class="php-var">$matches</span> = <span class="php-keyword1">null</span>;
</span><span id="671" class="l"><a class="l" href="#671">671: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword2">preg_match_all</span>(<span class="php-quote">'/(?:,\s*|(?:(?:NATURAL\s+)?(?:(?:LEFT|RIGHT)\s+)?(?:(?:INNER|CROSS|OUTER)\s+)?(?:STRAIGHT_)?JOIN\s*+))?+'</span> .
</span><span id="672" class="l"><a class="l" href="#672">672: </a>                        <span class="php-quote">'(?P&lt;table&gt;(?P&lt;fullname&gt;\((?:[^()]++|(?R))*\)\s*+|(?:(?P&lt;db&gt;`[^`]++`|\w++)\.)?(?P&lt;name&gt;`[^`]++`|\b\w++)\s*+)(?:(?P&lt;alias&gt;\bAS\s*+(?:`[^`]++`|\b\w++)|`[^`]++`|\b\w++(?&lt;!\bON)(?&lt;!\bNATURAL)(?&lt;!\bLEFT)(?&lt;!\bRIGHT)(?&lt;!\bINNER)(?&lt;!\bCROSS)(?&lt;!\bOUTER)(?&lt;!\bSTRAIGHT_JOIN)(?&lt;!\bJOIN))\s*+)?)'</span> .
</span><span id="673" class="l"><a class="l" href="#673">673: </a>                        <span class="php-quote">'(?:ON\b\s*+(?P&lt;on&gt;(?:(?:`[^`]*+`|&quot;(?:[^&quot;\\\\]++|\\\\.)*&quot;|\'(?:[^\'\\\\]++|\\\\.)*\'|\s++|\w++(?&lt;!\bNATURAL)(?&lt;!\bLEFT)(?&lt;!\bRIGHT)(?&lt;!\bINNER)(?&lt;!\bCROSS)(?&lt;!\bOUTER)(?&lt;!\bSTRAIGHT_JOIN)(?&lt;!\bJOIN)|\((?:[^()]++|(?R))*\)|[^`&quot;\'\w\s\,()]))+))?'</span> .
</span><span id="674" class="l"><a class="l" href="#674">674: </a>                        <span class="php-quote">'/si'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>, PREG_SET_ORDER)) {
</span><span id="675" class="l"><a class="l" href="#675">675: </a>            <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>();
</span><span id="676" class="l"><a class="l" href="#676">676: </a>        }
</span><span id="677" class="l"><a class="l" href="#677">677: </a>
</span><span id="678" class="l"><a class="l" href="#678">678: </a>        <span class="php-var">$tables</span> = <span class="php-keyword1">array</span>();
</span><span id="679" class="l"><a class="l" href="#679">679: </a>
</span><span id="680" class="l"><a class="l" href="#680">680: </a>        <span class="php-keyword1">foreach</span> (<span class="php-var">$matches</span> <span class="php-keyword1">as</span> <span class="php-var">$i</span> =&gt; &amp;<span class="php-var">$match</span>) {
</span><span id="681" class="l"><a class="l" href="#681">681: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*\((.*)\)\s*$/'</span>, <span class="php-var">$match</span>[<span class="php-quote">'fullname'</span>], <span class="php-var">$m</span>) &amp;&amp; !<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*\(\s*SELECT\b/i'</span>, <span class="php-var">$match</span>[<span class="php-quote">'fullname'</span>])) {
</span><span id="682" class="l"><a class="l" href="#682">682: </a>                <span class="php-var">$tables</span> = <span class="php-keyword2">array_merge</span>(<span class="php-var">$tables</span>, self::splitTables(<span class="php-var">$m</span>[<span class="php-num">1</span>]));
</span><span id="683" class="l"><a class="l" href="#683">683: </a>                <span class="php-keyword1">continue</span>;
</span><span id="684" class="l"><a class="l" href="#684">684: </a>            }
</span><span id="685" class="l"><a class="l" href="#685">685: </a>
</span><span id="686" class="l"><a class="l" href="#686">686: </a>            <span class="php-var">$key</span> = !<span class="php-keyword1">empty</span>(<span class="php-var">$match</span>[<span class="php-quote">'alias'</span>]) ? <span class="php-keyword2">preg_replace</span>(<span class="php-quote">'/^(?:AS\s*)?(`?)(.*?)\1\s*$/i'</span>, <span class="php-quote">'$2'</span>, <span class="php-var">$match</span>[<span class="php-quote">'alias'</span>]) : <span class="php-keyword2">trim</span>(<span class="php-var">$match</span>[<span class="php-quote">'name'</span>], <span class="php-quote">' `'</span>);
</span><span id="687" class="l"><a class="l" href="#687">687: </a>            <span class="php-var">$tables</span>[<span class="php-var">$key</span>] = <span class="php-keyword2">trim</span>(<span class="php-var">$match</span>[<span class="php-quote">'fullname'</span>]);
</span><span id="688" class="l"><a class="l" href="#688">688: </a>        }
</span><span id="689" class="l"><a class="l" href="#689">689: </a>
</span><span id="690" class="l"><a class="l" href="#690">690: </a>        <span class="php-keyword1">return</span> <span class="php-var">$tables</span>;
</span><span id="691" class="l"><a class="l" href="#691">691: </a>    }
</span><span id="692" class="l"><a class="l" href="#692">692: </a>
</span><span id="693" class="l"><a class="l" href="#693">693: </a>    <span class="php-comment">/**
</span></span><span id="694" class="l"><a class="l" href="#694">694: </a><span class="php-comment">     * Split limit in array(limit, offset)
</span></span><span id="695" class="l"><a class="l" href="#695">695: </a><span class="php-comment">     *
</span></span><span id="696" class="l"><a class="l" href="#696">696: </a><span class="php-comment">     * @param string $sql    SQL query or limit part
</span></span><span id="697" class="l"><a class="l" href="#697">697: </a><span class="php-comment">     * @param int    $flags
</span></span><span id="698" class="l"><a class="l" href="#698">698: </a><span class="php-comment">     * @return array
</span></span><span id="699" class="l"><a class="l" href="#699">699: </a><span class="php-comment">     */</span>
</span><span id="700" class="l"><a class="l" href="#700">700: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_splitLimit" href="#_splitLimit">splitLimit</a>(<span class="php-var">$sql</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="701" class="l"><a class="l" href="#701">701: </a>    {
</span><span id="702" class="l"><a class="l" href="#702">702: </a>        <span class="php-var">$type</span> = self::getQueryType(<span class="php-var">$sql</span>);
</span><span id="703" class="l"><a class="l" href="#703">703: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$type</span>)) {
</span><span id="704" class="l"><a class="l" href="#704">704: </a>            <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="705" class="l"><a class="l" href="#705">705: </a>            <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>])) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;A </span><span class="php-var">$type</span><span class="php-quote"> query doesn't have a LIMIT part.&quot;</span>);
</span><span id="706" class="l"><a class="l" href="#706">706: </a>            <span class="php-var">$sql</span> = &amp; <span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>];
</span><span id="707" class="l"><a class="l" href="#707">707: </a>        }
</span><span id="708" class="l"><a class="l" href="#708">708: </a>
</span><span id="709" class="l"><a class="l" href="#709">709: </a>        <span class="php-var">$matches</span> = <span class="php-keyword1">null</span>;
</span><span id="710" class="l"><a class="l" href="#710">710: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$sql</span> === <span class="php-keyword1">null</span> || <span class="php-var">$sql</span> === <span class="php-quote">''</span>) <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>(<span class="php-keyword1">null</span>, <span class="php-keyword1">null</span>);
</span><span id="711" class="l"><a class="l" href="#711">711: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">ctype_digit</span>(<span class="php-var">$sql</span>)) <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>(<span class="php-var">$sql</span>, <span class="php-keyword1">null</span>);
</span><span id="712" class="l"><a class="l" href="#712">712: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*(\d+)\s+OFFSET\s+(\d+)\s*$/'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>)) <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>(<span class="php-var">$matches</span>[<span class="php-num">1</span>], <span class="php-var">$matches</span>[<span class="php-num">2</span>]);
</span><span id="713" class="l"><a class="l" href="#713">713: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword2">preg_match</span>(<span class="php-quote">'/^\s*(\d+)\s*,\s*(\d+)\s*$/'</span>, <span class="php-var">$sql</span>, <span class="php-var">$matches</span>)) <span class="php-keyword1">return</span> <span class="php-keyword1">array</span>(<span class="php-var">$matches</span>[<span class="php-num">2</span>], <span class="php-var">$matches</span>[<span class="php-num">1</span>]);
</span><span id="714" class="l"><a class="l" href="#714">714: </a>
</span><span id="715" class="l"><a class="l" href="#715">715: </a>        <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Invalid limit statement '</span><span class="php-var">$sql</span><span class="php-quote">'&quot;</span>);
</span><span id="716" class="l"><a class="l" href="#716">716: </a>    }
</span><span id="717" class="l"><a class="l" href="#717">717: </a>
</span><span id="718" class="l"><a class="l" href="#718">718: </a>    <span class="php-comment">//------------- Convert statement --------------------</span>
</span><span id="719" class="l"><a class="l" href="#719">719: </a>
</span><span id="720" class="l"><a class="l" href="#720">720: </a>    <span class="php-comment">/**
</span></span><span id="721" class="l"><a class="l" href="#721">721: </a><span class="php-comment">     * Build query to count the number of rows
</span></span><span id="722" class="l"><a class="l" href="#722">722: </a><span class="php-comment">     * 
</span></span><span id="723" class="l"><a class="l" href="#723">723: </a><span class="php-comment">     * @param mixed $sql    Statement
</span></span><span id="724" class="l"><a class="l" href="#724">724: </a><span class="php-comment">     * @param bool  $flags  Optional DBQuery::ALL_ROWS
</span></span><span id="725" class="l"><a class="l" href="#725">725: </a><span class="php-comment">     * @return string
</span></span><span id="726" class="l"><a class="l" href="#726">726: </a><span class="php-comment">     */</span>
</span><span id="727" class="l"><a class="l" href="#727">727: </a>    <span class="php-keyword1">public</span> <span class="php-keyword1">static</span> <span class="php-keyword1">function</span> <a id="_buildCountQuery" href="#_buildCountQuery">buildCountQuery</a>(<span class="php-var">$sql</span>, <span class="php-var">$flags</span> = <span class="php-num">0</span>)
</span><span id="728" class="l"><a class="l" href="#728">728: </a>    {
</span><span id="729" class="l"><a class="l" href="#729">729: </a>        <span class="php-var">$type</span> = self::getQueryType(<span class="php-var">$sql</span>);
</span><span id="730" class="l"><a class="l" href="#730">730: </a>
</span><span id="731" class="l"><a class="l" href="#731">731: </a>        <span class="php-var">$parts</span> = <span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) ? <span class="php-var">$sql</span> : self::<span class="php-keyword2">split</span>(<span class="php-var">$sql</span>);
</span><span id="732" class="l"><a class="l" href="#732">732: </a>        <span class="php-keyword1">if</span> ((<span class="php-var">$type</span> == <span class="php-quote">'INSERT'</span> || <span class="php-var">$type</span> == <span class="php-quote">'REPLACE'</span>) &amp;&amp; <span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'query'</span>])) <span class="php-var">$parts</span> = self::<span class="php-keyword2">split</span>(<span class="php-var">$parts</span>[<span class="php-quote">'query'</span>]);
</span><span id="733" class="l"><a class="l" href="#733">733: </a>
</span><span id="734" class="l"><a class="l" href="#734">734: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'from'</span>]) &amp;&amp; !<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'into'</span>]) &amp;&amp; !<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'table'</span>])) <span class="php-keyword1">throw</span> <span class="php-keyword1">new</span> \Exception(<span class="php-quote">&quot;Unable to count rows for </span><span class="php-var">$type</span><span class="php-quote"> query. </span><span class="php-var">$sql</span><span class="php-quote">&quot;</span>);
</span><span id="735" class="l"><a class="l" href="#735">735: </a>        <span class="php-var">$table</span> = <span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'from'</span>]) ? <span class="php-var">$parts</span>[<span class="php-quote">'from'</span>] : (<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'into'</span>]) ? <span class="php-var">$parts</span>[<span class="php-quote">'into'</span>] : <span class="php-var">$parts</span>[<span class="php-quote">'table'</span>]);
</span><span id="736" class="l"><a class="l" href="#736">736: </a>
</span><span id="737" class="l"><a class="l" href="#737">737: </a>        <span class="php-keyword1">if</span> ((<span class="php-var">$flags</span> &amp; DBQuery::ALL_ROWS) &amp;&amp; <span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>])) <span class="php-keyword1">unset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>]);
</span><span id="738" class="l"><a class="l" href="#738">738: </a>
</span><span id="739" class="l"><a class="l" href="#739">739: </a>        <span class="php-keyword1">if</span> (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-quote">'having'</span>])) <span class="php-keyword1">return</span> <span class="php-quote">&quot;SELECT COUNT(*) FROM (&quot;</span> . (<span class="php-keyword2">is_array</span>(<span class="php-var">$sql</span>) ? self::<span class="php-keyword2">join</span>(<span class="php-var">$sql</span>) : <span class="php-var">$sql</span>) . <span class="php-quote">&quot;) AS q&quot;</span>;
</span><span id="740" class="l"><a class="l" href="#740">740: </a>
</span><span id="741" class="l"><a class="l" href="#741">741: </a>        <span class="php-keyword1">if</span> (<span class="php-var">$type</span> == <span class="php-quote">'SELECT'</span>) {
</span><span id="742" class="l"><a class="l" href="#742">742: </a>            <span class="php-var">$distinct</span> = <span class="php-keyword1">null</span>;
</span><span id="743" class="l"><a class="l" href="#743">743: </a>            <span class="php-var">$column</span> = <span class="php-keyword2">preg_match</span>(<span class="php-quote">'/\bDISTINCT\b/si'</span>, <span class="php-var">$parts</span>[<span class="php-quote">'select'</span>]) ? <span class="php-quote">&quot;COUNT(DISTINCT &quot;</span> . <span class="php-keyword2">trim</span>(<span class="php-var">$parts</span>[<span class="php-quote">'columns'</span>]) . <span class="php-quote">&quot;)&quot;</span> : (!<span class="php-keyword1">empty</span>(<span class="php-var">$parts</span>[<span class="php-quote">'group by'</span>]) ? <span class="php-quote">&quot;COUNT(DISTINCT &quot;</span> . <span class="php-keyword2">trim</span>(<span class="php-var">$parts</span>[<span class="php-quote">'group by'</span>]) . <span class="php-quote">&quot;)&quot;</span> : <span class="php-quote">&quot;COUNT(*)&quot;</span>);
</span><span id="744" class="l"><a class="l" href="#744">744: </a>        } <span class="php-keyword1">else</span> {
</span><span id="745" class="l"><a class="l" href="#745">745: </a>            <span class="php-var">$column</span> = <span class="php-quote">&quot;COUNT(*)&quot;</span>;
</span><span id="746" class="l"><a class="l" href="#746">746: </a>        }
</span><span id="747" class="l"><a class="l" href="#747">747: </a>
</span><span id="748" class="l"><a class="l" href="#748">748: </a>        <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>])) {
</span><span id="749" class="l"><a class="l" href="#749">749: </a>            <span class="php-keyword1">list</span>(<span class="php-var">$limit</span>, <span class="php-var">$offset</span>) = self::splitLimit(<span class="php-var">$parts</span>[<span class="php-quote">'limit'</span>]);
</span><span id="750" class="l"><a class="l" href="#750">750: </a>            <span class="php-keyword1">if</span> (<span class="php-keyword1">isset</span>(<span class="php-var">$limit</span>)) <span class="php-var">$column</span> = <span class="php-quote">&quot;LEAST(</span><span class="php-var">$column</span><span class="php-quote">, </span><span class="php-var">$limit</span><span class="php-quote">&quot;</span> . (<span class="php-keyword1">isset</span>(<span class="php-var">$offset</span>) ? <span class="php-quote">&quot;, </span><span class="php-var">$column</span><span class="php-quote"> - </span><span class="php-var">$offset</span><span class="php-quote">&quot;</span> : <span class="php-quote">''</span>) . <span class="php-quote">&quot;)&quot;</span>;
</span><span id="751" class="l"><a class="l" href="#751">751: </a>        }
</span><span id="752" class="l"><a class="l" href="#752">752: </a>
</span><span id="753" class="l"><a class="l" href="#753">753: </a>        <span class="php-keyword1">return</span> self::<span class="php-keyword2">join</span>(<span class="php-keyword1">array</span>(<span class="php-quote">'select'</span> =&gt; <span class="php-quote">''</span>, <span class="php-quote">'columns'</span> =&gt; <span class="php-var">$column</span>, <span class="php-quote">'from'</span> =&gt; <span class="php-var">$table</span>, <span class="php-quote">'where'</span> =&gt; <span class="php-keyword1">isset</span>(<span class="php-var">$parts</span>[<span class="php-quote">'where'</span>]) ? <span class="php-var">$parts</span>[<span class="php-quote">'where'</span>] : <span class="php-quote">''</span>));
</span><span id="754" class="l"><a class="l" href="#754">754: </a>    }
</span><span id="755" class="l"><a class="l" href="#755">755: </a>
</span><span id="756" class="l"><a class="l" href="#756">756: </a>}
</span><span id="757" class="l"><a class="l" href="#757">757: </a></span></code></pre>

	<div id="footer">
		DBQuery-MySQL · API documentation API documentation generated by <a href="http://apigen.org">ApiGen 2.8.0</a>
	</div>
</div>
</div>
</body>
</html>
Return current item: DBQuery-MySQL