diff --git a/extensions/yii/sphinx/Command.php b/extensions/yii/sphinx/Command.php index ba802f5..9197b67 100644 --- a/extensions/yii/sphinx/Command.php +++ b/extensions/yii/sphinx/Command.php @@ -319,7 +319,7 @@ class Command extends \yii\db\Command /** * @inheritdoc */ - public function checkIntegrity($check = true, $schema = '') + public function checkIntegrity($check = true, $schema = '', $table = '') { throw new NotSupportedException('"' . __METHOD__ . '" is not supported.'); } diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 747e59d..b3c13e5 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -34,6 +34,7 @@ Yii Framework 2 Change Log - Enh #1611: Added `BaseActiveRecord::markAttributeDirty()` (qiangxue) - Enh #1634: Use masked CSRF tokens to prevent BREACH exploits (qiangxue) - Enh #1641: Added `BaseActiveRecord::updateAttributes()` (qiangxue) +- Enh #1646: Added postgresql `QueryBuilder::checkIntegrity` and `QueryBuilder::resetSequence` (Ragazzo) - Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark) - Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue) - Enh: Support for file aliases in console command 'message' (omnilight) diff --git a/framework/yii/db/Command.php b/framework/yii/db/Command.php index 2075b2d..76b4269 100644 --- a/framework/yii/db/Command.php +++ b/framework/yii/db/Command.php @@ -743,12 +743,13 @@ class Command extends \yii\base\Component * @param boolean $check whether to turn on or off the integrity check. * @param string $schema the schema name of the tables. Defaults to empty string, meaning the current * or default schema. + * @param string $table the table name. * @return Command the command object itself * @throws NotSupportedException if this is not supported by the underlying DBMS */ - public function checkIntegrity($check = true, $schema = '') + public function checkIntegrity($check = true, $schema = '', $table = '') { - $sql = $this->db->getQueryBuilder()->checkIntegrity($check, $schema); + $sql = $this->db->getQueryBuilder()->checkIntegrity($check, $schema, $table); return $this->setSql($sql); } } diff --git a/framework/yii/db/mysql/Schema.php b/framework/yii/db/mysql/Schema.php index a649d8a..d5258c1 100644 --- a/framework/yii/db/mysql/Schema.php +++ b/framework/yii/db/mysql/Schema.php @@ -280,7 +280,7 @@ class Schema extends \yii\db\Schema * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. * @return array all table names in the database. The names have NO schema name prefix. */ - protected function findTableNames($schema = '') + public function findTableNames($schema = '') { $sql = 'SHOW TABLES'; if ($schema !== '') { diff --git a/framework/yii/db/pgsql/QueryBuilder.php b/framework/yii/db/pgsql/QueryBuilder.php index 09a620d..47255e6 100644 --- a/framework/yii/db/pgsql/QueryBuilder.php +++ b/framework/yii/db/pgsql/QueryBuilder.php @@ -7,6 +7,7 @@ */ namespace yii\db\pgsql; +use yii\base\InvalidParamException; /** * QueryBuilder is the query builder for PostgreSQL databases. @@ -62,6 +63,66 @@ class QueryBuilder extends \yii\db\QueryBuilder } /** + * Creates a SQL statement for resetting the sequence value of a table's primary key. + * The sequence will be reset such that the primary key of the next new row inserted + * will have the specified value or 1. + * @param string $tableName the name of the table whose primary key sequence will be reset + * @param mixed $value the value for the primary key of the next new row inserted. If this is not set, + * the next new row's primary key will have a value 1. + * @return string the SQL statement for resetting sequence + * @throws InvalidParamException if the table does not exist or there is no sequence associated with the table. + */ + public function resetSequence($tableName, $value = null) + { + $table = $this->db->getTableSchema($tableName); + if ($table !== null && $table->sequenceName !== null) { + $sequence='"'.$table->sequenceName.'"'; + + if (strpos($sequence,'.')!==false) { + $sequence=str_replace('.','"."',$sequence); + } + + $tableName = $this->db->quoteTableName($tableName); + if ($value === null) { + $key = reset($table->primaryKey); + $value="(SELECT COALESCE(MAX(\"{$key}\"),0) FROM {$tableName})+1"; + } else { + $value = (int)$value; + } + return "SELECT SETVAL('$sequence',$value,false)"; + } elseif ($table === null) { + throw new InvalidParamException("Table not found: $tableName"); + } else { + throw new InvalidParamException("There is not sequence associated with table '$tableName'."); + } + } + + /** + * Builds a SQL statement for enabling or disabling integrity check. + * @param boolean $check whether to turn on or off the integrity check. + * @param string $schema the schema of the tables. + * @param string $table the table name. + * @return string the SQL statement for checking integrity + */ + public function checkIntegrity($check = true, $schema = '', $table = '') + { + $enable = $check ? 'ENABLE' : 'DISABLE'; + $schema = $schema ? $schema : $this->db->schema->defaultSchema; + $tableNames = $table ? [$table] : $this->db->schema->findTableNames($schema); + $command = ''; + + foreach($tableNames as $tableName) + { + $tableName='"'.$schema.'"."'.$tableName.'"'; + $command .= "ALTER TABLE $tableName $enable TRIGGER ALL; "; + } + + #enable to have ability to alter several tables + $this->db->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); + return $command; + } + + /** * Builds a SQL statement for changing the definition of a column. * @param string $table the table whose column is to be changed. The table name will be properly quoted by the method. * @param string $column the name of the column to be changed. The name will be properly quoted by the method. diff --git a/framework/yii/db/pgsql/Schema.php b/framework/yii/db/pgsql/Schema.php index 96889ab..59340c9 100644 --- a/framework/yii/db/pgsql/Schema.php +++ b/framework/yii/db/pgsql/Schema.php @@ -158,7 +158,7 @@ class Schema extends \yii\db\Schema * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. * @return array all table names in the database. The names have NO schema name prefix. */ - protected function findTableNames($schema = '') + public function findTableNames($schema = '') { if ($schema === '') { $schema = $this->defaultSchema; diff --git a/framework/yii/db/sqlite/Schema.php b/framework/yii/db/sqlite/Schema.php index 9f410b4..6548999 100644 --- a/framework/yii/db/sqlite/Schema.php +++ b/framework/yii/db/sqlite/Schema.php @@ -87,7 +87,7 @@ class Schema extends \yii\db\Schema * If not empty, the returned table names will be prefixed with the schema name. * @return array all table names in the database. */ - protected function findTableNames($schema = '') + public function findTableNames($schema = '') { $sql = "SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'"; return $this->db->createCommand($sql)->queryColumn();