catfan / Medoo

The lightweight PHP database framework to accelerate the development.
https://medoo.in
MIT License
4.83k stars 1.15k forks source link

Medoo BUGs #368

Closed mingyuantech closed 7 years ago

mingyuantech commented 8 years ago

Medoo BUGs

我在使用<1.0>版本的时候, 发现的bug, 目前1.0.2仍然还是存在的.

执行代码如下:

require 'Resources/Medoo.php';

$oMedoo = new medoo(array(
        'database_type' => 'mysql',
        'database_name' => 'smartcc',
        'server' => 'localhost',
        'username' => 'root',
        'password' => '',
        'charset' => 'utf8',
        'port' => 3306,
        'prefix' => 'smart_'
    ));

$oMedoo->Select('crmentity(CRM)', array(
        '[><]account(ACC)' => array('crmid'=>'accountid')
    ), array('creatorid', 'sn', 'accountid'));
print_r($oMedoo->last_query()); echo "\n";

$oMedoo->Select('crmentity', array(
        '[><]account' => array('crmid'=>'accountid')
    ), array('creatorid', 'sn', 'accountid'));
print_r($oMedoo->last_query()); echo "\n";

那么编译的SQL为:

SELECT
    "creatorid",
    "sn",
    "accountid"
FROM
    "smart_crmentity(CRM)"
INNER JOIN "smart_account" AS "ACC" ON smart_ "smart_crmentity(CRM)"."crmid" = "ACC"."accountid"

SELECT
    "creatorid",
    "sn",
    "accountid"
FROM
    "smart_crmentity"
INNER JOIN "smart_account" ON smart_ "smart_crmentity"."crmid" = "account"."accountid"

实际上我期待的结果应该是这样:

SELECT
    "creatorid",
    "sn",
    "accountid"
FROM
    "smart_crmentity" AS "CRM"
INNER JOIN "smart_account" AS "ACC" ON "CRM"."crmid" = "ACC"."accountid"

SELECT
    "creatorid",
    "sn",
    "accountid"
FROM
    "smart_crmentity"
INNER JOIN "smart_account" ON "smart_crmentity"."crmid" = "smart_account"."accountid"

那么建议的修改以下两处在 select_context>: 545行

$table = '"' . $this->prefix . $table . '"';
$join_key = is_array($join) ? array_keys($join) : null;

修改为 以让 table 支持 别名(AS)功能

if ( strpos($table, '(') ) {
    list($table, $alias) = explode('=', str_replace(array('(', ')'), array('=', null), $table));
    $table = '"' . $this->prefix . $table . '" AS "'.$alias.'"';
    $alias = '"'.$alias.'"';
} else {
    $table = $alias = '"' . $this->prefix . $table . '"';
}

$join_key = is_array($join) ? array_keys($join) : null;

那么建议的修正在 select_context>: 584行

foreach ($relation as $key => $value)
{
    $joins[] = $this->prefix . (
        strpos($key, '.') > 0 ?
            // For ['tableB.column' => 'column']
            '"' . str_replace('.', '"."', $key) . '"' :

            // For ['column1' => 'column2']
            $table . '."' . $key . '"'
    ) .
    ' = ' .
    '"' . (isset($match[ 5 ]) ? $match[ 5 ] : $match[ 3 ]) . '"."' . $value . '"';
}

修改为 以让 join 表的前缀功能正常

foreach ($relation as $key => $value)
{
    $joins[] = (
        strpos($key, '.') > 0 ?
            // For ['tableB.column' => 'column']
            '"' . str_replace('.', '"."', $key) . '"' :

            // For ['column1' => 'column2']
            $alias . '."' . $key . '"'
    ) .
    ' = ' .
    '"' . (isset($match[ 5 ]) ? $match[ 5 ] : $this->prefix.$match[ 3 ]) . '"."' . $value . '"';
}

另外建议可以公开一个方法, 例如 Build_sql 可以让外部可以直接得到编译后的SQL语句.

leiyiyi commented 8 years ago

要么用作者的原版,不要使用prefix,自己加prefix;要么用楼上的修改版,完美prefix。 查询主键别名功能非常重要,不知为何原作者为嘛一直没实现,楼上的修改版非常好,代码很精辟。赞。 另外原作者还需要增加LIKE查询的组合查询功能,自用的修改了下实现了,那时还是0.8几版本的时候,现在本地找不到了,囧