Commit 91e0c5ae by Qiang Xue

Added Connection::useMaster() and refactored code.

parent d2cb245d
...@@ -69,7 +69,7 @@ class Command extends \yii\base\Component ...@@ -69,7 +69,7 @@ class Command extends \yii\base\Component
/** /**
* @var array the parameters (name => value) that are bound to the current PDO statement. * @var array the parameters (name => value) that are bound to the current PDO statement.
* This property is maintained by methods such as [[bindValue()]]. It is mainly provided for logging purpose * This property is maintained by methods such as [[bindValue()]]. It is mainly provided for logging purpose
* and is used to generated [[rawSql]]. Do not modify it directly. * and is used to generate [[rawSql]]. Do not modify it directly.
*/ */
public $params = []; public $params = [];
/** /**
......
...@@ -700,6 +700,31 @@ class Connection extends Component ...@@ -700,6 +700,31 @@ class Connection extends Component
} }
/** /**
* Executes the provided callback by using the master connection.
*
* This method is provided so that you can temporarily force using the master connection to perform
* DB operations. For example,
*
* ```php
* $result = $db->useMaster(function ($db) {
* return $db->createCommand('SELECT * FROM user LIMIT 1')->queryOne();
* });
* ```
*
* @param callable $callback a PHP callable to be executed by this method. Its signature is
* `function ($db)`. Its return value will be returned by this method.
* @return mixed the return value of the callback
*/
public function useMaster(callable $callback)
{
$enableSlave = $this->enableSlave;
$this->enableSlave = false;
$result = call_user_func($callback, $this);
$this->enableSlave = $enableSlave;
return $result;
}
/**
* Selects a slave and opens the connection. * Selects a slave and opens the connection.
* @param array $slaves the list of candidate slave configurations * @param array $slaves the list of candidate slave configurations
* @return Connection the opened slave connection, or null if no slave is available * @return Connection the opened slave connection, or null if no slave is available
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\db\oci; namespace yii\db\oci;
use yii\base\InvalidParamException; use yii\base\InvalidParamException;
use yii\db\Connection;
/** /**
* QueryBuilder is the query builder for Oracle databases. * QueryBuilder is the query builder for Oracle databases.
...@@ -133,11 +134,9 @@ EOD; ...@@ -133,11 +134,9 @@ EOD;
$value = (int) $value; $value = (int) $value;
} else { } else {
// use master connection to get the biggest PK value // use master connection to get the biggest PK value
$enableSlave = $this->db->enableSlave; $value = $this->db->useMaster(function (Connection $db) use ($tableSchema) {
$this->db->enableSlave = false; return $db->createCommand("SELECT MAX(\"{$tableSchema->primaryKey}\") FROM \"{$tableSchema->name}\"")->queryScalar();
$value = (int) $this->db->createCommand("SELECT MAX(\"{$tableSchema->primaryKey}\") FROM \"{$tableSchema->name}\"")->queryScalar(); }) + 1;
$this->db->enableSlave = $enableSlave;
$value++;
} }
return "DROP SEQUENCE \"{$tableSchema->name}_SEQ\";" return "DROP SEQUENCE \"{$tableSchema->name}_SEQ\";"
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\db\oci; namespace yii\db\oci;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\db\Connection;
use yii\db\TableSchema; use yii\db\TableSchema;
use yii\db\ColumnSchema; use yii\db\ColumnSchema;
...@@ -196,11 +197,9 @@ EOD; ...@@ -196,11 +197,9 @@ EOD;
{ {
if ($this->db->isActive) { if ($this->db->isActive) {
// get the last insert id from the master connection // get the last insert id from the master connection
$enableSlave = $this->db->enableSlave; return $this->db->useMaster(function (Connection $db) use ($sequenceName) {
$this->db->enableSlave = false; return $db->createCommand("SELECT {$sequenceName}.CURRVAL FROM DUAL")->queryScalar();
$id = $this->db->createCommand("SELECT {$sequenceName}.CURRVAL FROM DUAL")->queryScalar(); });
$this->db->enableSlave = $enableSlave;
return $id;
} else { } else {
throw new InvalidCallException('DB Connection is not active.'); throw new InvalidCallException('DB Connection is not active.');
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace yii\db\sqlite; namespace yii\db\sqlite;
use yii\db\Connection;
use yii\db\Exception; use yii\db\Exception;
use yii\base\InvalidParamException; use yii\base\InvalidParamException;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
...@@ -120,10 +121,9 @@ class QueryBuilder extends \yii\db\QueryBuilder ...@@ -120,10 +121,9 @@ class QueryBuilder extends \yii\db\QueryBuilder
if ($value === null) { if ($value === null) {
$key = reset($table->primaryKey); $key = reset($table->primaryKey);
$tableName = $db->quoteTableName($tableName); $tableName = $db->quoteTableName($tableName);
$enableSlave = $this->db->enableSlave; $value = $this->db->useMaster(function (Connection $db) use ($key, $tableName) {
$this->db->enableSlave = false; return $db->createCommand("SELECT MAX('$key') FROM $tableName")->queryScalar();
$value = $db->createCommand("SELECT MAX('$key') FROM $tableName")->queryScalar(); });
$this->db->enableSlave = $enableSlave;
} else { } else {
$value = (int) $value - 1; $value = (int) $value - 1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment