Changeset 913

Show
Ignore:
Timestamp:
09/12/07 12:51:01 (1 year ago)
Author:
mikey
Message:

some more work towards getting rid of the stubPersistable interface

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/main/php/net/stubbles/rdbms/persistence/eraser/stubDatabaseEraser.php

    r910 r913  
    99stubClassLoader::load('net.stubbles.rdbms.stubDatabaseConnection', 
    1010                      'net.stubbles.rdbms.criteria.stubCriterion', 
     11                      'net.stubbles.rdbms.criteria.stubAndCriterion', 
    1112                      'net.stubbles.rdbms.criteria.stubEqualCriterion', 
    1213                      'net.stubbles.rdbms.persistence.stubPersistenceHelper', 
     
    105106        } 
    106107         
     108        if ($criterion->hasCriterion() === false) { 
     109            throw new stubDatabaseEraserException('Can not delete instance of ' . $entity->getClassName() . ' by its primary keys as it has no primary key.'); 
     110        } 
     111         
    107112        try { 
    108113            $result = $this->connection->query(stubDatabaseQueryBuilderFactory::create($this->connection)->createDelete($table, $criterion)); 
  • trunk/src/main/php/net/stubbles/rdbms/persistence/finder/stubDatabaseFinder.php

    r907 r913  
    1010                      'net.stubbles.rdbms.criteria.stubCriterion', 
    1111                      'net.stubbles.rdbms.criteria.stubEqualCriterion', 
    12                       'net.stubbles.rdbms.persistence.stubPersistable', 
     12                      'net.stubbles.rdbms.persistence.stubPersistenceHelper', 
    1313                      'net.stubbles.rdbms.persistence.stubSetterMethodHelper', 
    14                       'net.stubbles.rdbms.persistence.annotations.stubDBColumnAnnotation', 
    15                       'net.stubbles.rdbms.persistence.annotations.stubDBJoinAnnotation', 
    16                       'net.stubbles.rdbms.persistence.annotations.stubDBTableAnnotation', 
    1714                      'net.stubbles.rdbms.persistence.finder.stubDatabaseFinderException', 
    1815                      'net.stubbles.rdbms.persistence.finder.stubDatabaseFinderResult', 
     
    2724 * @subpackage  rdbms_persistence_finder 
    2825 */ 
    29 class stubDatabaseFinder extends stubBaseObject 
     26class stubDatabaseFinder extends stubPersistenceHelper 
    3027{ 
    3128    /** 
     
    6562    public static function getInstance(stubDatabaseConnection $connection, $refresh = false) 
    6663    { 
    67         if (isset(self::$instances[$connection->hashCode()]) == false || true == $refresh) { 
     64        if (isset(self::$instances[$connection->hashCode()]) === false || true === $refresh) { 
    6865            self::$instances[$connection->hashCode()] = new self($connection); 
    6966        } 
     
    8582     * get a persistable object from database by its primary keys 
    8683     * 
    87      * @param   stubPersistable              $persistable 
     84     * @param   stubBaseReflectionClass      $entityClass  class information about the entity 
     85     * @param   array                        $primaryKeys  list of primary keys (name => value) 
     86     * @param   array                        $arguments    arguments for the constructor 
     87     * @return  object 
    8888     * @throws  stubDatabaseFinderException 
    8989     * @throws  stubPersistenceException 
    9090     */ 
    91     public function findByPrimaryKeys(stubPersistable $persistable
     91    public function findByPrimaryKeys(stubBaseReflectionClass $entityClass, array $primaryKeys, array $arguments = null
    9292    { 
    93         $refObject = $persistable->getClass(); 
    94         $setterMethodHelper = new stubSetterMethodHelper($refObject); 
    95         $select    = $this->createSelect($refObject, $setterMethodHelper); 
     93        if ($entityClass->hasAnnotation('Entity') === false) { 
     94            throw new stubPersistenceException('Class ' . $entityClass->getFullQualifiedClassName() . ' is not an entity.'); 
     95        } 
     96         
     97        $setterMethodHelper = new stubSetterMethodHelper($entityClass); 
     98        $select             = $this->createSelect($entityClass, $setterMethodHelper, $primaryKeys); 
    9699        try { 
    97100            $result = $this->connection->query(stubDatabaseQueryBuilderFactory::create($this->connection)->createSelect($select)); 
     
    99102            $result->free(); 
    100103        } catch (stubException $se) { 
    101             throw new stubDatabaseFinderException('Can not find instance of ' . $refObject->getFullQualifiedClassName() . ' by its primary keys.', $se); 
     104            throw new stubDatabaseFinderException('Can not find instance of ' . $entityClass->getFullQualifiedClassName() . ' by its primary keys.', $se); 
    102105        } 
    103106         
    104107        if (false === $data) { 
    105             return
     108            return null
    106109        } 
    107110         
    108         $setterMethodHelper->applySetterMethods($persistable, $data); 
    109         $persistable->setPersistent(true); 
     111        $entity = ((null === $arguments) ? ($entityClass->newInstance()) : ($entityClass->newInstanceArgs($arguments))); 
     112        $setterMethodHelper->applySetterMethods($entity, $data); 
     113        return $entity; 
    110114    } 
    111115 
     
    116120     * @param   string                       $persistableClassName  non qualified classname of the persistable class to find instances of 
    117121     * @param   array                        $arguments             optional  arguments for constructor 
    118      * @return  stubDatabaseFinderResult     list of instances of $persistableClassName found with $criterion 
     122     * @return  stubDatabaseFinderResult     list of instances of $entityClass found with $criterion 
    119123     * @throws  stubDatabaseFinderException 
    120124     * @throws  stubPersistenceException 
    121125     */ 
    122     public function findByCriterion(stubCriterion $criterion, $persistableClassName, array $arguments = null) 
     126    public function findByCriterion(stubCriterion $criterion, stubBaseReflectionClass $entityClass, array $arguments = null) 
    123127    { 
    124         try { 
    125             $refClass = new stubReflectionClass($persistableClassName); 
    126         } catch (ReflectionException $re) { 
    127             throw new stubDatabaseFinderException('Can not find any instance of ' . $refClass->getFullQualifiedClassName() . ' by criterion ' . $criterion, $re); 
     128        if ($entityClass->hasAnnotation('Entity') === false) { 
     129            throw new stubPersistenceException('Class ' . $entityClass->getFullQualifiedClassName() . ' is not an entity.'); 
    128130        } 
    129131         
    130         if ($refClass->implementsInterface('stubPersistable') == false) { 
    131             throw new stubDatabaseFinderException($refClass->getFullQualifiedClassName() . ' does not implement net.stubbles.rdbms.persistence.stubPersistable.'); 
    132         } 
    133          
    134         $setterMethodHelper = new stubSetterMethodHelper($refClass); 
    135         $select             = $this->createSelect($refClass, $setterMethodHelper); 
     132        $setterMethodHelper = new stubSetterMethodHelper($entityClass); 
     133        $select             = $this->createSelect($entityClass, $setterMethodHelper); 
    136134        $select->addCriterion($criterion); 
    137135        try { 
     
    140138            $result->free(); 
    141139        } catch (stubDatabaseException $se) { 
    142             throw new stubDatabaseFinderException('Can not find any instance of ' . $refClass->getFullQualifiedClassName() . ' by criterion ' . $criterion, $se); 
     140            throw new stubDatabaseFinderException('Can not find any instance of ' . $entityClass->getFullQualifiedClassName() . ' by criterion ' . $criterion, $se); 
    143141        }  
    144142         
     
    147145        } 
    148146         
    149         $finderResult = new stubDatabaseFinderResult($refClass, $data, $setterMethodHelper, $arguments); 
     147        $finderResult = new stubDatabaseFinderResult($entityClass, $data, $setterMethodHelper, $arguments); 
    150148        return $finderResult; 
    151149    } 
     
    154152     * reads annotations and returns data in a usable format 
    155153     * 
    156      * @param   stubBaseReflectionClass      $refBaseClass 
     154     * @param   stubBaseReflectionClass      $entityClass 
    157155     * @param   stubSetterMethodHelper       $setterMethodHelper 
    158156     * @return  stubDatabaseSelect 
    159157     * @throws  stubDatabaseFinderException 
    160158     */ 
    161     protected function createSelect(stubBaseReflectionClass $refBaseClass, stubSetterMethodHelper $setterMethodHelper
     159    protected function createSelect(stubBaseReflectionClass $entityClass, stubSetterMethodHelper $setterMethodHelper, array $primaryKeys = array()
    162160    { 
    163         if ($refBaseClass->hasAnnotation('DBTable') == false) { 
    164             throw new stubDatabaseFinderException('Can not find instance of ' . $refBaseClass->getFullQualifiedClassName() . ', class is missing the DBTable annotation.'); 
    165         } 
    166          
    167         $select  = new stubDatabaseSelect($refBaseClass->getAnnotation('DBTable')->getTableDescription()); 
    168         $methods = $refBaseClass->getMethods(); 
     161 
     162        $select  = new stubDatabaseSelect($this->getTableDescription($entityClass)); 
     163        $methods = $entityClass->getMethods(); 
    169164        foreach ($methods as $method) { 
    170             if ($method->hasAnnotation('DBColumn') == false) { 
     165            $column = $this->getTableColumn($method); 
     166            if (null === $column) { 
    171167                continue; 
    172168            } 
    173169             
    174             $dbColumn  = $method->getAnnotation('DBColumn')->getTableColumn(); 
    175             if ($method->hasAnnotation('DBJoin') == true) { 
    176                 $tableJoin = $method->getAnnotation('DBJoin')->getTableJoin(); 
    177                 $tableName = $tableJoin->getName(); 
    178                 $select->addJoin($tableJoin); 
    179             } else { 
    180                 $tableName = $select->getBaseTableName(); 
     170            if ($column->isPrimaryKey() === true && isset($primaryKeys[$column->getName()]) === true) { 
     171                $select->addCriterion(new stubEqualCriterion($column->getName(), $primaryKeys[$column->getName(), $select->getBaseTableName())); 
    181172            } 
    182173             
    183             if ($refBaseClass instanceof stubReflectionObject && $dbColumn->isPrimaryKey() == true) { 
    184                 $select->addCriterion(new stubEqualCriterion($dbColumn->getName(), $method->invoke($refBaseClass->getObjectInstance()), $tableName)); 
    185             } 
    186              
    187             $setterMethodHelper->addSetterMethod($dbColumn, $method->getName()); 
     174            $setterMethodHelper->addSetterMethod($column, $method->getName()); 
    188175        } 
    189176         
  • trunk/src/main/php/net/stubbles/rdbms/persistence/serializer/stubDatabaseSerializer.php

    r907 r913  
    99stubClassLoader::load('net.stubbles.rdbms.stubDatabaseConnection', 
    1010                      'net.stubbles.rdbms.criteria.stubEqualCriterion', 
    11                       'net.stubbles.rdbms.persistence.stubPersistable', 
     11                      'net.stubbles.rdbms.persistence.stubPersistenceHelper', 
    1212                      'net.stubbles.rdbms.persistence.stubSetterMethodHelper', 
    13                       'net.stubbles.rdbms.persistence.annotations.stubDBColumnAnnotation', 
    14                       'net.stubbles.rdbms.persistence.annotations.stubDBJoinAnnotation', 
    15                       'net.stubbles.rdbms.persistence.annotations.stubDBTableAnnotation', 
    1613                      'net.stubbles.rdbms.persistence.serializer.stubDatabaseSerializerException', 
    1714                      'net.stubbles.rdbms.querybuilder.stubDatabaseQueryBuilderFactory', 
     
    2421 * @subpackage  rdbms_persistence_serializer 
    2522 */ 
    26 class stubDatabaseSerializer extends stubBaseObject 
     23class stubDatabaseSerializer extends stubPersistenceHelper 
    2724{ 
    2825    /** 
     
    6259    public static function getInstance(stubDatabaseConnection $connection, $refresh = false) 
    6360    { 
    64         if (isset(self::$instances[$connection->hashCode()]) == false || true == $refresh) { 
     61        if (isset(self::$instances[$connection->hashCode()]) === false || true === $refresh) { 
    6562            self::$instances[$connection->hashCode()] = new self($connection); 
    6663        } 
     
    8582     * @throws  stubDatabaseSerializerException 
    8683     * @throws  stubPersistenceException 
    87      * @todo    isPersistent is buggy 
    88      * @todo    set default value only if not persistent 
    89      */ 
    90     public function serialize(stubObject $entity) 
    91     { 
    92         $entityClass = $entity->getClass(); 
     84     */ 
     85    public function serialize($entity) 
     86    { 
     87        if (is_object($entity) === false) { 
     88            throw new stubIllegalArgumentException('Can only serialize objects.'); 
     89        } 
     90         
     91        $entityClass = (($entity instanceof stubObject) ? ($entity->getClass()) : (new stubReflectionClass($entity))); 
    9392        if ($entityClass->hasAnnotation('Entity') === false) { 
    9493            throw new stubPersistenceException('Class ' . $entity->getClassName() . ' is not an entity.'); 
    9594        } 
    9695         
    97         $baseTableName    = $this->getTableDescription($entityClass)->getName(); 
     96        $tableRow         = new stubDatabaseTableRow($this->getTableDescription($entityClass)->getName()); 
    9897        $methods          = $refObject->getMethods(); 
    99         $tableRows        = array(); 
    10098        $singlePrimaryKey = null; 
    101         $isPersistent     = null
     99        $defaultValues    = array()
    102100        foreach ($methods as $method) { 
    103101            $column = $this->getTableColumn($method); 
     
    106104            } 
    107105             
    108             $tableName = (($method->hasAnnotation('DBJoin') == true) ? ($method->getAnnotation('DBJoin')->getTableJoin()->getName()) : ($baseTableName)); 
    109             if (isset($tableRows[$tableName]) == false) { 
    110                 $tableRows[$tableName] = new stubDatabaseTableRow($tableName); 
    111             } 
    112              
    113106            try { 
    114107                $value = $method->invoke($entity); 
     
    119112            if ($column->isPrimaryKey() === true) { 
    120113                if (null === $value) { 
    121                     $isPersistent = false; 
    122114                    if (null !== $singlePrimaryKey) { 
    123                         throw new stubDatabaseSerializerException('Persistence error: only one primary key can be null, but at least two primary keys are null: ' . $singlePrimaryKey['propertyName'] . ' and ' . $method->getName()); 
     115                        throw new stubDatabaseSerializerException('Persistence error for ' . $entity->getClassName() . ': only one primary key can be null, but at least two primary keys are null: ' . $singlePrimaryKey['propertyName'] . ' and ' . $method->getName()); 
    124116                    } 
    125117                     
     
    129121                    continue; 
    130122                } else { 
    131                     $isPersistent = true; 
    132                     $tableRows[$tableName]->addCriterion(new stubEqualCriterion($column->getName(), $value, $tableName)); 
     123                    $tableRow->addCriterion(new stubEqualCriterion($column->getName(), $value, $tableName)); 
    133124                } 
    134125            } elseif (null === $value) { 
    135                 $value = $dbColumn->getDefaultValue(); 
    136                 $setterMethod = stubSetterMethodHelper::create($column, $entityClass, $method->getName()); 
    137                 $setterMethod->invoke($entity, $value); 
    138             } 
    139              
    140             $tableRows[$tableName]->setColumn($column->getName(), $value); 
     126                $value = $column->getDefaultValue(); 
     127                if ($column->isNullable() === false && null === $value) { 
     128                    throw new stubDatabaseSerializerException('Persistence error for ' . $entity->getClassName() . ': column ' . $column->getName() . ' is not allowed to be null but return value from method ' . $method->getName() . ' and default value are both null.'); 
     129                } 
     130                 
     131                $defaultValues[] = array('setterMethod' => stubSetterMethodHelper::create($column, $entityClass, $method->getName()), 
     132                                         'value'        => $value 
     133                                   ); 
     134            } 
     135             
     136            $tableRow->setColumn($column->getName(), $value); 
     137        } 
     138         
     139        if ($tableRow->hasCriterion() === false) { 
     140            foreach ($defaultValues as $defaultValue) { 
     141                $defaultValue['setterMethod']->invoke($entity, $defaultValue['value']); 
     142            } 
    141143        } 
    142144         
    143145        try { 
    144             $this->processQueries($this->getQueries($tableRows, $isPersistent), $entity, $singlePrimaryKey); 
     146            $this->processQueries($this->getQuery($tableRow), $entity, $singlePrimaryKey); 
    145147        } catch (stubDatabaseException $dbe) { 
    146148            throw new stubDatabaseSerializerException('Can not persist ' . $entity->getClassName() . ': a database error occured.', $dbe); 
     
    149151 
    150152    /** 
    151      * build the queries out of the serialized value 
    152      * 
    153      * @param   array<string,stubDatabaseTableRow>  $tableRows 
    154      * @param   bool                                $isPersistent 
     153     * build the query out of the serialized value 
     154     * 
     155     * @param   stubDatabaseTableRow  $tableRow 
    155156     * @return  array<string,string> 
    156157     * @throws   
    157158     */ 
    158     protected function getQueries(array $tableRows, $isPersistent
     159    protected function getQuery(stubDatabaseTableRow $tableRow
    159160    { 
    160161        $queryBuilder = stubDatabaseQueryBuilderFactory::create($this->connection); 
    161162        try { 
    162             if (true == $isPersistent) { 
    163                 return $queryBuilder->createUpdate($tableRows); 
    164             } 
    165              
    166             return $queryBuilder->createInsert($tableRows); 
     163            if ($tableRow->hasCriterion() === true) { 
     164                return $queryBuilder->createUpdate(array($tableRow)); 
     165            } 
     166             
     167            return $queryBuilder->createInsert(array($tableRow)); 
    167168        } catch (stubIllegalArgumentException $iae) { 
    168169            throw new stubDatabaseSerializerException('Creating the queries failed.', $iae); 
  • trunk/src/test/php/net/stubbles/rdbms/persistence/eraser/stubDatabaseEraserTestCase.php

    r655 r913  
    11<?php 
    22/** 
    3  * Test for net.stubbles.rdbms.persistence.eraser.stubDatabaseEraser 
     3 * Test for net.stubbles.rdbms.persistence.eraser.stubDatabaseEraser. 
    44 * 
    55 * @author      Frank Kleine <mikey@stubbles.net> 
     
    1212Mock::generate('stubCriterion'); 
    1313require_once dirname(__FILE__) . '/../../querybuilder/TeststubDatabaseQueryBuilder.php'; 
     14require_once dirname(__FILE__) . '/../MockNoEntityAnnotationPersistable.php'; 
    1415require_once dirname(__FILE__) . '/../MockNoTableAnnotationPersistable.php'; 
    1516require_once dirname(__FILE__) . '/../MockSinglePrimaryKeyPersistable.php'; 
    16 require_once dirname(__FILE__) . '/../TestNonPersistable.php'; 
    1717/** 
    18  * Test for net.stubbles.rdbms.persistence.eraser.stubDatabaseEraser 
     18 * Test for net.stubbles.rdbms.persistence.eraser.stubDatabaseEraser. 
    1919 * 
    2020 * @package     stubbles 
     
    123123    public function testByPrimaryKeys() 
    124124    { 
    125         $singlePrimaryKey = new MockSinglePrimaryKeyPersistable(); 
    126         $singlePrimaryKey->setId('mock'); 
    127         $singlePrimaryKey->setPersistent(true); 
     125        $entity = new MockSinglePrimaryKeyPersistable(); 
     126        $entity->setId('mock'); 
    128127        $this->mockConnection->setReturnValue('query', new MockstubDatabaseResult()); 
    129         $this->dbEraser->deleteByPrimaryKeys($singlePrimaryKey); 
    130         $this->assertFalse($singlePrimaryKey->isPersistent()); 
     128        $this->dbEraser->deleteByPrimaryKeys($entity); 
    131129        $this->assertEqual($this->mockQueryBuilder->getDeleteTable(), 'foo'); 
    132130        $this->assertEqual($this->mockQueryBuilder->getDeleteCriterion()->toSQL(), "(`foo`.`id` = 'mock')"); 
     
    155153     * test that trying to delete a class that does not implement stubPersistable throws an exception 
    156154     */ 
    157     public function testByCriterionNonPersistableClass() 
     155    public function testByCriterionNonEntityClass() 
    158156    { 
    159         $this->expectException('stubDatabaseEraserException'); 
    160         $this->dbEraser->deleteByCriterion(new MockstubCriterion(), 'TestNonPersistable'); 
     157        $this->expectException('stubPersistenceException'); 
     158        $this->dbEraser->deleteByCriterion(new MockstubCriterion(), 'MockNoEntityAnnotationPersistable'); 
    161159    } 
    162160}