diff --git a/Annotation/Annotation.php b/Annotation/Annotation.php index 5ab7132b..b1aca7d0 100644 --- a/Annotation/Annotation.php +++ b/Annotation/Annotation.php @@ -16,185 +16,203 @@ class Annotation extends Component { - private Loader $_loader; + private Loader $_loader; - private array $_model_sets = []; - private array $_model_gets = []; - private array $_model_relate = []; + private array $_model_sets = []; + private array $_model_gets = []; + private array $_model_relate = []; - /** - * @param string $class - * @param string $setName - * @param string $method - */ - public function addSets(string $class, string $setName, string $method) - { - $this->_model_sets[$class][$setName] = $method; - } + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addSets(string $class, string $setName, string $method) + { + $this->_model_sets[$class][$setName] = $method; + } - /** - * @param string $class - * @param string $setName - * @param string $method - */ - public function addGets(string $class, string $setName, string $method) - { - $this->_model_gets[$class][$setName] = $method; - } + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addGets(string $class, string $setName, string $method) + { + $this->_model_gets[$class][$setName] = $method; + } - /** - * @param string $class - * @param string $setName - * @param string $method - */ - public function addRelate(string $class, string $setName, string $method) - { - $this->_model_relate[$class][$setName] = $method; - } + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addRelate(string $class, string $setName, string $method) + { + $this->_model_relate[$class][$setName] = $method; + } - /** - * @param string $class - * @param string $setName - * @return mixed|null - */ - public function getGetMethodName(string $class, string $setName): ?string - { - $gets = $this->_model_gets[$class] ?? $this->_model_relate[$class] ?? null; - if ($gets == null) { - return null; - } - return $gets[$setName] ?? null; - } + /** + * @param $class + * @return array + */ + public function getGets($class): array + { + return $this->_model_gets[$class] ?? []; + } + + /** + * @param $class + * @return array + */ + public function getSets($class): array + { + return $this->_model_gets[$class] ?? []; + } - /** - * @param string $class - * @return array - */ - public function getModelMethods(string $class): array - { - return $this->_model_gets[$class] ?? []; - } + /** + * @param string $class + * @param string $setName + * @return mixed|null + */ + public function getGetMethodName(string $class, string $setName): ?string + { + $gets = $this->_model_gets[$class] ?? $this->_model_relate[$class] ?? null; + if ($gets == null) { + return null; + } + return $gets[$setName] ?? null; + } - /** - * @param string $class - * @return array - */ - public function getRelateMethods(string $class): array - { - return $this->_model_relate[$class] ?? []; - } + /** + * @param string $class + * @return array + */ + public function getModelMethods(string $class): array + { + return $this->_model_gets[$class] ?? []; + } - - /** - * @param string $class - * @param string $setName - * @return mixed|null - */ - public function getSetMethodName(string $class, string $setName): ?string - { - if (!isset($this->_model_sets[$class])) { - return null; - } - - $lists = $this->_model_sets[$class]; - - if (isset($lists[$setName])) { - return $lists[$setName]; - } - return null; - } + /** + * @param string $class + * @return array + */ + public function getRelateMethods(string $class): array + { + return $this->_model_relate[$class] ?? []; + } - public function init(): void - { - $this->_loader = new Loader(); - } + /** + * @param string $class + * @param string $setName + * @return mixed|null + */ + public function getSetMethodName(string $class, string $setName): ?string + { + if (!isset($this->_model_sets[$class])) { + return null; + } + + $lists = $this->_model_sets[$class]; + + if (isset($lists[$setName])) { + return $lists[$setName]; + } + return null; + } - /** - * @return Loader - */ - public function getLoader(): Loader - { - return $this->_loader; - } + public function init(): void + { + $this->_loader = new Loader(); + } - /** - * @param Loader $loader - * @return Loader - */ - public function setLoader(Loader $loader): Loader - { - return $this->_loader = $loader; - } + /** + * @return Loader + */ + public function getLoader(): Loader + { + return $this->_loader; + } - /** - * @param string $className - * @param string $method - * @return array 根据类名获取注解 - * 根据类名获取注解 - */ - public function getMethods(string $className, string $method = ''): mixed - { - return $this->_loader->getMethod($className, $method); - } + /** + * @param Loader $loader + * @return Loader + */ + public function setLoader(Loader $loader): Loader + { + return $this->_loader = $loader; + } - /** - * @param object $class - */ - public function injectProperty(object $class) - { - $this->_loader->injectProperty($class::class, $class); - } + /** + * @param string $className + * @param string $method + * @return array 根据类名获取注解 + * 根据类名获取注解 + */ + public function getMethods(string $className, string $method = ''): mixed + { + return $this->_loader->getMethod($className, $method); + } - /** - * @param string $path - * @param string $namespace - * @param string $alias - * @return void - * @throws Exception - */ - public function read(string $path, string $namespace, string $alias = 'root'): void - { - - $this->_loader->_scanDir(new DirectoryIterator($path), $namespace); - } + /** + * @param object $class + */ + public function injectProperty(object $class) + { + $this->_loader->injectProperty($class::class, $class); + } - /** - * @param string $dir - * @param string|array $outPath - * @throws Exception - */ - public function runtime(string $dir, string|array $outPath = '') - { - if (empty($outPath)) { - $outPath = []; - } else if (is_string($outPath)) { - $outPath = [$outPath]; - } - $this->_loader->loadByDirectory($dir, $outPath); - } + /** + * @param string $path + * @param string $namespace + * @param string $alias + * @return void + * @throws Exception + */ + public function read(string $path, string $namespace, string $alias = 'root'): void + { + + $this->_loader->_scanDir(new DirectoryIterator($path), $namespace); + } - /** - * @param string $filename - * @return mixed - */ - public function getFilename(string $filename): mixed - { - return $this->_loader->getClassByFilepath($filename); - } + /** + * @param string $dir + * @param string|array $outPath + * @throws Exception + */ + public function runtime(string $dir, string|array $outPath = '') + { + if (empty($outPath)) { + $outPath = []; + } else if (is_string($outPath)) { + $outPath = [$outPath]; + } + $this->_loader->loadByDirectory($dir, $outPath); + } + + + /** + * @param string $filename + * @return mixed + */ + public function getFilename(string $filename): mixed + { + return $this->_loader->getClassByFilepath($filename); + } } diff --git a/Database/ActiveRecord.php b/Database/ActiveRecord.php index de6e5ce2..4002a6ea 100644 --- a/Database/ActiveRecord.php +++ b/Database/ActiveRecord.php @@ -307,7 +307,7 @@ class ActiveRecord extends BaseActiveRecord { $data = $this->_attributes; - $lists = Snowflake::getAnnotation()->getModelMethods(static::class); + $lists = $this->getAnnotation(self::ANNOTATION_GET); foreach ($lists as $key => $item) { $data[$key] = $this->{$item}($data[$key] ?? null); } diff --git a/Database/Base/AbstractCollection.php b/Database/Base/AbstractCollection.php index f590629d..0d0986a9 100644 --- a/Database/Base/AbstractCollection.php +++ b/Database/Base/AbstractCollection.php @@ -115,11 +115,10 @@ abstract class AbstractCollection extends Component implements \IteratorAggregat */ public function getModel(): ActiveRecord { - $model = $this->model;; - if (is_object($model)) { - return $model; + if (!is_object($this->model)) { + $this->model = $this->model::populate([]); } - return $model::populate([]); + return $this->model; } diff --git a/Database/Base/BaseActiveRecord.php b/Database/Base/BaseActiveRecord.php index d7988d9c..bf9dcbe3 100644 --- a/Database/Base/BaseActiveRecord.php +++ b/Database/Base/BaseActiveRecord.php @@ -139,6 +139,11 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess } else { $this->_relation = Context::getContext(Relation::class); } + + $annotation = Snowflake::app()->getAnnotation(); + $this->_annotations[self::ANNOTATION_GET] = $annotation->getGets(static::class); + $this->_annotations[self::ANNOTATION_SET] = $annotation->getSets(static::class); + $this->_relate = $annotation->getRelateMethods(static::class); } @@ -809,7 +814,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess parent::__set($name, $value); return; } - $method = annotation()->getSetMethodName(static::class, $name); + $method = $this->_get_annotation($name, self::ANNOTATION_SET); if (!empty($method)) { $value = $this->{$method}($value); } @@ -817,6 +822,22 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess } + /** + * @param $name + * @param string $method + * @return string|null + */ + protected function _get_annotation(string $name = null, string $method = self::ANNOTATION_GET): ?string + { + $matches = match ($method) { + self::ANNOTATION_GET => $this->_annotations[self::ANNOTATION_GET], + self::ANNOTATION_SET => $this->_annotations[self::ANNOTATION_SET], + default => $this->_relate + }; + return $matches[$name] ?? null; + } + + /** * @param $name * @return mixed @@ -840,9 +861,10 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess */ private function _gets(string $name, mixed $value): mixed { - $loader = Snowflake::app()->getAnnotation(); - $method = $loader->getGetMethodName(static::class, $name); - if (empty($method)) { + if (!empty($method = $this->_get_annotation($name))) { + return $this->{$method}(...[$value]); + } + if (empty($method = $this->_get_annotation())) { return $this->_decode($name, $value); } $_value = $this->{$method}(...[$value]); diff --git a/Database/Base/CollectionIterator.php b/Database/Base/CollectionIterator.php index 54d4f3d8..c1a80f61 100644 --- a/Database/Base/CollectionIterator.php +++ b/Database/Base/CollectionIterator.php @@ -8,10 +8,6 @@ namespace Database\Base; use Database\ActiveQuery; use Database\ActiveRecord; use Exception; -use ReflectionException; -use Snowflake\Channel; -use Snowflake\Exception\NotFindClassException; -use Snowflake\Snowflake; /** @@ -28,6 +24,9 @@ class CollectionIterator extends \ArrayIterator private ActiveQuery $query; + private ?ActiveRecord $_clone = null; + + public function clean() { unset($this->query); @@ -57,7 +56,10 @@ class CollectionIterator extends \ArrayIterator */ protected function newModel($current): ActiveRecord { - return $this->model::populate($current); + $model = clone $this->model; + $model->setAttributes($current); + $model->refresh(); + return $model; }