Mysql.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 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. namespace think\db\builder;
  12. use think\db\Builder;
  13. use think\db\Query;
  14. /**
  15. * mysql数据库驱动
  16. */
  17. class Mysql extends Builder
  18. {
  19. // 查询表达式解析
  20. protected $parser = [
  21. 'parseCompare' => ['=', '<>', '>', '>=', '<', '<='],
  22. 'parseLike' => ['LIKE', 'NOT LIKE'],
  23. 'parseBetween' => ['NOT BETWEEN', 'BETWEEN'],
  24. 'parseIn' => ['NOT IN', 'IN'],
  25. 'parseExp' => ['EXP'],
  26. 'parseRegexp' => ['REGEXP', 'NOT REGEXP'],
  27. 'parseNull' => ['NOT NULL', 'NULL'],
  28. 'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
  29. 'parseTime' => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
  30. 'parseExists' => ['NOT EXISTS', 'EXISTS'],
  31. ];
  32. protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
  33. protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
  34. /**
  35. * 生成insertall SQL
  36. * @access public
  37. * @param Query $query 查询对象
  38. * @param array $dataSet 数据集
  39. * @param bool $replace 是否replace
  40. * @return string
  41. */
  42. public function insertAll(Query $query, $dataSet, $replace = false)
  43. {
  44. $options = $query->getOptions();
  45. // 获取合法的字段
  46. if ('*' == $options['field']) {
  47. $allowFields = $this->connection->getTableFields($options['table']);
  48. } else {
  49. $allowFields = $options['field'];
  50. }
  51. // 获取绑定信息
  52. $bind = $this->connection->getFieldsBind($options['table']);
  53. foreach ($dataSet as $k => $data) {
  54. $data = $this->parseData($query, $data, $allowFields, $bind, '_' . $k);
  55. $values[] = '( ' . implode(',', array_values($data)) . ' )';
  56. if (!isset($insertFields)) {
  57. $insertFields = array_keys($data);
  58. }
  59. }
  60. $fields = [];
  61. foreach ($insertFields as $field) {
  62. $fields[] = $this->parseKey($query, $field);
  63. }
  64. return str_replace(
  65. ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
  66. [
  67. $replace ? 'REPLACE' : 'INSERT',
  68. $this->parseTable($query, $options['table']),
  69. implode(' , ', $fields),
  70. implode(' , ', $values),
  71. $this->parseComment($query, $options['comment']),
  72. ],
  73. $this->insertAllSql);
  74. }
  75. /**
  76. * 正则查询
  77. * @access protected
  78. * @param Query $query 查询对象
  79. * @param string $key
  80. * @param string $exp
  81. * @param mixed $value
  82. * @param string $field
  83. * @return string
  84. */
  85. protected function parseRegexp(Query $query, $key, $exp, $value, $field)
  86. {
  87. return $key . ' ' . $exp . ' ' . $value;
  88. }
  89. /**
  90. * 字段和表名处理
  91. * @access public
  92. * @param Query $query 查询对象
  93. * @param string $key 字段名
  94. * @return string
  95. */
  96. public function parseKey(Query $query, $key)
  97. {
  98. if (is_int($key)) {
  99. return $key;
  100. }
  101. $key = trim($key);
  102. if (strpos($key, '->') && false === strpos($key, '(')) {
  103. // JSON字段支持
  104. list($field, $name) = explode('->', $key);
  105. $key = 'json_extract(' . $this->parseKey($query, $field) . ', \'$.' . $name . '\')';
  106. } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
  107. list($table, $key) = explode('.', $key, 2);
  108. $alias = $query->getOptions('alias');
  109. if ('__TABLE__' == $table) {
  110. $table = $query->getOptions('table');
  111. $table = is_array($table) ? array_shift($table) : $table;
  112. }
  113. if (isset($alias[$table])) {
  114. $table = $alias[$table];
  115. }
  116. }
  117. if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
  118. $key = '`' . $key . '`';
  119. }
  120. if (isset($table)) {
  121. if (strpos($table, '.')) {
  122. $table = str_replace('.', '`.`', $table);
  123. }
  124. $key = '`' . $table . '`.' . $key;
  125. }
  126. return $key;
  127. }
  128. /**
  129. * field分析
  130. * @access protected
  131. * @param Query $query 查询对象
  132. * @param mixed $fields 字段名
  133. * @return string
  134. */
  135. protected function parseField(Query $query, $fields)
  136. {
  137. $fieldsStr = parent::parseField($query, $fields);
  138. $options = $query->getOptions();
  139. if (!empty($options['point'])) {
  140. $array = [];
  141. foreach ($options['point'] as $key => $field) {
  142. $key = !is_numeric($key) ? $key : $field;
  143. $array[] = 'AsText(' . $this->parseKey($query, $key) . ') AS ' . $this->parseKey($query, $field);
  144. }
  145. $fieldsStr .= ',' . implode(',', $array);
  146. }
  147. return $fieldsStr;
  148. }
  149. /**
  150. * 数组数据解析
  151. * @access protected
  152. * @param array $data
  153. * @return mixed
  154. */
  155. protected function parseArrayData($data)
  156. {
  157. list($type, $value) = $data;
  158. switch (strtolower($type)) {
  159. case 'exp':
  160. $result = $value;
  161. break;
  162. case 'point':
  163. $fun = isset($data[2]) ? $data[2] : 'GeomFromText';
  164. $point = isset($data[3]) ? $data[3] : 'POINT';
  165. if (is_array($value)) {
  166. $value = implode(' ', $value);
  167. }
  168. $result = $fun . '(\'' . $point . '(' . $value . ')\')';
  169. break;
  170. default:
  171. $result = false;
  172. }
  173. return $result;
  174. }
  175. /**
  176. * 随机排序
  177. * @access protected
  178. * @param Query $query 查询对象
  179. * @return string
  180. */
  181. protected function parseRand(Query $query)
  182. {
  183. return 'rand()';
  184. }
  185. }