This commit is contained in:
as2252258@163.com
2021-04-24 19:46:24 +08:00
parent 7b8c0dbf63
commit 1867083b14
3 changed files with 385 additions and 376 deletions
+26 -11
View File
@@ -31,7 +31,7 @@ class Annotation extends Component
*/ */
public function addSets(string $class, string $setName, string $method) public function addSets(string $class, string $setName, string $method)
{ {
$this->_model_sets[$class . '::' . $setName] = $method; $this->_model_sets[$class][$setName] = $method;
} }
/** /**
@@ -41,7 +41,7 @@ class Annotation extends Component
*/ */
public function addGets(string $class, string $setName, string $method) public function addGets(string $class, string $setName, string $method)
{ {
$this->_model_gets[$class . '::' . $setName] = $method; $this->_model_gets[$class][$setName] = $method;
} }
@@ -52,7 +52,7 @@ class Annotation extends Component
*/ */
public function addRelate(string $class, string $setName, string $method) public function addRelate(string $class, string $setName, string $method)
{ {
$this->_model_relate[$class . '::' . $setName] = $method; $this->_model_relate[$class][$setName] = $method;
} }
@@ -63,16 +63,25 @@ class Annotation extends Component
*/ */
public function getGetMethodName(string $class, string $setName): ?string public function getGetMethodName(string $class, string $setName): ?string
{ {
if (isset($this->_model_gets[$class . '::' . $setName])) { $gets = $this->_model_gets[$class] ?? $this->_model_relate[$class] ?? null;
return $this->_model_gets[$class . '::' . $setName]; if ($gets == null) {
return null;
} }
if (isset($this->_model_relate[$class . '::' . $setName])) { return $gets[$setName] ?? null;
return $this->_model_relate[$class . '::' . $setName];
}
return null;
} }
/**
* @param string $class
* @return array
*/
public function getModelMethods(string $class): array
{
return $this->_model_gets[$class] ?? [];
}
/** /**
* @param string $class * @param string $class
* @param string $setName * @param string $setName
@@ -80,8 +89,14 @@ class Annotation extends Component
*/ */
public function getSetMethodName(string $class, string $setName): ?string public function getSetMethodName(string $class, string $setName): ?string
{ {
if (isset($this->_model_sets[$class . '::' . $setName])) { if (!isset($this->_model_sets[$class])) {
return $this->_model_relate[$class . '::' . $setName]; return null;
}
$lists = $this->_model_sets[$class];
if (isset($lists[$setName])) {
return $lists[$setName];
} }
return null; return null;
} }
+358 -358
View File
@@ -32,415 +32,415 @@ defined('FIND_OR_CREATE_MESSAGE') or define('FIND_OR_CREATE_MESSAGE', 'Create a
class ActiveRecord extends BaseActiveRecord class ActiveRecord extends BaseActiveRecord
{ {
const DECR = 'decr'; const DECR = 'decr';
const INCR = 'incr'; const INCR = 'incr';
/** /**
* @return array * @return array
*/ */
public function rules(): array public function rules(): array
{ {
return []; return [];
} }
/** /**
* @param string $column * @param string $column
* @param int $value * @param int $value
* @return ActiveRecord|false * @return ActiveRecord|false
* @throws Exception * @throws Exception
*/ */
public function increment(string $column, int $value): bool|ActiveRecord public function increment(string $column, int $value): bool|ActiveRecord
{ {
if (!$this->mathematics([$column => $value], '+')) { if (!$this->mathematics([$column => $value], '+')) {
return false; return false;
} }
$this->{$column} += $value; $this->{$column} += $value;
return $this->refresh(); return $this->refresh();
} }
/** /**
* @param string $column * @param string $column
* @param int $value * @param int $value
* @return ActiveRecord|false * @return ActiveRecord|false
* @throws Exception * @throws Exception
*/ */
public function decrement(string $column, int $value): bool|ActiveRecord public function decrement(string $column, int $value): bool|ActiveRecord
{ {
if (!$this->mathematics([$column => $value], '-')) { if (!$this->mathematics([$column => $value], '-')) {
return false; return false;
} }
$this->{$column} -= $value; $this->{$column} -= $value;
return $this->refresh(); return $this->refresh();
} }
/** /**
* @param array $columns * @param array $columns
* @return ActiveRecord|false * @return ActiveRecord|false
* @throws Exception * @throws Exception
*/ */
public function increments(array $columns): bool|static public function increments(array $columns): bool|static
{ {
if (!$this->mathematics($columns, '+')) { if (!$this->mathematics($columns, '+')) {
return false; return false;
} }
foreach ($columns as $key => $attribute) { foreach ($columns as $key => $attribute) {
$this->$key += $attribute; $this->$key += $attribute;
} }
return $this; return $this;
} }
/** /**
* @param array $columns * @param array $columns
* @return ActiveRecord|false * @return ActiveRecord|false
* @throws Exception * @throws Exception
*/ */
public function decrements(array $columns): bool|static public function decrements(array $columns): bool|static
{ {
if (!$this->mathematics($columns, '-')) { if (!$this->mathematics($columns, '-')) {
return false; return false;
} }
foreach ($columns as $key => $attribute) { foreach ($columns as $key => $attribute) {
$this->$key -= $attribute; $this->$key -= $attribute;
} }
return $this; return $this;
} }
/** /**
* @param array $condition * @param array $condition
* @param array $attributes * @param array $attributes
* @return bool|ActiveRecord * @return bool|ActiveRecord
* @throws ReflectionException * @throws ReflectionException
* @throws NotFindClassException * @throws NotFindClassException
* @throws Exception * @throws Exception
*/ */
public static function findOrCreate(array $condition, array $attributes = []): bool|static public static function findOrCreate(array $condition, array $attributes = []): bool|static
{ {
$logger = Snowflake::app()->getLogger(); $logger = Snowflake::app()->getLogger();
/** @var static $select */ /** @var static $select */
$select = static::find()->where($condition)->first(); $select = static::find()->where($condition)->first();
if (!empty($select)) { if (!empty($select)) {
return $select; return $select;
} }
if (empty($attributes)) { if (empty($attributes)) {
return $logger->addError(FIND_OR_CREATE_MESSAGE, 'mysql'); return $logger->addError(FIND_OR_CREATE_MESSAGE, 'mysql');
} }
$select = self::getModelClass(); $select = self::getModelClass();
$select->attributes = $attributes; $select->attributes = $attributes;
if (!$select->save()) { if (!$select->save()) {
return $logger->addError($select->getLastError(), 'mysql'); return $logger->addError($select->getLastError(), 'mysql');
} }
return $select; return $select;
} }
/** /**
* @param array $condition * @param array $condition
* @param array $attributes * @param array $attributes
* @return bool|static * @return bool|static
* @throws Exception * @throws Exception
*/ */
public static function createOrUpdate(array $condition, array $attributes = []): bool|static public static function createOrUpdate(array $condition, array $attributes = []): bool|static
{ {
$logger = Snowflake::app()->getLogger(); $logger = Snowflake::app()->getLogger();
if (empty($attributes)) { if (empty($attributes)) {
return $logger->addError(FIND_OR_CREATE_MESSAGE, 'mysql'); return $logger->addError(FIND_OR_CREATE_MESSAGE, 'mysql');
} }
/** @var static $select */ /** @var static $select */
$select = static::find()->where($condition)->first(); $select = static::find()->where($condition)->first();
if (empty($select)) { if (empty($select)) {
$select = self::getModelClass(); $select = self::getModelClass();
} }
$select->attributes = $attributes; $select->attributes = $attributes;
if (!$select->save()) { if (!$select->save()) {
return $logger->addError($select->getLastError(), 'mysql'); return $logger->addError($select->getLastError(), 'mysql');
} }
return $select; return $select;
} }
/** /**
* @return static * @return static
* @throws Exception * @throws Exception
*/ */
private static function getModelClass(): static private static function getModelClass(): static
{ {
$className = get_called_class(); $className = get_called_class();
/** @var Channel $channel */ /** @var Channel $channel */
$channel = Snowflake::app()->get('channel'); $channel = Snowflake::app()->get('channel');
return $channel->pop($className, function () use ($className) { return $channel->pop($className, function () use ($className) {
return new $className(); return new $className();
}); });
} }
/** /**
* @param $action * @param $action
* @param $columns * @param $columns
* @param array $condition * @param array $condition
* @return array|bool|int|string|null * @return array|bool|int|string|null
* @throws Exception * @throws Exception
*/ */
private function mathematics($columns, $action, $condition = []): int|bool|array|string|null private function mathematics($columns, $action, $condition = []): int|bool|array|string|null
{ {
if (empty($condition)) { if (empty($condition)) {
$condition = [$this->getPrimary() => $this->getPrimaryValue()]; $condition = [$this->getPrimary() => $this->getPrimaryValue()];
} }
$activeQuery = static::find()->where($condition); $activeQuery = static::find()->where($condition);
$create = SqlBuilder::builder($activeQuery)->mathematics($columns, $action); $create = SqlBuilder::builder($activeQuery)->mathematics($columns, $action);
if (is_bool($create)) { if (is_bool($create)) {
return false; return false;
} }
return static::getDb()->createCommand($create[0], $create[1])->exec(); return static::getDb()->createCommand($create[0], $create[1])->exec();
} }
/** /**
* @param array $fields * @param array $fields
* @return ActiveRecord|bool * @return ActiveRecord|bool
* @throws Exception * @throws Exception
*/ */
public function update(array $fields): static|bool public function update(array $fields): static|bool
{ {
return $this->save($fields); return $this->save($fields);
} }
/** /**
* @param array $data * @param array $data
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public static function inserts(array $data): bool public static function inserts(array $data): bool
{ {
/** @var static $class */ /** @var static $class */
$class = Snowflake::createObject(['class' => static::class]); $class = Snowflake::createObject(['class' => static::class]);
if (empty($data)) { if (empty($data)) {
return $class->addError('Insert data empty.', 'mysql'); return $class->addError('Insert data empty.', 'mysql');
} }
return $class::find()->batchInsert($data); return $class::find()->batchInsert($data);
} }
/** /**
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function delete(): bool public function delete(): bool
{ {
$conditions = $this->_oldAttributes; $conditions = $this->_oldAttributes;
if (empty($conditions)) { if (empty($conditions)) {
return $this->addError("Delete condition do not empty.", 'mysql'); return $this->addError("Delete condition do not empty.", 'mysql');
} }
$primary = $this->getPrimary(); $primary = $this->getPrimary();
if (!empty($primary)) { if (!empty($primary)) {
$conditions = [$primary => $this->getAttribute($primary)]; $conditions = [$primary => $this->getAttribute($primary)];
} }
return static::deleteByCondition($conditions); return static::deleteByCondition($conditions);
} }
/** /**
* @param $condition * @param $condition
* @param array $attributes * @param array $attributes
* *
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public static function updateAll(mixed $condition, $attributes = []): bool public static function updateAll(mixed $condition, $attributes = []): bool
{ {
$condition = static::find()->where($condition); $condition = static::find()->where($condition);
return $condition->batchUpdate($attributes); return $condition->batchUpdate($attributes);
} }
/** /**
* @param $condition * @param $condition
* @param array $attributes * @param array $attributes
* *
* @return array|Collection * @return array|Collection
* @throws Exception * @throws Exception
*/ */
public static function findAll($condition, $attributes = []): array|Collection public static function findAll($condition, $attributes = []): array|Collection
{ {
$query = static::find()->where($condition); $query = static::find()->where($condition);
if (!empty($attributes)) { if (!empty($attributes)) {
$query->bindParams($attributes); $query->bindParams($attributes);
} }
return $query->all(); return $query->all();
} }
/** /**
* @param $method * @param $method
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
private function resolveObject($method): mixed private function resolveObject($method): mixed
{ {
$resolve = $this->{$this->getRelate($method)}(); $resolve = $this->{$this->getRelate($method)}();
if ($resolve instanceof HasBase) { if ($resolve instanceof HasBase) {
$resolve = $resolve->get(); $resolve = $resolve->get();
} }
if ($resolve instanceof Collection) { if ($resolve instanceof Collection) {
return $resolve->toArray(); return $resolve->toArray();
} else if ($resolve instanceof ActiveRecord) { } else if ($resolve instanceof ActiveRecord) {
return $resolve->toArray(); return $resolve->toArray();
} else if (is_object($resolve)) { } else if (is_object($resolve)) {
return get_object_vars($resolve); return get_object_vars($resolve);
} else { } else {
return $resolve; return $resolve;
} }
} }
/** /**
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function toArray(): array public function toArray(): array
{ {
$data = $this->_attributes; $data = $this->_attributes;
foreach ($this->getAnnotation(self::ANNOTATION_GET) as $key => $item) {
if (!isset($data[$key])) continue;
$data[$key] = $this->runAnnotation($key, $data[$key] ?? null); $lists = Snowflake::getAnnotation()->getModelMethods(get_called_class());
} foreach ($lists as $key => $item) {
$data = array_merge($data, $this->runRelate()); $data[$key] = $this->{$item}($data[$key] ?? null);
return $data; }
} $data = array_merge($data, $this->runRelate());
return $data;
}
/** /**
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function runRelate(): array private function runRelate(): array
{ {
$relates = []; $relates = [];
if (empty($with = $this->getWith())) { if (empty($with = $this->getWith())) {
return $relates; return $relates;
} }
foreach ($with as $val) { foreach ($with as $val) {
$relates[$val] = $this->resolveObject($val); $relates[$val] = $this->resolveObject($val);
} }
return $relates; return $relates;
} }
/** /**
* @param string $modelName * @param string $modelName
* @param $foreignKey * @param $foreignKey
* @param $localKey * @param $localKey
* @return ActiveQuery * @return ActiveQuery
* @throws Exception * @throws Exception
*/ */
public function hasOne(string $modelName, $foreignKey, $localKey): mixed public function hasOne(string $modelName, $foreignKey, $localKey): mixed
{ {
if (!$this->has($localKey)) { if (!$this->has($localKey)) {
throw new Exception("Need join table primary key."); throw new Exception("Need join table primary key.");
} }
$value = $this->getAttribute($localKey); $value = $this->getAttribute($localKey);
$relation = $this->getRelation(); $relation = $this->getRelation();
return new HasOne($modelName, $foreignKey, $value, $relation); return new HasOne($modelName, $foreignKey, $value, $relation);
} }
/** /**
* @param $modelName * @param $modelName
* @param $foreignKey * @param $foreignKey
* @param $localKey * @param $localKey
* @return ActiveQuery * @return ActiveQuery
* @throws Exception * @throws Exception
*/ */
public function hasCount($modelName, $foreignKey, $localKey): mixed public function hasCount($modelName, $foreignKey, $localKey): mixed
{ {
if (!$this->has($localKey)) { if (!$this->has($localKey)) {
throw new Exception("Need join table primary key."); throw new Exception("Need join table primary key.");
} }
$value = $this->getAttribute($localKey); $value = $this->getAttribute($localKey);
$relation = $this->getRelation(); $relation = $this->getRelation();
return new HasCount($modelName, $foreignKey, $value, $relation); return new HasCount($modelName, $foreignKey, $value, $relation);
} }
/** /**
* @param $modelName * @param $modelName
* @param $foreignKey * @param $foreignKey
* @param $localKey * @param $localKey
* @return ActiveQuery * @return ActiveQuery
* @throws Exception * @throws Exception
*/ */
public function hasMany($modelName, $foreignKey, $localKey): mixed public function hasMany($modelName, $foreignKey, $localKey): mixed
{ {
if (!$this->has($localKey)) { if (!$this->has($localKey)) {
throw new Exception("Need join table primary key."); throw new Exception("Need join table primary key.");
} }
$value = $this->getAttribute($localKey); $value = $this->getAttribute($localKey);
$relation = $this->getRelation(); $relation = $this->getRelation();
return new HasMany($modelName, $foreignKey, $value, $relation); return new HasMany($modelName, $foreignKey, $value, $relation);
} }
/** /**
* @param $modelName * @param $modelName
* @param $foreignKey * @param $foreignKey
* @param $localKey * @param $localKey
* @return ActiveQuery * @return ActiveQuery
* @throws Exception * @throws Exception
*/ */
public function hasIn($modelName, $foreignKey, $localKey): mixed public function hasIn($modelName, $foreignKey, $localKey): mixed
{ {
if (!$this->has($localKey)) { if (!$this->has($localKey)) {
throw new Exception("Need join table primary key."); throw new Exception("Need join table primary key.");
} }
$value = $this->getAttribute($localKey); $value = $this->getAttribute($localKey);
$relation = $this->getRelation(); $relation = $this->getRelation();
return new HasMany($modelName, $foreignKey, $value, $relation); return new HasMany($modelName, $foreignKey, $value, $relation);
} }
/** /**
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function afterDelete(): bool public function afterDelete(): bool
{ {
if (!$this->hasPrimary()) { if (!$this->hasPrimary()) {
return TRUE; return TRUE;
} }
$value = $this->getPrimaryValue(); $value = $this->getPrimaryValue();
if (empty($value)) { if (empty($value)) {
return TRUE; return TRUE;
} }
return TRUE; return TRUE;
} }
/** /**
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function beforeDelete(): bool public function beforeDelete(): bool
{ {
if (!$this->hasPrimary()) { if (!$this->hasPrimary()) {
return TRUE; return TRUE;
} }
$value = $this->getPrimaryValue(); $value = $this->getPrimaryValue();
if (empty($value)) { if (empty($value)) {
return TRUE; return TRUE;
} }
return TRUE; return TRUE;
} }
} }
+1 -7
View File
@@ -383,13 +383,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
*/ */
public function getAttributes(): array public function getAttributes(): array
{ {
$data = $this->_attributes; return $this->toArray();
foreach ($this->getAnnotation() as $key => $item) {
if (!isset($data[$key])) continue;
$data[$key] = $this->runAnnotation($key, $data[$key] ?? null);
}
return $data;
} }
/** /**