Browse Source

Fixes #6876: Fixed RBAC migration MSSQL cascade problem

tags/3.0.0-alpha1
Adrian Liechti 9 years ago committed by Alexander Makarov
parent
commit
43ce4e9192
  1. 1
      framework/CHANGELOG.md
  2. 58
      framework/rbac/migrations/m140506_102106_rbac_init.php
  3. 41
      framework/rbac/migrations/schema-mssql.sql

1
framework/CHANGELOG.md

@ -6,6 +6,7 @@ Yii Framework 2 Change Log
- Bug #6351: Find MySQL FK constraints from `information_schema` tables instead of `SHOW CREATE TABLE` to improve reliability (nineinchnick)
- Bug #6363, #8301, #8582, #9566: Fixed data methods and PJAX issues when used together (derekisbusy)
- Bug #6876: Fixed RBAC migration MSSQL cascade problem (thejahweh)
- Bug #8723: Fixed `yii\helpers\VarDumper::export()` unable to export circle referenced objects with `Closure` (klimov-paul)
- Bug #9108: Negative number resulted in no formatting when using `Formatter::asSize()` or `Formatter::asShortSize` (nxnx, cebe)
- Bug #9288: Fixed `FileHelper::createDirectory` directory creation to be concurrency friendly (dynasource)

58
framework/rbac/migrations/m140506_102106_rbac_init.php

@ -30,6 +30,14 @@ class m140506_102106_rbac_init extends \yii\db\Migration
}
/**
* @return bool
*/
protected function isMSSQL()
{
return $this->db->driverName === 'mssql' || $this->db->driverName === 'sqlsrv' || $this->db->driverName === 'dblib';
}
/**
* @inheritdoc
*/
public function up()
@ -60,7 +68,8 @@ class m140506_102106_rbac_init extends \yii\db\Migration
'created_at' => $this->integer(),
'updated_at' => $this->integer(),
'PRIMARY KEY (name)',
'FOREIGN KEY (rule_name) REFERENCES ' . $authManager->ruleTable . ' (name) ON DELETE SET NULL ON UPDATE CASCADE',
'FOREIGN KEY (rule_name) REFERENCES ' . $authManager->ruleTable . ' (name)'.
($this->isMSSQL() ? '' : ' ON DELETE SET NULL ON UPDATE CASCADE'),
], $tableOptions);
$this->createIndex('idx-auth_item-type', $authManager->itemTable, 'type');
@ -68,8 +77,10 @@ class m140506_102106_rbac_init extends \yii\db\Migration
'parent' => $this->string(64)->notNull(),
'child' => $this->string(64)->notNull(),
'PRIMARY KEY (parent, child)',
'FOREIGN KEY (parent) REFERENCES ' . $authManager->itemTable . ' (name) ON DELETE CASCADE ON UPDATE CASCADE',
'FOREIGN KEY (child) REFERENCES ' . $authManager->itemTable . ' (name) ON DELETE CASCADE ON UPDATE CASCADE',
'FOREIGN KEY (parent) REFERENCES ' . $authManager->itemTable . ' (name)'.
($this->isMSSQL() ? '' : ' ON DELETE CASCADE ON UPDATE CASCADE'),
'FOREIGN KEY (child) REFERENCES ' . $authManager->itemTable . ' (name)'.
($this->isMSSQL() ? '' : ' ON DELETE CASCADE ON UPDATE CASCADE'),
], $tableOptions);
$this->createTable($authManager->assignmentTable, [
@ -79,6 +90,43 @@ class m140506_102106_rbac_init extends \yii\db\Migration
'PRIMARY KEY (item_name, user_id)',
'FOREIGN KEY (item_name) REFERENCES ' . $authManager->itemTable . ' (name) ON DELETE CASCADE ON UPDATE CASCADE',
], $tableOptions);
if($this->isMsSQL()) {
$this->execute("CREATE TRIGGER dbo.trigger_auth_item_child
ON dbo.{$authManager->itemTable}
INSTEAD OF DELETE, UPDATE
AS
DECLARE @old_name VARCHAR (64) = (SELECT name FROM deleted)
DECLARE @new_name VARCHAR (64) = (SELECT name FROM inserted)
BEGIN
IF COLUMNS_UPDATED() > 0
BEGIN
IF @old_name <> @new_name
BEGIN
ALTER TABLE auth_item_child NOCHECK CONSTRAINT FK__auth_item__child;
UPDATE auth_item_child SET child = @new_name WHERE child = @old_name;
END
UPDATE auth_item
SET name = (SELECT name FROM inserted),
type = (SELECT type FROM inserted),
description = (SELECT description FROM inserted),
rule_name = (SELECT rule_name FROM inserted),
data = (SELECT data FROM inserted),
created_at = (SELECT created_at FROM inserted),
updated_at = (SELECT updated_at FROM inserted)
WHERE name IN (SELECT name FROM deleted)
IF @old_name <> @new_name
BEGIN
ALTER TABLE auth_item_child CHECK CONSTRAINT FK__auth_item__child;
END
END
ELSE
BEGIN
DELETE FROM dbo.{$authManager->itemChildTable} WHERE parent IN (SELECT name FROM deleted) OR child IN (SELECT name FROM deleted);
DELETE FROM dbo.{$authManager->itemTable} WHERE name IN (SELECT name FROM deleted);
END
END;");
}
}
/**
@ -89,6 +137,10 @@ class m140506_102106_rbac_init extends \yii\db\Migration
$authManager = $this->getAuthManager();
$this->db = $authManager->db;
if($this->isMsSQL()) {
$this->execute('DROP dbo.trigger_auth_item_child;');
}
$this->dropTable($authManager->assignmentTable);
$this->dropTable($authManager->itemChildTable);
$this->dropTable($authManager->itemTable);

41
framework/rbac/migrations/schema-mssql.sql

@ -33,7 +33,7 @@ create table [auth_item]
[created_at] integer,
[updated_at] integer,
primary key ([name]),
foreign key ([rule_name]) references [auth_rule] ([name]) on delete set null on update cascade
foreign key ([rule_name]) references [auth_rule] ([name])
);
create index [idx-auth_item-type] on [auth_item] ([type]);
@ -43,8 +43,8 @@ create table [auth_item_child]
[parent] varchar(64) not null,
[child] varchar(64) not null,
primary key ([parent],[child]),
foreign key ([parent]) references [auth_item] ([name]) on delete cascade on update cascade,
foreign key ([child]) references [auth_item] ([name]) on delete cascade on update cascade
foreign key ([parent]) references [auth_item] ([name]),
foreign key ([child]) references [auth_item] ([name])
);
create table [auth_assignment]
@ -55,3 +55,38 @@ create table [auth_assignment]
primary key ([item_name], [user_id]),
foreign key ([item_name]) references [auth_item] ([name]) on delete cascade on update cascade
);
CREATE TRIGGER dbo.trigger_auth_item_child
ON dbo.[auth_item]
INSTEAD OF DELETE, UPDATE
AS
DECLARE @old_name VARCHAR (64) = (SELECT name FROM deleted)
DECLARE @new_name VARCHAR (64) = (SELECT name FROM inserted)
BEGIN
IF COLUMNS_UPDATED() > 0
BEGIN
IF @old_name <> @new_name
BEGIN
ALTER TABLE auth_item_child NOCHECK CONSTRAINT FK__auth_item__child;
UPDATE auth_item_child SET child = @new_name WHERE child = @old_name;
END
UPDATE auth_item
SET name = (SELECT name FROM inserted),
type = (SELECT type FROM inserted),
description = (SELECT description FROM inserted),
rule_name = (SELECT rule_name FROM inserted),
data = (SELECT data FROM inserted),
created_at = (SELECT created_at FROM inserted),
updated_at = (SELECT updated_at FROM inserted)
WHERE name IN (SELECT name FROM deleted)
IF @old_name <> @new_name
BEGIN
ALTER TABLE auth_item_child CHECK CONSTRAINT FK__auth_item__child;
END
END
ELSE
BEGIN
DELETE FROM dbo.[auth_item_child] WHERE parent IN (SELECT name FROM deleted) OR child IN (SELECT name FROM deleted);
DELETE FROM dbo.[auth_item] WHERE name IN (SELECT name FROM deleted);
END
END;
Loading…
Cancel
Save