Passed
Pull Request — next (#145)
by Bas
15:26 queued 11:34
created

Builder   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 95.65%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
c 1
b 0
f 0
dl 0
loc 134
ccs 44
cts 46
cp 0.9565
rs 10
wmc 18

5 Methods

Rating   Name   Duplication   Size   Complexity  
A updateTimestamps() 0 27 6
A insert() 0 29 6
A addUpdatedAtColumn() 0 17 3
A createOrFirst() 0 7 2
A getQuery() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Eloquent;
6
7
use Illuminate\Database\Eloquent\Builder as IlluminateEloquentBuilder;
8
use Illuminate\Support\Arr;
9
use LaravelFreelancerNL\Aranguent\Eloquent\Concerns\QueriesAranguentRelationships;
10
use LaravelFreelancerNL\Aranguent\Exceptions\UniqueConstraintViolationException;
11
use LaravelFreelancerNL\Aranguent\Query\Builder as QueryBuilder;
12
13
class Builder extends IlluminateEloquentBuilder
14
{
15
    use QueriesAranguentRelationships;
0 ignored issues
show
introduced by
The trait LaravelFreelancerNL\Aran...sAranguentRelationships requires some properties which are not provided by LaravelFreelancerNL\Aranguent\Eloquent\Builder: $grammar, $from
Loading history...
16
17
    /**
18
     * The base query builder instance.
19
     *
20
     * @var QueryBuilder
21
     */
22
    protected $query;
23
24
    /**
25
     * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.
26
     *
27
     * @param  mixed[]  $attributes
28
     * @param  mixed[]  $values
29
     * @return \Illuminate\Database\Eloquent\Model|static
30
     */
31 9
    public function createOrFirst(array $attributes = [], array $values = [])
32
    {
33
        try {
34 9
            return $this->withSavepointIfNeeded(fn() => $this->create(array_merge($attributes, $values)));
35 2
        } catch (UniqueConstraintViolationException $e) {
36 2
            ray($e);
37 2
            return $this->useWritePdo()->where($attributes)->first() ?? throw $e;
0 ignored issues
show
Bug introduced by
The method useWritePdo() does not exist on LaravelFreelancerNL\Aranguent\Eloquent\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
            return $this->/** @scrutinizer ignore-call */ useWritePdo()->where($attributes)->first() ?? throw $e;
Loading history...
38
        }
39
    }
40
41
    /**
42
     * Insert a record in the database.
43
     *
44
     *
45
     * @param array<mixed> $values
46
     * @return bool
47
     */
48 6
    public function insert(array $values)
49
    {
50
        // Since every insert gets treated like a batch insert, we will make sure the
51
        // bindings are structured in a way that is convenient when building these
52
        // inserts statements by verifying these elements are actually an array.
53 6
        if (empty($values)) {
54
            return true;
55
        }
56
57 6
        if (Arr::isAssoc($values)) {
58 6
            $values = [$values];
59
        }
60 6
        if (!Arr::isAssoc($values)) {
61
            // Here, we will sort the insert keys for every record so that each insert is
62
            // in the same order for the record. We need to make sure this is the case
63
            // so there are not any errors or problems when inserting these records.
64 6
            foreach ($values as $key => $value) {
65 6
                ksort($value);
66
67 6
                $values[$key] = $value;
68
            }
69
        }
70
71
        //Set timestamps
72 6
        foreach ($values as $key => $value) {
73 6
            $values[$key] = $this->updateTimestamps($value);
74
        }
75
76 6
        return $this->toBase()->insert($values);
77
    }
78
79
    /**
80
     * Add the "updated at" column to an array of values.
81
     *
82
     * @param array<string, string> $values
83
     * @return array<string, string>
84
     */
85 6
    protected function updateTimestamps(array $values)
86
    {
87
        if (
88 6
            !$this->model->usesTimestamps() ||
89 2
            is_null($this->model->getUpdatedAtColumn()) ||
90 6
            is_null($this->model->getCreatedAtColumn())
91
        ) {
92 4
            return $values;
93
        }
94
95 2
        $timestamp = $this->model->freshTimestampString();
96 2
        $updatedAtColumn = $this->model->getUpdatedAtColumn();
97
98 2
        $timestamps = [];
99 2
        $timestamps[$updatedAtColumn] = $timestamp;
100
101 2
        $createdAtColumn = $this->model->getCreatedAtColumn();
102 2
        if (!isset($values[$createdAtColumn]) && !isset($this->model->$createdAtColumn)) {
103 2
            $timestamps[$createdAtColumn] = $timestamp;
104
        }
105
106 2
        $values = array_merge(
107 2
            $timestamps,
108 2
            $values,
109 2
        );
110
111 2
        return $values;
112
    }
113
114
    /**
115
     * Add the "updated at" column to an array of values.
116
     *
117
     * @param array<string> $values
118
     * @return array<string>
119
     */
120 24
    protected function addUpdatedAtColumn(array $values): array
121
    {
122
        if (
123 24
            !$this->model->usesTimestamps() ||
124 24
            is_null($this->model->getUpdatedAtColumn())
125
        ) {
126
            return $values;
127
        }
128
129 24
        $column = $this->model->getUpdatedAtColumn();
130
131 24
        $values = array_merge(
132 24
            [$column => $this->model->freshTimestampString()],
133 24
            $values,
134 24
        );
135
136 24
        return $values;
137
    }
138
139
    /**
140
     * Get the underlying query builder instance.
141
     *
142
     * @return QueryBuilder
143
     */
144 115
    public function getQuery()
145
    {
146 115
        return $this->query;
147
    }
148
}
149