sqlbuilderstate.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095
  1. <?php
  2. class sqlBuilderState
  3. {
  4. /**
  5. * from
  6. *
  7. * @var array
  8. * @access public
  9. */
  10. public $from = array();
  11. /**
  12. * joins
  13. *
  14. * @var array
  15. * @access public
  16. */
  17. public $joins = array();
  18. /**
  19. * funcs
  20. *
  21. * @var array
  22. * @access public
  23. */
  24. public $funcs = array();
  25. /**
  26. * wheres
  27. *
  28. * @var array
  29. * @access public
  30. */
  31. public $wheres = array();
  32. /**
  33. * querys
  34. *
  35. * @var array
  36. * @access public
  37. */
  38. public $querys = array();
  39. /**
  40. * groups
  41. *
  42. * @var array
  43. * @access public
  44. */
  45. public $groups = false;
  46. /**
  47. * tableDesc
  48. *
  49. * @var array
  50. * @access public
  51. */
  52. public $tableDesc = array();
  53. /**
  54. * queryFilterSelectOptions
  55. *
  56. * @var array
  57. * @access public
  58. */
  59. public $queryFilterSelectOptions = array();
  60. /**
  61. * sql
  62. *
  63. * @var string
  64. * @access public
  65. */
  66. public $sql = '';
  67. /**
  68. * step
  69. *
  70. * @var string
  71. * @access public
  72. */
  73. public $step = 'table';
  74. /**
  75. * error
  76. *
  77. * @var array
  78. * @access public
  79. */
  80. public $error = array();
  81. /**
  82. * __construct method.
  83. *
  84. * @param pivot object
  85. * @param drills array
  86. * @param clientLang string
  87. * @access public
  88. * @return void
  89. */
  90. public function __construct($from = null, $joins = null, $funcs = null, $wheres = null, $querys = null, $groups = null)
  91. {
  92. if(!is_array($joins))
  93. {
  94. if(empty($from)) $from = array(
  95. 'from' => array(),
  96. 'joins' => array(),
  97. 'funcs' => array(),
  98. 'wheres' => array(),
  99. 'querys' => array(),
  100. 'groups' => false,
  101. 'step' => 'table',
  102. 'tableDesc' => array(),
  103. 'queryFilterSelectOptions' => array()
  104. );
  105. extract($from);
  106. }
  107. $this->from = $from;
  108. $this->joins = $joins;
  109. $this->funcs = $funcs;
  110. $this->wheres = $wheres;
  111. $this->querys = $querys;
  112. $this->groups = $groups;
  113. $this->step = $step ?? 'table';
  114. $this->tableDesc = $tableDesc ?? array();
  115. $this->queryFilterSelectOptions = $queryFilterSelectOptions ?? array();
  116. if(empty($from) || !isset($from['table'])) $this->setFrom();
  117. $this->processAddJoins();
  118. $this->processAddFuncs();
  119. $this->processAddWheres();
  120. $this->processAddQuerys();
  121. $this->processSelect();
  122. if($this->groups === true) $this->enableGroupBy();
  123. }
  124. /**
  125. * Add table desc.
  126. *
  127. * @param string $table
  128. * @param array $list
  129. * @access public
  130. * @return void
  131. */
  132. public function addTableDesc($table, $list)
  133. {
  134. if(!isset($this->tableDesc[$table])) $this->tableDesc[$table] = $list;
  135. }
  136. /**
  137. * Set from.
  138. *
  139. * @param string $table
  140. * @access public
  141. * @return void
  142. */
  143. public function setFrom($table = '')
  144. {
  145. $this->from = array('table' => $table, 'alias' => 't1', 'select' => array());
  146. }
  147. /**
  148. * Add join
  149. *
  150. * @param string|array $left
  151. * @param string $alias
  152. * @param string $columnA
  153. * @param string $fieldA
  154. * @param string $fieldB
  155. * @access public
  156. * @return void
  157. */
  158. public function addJoin($left, $alias = '', $columnA = '', $fieldA = '', $fieldB = '')
  159. {
  160. if(is_array($left))
  161. {
  162. $this->joins[] = $left;
  163. return;
  164. }
  165. $join = array();
  166. $join['table'] = $left;
  167. $join['alias'] = $alias;
  168. $join['select'] = array();
  169. $join['on'] = array($columnA, $fieldA, '=', $alias, $fieldB);
  170. $this->joins[] = $join;
  171. }
  172. /**
  173. * Add func.
  174. *
  175. * @param string|array $type
  176. * @param string $table
  177. * @param string $field
  178. * @param string $function
  179. * @param string $alias
  180. * @access public
  181. * @return void
  182. */
  183. public function addFunc($type, $table = '', $field = '', $function = '', $alias = '', $name = '')
  184. {
  185. if(is_array($type))
  186. {
  187. $this->funcs[] = $type;
  188. return;
  189. }
  190. $func = array();
  191. $func['type'] = $type;
  192. $func['table'] = $table;
  193. $func['field'] = $field;
  194. $func['function'] = $function;
  195. $func['alias'] = $alias;
  196. $func['name'] = $name;
  197. $this->funcs[] = $func;
  198. }
  199. /**
  200. * Add where group.
  201. *
  202. * @param array $group
  203. * @access public
  204. * @return void
  205. */
  206. public function addWhereGroup($group)
  207. {
  208. $this->wheres[] = $group;
  209. }
  210. /**
  211. * Add where item.
  212. *
  213. * @param int $index
  214. * @param string|array $table
  215. * @param string $field
  216. * @param string $operator
  217. * @param string $value
  218. * @access public
  219. * @return void
  220. */
  221. public function addWhereItem($index, $table = '', $field = '', $operator = '=', $value = '', $conditionOperator = 'and')
  222. {
  223. $item = is_array($table) ? $table : array($table, $field, $operator, null, $value, $conditionOperator);
  224. $this->wheres[$index]['items'][] = $item;
  225. }
  226. /**
  227. * add query filter.
  228. *
  229. * @param string $table
  230. * @param string $field
  231. * @param string $name
  232. * @param string $type
  233. * @param string $typeOption
  234. * @param string $default
  235. * @access public
  236. * @return void
  237. */
  238. public function addQueryFilter($table = '', $field = '', $name = '', $type = 'select', $typeOption = 'user', $default = '')
  239. {
  240. if(is_array($table))
  241. {
  242. $this->querys[] = $table;
  243. return;
  244. }
  245. $query = array();
  246. $query['table'] = $table;
  247. $query['field'] = $field;
  248. $query['name'] = $name;
  249. $query['type'] = $type;
  250. $query['typeOption'] = $typeOption;
  251. $query['default'] = $default;
  252. $this->querys[] = $query;
  253. }
  254. /**
  255. * set agg func.
  256. *
  257. * @access public
  258. * @return void
  259. */
  260. public function setAggFunc()
  261. {
  262. $this->funcs = array_filter($this->funcs, function ($func) {
  263. return $func['type'] !== 'agg';
  264. });
  265. if($this->groups === false) return;
  266. foreach($this->groups as $group)
  267. {
  268. if($group['type'] == 'group') continue;
  269. list($table, $field, $alias, $function, $name) = $group['select'];
  270. $this->addFunc('agg', $table, $field, $function, "{$alias}_{$function}", $name);
  271. }
  272. }
  273. /**
  274. * addGroupBy
  275. *
  276. * @param int $type
  277. * @param int $order
  278. * @param int $select
  279. * @param string $function
  280. * @access public
  281. * @return void
  282. */
  283. public function addGroupBy($type, $order, $select, $function = 'count')
  284. {
  285. list($table, $field, $selectFunc) = array($select[0], $select[1], $select[3]);
  286. $fieldList = $this->getTableDescList($table);
  287. $name = $table . '_' . $fieldList[$field];
  288. if(!empty($selectFunc)) $name = $name . '_' . $selectFunc;
  289. $select[3] = $function;
  290. $select[4] = $name;
  291. $this->groups[] = array('select' => $select, 'type' => $type, 'order' => $order, 'name' => $name);
  292. }
  293. /**
  294. * Set group by.
  295. *
  296. * @access public
  297. * @return void
  298. */
  299. public function enableGroupBy()
  300. {
  301. $selects = array_merge($this->getSelects(), $this->getFuncSelects());
  302. $this->groups = array();
  303. foreach($selects as $index => $select) $this->addGroupBy('agg', $index, $select);
  304. $this->setAggFunc();
  305. }
  306. /**
  307. * Get select tables.
  308. *
  309. * @param array $tableList
  310. * @access public
  311. * @return array
  312. */
  313. public function getSelectTables($tableList)
  314. {
  315. $selectTables = array();
  316. $tables = $this->joins;
  317. array_unshift($tables, $this->from);
  318. foreach($tables as $join)
  319. {
  320. $table = $join['table'];
  321. if(empty($table)) continue;
  322. $alias = $join['alias'];
  323. $name = $tableList[$table];
  324. $selectTables[$alias] = "$name($alias)";
  325. }
  326. return $selectTables;
  327. }
  328. /**
  329. * Get func selects.
  330. *
  331. * @access public
  332. * @return array
  333. */
  334. public function getFuncSelects()
  335. {
  336. $funcs = $this->getFuncs('func', true);
  337. $selects = array();
  338. foreach($funcs as $func)
  339. {
  340. list($table, $field, $alias, $function) = array($func['table'], $func['field'], $func['alias'], $func['function']);
  341. $selects[] = array($table, $field, $alias, $function);
  342. }
  343. return $selects;
  344. }
  345. /**
  346. * Get selects.
  347. *
  348. * @access public
  349. * @return array
  350. */
  351. public function getSelects()
  352. {
  353. $selects = array();
  354. $tables = $this->joins;
  355. array_unshift($tables, $this->from);
  356. foreach($tables as $table)
  357. {
  358. $alias = $table['alias'];
  359. foreach($table['select'] as $field) $selects[] = array($alias, $field, "{$alias}_{$field}", null);
  360. }
  361. return $selects;
  362. }
  363. /**
  364. * Get selects with key.
  365. *
  366. * @access public
  367. * @return array
  368. */
  369. public function getSelectsWithKey($selects)
  370. {
  371. $selectsWithKey = array();
  372. foreach($selects as $select)
  373. {
  374. list($table, $field, $alias) = $select;
  375. $key = "{$table}_{$field}_{$alias}";
  376. $selectsWithKey[$key] = $select;
  377. }
  378. return $selectsWithKey;
  379. }
  380. /**
  381. * Get funcs.
  382. *
  383. * @param string $type
  384. * @access public
  385. * @return array
  386. */
  387. public function getFuncs($type, $skipEmpty = false)
  388. {
  389. $funcs = array();
  390. foreach($this->funcs as $index => $func)
  391. {
  392. $hasEmpty = empty($func['table']) || empty($func['field']);
  393. $hasEmpty = $hasEmpty || empty($func['function']) || empty($func['alias']);
  394. if($skipEmpty && $hasEmpty) continue;
  395. if($func['type'] == $type || $type == 'all') $funcs[$index] = $func;
  396. }
  397. return $funcs;
  398. }
  399. /**
  400. * Get group by.
  401. *
  402. * @param bool $sort
  403. * @param bool $onlyField
  404. * @access public
  405. * @return array
  406. */
  407. public function getGroupBy($sort = true, $onlyField = true)
  408. {
  409. if($this->groups === false) return array();
  410. $groupBys = array_filter($this->groups, function ($group) {
  411. return $group['type'] === 'group';
  412. });
  413. if($sort) uasort($groupBys, function($a, $b) {return $a['order'] <= $b['order'] ? -1 : 1;});
  414. if($onlyField)
  415. {
  416. foreach($groupBys as $index => $groupBy)
  417. {
  418. $select = $groupBy['select'];
  419. list($table, $field) = array($select[0], $select[1]);
  420. $groupBys[$index] = array($table, $field);
  421. }
  422. }
  423. return array_values($groupBys);
  424. }
  425. /**
  426. * Get next table alias.
  427. *
  428. * @access public
  429. * @return string
  430. */
  431. public function getNextTableAlias()
  432. {
  433. $indexes = array();
  434. foreach($this->joins as $join)
  435. {
  436. if(!is_array($join)) continue;
  437. $alias = $join['alias'];
  438. $indexes[] = (int)str_replace('t', '', $alias);
  439. }
  440. $max = empty($indexes) ? 1 : max($indexes);
  441. $next = $max + 1;
  442. return "t{$next}";
  443. }
  444. /**
  445. * Get table desc field list.
  446. *
  447. * @param string $alias
  448. * @access public
  449. * @return array
  450. */
  451. public function getTableDescList($alias)
  452. {
  453. $tableDesc = $this->tableDesc;
  454. $tables = $this->joins;
  455. array_unshift($tables, $this->from);
  456. foreach($tables as $join)
  457. {
  458. if($alias == $join['alias'] && isset($tableDesc[$join['table']])) return $tableDesc[$join['table']];
  459. }
  460. return array();
  461. }
  462. /**
  463. * Get json
  464. *
  465. * @access public
  466. * @return string
  467. */
  468. public function getJson()
  469. {
  470. $data = array();
  471. $data['from'] = $this->from;
  472. $data['joins'] = $this->joins;
  473. $data['funcs'] = $this->funcs;
  474. $data['wheres'] = $this->wheres;
  475. $data['querys'] = $this->querys;
  476. $data['groups'] = $this->groups;
  477. return json_encode($data);
  478. }
  479. /**
  480. * buildSelects
  481. *
  482. * @access public
  483. * @return void
  484. */
  485. public function buildSelects()
  486. {
  487. $selects = array();
  488. if($this->groups !== false)
  489. {
  490. foreach($this->groups as $group)
  491. {
  492. list($table, $field, $alias, $function) = $group['select'];
  493. $selects[] = $group['type'] == 'agg' ? array($table, $field, $alias, $function) : array($table, $field, $alias);
  494. }
  495. return $selects;
  496. }
  497. return array_merge($this->getSelects(), $this->getFuncSelects('func'));
  498. }
  499. /**
  500. * Build functions.
  501. *
  502. * @access public
  503. * @return void
  504. */
  505. public function buildFunctions()
  506. {
  507. $functions = $this->getFuncs('all', true);
  508. $funcArr = array();
  509. foreach($functions as $function) $funcArr[] = array($function['table'], $function['field'], $function['alias'], $function['function']);
  510. return $funcArr;
  511. }
  512. /**
  513. * build wheres.
  514. *
  515. * @access public
  516. * @return array
  517. */
  518. public function buildWheres()
  519. {
  520. $wheres = array();
  521. $groupCount = count($this->wheres);
  522. foreach($this->wheres as $groupIndex => $group)
  523. {
  524. $groups = array();
  525. foreach($group['items'] as $itemIndex => $item)
  526. {
  527. list($columnA, $fieldA, $operator, $columnB, $fieldB, $conditionOperator) = $item;
  528. if($itemIndex !== 0) $groups[] = $conditionOperator;
  529. $groups[] = array($columnA, $fieldA, $operator, $columnB, $fieldB);
  530. }
  531. $wheres[] = $groups;
  532. if($groupIndex + 1 < $groupCount) $wheres[] = $group['operator'];
  533. }
  534. return $wheres;
  535. }
  536. /**
  537. * Build querys.
  538. *
  539. * @access public
  540. * @return array
  541. */
  542. public function buildQuerys()
  543. {
  544. $querys = array();
  545. $hasWhere = count($this->wheres) > 0;
  546. foreach($this->querys as $index => $query)
  547. {
  548. if($index != 0 || $hasWhere) $querys[] = 'and';
  549. $variable = "var$index";
  550. $table = $query['table'];
  551. $field = $query['field'];
  552. $type = $query['type'];
  553. if($type != 'multipleselect')
  554. {
  555. $querys[] = array(null, "if(\${$variable}='',1=2,\${$variable}=`{$table}`.`{$field}`)");
  556. }
  557. else
  558. {
  559. $querys[] = array(null, "if(\"\${$variable}\"='',1=2,`{$table}`.`{$field}` in (\${$variable}))");
  560. }
  561. }
  562. return $querys;
  563. }
  564. /**
  565. * check from.
  566. *
  567. * @access public
  568. * @return bool|string
  569. */
  570. public function checkFrom()
  571. {
  572. if(empty($this->from['table'])) return $this->getError('from', 'table', $this->from['alias']);
  573. return true;
  574. }
  575. /**
  576. * check joins
  577. *
  578. * @access public
  579. * @return bool|string
  580. */
  581. public function checkJoins()
  582. {
  583. foreach($this->joins as $join)
  584. {
  585. $alias = $join['alias'];
  586. if(empty($join['table'])) return $this->getError('join', 'table', $alias);
  587. list($columnA, $fieldA, $fieldB) = array($join['on'][0], $join['on'][1], $join['on'][4]);
  588. if(empty($columnA)) return $this->getError('join', 'columnA', $alias);
  589. if(empty($fieldA)) return $this->getError('join', 'fieldA', $alias);
  590. if(empty($fieldB)) return $this->getError('join', 'fieldB', $alias);
  591. }
  592. return true;
  593. }
  594. /**
  595. * check selects.
  596. *
  597. * @access public
  598. * @return bool|string
  599. */
  600. public function checkSelects()
  601. {
  602. $from = $this->from;
  603. $joins = $this->joins;
  604. $select = array();
  605. $select = array_merge($select, $from['select']);
  606. foreach($joins as $join) $select = array_merge($select, $join['select']);
  607. $checkFuncs = $this->checkFuncs();
  608. if(empty($select) && $checkFuncs === false) return $this->getError('select', 'field');
  609. return true;
  610. }
  611. /**
  612. * Check funcs.
  613. *
  614. * @access public
  615. * @return bool|string
  616. */
  617. public function checkFuncs($type = 'func')
  618. {
  619. $funcs = $this->getFuncs($type);
  620. if(empty($funcs)) return false;
  621. $checkDuplicate = array();
  622. foreach($funcs as $index => $func)
  623. {
  624. if(empty($func['table'])) return $this->getError('func', 'table', $index);
  625. if(empty($func['field'])) return $this->getError('func', 'field', $index);
  626. if(empty($func['function'])) return $this->getError('func', 'function', $index);
  627. if(empty($func['alias']) && !is_numeric($func['alias'])) return $this->getError('func', 'alias', $index);
  628. $alias = $func['alias'];
  629. if(!isset($checkDuplicate[$alias]))
  630. {
  631. $checkDuplicate[$alias] = $index;
  632. }
  633. else
  634. {
  635. return $this->getError('func', 'duplicate', $index);
  636. }
  637. }
  638. return true;
  639. }
  640. /**
  641. * Check wheres.
  642. *
  643. * @access public
  644. * @return bool|string
  645. */
  646. public function checkWheres()
  647. {
  648. foreach($this->wheres as $groupIndex => $group)
  649. {
  650. foreach($group['items'] as $itemIndex => $item)
  651. {
  652. list($table, $field, $value) = array($item[0], $item[1], $item[4]);
  653. if(empty($table)) return $this->getError('where', "{$groupIndex}_{$itemIndex}_0");
  654. if(empty($field)) return $this->getError('where', "{$groupIndex}_{$itemIndex}_1");
  655. if(empty($value) && !is_numeric($value)) return $this->getError('where', "{$groupIndex}_{$itemIndex}_4");
  656. }
  657. }
  658. return true;
  659. }
  660. /**
  661. * Check querys.
  662. *
  663. * @access public
  664. * @return bool|string
  665. */
  666. public function checkQuerys()
  667. {
  668. $querys = $this->querys;
  669. foreach($querys as $index => $query)
  670. {
  671. if(empty($query['table'])) return $this->getError('query', 'table', $index);
  672. if(empty($query['field'])) return $this->getError('query', 'field', $index);
  673. if(empty($query['name']) && !is_numeric($query['name'])) return $this->getError('query', 'name', $index);
  674. }
  675. return true;
  676. }
  677. /**
  678. * Set error.
  679. *
  680. * @param string $key
  681. * @access public
  682. * @return void
  683. */
  684. public function setError($key)
  685. {
  686. $this->error[$key] = true;
  687. }
  688. /**
  689. * Get Error.
  690. *
  691. * @param string $key
  692. * @param string $type
  693. * @param string $field
  694. * @access public
  695. * @return string
  696. */
  697. public function getError($key, $type = '', $field = '')
  698. {
  699. return implode('_', array_filter(array($key, $type, $field), function($value) { return $value !== ''; }));
  700. }
  701. /**
  702. * Has error.
  703. *
  704. * @param string $key
  705. * @param string $type
  706. * @param string $field
  707. * @access public
  708. * @return bool
  709. */
  710. public function hasError($key, $type = '', $field = '')
  711. {
  712. $key = $this->getError($key, $type, $field);
  713. return isset($this->error[$key]);
  714. }
  715. /**
  716. * Process check all.
  717. *
  718. * @access public
  719. * @return void
  720. */
  721. public function processCheckAll()
  722. {
  723. $from = $this->from;
  724. $joins = $this->joins;
  725. if($from['select'] == '*') $this->from['select'] = array_keys($this->getTableDescList($from['alias']));
  726. foreach($joins as $index => $join)
  727. {
  728. if($join['select'] == '*') $this->joins[$index]['select'] = array_keys($this->getTableDescList($join['alias']));
  729. }
  730. }
  731. /**
  732. * Process funcs.
  733. *
  734. * @access public
  735. * @return void
  736. */
  737. public function processFuncs()
  738. {
  739. foreach($this->funcs as $index => $func)
  740. {
  741. $alias = $func['alias'];
  742. $table = $func['table'];
  743. $field = $func['field'];
  744. if(!empty($alias) || empty($table) || empty($field)) continue;
  745. $this->funcs[$index]['alias'] = "{$table}_{$field}_{$index}";
  746. }
  747. }
  748. /**
  749. * Process group by.
  750. *
  751. * @access public
  752. * @return void
  753. */
  754. public function processGroupBy()
  755. {
  756. if($this->groups === false) return;
  757. list($selects, $groups) = $this->updateGroupsFromSelects();
  758. $this->groups = $this->reorderGroupBy($groups);
  759. $order = count($this->groups);
  760. foreach($selects as $select)
  761. {
  762. $this->addGroupBy('agg', $order, $select);
  763. $order += 1;
  764. }
  765. $this->setAggFunc();
  766. }
  767. /**
  768. * Process query filters.
  769. *
  770. * @access public
  771. * @return void
  772. */
  773. public function processQueryFilters()
  774. {
  775. foreach($this->querys as $index => $query)
  776. {
  777. $table = $query['table'];
  778. $field = $query['field'];
  779. $name = $query['name'];
  780. if(!empty($field) && empty($name))
  781. {
  782. $fieldList = $this->getTableDescList($table);
  783. $this->querys[$index]['name'] = zget($fieldList, $field, $field);
  784. }
  785. }
  786. }
  787. /**
  788. * Process select.
  789. *
  790. * @access public
  791. * @return void
  792. */
  793. public function processSelect()
  794. {
  795. $fromSelect = $this->from['select'];
  796. if($fromSelect == '*') $this->from['select'] = array_keys($this->getTableDescList($this->from['alias']));
  797. foreach($this->joins as $index => $join)
  798. {
  799. if($join['select'] !== '*') continue;
  800. $this->joins[$index]['select'] = array_keys($this->getTableDescList($join['alias']));
  801. }
  802. }
  803. /**
  804. * Process add joins.
  805. *
  806. * @access public
  807. * @return void
  808. */
  809. public function processAddJoins()
  810. {
  811. $joins = $this->joins;
  812. $alias = $this->getNextTableAlias();
  813. $this->joins = array();
  814. foreach($joins as $join)
  815. {
  816. if($join == 'add')
  817. {
  818. $this->addJoin('', $alias);
  819. continue;
  820. }
  821. $this->addJoin($join);
  822. }
  823. }
  824. /**
  825. * Process add funcs.
  826. *
  827. * @access public
  828. * @return void
  829. */
  830. public function processAddFuncs()
  831. {
  832. $funcs = $this->funcs;
  833. $this->funcs = array();
  834. foreach($funcs as $func)
  835. {
  836. if($func == 'add')
  837. {
  838. $this->addFunc('func');
  839. continue;
  840. }
  841. $this->addFunc($func);
  842. }
  843. }
  844. /**
  845. * Process add wheres.
  846. *
  847. * @access public
  848. * @return void
  849. */
  850. public function processAddWheres()
  851. {
  852. $wheres = $this->wheres;
  853. $this->wheres = array();
  854. foreach($wheres as $index => $group)
  855. {
  856. if($group == 'add') $group = array('items' => array(), 'operator' => 'and');
  857. $this->addWhereGroup(array('items' => array(), 'operator' => $group['operator']));
  858. $items = $group['items'];
  859. if(empty($items)) $items[] = 'add';
  860. foreach($items as $itemIndex => $item)
  861. {
  862. if($item == 'add') $this->addWhereItem($index);
  863. else $this->addWhereItem($index, $item);
  864. }
  865. }
  866. }
  867. /**
  868. * Process add querys
  869. *
  870. * @access public
  871. * @return void
  872. */
  873. public function processAddQuerys()
  874. {
  875. $querys = $this->querys;
  876. $this->querys = array();
  877. foreach($querys as $query)
  878. {
  879. if($query == 'add') $query = '';
  880. $this->addQueryFilter($query);
  881. }
  882. }
  883. /**
  884. * Update group from selects.
  885. *
  886. * @access public
  887. * @return array
  888. */
  889. public function updateGroupsFromSelects()
  890. {
  891. $selects = array_merge($this->getSelects(), $this->getFuncSelects());
  892. $selects = $this->getSelectsWithKey($selects);
  893. if($this->groups === false) return array(array(), array());
  894. $groups = array();
  895. foreach($this->groups as $group)
  896. {
  897. list($table, $field, $alias) = $group['select'];
  898. $key = "{$table}_{$field}_{$alias}";
  899. if(!isset($selects[$key])) continue;
  900. $groups[] = $group;
  901. unset($selects[$key]);
  902. }
  903. return array($selects, $groups);
  904. }
  905. /**
  906. * Reorder group by.
  907. *
  908. * @param array $groups
  909. * @access public
  910. * @return array
  911. */
  912. public function reorderGroupBy($groups)
  913. {
  914. uasort($groups, function($a, $b) {return $a['order'] <= $b['order'] ? -1 : 1;});
  915. $order = 0;
  916. foreach($groups as $index => $group)
  917. {
  918. $groups[$index]['order'] = $order;
  919. $order += 1;
  920. }
  921. ksort($groups, SORT_NUMERIC);
  922. return $groups;
  923. }
  924. /**
  925. * build
  926. *
  927. * @param array $selects
  928. * @param array $from
  929. * @param array $joins
  930. * @param array $functions
  931. * @param array $wheres
  932. * @param array $querys
  933. * @param array $groups
  934. * @access public
  935. * @return object
  936. */
  937. public function build($parser)
  938. {
  939. $checkList = array('checkFrom', 'checkJoins', 'checkSelects', 'checkFuncs', 'checkWheres', 'checkQuerys');
  940. foreach($checkList as $check) if(is_string($this->$check())) return;
  941. $parser->createStatement();
  942. /* from */
  943. $from = array($this->from['table'], null, $this->from['alias']);
  944. $parser->setFrom($parser->getExpression($from));
  945. /* join */
  946. foreach($this->joins as $join)
  947. {
  948. $alias = $join['alias'];
  949. $table = $join['table'];
  950. $on = $join['on'];
  951. $onExprs = $parser->getCondition($on);
  952. $leftJoinExpr = $parser->getLeftJoin($table, $alias, $onExprs);
  953. $parser->addJoin($leftJoinExpr);
  954. }
  955. /* select */
  956. $selects = $this->buildSelects();
  957. foreach($selects as $select) $parser->addSelect($parser->getExpression($select));
  958. /* where */
  959. $wheres = $this->buildWheres();
  960. if(!empty($wheres)) $parser->addWhere($parser->combineConditions($parser->getConditionsFromArray($wheres)));
  961. /* querys */
  962. $querys = $this->buildQuerys();
  963. if(!empty($querys)) $parser->addWhere($parser->combineConditions($parser->getConditionsFromArray($querys)));
  964. /* group by */
  965. $groups = $this->getGroupBy(true, true);
  966. if(!empty($groups)) foreach($groups as $group) $parser->addGroup($parser->getGroup($parser->getExpression($group)));
  967. $this->sql = $parser->statement->build();
  968. }
  969. }