Skip to content

Commit

Permalink
Merge pull request phalcon#11971 from basilfx/2.1.x
Browse files Browse the repository at this point in the history
Uniqueness validator with NULL values
  • Loading branch information
andresgutierrez authored Jul 13, 2016
2 parents 755d651 + 6f2b7c8 commit 18eaefc
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
- Fixed `Phalcon\Validation::appendMessage` to allow append message to the empty stack [#10405](https://github.com/phalcon/cphalcon/issues/10405)
- Fixed `Phalcon\Session\Flash::getMessages`. Now it returns an empty array in case of non existent message type request [#11941](https://github.com/phalcon/cphalcon/issues/11941)
- Amended `Phalcon\Mvc\RouterInterface` and `Phalcon\Mvc\Router`. Added missed `addPurge`, `addTrace` and `addConnect` methods
- Fixed incorrect query when using NULL fields with `Phalcon\Validation\Validator\Uniqueness`

# [2.0.13](https://github.com/phalcon/cphalcon/releases/tag/phalcon-v2.0.13) (2016-05-19)
- Restored `Phalcon\Text::camelize` behavior [#11767](https://github.com/phalcon/cphalcon/issues/11767)
Expand Down
11 changes: 8 additions & 3 deletions phalcon/validation/validator/uniqueness.zep
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,14 @@ class Uniqueness extends CombinedFieldsValidator
let attribute = this->getColumnNameReal(record, this->getOption("attribute", singleField)),
except = this->getOption("except");

let params["conditions"][] = attribute . " = ?" . index;
let params["bind"][] = value;
let index++;
if value != null {
let params["conditions"][] = attribute . " = ?" . index;
let params["bind"][] = value;
let index++;
}
else {
let params["conditions"][] = attribute . " IS NULL";
}

if except {
if typeof except == "array" && count(field) > 1 {
Expand Down
7 changes: 4 additions & 3 deletions tests/_data/schemas/mysql/mysql.dump.sql
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ CREATE TABLE `robots` (
`type` varchar(32) COLLATE utf8_unicode_ci NOT NULL default 'mechanical',
`year` int(11) NOT NULL default 1900,
`datetime` datetime NOT NULL,
`deleted` datetime DEFAULT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Expand All @@ -283,9 +284,9 @@ CREATE TABLE `robots` (

LOCK TABLES `robots` WRITE;
/*!40000 ALTER TABLE `robots` DISABLE KEYS */;
INSERT INTO `robots` VALUES (1,'Robotina','mechanical',1972,'1972/01/01 00:00:00','text'),
(2,'Astro Boy','mechanical',1952,'1952/01/01 00:00:00','text'),
(3,'Terminator','cyborg',2029,'2029/01/01 00:00:00','text');
INSERT INTO `robots` VALUES (1,'Robotina','mechanical',1972,'1972/01/01 00:00:00', null, 'text'),
(2,'Astro Boy','mechanical',1952,'1952/01/01 00:00:00', null, 'text'),
(3,'Terminator','cyborg',2029,'2029/01/01 00:00:00', null, 'text');
/*!40000 ALTER TABLE `robots` ENABLE KEYS */;
UNLOCK TABLES;

Expand Down
2 changes: 1 addition & 1 deletion tests/_data/schemas/postgresql/phalcon_test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ CREATE TABLE robots (
type character varying(32) DEFAULT 'mechanical'::character varying NOT NULL,
year integer DEFAULT 1900 NOT NULL,
datetime timestamp NOT NULL,
deleted timestamp DEFAULT NULL,
text text NOT NULL
);

Expand Down Expand Up @@ -6921,4 +6922,3 @@ GRANT ALL ON SCHEMA public TO PUBLIC;
--
-- PostgreSQL database dump complete
--

9 changes: 5 additions & 4 deletions tests/_data/schemas/sqlite/phalcon_test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4464,11 +4464,12 @@ CREATE TABLE `robots` (
`type` varchar(32) NOT NULL default 'mechanical',
`year` int(11) NOT NULL default 1900,
`datetime` datetime NOT NULL,
`deleted` datetime default NULL,
`text` text NOT NULL
);
INSERT INTO "robots" VALUES(1,'Robotina','mechanical',1972,'1972/01/01 00:00:00','text');
INSERT INTO "robots" VALUES(2,'Astro Boy','mechanical',1952,'1952/01/01 00:00:00','text');
INSERT INTO "robots" VALUES(3,'Terminator','cyborg',2029,'2029/01/01 00:00:00','text');
INSERT INTO "robots" VALUES(1,'Robotina','mechanical',1972,'1972/01/01 00:00:00',NULL,'text');
INSERT INTO "robots" VALUES(2,'Astro Boy','mechanical',1952,'1952/01/01 00:00:00',NULL,'text');
INSERT INTO "robots" VALUES(3,'Terminator','cyborg',2029,'2029/01/01 00:00:00',NULL,'text');
CREATE TABLE `robots_parts` (
`id` INTEGER NOT NULL PRIMARY KEY,
`robots_id` int(10) NOT NULL,
Expand Down Expand Up @@ -6511,4 +6512,4 @@ CREATE TABLE COMPANY (
CREATE INDEX salary_index ON COMPANY (salary);
CREATE UNIQUE INDEX name_index ON COMPANY (name);

COMMIT;
COMMIT;
13 changes: 9 additions & 4 deletions tests/_fixtures/metadata/robots.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
2 => 'type',
3 => 'year',
4 => 'datetime',
5 => 'text',
5 => 'deleted',
6 => 'text',
],
1 => [
0 => 'id',
Expand All @@ -33,7 +34,8 @@
1 => 'type',
2 => 'year',
3 => 'datetime',
4 => 'text',
4 => 'deleted',
5 => 'text',
],
3 => [
0 => 'id',
Expand All @@ -49,6 +51,7 @@
'type' => 2,
'year' => 0,
'datetime' => 4,
'deleted' => 4,
'text' => 6,
],
5 => [
Expand All @@ -62,13 +65,15 @@
'type' => 2,
'year' => 1,
'datetime' => 2,
'deleted' => 2,
'text' => 2,
],
10 => [],
11 => [],
12 => [
'type' => 'mechanical',
'year' => 1900,
'type' => 'mechanical',
'year' => 1900,
'deleted' => null,
],
13 => [],
],
Expand Down
56 changes: 56 additions & 0 deletions tests/unit/Validation/Validator/UniquenessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* @author Andres Gutierrez <andres@phalconphp.com>
* @author Nikolaos Dimopoulos <nikos@phalconphp.com>
* @author Wojciech Ślawski <jurigag@gmail.com>
* @author Bas Stottelaar <basstottelaar@gmail.com>
* @package Phalcon\Test\Unit\Validation\Validator
*
* The contents of this file are subject to the New BSD License that is
Expand All @@ -45,6 +46,11 @@ class UniquenessTest extends UnitTest
*/
protected $anotherRobot;

/**
* @var Robots
*/
protected $deletedRobot;

/**
* Tests uniqueness validator with single fields
*
Expand All @@ -63,6 +69,26 @@ public function testSingleField()
});
}

/**
* Tests uniqueness validator with single field and a null value
*
* @author Bas Stottelaar <basstottelaar@gmail.com>
* @since 2016-07-13
*/
public function testSingleFieldWithNull()
{
$this->specify('Test uniqueness with single field and a null value.', function () {
$validation = new Validation();
$validation->add('deleted', new Uniqueness());
$messages = $validation->validate(null, $this->robot);
expect($messages->count())->equals(1);
$messages = $validation->validate(null, $this->anotherRobot);
expect($messages->count())->equals(1);
$messages = $validation->validate(null, $this->deletedRobot);
expect($messages->count())->equals(0);
});
}

/**
* Tests uniqueness validator with multiple fields
*
Expand All @@ -81,6 +107,26 @@ public function testMultipleFields()
});
}

/**
* Tests uniqueness validator with multiple fields and a null value
*
* @author Bas Stottelaar <basstottelaar@gmail.com>
* @since 2016-07-13
*/
public function testMultipleFieldsWithNull()
{
$this->specify('Test uniqueness with combination of fields and a null value.', function () {
$validation = new Validation();
$validation->add(['type','deleted'], new Uniqueness());
$messages = $validation->validate(null, $this->robot);
expect($messages->count())->equals(1);
$messages = $validation->validate(null, $this->anotherRobot);
expect($messages->count())->equals(0);
$messages = $validation->validate(null, $this->deletedRobot);
expect($messages->count())->equals(0);
});
}

/**
* Tests uniqueness validator with single field and except
*
Expand Down Expand Up @@ -179,13 +225,23 @@ protected function _before()
'type' => 'mechanical',
'year' => 1972,
'datetime' => (new DateTime())->format('Y-m-d H:i:s'),
'deleted' => null,
'text' => 'text',
]);
$this->anotherRobot = new Robots([
'name' => 'Robotina',
'type' => 'hydraulic',
'year' => 1952,
'datetime' => (new DateTime())->format('Y-m-d H:i:s'),
'deleted' => null,
'text' => 'text',
]);
$this->deletedRobot = new Robots([
'name' => 'Robotina',
'type' => 'mechanical',
'year' => 1972,
'datetime' => (new DateTime())->format('Y-m-d H:i:s'),
'deleted' => (new DateTime())->format('Y-m-d H:i:s'),
'text' => 'text',
]);
}
Expand Down
6 changes: 3 additions & 3 deletions unit-tests/ModelsHydrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ protected function _executeTestsNormal($di)
$robots->setHydrateMode(Phalcon\Mvc\Model\Resultset::HYDRATE_ARRAYS);
foreach ($robots as $robot) {
$this->assertTrue(is_array($robot));
$this->assertEquals(6, count($robot));
$this->assertEquals(7, count($robot));
$number++;
}

Expand Down Expand Up @@ -209,7 +209,7 @@ protected function _executeTestsRenamed($di)
$robots->setHydrateMode(Phalcon\Mvc\Model\Resultset::HYDRATE_ARRAYS);
foreach ($robots as $robot) {
$this->assertTrue(is_array($robot));
$this->assertEquals(count($robot), 6);
$this->assertEquals(count($robot), 7);
$number++;
}

Expand Down Expand Up @@ -312,7 +312,7 @@ protected function _executeTestsNormalComplex($di)
$this->assertTrue(is_array($row));
$this->assertTrue(is_numeric($row['id']));
$this->assertEquals(gettype($row['robots']), 'array');
$this->assertEquals(count($row['robots']), 6);
$this->assertEquals(count($row['robots']), 7);
$this->assertEquals(gettype($row['robotsParts']), 'array');
$this->assertEquals(count($row['robotsParts']), 3);
}
Expand Down
13 changes: 9 additions & 4 deletions unit-tests/ModelsMetadataStrategyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class ModelsMetadataStrategyTest extends PHPUnit_Framework_TestCase
2 => 'type',
3 => 'year',
4 => 'datetime',
5 => 'text',
5 => 'deleted',
6 => 'text',
),
1 => array(
0 => 'id',
Expand All @@ -38,22 +39,24 @@ class ModelsMetadataStrategyTest extends PHPUnit_Framework_TestCase
1 => 'type',
2 => 'year',
3 => 'datetime',
4 => 'text',
4 => 'deleted',
5 => 'text'
),
3 => array(
0 => 'id',
1 => 'name',
2 => 'type',
3 => 'year',
4 => 'datetime',
5 => 'text',
5 => 'text'
),
4 => array(
'id' => 0,
'name' => 2,
'type' => 2,
'year' => 0,
'datetime' => 4,
'deleted' => 4,
'text' => 6
),
5 => array(
Expand All @@ -67,13 +70,15 @@ class ModelsMetadataStrategyTest extends PHPUnit_Framework_TestCase
'type' => 2,
'year' => 1,
'datetime' => 2,
'deleted' => 2,
'text' => 2
),
10 => array(),
11 => array(),
12 => array(
'type' => 'mechanical',
'year' => 1900
'year' => 1900,
'deleted' => null
),
13 => array()
);
Expand Down
11 changes: 7 additions & 4 deletions unit-tests/ModelsMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ protected function _executeTests($di)
2 => 'type',
3 => 'year',
4 => 'datetime',
5 => 'text'
5 => 'deleted',
6 => 'text'
);

$attributes = $metaData->getAttributes($robots);
Expand All @@ -249,7 +250,8 @@ protected function _executeTests($di)
1 => 'type',
2 => 'year',
3 => 'datetime',
4 => 'text'
4 => 'deleted',
5 => 'text'
);

$npkAttributes = $metaData->getNonPrimaryKeyAttributes($robots);
Expand All @@ -258,8 +260,9 @@ protected function _executeTests($di)
$this->assertEquals($metaData->getIdentityField($robots), 'id');

$defValues = array(
'type' => 'mechanical',
'year' => 1900
'type' => 'mechanical',
'year' => 1900,
'deleted' => null
);

$modelDefValues = $metaData->getDefaultValues($robots);
Expand Down
6 changes: 6 additions & 0 deletions unit-tests/ModelsSnapshotsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ protected function _executeTestsNormal($di)
'type' => 'mechanical',
'year' => '1972',
'datetime' => '1972-01-01 00:00:00',
'deleted' => null,
'text' => 'text'
),
2 => array(
Expand All @@ -95,6 +96,7 @@ protected function _executeTestsNormal($di)
'type' => 'mechanical',
'year' => '1952',
'datetime' => '1952-01-01 00:00:00',
'deleted' => null,
'text' => 'text'
),
3 => array(
Expand All @@ -103,6 +105,7 @@ protected function _executeTestsNormal($di)
'type' => 'cyborg',
'year' => '2029',
'datetime' => '2029-01-01 00:00:00',
'deleted' => null,
'text' => 'text'
)
);
Expand Down Expand Up @@ -143,6 +146,7 @@ protected function _executeTestsRenamed($di)
'theType' => 'mechanical',
'theYear' => '1972',
'theDatetime' => '1972-01-01 00:00:00',
'theDeleted' => null,
'theText' => 'text',
),
2 => array(
Expand All @@ -151,6 +155,7 @@ protected function _executeTestsRenamed($di)
'theType' => 'mechanical',
'theYear' => '1952',
'theDatetime' => '1952-01-01 00:00:00',
'theDeleted' => null,
'theText' => 'text',
),
3 => array(
Expand All @@ -159,6 +164,7 @@ protected function _executeTestsRenamed($di)
'theType' => 'cyborg',
'theYear' => '2029',
'theDatetime' => '2029-01-01 00:00:00',
'theDeleted' => null,
'theText' => 'text',
)
);
Expand Down
5 changes: 5 additions & 0 deletions unit-tests/models/Boutique/Robots.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class Robots extends \Phalcon\Mvc\Model
*/
public $datetime;

/**
* @Column(type="datetime", nullable=true)
*/
public $deleted;

/**
* @Column(type="text", nullable=false)
*/
Expand Down
Loading

0 comments on commit 18eaefc

Please sign in to comment.