Table Prefix, problem with left join convention structure.
Opened this issue · 4 comments
Hi,
There seems to be a problem with left joining, when using the convention structure. The prefix was not removed from the column name, which suppose to be a must.
Take a look this sample tables below:
user : id, name, email
question : id, user_id, text, html
answer : id, user_id, question_id, text, html
If I do this call, then it will return the left join with foreign column being referenced together with table prefix:
$db->question()->where('answer:user_id = ?', 1);
I fix this with:
protected function getColumnFromTable($name) {
if ($this->table != '%s' && preg_match('(^' . str_replace('%s', '(.*)', preg_quote($this->table)) . '$)', $name, $match)) {
return $match[1];
}
return substr($name, strlen($this->prefix)); // FIX: Remove Unnecessary Prefix
}
I haven't tested further, but I assume it might trigger abnormal behavior. Would you mind taking a look into this?
Thanks.
Wendy
I think the problem is not on the convention structure class, instead it's on the result class itself, when joining the table. Here's what I did and so far it looks ok, though I'm not sure whether it solves the root of the bug or not. Please advice!
protected function createJoins($val) {
$return = array();
preg_match_all('~\\b([a-z_][a-z0-9_.:]*[.:])[a-z_*]~i', $val, $matches);
foreach ($matches[1] as $names) {
$parent = $this->table;
if ($names != "$parent.") { // case-sensitive
preg_match_all('~\\b([a-z_][a-z0-9_]*)([.:])~i', $names, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
list(, $name, $delimiter) = $match;
$table = $this->notORM->structure->getReferencedTable($name, $parent);
$column = ($delimiter == ':' ? $this->notORM->structure->getPrimary($parent) : $this->notORM->structure->getReferencedColumn($name, $parent));
$primary = ($delimiter == ':' ? $this->notORM->structure->getReferencingColumn($table, $parent) : $this->notORM->structure->getPrimary($table));
$return[$name] = " LEFT JOIN $table" . ($table != $name ? " AS $name" : "") . " ON $parent.$column = $name.$primary"; // should use alias if the table is used on more places
$parent = $name;
}
}
}
return $return;
}
I wonder whether this issue had been fixed yet?
$primary = ($delimiter == ':' ? $this->notORM->structure->getReferencingColumn($parent, $table) : $this->notORM->structure->getPrimary($table));
I change getReferencedColumn
to getReferencingColumn
.
Is the fix above actually fix the problem or not?
Please advice.
I think this is more complicated than it does.
Anybody can help out?
I tried this, but haven't actually tested it fully.
protected function getColumnFromTable($name) {
if ($this->table != '%s' && preg_match('(^' . str_replace('%s', '(.*)', preg_quote($this->table)) . '$)', $name, $match)) {
return $match[1];
}
return substr($name, strlen($this->prefix));
}
Basically I change return $name;
into return substr($name, strlen($this->prefix));
.
Please correct me if I'm wrong.