ソースを参照

Joinless wrappers

euromark 11 年 前
コミット
00cff17512
2 ファイル変更120 行追加0 行削除
  1. 48 0
      Model/MyModel.php
  2. 72 0
      Test/Case/Model/MyModelTest.php

+ 48 - 0
Model/MyModel.php

@@ -380,6 +380,54 @@ class MyModel extends Model {
 	}
 
 	/**
+	 * Override default updateAll to workaround forced joins.
+	 *
+	 * This is a shim method to more easily migrate to 3.x as there
+	 * updateAll() does not allow joining anymore.
+	 *
+	 * @param array $fields Set of fields and values, indexed by fields.
+	 *   Fields are treated as SQL snippets, to insert literal values manually escape your data.
+	 * @param mixed $conditions Conditions to match, true for all records
+	 * @return bool True on success, false on failure
+	 */
+	public function updateAllJoinless($fields, $conditions = true) {
+		$name = $this->name;
+		$this->name = '_model_';
+
+		try {
+			$result = $this->updateAll($fields, $conditions);
+		} catch (Exception $e) {
+			$this->name = $name;
+			throw $e;
+		}
+
+		$this->name = $name;
+		return $result;
+	}
+
+	/**
+	 * Override default deleteAll to workaround forced joins
+	 *
+	 * This is a shim method to more easily migrate to 3.x as there
+	 * deleteAll() does not allow joining anymore.
+	 *
+	 * @param mixed $conditions Conditions to match
+	 * @param bool $cascade Set to true to delete records that depend on this record
+	 * @param bool $callbacks Run callbacks
+	 * @return bool True on success, false on failure
+	 */
+	public function deleteAllJoinless($conditions, $dependent = true, $callbacks = false) {
+		$associated = [];
+		foreach ($this->getAssociated() as $model => $type) {
+			$associated[$type][] = $model;
+		}
+
+		$this->unbindModel($associated);
+
+		return $this->deleteAll($conditions, $dependent, $callbacks);
+	}
+
+	/**
 	 * Enables HABTM-Validation
 	 * e.g. with
 	 * 'rule' => array('multiple', array('min' => 2))

+ 72 - 0
Test/Case/Model/MyModelTest.php

@@ -196,6 +196,78 @@ class MyModelTest extends MyCakeTestCase {
 	}
 
 	/**
+	 * MyModelTest::testUpdateAllJoinless()
+	 *
+	 * @return void
+	 */
+	public function testUpdateAllJoinless() {
+		$db = ConnectionManager::getDataSource($this->Post->useDbConfig);
+		$db->getLog();
+		$postTable = $db->fullTableName($this->Post->table);
+		$authorTable = $db->fullTableName($this->Post->Author->table);
+
+		$result = $this->Post->updateAll(array('title' => '"Foo"'), array('title !=' => 'Foo'));
+		$this->assertTrue($result);
+
+		$queries = $db->getLog();
+		$expected = 'UPDATE ' . $postTable . ' AS `Post` LEFT JOIN ' . $authorTable . ' AS `Author` ON (`Post`.`author_id` = `Author`.`id`) SET `Post`.`title` = "Foo"  WHERE `title` != \'Foo\'';
+		$this->assertSame($expected, $queries['log'][0]['query']);
+
+		// Now joinless
+		$result = $this->Post->updateAllJoinless(array('title' => '"Foo"'), array('title !=' => 'Foo'));
+		$this->assertTrue($result);
+
+		$queries = $db->getLog();
+		$expected = 'UPDATE ' . $postTable . ' AS `Post`  SET `Post`.`title` = "Foo"  WHERE `title` != \'Foo\'';
+		$this->assertSame($expected, $queries['log'][0]['query']);
+	}
+
+	/**
+	 * MyModelTest::testDeleteAll()
+	 *
+	 * @return void
+	 */
+	public function testDeleteAll() {
+		$db = ConnectionManager::getDataSource($this->Post->useDbConfig);
+		$db->getLog();
+		$postTable = $db->fullTableName($this->Post->table);
+		$authorTable = $db->fullTableName($this->Post->Author->table);
+
+		$result = $this->Post->deleteAll(array('title !=' => 'Foo'));
+		$this->assertTrue($result);
+
+		$queries = $db->getLog();
+		$expected = 'SELECT `Post`.`id` FROM ' . $postTable . ' AS `Post` LEFT JOIN ' . $authorTable . ' AS `Author` ON (`Post`.`author_id` = `Author`.`id`)  WHERE `title` != \'Foo\'  GROUP BY `Post`.`id`';
+		$this->assertSame($expected, $queries['log'][0]['query']);
+
+		$expected = 'DELETE `Post` FROM ' . $postTable . ' AS `Post`   WHERE `Post`.`id` IN';
+		$this->assertContains($expected, $queries['log'][1]['query']);
+	}
+
+	/**
+	 * MyModelTest::testDeleteAllJoinless()
+	 *
+	 * @return void
+	 */
+	public function testDeleteAllJoinless() {
+		// Now joinless
+		$db = ConnectionManager::getDataSource($this->Post->useDbConfig);
+		$db->getLog();
+		$postTable = $db->fullTableName($this->Post->table);
+		$authorTable = $db->fullTableName($this->Post->Author->table);
+
+		$result = $this->Post->deleteAllJoinless(array('title !=' => 'Foo'));
+		$this->assertTrue($result);
+
+		$queries = $db->getLog();
+		$expected = 'SELECT `Post`.`id` FROM ' . $postTable . ' AS `Post`   WHERE `title` != \'Foo\'  GROUP BY `Post`.`id`';
+		$this->assertSame($expected, $queries['log'][0]['query']);
+
+		$expected = 'DELETE `Post` FROM ' . $postTable . ' AS `Post`   WHERE `Post`.`id` IN';
+		$this->assertContains($expected, $queries['log'][1]['query']);
+	}
+
+	/**
 	 * Test deleteAllRaw()
 	 *
 	 * @return void