Skip to content

Commit

Permalink
You can set an expression to model parameters, but it is not standard…
Browse files Browse the repository at this point in the history
…ized. (#6556)


Co-authored-by: 李铭昕 <715557344@qq.com>
  • Loading branch information
szutoutou and limingxinleo committed Feb 28, 2024
1 parent 22df098 commit 9528e1d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Model/Concerns/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use Hyperf\Database\Model\EnumCollector;
use Hyperf\Database\Model\JsonEncodingException;
use Hyperf\Database\Model\Relations\Relation;
use Hyperf\Database\Query\Expression;
use Hyperf\Stringable\Str;
use Hyperf\Stringable\StrCache;
use LogicException;
Expand Down Expand Up @@ -629,6 +630,14 @@ public function originalIsEquivalent(string $key, mixed $current): bool
return false;
}

// The model parameters should not be set with an expression,
// Because after saving the expression, the parameters of the model will not receive the latest results,
// When the model be used again, It will cause some problems.
// So you must do something by yourself, the framework shouldn't be modified in any way.
if ($current instanceof Expression) {
return false;
}

if ($this->isDateAttribute($key)) {
return $this->fromDateTime($current) ===
$this->fromDateTime($original);
Expand Down
45 changes: 45 additions & 0 deletions tests/ModelRealBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,51 @@ public function testSaveBitValue()
$this->assertTrue($model->save());
}

public function testSaveExpression()
{
$container = $this->getContainer();
$container->shouldReceive('get')->with(Db::class)->andReturn(new Db($container));

/** @var UserExt $ext */
$ext = UserExt::query()->find(1);
$ext->timestamps = false;

$this->assertFalse($ext->isDirty());
$ext->count = Db::raw('`count` + 1');
$this->assertTrue($ext->isDirty('count'));
$this->assertTrue($ext->save());

$this->assertFalse($ext->isDirty());
$ext->float_num = Db::raw('`float_num` + 0.1');
$this->assertTrue($ext->isDirty('float_num'));
$this->assertTrue($ext->save());

$this->assertFalse($ext->isDirty());
$ext->str = Db::raw('concat(`str`, \'t\')');
$this->assertTrue($ext->isDirty('str'));
$this->assertTrue($ext->save());

$this->assertFalse($ext->isDirty());
$ext->count = Db::raw('`count` + 1');
$ext->float_num = Db::raw('`float_num` + 0.1');
$ext->str = Db::raw('concat(`str`, \'e\')');
$this->assertTrue($ext->isDirty());
$this->assertTrue($ext->save());

$sqls = [
'select * from `user_ext` where `user_ext`.`id` = ? limit 1',
'update `user_ext` set `count` = `count` + 1 where `id` = ?',
'update `user_ext` set `float_num` = `float_num` + 0.1 where `id` = ?',
'update `user_ext` set `str` = concat(`str`, \'t\') where `id` = ?',
'update `user_ext` set `count` = `count` + 1, `float_num` = `float_num` + 0.1, `str` = concat(`str`, \'e\') where `id` = ?',
];
while ($event = $this->channel->pop(0.001)) {
if ($event instanceof QueryExecuted) {
$this->assertSame($event->sql, array_shift($sqls));
}
}
}

public function testSelectForBindingIntegerWhenUsingVarcharIndex()
{
$container = $this->getContainer();
Expand Down

0 comments on commit 9528e1d

Please sign in to comment.