Mysql.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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\Expression;
  14. use think\db\Query;
  15. use think\Exception;
  16. /**
  17. * mysql数据库驱动
  18. */
  19. class Mysql extends Builder
  20. {
  21. // 查询表达式解析
  22. protected $parser = [
  23. 'parseCompare' => ['=', '<>', '>', '>=', '<', '<='],
  24. 'parseLike' => ['LIKE', 'NOT LIKE'],
  25. 'parseBetween' => ['NOT BETWEEN', 'BETWEEN'],
  26. 'parseIn' => ['NOT IN', 'IN'],
  27. 'parseExp' => ['EXP'],
  28. 'parseRegexp' => ['REGEXP', 'NOT REGEXP'],
  29. 'parseNull' => ['NOT NULL', 'NULL'],
  30. 'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
  31. 'parseTime' => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
  32. 'parseExists' => ['NOT EXISTS', 'EXISTS'],
  33. 'parseColumn' => ['COLUMN'],
  34. ];
  35. protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
  36. protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
  37. /**
  38. * 生成insertall SQL
  39. * @access public
  40. * @param Query $query 查询对象
  41. * @param array $dataSet 数据集
  42. * @param bool $replace 是否replace
  43. * @return string
  44. */
  45. public function insertAll(Query $query, $dataSet, $replace = false)
  46. {
  47. $options = $query->getOptions();
  48. // 获取合法的字段
  49. if ('*' == $options['field']) {
  50. $allowFields = $this->connection->getTableFields($options['table']);
  51. } else {
  52. $allowFields = $options['field'];
  53. }
  54. // 获取绑定信息
  55. $bind = $this->connection->getFieldsBind($options['table']);
  56. foreach ($dataSet as $k => $data) {
  57. $data = $this->parseData($query, $data, $allowFields, $bind);
  58. $values[] = '( ' . implode(',', array_values($data)) . ' )';
  59. if (!isset($insertFields)) {
  60. $insertFields = array_keys($data);
  61. }
  62. }
  63. $fields = [];
  64. foreach ($insertFields as $field) {
  65. $fields[] = $this->parseKey($query, $field);
  66. }
  67. return str_replace(
  68. ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
  69. [
  70. $replace ? 'REPLACE' : 'INSERT',
  71. $this->parseTable($query, $options['table']),
  72. implode(' , ', $fields),
  73. implode(' , ', $values),
  74. $this->parseComment($query, $options['comment']),
  75. ],
  76. $this->insertAllSql);
  77. }
  78. /**
  79. * 正则查询
  80. * @access protected
  81. * @param Query $query 查询对象
  82. * @param string $key
  83. * @param string $exp
  84. * @param mixed $value
  85. * @param string $field
  86. * @return string
  87. */
  88. protected function parseRegexp(Query $query, $key, $exp, $value, $field)
  89. {
  90. if ($value instanceof Expression) {
  91. $value = $value->getValue();
  92. }
  93. return $key . ' ' . $exp . ' ' . $value;
  94. }
  95. /**
  96. * 字段和表名处理
  97. * @access public
  98. * @param Query $query 查询对象
  99. * @param mixed $key 字段名
  100. * @param bool $strict 严格检测
  101. * @return string
  102. */
  103. public function parseKey(Query $query, $key, $strict = false)
  104. {
  105. if (is_numeric($key)) {
  106. return $key;
  107. } elseif ($key instanceof Expression) {
  108. return $key->getValue();
  109. }
  110. $key = trim($key);
  111. if(strpos($key, '->>') && false === strpos($key, '(')){
  112. // JSON字段支持
  113. list($field, $name) = explode('->>', $key, 2);
  114. return $this->parseKey($query, $field, true) . '->>\'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->>', '.', $name) . '\'';
  115. }
  116. elseif (strpos($key, '->') && false === strpos($key, '(')) {
  117. // JSON字段支持
  118. list($field, $name) = explode('->', $key, 2);
  119. return 'json_extract(' . $this->parseKey($query, $field, true) . ', \'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->', '.', $name) . '\')';
  120. } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
  121. list($table, $key) = explode('.', $key, 2);
  122. $alias = $query->getOptions('alias');
  123. if ('__TABLE__' == $table) {
  124. $table = $query->getOptions('table');
  125. $table = is_array($table) ? array_shift($table) : $table;
  126. }
  127. if (isset($alias[$table])) {
  128. $table = $alias[$table];
  129. }
  130. }
  131. if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
  132. throw new Exception('not support data:' . $key);
  133. }
  134. if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
  135. $key = '`' . $key . '`';
  136. }
  137. if (isset($table)) {
  138. if (strpos($table, '.')) {
  139. $table = str_replace('.', '`.`', $table);
  140. }
  141. $key = '`' . $table . '`.' . $key;
  142. }
  143. return $key;
  144. }
  145. /**
  146. * 随机排序
  147. * @access protected
  148. * @param Query $query 查询对象
  149. * @return string
  150. */
  151. protected function parseRand(Query $query)
  152. {
  153. return 'rand()';
  154. }
  155. }