• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tempestphp / tempest-framework / 14122915110

28 Mar 2025 05:56AM UTC coverage: 79.691% (+0.4%) from 79.334%
14122915110

Pull #1076

github

web-flow
Merge 2ccad9efc into 6af05d563
Pull Request #1076: refactor(database): remove `DatabaseModel` interface

558 of 571 new or added lines in 42 files covered. (97.72%)

1 existing line in 1 file now uncovered.

10767 of 13511 relevant lines covered (79.69%)

93.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.15
/src/Tempest/Database/src/Builder/QueryBuilders/UpdateQueryBuilder.php
1
<?php
2

3
namespace Tempest\Database\Builder\QueryBuilders;
4

5
use Tempest\Database\Exceptions\CannotUpdateHasManyRelation;
6
use Tempest\Database\Id;
7
use Tempest\Database\Query;
8
use Tempest\Database\QueryStatements\UpdateStatement;
9
use Tempest\Database\QueryStatements\WhereStatement;
10
use Tempest\Mapper\SerializerFactory;
11
use Tempest\Reflection\ClassReflector;
12
use Tempest\Support\Arr\ImmutableArray;
13

14
use function Tempest\Database\model;
15
use function Tempest\Support\arr;
16

17
final class UpdateQueryBuilder
18
{
19
    private UpdateStatement $update;
20

21
    private array $bindings = [];
22

23
    public function __construct(
13✔
24
        private string|object $model,
25
        private array|ImmutableArray $values,
26
        private SerializerFactory $serializerFactory,
27
    ) {
28
        $this->update = new UpdateStatement(
13✔
29
            table: model($this->model)->getTableDefinition(),
13✔
30
        );
13✔
31
    }
32

33
    public function execute(...$bindings): Id
3✔
34
    {
35
        return $this->build()->execute(...$bindings);
3✔
36
    }
37

38
    public function allowAll(): self
1✔
39
    {
40
        $this->update->allowAll = true;
1✔
41

42
        return $this;
1✔
43
    }
44

45
    public function where(string $where, mixed ...$bindings): self
11✔
46
    {
47
        $this->update->where[] = new WhereStatement($where);
11✔
48

49
        $this->bind(...$bindings);
11✔
50

51
        return $this;
11✔
52
    }
53

54
    public function bind(mixed ...$bindings): self
11✔
55
    {
56
        $this->bindings = [...$this->bindings, ...$bindings];
11✔
57

58
        return $this;
11✔
59
    }
60

61
    public function build(): Query
13✔
62
    {
63
        $values = $this->resolveValues();
13✔
64

65
        unset($values['id']);
13✔
66

67
        $this->update->values = $values;
13✔
68

69
        if (model($this->model)->isObjectModel() && is_object($this->model)) {
13✔
70
            $this->where('`id` = ?', id: $this->model->id->id);
9✔
71
        }
72

73
        $bindings = [];
13✔
74

75
        foreach ($values as $value) {
13✔
76
            $bindings[] = $value;
13✔
77
        }
78

79
        foreach ($this->bindings as $binding) {
13✔
80
            $bindings[] = $binding;
11✔
81
        }
82

83
        return new Query($this->update, $bindings);
13✔
84
    }
85

86
    private function resolveValues(): ImmutableArray
13✔
87
    {
88
        if (! model($this->model)->isObjectModel()) {
13✔
89
            return arr($this->values);
3✔
90
        }
91

92
        $values = arr();
10✔
93

94
        $modelClass = new ClassReflector($this->model);
10✔
95

96
        foreach ($this->values as $column => $value) {
10✔
97
            $property = $modelClass->getProperty($column);
10✔
98

99
            if ($property->getIterableType()?->isRelation()) {
10✔
NEW
100
                throw new CannotUpdateHasManyRelation($modelClass->getName(), $property->getName());
×
101
            }
102

103
            if ($property->getType()->isRelation()) {
10✔
104
                $column .= '_id';
3✔
105

106
                $value = match (true) {
3✔
107
                    $value === null => null,
1✔
108
                    isset($value->id) => $value->id->id,
2✔
109
                    default => new InsertQueryBuilder(
1✔
110
                        $value::class,
1✔
111
                        [$value],
1✔
112
                        $this->serializerFactory,
1✔
113
                    )->build(),
1✔
114
                };
3✔
115
            }
116

117
            if (! $property->getType()->isRelation() && ! $property->getIterableType()?->isRelation()) {
10✔
118
                $serializer = $this->serializerFactory->forProperty($property);
8✔
119

120
                if ($value !== null && $serializer !== null) {
8✔
121
                    $value = $serializer->serialize($value);
8✔
122
                }
123
            }
124

125
            $values[$column] = $value;
10✔
126
        }
127

128
        return $values;
10✔
129
    }
130
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc