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

tempestphp / tempest-framework / 14101947540

27 Mar 2025 08:19AM UTC coverage: 79.533% (+0.2%) from 79.334%
14101947540

Pull #1076

github

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

411 of 420 new or added lines in 34 files covered. (97.86%)

1 existing line in 1 file now uncovered.

10651 of 13392 relevant lines covered (79.53%)

92.36 hits per line

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

96.36
/src/Tempest/Database/src/Builder/QueryBuilders/CreateQueryBuilder.php
1
<?php
2

3
namespace Tempest\Database\Builder\QueryBuilders;
4

5
use Tempest\Database\Builder\ModelDefinition;
6
use Tempest\Database\Id;
7
use Tempest\Database\Query;
8
use Tempest\Mapper\SerializerFactory;
9
use Tempest\Reflection\ClassReflector;
10

11
/**
12
 * @template TModelClass of object
13
 */
14
final readonly class CreateQueryBuilder
15
{
16
    public function __construct(
59✔
17
        private object $model,
18
        private SerializerFactory $serializerFactory,
19
    ) {}
59✔
20

NEW
21
    public function execute(...$bindings): Id
×
22
    {
NEW
23
        return $this->build()->execute(...$bindings);
×
24
    }
25

26
    public function build(): Query
59✔
27
    {
28
        $modelClass = new ClassReflector($this->model);
59✔
29
        $modelDefinition = new ModelDefinition($this->model);
59✔
30

31
        $fields = $this->fields($modelClass, $this->model);
59✔
32

33
        unset($fields['id']);
59✔
34

35
        $columns = [];
59✔
36
        $valuePlaceholders = [];
59✔
37
        $bindings = [];
59✔
38

39
        foreach ($fields as $key => $value) {
59✔
40
            $columns[] = $key;
59✔
41
            $valuePlaceholders[] = ":{$key}";
59✔
42
            $bindings[$key] = $value;
59✔
43
        }
44

45
        $relations = $this->relations($modelClass, $this->model);
59✔
46

47
        foreach ($relations as $key => $relation) {
59✔
48
            $key = "{$key}_id";
30✔
49
            $columns[] = $key;
30✔
50
            $valuePlaceholders[] = ":{$key}";
30✔
51

52
            if ($relation !== null) {
30✔
53
                $bindings[$key] = $relation->id ?? new self($relation, $this->serializerFactory)->build();
23✔
54
            } else {
55
                $bindings[$key] = null;
8✔
56
            }
57
        }
58

59
        $valuePlaceholders = implode(', ', $valuePlaceholders);
59✔
60
        $columns = implode(', ', $columns);
59✔
61
        $table = $modelDefinition->getTableDefinition();
59✔
62

63
        return new Query(
59✔
64
            "INSERT INTO {$table} ({$columns}) VALUES ({$valuePlaceholders});",
59✔
65
            $bindings,
59✔
66
        );
59✔
67
    }
68

69
    // TODO: move to model definition class?
70
    private function fields(ClassReflector $modelClass, object $model): array
59✔
71
    {
72
        $fields = [];
59✔
73

74
        foreach ($modelClass->getPublicProperties() as $property) {
59✔
75
            if (! $property->isInitialized($model)) {
59✔
76
                continue;
7✔
77
            }
78

79
            // 1:1 or n:1 relations
80
            if ($property->getType()->isRelation()) {
59✔
81
                continue;
30✔
82
            }
83

84
            // 1:n relations
85
            if ($property->getIterableType()?->isRelation()) {
59✔
86
                continue;
31✔
87
            }
88

89
            $value = $property->getValue($model);
59✔
90

91
            // Check if serializer is available for value serialization
92
            if ($value !== null && ($serializer = $this->serializerFactory->forProperty($property))) {
59✔
93
                $value = $serializer->serialize($value);
59✔
94
            }
95

96
            $fields[$property->getName()] = $value;
59✔
97
        }
98

99
        return $fields;
59✔
100
    }
101

102
    // TODO: move to model definition class?
103
    private function relations(ClassReflector $modelClass, object $model): array
59✔
104
    {
105
        $fields = [];
59✔
106

107
        foreach ($modelClass->getPublicProperties() as $property) {
59✔
108
            if (! $property->isInitialized($model)) {
59✔
109
                continue;
7✔
110
            }
111

112
            if (! $property->getType()->isRelation()) {
59✔
113
                continue;
59✔
114
            }
115

116
            $value = $property->getValue($model);
30✔
117

118
            // Only 1:1 or n:1 relations
119
            $fields[$property->getName()] = $value;
30✔
120
        }
121

122
        return $fields;
59✔
123
    }
124
}
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