Browse Source

Insert data in a different transaction than schema.

Postgres will puke if you try to alter schema and update rows in the
same transaction. While this makes the tests a bit slower, it is
necessary to have foreign key fixtures work with postgres.
mark_story 11 years ago
parent
commit
e4dedd7597

+ 14 - 0
src/Database/Schema/PostgresSchema.php

@@ -475,4 +475,18 @@ class PostgresSchema extends BaseSchema {
 		];
 	}
 
+/**
+ * Generate the SQL to drop a table.
+ *
+ * @param \Cake\Database\Schema\Table $table Table instance
+ * @return array SQL statements to drop a table.
+ */
+	public function dropTableSql(Table $table) {
+		$sql = sprintf(
+			'DROP TABLE %s CASCADE',
+			$this->_driver->quoteIdentifier($table->name())
+		);
+		return [$sql];
+	}
+
 }

+ 12 - 3
src/TestSuite/Fixture/FixtureManager.php

@@ -234,10 +234,17 @@ class FixtureManager {
 					if (!$test->dropTables) {
 						$fixture->truncate($db);
 					}
-					$fixture->insert($db);
 				}
 			};
 			$this->_runOperation($fixtures, $createTables);
+
+			// Use a separate transaction because of postgres.
+			$insert = function($db, $fixtures) {
+				foreach ($fixtures as $fixture) {
+					$fixture->insert($db);
+				}
+			};
+			$this->_runOperation($fixtures, $insert);
 		} catch (\PDOException $e) {
 			$msg = sprintf('Unable to insert fixtures for "%s" test case. %s', get_class($test), $e->getMessage());
 			throw new Exception($msg);
@@ -287,7 +294,9 @@ class FixtureManager {
  * @return void
  */
 	public function unload($test) {
-		$fixtures = !empty($test->fixtures) ? $test->fixtures : [];
+		if (empty($test->fixtures)) {
+			return;
+		}
 		$truncate = function($db, $fixtures) {
 			$connection = $db->configName();
 			foreach ($fixtures as $fixture) {
@@ -296,7 +305,7 @@ class FixtureManager {
 				}
 			}
 		};
-		$this->_runOperation($fixtures, $truncate);
+		$this->_runOperation($test->fixtures, $truncate);
 	}
 
 /**

+ 1 - 1
tests/TestCase/Database/Schema/PostgresSchemaTest.php

@@ -878,7 +878,7 @@ SQL;
 		$table = new Table('schema_articles');
 		$result = $table->dropSql($connection);
 		$this->assertCount(1, $result);
-		$this->assertEquals('DROP TABLE "schema_articles"', $result[0]);
+		$this->assertEquals('DROP TABLE "schema_articles" CASCADE', $result[0]);
 	}
 
 /**