Created
May 18, 2014 08:24
-
-
Save miau/f84374fe13b9a1ef5523 to your computer and use it in GitHub Desktop.
Doctrine DBAL のパラメータ置換処理(「?」を「:param1」等に書き換える処理)を高速化するパッチ。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: Doctrine/DBAL/Driver/OCI8/OCI8Statement.php | |
=================================================================== | |
--- Doctrine/DBAL/Driver/OCI8/OCI8Statement.php | |
+++ Doctrine/DBAL/Driver/OCI8/OCI8Statement.php | |
@@ -72,26 +72,23 @@ | |
* @return string | |
*/ | |
static public function convertPositionalToNamedPlaceholders($statement) | |
- { | |
- $count = 1; | |
- $inLiteral = false; // a valid query never starts with quotes | |
- $stmtLen = strlen($statement); | |
- $paramMap = array(); | |
- for ($i = 0; $i < $stmtLen; $i++) { | |
- if ($statement[$i] == '?' && !$inLiteral) { | |
- // real positional parameter detected | |
- $paramMap[$count] = ":param$count"; | |
- $len = strlen($paramMap[$count]); | |
- $statement = substr_replace($statement, ":param$count", $i, 1); | |
- $i += $len-1; // jump ahead | |
- $stmtLen = strlen($statement); // adjust statement length | |
- ++$count; | |
- } else if ($statement[$i] == "'" || $statement[$i] == '"') { | |
- $inLiteral = ! $inLiteral; // switch state! | |
- } | |
- } | |
- | |
- return array($statement, $paramMap); | |
+ { | |
+ // 高速化のために正規表現を使った処理に書き換えている。 | |
+ // 元の処理ではシングルクォートとダブルクォートを同一視していた | |
+ // (これはこれで問題がある)が、書き換え後の処理ではシングルクォート | |
+ // のみ考慮している。 | |
+ // そのためダブルクォート内に「?」や「'」が出現する場合にうまく処理 | |
+ // できないが、そのような識別子は通常使われないので問題ないはず。 | |
+ $count = 0; | |
+ $paramMap = array(); | |
+ $replaced = preg_replace_callback( | |
+ "/\\G(?>((?:'[^']*'|[^'?]+)*))\\?/", | |
+ function($matches) use (&$count, &$paramMap) { | |
+ return $matches[1] . ($paramMap[++$count] = ':param' . $count); | |
+ }, | |
+ $statement | |
+ ); | |
+ return array($replaced ?: $statement, $paramMap); | |
} | |
/** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment