Commit c27d6630 authored by Dries's avatar Dries

- Patch #770838 by sdboyer: optimize DatabaseConnection::ExpandArguments.

parent 00deb1df
......@@ -213,7 +213,7 @@ abstract class DatabaseConnection extends PDO {
/**
* Index of what driver-specific class to use for various operations.
*
*
* @var array
*/
protected $driverClasses = array();
......@@ -592,36 +592,33 @@ public function query($query, array $args = array(), $options = array()) {
protected function expandArguments(&$query, &$args) {
$modified = FALSE;
foreach ($args as $key => $data) {
// If the placeholder value to insert is an array, assume that we need
// to expand it out into a comma-delimited set of placeholders.
if (is_array($data)) {
$new_keys = array();
foreach ($data as $i => $value) {
// This assumes that there are no other placeholders that use the same
// name. For example, if the array placeholder is defined as :example
// and there is already an :example_2 placeholder, this will generate
// a duplicate key. We do not account for that as the calling code
// is already broken if that happens.
$new_keys[$key . '_' . $i] = $value;
}
// Update the query with the new placeholders.
// preg_replace is a little bit slower than str_replace, but it is
// necessary to ensure the replacement does not affect placeholders
// that start with the same exact text. For example, if the query
// contains the placeholders :foo and :foobar, and :foo has an array
// of values, using str_replace would affect both placeholders, but
// using the following preg_replace would only affect :foo because it
// is followed by a non-word character.
$query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);
// Update the args array with the new placeholders.
unset($args[$key]);
$args += $new_keys;
$modified = TRUE;
// If the placeholder value to insert is an array, assume that we need
// to expand it out into a comma-delimited set of placeholders.
foreach (array_filter($args, 'is_array') as $key => $data) {
$new_keys = array();
foreach ($data as $i => $value) {
// This assumes that there are no other placeholders that use the same
// name. For example, if the array placeholder is defined as :example
// and there is already an :example_2 placeholder, this will generate
// a duplicate key. We do not account for that as the calling code
// is already broken if that happens.
$new_keys[$key . '_' . $i] = $value;
}
// Update the query with the new placeholders.
// preg_replace is necessary to ensure the replacement does not affect
// placeholders that start with the same exact text. For example, if the
// query contains the placeholders :foo and :foobar, and :foo has an
// array of values, using str_replace would affect both placeholders,
// but using the following preg_replace would only affect :foo because
// it is followed by a non-word character.
$query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);
// Update the args array with the new placeholders.
unset($args[$key]);
$args += $new_keys;
$modified = TRUE;
}
return $modified;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment