Skip to content

Commit

Permalink
Refactory of DboSource::name() to improve performance. Added more tes…
Browse files Browse the repository at this point in the history
…ts to it.

Signed-off-by: Mark Story <mark@mark-story.com>
  • Loading branch information
jrbasso authored and markstory committed Jan 27, 2010
1 parent 827c65a commit 57997e7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 49 deletions.
72 changes: 23 additions & 49 deletions cake/libs/model/datasources/dbo_source.php
Expand Up @@ -469,63 +469,37 @@ function field($name, $sql) {
* @access public
*/
function name($data) {
if ($data == '*') {
if ($data === '*') {
return '*';
}
if (is_object($data) && isset($data->type)) {
return $data->value;
}
$array = is_array($data);
$data = (array)$data;
$count = count($data);

for ($i = 0; $i < $count; $i++) {
if ($data[$i] == '*') {
continue;
}
if (strpos($data[$i], '(') !== false && preg_match_all('/([^(]*)\((.*)\)(.*)/', $data[$i], $fields)) {
$fields = Set::extract($fields, '{n}.0');

if (!empty($fields[1])) {
if (!empty($fields[2])) {
$data[$i] = $fields[1] . '(' . $this->name($fields[2]) . ')' . $fields[3];
} else {
$data[$i] = $fields[1] . '()' . $fields[3];
}
}
}
$data[$i] = str_replace('.', $this->endQuote . '.' . $this->startQuote, $data[$i]);
$data[$i] = $this->startQuote . $data[$i] . $this->endQuote;
$data[$i] = str_replace($this->startQuote . $this->startQuote, $this->startQuote, $data[$i]);
$data[$i] = str_replace($this->startQuote . '(', '(', $data[$i]);
$data[$i] = str_replace(')' . $this->startQuote, ')', $data[$i]);
$alias = !empty($this->alias) ? $this->alias : 'AS ';

if (preg_match('/\s+' . $alias . '\s*/', $data[$i])) {
if (preg_match('/\w+\s+' . $alias . '\s*/', $data[$i])) {
$quoted = $this->endQuote . ' ' . $alias . $this->startQuote;
$data[$i] = str_replace(' ' . $alias, $quoted, $data[$i]);
} else {
$quoted = $alias . $this->startQuote;
$data[$i] = str_replace($alias, $quoted, $data[$i]) . $this->endQuote;
}
if (is_array($data)) {
foreach ($data as $i => $dataItem) {
$data[$i] = $this->name($dataItem);
}

if (!empty($this->endQuote) && $this->endQuote == $this->startQuote) {
if (substr_count($data[$i], $this->endQuote) % 2 == 1) {
if (substr($data[$i], -2) == $this->endQuote . $this->endQuote) {
$data[$i] = substr($data[$i], 0, -1);
} else {
$data[$i] = trim($data[$i], $this->endQuote);
}
}
}
if (strpos($data[$i], '*')) {
$data[$i] = str_replace($this->endQuote . '*' . $this->endQuote, '*', $data[$i]);
return $data;
}
$data = trim($data);
if (preg_match('/^\w+(\.\w+)*$/', $data)) { // string, string.string
if (strpos($data, '.') === false) { // string
return $this->startQuote . $data . $this->endQuote;
}
$data[$i] = str_replace($this->endQuote . $this->endQuote, $this->endQuote, $data[$i]);
$items = explode('.', $data);
return $this->startQuote . implode($this->endQuote . '.' . $this->startQuote, $items) . $this->endQuote;
}
if (preg_match('/^\w+\.\*$/', $data)) { // string.*
$items = explode('.', $data);
return $this->startQuote . str_replace('.*', $this->endQuote . '.*', $data);
}
if (preg_match('/^(\w+)\((.*)\)$/', $data, $matches)) { // Functions
return $matches[1] . '(' . $this->name($matches[2]) . ')';
}
return (!$array) ? $data[0] : $data;
if (preg_match('/^(\w+(\.\w+|\(.*\))*)\s+' . preg_quote($this->alias) . '\s*(\w+)$/', $data, $matches)) {
return preg_replace('/\s{2,}/', ' ', $this->name($matches[1]) . ' ' . $this->alias . ' ' . $this->name($matches[3]));
}
return $data;
}

/**
Expand Down
16 changes: 16 additions & 0 deletions cake/tests/cases/libs/model/datasources/dbo_source.test.php
Expand Up @@ -4014,9 +4014,25 @@ function testName() {
$expected = '(sm)';
$this->assertEqual($result, $expected);

$result = $this->testDb->name('name AS x');
$expected = '`name` AS `x`';
$this->assertEqual($result, $expected);

$result = $this->testDb->name('Model.name AS x');
$expected = '`Model`.`name` AS `x`';
$this->assertEqual($result, $expected);

$result = $this->testDb->name('Function(Something.foo)');
$expected = 'Function(`Something`.`foo`)';
$this->assertEqual($result, $expected);

$result = $this->testDb->name('Function(SubFunction(Something.foo))');
$expected = 'Function(SubFunction(`Something`.`foo`))';
$this->assertEqual($result, $expected);

$result = $this->testDb->name('Function(Something.foo) AS x');
$expected = 'Function(`Something`.`foo`) AS `x`';
$this->assertEqual($result, $expected);
}

/**
Expand Down

0 comments on commit 57997e7

Please sign in to comment.