ClassTableInheritanceTestCase.php 10.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */

/**
 * Doctrine_ClassTableInheritance_TestCase
 *
 * @package     Doctrine
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
 */
class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase 
{
    public function prepareTables()
    { }
    public function prepareData()
    { }

    public function testClassTableInheritanceIsTheDefaultInheritanceType()
    {
        $class = new CTITest();

        $table = $class->getTable();

46 47
        $this->assertEqual($table->getOption('joinedParents'),
                array('CTITestParent4', 'CTITestParent3', 'CTITestParent2', 'CTITestParent1'));
zYne's avatar
zYne committed
48 49 50 51
    }

    public function testExportGeneratesAllInheritedTables()
    {
52
        $sql = $this->conn->export->exportClassesSql(array('CTITest', 'CTITestOneToManyRelated'));
zYne's avatar
zYne committed
53 54 55 56
    
        $this->assertEqual($sql[0], 'CREATE TABLE c_t_i_test_parent4 (id INTEGER, age INTEGER, PRIMARY KEY(id))');
        $this->assertEqual($sql[1], 'CREATE TABLE c_t_i_test_parent3 (id INTEGER, added INTEGER, PRIMARY KEY(id))');
        $this->assertEqual($sql[2], 'CREATE TABLE c_t_i_test_parent2 (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(200), verified INTEGER)');
57 58 59 60
    
        foreach ($sql as $query) {
            $this->conn->exec($query);
        }
zYne's avatar
zYne committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    }

    public function testInheritedPropertiesGetOwnerFlags()
    {
        $class = new CTITest();

        $table = $class->getTable();
        
        $columns = $table->getColumns();

        $this->assertEqual($columns['verified']['owner'], 'CTITestParent2');
        $this->assertEqual($columns['name']['owner'], 'CTITestParent2');
        $this->assertEqual($columns['added']['owner'], 'CTITestParent3');
    }

    public function testNewlyCreatedRecordsHaveInheritedPropertiesInitialized()
    {
78 79 80 81
    	$profiler = new Doctrine_Connection_Profiler();

    	$this->conn->addListener($profiler);

zYne's avatar
zYne committed
82
        $record = new CTITest();
83

zYne's avatar
zYne committed
84
        $this->assertEqual($record->toArray(), array('id' => null,
85 86 87 88
                                                    'age' => null,
                                                    'name' => null,
                                                    'verified' => null,
                                                    'added' => null));
89

zYne's avatar
zYne committed
90 91 92 93 94
        $record->age = 13;
        $record->name = 'Jack Daniels';
        $record->verified = true;
        $record->added = time();
        $record->save();
95 96
        
        // pop the commit event
97 98
        $p = $profiler->pop();
        var_dump($p->getQuery());
99 100 101 102 103 104 105
        $this->assertEqual($profiler->pop()->getQuery(), 'INSERT INTO c_t_i_test_parent4 (age, id) VALUES (?, ?)');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'INSERT INTO c_t_i_test_parent3 (added, id) VALUES (?, ?)');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'INSERT INTO c_t_i_test_parent2 (name, verified) VALUES (?, ?)');
106
        $this->conn->addListener(new Doctrine_EventListener());
107
    }
zYne's avatar
zYne committed
108 109 110 111 112 113
    
    public function testParentalJoinsAreAddedAutomaticallyWithDql()
    {
        $q = new Doctrine_Query();
        $q->from('CTITest c')->where('c.id = 1');

114
        $this->assertEqual($q->getSql(), 'SELECT c.id AS c__id, c3.added AS c__added, c2.name AS c__name, c2.verified AS c__verified, c.age AS c__age FROM c_t_i_test_parent4 c LEFT JOIN c_t_i_test_parent2 c2 ON c.id = c2.id LEFT JOIN c_t_i_test_parent3 c3 ON c.id = c3.id WHERE c.id = 1');
zYne's avatar
zYne committed
115 116 117 118 119 120 121 122 123

        $record = $q->fetchOne();
        
        $this->assertEqual($record->id, 1);
        $this->assertEqual($record->name, 'Jack Daniels');
        $this->assertEqual($record->verified, true);
        $this->assertTrue(isset($record->added));
        $this->assertEqual($record->age, 13);
    }
124 125 126 127 128 129

    public function testReferenfingParentColumnsUsesProperAliases()
    {
        $q = new Doctrine_Query();
        $q->from('CTITest c')->where("c.name = 'Jack'");

zYne's avatar
zYne committed
130
        $this->assertEqual($q->getSql(), "SELECT c.id AS c__id, c3.added AS c__added, c2.name AS c__name, c2.verified AS c__verified, c.age AS c__age FROM c_t_i_test_parent4 c LEFT JOIN c_t_i_test_parent2 c2 ON c.id = c2.id LEFT JOIN c_t_i_test_parent3 c3 ON c.id = c3.id WHERE c2.name = 'Jack'");
131 132 133 134

        $q = new Doctrine_Query();
        $q->from('CTITest c')->where("name = 'Jack'");

zYne's avatar
zYne committed
135
        $this->assertEqual($q->getSql(), "SELECT c.id AS c__id, c3.added AS c__added, c2.name AS c__name, c2.verified AS c__verified, c.age AS c__age FROM c_t_i_test_parent4 c LEFT JOIN c_t_i_test_parent2 c2 ON c.id = c2.id LEFT JOIN c_t_i_test_parent3 c3 ON c.id = c3.id WHERE c2.name = 'Jack'");
136 137
    }

zYne's avatar
zYne committed
138 139
    public function testFetchingCtiRecordsSupportsLimitSubqueryAlgorithm()
    {
140 141 142 143 144 145 146
    	$record = new CTITestOneToManyRelated;
    	$record->name = 'Someone';
    	$record->cti_id = 1;
    	$record->save();

        $this->conn->clear();

zYne's avatar
zYne committed
147 148 149
        $q = new Doctrine_Query();
        $q->from('CTITestOneToManyRelated c')->leftJoin('c.CTITest c2')->where('c.id = 1')->limit(1);

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
        $record = $q->fetchOne();
        
        $this->assertEqual($record->name, 'Someone');
        $this->assertEqual($record->cti_id, 1);

        $cti = $record->CTITest[0];

        $this->assertEqual($cti->id, 1);
        $this->assertEqual($cti->name, 'Jack Daniels');
        $this->assertEqual($cti->verified, true);
        $this->assertTrue(isset($cti->added));
        $this->assertEqual($cti->age, 13);
    }

    public function testUpdatingCtiRecordsUpdatesAllParentTables()
    {
        $this->conn->clear();

        $profiler = new Doctrine_Connection_Profiler();
    	$this->conn->addListener($profiler);

171
        $record = $this->conn->getMapper('CTITest')->find(1);
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
        
        $record->age = 11;
        $record->name = 'Jack';
        $record->verified = false;
        $record->added = 0;
        
        $record->save();
        
        // pop the commit event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'UPDATE c_t_i_test_parent4 SET age = ? WHERE id = ?');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'UPDATE c_t_i_test_parent3 SET added = ? WHERE id = ?');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'UPDATE c_t_i_test_parent2 SET name = ?, verified = ? WHERE id = ?');
        $this->conn->addListener(new Doctrine_EventListener());
    }
    
    public function testUpdateOperationIsPersistent()
    {
        $this->conn->clear();
        
196
        $record = $this->conn->getMapper('CTITest')->find(1);
197 198 199 200 201 202
        
        $this->assertEqual($record->id, 1);
        $this->assertEqual($record->name, 'Jack');
        $this->assertEqual($record->verified, false);
        $this->assertEqual($record->added, 0);
        $this->assertEqual($record->age, 11);
zYne's avatar
zYne committed
203
    }
zYne's avatar
zYne committed
204 205 206 207 208 209 210 211
    
    public function testDeleteIssuesQueriesOnAllJoinedTables()
    {
        $this->conn->clear();

        $profiler = new Doctrine_Connection_Profiler();
    	$this->conn->addListener($profiler);

212
        $record = $this->conn->getMapper('CTITest')->find(1);
zYne's avatar
zYne committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226
        
        $record->delete();

        // pop the commit event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'DELETE FROM c_t_i_test_parent4 WHERE id = ?');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'DELETE FROM c_t_i_test_parent3 WHERE id = ?');
        // pop the prepare event
        $profiler->pop();
        $this->assertEqual($profiler->pop()->getQuery(), 'DELETE FROM c_t_i_test_parent2 WHERE id = ?');
        $this->conn->addListener(new Doctrine_EventListener());
    }
227
}
228
class CTITestParent1 extends Doctrine_Record
229 230 231
{
    public function setTableDefinition()
    {
232 233 234 235
        $this->setInheritanceType(Doctrine::INHERITANCETYPE_JOINED, array(
                'CTITestParent1' => 1, 'CTITestParent2' => 2,
                'CTITestParent3' => 3, 'CTITestParent4' => 4,
                'CTITest' => 5));
236 237 238 239 240 241 242 243 244 245 246 247 248 249
        $this->hasColumn('name', 'string', 200);
    }
}
class CTITestParent2 extends CTITestParent1
{
    public function setTableDefinition()
    {
        $this->hasColumn('verified', 'boolean', 1);
    }
}
class CTITestParent3 extends CTITestParent2
{
    public function setTableDefinition()
    {
zYne's avatar
zYne committed
250
        $this->hasColumn('added', 'integer');
251 252 253 254 255 256 257 258 259 260 261
    }
}
class CTITestParent4 extends CTITestParent3
{
    public function setTableDefinition()
    {
        $this->hasColumn('age', 'integer', 4);
    }
}
class CTITest extends CTITestParent4
{
262 263 264 265
    public function setTableDefinition()
    {
        $this->hasColumn('age2', 'integer', 4);
    }
266
}
zYne's avatar
zYne committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280

class CTITestOneToManyRelated extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('name', 'string');
        $this->hasColumn('cti_id', 'integer');
    }
    
    public function setUp()
    {
        $this->hasMany('CTITest', array('local' => 'cti_id', 'foreign' => 'id'));
    }
}