yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

\yii2\rbac\DbManager::getRolesByUser($userId) has no use cache #15376

Closed bscheshirwork closed 1 year ago

bscheshirwork commented 6 years ago

https://github.com/yiisoft/yii2/blob/339f12969b264b4deae3ad0e88423162676348e1/framework/rbac/DbManager.php#L461-L483

What steps will reproduce the problem?

  1. add

    'cache' => 'cache'

    to config of rbac

  2. check mysql query log

What is the expected result?

all of queries to db is stored to cache

What do you get instead?

each time

2017-12-18 10:57:51     11 -- SELECT `b`.* FROM `auth_assignment` `a`, `auth_item` `b` WHERE (`a`.`item_name`=`b`.`name`) AND (`a`.`user_id`='1') AND (`b`.`type`=1) 
2017-12-18 10:57:51     11 -- SELECT `b`.* FROM `auth_assignment` `a`, `auth_item` `b` WHERE (`a`.`item_name`=`b`.`name`) AND (`a`.`user_id`='1') AND (`b`.`type`=2) 
2017-12-18 10:57:51     11 -- SELECT * FROM `auth_item_child` 
2017-12-18 10:57:51     11 -- SELECT `item_name` FROM `auth_assignment` WHERE `user_id`='1' 
2017-12-18 10:57:51     11 -- SELECT * FROM `auth_item` WHERE (`type`=2) AND (`name` IN ('list', 'of', 'name')) 

Additional info

Q A
Yii version dev
PHP version 7.2
Operating system Debian scratch
bscheshirwork commented 6 years ago

So... This will be called in https://github.com/yiisoft/yii2-debug/blob/b37f414959c2fafefb332020b42037cd17c1cb7f/panels/UserPanel.php#L238

bscheshirwork commented 6 years ago

same situation: I can't see any cache calling

https://github.com/yiisoft/yii2/blob/339f12969b264b4deae3ad0e88423162676348e1/framework/rbac/DbManager.php#L546-L616

samdark commented 6 years ago

Yes. Worth fixing.

bscheshirwork commented 6 years ago

we can use db cache

    /**
     * @inheritdoc
     * The roles returned by this method include the roles assigned via [[$defaultRoles]].
     */
    public function getRolesByUser($userId)
    {
        if ($this->isEmptyUserId($userId)) {
            return [];
        }

        $query = (new Query())->select('b.*')
            ->from(['a' => $this->assignmentTable, 'b' => $this->itemTable])
            ->where('{{a}}.[[item_name]]={{b}}.[[name]]')
            ->andWhere(['a.user_id' => (string) $userId])
            ->andWhere(['b.type' => Item::TYPE_ROLE]);
        $roles = $this->getDefaultRoleInstances();
        $rows = $this->db->cache(function () use ($query) {
            return $query->createCommand($this->db)->queryAll();
        });

        foreach ($rows as $row) {
            $roles[$row['name']] = $this->populateItem($row);
        }

        return $roles;
    }

but this is not correct - we must use only internal cache settings

Also we can use separate keys on main data (current) and other query data