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