From f1a4e7203e165ba99c4ac72ae925941cf1ff1502 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Tue, 7 May 2013 11:57:49 +1200 Subject: [PATCH] BUG Fixing queries on non-existent table breaking archive site With a many to many relation, e.g. SiteTree_MyRelation, and listing them in your template then adding ?archiveDate=x in the URL, a SQL error is shown because Versioned::augmentSQL() tries to query the non-existent table "SiteTree_MyRelation_versions" assuming there's versioning setup, but there isn't. --- model/Versioned.php | 5 +++- tests/model/VersionedTest.php | 52 ++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/model/Versioned.php b/model/Versioned.php index 88f4a20da..a2a457a4c 100644 --- a/model/Versioned.php +++ b/model/Versioned.php @@ -147,6 +147,10 @@ class Versioned extends DataExtension { case 'archive': $date = $dataQuery->getQueryParam('Versioned.date'); foreach($query->getFrom() as $table => $dummy) { + if(!DB::getConn()->hasTable($table . '_versions')) { + continue; + } + $query->renameTable($table, $table . '_versions'); $query->replaceText("\"{$table}_versions\".\"ID\"", "\"{$table}_versions\".\"RecordID\""); $query->replaceText("`{$table}_versions`.`ID`", "`{$table}_versions`.`RecordID`"); @@ -161,7 +165,6 @@ class Versioned extends DataExtension { $query->addWhere("\"{$table}_versions\".\"Version\" = \"{$baseTable}_versions\".\"Version\""); } } - // Link to the version archived on that date $safeDate = Convert::raw2sql($date); $query->addWhere( diff --git a/tests/model/VersionedTest.php b/tests/model/VersionedTest.php index 2cb4a7096..392037310 100644 --- a/tests/model/VersionedTest.php +++ b/tests/model/VersionedTest.php @@ -5,7 +5,8 @@ class VersionedTest extends SapphireTest { protected $extraDataObjects = array( 'VersionedTest_DataObject', - 'VersionedTest_Subclass' + 'VersionedTest_Subclass', + 'VersionedTest_RelatedWithoutVersion' ); protected $requiredExtensions = array( @@ -407,6 +408,38 @@ class VersionedTest extends SapphireTest { 'Additional version fields returned'); $this->assertEquals($extraFields, array('2005', '2007', '2009'), 'Additional version fields returned'); } + + public function testArchiveRelatedDataWithoutVersioned() { + SS_Datetime::set_mock_now('2009-01-01 00:00:00'); + + $relatedData = new VersionedTest_RelatedWithoutVersion(); + $relatedData->Name = 'Related Data'; + $relatedDataId = $relatedData->write(); + + $testData = new VersionedTest_DataObject(); + $testData->Title = 'Test'; + $testData->Content = 'Before Content'; + $testData->Related()->add($relatedData); + $id = $testData->write(); + + SS_Datetime::set_mock_now('2010-01-01 00:00:00'); + $testData->Content = 'After Content'; + $testData->write(); + + $_GET['archiveDate'] = '2009-01-01 19:00:00'; + Versioned::reading_archived_date('2009-01-01 19:00:00'); + + $fetchedData = VersionedTest_DataObject::get()->byId($id); + $this->assertEquals('Before Content', $fetchedData->Content, 'We see the correct content of the older version'); + + $relatedData = VersionedTest_RelatedWithoutVersion::get()->byId($relatedDataId); + $this->assertEquals( + 1, + $relatedData->Related()->count(), + 'We have a relation, with no version table, querying it still works' + ); + } + } class VersionedTest_DataObject extends DataObject implements TestOnly { @@ -423,6 +456,23 @@ class VersionedTest_DataObject extends DataObject implements TestOnly { private static $has_one = array( 'Parent' => 'VersionedTest_DataObject' ); + + private static $many_many = array( + 'Related' => 'VersionedTest_RelatedWithoutVersion' + ); + +} + +class VersionedTest_RelatedWithoutVersion extends DataObject implements TestOnly { + + private static $db = array( + 'Name' => 'Varchar' + ); + + private static $belongs_many_many = array( + 'Related' => 'VersionedTest_DataObject' + ); + } class VersionedTest_Subclass extends VersionedTest_DataObject implements TestOnly {