PageRenderTime 44ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/Driver/Sql.php

https://github.com/ilyich/iqyou
PHP | 408 lines | 334 code | 64 blank | 10 comment | 60 complexity | e88613aab261ba5bc5244b0ffbc5f875 MD5 | raw file
  1. <?php
  2. class Driver_Sql extends Driver_DBQuery
  3. {
  4. public static $dbByTable = array();
  5. public static $dbnameDefault = '';
  6. /**
  7. * @return Driver_Select
  8. */
  9. public static function select()
  10. {
  11. return new Driver_Select();
  12. }
  13. public static function qqInsertMulty($binds, &$sqlCols=null)
  14. {
  15. $sqlVals = array();
  16. foreach ($binds as $bind) {
  17. $sqlVals[] = self::qqInsert($bind, $sqlCols);
  18. }
  19. $sql = '('.implode('), (', $sqlVals).')';
  20. return $sql;
  21. }
  22. public static function qqInsert($bind, &$sqlCols=null)
  23. {
  24. $cols = array();
  25. $vals = array();
  26. foreach ($bind as $col => $val) {
  27. $cols[] = self::quoteIdentifier($col);
  28. if ($val instanceof Zend_Db_Expr) {
  29. $vals[] = $val->__toString();
  30. unset($bind[$col]);
  31. } else {
  32. $vals[] = self::quote($val); // '?'
  33. }
  34. }
  35. $sqlCols = implode(', ', $cols);
  36. $sqlVals = implode(', ', $vals);
  37. return $sqlVals;
  38. }
  39. public static function qqUpdate($bind)
  40. {
  41. $set = array();
  42. foreach ($bind as $col => $val) {
  43. if ($val instanceof Zend_Db_Expr) {
  44. $val = $val->__toString();
  45. unset($bind[$col]);
  46. } else {
  47. $val = self::quote($val); // '?';
  48. }
  49. $set[] = self::quoteIdentifier($col) . ' = ' . $val;
  50. }
  51. $sql = implode(', ', $set);
  52. return $sql;
  53. }
  54. public static function sqlInsert($table, array $bind, $duplicate = '', &$dbName = null, $insertIgnore = false)
  55. {
  56. $cols = array();
  57. $vals = array();
  58. foreach ($bind as $col => $val) {
  59. $cols[] = self::quoteIdentifier($col);
  60. if ($val instanceof Zend_Db_Expr) {
  61. $vals[] = $val->__toString();
  62. unset($bind[$col]);
  63. } else {
  64. $vals[] = self::quote($val); // '?'
  65. }
  66. }
  67. $sql = 'INSERT '.(!$insertIgnore ? '' : 'IGNORE ').'INTO '
  68. . self::quoteIdentifier($table)
  69. . ' (' . implode(', ', $cols) . ') '
  70. . 'VALUES (' . implode(', ', $vals) . ')';
  71. if (!$insertIgnore && $duplicate) {
  72. $sql .= ' ON DUPLICATE KEY UPDATE ';
  73. if (is_array($duplicate)) {
  74. $vals = array();
  75. foreach ($duplicate as $col => $val) {
  76. $vals[] = self::quoteIdentifier($col) . ' = ' . self::quote($val);
  77. }
  78. $sql .= implode(', ', $vals);
  79. } else {
  80. $sql .= $duplicate;
  81. }
  82. }
  83. $dbName = self::_getDbnameByTable($table);
  84. return $sql;
  85. }
  86. public static function sqlInsertMultiple($table, array $binds, &$dbName = null)
  87. {
  88. $cols = array();
  89. $vals = array();
  90. foreach ($binds as $k => $bind) {
  91. foreach ($bind as $col => $val) {
  92. $cols[] = self::quoteIdentifier($col);
  93. if ($val instanceof Zend_Db_Expr) {
  94. $val = $val->__toString();
  95. } else {
  96. $val = self::quote($val); // '?'
  97. }
  98. $binds[$k][$col] = $val;
  99. }
  100. }
  101. $cols = array_unique($cols);
  102. foreach ($binds as $bind) {
  103. $sqlVals[] = implode(',', $bind);
  104. }
  105. $sql = "INSERT INTO "
  106. . self::quoteIdentifier($table)
  107. . ' (' . implode(', ', $cols) . ') '
  108. . 'VALUES ('. implode('), (', $sqlVals) .')';
  109. $dbName = self::_getDbnameByTable($table);
  110. return $sql;
  111. }
  112. public static function sqlInsertMultipleIgnore($table, array $binds, &$dbName = null)
  113. {
  114. $cols = array();
  115. $vals = array();
  116. foreach ($binds as $k => $bind) {
  117. foreach ($bind as $col => $val) {
  118. $cols[] = self::quoteIdentifier($col);
  119. if ($val instanceof Zend_Db_Expr) {
  120. $val = $val->__toString();
  121. } else {
  122. $val = self::quote($val); // '?'
  123. }
  124. $binds[$k][$col] = $val;
  125. }
  126. }
  127. $cols = array_unique($cols);
  128. foreach ($binds as $bind) {
  129. $sqlVals[] = implode(',', $bind);
  130. }
  131. $sql = "INSERT IGNORE INTO "
  132. . self::quoteIdentifier($table)
  133. . ' (' . implode(', ', $cols) . ') '
  134. . 'VALUES ('. implode('), (', $sqlVals) .')';
  135. $dbName = self::_getDbnameByTable($table);
  136. return $sql;
  137. }
  138. public static function sqlInsertMultipleUpdate($table, array $binds, $duplicate = false)
  139. {
  140. $cols = array();
  141. $vals = array();
  142. foreach ($binds as $k => $bind) {
  143. foreach ($bind as $col => $val) {
  144. $cols[] = self::quoteIdentifier($col);
  145. if ($val instanceof Zend_Db_Expr) {
  146. $val = $val->__toString();
  147. } else {
  148. $val = self::quote($val); // '?'
  149. }
  150. $binds[$k][$col] = $val;
  151. }
  152. }
  153. $cols = array_unique($cols);
  154. foreach ($binds as $bind) {
  155. $sqlVals[] = implode(',', $bind);
  156. }
  157. $sql = "INSERT IGNORE INTO "
  158. . self::quoteIdentifier($table)
  159. . ' (' . implode(', ', $cols) . ') '
  160. . 'VALUES ('. implode('), (', $sqlVals) .')';
  161. if ($duplicate) {
  162. $sql .= ' ON DUPLICATE KEY UPDATE ';
  163. if (is_array($duplicate)) {
  164. $vals = array();
  165. foreach ($duplicate as $col => $val) {
  166. $vals[] = self::quoteIdentifier($col) . ' = ' . self::quote($val);
  167. }
  168. $sql .= implode(', ', $vals);
  169. } else {
  170. $sql .= $duplicate;
  171. }
  172. }
  173. $dbName = self::_getDbnameByTable($table);
  174. return $sql;
  175. }
  176. public static function sqlUpdate($table, array $bind, $where = '', &$dbName = null)
  177. {
  178. $set = array();
  179. foreach ($bind as $col => $val) {
  180. if ($val instanceof Zend_Db_Expr) {
  181. $val = $val->__toString();
  182. unset($bind[$col]);
  183. } else {
  184. $val = self::quote($val); // '?';
  185. }
  186. $set[] = self::quoteIdentifier($col) . ' = ' . $val;
  187. }
  188. $sql = "UPDATE "
  189. . self::quoteIdentifier($table)
  190. . ' SET ' . implode(', ', $set)
  191. . (($where) ? " WHERE ($where)" : '');
  192. $dbName = self::_getDbnameByTable($table);
  193. return $sql;
  194. }
  195. public static function sqlDelete($table, $where = '', &$dbName = null)
  196. {
  197. $sql = "DELETE FROM "
  198. . self::quoteIdentifier($table)
  199. . (($where) ? " WHERE ($where)" : '');
  200. $dbName = self::_getDbnameByTable($table);
  201. return $sql;
  202. }
  203. public static function sqlReplace($table, array $bind, &$dbName = null)
  204. {
  205. $cols = array();
  206. $vals = array();
  207. foreach ($bind as $col => $val) {
  208. $cols[] = self::quoteIdentifier($col);
  209. if ($val instanceof Zend_Db_Expr) {
  210. $vals[] = $val->__toString();
  211. unset($bind[$col]);
  212. } else {
  213. $vals[] = self::quote($val); // '?'
  214. }
  215. }
  216. $sql = 'REPLACE INTO '.self::quoteIdentifier($table).' ('.implode(', ', $cols).') VALUES ('.implode(', ', $vals).')';
  217. $dbName = self::_getDbnameByTable($table);
  218. return $sql;
  219. }
  220. public static function quote($value)
  221. {
  222. if (is_int($value)) {
  223. return $value;
  224. } elseif (is_float($value)) {
  225. return sprintf('%F', $value);
  226. } elseif (is_array($value)) {
  227. foreach ($value as &$val) {
  228. $val = self::quote($val);
  229. }
  230. return implode(', ', $value);
  231. } elseif ($value instanceof Zend_Db_Expr) {
  232. return $value->__toString();
  233. }
  234. return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
  235. }
  236. public static function quoteInto($text, $value, $type = null, $count = null)
  237. {
  238. if ($count === null) {
  239. return str_replace('?', self::quote($value, $type), $text);
  240. } else {
  241. while ($count > 0) {
  242. if (Utf::strpos($text, '?') != false) {
  243. $text = Utf::substr_replace($text, self::quote($value, $type), Utf::strpos($text, '?'), 1);
  244. }
  245. --$count;
  246. }
  247. return $text;
  248. }
  249. }
  250. public static function quoteIdentifier($value)
  251. {
  252. if (Utf::strpos($value, '*') !== false || Utf::strpos($value, '(') !== false) return $value;
  253. if (Utf::strpos($value, '.') !== false) {
  254. $vals = explode('.', $value);
  255. foreach ($vals as &$v) $v = self::quoteIdentifier($v);
  256. return implode('.', $vals);
  257. }
  258. $q = '`';
  259. return ($q . str_replace("$q", "$q$q", $value) . $q);
  260. }
  261. public static function qq($subject, $values = '', $identifiers = array())
  262. {
  263. if (!is_array($values)) {
  264. $values = array($values);
  265. }
  266. if (!is_array($identifiers)) {
  267. $identifiers = array($identifiers);
  268. }
  269. if (!empty($values)) {
  270. for ($i = 0; $i < Utf::strlen($subject); $i++) {
  271. $char = Utf::getChar($subject, $i);
  272. if ($char == '?' && !empty($values)) {
  273. $value = self::quote(array_shift($values));
  274. $subject = Utf::substr_replace($subject, $value, $i, 1);
  275. $i += Utf::strlen($value);
  276. }
  277. }
  278. }
  279. if (!empty($identifiers)) {
  280. for ($i = 0; $i < Utf::strlen($subject); $i++) {
  281. $char = Utf::getChar($subject, $i);
  282. if ($char == '@' && !empty($identifiers)) {
  283. $value = self::quoteIdentifier(array_shift($identifiers));
  284. $subject = Utf::substr_replace($subject, $value, $i, 1);
  285. $i += Utf::strlen($value);
  286. }
  287. }
  288. }
  289. return $subject;
  290. }
  291. /**
  292. * Следующие две функции занимаются получение имени таблицы из селект
  293. * и определением dbName по таблице
  294. */
  295. public static function _getTableFromSelect($select)
  296. {
  297. if (is_object($select)) {
  298. $select = $select->__toString();
  299. }
  300. Utf::preg_match('/FROM\s+`?([\w\d]+)`?/i', $select, $matches);
  301. if ($matches[1]) {
  302. return $matches[1];
  303. }
  304. else throw new Exception('cant define table ! '.$select);
  305. }
  306. public static function _getDbnameByTable($table)
  307. {
  308. if (!isset(self::$dbByTable[$table])) {
  309. $listDb = Base_Application::getInstance()->config['db']['tables'];
  310. $dbName = 'database';
  311. // Обработка имени дефолтной базы (сработает только если вдруг это станет не database)
  312. if (!isset($listDb[$dbName]) || !$listDb[$dbName] == 'DEFAULT') {
  313. foreach ($listDb as $name => $tables) {
  314. if (is_string($tables) && $tables == 'DEFAULT') {
  315. $dbName = $name;
  316. }
  317. }
  318. }
  319. // Ищем таблицу по полному названию напрямую
  320. $found = false;
  321. foreach ($listDb as $name => $tables) {
  322. if (is_array($tables) && in_array($table, $tables)) {
  323. $dbName = $name;
  324. $found = true;
  325. break;
  326. }
  327. }
  328. if (!$found) {
  329. // Таблицу не нашли, отрезаем правое число и ищем по названию = префикс*
  330. if (Utf::preg_match('/((.+)([^(\d+)]))(\d+)$/', $table, $matches)) {
  331. $partTable = $matches[1] . '*';
  332. foreach ($listDb as $name => $tables) {
  333. if (is_array($tables) && in_array($partTable, $tables)) {
  334. $dbName = $name;
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. self::$dbByTable[$table] = $dbName;
  341. }
  342. return self::$dbByTable[$table];
  343. }
  344. }