Lines 88.88% 8 / 9
Functions and Methods 88.88% 8 / 9
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
WhereBuilder 88.88% 8 / 9 88.88% 8 / 9 9.11 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 where 100.00% 1 / 1 100.00% 1 / 1 1
 whereNested 100.00% 1 / 1 100.00% 1 / 1 1
 whereExists 100.00% 1 / 1 100.00% 1 / 1 1
 whereInQuery 0.00% 0 / 1 0.00% 0 / 1 2
 whereRaw 100.00% 1 / 1 100.00% 1 / 1 1
 whereColumn 100.00% 1 / 1 100.00% 1 / 1 1
 getWheres 100.00% 1 / 1 100.00% 1 / 1 1
 getNestedQuery 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace BlueprintAU\Radiant\Database\Query;
6
7use BlueprintAU\Radiant\Concerns\FiltersWhere;
8use BlueprintAU\Radiant\Database\Query\Enums\WhereBoolean;
9use BlueprintAU\Radiant\Database\Query\Enums\WhereOperator;
10
11/**
12 * The where-family builder handed to {@see QueryBuilder::whereNested()}
13 * callbacks — the vocabulary a parenthesized group may legally carry.
14 *
15 * It holds no clauses itself — it delegates everything to the underlying
16 * query builder, where the clause list, bindings, and validation already
17 * live.
18 *
19 * @phpstan-import-type WhereClause from \BlueprintAU\Radiant\Database\Query\QueryBuilder
20 */
21final class WhereBuilder
22{
23    use FiltersWhere;
24
25    /**
26     * Create a builder over the given query.
27     *
28     * @param  QueryBuilder  $query
29     */
30    public function __construct(
31        private readonly QueryBuilder $query,
32    ) {
33    }
34
35    /**
36     * Add a where clause to the query.
37     *
38     * @param  string|Expression  $column
39     * @param  WhereOperator|string  $operator
40     * @param  mixed  $value
41     * @param  WhereBoolean  $boolean
42     * @return static
43     */
44    public function where(
45        string|Expression $column,
46        WhereOperator|string $operator,
47        mixed $value,
48        WhereBoolean $boolean = WhereBoolean::And,
49    ): static {
50        return new self($this->query->where($column, $operator, $value, $boolean));
51    }
52
53    /**
54     * Add a nested where group to the query.
55     *
56     * @param  callable(WhereBuilder): WhereBuilder  $callback
57     * @param  WhereBoolean  $boolean
58     * @return static
59     */
60    public function whereNested(
61        callable $callback,
62        WhereBoolean $boolean = WhereBoolean::And,
63    ): static {
64        return new self($this->query->whereNested($callback, $boolean));
65    }
66
67    /**
68     * Add an `EXISTS (subquery)` clause to the query.
69     *
70     * @param  QueryBuilder  $query  The existential subquery.
71     * @param  WhereBoolean  $boolean
72     * @param  bool  $negated  True renders `NOT EXISTS`.
73     * @return static
74     */
75    public function whereExists(
76        QueryBuilder $query,
77        WhereBoolean $boolean = WhereBoolean::And,
78        bool $negated = false,
79    ): static {
80        return new self($this->query->whereExists($query, $boolean, $negated));
81    }
82
83    /**
84     * Add a `column IN (subquery)` clause to the query.
85     *
86     * @param  string  $column  The outer column the IN constrains.
87     * @param  QueryBuilder  $query  The single-column value subquery.
88     * @param  WhereBoolean  $boolean
89     * @param  bool  $negated  True renders `NOT IN`.
90     * @return static
91     */
92    public function whereInQuery(
93        string $column,
94        QueryBuilder $query,
95        WhereBoolean $boolean = WhereBoolean::And,
96        bool $negated = false,
97    ): static {
98        return new self($this->query->whereInQuery($column, $query, $boolean, $negated));
99    }
100
101    /**
102     * Add a raw where clause to the query.
103     *
104     * @param  string  $sql
105     * @param  array<int, mixed>  $bindings
106     * @param  WhereBoolean  $boolean
107     * @return static
108     */
109    public function whereRaw(string $sql, array $bindings = [], WhereBoolean $boolean = WhereBoolean::And): static
110    {
111        return new self($this->query->whereRaw($sql, $bindings, $boolean));
112    }
113
114    /**
115     * Add a where clause comparing two columns to the query.
116     *
117     * @param  string  $first
118     * @param  \BlueprintAU\Radiant\Database\Query\Enums\ColumnOperator|string  $operator
119     * @param  string  $second
120     * @param  WhereBoolean  $boolean
121     * @return static
122     */
123    public function whereColumn(string $first, \BlueprintAU\Radiant\Database\Query\Enums\ColumnOperator|string $operator = '=', string $second = '', WhereBoolean $boolean = WhereBoolean::And): static
124    {
125        return new self($this->query->whereColumn($first, $operator, $second, $boolean));
126    }
127
128    /**
129     * Get the where clauses of the query.
130     *
131     * @return list<WhereClause>
132     */
133    public function getWheres(): array
134    {
135        return $this->query->getWheres();
136    }
137
138    /**
139     * Get the underlying query builder.
140     *
141     * @return QueryBuilder
142     */
143    public function getNestedQuery(): QueryBuilder
144    {
145        return $this->query;
146    }
147}