如何在复制执行时同步不同的主键值?

发布于 2025-01-10 05:36:30 字数 818 浏览 6 评论 0原文

我有两个连接,dc。基本上,无论我对 d 的某些模型进行什么更改,它也需要在 c 上复制。这是执行此操作的代码:

    public function execute()
    {
        if ($this->isReplicate()) {
            $primaryKey = $this->_repository->getPrimaryKey();
            $replica = clone $this;
            $replica->setConnection(ConnectionManager::get('c'));
            $replica->execute();
            //$this->_repository->{$primaryKey} = $replica->getRepository()->{$primaryKey};
        }
        $result = parent::execute();
        return $result;
    }

注释行将负责同步主键,但这当然不起作用,因为 _repository 代表一个 table,但是,我需要应用行级更改。如何确保此查询创建的所有新记录都会同步?

此代码位于 App\ORM\Query 命名空间中,该命名空间扩展 Cake\ORM\Query

I have two connections, d and c. Basically, whatever changes I do on certain models of d, it needs to be replicated at c as well. This is the code doing it:

    public function execute()
    {
        if ($this->isReplicate()) {
            $primaryKey = $this->_repository->getPrimaryKey();
            $replica = clone $this;
            $replica->setConnection(ConnectionManager::get('c'));
            $replica->execute();
            //$this->_repository->{$primaryKey} = $replica->getRepository()->{$primaryKey};
        }
        $result = parent::execute();
        return $result;
    }

The commented line would be responsible for syncing the primary keys, but of course this is not working, because _repository represents a table, yet, I need to apply row-level changes. How could I ensure that all new records created by this query will be synced?

This code is located in the App\ORM\Query namespace, which extends Cake\ORM\Query.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南烟雨〆相思醉 2025-01-17 05:36:30

我已经设法用下面的代码解决了这个问题(逻辑在注释中解释):

    /**
     * Overrides a method with the same name to handle synchronizations with c
     */
    public function execute()
    {
        //Some tables need replication. If this is such a table, then we need to perform some extra steps. Otherwise we would just call the parent
        //Method
        if ($this->isReplicate()) {
            //Getting the table
            $table = $this->_repository->getTable();
            //Replicating the query
            $replica = clone $this;
            //Setting the connection of the replica to c, because we need to apply the district changes to central
            $replica->setConnection(ConnectionManager::get('c'));
            //We execute the replica first, because we will need to refer c IDs and not the other way around
            $replica->execute();
            //If this is an insert, then we need to handle the ids as well
            if (!empty($this->clause('insert'))) {
                //We load the primary key's name to use it later to find the maximum value
                $primaryKey = $this->_repository->getPrimaryKey();
                //We get the highest ID value, which will always be a positive number, because we have already executed the query at the replica
                $maxID = $this->getConnection()
                              ->execute("SELECT {$primaryKey} FROM {$table} ORDER BY {$primaryKey} DESC LIMIT 0, 1")
                              ->fetchAll('assoc')[0][$primaryKey];

                //We get the columns
                $columns = $this->clause('values')->getColumns();
                //In order to add the primary key
                $columns[] = $primaryKey;
                //And then override the insert clause with this adjusted array
                $this->insert($columns);
                //We get the values
                $values = $this->clause('values')->getValues();
                //And their count
                $count = count($values);
                //There could be multiple rows inserted already into the replica as part of this query, we need to replicate all their IDs, without
                //assuming that there is a single inserted record
                for ($index = 0; $index < $count; $index++) {
                    $values[$index][$primaryKey] = $maxID - $count + $index + 1;
                }
                //We override the values clause with this adjusted array, which contains PK values as well
                $this->clause('values')->values($values);
            }
            //We nevertheless execute the query in any case, independently of whether it was a replicate table
            //If it was a replicate table, then we have already made adjustments to the query in the if block
            return parent::execute();
        }
    }

I have managed to resolve the issue with the code that follows (the logic is explained in the comments):

    /**
     * Overrides a method with the same name to handle synchronizations with c
     */
    public function execute()
    {
        //Some tables need replication. If this is such a table, then we need to perform some extra steps. Otherwise we would just call the parent
        //Method
        if ($this->isReplicate()) {
            //Getting the table
            $table = $this->_repository->getTable();
            //Replicating the query
            $replica = clone $this;
            //Setting the connection of the replica to c, because we need to apply the district changes to central
            $replica->setConnection(ConnectionManager::get('c'));
            //We execute the replica first, because we will need to refer c IDs and not the other way around
            $replica->execute();
            //If this is an insert, then we need to handle the ids as well
            if (!empty($this->clause('insert'))) {
                //We load the primary key's name to use it later to find the maximum value
                $primaryKey = $this->_repository->getPrimaryKey();
                //We get the highest ID value, which will always be a positive number, because we have already executed the query at the replica
                $maxID = $this->getConnection()
                              ->execute("SELECT {$primaryKey} FROM {$table} ORDER BY {$primaryKey} DESC LIMIT 0, 1")
                              ->fetchAll('assoc')[0][$primaryKey];

                //We get the columns
                $columns = $this->clause('values')->getColumns();
                //In order to add the primary key
                $columns[] = $primaryKey;
                //And then override the insert clause with this adjusted array
                $this->insert($columns);
                //We get the values
                $values = $this->clause('values')->getValues();
                //And their count
                $count = count($values);
                //There could be multiple rows inserted already into the replica as part of this query, we need to replicate all their IDs, without
                //assuming that there is a single inserted record
                for ($index = 0; $index < $count; $index++) {
                    $values[$index][$primaryKey] = $maxID - $count + $index + 1;
                }
                //We override the values clause with this adjusted array, which contains PK values as well
                $this->clause('values')->values($values);
            }
            //We nevertheless execute the query in any case, independently of whether it was a replicate table
            //If it was a replicate table, then we have already made adjustments to the query in the if block
            return parent::execute();
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文