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

tempestphp / tempest-framework / 14101306725

27 Mar 2025 07:40AM UTC coverage: 79.503% (+0.2%) from 79.334%
14101306725

Pull #1076

github

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

355 of 362 new or added lines in 34 files covered. (98.07%)

1 existing line in 1 file now uncovered.

10632 of 13373 relevant lines covered (79.5%)

92.08 hits per line

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

98.39
/src/Tempest/Database/src/IsDatabaseModel.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\Database;
6

7
use Tempest\Database\Builder\QueryBuilders\SelectQueryBuilder;
8
use Tempest\Database\Exceptions\MissingRelation;
9
use Tempest\Database\Exceptions\MissingValue;
10
use Tempest\Reflection\ClassReflector;
11
use Tempest\Reflection\PropertyReflector;
12

13
use function Tempest\make;
14

15
trait IsDatabaseModel
16
{
17
    public ?Id $id = null;
18

19
    public static function new(mixed ...$params): self
62✔
20
    {
21
        return make(self::class)->from($params);
62✔
22
    }
23

24
    public static function resolve(string $input): static
1✔
25
    {
26
        return self::get(new Id($input));
1✔
27
    }
28

29
    /**
30
     * @return \Tempest\Database\Builder\QueryBuilders\SelectQueryBuilder<self>
31
     */
32
    public static function select(): SelectQueryBuilder
49✔
33
    {
34
        return query(self::class)->select();
49✔
35
    }
36

37
    /** @return self[] */
38
    public static function all(array $relations = []): array
14✔
39
    {
40
        return self::select()
14✔
41
            ->with(...$relations)
14✔
42
            ->all();
14✔
43
    }
44

45
    public static function get(Id $id, array $relations = []): ?self
20✔
46
    {
47
        return self::select()
20✔
48
            ->with(...$relations)
20✔
49
            ->get($id);
20✔
50
    }
51

52
    public static function find(mixed ...$conditions): SelectQueryBuilder
1✔
53
    {
54
        $query = self::select();
1✔
55

56
        array_walk($conditions, fn ($value, $column) => $query->whereField($column, $value));
1✔
57

58
        return $query;
1✔
59
    }
60

61
    public static function create(mixed ...$params): self
57✔
62
    {
63
        return self::new(...$params)->save();
57✔
64
    }
65

66
    public static function updateOrNew(array $find, array $update): self
1✔
67
    {
68
        $existing = self::select()->bind(...$find);
1✔
69

70
        foreach ($find as $key => $value) {
1✔
71
            $existing = $existing->where("{$key} = :{$key}");
1✔
72
        }
73

74
        $model = $existing->first() ?? self::new(...$find);
1✔
75

76
        foreach ($update as $key => $value) {
1✔
77
            $model->{$key} = $value;
1✔
78
        }
79

80
        return $model;
1✔
81
    }
82

83
    public static function updateOrCreate(array $find, array $update): self
1✔
84
    {
85
        return self::updateOrNew($find, $update)->save();
1✔
86
    }
87

88
    public function __get(string $name): mixed
3✔
89
    {
90
        $property = PropertyReflector::fromParts($this, $name);
3✔
91

92
        if ($property->hasAttribute(Lazy::class)) {
3✔
93
            $this->load($name);
1✔
94

95
            return $property->getValue($this);
1✔
96
        }
97

98
        $type = $property->getType();
2✔
99

100
        if ($type->isIterable()) {
2✔
NEW
101
            throw new MissingRelation($this, $name);
×
102
        }
103

104
        if ($type->isBuiltIn()) {
2✔
105
            throw new MissingValue($this, $name);
1✔
106
        }
107

108
        throw new MissingRelation($this, $name);
1✔
109
    }
110

111
    public function load(string ...$relations): self
9✔
112
    {
113
        $new = self::get($this->id, $relations);
9✔
114

115
        foreach (new ClassReflector($new)->getPublicProperties() as $property) {
9✔
116
            $property->setValue($this, $property->getValue($new));
9✔
117
        }
118

119
        return $this;
9✔
120
    }
121

122
    public function save(): self
57✔
123
    {
124
        if ($this->id === null) {
57✔
125
            $query = query($this)->create();
57✔
126
        } else {
127
            $query = query($this)->update();
4✔
128
        }
129

130
        $id = $query->build()->execute();
57✔
131

132
        $this->id = $id;
57✔
133

134
        return $this;
57✔
135
    }
136

137
    public function update(mixed ...$params): self
1✔
138
    {
139
        foreach ($params as $key => $value) {
1✔
140
            $this->{$key} = $value;
1✔
141
        }
142

143
        return $this->save();
1✔
144
    }
145

146
    public function delete(): void
2✔
147
    {
148
        query($this)
2✔
149
            ->delete()
2✔
150
            ->build()
2✔
151
            ->execute();
2✔
152
    }
153
}
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