Skip to content
This repository
Browse code

Adding tests from 'Stephen Cuppert' to test incorrectly generate DELE…

…TE queries for habtm join tables that do not have a primary key when using PostgreSQL. Updating DboSource::_matchRecords() to only query the table if the supplied conditions are actually multi-table conditions. Fixes #459
  • Loading branch information...
commit ea64588a814b09565b82c428845f7a096814c327 1 parent 190066f
Mark Story authored March 15, 2010
16  cake/libs/model/datasources/dbo_source.php
@@ -1477,6 +1477,22 @@ function _matchRecords(&$model, $conditions = null) {
1477 1477
 		} elseif ($conditions === null) {
1478 1478
 			$conditions = $this->conditions($this->defaultConditions($model, $conditions, false), true, true, $model);
1479 1479
 		} else {
  1480
+			$noJoin = true;
  1481
+			foreach ($conditions as $field => $value) {
  1482
+				$originalField = $field;
  1483
+				if (strpos($field, '.') !== false) {
  1484
+					list($alias, $field) = explode('.', $field);
  1485
+				}
  1486
+				if (!$model->hasField($field)) {
  1487
+					$noJoin = false;
  1488
+					break;
  1489
+				}
  1490
+				$conditions[$field] = $value;
  1491
+				unset($conditions[$originalField]);
  1492
+			}
  1493
+			if ($noJoin === true) {
  1494
+				return $this->conditions($conditions);
  1495
+			}
1480 1496
 			$idList = $model->find('all', array(
1481 1497
 				'fields' => "{$model->alias}.{$model->primaryKey}",
1482 1498
 				'conditions' => $conditions
55  cake/tests/cases/libs/model/model_delete.test.php
@@ -580,6 +580,61 @@ function testBeforeDeleteDeleteAbortion() {
580 580
 		$exists = $Model->findById(1);
581 581
 		$this->assertTrue(is_array($exists));
582 582
 	}
  583
+/**
  584
+ * test for a habtm deletion error that occurs in postgres but should not.
  585
+ * And should not occur in any dbo.
  586
+ *
  587
+ * @return void
  588
+ */
  589
+	function testDeleteHabtmPostgresFailure() {
  590
+		$this->loadFixtures('Article', 'Tag', 'ArticlesTag');
  591
+
  592
+		$Article =& ClassRegistry::init('Article');
  593
+		$Article->hasAndBelongsToMany['Tag']['unique'] = true;
  594
+
  595
+		$Tag =& ClassRegistry::init('Tag');
  596
+		$Tag->bindModel(array('hasAndBelongsToMany' => array(
  597
+			'Article' => array(
  598
+				'className' => 'Article',
  599
+				'unique' => true
  600
+			)
  601
+		)), true);
  602
+
  603
+		// Article 1 should have Tag.1 and Tag.2
  604
+	    $before = $Article->find("all", array(
  605
+			"conditions" => array("Article.id" => 1),
  606
+		));
  607
+		$this->assertEqual(count($before[0]['Tag']), 2, 'Tag count for Article.id = 1 is incorrect, should be 2 %s');
  608
+
  609
+		// From now on, Tag #1 is only associated with Post #1
  610
+		$submitted_data = array(
  611
+			"Tag" => array("id" => 1, 'tag' => 'tag1'),
  612
+			"Article" => array(
  613
+				"Article" => array(1)
  614
+			)
  615
+		);
  616
+		$Tag->save($submitted_data);
  617
+
  618
+	    // One more submission (The other way around) to make sure the reverse save looks good.
  619
+	    $submitted_data = array(
  620
+			"Article" => array("id" => 2, 'title' => 'second article'),
  621
+			"Tag" => array(
  622
+				"Tag" => array(2, 3)
  623
+			)
  624
+		);
  625
+	    // ERROR:
  626
+	    // Postgresql: DELETE FROM "articles_tags" WHERE tag_id IN ('1', '3')
  627
+	    // MySQL: DELETE `ArticlesTag` FROM `articles_tags` AS `ArticlesTag` WHERE `ArticlesTag`.`article_id` = 2 AND `ArticlesTag`.`tag_id` IN (1, 3)
  628
+	    $Article->save($submitted_data);
  629
+
  630
+		// Want to make sure Article #1 has Tag #1 and Tag #2 still.
  631
+		$after = $Article->find("all", array(
  632
+			"conditions" => array("Article.id" => 1),
  633
+		));
  634
+
  635
+		// Removing Article #2 from Tag #1 is all that should have happened.
  636
+		$this->assertEqual(count($before[0]["Tag"]), count($after[0]["Tag"]));
  637
+	}
583 638
 }
584 639
 
585 640
 ?>

0 notes on commit ea64588

Please sign in to comment.
Something went wrong with that request. Please try again.