简体   繁体   中英

How can I sync differing primary key values on replicating execute?

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 .

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();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM