@@ -68,82 +68,103 @@ public function getWhereSql(array $sql): array
6868 * Get sql.
6969 *
7070 * @param array $sql
71+ * @param array $where
72+ * @param string $conditionType
7173 * @return array
7274 */
73- public function getHavingSql (array $ sql ): array
75+ public function getConditionSql (array $ sql, array $ where , string $ conditionType ): array
7476 {
75- return $ this ->getConditionSql ($ sql , $ this ->having , 'HAVING ' );
76- }
77+ if (empty ($ where )) {
78+ return $ sql ;
79+ }
80+ foreach ($ where as $ index => $ item ) {
81+ if ($ item instanceof RawExp) {
82+ $ sql [] = $ item ->getValue ();
83+ continue ;
84+ }
85+ list ($ type , $ conditions ) = $ item ;
86+ if (!$ index ) {
87+ $ whereType = $ conditionType ;
88+ } else {
89+ $ whereType = strtoupper ($ type );
90+ }
91+ if ($ conditions [0 ] instanceof RawExp) {
92+ $ sql [] = $ whereType . ' ' . $ conditions [0 ]->getValue ();
93+ continue ;
94+ }
95+ list ($ leftField , $ operator , $ rightField ) = $ conditions ;
96+ $ leftField = $ this ->quoter ->quoteName ($ leftField );
97+ list ($ rightField , $ operator ) = $ this ->getRightFieldValue ($ rightField , $ operator );
7798
78- /**
79- * Where AND condition.
80- *
81- * @param array ...$conditions (field, comparison, value)
82- * or (field, comparison, new RawExp('table.field'))
83- * or new RawExp('...')
84- * @return self
85- */
86- public function where ($ conditions ): self
87- {
88- if ($ conditions [0 ] instanceof Closure) {
89- $ this ->addClauseCondClosure ('where ' , 'AND ' , $ conditions [0 ]);
90- return $ this ;
99+ $ sql [] = sprintf ('%s %s %s %s ' , $ whereType , $ leftField , $ operator , $ rightField );
91100 }
92- $ this -> where [] = [ ' and ' , $ conditions ];
93- return $ this ;
101+
102+ return $ sql ;
94103 }
95104
96105 /**
97- * Where OR condition.
106+ * Comparison Functions and Operators
98107 *
99- * @param array ...$conditions (field, comparison, value)
100- * or (field, comparison, new RawExp('table.field'))
101- * or new RawExp('...')
102- * @return self
108+ * https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html
109+ *
110+ * @param mixed $rightField
111+ * @param mixed $comparison
112+ * @return array
103113 */
104- public function orWhere ( $ conditions ): self
114+ protected function getRightFieldValue ( $ rightField , $ comparison ): array
105115 {
106- if ($ conditions [0 ] instanceof Closure) {
107- $ this ->addClauseCondClosure ('where ' , 'OR ' , $ conditions [0 ]);
108- return $ this ;
116+ if ($ comparison == 'in ' || $ comparison == 'not in ' ) {
117+ $ rightField = '( ' . implode (', ' , $ this ->quoter ->quoteArray ((array )$ rightField )) . ') ' ;
118+ } elseif ($ comparison == 'greatest ' || $ comparison == 'interval ' || $ comparison === 'strcmp ' ) {
119+ $ comparison = '= ' . $ comparison ;
120+ $ rightField = '( ' . implode (', ' , $ this ->quoter ->quoteArray ((array )$ rightField )) . ') ' ;
121+ } elseif ($ comparison === '= ' && $ rightField === null ) {
122+ $ comparison = 'IS ' ;
123+ $ rightField = $ this ->quoter ->quoteValue ($ rightField );
124+ } elseif (($ comparison === '<> ' || $ comparison === '!= ' ) && $ rightField === null ) {
125+ $ comparison = 'IS NOT ' ;
126+ $ rightField = $ this ->quoter ->quoteValue ($ rightField );
127+ } elseif ($ comparison === 'between ' || $ comparison === 'not between ' ) {
128+ $ between1 = $ this ->quoter ->quoteValue ($ rightField [0 ]);
129+ $ between2 = $ this ->quoter ->quoteValue ($ rightField [1 ]);
130+ $ rightField = sprintf ('%s AND %s ' , $ between1 , $ between2 );
131+ } elseif ($ rightField instanceof RawExp) {
132+ $ rightField = $ rightField ->getValue ();
133+ } else {
134+ $ rightField = $ this ->quoter ->quoteValue ($ rightField );
109135 }
110- $ this -> where [] = [ ' or ' , $ conditions ];
111- return $ this ;
136+
137+ return [ $ rightField , strtoupper ( $ comparison )] ;
112138 }
113139
114140 /**
115- * Add AND having condition .
141+ * Get sql .
116142 *
117- * @param array ...$conditions (field, comparison, value)
118- * or (field, comparison, new RawExp('table.field'))
119- * or new RawExp('...')
120- * @return self
143+ * @param array $sql
144+ * @return array
121145 */
122- public function having ( $ conditions ): self
146+ public function getHavingSql ( array $ sql ): array
123147 {
124- if ($ conditions [0 ] instanceof Closure) {
125- $ this ->addClauseCondClosure ('having ' , 'AND ' , $ conditions [0 ]);
126- return $ this ;
127- }
128- $ this ->having [] = ['and ' , $ conditions ];
129- return $ this ;
148+ return $ this ->getConditionSql ($ sql , $ this ->having , 'HAVING ' );
130149 }
131150
132151 /**
133- * Add OR having condition.
152+ * Where AND condition.
134153 *
135154 * @param array ...$conditions (field, comparison, value)
136155 * or (field, comparison, new RawExp('table.field'))
137156 * or new RawExp('...')
138157 * @return self
139158 */
140- public function orHaving ($ conditions ): self
159+ public function where ($ conditions ): self
141160 {
142161 if ($ conditions [0 ] instanceof Closure) {
143- $ this ->addClauseCondClosure ('having ' , 'OR ' , $ conditions [0 ]);
162+ $ this ->addClauseCondClosure ('where ' , 'AND ' , $ conditions [0 ]);
163+
144164 return $ this ;
145165 }
146- $ this ->having [] = ['or ' , $ conditions ];
166+ $ this ->where [] = ['and ' , $ conditions ];
167+
147168 return $ this ;
148169 }
149170
@@ -168,6 +189,7 @@ protected function addClauseCondClosure($clause, $andor, $closure)
168189 if (!$ this ->$ clause ) {
169190 // no: restore the old ones, and done
170191 $ this ->$ clause = $ set ;
192+
171193 return ;
172194 }
173195
@@ -194,73 +216,62 @@ protected function addClauseCondClosure($clause, $andor, $closure)
194216 }
195217
196218 /**
197- * Comparison Functions and Operators
198- *
199- * https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html
219+ * Where OR condition.
200220 *
201- * @param mixed $rightField
202- * @param mixed $comparison
203- * @return array
221+ * @param array ...$conditions (field, comparison, value)
222+ * or (field, comparison, new RawExp('table.field'))
223+ * or new RawExp('...')
224+ * @return self
204225 */
205- protected function getRightFieldValue ( $ rightField , $ comparison ): array
226+ public function orWhere ( $ conditions ): self
206227 {
207- if ($ comparison == 'in ' || $ comparison == 'not in ' ) {
208- $ rightField = '( ' . implode (', ' , $ this ->quoter ->quoteArray ((array )$ rightField )) . ') ' ;
209- } elseif ($ comparison == 'greatest ' || $ comparison == 'interval ' || $ comparison === 'strcmp ' ) {
210- $ comparison = '= ' . $ comparison ;
211- $ rightField = '( ' . implode (', ' , $ this ->quoter ->quoteArray ((array )$ rightField )) . ') ' ;
212- } elseif ($ comparison === '= ' && $ rightField === null ) {
213- $ comparison = 'IS ' ;
214- $ rightField = $ this ->quoter ->quoteValue ($ rightField );
215- } elseif (($ comparison === '<> ' || $ comparison === '!= ' ) && $ rightField === null ) {
216- $ comparison = 'IS NOT ' ;
217- $ rightField = $ this ->quoter ->quoteValue ($ rightField );
218- } elseif ($ comparison === 'between ' || $ comparison === 'not between ' ) {
219- $ between1 = $ this ->quoter ->quoteValue ($ rightField [0 ]);
220- $ between2 = $ this ->quoter ->quoteValue ($ rightField [1 ]);
221- $ rightField = sprintf ('%s AND %s ' , $ between1 , $ between2 );
222- } elseif ($ rightField instanceof RawExp) {
223- $ rightField = $ rightField ->getValue ();
224- } else {
225- $ rightField = $ this ->quoter ->quoteValue ($ rightField );
228+ if ($ conditions [0 ] instanceof Closure) {
229+ $ this ->addClauseCondClosure ('where ' , 'OR ' , $ conditions [0 ]);
230+
231+ return $ this ;
226232 }
227- return [$ rightField , strtoupper ($ comparison )];
233+ $ this ->where [] = ['or ' , $ conditions ];
234+
235+ return $ this ;
228236 }
229237
230238 /**
231- * Get sql .
239+ * Add AND having condition .
232240 *
233- * @param array $sql
234- * @param array $where
235- * @param string $conditionType
236- * @return array
241+ * @param array ...$conditions (field, comparison, value)
242+ * or (field, comparison, new RawExp('table.field'))
243+ * or new RawExp('...')
244+ * @return self
237245 */
238- public function getConditionSql ( array $ sql , array $ where , string $ conditionType ): array
246+ public function having ( $ conditions ): self
239247 {
240- if (empty ($ where )) {
241- return $ sql ;
248+ if ($ conditions [0 ] instanceof Closure) {
249+ $ this ->addClauseCondClosure ('having ' , 'AND ' , $ conditions [0 ]);
250+
251+ return $ this ;
242252 }
243- foreach ($ where as $ index => $ item ) {
244- if ($ item instanceof RawExp) {
245- $ sql [] = $ item ->getValue ();
246- continue ;
247- }
248- list ($ type , $ conditions ) = $ item ;
249- if (!$ index ) {
250- $ whereType = $ conditionType ;
251- } else {
252- $ whereType = strtoupper ($ type );
253- }
254- if ($ conditions [0 ] instanceof RawExp) {
255- $ sql [] = $ whereType . ' ' . $ conditions [0 ]->getValue ();
256- continue ;
257- }
258- list ($ leftField , $ operator , $ rightField ) = $ conditions ;
259- $ leftField = $ this ->quoter ->quoteName ($ leftField );
260- list ($ rightField , $ operator ) = $ this ->getRightFieldValue ($ rightField , $ operator );
253+ $ this ->having [] = ['and ' , $ conditions ];
261254
262- $ sql [] = sprintf ('%s %s %s %s ' , $ whereType , $ leftField , $ operator , $ rightField );
255+ return $ this ;
256+ }
257+
258+ /**
259+ * Add OR having condition.
260+ *
261+ * @param array ...$conditions (field, comparison, value)
262+ * or (field, comparison, new RawExp('table.field'))
263+ * or new RawExp('...')
264+ * @return self
265+ */
266+ public function orHaving ($ conditions ): self
267+ {
268+ if ($ conditions [0 ] instanceof Closure) {
269+ $ this ->addClauseCondClosure ('having ' , 'OR ' , $ conditions [0 ]);
270+
271+ return $ this ;
263272 }
264- return $ sql ;
273+ $ this ->having [] = ['or ' , $ conditions ];
274+
275+ return $ this ;
265276 }
266277}
0 commit comments