mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-15 23:04:54 +08:00
Fixed yii\db\ActiveRecord
does not updates attribute specified at optimisticLock()
after save
This commit is contained in:
@ -11,6 +11,7 @@ Yii Framework 2 Change Log
|
||||
- Bug #8451: `yii\i18n\Formatter` did not allow negative unix timestamps as input for date formatting (cebe)
|
||||
- Bug #8483: sequence name in `Schema::getLastInsertId()` was not properly quoted (nineinchnick)
|
||||
- Bug #8506: Cleaning of output buffer in `Widget::run()` conflicts with `Pjax` widget which did the cleanup itself (cebe, joester89)
|
||||
- Bug #8544: Fixed `yii\db\ActiveRecord` does not updates attribute specified at `optimisticLock()` after save (klimov-paul)
|
||||
- Bug: Fixed string comparison in `BaseActiveRecord::unlink()` which may result in wrong comparison result for hash valued primary keys starting with `0e` (cebe)
|
||||
- Enh #7169: `yii\widgets\ActiveField` now uses corresponding methods for default parts rendering (klimov-paul)
|
||||
- Enh #8070: `yii\console\controllers\MessageController` now sorts created messages, even if there is no new one, while saving to PHP file (klimov-paul)
|
||||
|
@ -725,6 +725,9 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
||||
foreach ($values as $name => $value) {
|
||||
$changedAttributes[$name] = isset($this->_oldAttributes[$name]) ? $this->_oldAttributes[$name] : null;
|
||||
$this->_oldAttributes[$name] = $value;
|
||||
if ($name === $lock) {
|
||||
$this->$lock = $value;
|
||||
}
|
||||
}
|
||||
$this->afterSave(false, $changedAttributes);
|
||||
|
||||
|
17
tests/data/ar/Document.php
Normal file
17
tests/data/ar/Document.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace yiiunit\data\ar;
|
||||
|
||||
/**
|
||||
* @property integer $id
|
||||
* @property string $title
|
||||
* @property string $content
|
||||
* @property integer $version
|
||||
*/
|
||||
class Document extends ActiveRecord
|
||||
{
|
||||
public function optimisticLock()
|
||||
{
|
||||
return 'version';
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ DROP TABLE IF EXISTS "type";
|
||||
DROP TABLE IF EXISTS "constraints";
|
||||
DROP TABLE IF EXISTS "animal";
|
||||
DROP TABLE IF EXISTS "default_pk";
|
||||
DROP TABLE IF EXISTS "document";
|
||||
DROP VIEW IF EXISTS "animal_view";
|
||||
|
||||
CREATE TABLE "constraints"
|
||||
@ -139,6 +140,14 @@ CREATE TABLE "default_pk" (
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "document" (
|
||||
"id" int(11) NOT NULL AUTO_INCREMENT,
|
||||
"title" varchar(255) NOT NULL,
|
||||
"content" string,
|
||||
"version" int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE VIEW "animal_view" AS SELECT * FROM "animal";
|
||||
|
||||
INSERT INTO "animal" ("type") VALUES ('yiiunit\data\ar\Cat');
|
||||
@ -181,3 +190,5 @@ INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VA
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0);
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO "document" (title, content, version) VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
@ -10,6 +10,7 @@ IF OBJECT_ID('[dbo].[type]', 'U') IS NOT NULL DROP TABLE [dbo].[type];
|
||||
IF OBJECT_ID('[dbo].[null_values]', 'U') IS NOT NULL DROP TABLE [dbo].[null_values];
|
||||
IF OBJECT_ID('[dbo].[animal]', 'U') IS NOT NULL DROP TABLE [dbo].[animal];
|
||||
IF OBJECT_ID('[dbo].[default_pk]', 'U') IS NOT NULL DROP TABLE [dbo].[default_pk];
|
||||
IF OBJECT_ID('[dbo].[document]', 'U') IS NOT NULL DROP TABLE [dbo].[document];
|
||||
IF OBJECT_ID('[dbo].[animal_view]', 'V') IS NOT NULL DROP VIEW [dbo].[animal_view];
|
||||
|
||||
CREATE TABLE [dbo].[profile] (
|
||||
@ -124,6 +125,16 @@ CREATE TABLE [dbo].[default_pk] (
|
||||
) ON [PRIMARY]
|
||||
);
|
||||
|
||||
CREATE TABLE [dbo].[document] (
|
||||
[id] [int] IDENTITY(1,1) NOT NULL,
|
||||
[title] [varchar](255) NOT NULL,
|
||||
[content] [text],
|
||||
[version] [int] NOT NULL DEFAULT 0,
|
||||
CONSTRAINT [PK_default_pk] PRIMARY KEY CLUSTERED (
|
||||
[id] ASC
|
||||
) ON [PRIMARY]
|
||||
);
|
||||
|
||||
CREATE VIEW [dbo].[animal_view] AS SELECT * FROM [dbo].[animal];
|
||||
|
||||
INSERT INTO [dbo].[animal] (type) VALUES ('yiiunit\data\ar\Cat');
|
||||
@ -166,3 +177,5 @@ INSERT INTO [dbo].[order_item_with_null_fk] ([order_id], [item_id], [quantity],
|
||||
INSERT INTO [dbo].[order_item_with_null_fk] ([order_id], [item_id], [quantity], [subtotal]) VALUES (2, 5, 1, 15.0);
|
||||
INSERT INTO [dbo].[order_item_with_null_fk] ([order_id], [item_id], [quantity], [subtotal]) VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO [dbo].[order_item_with_null_fk] ([order_id], [item_id], [quantity], [subtotal]) VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO [dbo].[document] ([title], [content], [version]) VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
@ -17,6 +17,7 @@ DROP TABLE IF EXISTS `type` CASCADE;
|
||||
DROP TABLE IF EXISTS `constraints` CASCADE;
|
||||
DROP TABLE IF EXISTS `animal` CASCADE;
|
||||
DROP TABLE IF EXISTS `default_pk` CASCADE;
|
||||
DROP TABLE IF EXISTS `document` CASCADE;
|
||||
DROP VIEW IF EXISTS `animal_view`;
|
||||
|
||||
CREATE TABLE `constraints`
|
||||
@ -141,6 +142,14 @@ CREATE TABLE `default_pk` (
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `document` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`content` TEXT,
|
||||
`version` INT(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE VIEW `animal_view` AS SELECT * FROM `animal`;
|
||||
|
||||
INSERT INTO `animal` (`type`) VALUES ('yiiunit\data\ar\Cat');
|
||||
@ -184,6 +193,8 @@ INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VA
|
||||
INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO `document` (title, content, version) VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
||||
|
||||
/**
|
||||
* (MySQL-)Database Schema for validator tests
|
||||
|
@ -19,6 +19,7 @@ BEGIN EXECUTE IMMEDIATE 'DROP TABLE "constraints"'; EXCEPTION WHEN OTHERS THEN I
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "bool_values"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "animal"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "default_pk"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "document"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP VIEW "animal_view"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "validator_main"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP TABLE "validator_ref"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;--
|
||||
@ -32,6 +33,7 @@ BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE "order_with_null_fk_SEQ"'; EXCEPTION WHEN
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE "null_values_SEQ"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -2289 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE "bool_values_SEQ"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -2289 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE "animal_SEQ"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -2289 THEN RAISE; END IF; END;--
|
||||
BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE "document_SEQ"'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -2289 THEN RAISE; END IF; END;--
|
||||
|
||||
/* STATEMENTS */
|
||||
|
||||
@ -171,6 +173,15 @@ CREATE TABLE "default_pk" (
|
||||
CONSTRAINT "default_pk_PK" PRIMARY KEY ("id") ENABLE
|
||||
);
|
||||
|
||||
CREATE TABLE "document" (
|
||||
"id" integer,
|
||||
"title" varchar2(255) not null,
|
||||
"content" varchar(4000),
|
||||
"version" integer default 0 not null,
|
||||
CONSTRAINT "document_PK" PRIMARY KEY ("id") ENABLE
|
||||
);
|
||||
CREATE SEQUENCE "document_SEQ";
|
||||
|
||||
CREATE VIEW "animal_view" AS SELECT * FROM "animal";
|
||||
|
||||
/**
|
||||
@ -282,6 +293,8 @@ INSERT INTO "order_item_with_null_fk" ("order_id", "item_id", "quantity", "subto
|
||||
INSERT INTO "order_item_with_null_fk" ("order_id", "item_id", "quantity", "subtotal") VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO "order_item_with_null_fk" ("order_id", "item_id", "quantity", "subtotal") VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO "document" ("title", "content", "version") VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
||||
INSERT INTO "validator_main" ("id", "field1") VALUES (1, 'just a string1');
|
||||
INSERT INTO "validator_main" ("id", "field1") VALUES (2, 'just a string2');
|
||||
INSERT INTO "validator_main" ("id", "field1") VALUES (3, 'just a string3');
|
||||
|
@ -19,6 +19,7 @@ DROP TABLE IF EXISTS "constraints" CASCADE;
|
||||
DROP TABLE IF EXISTS "bool_values" CASCADE;
|
||||
DROP TABLE IF EXISTS "animal" CASCADE;
|
||||
DROP TABLE IF EXISTS "default_pk" CASCADE;
|
||||
DROP TABLE IF EXISTS "document" CASCADE;
|
||||
DROP VIEW IF EXISTS "animal_view";
|
||||
DROP SCHEMA IF EXISTS "schema1" CASCADE;
|
||||
DROP SCHEMA IF EXISTS "schema2" CASCADE;
|
||||
@ -136,7 +137,6 @@ CREATE TABLE "bool_values" (
|
||||
default_false boolean not null default false
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "animal" (
|
||||
id serial primary key,
|
||||
type varchar(255) not null
|
||||
@ -147,6 +147,13 @@ CREATE TABLE "default_pk" (
|
||||
type varchar(255) not null
|
||||
);
|
||||
|
||||
CREATE TABLE "animal" (
|
||||
id serial primary key,
|
||||
title varchar(255) not null,
|
||||
content text not null,
|
||||
version integer not null default 0
|
||||
);
|
||||
|
||||
CREATE VIEW "animal_view" AS SELECT * FROM "animal";
|
||||
|
||||
INSERT INTO "animal" (type) VALUES ('yiiunit\data\ar\Cat');
|
||||
@ -194,6 +201,8 @@ INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VA
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO "document" (title, content, version) VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
||||
/**
|
||||
* (Postgres-)Database Schema for validator tests
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@ DROP TABLE IF EXISTS "type";
|
||||
DROP TABLE IF EXISTS "null_values";
|
||||
DROP TABLE IF EXISTS "animal";
|
||||
DROP TABLE IF EXISTS "default_pk";
|
||||
DROP TABLE IF EXISTS "document";
|
||||
DROP VIEW IF EXISTS "animal_view";
|
||||
|
||||
CREATE TABLE "profile" (
|
||||
@ -123,6 +124,14 @@ CREATE TABLE "default_pk" (
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE "document" (
|
||||
id INTEGER NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
content text,
|
||||
version INTEGER NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE VIEW "animal_view" AS SELECT * FROM "animal";
|
||||
|
||||
INSERT INTO "animal" ("type") VALUES ('yiiunit\data\ar\Cat');
|
||||
@ -166,6 +175,8 @@ INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VA
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0);
|
||||
INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0);
|
||||
|
||||
INSERT INTO "document" (title, content, version) VALUES ('Yii 2.0 guide', 'This is Yii 2.0 guide', 0);
|
||||
|
||||
/**
|
||||
* (SqLite-)Database Schema for validator tests
|
||||
*/
|
||||
|
@ -4,6 +4,7 @@ namespace yiiunit\framework\db;
|
||||
use yiiunit\data\ar\ActiveRecord;
|
||||
use yiiunit\data\ar\Category;
|
||||
use yiiunit\data\ar\Customer;
|
||||
use yiiunit\data\ar\Document;
|
||||
use yiiunit\data\ar\NullValues;
|
||||
use yiiunit\data\ar\OrderItem;
|
||||
use yiiunit\data\ar\Order;
|
||||
@ -706,4 +707,20 @@ class ActiveRecordTest extends DatabaseTestCase
|
||||
$this->assertTrue($record->save(false));
|
||||
$this->assertEquals(1, $record->id);
|
||||
}
|
||||
|
||||
public function testOptimisticLock()
|
||||
{
|
||||
/* @var $record Document */
|
||||
|
||||
$record = Document::findOne(1);
|
||||
$record->content = 'New Content';
|
||||
$record->save(false);
|
||||
$this->assertEquals(1, $record->version);
|
||||
|
||||
$record = Document::findOne(1);
|
||||
$record->content = 'Rewrite attempt content';
|
||||
$record->version = 0;
|
||||
$this->setExpectedException('yii\db\StaleObjectException');
|
||||
$record->save(false);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user