PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/mysql.query.insert.class.php

https://github.com/magedeveloper/frosted-mysql-library
PHP | 560 lines | 463 code | 38 blank | 59 comment | 39 complexity | 5c1b22c2d323c6b92921430bb9d0a687 MD5 | raw file
  1. <?php
  2. /**
  3. * Frosted MySQL Library Insert Query Class
  4. * - - - - - - - - - -
  5. * Add "INSERT" functionality to Frosted MySQL Library and will not work without them.
  6. * - - - - - - - - - -
  7. * Licensed under MIT license
  8. * - - - - - - - - - -
  9. * @Creator Daniel 'Eisbehr' Kern
  10. * @Require PHP5
  11. * @Version 3.0
  12. * @Date 01.08.2013
  13. * @Update 01.08.2013
  14. * - - - - - - - - - -
  15. */
  16. class mysqlClass_Insert extends mysqlClass_Abstract implements mysqlClass_Queries
  17. {
  18. /**
  19. * insert error messages
  20. * @var string
  21. */
  22. const MESSAGE_AFTER_FIELDS = "you cannot add columns after using 'set' or 'select'";
  23. const MESSAGE_AFTER_SET = "you cannot use 'set' after adding columns or a select";
  24. const MESSAGE_AFTER_SELECT = "you cannot use 'select' after adding values or 'set'";
  25. const MESSAGE_BEFORE_VALUES = "you have to specify a column list before adding values";
  26. const MESSAGE_VALUES_COUNT = "value count doesn't match columns";
  27. const MESSAGE_VALUES_MISSING = "columns not found in values";
  28. /*
  29. ** public
  30. */
  31. /**
  32. * reset insert class
  33. * @param boolean $format
  34. * @return mysqlClass_Select
  35. */
  36. public function resetQuery($format)
  37. {
  38. parent::resetQuery($format);
  39. $this->query["table"] = NULL;
  40. $this->query["low"] = false;
  41. $this->query["delayed"] = false;
  42. $this->query["high"] = false;
  43. $this->query["ignore"] = false;
  44. $this->query["columns"] = array();
  45. $this->query["values"] = array();
  46. $this->query["set"] = array();
  47. $this->query["select"] = NULL;
  48. $this->query["duplicate"] = array();
  49. return $this;
  50. }
  51. /*
  52. ** query related
  53. */
  54. /**
  55. * add table to insert query
  56. * @param string $table
  57. * @return mysqlClass_Insert
  58. */
  59. public function table($table)
  60. {
  61. if( is_string($table) )
  62. $this->query["table"] = $table;
  63. else if( is_array($table) )
  64. foreach( $table as $_table => $_name )
  65. if( !is_numeric($_table) )
  66. $this->query["table"] = $_table;
  67. else
  68. $this->query["table"] = $_name;
  69. return $this;
  70. }
  71. /**
  72. * alias of 'table'
  73. * @param string $table
  74. * @return mysqlClass_Insert
  75. */
  76. public function into($table)
  77. {
  78. return $this->table($table);
  79. }
  80. /**
  81. * add 'low priority' to query
  82. * @param boolean $low
  83. * @return mysqlClass_Insert
  84. */
  85. public function lowPriority($low = true)
  86. {
  87. if( (bool)$low )
  88. {
  89. $this->query["delayed"] = false;
  90. $this->query["high"] = false;
  91. }
  92. $this->query["low"] = (bool)$low;
  93. return $this;
  94. }
  95. /**
  96. * add 'delayed' to insert query
  97. * @param boolean $delayed
  98. * @return mysqlClass_Insert
  99. */
  100. public function delayed($delayed = true)
  101. {
  102. if( (bool)$delayed )
  103. {
  104. $this->query["low"] = false;
  105. $this->query["high"] = false;
  106. }
  107. $this->query["delayed"] = (bool)$delayed;
  108. return $this;
  109. }
  110. /**
  111. * add 'high priority' to query
  112. * @param boolean $high
  113. * @return mysqlClass_Insert
  114. */
  115. public function highPriority($high = true)
  116. {
  117. if( (bool)$high )
  118. {
  119. $this->query["low"] = false;
  120. $this->query["delayed"] = false;
  121. }
  122. $this->query["high"] = (bool)$high;
  123. return $this;
  124. }
  125. /**
  126. * add 'ignore' to insert query
  127. * @param boolean $ignore
  128. * @return mysqlClass_Insert
  129. */
  130. public function ignore($ignore = true)
  131. {
  132. $this->query["ignore"] = (bool)$ignore;
  133. return $this;
  134. }
  135. /**
  136. * add columns to insert query
  137. * @param string|array $columns
  138. * @return mysqlClass_Insert
  139. */
  140. public function columns($columns)
  141. {
  142. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  143. {
  144. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  145. return $this;
  146. }
  147. if( func_num_args() == 1 && is_string($columns) && !in_array($columns, $this->query["columns"]) )
  148. {
  149. $this->query["columns"][] = $columns;
  150. return $this;
  151. }
  152. foreach( func_get_args() as $column )
  153. {
  154. if( !is_array($column) && !in_array($column, $this->query["columns"]) )
  155. {
  156. $this->query["columns"][] = $column;
  157. }
  158. else
  159. {
  160. foreach( $column as $_column )
  161. if( !in_array($_column, $this->query["columns"]) )
  162. $this->query["columns"][] = $_column;
  163. }
  164. }
  165. return $this;
  166. }
  167. /**
  168. * alias of "columns"
  169. * @param string|array $fields
  170. * @return mysqlClass_Insert
  171. */
  172. public function fields($fields)
  173. {
  174. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  175. {
  176. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  177. return $this;
  178. }
  179. if( func_num_args() == 1 && is_string($fields) && !in_array($fields, $this->query["columns"]) )
  180. {
  181. $this->query["columns"][] = $fields;
  182. return $this;
  183. }
  184. return call_user_func_array(array($this, "columns"), func_get_args());
  185. }
  186. /**
  187. * add 'values' to insert query
  188. * @param string|array $values
  189. * @return mysqlClass_Insert
  190. */
  191. public function values($values)
  192. {
  193. $columnCount = count($this->query["columns"]);
  194. if( $columnCount == 0 )
  195. {
  196. $this->parent->createError(self::MESSAGE_BEFORE_VALUES);
  197. return $this;
  198. }
  199. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  200. {
  201. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  202. return $this;
  203. }
  204. if( func_num_args() == 1 && $columnCount == 1 && !is_array($values) )
  205. {
  206. $this->query["values"][] = array($values);
  207. return $this;
  208. }
  209. // count params
  210. $count = 0;
  211. $values = array();
  212. foreach( func_get_args() as $value )
  213. {
  214. if( !is_array($value) )
  215. {
  216. $count++;
  217. $values[] = $this->parent->escape($value);
  218. }
  219. else
  220. {
  221. foreach( $value as $_key => $_value )
  222. {
  223. $count++;
  224. if( is_numeric($_key) )
  225. $values[] = $this->parent->escape($_value);
  226. else
  227. $values[$_key] = $this->parent->escape($_value);
  228. }
  229. }
  230. }
  231. // check if params count match fields
  232. if( $count == $columnCount )
  233. {
  234. $this->query["values"][] = $values;
  235. }
  236. // check if fields names are in values
  237. else if( $count > $columnCount )
  238. {
  239. $_values = array();
  240. foreach( $this->query["columns"] as $column )
  241. {
  242. if( !isset($values[$column]) ) break;
  243. $_values[] = $values[$column];
  244. }
  245. if( count($_values) == $columnCount )
  246. $this->query["values"][] = $_values;
  247. else
  248. $this->parent->createError(self::MESSAGE_VALUES_MISSING);
  249. }
  250. // values doesn't match
  251. else
  252. {
  253. $this->parent->createError(self::MESSAGE_VALUES_COUNT);
  254. }
  255. return $this;
  256. }
  257. /**
  258. * add 'set' to insert query
  259. * @param string|array $column
  260. * @param string $replace
  261. * @return mysqlClass_Insert
  262. */
  263. public function set($column, $replace = NULL)
  264. {
  265. if( count($this->query["columns"]) > 0 || !is_null($this->query["select"]) )
  266. {
  267. $this->parent->createError(self::MESSAGE_AFTER_SET);
  268. return $this;
  269. }
  270. if( is_null($replace) )
  271. {
  272. if( is_array($column) )
  273. {
  274. foreach( $column as $_column => $_replace )
  275. {
  276. if( !is_numeric($_column) )
  277. if( strpos($_column, "?") === false && strpos($column, "=") === false )
  278. $this->query["set"][] = $_column . " = " . $this->parent->escape($_replace);
  279. else
  280. $this->query["set"][] = str_replace("?", $this->parent->escape($_replace), $_column);
  281. else
  282. $this->query["set"][] = $_replace;
  283. }
  284. }
  285. else
  286. {
  287. $this->query["set"][] = $column;
  288. }
  289. }
  290. else
  291. {
  292. if( strpos($column, "?") === false && strpos($column, "=") === false )
  293. $this->query["set"][] = $column . " = " . $this->parent->escape($replace);
  294. else
  295. $this->query["set"][] = str_replace("?", $this->parent->escape($replace), $column);
  296. }
  297. return $this;
  298. }
  299. /**
  300. * add a select statement to insert query
  301. * @param string|mysqlClass_Select $subSelect
  302. * @return mysqlClass_Insert
  303. */
  304. public function select($subSelect)
  305. {
  306. if( count($this->query["values"]) > 0 || count($this->query["set"]) > 0 )
  307. {
  308. $this->parent->createError(self::MESSAGE_AFTER_SELECT);
  309. return $this;
  310. }
  311. if( is_string($subSelect) || $subSelect instanceof mysqlClass_Select )
  312. {
  313. $this->query["select"] = $subSelect;
  314. }
  315. return $this;
  316. }
  317. /**
  318. * add 'onDuplicate' to query
  319. * @param array|string $update
  320. * @param string $replace
  321. * @return mysqlClass_Insert
  322. */
  323. public function onDuplicate($update, $replace = NULL)
  324. {
  325. if( is_null($replace) )
  326. {
  327. if( is_array($update) )
  328. {
  329. foreach( $update as $_update => $_replace )
  330. {
  331. if( !is_numeric($_update) )
  332. $this->query["duplicate"][] = str_replace("?", $this->parent->escape($_replace), $_update);
  333. else
  334. $this->query["duplicate"][] = $_replace;
  335. }
  336. }
  337. else
  338. {
  339. $this->query["duplicate"][] = $update;
  340. }
  341. }
  342. else
  343. {
  344. $this->query["duplicate"][] = str_replace("?", $this->parent->escape($replace), $update);
  345. }
  346. return $this;
  347. }
  348. /**
  349. * alias of 'onDuplicate'
  350. * @param array|string $update
  351. * @param string $replace
  352. * @return mysqlClass_Insert
  353. */
  354. public function duplicate($update, $replace = NULL)
  355. {
  356. return $this->onDuplicate($update, $replace);
  357. }
  358. /*
  359. ** build
  360. */
  361. /**
  362. * build mysql insert query string
  363. * @param integer $formatOffset
  364. * @return string
  365. */
  366. public function build($formatOffset = 0)
  367. {
  368. $this->formatOffset += $formatOffset;
  369. $offset = str_pad("", $this->formatOffset, " ");
  370. // end if no table is set
  371. if( is_null($this->query["table"]) ) return NULL;
  372. $query = $this->format ? $offset . "INSERT " : "INSERT ";
  373. // low priority
  374. if( $this->query["low"] ) $query .= $this->format ? "\n" . $offset . " LOW_PRIORITY " : "LOW_PRIORITY ";
  375. // delayed
  376. if( $this->query["delayed"] ) $query .= $this->format ? "\n" . $offset . " DELAYED " : "DELAYED ";
  377. // high priority
  378. if( $this->query["high"] ) $query .= $this->format ? "\n" . $offset . " HIGH_PRIORITY " : "HIGH_PRIORITY ";
  379. // ignore
  380. if( $this->query["ignore"] ) $query .= $this->format ? "\n" . $offset . " IGNORE \n" : "IGNORE ";
  381. $query .= $this->format ? $offset . "INTO " : "INTO ";
  382. // table
  383. $query .= $this->format ? "\n" . $offset . " " . $this->query["table"] . "\n" : $this->query["table"] . " ";
  384. // columns
  385. if( !empty($this->query["columns"]) )
  386. {
  387. if( $this->format )
  388. {
  389. $query .= $offset . " (";
  390. for( $i = 0; $i < count($this->query["columns"]); $i++ )
  391. {
  392. $query .= " " . $this->query["columns"][$i];
  393. $query .= $i < count($this->query["columns"]) - 1 ? "," : NULL;
  394. }
  395. $query .= " ) \n";
  396. }
  397. else
  398. $query .= "(" . join(",", $this->query["columns"]) . ") ";
  399. if( !empty($this->query["values"]) )
  400. {
  401. $query .= $this->format ? "VALUES\n" : "VALUES ";
  402. for( $i = 0; $i < count($this->query["values"]); $i++ )
  403. {
  404. if( $this->format )
  405. {
  406. $query .= $offset . " " . "( " . join(", ", $this->query["values"][$i]) . " )";
  407. $query .= $i < count($this->query["values"]) - 1 ? ",\n" : NULL;
  408. }
  409. else
  410. {
  411. $query .= "(" . join(",", $this->query["values"][$i]) . ")";
  412. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  413. }
  414. }
  415. $query .= $this->format ? "\n" : " ";
  416. }
  417. }
  418. // set
  419. else if( !empty($this->query["set"]) )
  420. {
  421. $query .= $this->format ? "SET\n" : "SET ";
  422. for( $i = 0; $i < count($this->query["set"]); $i++ )
  423. {
  424. if( $this->format )
  425. {
  426. $query .= $offset . " " . $this->query["set"][$i] . "";
  427. $query .= $i < count($this->query["set"]) - 1 ? ", \n" : NULL;
  428. }
  429. else
  430. {
  431. $query .= "(" . join(",", $this->query["set"]) . ")";
  432. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  433. }
  434. }
  435. $query .= $this->format ? "\n" : " ";
  436. }
  437. // select
  438. if( !is_null($this->query["select"]) )
  439. {
  440. if( is_string($this->query["select"]) )
  441. {
  442. if( $this->format )
  443. $query .= $offset . " ( " . $this->query["select"] . " ) \n";
  444. else
  445. $query .= "(" . $this->query["select"] . ") ";
  446. }
  447. else
  448. {
  449. $select = $this->query["select"];
  450. if( $select instanceof mysqlClass_Select )
  451. {
  452. if( $this->format )
  453. $query .= $offset . " (" . trim($select->build($this->formatOffset + 4)) . ") \n";
  454. else
  455. $query .= "(" . $select->build() . ") ";
  456. }
  457. }
  458. }
  459. // on duplicate
  460. if( !empty($this->query["duplicate"]) )
  461. {
  462. if( $this->format )
  463. {
  464. $query .= "ON DUPLICATE KEY UPDATE \n";
  465. for( $i = 0; $i < count($this->query["duplicate"]); $i++ )
  466. {
  467. $query .= $offset . " " . $this->query["duplicate"][$i];
  468. $query .= $i < count($this->query["duplicate"]) - 1 ? "," : NULL;
  469. $query .= " \n";
  470. }
  471. }
  472. else
  473. {
  474. $query .= "ON DUPLICATE KEY UPDATE " . join(",", $this->query["duplicate"]) . " ";
  475. }
  476. }
  477. return $query;
  478. }
  479. }