Changeset 1925

Show
Ignore:
Timestamp:
11/11/08 00:40:51 (2 months ago)
Author:
mikey
Message:

refactoring #183: optimize reflection on entities
Reflection on an entity class is now only done once per request, regardless of how many times an entity is found, erased or serialized. Will need more memory, but should improve runtime considerably.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/creator/stubDatabaseCreator.php

    r1893 r1925  
    8787         
    8888        $tableDescription = $this->getTableDescription($entityClass); 
    89         $methods          = $entityClass->getMethods(); 
    90         foreach ($methods as $method) { 
    91             $column = $this->getTableColumn($method); 
    92             if (null === $column) { 
    93                 continue; 
    94             } 
    95              
     89        foreach ($this->getColumns($entityClass) as $column) { 
    9690            $tableDescription->addColumn($column); 
    9791        } 
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/eraser/stubDatabaseEraser.php

    r1763 r1925  
    9797         
    9898        $table     = $this->getTableDescription($entityClass)->getName(); 
    99         $methods   = $entityClass->getMethods(); 
    10099        $criterion = new stubAndCriterion(); 
    101         foreach ($methods as $method) { 
    102             if ($method->hasAnnotation('Id') === false) { 
     100        foreach ($this->getColumns($entityClass) as $method => $column) { 
     101            if ($column->isPrimaryKey() === false) { 
    103102                continue; 
    104103            } 
    105104             
    106             $column = $this->getTableColumn($method); 
    107             if (null === $column) { 
    108                 continue; 
    109             } 
    110              
    111             $criterion->addCriterion(new stubEqualCriterion($column->getName(), $method->invoke($entity), $table)); 
     105            $criterion->addCriterion(new stubEqualCriterion($column->getName(), $entity->$method(), $table)); 
    112106        } 
    113107         
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/finder/stubDatabaseFinder.php

    r1901 r1925  
    219219    { 
    220220        $select  = new stubDatabaseSelect($this->getTableDescription($entityClass)); 
    221         $methods = $entityClass->getMethods(); 
    222         foreach ($methods as $method) { 
    223             $column = $this->getTableColumn($method); 
    224             if (null === $column) { 
    225                 continue; 
    226             } 
    227              
    228             if ($column->isPrimaryKey() === true && isset($primaryKeys[$this->getPropertyName($method->getName())]) === true) { 
    229                 $select->addCriterion(new stubEqualCriterion($column->getName(), $primaryKeys[$this->getPropertyName($method->getName())], $select->getBaseTableName())); 
     221        foreach ($this->getColumns($entityClass) as $method => $column) { 
     222            if ($column->isPrimaryKey() === true && isset($primaryKeys[$this->getPropertyName($method)]) === true) { 
     223                $select->addCriterion(new stubEqualCriterion($column->getName(), $primaryKeys[$this->getPropertyName($method)], $select->getBaseTableName())); 
    230224            } elseif ($column->isPrimaryKey() === true && isset($primaryKeys[$column->getName()]) === true) { 
    231225                $select->addCriterion(new stubEqualCriterion($column->getName(), $primaryKeys[$column->getName()], $select->getBaseTableName())); 
    232226            } 
    233227             
    234             $setterMethodHelper->addSetterMethod($column, $method->getName()); 
     228            $setterMethodHelper->addSetterMethod($column, $method); 
    235229        } 
    236230         
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/serializer/stubDatabaseSerializer.php

    r1898 r1925  
    202202    { 
    203203        $tableRow      = new stubDatabaseTableRow($this->getTableDescription($entityClass)->getName()); 
    204         $methods       = $entityClass->getMethods(); 
    205204        $primaryKeys   = array(); 
    206205        $defaultValues = array(); 
    207         foreach ($methods as $method) { 
    208             $column = $this->getTableColumn($method); 
    209             if (null === $column) { 
    210                 continue; 
    211             } 
    212              
    213             try { 
    214                 $value = $method->invoke($entity); 
    215             } catch (ReflectionException $re) { 
    216                 throw new stubDatabaseSerializerException('Can not get return value of ' . $entityClass->getFullQualifiedClassName() . '::' . $method->getName() . '(), invocation failed.', $re); 
    217             } 
    218              
     206        foreach ($this->getColumns($entityClass) as $method => $column) { 
     207            $value = $entity->$method(); 
    219208            if ($value instanceof stubDate) { 
    220209                $value = $value->format('Y-m-d H:i:s'); 
     
    223212            if ($column->isPrimaryKey() === true) { 
    224213                if (null === $value && self::UPDATE === $type) { 
    225                     throw new stubDatabaseSerializerException('Persistence error for ' . $entityClass->getFullQualifiedClassName() . ': should be updated, but one primary key column is null: ' . $method->getName()); 
     214                    throw new stubDatabaseSerializerException('Persistence error for ' . $entityClass->getFullQualifiedClassName() . ': should be updated, but one primary key column is null: ' . $method); 
    226215                } elseif (null === $value) { 
    227                     $primaryKeys[$method->getName()] = array('setterMethod' => stubSetterMethodHelper::create($column, $entityClass, $method->getName()), 
    228                                                              'tableName'    => $tableRow->getTableName() 
    229                                                        ); 
     216                    $primaryKeys[$method] = array('setterMethod' => stubSetterMethodHelper::getSetterMethodName($column, $entityClass, $method), 
     217                                                  'tableName'    => $tableRow->getTableName() 
     218                                            ); 
    230219                } elseif (self::INSERT === $type) { 
    231220                    $tableRow->setColumn($column->getName(), $value); 
     
    236225                $defaultValue = $column->getDefaultValue(); 
    237226                if ($column->isNullable() === false && null === $defaultValue) { 
    238                     throw new stubDatabaseSerializerException('Persistence error for ' . $entityClass->getFullQualifiedClassName() . ': column ' . $column->getName() . ' is not allowed to be null but return value from method ' . $method->getName() . ' and default value are both null.'); 
     227                    throw new stubDatabaseSerializerException('Persistence error for ' . $entityClass->getFullQualifiedClassName() . ': column ' . $column->getName() . ' is not allowed to be null but return value from method ' . $method . ' and default value are both null.'); 
    239228                } 
    240229                 
    241                 $defaultValues[] = array('setterMethod' => stubSetterMethodHelper::create($column, $entityClass, $method->getName()), 
     230                $defaultValues[] = array('setterMethod' => stubSetterMethodHelper::getSetterMethodName($column, $entityClass, $method), 
    242231                                         'value'        => $value, 
    243232                                         'defaultValue' => $defaultValue, 
     
    272261                // only reset entity with default value if default value is not null 
    273262                if (null !== $defaultValue['defaultValue']) { 
    274                     $defaultValue['setterMethod']->invokeArgs($entity, array($defaultValue['defaultValue'])); 
     263                    $setterMethodName = $defaultValue['setterMethod']; 
     264                    $entity->$setterMethodName($defaultValue['defaultValue']); 
    275265                } 
    276266                 
     
    319309            $this->connection->exec($query); 
    320310            if (null !== $singlePrimaryKey && $singlePrimaryKey['tableName'] == $tableName) { 
    321                 $singlePrimaryKey['setterMethod']->invokeArgs($entity, array($this->connection->getLastInsertId())); 
     311                $setterMethodName = $singlePrimaryKey['setterMethod']; 
     312                $entity->$setterMethodName($this->connection->getLastInsertId()); 
    322313            } 
    323314        } 
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/stubPersistenceHelper.php

    r1907 r1925  
    2828{ 
    2929    /** 
     30     * list of table descriptions 
     31     * 
     32     * @var  array<string,stubDatabaseTableDescription> 
     33     */ 
     34    protected static $tableDescriptions = array(); 
     35    /** 
     36     * list of classes with their persistence data 
     37     * 
     38     * @var  array<string,array<string,stubDatabaseTableColumn>> 
     39     */ 
     40    protected static $columns           = array(); 
     41    /** 
    3042     * list of forbidden methods 
    3143     * 
     
    4759    protected function getTableDescription(stubBaseReflectionClass $entityClass) 
    4860    { 
    49         if ($entityClass->hasAnnotation('DBTable') === true) { 
    50             return $entityClass->getAnnotation('DBTable')->getTableDescription(); 
     61        $fqClassName = $entityClass->getFullQualifiedClassName(); 
     62        if (isset(self::$tableDescriptions[$fqClassName]) === false) { 
     63            if ($entityClass->hasAnnotation('DBTable') === true) { 
     64                 self::$tableDescriptions[$fqClassName] = $entityClass->getAnnotation('DBTable')->getTableDescription(); 
     65            } else { 
     66                self::$tableDescriptions[$fqClassName] = new stubDatabaseTableDescription(); 
     67                self::$tableDescriptions[$fqClassName]->setName($entityClass->getName() . 's'); 
     68            } 
    5169        } 
    5270         
    53         $tableDescription = new stubDatabaseTableDescription(); 
    54         $tableDescription->setName($entityClass->getName() . 's'); 
    55         return $tableDescription; 
     71        return self::$tableDescriptions[$fqClassName]; 
     72    } 
     73 
     74    /** 
     75     * returns list of columns and method names 
     76     * 
     77     * @param   stubBaseReflectionClass                $entityClass 
     78     * @return  array<string,stubDatabaseTableColumn> 
     79     */ 
     80    protected function getColumns(stubBaseReflectionClass $entityClass) 
     81    { 
     82        $fqClassName = $entityClass->getFullQualifiedClassName(); 
     83        if (isset(self::$columns[$fqClassName]) === false) { 
     84            self::$columns[$fqClassName] = array(); 
     85            foreach ($entityClass->getMethods() as $method) { 
     86                $column = $this->getTableColumn($method); 
     87                if (null === $column) { 
     88                    continue; 
     89                } 
     90                 
     91                self::$columns[$fqClassName][$method->getName()] = $column; 
     92            } 
     93             
     94        } 
     95        return self::$columns[$fqClassName]; 
    5696    } 
    5797 
     
    65105     * @throws  stubPersistenceException 
    66106     */ 
    67     protected function getTableColumn(stubReflectionMethod $method) 
     107    private function getTableColumn(stubReflectionMethod $method) 
    68108    { 
    69109        if ($method->isStatic() === true || $method->isPublic() === false 
  • framework/trunk/src/main/php/net/stubbles/rdbms/persistence/stubSetterMethodHelper.php

    r1896 r1925  
    5252    public function addSetterMethod(stubDatabaseTableColumn $dbColumn, $getterMethodName) 
    5353    { 
    54         $this->setterMethods[$dbColumn->getName()] = array('setterMethod' => self::create($dbColumn, $this->refBaseClass, $getterMethodName), 
     54        $this->setterMethods[$dbColumn->getName()] = array('setterMethod' => self::getSetterMethodName($dbColumn, $this->refBaseClass, $getterMethodName), 
    5555                                                           'type'         => $dbColumn->getType() 
    5656                                                     ); 
     
    7272         
    7373        foreach ($this->setterMethods as $columnName => $info) { 
    74             if (isset($data[$columnName]) == false) { 
     74            if (isset($data[$columnName]) === false) { 
    7575                continue; 
    7676            } 
     
    8080            } 
    8181             
    82             $info['setterMethod']->invoke($entity, $data[$columnName]); 
     82            $setterMethodName = $info['setterMethod']; 
     83            $entity->$setterMethodName($data[$columnName]); 
    8384        } 
    8485    } 
     
    9091     * @param   stubBaseReflectionClass   $refBaseClass      the class that contains the method 
    9192     * @param   string                    $getterMethodName  name of the method annotated with DBColumn 
    92      * @return  stubReflectionMethod      reflection instance for the setter method 
     93     * @return  string                    name of setter setter method 
    9394     * @throws  stubPersistenceException 
    9495     */ 
    95     public static function create(stubDatabaseTableColumn $dbColumn, stubBaseReflectionClass $refBaseClass, $getterMethodName) 
     96    public static function getSetterMethodName(stubDatabaseTableColumn $dbColumn, stubBaseReflectionClass $refBaseClass, $getterMethodName) 
    9697    { 
    9798        $setterMethodName = (($dbColumn->hasSetterMethod() == true) ? ($dbColumn->getSetterMethod()) : (str_replace('get', 'set', $getterMethodName))); 
    98         if ($refBaseClass->hasMethod($setterMethodName) == false) { 
    99             throw new stubPersistenceException($refBaseClass->getFullQualifiedClassName() . ' has no setter method ' . $setterMethodName . '() for database field ' . $dbColumn->getName()); 
    100         } 
    101              
    102         $setterMethod = $refBaseClass->getMethod($setterMethodName); 
    103         if ($setterMethod->isPublic() == false) { 
    104             throw new stubPersistenceException($refBaseClass->getFullQualifiedClassName() . '::' . $setterMethodName . '() for database field ' . $dbColumn->getName() . '  must be a public setter method.'); 
    105         } elseif ($setterMethod->isStatic() == true) { 
    106             throw new stubPersistenceException($refBaseClass->getFullQualifiedClassName() . '::' . $setterMethodName . '() for database field ' . $dbColumn->getName() . '  must not be a static setter method.'); 
     99        if (in_array($setterMethodName, get_class_methods($refBaseClass->getName())) === false) { 
     100            throw new stubPersistenceException('Public setter method ' . $refBaseClass->getFullQualifiedClassName() . '::' . $setterMethodName . '() for database field ' . $dbColumn->getName() . '  does not exist.'); 
    107101        } 
    108102         
    109         return $setterMethod
     103        return $setterMethodName
    110104    } 
    111105}