Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 51 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
JoinGroupBase | |
0.00% |
0 / 51 |
|
0.00% |
0 / 5 |
380 | |
0.00% |
0 / 1 |
table | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
56 | |||
leftJoin | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
join | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
straightJoin | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
addJoin | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
90 | |||
getAutoAlias | n/a |
0 / 0 |
n/a |
0 / 0 |
0 |
1 | <?php |
2 | |
3 | namespace Wikimedia\Rdbms; |
4 | |
5 | use InvalidArgumentException; |
6 | |
7 | /** |
8 | * Shared code between SelectQueryBuilder and JoinGroup to represent tables and join conditions. |
9 | * |
10 | * @internal |
11 | */ |
12 | abstract class JoinGroupBase { |
13 | /** @var array */ |
14 | protected $tables = []; |
15 | |
16 | /** @var array */ |
17 | protected $joinConds = []; |
18 | |
19 | /** @var string|null */ |
20 | protected $lastAlias; |
21 | |
22 | /** |
23 | * Add a single table or a single parenthesized group. |
24 | * |
25 | * @param string|JoinGroup|Subquery|SelectQueryBuilder $table The unqualified name of a table, |
26 | * a table name of the form "information_schema.<unquoted identifier>", a JoinGroup |
27 | * containing multiple tables, a Subquery instance, or a SelectQueryBuilder representing a subquery. |
28 | * @param-taint $table exec_sql |
29 | * @param string|null $alias The table alias, or null for no alias |
30 | * @param-taint $alias exec_sql |
31 | * @return $this |
32 | */ |
33 | public function table( $table, $alias = null ) { |
34 | if ( $table instanceof JoinGroup ) { |
35 | $alias ??= $table->getAlias(); |
36 | $table = $table->getRawTables(); |
37 | } elseif ( $table instanceof SelectQueryBuilder ) { |
38 | $alias ??= $this->getAutoAlias(); |
39 | $table = new Subquery( $table->getSQL() ); |
40 | } elseif ( $table instanceof Subquery ) { |
41 | if ( $alias === null ) { |
42 | throw new InvalidArgumentException( __METHOD__ . |
43 | ': Subquery as table must provide an alias.' ); |
44 | } |
45 | } elseif ( !is_string( $table ) ) { |
46 | throw new InvalidArgumentException( __METHOD__ . |
47 | ': $table must be either string, JoinGroup or SelectQueryBuilder' ); |
48 | } |
49 | if ( $alias === null ) { |
50 | $this->tables[] = $table; |
51 | $this->lastAlias = $table; |
52 | } else { |
53 | $this->tables[$alias] = $table; |
54 | $this->lastAlias = $alias; |
55 | } |
56 | return $this; |
57 | } |
58 | |
59 | /** |
60 | * Left join a table or group of tables. This should be called after table(). |
61 | * |
62 | * @param string|JoinGroup|SelectQueryBuilder $table The unqualified name of a table, |
63 | * a table name of the form "information_schema.<unquoted identifier>", a JoinGroup |
64 | * containing multiple tables, or a SelectQueryBuilder representing a subquery. |
65 | * @param string|null $alias The alias name, or null to automatically |
66 | * generate an alias which will be unique to this builder |
67 | * @param string|array $conds The conditions for the ON clause |
68 | * @return $this |
69 | */ |
70 | public function leftJoin( $table, $alias = null, $conds = [] ) { |
71 | $this->addJoin( 'LEFT JOIN', $table, $alias, $conds ); |
72 | return $this; |
73 | } |
74 | |
75 | /** |
76 | * Inner join a table or group of tables. This should be called after table(). |
77 | * |
78 | * @param string|JoinGroup|SelectQueryBuilder $table The unqualified name of a table, |
79 | * a table name of the form "information_schema.<unquoted identifier>", a JoinGroup |
80 | * containing multiple tables, or a SelectQueryBuilder representing a subquery. |
81 | * @param string|null $alias The alias name, or null to automatically |
82 | * generate an alias which will be unique to this builder |
83 | * @param string|array $conds The conditions for the ON clause |
84 | * @return $this |
85 | */ |
86 | public function join( $table, $alias = null, $conds = [] ) { |
87 | $this->addJoin( 'JOIN', $table, $alias, $conds ); |
88 | return $this; |
89 | } |
90 | |
91 | /** |
92 | * Straight join a table or group of tables. This should be called after table(). |
93 | * |
94 | * @param string|JoinGroup|SelectQueryBuilder $table The unqualified name of a table, |
95 | * a table name of the form "information_schema.<unquoted identifier>", a JoinGroup |
96 | * containing multiple tables, or a SelectQueryBuilder representing a subquery. |
97 | * @param string|null $alias The alias name, or null to automatically |
98 | * generate an alias which will be unique to this builder |
99 | * @param string|array $conds The conditions for the ON clause |
100 | * @return $this |
101 | */ |
102 | public function straightJoin( $table, $alias = null, $conds = [] ) { |
103 | $this->addJoin( 'STRAIGHT_JOIN', $table, $alias, $conds ); |
104 | return $this; |
105 | } |
106 | |
107 | /** |
108 | * Private helper for functions that add joins |
109 | * @param string $type |
110 | * @param string|JoinGroup|SelectQueryBuilder $table |
111 | * @param string|null $alias |
112 | * @param string|array $joinConds |
113 | */ |
114 | private function addJoin( $type, $table, $alias, $joinConds ) { |
115 | if ( !$this->tables ) { |
116 | throw new \LogicException( __METHOD__ . |
117 | ': cannot add a join unless a regular table is added first' ); |
118 | } |
119 | if ( $alias === null ) { |
120 | if ( is_string( $table ) ) { |
121 | $alias = $table; |
122 | } else { |
123 | $alias = $this->getAutoAlias(); |
124 | } |
125 | } |
126 | if ( isset( $this->joinConds[$alias] ) ) { |
127 | throw new \LogicException( __METHOD__ . |
128 | ": a join with alias \"$alias\" has already been added" ); |
129 | } |
130 | if ( $table instanceof JoinGroup ) { |
131 | $conflicts = array_intersect_key( $this->joinConds, $table->getRawJoinConds() ); |
132 | if ( $conflicts ) { |
133 | $conflict = reset( $conflicts ); |
134 | throw new \LogicException( __METHOD__ . |
135 | ": a join with alias \"$conflict\" has already been added" ); |
136 | } |
137 | $this->tables[$alias] = $table->getRawTables(); |
138 | $this->joinConds += $table->getRawJoinConds(); |
139 | } elseif ( $table instanceof SelectQueryBuilder ) { |
140 | $this->tables[$alias] = new Subquery( $table->getSQL() ); |
141 | } elseif ( is_string( $table ) ) { |
142 | $this->tables[$alias] = $table; |
143 | } else { |
144 | throw new InvalidArgumentException( __METHOD__ . |
145 | ': $table must be either string, JoinGroup or SelectQueryBuilder' ); |
146 | } |
147 | $this->joinConds[$alias] = [ $type, $joinConds ]; |
148 | $this->lastAlias = $alias; |
149 | } |
150 | |
151 | abstract protected function getAutoAlias(); |
152 | } |