BaseBuilder.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare(strict_types=1);
  12. namespace think\db;
  13. use Closure;
  14. use think\db\BaseQuery as Query;
  15. use think\db\exception\DbException as Exception;
  16. /**
  17. * Db Base Builder.
  18. */
  19. abstract class BaseBuilder
  20. {
  21. /**
  22. * Connection对象
  23. *
  24. * @var ConnectionInterface
  25. */
  26. protected $connection;
  27. /**
  28. * 查询表达式映射.
  29. *
  30. * @var array
  31. */
  32. protected $exp = ['NOTLIKE' => 'NOT LIKE', 'NOTIN' => 'NOT IN', 'NOTBETWEEN' => 'NOT BETWEEN', 'NOTEXISTS' => 'NOT EXISTS', 'NOTNULL' => 'NOT NULL', 'NOTBETWEEN TIME' => 'NOT BETWEEN TIME'];
  33. /**
  34. * 查询表达式解析.
  35. *
  36. * @var array
  37. */
  38. protected $parser = [
  39. 'parseCompare' => ['=', '<>', '>', '>=', '<', '<='],
  40. 'parseLike' => ['LIKE', 'NOT LIKE'],
  41. 'parseBetween' => ['NOT BETWEEN', 'BETWEEN'],
  42. 'parseIn' => ['NOT IN', 'IN'],
  43. 'parseExp' => ['EXP'],
  44. 'parseNull' => ['NOT NULL', 'NULL'],
  45. 'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
  46. 'parseTime' => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
  47. 'parseExists' => ['NOT EXISTS', 'EXISTS'],
  48. 'parseColumn' => ['COLUMN'],
  49. ];
  50. /**
  51. * SELECT SQL表达式.
  52. *
  53. * @var string
  54. */
  55. protected $selectSql = 'SELECT%DISTINCT%%EXTRA% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%UNION%%ORDER%%LIMIT% %LOCK%%COMMENT%';
  56. /**
  57. * INSERT SQL表达式.
  58. *
  59. * @var string
  60. */
  61. protected $insertSql = '%INSERT%%EXTRA% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
  62. /**
  63. * INSERT ALL SQL表达式.
  64. *
  65. * @var string
  66. */
  67. protected $insertAllSql = '%INSERT%%EXTRA% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
  68. /**
  69. * UPDATE SQL表达式.
  70. *
  71. * @var string
  72. */
  73. protected $updateSql = 'UPDATE%EXTRA% %TABLE% SET %SET%%JOIN%%WHERE%%ORDER%%LIMIT% %LOCK%%COMMENT%';
  74. /**
  75. * DELETE SQL表达式.
  76. *
  77. * @var string
  78. */
  79. protected $deleteSql = 'DELETE%EXTRA% FROM %TABLE%%USING%%JOIN%%WHERE%%ORDER%%LIMIT% %LOCK%%COMMENT%';
  80. /**
  81. * 架构函数.
  82. *
  83. * @param ConnectionInterface $connection 数据库连接对象实例
  84. */
  85. public function __construct(ConnectionInterface $connection)
  86. {
  87. $this->connection = $connection;
  88. }
  89. /**
  90. * 获取当前的连接对象实例.
  91. *
  92. * @return ConnectionInterface
  93. */
  94. public function getConnection(): ConnectionInterface
  95. {
  96. return $this->connection;
  97. }
  98. /**
  99. * 注册查询表达式解析.
  100. *
  101. * @param string $name 解析方法
  102. * @param array $parser 匹配表达式数据
  103. *
  104. * @return $this
  105. */
  106. public function bindParser(string $name, array $parser)
  107. {
  108. $this->parser[$name] = $parser;
  109. return $this;
  110. }
  111. /**
  112. * 数据分析.
  113. *
  114. * @param Query $query 查询对象
  115. * @param array $data 数据
  116. * @param array $fields 字段信息
  117. * @param array $bind 参数绑定
  118. *
  119. * @return array
  120. */
  121. abstract protected function parseData(Query $query, array $data = [], array $fields = [], array $bind = []): array;
  122. /**
  123. * 数据绑定处理.
  124. *
  125. * @param Query $query 查询对象
  126. * @param string $key 字段名
  127. * @param mixed $data 数据
  128. * @param array $bind 绑定数据
  129. *
  130. * @return string
  131. */
  132. abstract protected function parseDataBind(Query $query, string $key, $data, array $bind = []): string;
  133. /**
  134. * 字段名分析.
  135. *
  136. * @param Query $query 查询对象
  137. * @param mixed $key 字段名
  138. * @param bool $strict 严格检测
  139. *
  140. * @return string
  141. */
  142. abstract public function parseKey(Query $query, string|int|Raw $key, bool $strict = false): string;
  143. /**
  144. * 查询额外参数分析.
  145. *
  146. * @param Query $query 查询对象
  147. * @param string $extra 额外参数
  148. *
  149. * @return string
  150. */
  151. abstract protected function parseExtra(Query $query, string $extra): string;
  152. /**
  153. * field分析.
  154. *
  155. * @param Query $query 查询对象
  156. * @param array $fields 字段名
  157. *
  158. * @return string
  159. */
  160. abstract protected function parseField(Query $query, array $fields): string;
  161. /**
  162. * table分析.
  163. *
  164. * @param Query $query 查询对象
  165. * @param array|string $tables 表名
  166. *
  167. * @return string
  168. */
  169. abstract protected function parseTable(Query $query, array|string $tables): string;
  170. /**
  171. * where分析.
  172. *
  173. * @param Query $query 查询对象
  174. * @param array $where 查询条件
  175. *
  176. * @return string
  177. */
  178. abstract protected function parseWhere(Query $query, array $where): string;
  179. /**
  180. * 生成查询条件SQL.
  181. *
  182. * @param Query $query 查询对象
  183. * @param array $where 查询条件
  184. *
  185. * @return string
  186. */
  187. public function buildWhere(Query $query, array $where): string
  188. {
  189. if (empty($where)) {
  190. $where = [];
  191. }
  192. $whereStr = '';
  193. $binds = $query->getFieldsBindType();
  194. foreach ($where as $logic => $val) {
  195. $str = $this->parseWhereLogic($query, $logic, $val, $binds);
  196. $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($logic) + 1) : implode(' ', $str);
  197. }
  198. return $whereStr;
  199. }
  200. /**
  201. * 不同字段使用相同查询条件(AND).
  202. *
  203. * @param Query $query 查询对象
  204. * @param string $logic Logic
  205. * @param array $val 查询条件
  206. * @param array $binds 参数绑定
  207. *
  208. * @return array
  209. */
  210. protected function parseWhereLogic(Query $query, string $logic, array $val, array $binds = []): array
  211. {
  212. $where = [];
  213. foreach ($val as $value) {
  214. if ($value instanceof Raw) {
  215. $where[] = ' ' . $logic . ' ( ' . $this->parseRaw($query, $value) . ' )';
  216. continue;
  217. }
  218. if (is_array($value)) {
  219. if (key($value) !== 0) {
  220. throw new Exception('where express error:' . var_export($value, true));
  221. }
  222. $field = array_shift($value);
  223. } elseif (true === $value) {
  224. $where[] = ' ' . $logic . ' 1 ';
  225. continue;
  226. } elseif (!($value instanceof Closure)) {
  227. throw new Exception('where express error:' . var_export($value, true));
  228. }
  229. if ($value instanceof Closure) {
  230. // 使用闭包查询
  231. $whereClosureStr = $this->parseClosureWhere($query, $value, $logic);
  232. if ($whereClosureStr) {
  233. $where[] = $whereClosureStr;
  234. }
  235. } elseif (is_array($field)) {
  236. $where[] = $this->parseMultiWhereField($query, $value, $field, $logic, $binds);
  237. } elseif ($field instanceof Raw) {
  238. $where[] = ' ' . $logic . ' ' . $this->parseWhereItem($query, $field, $value, $binds);
  239. } elseif (str_contains($field, '|')) {
  240. $where[] = $this->parseFieldsOr($query, $value, $field, $logic, $binds);
  241. } elseif (str_contains($field, '&')) {
  242. $where[] = $this->parseFieldsAnd($query, $value, $field, $logic, $binds);
  243. } else {
  244. // 对字段使用表达式查询
  245. $field = is_string($field) ? $field : '';
  246. $where[] = ' ' . $logic . ' ' . $this->parseWhereItem($query, $field, $value, $binds);
  247. }
  248. }
  249. return $where;
  250. }
  251. /**
  252. * 不同字段使用相同查询条件(AND).
  253. *
  254. * @param Query $query 查询对象
  255. * @param mixed $value 查询条件
  256. * @param string $field 查询字段
  257. * @param string $logic Logic
  258. * @param array $binds 参数绑定
  259. *
  260. * @return string
  261. */
  262. protected function parseFieldsAnd(Query $query, $value, string $field, string $logic, array $binds): string
  263. {
  264. $item = [];
  265. foreach (explode('&', $field) as $k) {
  266. $item[] = $this->parseWhereItem($query, $k, $value, $binds);
  267. }
  268. return ' ' . $logic . ' ( ' . implode(' AND ', $item) . ' )';
  269. }
  270. /**
  271. * 不同字段使用相同查询条件(OR).
  272. *
  273. * @param Query $query 查询对象
  274. * @param array $value 查询条件
  275. * @param string $field 查询字段
  276. * @param string $logic Logic
  277. * @param array $binds 参数绑定
  278. *
  279. * @return string
  280. */
  281. protected function parseFieldsOr(Query $query, array $value, string $field, string $logic, array $binds): string
  282. {
  283. $item = [];
  284. foreach (explode('|', $field) as $k) {
  285. $item[] = $this->parseWhereItem($query, $k, $value, $binds);
  286. }
  287. return ' ' . $logic . ' ( ' . implode(' OR ', $item) . ' )';
  288. }
  289. /**
  290. * 闭包查询.
  291. *
  292. * @param Query $query 查询对象
  293. * @param Closure $value 查询条件
  294. * @param string $logic Logic
  295. *
  296. * @return string
  297. */
  298. protected function parseClosureWhere(Query $query, Closure $value, string $logic): string
  299. {
  300. $newQuery = $query->newQuery();
  301. $value($newQuery);
  302. $whereClosure = $this->buildWhere($newQuery, $newQuery->getOptions('where') ?: []);
  303. if (!empty($whereClosure)) {
  304. $query->bind($newQuery->getBind(false));
  305. $where = ' ' . $logic . ' ( ' . $whereClosure . ' )';
  306. }
  307. return $where ?? '';
  308. }
  309. /**
  310. * 复合条件查询.
  311. *
  312. * @param Query $query 查询对象
  313. * @param mixed $value 查询条件
  314. * @param mixed $field 查询字段
  315. * @param string $logic Logic
  316. * @param array $binds 参数绑定
  317. *
  318. * @return string
  319. */
  320. protected function parseMultiWhereField(Query $query, array $value, $field, string $logic, array $binds): string
  321. {
  322. array_unshift($value, $field);
  323. $where = [];
  324. foreach ($value as $item) {
  325. $where[] = $this->parseWhereItem($query, array_shift($item), $item, $binds);
  326. }
  327. return ' ' . $logic . ' ( ' . implode(' AND ', $where) . ' )';
  328. }
  329. /**
  330. * where子单元分析.
  331. *
  332. * @param Query $query 查询对象
  333. * @param mixed $field 查询字段
  334. * @param array $val 查询条件
  335. * @param array $binds 参数绑定
  336. *
  337. * @return string
  338. */
  339. abstract protected function parseWhereItem(Query $query, $field, array $val, array $binds = []): string;
  340. /**
  341. * 模糊查询.
  342. *
  343. * @param Query $query 查询对象
  344. * @param string $key
  345. * @param string $exp
  346. * @param array $value
  347. * @param string $field
  348. * @param int $bindType
  349. * @param string $logic
  350. *
  351. * @return string
  352. */
  353. abstract protected function parseLike(Query $query, string $key, string $exp, $value, $field, int $bindType, string $logic): string;
  354. /**
  355. * 表达式查询.
  356. *
  357. * @param Query $query 查询对象
  358. * @param string $key
  359. * @param string $exp
  360. * @param Raw $value
  361. * @param string $field
  362. * @param int $bindType
  363. *
  364. * @return string
  365. */
  366. protected function parseExp(Query $query, string $key, string $exp, Raw $value, string $field, int $bindType): string
  367. {
  368. // 表达式查询
  369. return '( ' . $key . ' ' . $this->parseRaw($query, $value) . ' )';
  370. }
  371. /**
  372. * 表达式查询.
  373. *
  374. * @param Query $query 查询对象
  375. * @param string $key
  376. * @param string $exp
  377. * @param array $value
  378. * @param string $field
  379. * @param int $bindType
  380. *
  381. * @return string
  382. */
  383. protected function parseColumn(Query $query, string $key, $exp, array $value, string $field, int $bindType): string
  384. {
  385. // 字段比较查询
  386. [$op, $field] = $value;
  387. if (!in_array(trim($op), ['=', '<>', '>', '>=', '<', '<='])) {
  388. throw new Exception('where express error:' . var_export($value, true));
  389. }
  390. return '( ' . $key . ' ' . $op . ' ' . $this->parseKey($query, $field, true) . ' )';
  391. }
  392. /**
  393. * Null查询.
  394. *
  395. * @param Query $query 查询对象
  396. * @param string $key
  397. * @param string $exp
  398. * @param mixed $value
  399. * @param string $field
  400. * @param int $bindType
  401. *
  402. * @return string
  403. */
  404. abstract protected function parseNull(Query $query, string $key, string $exp, $value, $field, int $bindType): string;
  405. /**
  406. * 范围查询.
  407. *
  408. * @param Query $query 查询对象
  409. * @param string $key
  410. * @param string $exp
  411. * @param mixed $value
  412. * @param string $field
  413. * @param int $bindType
  414. *
  415. * @return string
  416. */
  417. abstract protected function parseBetween(Query $query, string $key, string $exp, array|string $value, $field, int $bindType): string;
  418. /**
  419. * Exists查询.
  420. *
  421. * @param Query $query 查询对象
  422. * @param string $key
  423. * @param string $exp
  424. * @param Raw|Closure $value
  425. * @param string $field
  426. * @param int $bindType
  427. *
  428. * @return string
  429. */
  430. protected function parseExists(Query $query, string $key, string $exp, Raw|Closure $value, string $field, int $bindType): string
  431. {
  432. // EXISTS 查询
  433. if ($value instanceof Closure) {
  434. $value = $this->parseClosure($query, $value, false);
  435. } elseif ($value instanceof Raw) {
  436. $value = $this->parseRaw($query, $value);
  437. }
  438. return $exp . ' ( ' . $value . ' )';
  439. }
  440. /**
  441. * 时间比较查询.
  442. *
  443. * @param Query $query 查询对象
  444. * @param string $key
  445. * @param string $exp
  446. * @param mixed $value
  447. * @param string $field
  448. * @param int $bindType
  449. *
  450. * @return string
  451. */
  452. protected function parseTime(Query $query, string $key, string $exp, $value, $field, int $bindType): string
  453. {
  454. return $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($query, $value, $field, $bindType);
  455. }
  456. /**
  457. * 大小比较查询.
  458. *
  459. * @param Query $query 查询对象
  460. * @param string $key
  461. * @param string $exp
  462. * @param mixed $value
  463. * @param string $field
  464. * @param int $bindType
  465. *
  466. * @return string
  467. */
  468. protected function parseCompare(Query $query, string $key, string $exp, $value, $field, int $bindType): string
  469. {
  470. if (is_array($value)) {
  471. throw new Exception('where express error:' . $exp . var_export($value, true));
  472. }
  473. // 比较运算
  474. if ($value instanceof Closure) {
  475. $value = $this->parseClosure($query, $value);
  476. } elseif ($value instanceof Raw) {
  477. $value = $this->parseRaw($query, $value);
  478. }
  479. if ('=' == $exp && is_null($value)) {
  480. return $key . ' IS NULL';
  481. }
  482. return $key . ' ' . $exp . ' ' . $value;
  483. }
  484. /**
  485. * 时间范围查询.
  486. *
  487. * @param Query $query 查询对象
  488. * @param string $key
  489. * @param string $exp
  490. * @param mixed $value
  491. * @param string $field
  492. * @param int $bindType
  493. *
  494. * @return string
  495. */
  496. protected function parseBetweenTime(Query $query, string $key, string $exp, $value, $field, int $bindType): string
  497. {
  498. if (is_string($value)) {
  499. $value = explode(',', $value);
  500. }
  501. return $key . ' ' . substr($exp, 0, -4)
  502. . $this->parseDateTime($query, $value[0], $field, $bindType)
  503. . ' AND '
  504. . $this->parseDateTime($query, $value[1], $field, $bindType);
  505. }
  506. /**
  507. * IN查询.
  508. *
  509. * @param Query $query 查询对象
  510. * @param string $key
  511. * @param string $exp
  512. * @param mixed $value
  513. * @param string $field
  514. * @param int $bindType
  515. *
  516. * @return string
  517. */
  518. abstract protected function parseIn(Query $query, string $key, string $exp, $value, $field, int $bindType): string;
  519. /**
  520. * 闭包子查询.
  521. *
  522. * @param Query $query 查询对象
  523. * @param Closure $call
  524. * @param bool $show
  525. *
  526. * @return string
  527. */
  528. protected function parseClosure(Query $query, Closure $call, bool $show = true): string
  529. {
  530. $newQuery = $query->newQuery()->removeOption();
  531. $call($newQuery);
  532. return $newQuery->buildSql($show);
  533. }
  534. /**
  535. * 日期时间条件解析.
  536. *
  537. * @param Query $query 查询对象
  538. * @param mixed $value
  539. * @param string $key
  540. * @param int $bindType
  541. *
  542. * @return string
  543. */
  544. abstract protected function parseDateTime(Query $query, $value, string $key, int $bindType): string;
  545. /**
  546. * limit分析.
  547. *
  548. * @param Query $query 查询对象
  549. * @param mixed $limit
  550. *
  551. * @return string
  552. */
  553. abstract protected function parseLimit(Query $query, string $limit): string;
  554. /**
  555. * join分析.
  556. *
  557. * @param Query $query 查询对象
  558. * @param array $join
  559. *
  560. * @return string
  561. */
  562. abstract protected function parseJoin(Query $query, array $join): string;
  563. /**
  564. * order分析.
  565. *
  566. * @param Query $query 查询对象
  567. * @param array $order
  568. *
  569. * @return string
  570. */
  571. abstract protected function parseOrder(Query $query, array $order): string;
  572. /**
  573. * 分析Raw对象
  574. *
  575. * @param Query $query 查询对象
  576. * @param Raw $raw Raw对象
  577. *
  578. * @return string
  579. */
  580. abstract protected function parseRaw(Query $query, Raw $raw): string;
  581. /**
  582. * 随机排序.
  583. *
  584. * @param Query $query 查询对象
  585. *
  586. * @return string
  587. */
  588. abstract protected function parseRand(Query $query): string;
  589. /**
  590. * group分析.
  591. *
  592. * @param Query $query 查询对象
  593. * @param mixed $group
  594. *
  595. * @return string
  596. */
  597. abstract protected function parseGroup(Query $query, string|array $group): string;
  598. /**
  599. * having分析.
  600. *
  601. * @param Query $query 查询对象
  602. * @param string $having
  603. *
  604. * @return string
  605. */
  606. abstract protected function parseHaving(Query $query, string $having): string;
  607. /**
  608. * comment分析.
  609. *
  610. * @param Query $query 查询对象
  611. * @param string $comment
  612. *
  613. * @return string
  614. */
  615. protected function parseComment(Query $query, string $comment): string
  616. {
  617. if (str_contains($comment, '*/')) {
  618. $comment = strstr($comment, '*/', true);
  619. }
  620. return !empty($comment) ? ' /* ' . $comment . ' */' : '';
  621. }
  622. /**
  623. * distinct分析.
  624. *
  625. * @param Query $query 查询对象
  626. * @param mixed $distinct
  627. *
  628. * @return string
  629. */
  630. abstract protected function parseDistinct(Query $query, bool $distinct): string;
  631. /**
  632. * union分析.
  633. *
  634. * @param Query $query 查询对象
  635. * @param array $union
  636. *
  637. * @return string
  638. */
  639. protected function parseUnion(Query $query, array $union): string
  640. {
  641. if (empty($union)) {
  642. return '';
  643. }
  644. $type = $union['type'];
  645. unset($union['type']);
  646. foreach ($union as $u) {
  647. if ($u instanceof Closure) {
  648. $sql[] = $type . ' ' . $this->parseClosure($query, $u);
  649. } elseif (is_string($u)) {
  650. $sql[] = $type . ' ( ' . $u . ' )';
  651. }
  652. }
  653. return ' ' . implode(' ', $sql);
  654. }
  655. /**
  656. * index分析,可在操作链中指定需要强制使用的索引.
  657. *
  658. * @param Query $query 查询对象
  659. * @param mixed $index
  660. *
  661. * @return string
  662. */
  663. abstract protected function parseForce(Query $query, string|array $index): string;
  664. /**
  665. * 设置锁机制.
  666. *
  667. * @param Query $query 查询对象
  668. * @param bool|string $lock
  669. *
  670. * @return string
  671. */
  672. abstract protected function parseLock(Query $query, bool|string $lock = false): string;
  673. /**
  674. * 生成查询SQL.
  675. *
  676. * @param Query $query 查询对象
  677. * @param bool $one 是否仅获取一个记录
  678. *
  679. * @return string
  680. */
  681. public function select(Query $query, bool $one = false): string
  682. {
  683. $options = $query->getOptions();
  684. var_dump($options);
  685. var_dump($this->selectSql);
  686. var_dump([
  687. $this->parseTable($query, $options['table']),
  688. $this->parseDistinct($query, $options['distinct']),
  689. $this->parseExtra($query, $options['extra']),
  690. $this->parseField($query, $options['field'] ?? []),
  691. $this->parseJoin($query, $options['join']),
  692. $this->parseWhere($query, $options['where']),
  693. $this->parseGroup($query, $options['group']),
  694. $this->parseHaving($query, $options['having']),
  695. $this->parseOrder($query, $options['order']),
  696. $this->parseLimit($query, $one ? '1' : $options['limit']),
  697. $this->parseUnion($query, $options['union']),
  698. $this->parseLock($query, $options['lock']),
  699. $this->parseComment($query, $options['comment']),
  700. $this->parseForce($query, $options['force']),
  701. ]);die;
  702. var_dump( str_replace(
  703. ['%TABLE%', '%DISTINCT%', '%EXTRA%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'],
  704. [
  705. $this->parseTable($query, $options['table']),
  706. $this->parseDistinct($query, $options['distinct']),
  707. $this->parseExtra($query, $options['extra']),
  708. $this->parseField($query, $options['field'] ?? []),
  709. $this->parseJoin($query, $options['join']),
  710. $this->parseWhere($query, $options['where']),
  711. $this->parseGroup($query, $options['group']),
  712. $this->parseHaving($query, $options['having']),
  713. $this->parseOrder($query, $options['order']),
  714. $this->parseLimit($query, $one ? '1' : $options['limit']),
  715. $this->parseUnion($query, $options['union']),
  716. $this->parseLock($query, $options['lock']),
  717. $this->parseComment($query, $options['comment']),
  718. $this->parseForce($query, $options['force']),
  719. ],
  720. $this->selectSql
  721. ));die;
  722. }
  723. /**
  724. * 生成Insert SQL.
  725. *
  726. * @param Query $query 查询对象
  727. *
  728. * @return string
  729. */
  730. public function insert(Query $query): string
  731. {
  732. $options = $query->getOptions();
  733. // 分析并处理数据
  734. $data = $this->parseData($query, $options['data']);
  735. if (empty($data)) {
  736. return '';
  737. }
  738. $fields = array_keys($data);
  739. $values = array_values($data);
  740. return str_replace(
  741. ['%INSERT%', '%TABLE%', '%EXTRA%', '%FIELD%', '%DATA%', '%COMMENT%'],
  742. [
  743. !empty($options['replace']) ? 'REPLACE' : 'INSERT',
  744. $this->parseTable($query, $options['table']),
  745. $this->parseExtra($query, $options['extra']),
  746. implode(' , ', $fields),
  747. implode(' , ', $values),
  748. $this->parseComment($query, $options['comment']),
  749. ],
  750. $this->insertSql
  751. );
  752. }
  753. /**
  754. * 生成insertall SQL.
  755. *
  756. * @param Query $query 查询对象
  757. * @param array $dataSet 数据集
  758. *
  759. * @return string
  760. */
  761. public function insertAll(Query $query, array $dataSet): string
  762. {
  763. $options = $query->getOptions();
  764. // 获取绑定信息
  765. $bind = $query->getFieldsBindType();
  766. // 获取合法的字段
  767. if (empty($options['field']) || '*' == $options['field']) {
  768. $allowFields = array_keys($bind);
  769. } else {
  770. $allowFields = $options['field'];
  771. }
  772. $fields = [];
  773. $values = [];
  774. foreach ($dataSet as $k => $data) {
  775. $data = $this->parseData($query, $data, $allowFields, $bind);
  776. $values[] = 'SELECT ' . implode(',', array_values($data));
  777. if (!isset($insertFields)) {
  778. $insertFields = array_keys($data);
  779. }
  780. }
  781. foreach ($insertFields as $field) {
  782. $fields[] = $this->parseKey($query, $field);
  783. }
  784. return str_replace(
  785. ['%INSERT%', '%TABLE%', '%EXTRA%', '%FIELD%', '%DATA%', '%COMMENT%'],
  786. [
  787. !empty($options['replace']) ? 'REPLACE' : 'INSERT',
  788. $this->parseTable($query, $options['table']),
  789. $this->parseExtra($query, $options['extra']),
  790. implode(' , ', $fields),
  791. implode(' UNION ALL ', $values),
  792. $this->parseComment($query, $options['comment']),
  793. ],
  794. $this->insertAllSql
  795. );
  796. }
  797. /**
  798. * 生成slect insert SQL.
  799. *
  800. * @param Query $query 查询对象
  801. * @param array $fields 数据
  802. * @param string $table 数据表
  803. *
  804. * @return string
  805. */
  806. public function selectInsert(Query $query, array $fields, string $table): string
  807. {
  808. foreach ($fields as &$field) {
  809. $field = $this->parseKey($query, $field, true);
  810. }
  811. return 'INSERT INTO ' . $this->parseTable($query, $table) . ' (' . implode(',', $fields) . ') ' . $this->select($query);
  812. }
  813. /**
  814. * 生成update SQL.
  815. *
  816. * @param Query $query 查询对象
  817. *
  818. * @return string
  819. */
  820. public function update(Query $query): string
  821. {
  822. $options = $query->getOptions();
  823. $data = $this->parseData($query, $options['data']);
  824. if (empty($data)) {
  825. return '';
  826. }
  827. $set = [];
  828. foreach ($data as $key => $val) {
  829. $set[] = $key . ' = ' . $val;
  830. }
  831. return str_replace(
  832. ['%TABLE%', '%EXTRA%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
  833. [
  834. $this->parseTable($query, $options['table']),
  835. $this->parseExtra($query, $options['extra']),
  836. implode(' , ', $set),
  837. $this->parseJoin($query, $options['join']),
  838. $this->parseWhere($query, $options['where']),
  839. $this->parseOrder($query, $options['order']),
  840. $this->parseLimit($query, $options['limit']),
  841. $this->parseLock($query, $options['lock']),
  842. $this->parseComment($query, $options['comment']),
  843. ],
  844. $this->updateSql
  845. );
  846. }
  847. /**
  848. * 生成delete SQL.
  849. *
  850. * @param Query $query 查询对象
  851. *
  852. * @return string
  853. */
  854. public function delete(Query $query): string
  855. {
  856. $options = $query->getOptions();
  857. return str_replace(
  858. ['%TABLE%', '%EXTRA%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
  859. [
  860. $this->parseTable($query, $options['table']),
  861. $this->parseExtra($query, $options['extra']),
  862. !empty($options['using']) ? ' USING ' . $this->parseTable($query, $options['using']) . ' ' : '',
  863. $this->parseJoin($query, $options['join']),
  864. $this->parseWhere($query, $options['where']),
  865. $this->parseOrder($query, $options['order']),
  866. $this->parseLimit($query, $options['limit']),
  867. $this->parseLock($query, $options['lock']),
  868. $this->parseComment($query, $options['comment']),
  869. ],
  870. $this->deleteSql
  871. );
  872. }
  873. }