PageRenderTime 72ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/packed/mysql.class.packed.php

https://github.com/magedeveloper/frosted-mysql-library
PHP | 6153 lines | 4475 code | 594 blank | 1084 comment | 369 complexity | 80c600450db1feff26207d6296b0a14c MD5 | raw file
  1. <?php
  2. /**
  3. * Frosted MySQL Library Class
  4. * - - - - - - - - - -
  5. * Supplies different functions for fast and easy mysql communication. Build your
  6. * queries inside this class or fire direct queries and scalars. Works completely
  7. * without zend framework but delivers similar functionality. Build with php5 and
  8. * oop techniques to get best possible usability.
  9. * - - - - - - - - - -
  10. * If you include "mysqlClass_Config" class in your scripts, before the
  11. * communication class, you don't have to set up the class every time you use it.
  12. * Take a look at the example configuration file to get an overview.
  13. * - - - - - - - - - -
  14. * Licensed under MIT license
  15. * - - - - - - - - - -
  16. * @Creator Daniel 'Eisbehr' Kern
  17. * @Require PHP5
  18. * @Version 3.0
  19. * @Date 01.08.2013
  20. * @Update 01.08.2013
  21. * - - - - - - - - - -
  22. */
  23. class mysqlClass
  24. {
  25. /**
  26. * mysql hostname
  27. * @var string
  28. */
  29. private $hostname = "localhost";
  30. /**
  31. * mysql port number
  32. * @var string
  33. */
  34. private $port = "3306";
  35. /**
  36. * mysql username
  37. * @var string
  38. */
  39. private $username = "root";
  40. /**
  41. * password to access the database
  42. * @var string
  43. */
  44. private $password = "";
  45. /**
  46. * actually used database
  47. * @var string
  48. */
  49. private $database = "";
  50. /**
  51. * prefix for {PRE} or {PREFIX} replacement
  52. * @var string
  53. */
  54. private $prefix = "";
  55. /**
  56. * use a persistent mysql connection
  57. * @var boolean
  58. */
  59. private $persistent = true;
  60. /**
  61. * use mysqli instead of default mysql
  62. * @var boolean
  63. */
  64. private $mysqli = false;
  65. /**
  66. * selected connection type
  67. * @var string
  68. */
  69. private $type = self::CONNECTION_TYPE_WRITE;
  70. /*
  71. ** internal data fields
  72. */
  73. /**
  74. * actually database connection identifier
  75. * @var resource|mysqli
  76. */
  77. private $identifier;
  78. /**
  79. * last query result
  80. * @var mixed
  81. */
  82. private $result;
  83. /**
  84. * connection types for database handling
  85. * @var string array
  86. */
  87. private $types = array();
  88. /**
  89. * replace data inside of mysql queries
  90. * @var string array
  91. */
  92. private $replaces;
  93. /**
  94. * verbose on error
  95. * @var boolean
  96. */
  97. private $verbose = false;
  98. /**
  99. * verbose on error
  100. * @var boolean
  101. */
  102. private $format = false;
  103. /*
  104. ** query classes
  105. */
  106. /**
  107. * select query
  108. * @var mysqlClass_Select
  109. */
  110. private $querySelect = NULL;
  111. /**
  112. * insert query
  113. * @var mysqlClass_Insert
  114. */
  115. private $queryInsert = NULL;
  116. /**
  117. * replace query
  118. * @var mysqlClass_Replace
  119. */
  120. private $queryReplace = NULL;
  121. /**
  122. * update query
  123. * @var mysqlClass_Update
  124. */
  125. private $queryUpdate = NULL;
  126. /**
  127. * delete query
  128. * @var mysqlClass_Delete
  129. */
  130. private $queryDelete = NULL;
  131. /**
  132. * truncate query
  133. * @var mysqlClass_Truncate
  134. */
  135. private $queryTruncate = NULL;
  136. /*
  137. ** static & constants
  138. */
  139. /**
  140. * singleton instance holder
  141. * @var mysqlClass
  142. */
  143. private static $instance = NULL;
  144. /**
  145. * connection types
  146. * @var string
  147. */
  148. const CONNECTION_TYPE_READ = "r";
  149. const CONNECTION_TYPE_WRITE = "w";
  150. /**
  151. * result fetching types
  152. * @var string
  153. */
  154. const FETCH_ARRAY = "array";
  155. const FETCH_ASSOC = "assoc";
  156. const FETCH_ROW = "row";
  157. const FETCH_OBJ = "obj";
  158. const FETCH_OBJECT = "object";
  159. const FETCH_COLLECTION = "collection";
  160. /**
  161. * join condition relations
  162. * @var string
  163. */
  164. const JOIN_OR = "OR";
  165. const JOIN_AND = "AND";
  166. /**
  167. * where condition relations
  168. * @var string
  169. */
  170. const WHERE_OR = "OR";
  171. const WHERE_AND = "AND";
  172. /**
  173. * having condition relations
  174. * @var string
  175. */
  176. const HAVING_OR = "OR";
  177. const HAVING_AND = "AND";
  178. /**
  179. * group directions
  180. * @var string
  181. */
  182. const GROUP_ASC = "ASC";
  183. const GROUP_DESC = "DESC";
  184. /**
  185. * order directions
  186. * @var string
  187. */
  188. const ORDER_ASC = "ASC";
  189. const ORDER_DESC = "DESC";
  190. /**
  191. * exception messages
  192. * @var string
  193. */
  194. const MESSAGE_CONNECTION = "connection could not be established";
  195. const MESSAGE_DATABASE = "could not handle or get into the chosen database '%s'";
  196. const MESSAGE_QUERY = "could not process the given query";
  197. const MESSAGE_CREATE = "could not create the mysql query";
  198. const MESSAGE_PERMISSION = "the mysqlClass instance doesn't have the permission for this query, change the connection type to 'write' first";
  199. const MESSAGE_UNKNOWN = "function '%s(%s)' not found in class '%s'";
  200. /*
  201. ** constuct & destruct
  202. */
  203. /**
  204. * create mysql class instance
  205. * @param boolean $verbose
  206. * @param string $type
  207. * @return mysqlClass
  208. */
  209. function __construct($verbose = false, $type = self::CONNECTION_TYPE_WRITE)
  210. {
  211. // reset class configuration
  212. $this->resetConfig();
  213. // create connection types
  214. $this->types["r"] = self::CONNECTION_TYPE_READ;
  215. $this->types["read"] = self::CONNECTION_TYPE_READ;
  216. $this->types["w"] = self::CONNECTION_TYPE_WRITE;
  217. $this->types["write"] = self::CONNECTION_TYPE_WRITE;
  218. // check if chosen type exists
  219. if( array_key_exists($type, $this->types) )
  220. $this->type = $this->types[$type];
  221. else
  222. $this->type = self::CONNECTION_TYPE_WRITE;
  223. // get verbose option
  224. if( is_bool($verbose) ) $this->verbose = $verbose;
  225. // try to find config class
  226. if( class_exists("mysqlClass_Config") )
  227. {
  228. $class = new ReflectionClass("mysqlClass_Config");
  229. // get possible configuration from config class
  230. if( $class->hasConstant("hostname") ) $this->hostname = mysqlClass_Config::hostname;
  231. if( $class->hasConstant("port") ) $this->port = mysqlClass_Config::port;
  232. if( $class->hasConstant("username") ) $this->username = mysqlClass_Config::username;
  233. if( $class->hasConstant("password") ) $this->password = mysqlClass_Config::password;
  234. if( $class->hasConstant("database") ) $this->database = mysqlClass_Config::database;
  235. if( $class->hasConstant("prefix") ) $this->prefix = mysqlClass_Config::prefix;
  236. if( $class->hasConstant("persistent") ) $this->persistent = mysqlClass_Config::persistent;
  237. if( $class->hasConstant("mysqli") ) $this->mysqli = mysqlClass_Config::mysqli;
  238. if( $class->hasConstant("verbose") ) $this->verbose = mysqlClass_Config::verbose;
  239. if( $class->hasConstant("format") ) $this->format = mysqlClass_Config::format;
  240. }
  241. // create default data replacement
  242. $this->updateReplacement();
  243. // set singleton class instance
  244. self::$instance = $this;
  245. return $this;
  246. }
  247. /**
  248. * destruct mysql class instance
  249. * @return boolean
  250. */
  251. function __destruct()
  252. {
  253. $this->close();
  254. self::$instance = NULL;
  255. unset($this->identifier);
  256. unset($this->result);
  257. unset($this);
  258. return true;
  259. }
  260. /**
  261. * return class singleton or create new instance
  262. * @param boolean $forceNew
  263. * @return mysqlClass
  264. */
  265. public static function getInstance($forceNew = false)
  266. {
  267. if( $forceNew ) return new self();
  268. if( !self::$instance ) self::$instance = new self();
  269. return self::$instance;
  270. }
  271. /*
  272. ** getter & setter for internal data
  273. */
  274. /**
  275. * handle all get calls
  276. * @param string $name
  277. * @return mixed
  278. */
  279. public function getData($name)
  280. {
  281. switch( $name )
  282. {
  283. case "hostname":
  284. case "port":
  285. case "username":
  286. case "password":
  287. case "database":
  288. case "prefix":
  289. case "type":
  290. case "connectiontype":
  291. return (string)$this->{$name};
  292. break;
  293. case "connection":
  294. case "identifier":
  295. return $this->identifier;
  296. break;
  297. case "verbose":
  298. case "format":
  299. case "persistent":
  300. case "mysqli":
  301. return (bool)$this->{$name};
  302. break;
  303. }
  304. $this->unknownFunction($this, $name);
  305. return NULL;
  306. }
  307. /**
  308. * mysql hostname
  309. * @return string
  310. */
  311. public function getHostname()
  312. {
  313. return $this->getData("hostname");
  314. }
  315. /**
  316. * set mysql port number
  317. * @return string|integer
  318. */
  319. public function getPort()
  320. {
  321. return $this->getData("port");
  322. }
  323. /**
  324. * database username
  325. * @return string
  326. */
  327. public function getUsername()
  328. {
  329. return $this->getData("username");
  330. }
  331. /**
  332. * database password
  333. * @return string
  334. */
  335. public function getPassword()
  336. {
  337. return $this->getData("password");
  338. }
  339. /**
  340. * mysql database
  341. * @return string
  342. */
  343. public function getDatabase()
  344. {
  345. return $this->getData("database");
  346. }
  347. /**
  348. * database table prefix
  349. * @return string
  350. */
  351. public function getPrefix()
  352. {
  353. return $this->getData("prefix");
  354. }
  355. /**
  356. * persistent connection enabled
  357. * @return boolean
  358. */
  359. public function getPersistent()
  360. {
  361. return $this->getData("persistent");
  362. }
  363. /**
  364. * mysqli enabled
  365. * @return boolean
  366. */
  367. public function getMysqli()
  368. {
  369. return $this->getData("mysqli");
  370. }
  371. /**
  372. * verbose on error enabled
  373. * @return boolean
  374. */
  375. public function getVerbose()
  376. {
  377. return $this->getData("verbose");
  378. }
  379. /**
  380. * query string formation enabled
  381. * @return boolean
  382. */
  383. public function getFormat()
  384. {
  385. return $this->getData("format");
  386. }
  387. /**
  388. * set mysql connection type
  389. * @return boolean
  390. */
  391. public function getType()
  392. {
  393. return $this->getData("type");
  394. }
  395. /**
  396. * handle all set calls
  397. * @param string $name
  398. * @param mixed $value
  399. * @return boolean
  400. */
  401. public function setData($name, $value)
  402. {
  403. switch( $name )
  404. {
  405. case "hostname":
  406. case "username":
  407. case "password":
  408. if( is_string($value) )
  409. {
  410. $this->{$name} = $value;
  411. return true;
  412. }
  413. return false;
  414. break;
  415. case "database":
  416. case "prefix":
  417. if( is_string($value) )
  418. {
  419. $this->{$name} = $value;
  420. $this->updateReplacement();
  421. return true;
  422. }
  423. return false;
  424. break;
  425. case "port":
  426. if( is_string($value) || is_integer($value) )
  427. {
  428. $this->{$name} = $value;
  429. return true;
  430. }
  431. return false;
  432. break;
  433. case "verbose":
  434. case "format":
  435. case "persistent":
  436. case "mysqli":
  437. if( is_bool($value) )
  438. {
  439. $this->{$name} = $value;
  440. return true;
  441. }
  442. return false;
  443. break;
  444. case "type":
  445. case "connectiontype":
  446. if( array_key_exists($value, $this->types) )
  447. {
  448. $this->type = $this->types[$value];
  449. return true;
  450. }
  451. return false;
  452. break;
  453. }
  454. $this->unknownFunction($this, $name, array($value));
  455. return false;
  456. }
  457. /**
  458. * set mysql hostname
  459. * @param string $hostname
  460. * @return boolean
  461. */
  462. public function setHostname($hostname)
  463. {
  464. return $this->setData("hostname", $hostname);
  465. }
  466. /**
  467. * set mysql port number
  468. * @param string|integer $port
  469. * @return boolean
  470. */
  471. public function setPort($port)
  472. {
  473. return $this->setData("port", $port);
  474. }
  475. /**
  476. * set database username
  477. * @param string $username
  478. * @return boolean
  479. */
  480. public function setUsername($username)
  481. {
  482. return $this->setData("username", $username);
  483. }
  484. /**
  485. * set database password
  486. * @param string $password
  487. * @return boolean
  488. */
  489. public function setPassword($password)
  490. {
  491. return $this->setData("password", $password);
  492. }
  493. /**
  494. * set mysql database
  495. * @param string $database
  496. * @return boolean
  497. */
  498. public function setDatabase($database)
  499. {
  500. return $this->setData("database", $database);
  501. }
  502. /**
  503. * set database table prefix
  504. * @param string $prefix
  505. * @return boolean
  506. */
  507. public function setPrefix($prefix)
  508. {
  509. return $this->setData("prefix", $prefix);
  510. }
  511. /**
  512. * enable persistent connection
  513. * @param boolean $persistent
  514. * @return boolean
  515. */
  516. public function setPersistent($persistent)
  517. {
  518. return $this->setData("persistent", $persistent);
  519. }
  520. /**
  521. * enable mysqli
  522. * @param boolean $mysqli
  523. * @return boolean
  524. */
  525. public function setMysqli($mysqli)
  526. {
  527. return $this->setData("mysqli", $mysqli);
  528. }
  529. /**
  530. * enable verbose on error
  531. * @param boolean $verbose
  532. * @return boolean
  533. */
  534. public function setVerbose($verbose)
  535. {
  536. return $this->setData("verbose", $verbose);
  537. }
  538. /**
  539. * enable query string formation
  540. * @param boolean $format
  541. * @return boolean
  542. */
  543. public function setFormat($format)
  544. {
  545. return $this->setData("format", $format);
  546. }
  547. /**
  548. * set mysql connection type
  549. * @param string $type
  550. * @return boolean
  551. */
  552. public function setType($type)
  553. {
  554. return $this->setData("type", $type);
  555. }
  556. /**
  557. * set mysql connection type
  558. * @param string $connectiontype
  559. * @return boolean
  560. */
  561. public function setConnectionType($connectiontype)
  562. {
  563. return $this->setData("connectiontype", $connectiontype);
  564. }
  565. /**
  566. * get class configuration as array
  567. * @return array
  568. */
  569. public function getConfigArray()
  570. {
  571. $config = array();
  572. $config["hostname"] = $this->hostname;
  573. $config["port"] = $this->port;
  574. $config["username"] = $this->username;
  575. $config["password"] = $this->password;
  576. $config["database"] = $this->database;
  577. $config["prefix"] = $this->prefix;
  578. $config["persistent"] = $this->persistent;
  579. $config["mysqli"] = $this->mysqli;
  580. $config["verbose"] = $this->verbose;
  581. $config["format"] = $this->format;
  582. return $config;
  583. }
  584. /**
  585. * set class configuration as array
  586. * @param array $config
  587. * @return mysqlClass
  588. */
  589. public function setConfigArray($config)
  590. {
  591. if( isset($config["hostname"]) ) $this->hostname = $config["hostname"];
  592. if( isset($config["port"]) ) $this->port = $config["port"];
  593. if( isset($config["username"]) ) $this->username = $config["username"];
  594. if( isset($config["password"]) ) $this->password = $config["password"];
  595. if( isset($config["database"]) ) $this->database = $config["database"];
  596. if( isset($config["prefix"]) ) $this->prefix = $config["prefix"];
  597. if( isset($config["persistent"]) ) $this->persistent = $config["persistent"];
  598. if( isset($config["mysqli"]) ) $this->mysqli = $config["mysqli"];
  599. if( isset($config["verbose"]) ) $this->verbose = $config["verbose"];
  600. if( isset($config["format"]) ) $this->format = $config["format"];
  601. return $this;
  602. }
  603. /**
  604. * reset whole class configuration
  605. * @return void
  606. */
  607. public function resetConfig()
  608. {
  609. $this->close();
  610. $this->hostname = "localhost";
  611. $this->port = "3306";
  612. $this->username = "root";
  613. $this->password = "";
  614. $this->database = "";
  615. $this->prefix = "";
  616. $this->persistent = true;
  617. $this->mysqli = false;
  618. $this->verbose = false;
  619. $this->format = false;
  620. $this->updateReplacement();
  621. return;
  622. }
  623. /**
  624. * internal getter for mysql hostname by current configuration
  625. * @return string
  626. */
  627. private function getConnectionHostname()
  628. {
  629. if( $this->mysqli )
  630. {
  631. $hostname = ( $this->persistent ? "p:" : NULL) . $this->hostname;
  632. $hostname .= !empty($this->port) && (string)$this->port != "3306" ? ":" . $this->port : NULL;
  633. return $hostname;
  634. }
  635. $hostname = $this->hostname;
  636. $hostname .= !empty($this->port) && (string)$this->port != "3306" ? ":" . $this->port : NULL;
  637. return $hostname;
  638. }
  639. /*
  640. ** replacement functions
  641. */
  642. /**
  643. * replace all data inside mysql query
  644. * @param string $query
  645. * @return string
  646. */
  647. public function replaceQuery($query)
  648. {
  649. if( !is_array($this->replaces) ) $this->replaces = array();
  650. foreach( $this->replaces as $replace => $value )
  651. {
  652. $query = str_replace($replace, $value, $query);
  653. }
  654. return $query;
  655. }
  656. /**
  657. * reset replacements to default
  658. * @return void
  659. */
  660. private function updateReplacement()
  661. {
  662. if( !is_array($this->replaces) ) $this->replaces = array();
  663. $this->replaces["{DB}"] = $this->database;
  664. $this->replaces["{DATABASE}"] = $this->database;
  665. $this->replaces["{PRE}"] = $this->prefix;
  666. $this->replaces["{PREFIX}"] = $this->prefix;
  667. return;
  668. }
  669. /**
  670. * add a new replacement entry
  671. * @param string $replace
  672. * @param string $value
  673. * @return boolean
  674. */
  675. public function addReplacement($replace, $value)
  676. {
  677. if( !is_array($this->replaces) ) $this->updateReplacement();
  678. if( !empty($replace) && $replace != $value )
  679. {
  680. $this->replaces[$replace] = $value;
  681. return true;
  682. }
  683. return false;
  684. }
  685. /**
  686. * remove a single replacement
  687. * @param string $replace
  688. * @return void
  689. */
  690. public function removeReplacement($replace)
  691. {
  692. if( !is_array($this->replaces) ) $this->updateReplacement();
  693. if( isset($this->replaces[$replace]) )
  694. {
  695. unset($this->replaces[$replace]);
  696. }
  697. return;
  698. }
  699. /*
  700. ** connection related functions
  701. */
  702. /**
  703. * open connection to database
  704. * @return boolean
  705. */
  706. public function connect()
  707. {
  708. // close possible open connection
  709. $this->close();
  710. // use mysqli
  711. if( $this->mysqli )
  712. {
  713. if( $this->persistent )
  714. $this->identifier = mysqli_connect($this->getConnectionHostname(), $this->username, $this->password);
  715. else
  716. $this->identifier = mysqli_connect($this->getConnectionHostname(), $this->username, $this->password);
  717. // on connection error
  718. if( mysqli_connect_error() ) $this->connectionError();
  719. // select database
  720. if( @mysqli_select_db($this->identifier, $this->database) )
  721. return true;
  722. else
  723. $this->databaseError();
  724. }
  725. // use default mysql
  726. else
  727. {
  728. if( $this->persistent )
  729. $this->identifier = @mysql_connect($this->getConnectionHostname(), $this->username, $this->password, true);
  730. else
  731. $this->identifier = @mysql_pconnect($this->getConnectionHostname(), $this->username, $this->password);
  732. if( !$this->identifier && mysql_error() ) $this->connectionError();
  733. // if connection was successfully select database
  734. if( $this->identifier )
  735. {
  736. if( @mysql_select_db($this->database, $this->identifier) )
  737. return true;
  738. else
  739. $this->databaseError();
  740. }
  741. }
  742. return false;
  743. }
  744. /**
  745. * alias of connect()
  746. * @return boolean
  747. */
  748. public function reconnect()
  749. {
  750. return $this->connect();
  751. }
  752. /**
  753. * check if connection is established
  754. * @return boolean
  755. */
  756. public function isConnected()
  757. {
  758. if( $this->identifier )
  759. {
  760. if( $this->mysqli )
  761. {
  762. if( $this->identifier instanceof mysqli && mysqli_ping($this->identifier) )
  763. {
  764. return true;
  765. }
  766. }
  767. else
  768. {
  769. if( is_resource($this->identifier) && mysql_ping($this->identifier) )
  770. {
  771. return true;
  772. }
  773. }
  774. }
  775. return false;
  776. }
  777. /**
  778. * alias of isConnected()
  779. * @return boolean
  780. */
  781. public function ping()
  782. {
  783. return $this->isConnected();
  784. }
  785. /**
  786. * close mysql connection
  787. * @return boolean
  788. */
  789. public function close()
  790. {
  791. if( isset($this->identifyer) )
  792. {
  793. if( $this->mysqli )
  794. {
  795. if( $this->identifier instanceof mysqli )
  796. {
  797. @mysqli_close($this->identifier);
  798. return true;
  799. }
  800. }
  801. else
  802. {
  803. if( is_resource($this->identifier) )
  804. {
  805. @mysql_close($this->identifyer);
  806. return true;
  807. }
  808. }
  809. }
  810. return false;
  811. }
  812. /*
  813. ** query functions
  814. */
  815. /**
  816. * check if class has the permission for the query
  817. * @param string $query
  818. * @return boolean
  819. */
  820. private function hasQueryPermission($query)
  821. {
  822. if( $this->type == self::CONNECTION_TYPE_WRITE )
  823. return true;
  824. if( preg_match("/(INSERT|UPDATE|DELETE) (.*)/i", $query) ||
  825. preg_match("/(?:CREATE|DROP|ALTER|CACHE) (.*)(?:FUNCTION|TABLE|VIEW|EVENT|TRIGGER|INDEX|SERVER|USER|DATABASE|TABLESPACE|PROCEDURE) /i", $query) )
  826. return false;
  827. return true;
  828. }
  829. /**
  830. * run query string against database
  831. * @param string $query
  832. * @param boolean $fetch
  833. * @param string $fetchType
  834. * @return mixed
  835. */
  836. public function query($query, $fetch = false, $fetchType = self::FETCH_ASSOC)
  837. {
  838. // if query is not an empty string
  839. if( !empty($query) )
  840. {
  841. // replace data inside query
  842. $queryString = $this->replaceQuery($query);
  843. // check if query is allowed by given connection type
  844. if( $this->hasQueryPermission($queryString) )
  845. {
  846. // run mysqli query
  847. if( $this->mysqli )
  848. $this->result = @mysqli_query($this->identifier, $queryString);
  849. // run default query
  850. else
  851. $this->result = @mysql_query($queryString, $this->identifier);
  852. // return error on failed query
  853. if( !$this->result )
  854. $this->queryError();
  855. // fetch or return result
  856. else
  857. {
  858. // return fetched result
  859. if( $fetch )
  860. return $this->fetch($this->result, $fetchType);
  861. // return result
  862. return $this->result;
  863. }
  864. }
  865. else
  866. {
  867. // print permission error
  868. $this->permissionError();
  869. }
  870. }
  871. return false;
  872. }
  873. /**
  874. * alias of query()
  875. * @param string $query
  876. * @param boolean $fetch
  877. * @param string $fetchType
  878. * @return mixed
  879. */
  880. public function qry($query, $fetch = false, $fetchType = self::FETCH_ASSOC)
  881. {
  882. return $this->query($query, $fetch, $fetchType);
  883. }
  884. /**
  885. * affected rows by the last query
  886. * @return integer
  887. */
  888. public function getAffected()
  889. {
  890. if( $this->mysqli )
  891. {
  892. return mysqli_affected_rows($this->identifier);
  893. }
  894. return mysql_affected_rows($this->identifier);
  895. }
  896. /**
  897. * count the rows in the result
  898. * @return integer
  899. */
  900. public function getNumRows()
  901. {
  902. if( $this->mysqli )
  903. {
  904. return mysqli_num_rows($this->result);
  905. }
  906. return mysql_num_rows($this->result);
  907. }
  908. /**
  909. * get last insert id
  910. * @return integer
  911. */
  912. public function getLastId()
  913. {
  914. if( $this->mysqli )
  915. {
  916. return mysqli_insert_id($this->identifier);
  917. }
  918. if( ($id = @mysql_insert_id($this->identifier)) !== false )
  919. {
  920. return $id;
  921. }
  922. return 0;
  923. }
  924. /**
  925. * alias of getLastId()
  926. * @return integer | boolean
  927. */
  928. public function getLastInsertId()
  929. {
  930. return $this->getLastId();
  931. }
  932. /**
  933. * free result memory
  934. * @return boolean
  935. */
  936. public function free()
  937. {
  938. if( $this->mysqli )
  939. {
  940. mysqli_free_result($this->result);
  941. return true;
  942. }
  943. return @mysql_free_result($this->result);
  944. }
  945. /**
  946. * fetch result to useable formats
  947. * @param boolean|resource|mysqli_result $result
  948. * @param string $type
  949. * @return mixed
  950. */
  951. public function fetch($result = false, $type = "assoc")
  952. {
  953. // call again to shift parameters
  954. if( $result === false || is_string($result) )
  955. {
  956. $type = is_string($result) ? $result : $type;
  957. $fetched = $this->fetch($this->result, $type);
  958. $this->free();
  959. return $fetched;
  960. }
  961. $fetched = array();
  962. // array
  963. if( $type == self::FETCH_ARRAY )
  964. {
  965. if( $this->mysqli )
  966. while( $row = mysqli_fetch_array($result) )
  967. $fetched[] = $row;
  968. else
  969. while( $row = mysql_fetch_array($result) )
  970. $fetched[] = $row;
  971. return $fetched;
  972. }
  973. // row
  974. if( $type == self::FETCH_ROW )
  975. {
  976. if( $this->mysqli )
  977. while( $row = mysqli_fetch_row($result) )
  978. $fetched[] = $row;
  979. else
  980. while( $row = mysql_fetch_row($result) )
  981. $fetched[] = $row;
  982. return $fetched;
  983. }
  984. // object
  985. if( $type == self::FETCH_OBJ || $type == self::FETCH_OBJECT || $type == self::FETCH_COLLECTION )
  986. {
  987. $fetched = new mysqlClass_Collection();
  988. if( $this->mysqli )
  989. {
  990. while( $row = mysqli_fetch_assoc($result) )
  991. $fetched->addItem($fetched->getNewItemWithData($row));
  992. }
  993. else
  994. {
  995. while( $row = mysql_fetch_assoc($result) )
  996. $fetched->addItem($fetched->getNewItemWithData($row));
  997. }
  998. }
  999. // default / assoc
  1000. if( $this->mysqli )
  1001. while( $row = mysqli_fetch_assoc($result) )
  1002. $fetched[] = $row;
  1003. else
  1004. while( $row = mysql_fetch_assoc($result) )
  1005. $fetched[] = $row;
  1006. return $fetched;
  1007. }
  1008. /**
  1009. * fetch result to collection
  1010. * @param boolean|resource|mysqli_result $result
  1011. * @return mysqlClass_Collection
  1012. */
  1013. public function getCollection($result = false)
  1014. {
  1015. return $this->fetch($result, self::FETCH_COLLECTION);
  1016. }
  1017. /**
  1018. * escape and quote value inside mysql query
  1019. * @param string $value
  1020. * @param boolean $nullable
  1021. * @return string
  1022. */
  1023. public function escape($value, $nullable = true)
  1024. {
  1025. if( is_string($value) )
  1026. {
  1027. if( $this->mysqli )
  1028. {
  1029. if( $this->identifier instanceof mysqli )
  1030. $value = mysqli_real_escape_string($this->identifier, $value);
  1031. }
  1032. else
  1033. {
  1034. $value = mysql_real_escape_string($value);
  1035. }
  1036. }
  1037. if( is_null($value) && $nullable )
  1038. $value = "NULL";
  1039. elseif( is_numeric($value) );
  1040. // nothing to do, numeral literals need no escape
  1041. elseif( is_bool($value) )
  1042. $value = (integer)$value;
  1043. else
  1044. $value = "'" . $value . "'";
  1045. return $value;
  1046. }
  1047. /**
  1048. * alias of escape()
  1049. * @param string $value
  1050. * @param boolean $nullable
  1051. * @return string
  1052. */
  1053. public function e($value, $nullable = true)
  1054. {
  1055. return $this->escape($value, $nullable);
  1056. }
  1057. /**
  1058. * alias of escape()
  1059. * @param string $value
  1060. * @param boolean $nullable
  1061. * @return string
  1062. */
  1063. public function __($value, $nullable = true)
  1064. {
  1065. return $this->escape($value, $nullable);
  1066. }
  1067. /*
  1068. ** error verbose function
  1069. */
  1070. /**
  1071. * print connection error or throw exception on verbose
  1072. * otherwise die with an message
  1073. * @throws mysqlClass_Connection_Exception
  1074. * @return void
  1075. */
  1076. private function connectionError()
  1077. {
  1078. if( $this->verbose )
  1079. {
  1080. if( $this->mysqli )
  1081. $reason = mysqli_connect_error();
  1082. else
  1083. $reason = mysql_error($this->identifier);
  1084. throw new mysqlClass_Connection_Exception(self::MESSAGE_CONNECTION . ", reason: " . $reason);
  1085. }
  1086. $this->printError(self::MESSAGE_CONNECTION . "!");
  1087. }
  1088. /**
  1089. * print database error or throw exception on verbose
  1090. * @throws mysqlClass_Database_Exception
  1091. * @return void
  1092. */
  1093. private function databaseError()
  1094. {
  1095. $message = sprintf(self::MESSAGE_DATABASE, $this->database);
  1096. if( $this->verbose)
  1097. {
  1098. if( $this->mysqli )
  1099. $reason = mysqli_error($this->identifier);
  1100. else
  1101. $reason = mysql_error($this->identifier);
  1102. throw new mysqlClass_Database_Exception($message . ", reason: " . $reason);
  1103. }
  1104. $this->printError($message . " !");
  1105. }
  1106. /**
  1107. * print query error or throw exception on verbose
  1108. * @throws mysqlClass_Query_Exception
  1109. * @return void
  1110. */
  1111. private function queryError()
  1112. {
  1113. if( $this->verbose)
  1114. {
  1115. if( $this->mysqli )
  1116. $reason = mysqli_error($this->identifier);
  1117. else
  1118. $reason = mysql_error($this->identifier);
  1119. throw new mysqlClass_Query_Exception(self::MESSAGE_QUERY . ", reason: " . $reason);
  1120. }
  1121. $this->printError(self::MESSAGE_QUERY . "!");
  1122. }
  1123. /**
  1124. * print create error or throw exception on verbose
  1125. * @param string $reason
  1126. * @throws mysqlClass_Create_Exception
  1127. */
  1128. public function createError($reason = NULL)
  1129. {
  1130. if( $this->verbose)
  1131. {
  1132. if( !is_null($reason) )
  1133. throw new mysqlClass_Create_Exception(self::MESSAGE_CREATE . ", reason: " . strtolower($reason));
  1134. throw new mysqlClass_Create_Exception(self::MESSAGE_CREATE);
  1135. }
  1136. if( !is_null($reason) )
  1137. {
  1138. $this->printError(self::MESSAGE_CREATE . ", reason: " . strtolower($reason));
  1139. return;
  1140. }
  1141. $this->printError(self::MESSAGE_CREATE . "!");
  1142. }
  1143. /**
  1144. * print permission error or throw exception on verbose
  1145. * dies or throws an mysqlClass_Permission_Exception
  1146. * @throws mysqlClass_Permission_Exception
  1147. */
  1148. private function permissionError()
  1149. {
  1150. if( $this->verbose )
  1151. throw new mysqlClass_Permission_Exception(self::MESSAGE_PERMISSION);
  1152. $this->printError(self::MESSAGE_PERMISSION . "!");
  1153. }
  1154. /**
  1155. * print unknown function error or throw exception on verbose
  1156. * @param object $class
  1157. * @param string $name
  1158. * @param array $parameter
  1159. * @throws mysqlClass_Unknown_Function_Exception
  1160. */
  1161. public function unknownFunction($class, $name, $parameter = array())
  1162. {
  1163. $params = "";
  1164. for( $i = 1; $i <= count($parameter); $i++ )
  1165. {
  1166. $params .= "param" . $i;
  1167. if( $i != count($parameter) )
  1168. {
  1169. $params .= ", ";
  1170. }
  1171. }
  1172. $message = sprintf(self::MESSAGE_UNKNOWN, $name, $params, get_class($class));
  1173. if( $this->verbose)
  1174. throw new mysqlClass_Unknown_Function_Exception($message);
  1175. $this->printError($message . " !");
  1176. }
  1177. /**
  1178. * print a non-verbose message
  1179. * @param string $message
  1180. */
  1181. private function printError($message)
  1182. {
  1183. if( !$this->verbose )
  1184. {
  1185. trigger_error($message, E_USER_ERROR);
  1186. }
  1187. }
  1188. /*
  1189. ** query initializer
  1190. */
  1191. /**
  1192. * get select query instance
  1193. * @param string|array $columns
  1194. * @param boolean $newInstance
  1195. * @return mysqlClass_Select
  1196. */
  1197. public function select($columns = "*", $newInstance = false)
  1198. {
  1199. // prevent php debug notification
  1200. if( $columns && $newInstance );
  1201. $args = array();
  1202. // check if new instance have to be created
  1203. if( func_num_args() > 0 )
  1204. {
  1205. $args = func_get_args();
  1206. $last = array_splice($args, -1);
  1207. if( is_bool($last[0]) )
  1208. {
  1209. if( $last[0] )
  1210. {
  1211. $instance = new mysqlClass_Select($this);
  1212. if( !empty($args) )
  1213. call_user_func_array(array($instance, "columns"), $args);
  1214. return $instance;
  1215. }
  1216. }
  1217. else
  1218. {
  1219. array_push($args, $last);
  1220. }
  1221. }
  1222. // create instance or reset
  1223. if( !$this->querySelect )
  1224. $this->querySelect = new mysqlClass_Select($this);
  1225. else
  1226. $this->querySelect->resetQuery($this->format);
  1227. // pass parameter
  1228. if( count($args) > 0 )
  1229. call_user_func_array(array($this->querySelect, "columns"), $args);
  1230. return $this->querySelect;
  1231. }
  1232. /**
  1233. * get insert query instance
  1234. * @param string $table
  1235. * @param boolean $newInstance
  1236. * @return mysqlClass_Insert
  1237. */
  1238. public function insert($table = NULL, $newInstance = false)
  1239. {
  1240. // prevent php debug notification
  1241. if( $table && $newInstance );
  1242. $args = array();
  1243. // check parameters for new instance
  1244. if( func_num_args() > 0 )
  1245. {
  1246. // extract last parameter
  1247. $args = func_get_args();
  1248. $last = array_splice($args, -1);
  1249. // if last parameter is a boolean
  1250. if( is_bool($last[0]) )
  1251. {
  1252. // if new instance has to be created
  1253. if( $last[0] )
  1254. {
  1255. $instance = new mysqlClass_Insert($this);
  1256. if( !empty($args) )
  1257. call_user_func_array(array($instance, "table"), $args);
  1258. return $instance;
  1259. }
  1260. }
  1261. // otherwise push parameter back in list
  1262. else
  1263. {
  1264. array_push($args, $last);
  1265. }
  1266. }
  1267. // create instance or reset
  1268. if( !$this->queryInsert)
  1269. $this->queryInsert = new mysqlClass_Insert($this);
  1270. else
  1271. $this->queryInsert->resetQuery($this->format);
  1272. // pass parameter
  1273. if( count($args) > 0 )
  1274. call_user_func_array(array($this->queryInsert, "table"), $args);
  1275. return $this->queryInsert;
  1276. }
  1277. /**
  1278. * get insert query instance
  1279. * @param string $table
  1280. * @param boolean $newInstance
  1281. * @return mysqlClass_Insert
  1282. */
  1283. public function insertInto($table = NULL, $newInstance = false)
  1284. {
  1285. // prevent php debug notification
  1286. if( $table && $newInstance );
  1287. return call_user_func_array(array($this, "insert"), func_get_args());
  1288. }
  1289. /**
  1290. * get replace query instance
  1291. * @param string $table
  1292. * @param boolean $newInstance
  1293. * @return mysqlClass_Replace
  1294. */
  1295. public function replace($table = NULL, $newInstance = false)
  1296. {
  1297. // prevent php debug notification
  1298. if( $table && $newInstance );
  1299. $args = array();
  1300. // check parameters for new instance
  1301. if( func_num_args() > 0 )
  1302. {
  1303. // extract last parameter
  1304. $args = func_get_args();
  1305. $last = array_splice($args, -1);
  1306. // if last parameter is a boolean
  1307. if( is_bool($last[0]) )
  1308. {
  1309. // if new instance has to be created
  1310. if( $last[0] )
  1311. {
  1312. $instance = new mysqlClass_Replace($this);
  1313. if( !empty($args) )
  1314. call_user_func_array(array($instance, "table"), $args);
  1315. return $instance;
  1316. }
  1317. }
  1318. // otherwise push parameter back in list
  1319. else
  1320. {
  1321. array_push($args, $last);
  1322. }
  1323. }
  1324. // create instance or reset
  1325. if( !$this->queryReplace)
  1326. $this->queryReplace = new mysqlClass_Replace($this);
  1327. else
  1328. $this->queryReplace->resetQuery($this->format);
  1329. // pass parameter
  1330. if( count($args) > 0 )
  1331. call_user_func_array(array($this->queryReplace, "table"), $args);
  1332. return $this->queryReplace;
  1333. }
  1334. /**
  1335. * get replace query instance
  1336. * @param string $table
  1337. * @param boolean $newInstance
  1338. * @return mysqlClass_Replace
  1339. */
  1340. public function replaceInto($table = NULL, $newInstance = false)
  1341. {
  1342. // prevent php debug notification
  1343. if( $table && $newInstance );
  1344. return call_user_func_array(array($this, "replace"), func_get_args());
  1345. }
  1346. /**
  1347. * get update query instance
  1348. * @param string|array $table
  1349. * @param boolean $newInstance
  1350. * @return mysqlClass_Update
  1351. */
  1352. public function update($table = NULL, $newInstance = false)
  1353. {
  1354. // prevent php debug notification
  1355. if( $table && $newInstance );
  1356. $args = array();
  1357. // check parameters for new instance
  1358. if( func_num_args() > 0 )
  1359. {
  1360. // extract last parameter
  1361. $args = func_get_args();
  1362. $last = array_splice($args, -1);
  1363. // if last parameter is a boolean
  1364. if( is_bool($last[0]) )
  1365. {
  1366. // if new instance has to be created
  1367. if( $last[0] )
  1368. {
  1369. $instance = new mysqlClass_Update($this);
  1370. if( !empty($args) )
  1371. call_user_func_array(array($instance, "table"), $args);
  1372. return $instance;
  1373. }
  1374. }
  1375. // otherwise push parameter back in list
  1376. else
  1377. {
  1378. array_push($args, $last);
  1379. }
  1380. }
  1381. // create instance or reset
  1382. if( !$this->queryUpdate)
  1383. $this->queryUpdate = new mysqlClass_Update($this);
  1384. else
  1385. $this->queryUpdate->resetQuery($this->format);
  1386. // pass parameter
  1387. if( count($args) > 0 )
  1388. call_user_func_array(array($this->queryUpdate, "table"), $args);
  1389. return $this->queryUpdate;
  1390. }
  1391. /**
  1392. * get update query instance
  1393. * @param string|array $table
  1394. * @param boolean $newInstance
  1395. * @return mysqlClass_Delete
  1396. */
  1397. public function delete($table = NULL, $newInstance = false)
  1398. {
  1399. // prevent php debug notification
  1400. if( $table && $newInstance );
  1401. $args = array();
  1402. // check parameters for new instance
  1403. if( func_num_args() > 0 )
  1404. {
  1405. // extract last parameter
  1406. $args = func_get_args();
  1407. $last = array_splice($args, -1);
  1408. // if last parameter is a boolean
  1409. if( is_bool($last[0]) )
  1410. {
  1411. // if new instance has to be created
  1412. if( $last[0] )
  1413. {
  1414. $instance = new mysqlClass_Delete($this);
  1415. if( !empty($args) )
  1416. call_user_func_array(array($instance, "table"), $args);
  1417. return $instance;
  1418. }
  1419. }
  1420. // otherwise push parameter back in list
  1421. else
  1422. {
  1423. array_push($args, $last);
  1424. }
  1425. }
  1426. // create instance or reset
  1427. if( !$this->queryDelete)
  1428. $this->queryDelete = new mysqlClass_Delete($this);
  1429. else
  1430. $this->queryDelete->resetQuery($this->format);
  1431. // pass parameter
  1432. if( count($args) > 0 )
  1433. call_user_func_array(array($this->queryDelete, "table"), $args);
  1434. return $this->queryDelete;
  1435. }
  1436. /**
  1437. * get update query instance
  1438. * @param string|array $table
  1439. * @param boolean $newInstance
  1440. * @return mysqlClass_Delete
  1441. */
  1442. public function deleteFrom($table = NULL, $newInstance = false)
  1443. {
  1444. // prevent php debug notification
  1445. if( $table && $newInstance );
  1446. return call_user_func_array(array($this, "delete"), func_get_args());
  1447. }
  1448. /**
  1449. * get truncate query instance
  1450. * @param string|array $table
  1451. * @param boolean $newInstance
  1452. * @return mysqlClass_Truncate
  1453. */
  1454. public function truncate($table = NULL, $newInstance = false)
  1455. {
  1456. // prevent php debug notification
  1457. if( $table && $newInstance );
  1458. $args = array();
  1459. // check parameters for new instance
  1460. if( func_num_args() > 0 )
  1461. {
  1462. // extract last parameter
  1463. $args = func_get_args();
  1464. $last = array_splice($args, -1);
  1465. // if last parameter is a boolean
  1466. if( is_bool($last[0]) )
  1467. {
  1468. // if new instance has to be created
  1469. if( $last[0] )
  1470. {
  1471. $instance = new mysqlClass_Truncate($this);
  1472. if( !empty($args) )
  1473. call_user_func_array(array($instance, "table"), array($table));
  1474. return $instance;
  1475. }
  1476. }
  1477. // otherwise push parameter back in list
  1478. else
  1479. {
  1480. array_push($args, $last);
  1481. }
  1482. }
  1483. // create instance or reset
  1484. if( !$this->queryTruncate )
  1485. $this->queryTruncate = new mysqlClass_Truncate($this);
  1486. else
  1487. $this->queryTruncate->resetQuery($this->format);
  1488. // pass parameter
  1489. if( count($args) > 0 )
  1490. call_user_func_array(array($this->queryTruncate, "table"), array($table));
  1491. return $this->queryTruncate;
  1492. }
  1493. /**
  1494. * get truncate query instance
  1495. * @param string|array $table
  1496. * @param boolean $newInstance
  1497. * @return mysqlClass_Truncate
  1498. */
  1499. public function truncateTable($table = NULL, $newInstance = false)
  1500. {
  1501. // prevent php debug notification
  1502. if( $table && $newInstance );
  1503. return call_user_func_array(array($this, "truncate"), func_get_args());
  1504. }
  1505. }
  1506. /*
  1507. ** query classes
  1508. */
  1509. /**
  1510. * Frosted MySQL Library Query Class Interface
  1511. * - - - - - - - - - -
  1512. * Interface for all query classes related to Frosted MySQL Library.
  1513. * - - - - - - - - - -
  1514. * Licensed under MIT license
  1515. * - - - - - - - - - -
  1516. * @Creator Daniel 'Eisbehr' Kern
  1517. * @Require PHP5
  1518. * @Version 3.0
  1519. * @Date 01.08.2013
  1520. * @Update 01.08.2013
  1521. * - - - - - - - - - -
  1522. */
  1523. interface mysqlClass_Queries
  1524. {
  1525. /**
  1526. * execute mysql query
  1527. * @param boolean $returnRaw
  1528. * @return mysqlClass|mixed
  1529. */
  1530. public function run($returnRaw = false);
  1531. /**
  1532. * execute mysql query
  1533. * @param boolean $returnRaw
  1534. * @return mysqlClass|mixed
  1535. */
  1536. public function execute($returnRaw = false);
  1537. /**
  1538. * build query string
  1539. * @param integer $formatOffset
  1540. * @return string
  1541. */
  1542. public function build($formatOffset = 0);
  1543. /**
  1544. * reset query instance
  1545. * @param boolean $format
  1546. * @return mysqlClass_Queries
  1547. */
  1548. public function resetQuery($format);
  1549. /**
  1550. * print query to browser
  1551. * @return mysqlClass_Queries
  1552. */
  1553. public function showQuery();
  1554. /**
  1555. * build and return query
  1556. * @return string
  1557. */
  1558. public function getQuery();
  1559. }
  1560. /**
  1561. * Frosted MySQL Library Query Abstract Class
  1562. * - - - - - - - - - -
  1563. * Abstraction for all query classes related to Frosted MySQL Library.
  1564. * - - - - - - - - - -
  1565. * Licensed under MIT license
  1566. * - - - - - - - - - -
  1567. * @Creator Daniel 'Eisbehr' Kern
  1568. * @Require PHP5
  1569. * @Version 3.0
  1570. * @Date 01.08.2013
  1571. * @Update 01.08.2013
  1572. * - - - - - - - - - -
  1573. */
  1574. class mysqlClass_Abstract implements mysqlClass_Queries
  1575. {
  1576. /**
  1577. * parent class
  1578. * @var mysqlClass
  1579. */
  1580. protected $parent = NULL;
  1581. /**
  1582. * format the query output
  1583. * @var boolean
  1584. */
  1585. protected $format = true;
  1586. /**
  1587. * format offset
  1588. * @var integer
  1589. */
  1590. protected $formatOffset = 0;
  1591. /**
  1592. * build query
  1593. * @var array
  1594. */
  1595. protected $query = array();
  1596. /*
  1597. ** public
  1598. */
  1599. /**
  1600. * create select class
  1601. * @param mysqlClass $parent
  1602. */
  1603. public function __construct($parent)
  1604. {
  1605. $this->parent = $parent;
  1606. $this->resetQuery($this->parent->getFormat());
  1607. }
  1608. /**
  1609. * reset query instance
  1610. * @param boolean $format
  1611. * @return mysqlClass_Queries
  1612. */
  1613. public function resetQuery($format)
  1614. {
  1615. $this->format = $format;
  1616. $this->query = array();
  1617. return $this;
  1618. }
  1619. /**
  1620. * build query string
  1621. * @param integer $formatOffset
  1622. * @return string
  1623. */
  1624. public function build($formatOffset = 0)
  1625. {
  1626. return NULL;
  1627. }
  1628. /**
  1629. * print query string
  1630. * @return mysqlClass_Select
  1631. */
  1632. public function showQuery()
  1633. {
  1634. $query = $this->build();
  1635. $query = $this->parent->replaceQuery($query);
  1636. echo $query . "\n\n";
  1637. return $this;
  1638. }
  1639. /**
  1640. * build and get query string
  1641. * @return string
  1642. */
  1643. public function getQuery()
  1644. {
  1645. $query = $this->build();
  1646. $query = $this->parent->replaceQuery($query);
  1647. return $query;
  1648. }
  1649. /**
  1650. * run mysql query against database
  1651. * @param boolean $returnRaw
  1652. * @return mysqlClass|mysqli_result|resource
  1653. */
  1654. public function run($returnRaw = false)
  1655. {
  1656. $query = $this->build();
  1657. $result = $this->parent->query($query);
  1658. if( $returnRaw )
  1659. return $result;
  1660. return $this->parent;
  1661. }
  1662. /**
  1663. * alias of run()
  1664. * @param boolean $returnRaw
  1665. * @return mixed|mysqlClass|resource
  1666. */
  1667. public function execute($returnRaw = false)
  1668. {
  1669. return $this->run($returnRaw);
  1670. }
  1671. }
  1672. /**
  1673. * Frosted MySQL Library Delete Query Class
  1674. * - - - - - - - - - -
  1675. * Add "DELETE" functionality to Frosted MySQL Library and will not work without them.
  1676. * - - - - - - - - - -
  1677. * Licensed under MIT license
  1678. * - - - - - - - - - -
  1679. * @Creator Daniel 'Eisbehr' Kern
  1680. * @Require PHP5
  1681. * @Version 3.0
  1682. * @Date 01.08.2013
  1683. * @Update 01.08.2013
  1684. * - - - - - - - - - -
  1685. */
  1686. class mysqlClass_Delete extends mysqlClass_Abstract implements mysqlClass_Queries
  1687. {
  1688. /**
  1689. * delete error messages
  1690. * @var string
  1691. */
  1692. const MESSAGE_ORDER = "you cannot use 'order' if you delete from more than one table";
  1693. const MESSAGE_LIMIT = "you cannot use 'limit' if you delete from more than one table";
  1694. /*
  1695. ** public
  1696. */
  1697. /**
  1698. * reset delete class
  1699. * @param boolean $format
  1700. * @return mysqlClass_Delete
  1701. */
  1702. public function resetQuery($format)
  1703. {
  1704. parent::resetQuery($format);
  1705. $this->query["tables"] = array();
  1706. $this->query["using"] = array();
  1707. $this->query["low"] = false;
  1708. $this->query["quick"] = false;
  1709. $this->query["ignore"] = false;
  1710. $this->query["where"] = array();
  1711. $this->query["order"] = array();
  1712. $this->query["limit"] = NULL;
  1713. return $this;
  1714. }
  1715. /*
  1716. ** query related
  1717. */
  1718. /**
  1719. * add tables to query
  1720. * @param string|array $table
  1721. * @return mysqlClass_Delete
  1722. */
  1723. public function table($table)
  1724. {
  1725. // only one string is set
  1726. if( func_num_args() == 1 && is_string($table) )
  1727. {
  1728. $this->query["tables"][] = $table;
  1729. return $this;
  1730. }
  1731. // add all tables to query
  1732. foreach( func_get_args() as $param )
  1733. {
  1734. if( !is_array($param) )
  1735. $this->query["tables"][] = $param;
  1736. else
  1737. foreach( $param as $database => $name )
  1738. {
  1739. if( !is_numeric($database) )
  1740. $this->query["tables"][] = $database;
  1741. else
  1742. $this->query["tables"][] = $name;
  1743. }
  1744. }
  1745. // add table to using
  1746. call_user_func_array(array($this, "using"), func_get_args());
  1747. return $this;
  1748. }
  1749. /**
  1750. * add using tables to query
  1751. * @param string|array $table
  1752. * @return mysqlClass_Delete
  1753. */
  1754. public function using($table)
  1755. {
  1756. // only one string is set
  1757. if( func_num_args() == 1 && is_string($table) )
  1758. {
  1759. if( !in_array($table, $this->query["using"]) )
  1760. $this->query["using"][] = $table;
  1761. return $this;
  1762. }
  1763. // add all tables to query
  1764. foreach( func_get_args() as $param )
  1765. {
  1766. if( !is_array($param) )
  1767. {
  1768. if( !in_array($table, $this->query["using"]) )
  1769. $this->query["using"][] = $param;
  1770. }
  1771. else
  1772. foreach( $param as $database => $name )
  1773. if( !is_numeric($database) )
  1774. $this->query["using"][] = $database . " AS " . $name;
  1775. else if( !in_array($name, $this->query["using"]) )
  1776. $this->query["using"][] = $name;
  1777. }
  1778. return $this;
  1779. }
  1780. /**
  1781. * add 'low priority' to query
  1782. * @param boolean $low
  1783. * @return mysqlClass_Delete
  1784. */
  1785. public function lowPriority($low = true)
  1786. {
  1787. $this->query["low"] = (bool)$low;
  1788. return $this;
  1789. }
  1790. /**
  1791. * add 'quick' to query
  1792. * @param boolean $quick
  1793. * @return mysqlClass_Delete
  1794. */
  1795. public function quick($quick = true)
  1796. {
  1797. $this->query["quick"] = (bool)$quick;
  1798. return $this;
  1799. }
  1800. /**
  1801. * add 'ignore' to query
  1802. * @param boolean $ignore
  1803. * @return mysqlClass_Delete
  1804. */
  1805. public function ignore($ignore = true)
  1806. {
  1807. $this->query["ignore"] = (bool)$ignore;
  1808. return $this;
  1809. }
  1810. /**
  1811. * add 'where' to query
  1812. * @param string $condition
  1813. * @param string $replace
  1814. * @param string $nextRelation
  1815. * @return mysqlClass_Delete
  1816. */
  1817. public function where($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  1818. {
  1819. // add condition
  1820. if( !is_null($replace) )
  1821. {
  1822. if( is_array($replace) )
  1823. {
  1824. // escape all values
  1825. foreach( $replace as &$value ) $value = $this->parent->escape($value);
  1826. // format sub-query
  1827. if( $this->format )
  1828. {
  1829. $condition = str_replace("ANY(?)", "\nANY\n(\n ?\n)", $condition);
  1830. $condition = str_replace("IN(?)", "\nIN\n(\n ?\n)", $condition);
  1831. $condition = str_replace("SOME(?)", "\nSOME\n(\n ?\n)", $condition);
  1832. }
  1833. $glue = $this->format ? ",\n " : ",";
  1834. $this->query["where"][] = str_replace("?", join($glue, $replace), $condition);
  1835. }
  1836. else if( $replace instanceof mysqlClass_Select )
  1837. $this->query["where"][] = array($condition, $replace);
  1838. else
  1839. $this->query["where"][] = str_replace("?", $this->parent->escape($replace), $condition);
  1840. }
  1841. else
  1842. $this->query["where"][] = $condition;
  1843. // add relation
  1844. if( strtoupper($nextRelation) == mysqlClass::WHERE_OR )
  1845. $this->query["where"][] = mysqlClass::WHERE_OR;
  1846. else
  1847. $this->query["where"][] = mysqlClass::WHERE_AND;
  1848. return $this;
  1849. }
  1850. /**
  1851. * add 'or' related 'where' to query
  1852. * @param string $condition
  1853. * @param string $replace
  1854. * @param string $nextRelation
  1855. * @return mysqlClass_Delete
  1856. */
  1857. public function orWhere($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  1858. {
  1859. if( !empty($this->query["where"]) )
  1860. $this->query["where"][(count($this->query["where"]) - 1)] = mysqlClass::WHERE_OR;
  1861. return $this->where($condition, $replace, $nextRelation);
  1862. }
  1863. /**
  1864. * add 'order' to query
  1865. * @param string $field
  1866. * @param string $order
  1867. * @return mysqlClass_Delete
  1868. */
  1869. public function orderBy($field, $order = mysqlClass::ORDER_ASC)
  1870. {
  1871. if( count($this->query["tables"]) >= 2 )
  1872. {
  1873. $this->parent->createError(self::MESSAGE_ORDER);
  1874. return $this;
  1875. }
  1876. if( strtoupper($order) == mysqlClass::ORDER_DESC )
  1877. $this->query["order"][] = $field . " " . mysqlClass::ORDER_DESC;
  1878. else
  1879. $this->query["order"][] = $field . " " . mysqlClass::ORDER_ASC;
  1880. return $this;
  1881. }
  1882. /**
  1883. * alias of 'orderBy'
  1884. * @param string $field
  1885. * @param string $order
  1886. * @return mysqlClass_Delete
  1887. */
  1888. public function order($field, $order = mysqlClass::ORDER_ASC)
  1889. {
  1890. return $this->orderBy($field, $order);
  1891. }
  1892. /**
  1893. * add 'limit' to query
  1894. * @param integer $limit
  1895. * @return mysqlClass_Delete
  1896. */
  1897. public function limit($limit)
  1898. {
  1899. if( count($this->query["tables"]) >= 2 )
  1900. {
  1901. $this->parent->createError(self::MESSAGE_LIMIT);
  1902. return $this;
  1903. }
  1904. $this->query["limit"] = $limit;
  1905. return $this;
  1906. }
  1907. /*
  1908. ** build
  1909. */
  1910. /**
  1911. * build mysql delete query string
  1912. * @param integer $formatOffset
  1913. * @return string
  1914. */
  1915. public function build($formatOffset = 0)
  1916. {
  1917. $this->formatOffset += $formatOffset;
  1918. $offset = str_pad("", $this->formatOffset, " ");
  1919. // end if no table is set
  1920. if( empty($this->query["tables"]) ) return NULL;
  1921. $query = $this->format ? $offset . "DELETE " : "DELETE ";
  1922. // low priority
  1923. if( $this->query["low"] ) $query .= $this->format ? "\n" . $offset . " LOW_PRIORITY " : "LOW_PRIORITY ";
  1924. // quick
  1925. if( $this->query["quick"] ) $query .= $this->format ? "\n" . $offset . " QUICK " : "QUICK ";
  1926. // ignore
  1927. if( $this->query["ignore"] ) $query .= $this->format ? "\n" . $offset . " IGNORE " : "IGNORE ";
  1928. // format line break
  1929. $query .= $this->format && ($this->query["low"] || $this->query["quick"] || $this->query["ignore"]) ? "\n" : NULL;
  1930. // tables
  1931. if( count($this->query["tables"]) == 1 )
  1932. {
  1933. $query .= $this->format ? $offset . "FROM\n" . $offset . " " . $this->query["tables"][0] . "\n" : "FROM " . $this->query["tables"][0] . " ";
  1934. }
  1935. else
  1936. {
  1937. if( $this->format )
  1938. {
  1939. $query .= "FROM\n";
  1940. for( $i = 0; $i < count($this->query["tables"]); $i++ )
  1941. {
  1942. $query .= $offset . " " . $this->query["tables"][$i];
  1943. $query .= $i < count($this->query["tables"]) - 1 ? "," : NULL;
  1944. $query .= "\n";
  1945. }
  1946. $query .= $offset . "USING\n";
  1947. for( $i = 0; $i < count($this->query["using"]); $i++ )
  1948. {
  1949. $query .= $offset . " " . $this->query["using"][$i];
  1950. $query .= $i < count($this->query["using"]) - 1 ? "," : NULL;
  1951. $query .= "\n";
  1952. }
  1953. }
  1954. else
  1955. {
  1956. $query .= "FROM " . join(",", $this->query["tables"]) . " ";
  1957. $query .= "USING " . join(",", $this->query["using"]) . " ";
  1958. }
  1959. }
  1960. // where
  1961. if( !empty($this->query["where"]) )
  1962. {
  1963. if( $this->format )
  1964. {
  1965. $query .= $offset . "WHERE \n";
  1966. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  1967. {
  1968. if( is_array($this->query["where"][$i]) )
  1969. {
  1970. $select = $this->query["where"][$i][1];
  1971. if( $select instanceof mysqlClass_Select )
  1972. {
  1973. $select = $select->build($this->formatOffset + 4);
  1974. $select = trim($select);
  1975. }
  1976. $query .= $offset . " " . str_replace("?", "\n" . $offset . " (" . $select . ")", $this->query["where"][$i][0]);
  1977. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  1978. $query .= " \n";
  1979. }
  1980. else
  1981. {
  1982. $query .= $offset . " " . $this->query["where"][$i];
  1983. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  1984. $query .= " \n";
  1985. }
  1986. }
  1987. }
  1988. else
  1989. {
  1990. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  1991. {
  1992. if( is_array($this->query["where"][$i]) )
  1993. {
  1994. $select = $this->query["where"][$i][1];
  1995. if( $select instanceof mysqlClass_Select )
  1996. $select = $select->build();
  1997. $this->query["where"][$i] = str_replace("?", "(" . $select . ")", $this->query["where"][$i][0]);
  1998. }
  1999. }
  2000. $where = array_slice($this->query["where"], 0, -1);
  2001. $query .= "WHERE " . join(" ", $where) . " ";
  2002. }
  2003. }
  2004. // order
  2005. if( !empty($this->query["order"]) )
  2006. {
  2007. if( $this->format )
  2008. {
  2009. $query .= $offset . "ORDER BY \n";
  2010. for( $i = 0; $i < count($this->query["order"]); $i++ )
  2011. {
  2012. $query .= $offset . " " . $this->query["order"][$i];
  2013. $query .= $i < count($this->query["order"]) - 1 ? "," : NULL;
  2014. $query .= " \n";
  2015. }
  2016. }
  2017. else
  2018. {
  2019. $query .= "ORDER BY " . join(",", $this->query["order"]) . " ";
  2020. }
  2021. }
  2022. // limit
  2023. if( !empty($this->query["limit"]) )
  2024. {
  2025. $query .= $this->format ? $offset . "LIMIT \n" . $offset . " " : "LIMIT ";
  2026. $query .= $this->query["limit"];
  2027. }
  2028. return $query;
  2029. }
  2030. }
  2031. /**
  2032. * Frosted MySQL Library Insert Query Class
  2033. * - - - - - - - - - -
  2034. * Add "INSERT" functionality to Frosted MySQL Library and will not work without them.
  2035. * - - - - - - - - - -
  2036. * Licensed under MIT license
  2037. * - - - - - - - - - -
  2038. * @Creator Daniel 'Eisbehr' Kern
  2039. * @Require PHP5
  2040. * @Version 3.0
  2041. * @Date 01.08.2013
  2042. * @Update 01.08.2013
  2043. * - - - - - - - - - -
  2044. */
  2045. class mysqlClass_Insert extends mysqlClass_Abstract implements mysqlClass_Queries
  2046. {
  2047. /**
  2048. * insert error messages
  2049. * @var string
  2050. */
  2051. const MESSAGE_AFTER_FIELDS = "you cannot add columns after using 'set' or 'select'";
  2052. const MESSAGE_AFTER_SET = "you cannot use 'set' after adding columns or a select";
  2053. const MESSAGE_AFTER_SELECT = "you cannot use 'select' after adding values or 'set'";
  2054. const MESSAGE_BEFORE_VALUES = "you have to specify a column list before adding values";
  2055. const MESSAGE_VALUES_COUNT = "value count doesn't match columns";
  2056. const MESSAGE_VALUES_MISSING = "columns not found in values";
  2057. /*
  2058. ** public
  2059. */
  2060. /**
  2061. * reset insert class
  2062. * @param boolean $format
  2063. * @return mysqlClass_Select
  2064. */
  2065. public function resetQuery($format)
  2066. {
  2067. parent::resetQuery($format);
  2068. $this->query["table"] = NULL;
  2069. $this->query["low"] = false;
  2070. $this->query["delayed"] = false;
  2071. $this->query["high"] = false;
  2072. $this->query["ignore"] = false;
  2073. $this->query["columns"] = array();
  2074. $this->query["values"] = array();
  2075. $this->query["set"] = array();
  2076. $this->query["select"] = NULL;
  2077. $this->query["duplicate"] = array();
  2078. return $this;
  2079. }
  2080. /*
  2081. ** query related
  2082. */
  2083. /**
  2084. * add table to insert query
  2085. * @param string $table
  2086. * @return mysqlClass_Insert
  2087. */
  2088. public function table($table)
  2089. {
  2090. if( is_string($table) )
  2091. $this->query["table"] = $table;
  2092. else if( is_array($table) )
  2093. foreach( $table as $_table => $_name )
  2094. if( !is_numeric($_table) )
  2095. $this->query["table"] = $_table;
  2096. else
  2097. $this->query["table"] = $_name;
  2098. return $this;
  2099. }
  2100. /**
  2101. * alias of 'table'
  2102. * @param string $table
  2103. * @return mysqlClass_Insert
  2104. */
  2105. public function into($table)
  2106. {
  2107. return $this->table($table);
  2108. }
  2109. /**
  2110. * add 'low priority' to query
  2111. * @param boolean $low
  2112. * @return mysqlClass_Insert
  2113. */
  2114. public function lowPriority($low = true)
  2115. {
  2116. if( (bool)$low )
  2117. {
  2118. $this->query["delayed"] = false;
  2119. $this->query["high"] = false;
  2120. }
  2121. $this->query["low"] = (bool)$low;
  2122. return $this;
  2123. }
  2124. /**
  2125. * add 'delayed' to insert query
  2126. * @param boolean $delayed
  2127. * @return mysqlClass_Insert
  2128. */
  2129. public function delayed($delayed = true)
  2130. {
  2131. if( (bool)$delayed )
  2132. {
  2133. $this->query["low"] = false;
  2134. $this->query["high"] = false;
  2135. }
  2136. $this->query["delayed"] = (bool)$delayed;
  2137. return $this;
  2138. }
  2139. /**
  2140. * add 'high priority' to query
  2141. * @param boolean $high
  2142. * @return mysqlClass_Insert
  2143. */
  2144. public function highPriority($high = true)
  2145. {
  2146. if( (bool)$high )
  2147. {
  2148. $this->query["low"] = false;
  2149. $this->query["delayed"] = false;
  2150. }
  2151. $this->query["high"] = (bool)$high;
  2152. return $this;
  2153. }
  2154. /**
  2155. * add 'ignore' to insert query
  2156. * @param boolean $ignore
  2157. * @return mysqlClass_Insert
  2158. */
  2159. public function ignore($ignore = true)
  2160. {
  2161. $this->query["ignore"] = (bool)$ignore;
  2162. return $this;
  2163. }
  2164. /**
  2165. * add columns to insert query
  2166. * @param string|array $columns
  2167. * @return mysqlClass_Insert
  2168. */
  2169. public function columns($columns)
  2170. {
  2171. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2172. {
  2173. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2174. return $this;
  2175. }
  2176. if( func_num_args() == 1 && is_string($columns) && !in_array($columns, $this->query["columns"]) )
  2177. {
  2178. $this->query["columns"][] = $columns;
  2179. return $this;
  2180. }
  2181. foreach( func_get_args() as $column )
  2182. {
  2183. if( !is_array($column) && !in_array($column, $this->query["columns"]) )
  2184. {
  2185. $this->query["columns"][] = $column;
  2186. }
  2187. else
  2188. {
  2189. foreach( $column as $_column )
  2190. if( !in_array($_column, $this->query["columns"]) )
  2191. $this->query["columns"][] = $_column;
  2192. }
  2193. }
  2194. return $this;
  2195. }
  2196. /**
  2197. * alias of "columns"
  2198. * @param string|array $fields
  2199. * @return mysqlClass_Insert
  2200. */
  2201. public function fields($fields)
  2202. {
  2203. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2204. {
  2205. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2206. return $this;
  2207. }
  2208. if( func_num_args() == 1 && is_string($fields) && !in_array($fields, $this->query["columns"]) )
  2209. {
  2210. $this->query["columns"][] = $fields;
  2211. return $this;
  2212. }
  2213. return call_user_func_array(array($this, "columns"), func_get_args());
  2214. }
  2215. /**
  2216. * add 'values' to insert query
  2217. * @param string|array $values
  2218. * @return mysqlClass_Insert
  2219. */
  2220. public function values($values)
  2221. {
  2222. $columnCount = count($this->query["columns"]);
  2223. if( $columnCount == 0 )
  2224. {
  2225. $this->parent->createError(self::MESSAGE_BEFORE_VALUES);
  2226. return $this;
  2227. }
  2228. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2229. {
  2230. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2231. return $this;
  2232. }
  2233. if( func_num_args() == 1 && $columnCount == 1 && !is_array($values) )
  2234. {
  2235. $this->query["values"][] = array($values);
  2236. return $this;
  2237. }
  2238. // count params
  2239. $count = 0;
  2240. $values = array();
  2241. foreach( func_get_args() as $value )
  2242. {
  2243. if( !is_array($value) )
  2244. {
  2245. $count++;
  2246. $values[] = $this->parent->escape($value);
  2247. }
  2248. else
  2249. {
  2250. foreach( $value as $_key => $_value )
  2251. {
  2252. $count++;
  2253. if( is_numeric($_key) )
  2254. $values[] = $this->parent->escape($_value);
  2255. else
  2256. $values[$_key] = $this->parent->escape($_value);
  2257. }
  2258. }
  2259. }
  2260. // check if params count match fields
  2261. if( $count == $columnCount )
  2262. {
  2263. $this->query["values"][] = $values;
  2264. }
  2265. // check if fields names are in values
  2266. else if( $count > $columnCount )
  2267. {
  2268. $_values = array();
  2269. foreach( $this->query["columns"] as $column )
  2270. {
  2271. if( !isset($values[$column]) ) break;
  2272. $_values[] = $values[$column];
  2273. }
  2274. if( count($_values) == $columnCount )
  2275. $this->query["values"][] = $_values;
  2276. else
  2277. $this->parent->createError(self::MESSAGE_VALUES_MISSING);
  2278. }
  2279. // values doesn't match
  2280. else
  2281. {
  2282. $this->parent->createError(self::MESSAGE_VALUES_COUNT);
  2283. }
  2284. return $this;
  2285. }
  2286. /**
  2287. * add 'set' to insert query
  2288. * @param string|array $column
  2289. * @param string $replace
  2290. * @return mysqlClass_Insert
  2291. */
  2292. public function set($column, $replace = NULL)
  2293. {
  2294. if( count($this->query["columns"]) > 0 || !is_null($this->query["select"]) )
  2295. {
  2296. $this->parent->createError(self::MESSAGE_AFTER_SET);
  2297. return $this;
  2298. }
  2299. if( is_null($replace) )
  2300. {
  2301. if( is_array($column) )
  2302. {
  2303. foreach( $column as $_column => $_replace )
  2304. {
  2305. if( !is_numeric($_column) )
  2306. if( strpos($_column, "?") === false && strpos($column, "=") === false )
  2307. $this->query["set"][] = $_column . " = " . $this->parent->escape($_replace);
  2308. else
  2309. $this->query["set"][] = str_replace("?", $this->parent->escape($_replace), $_column);
  2310. else
  2311. $this->query["set"][] = $_replace;
  2312. }
  2313. }
  2314. else
  2315. {
  2316. $this->query["set"][] = $column;
  2317. }
  2318. }
  2319. else
  2320. {
  2321. if( strpos($column, "?") === false && strpos($column, "=") === false )
  2322. $this->query["set"][] = $column . " = " . $this->parent->escape($replace);
  2323. else
  2324. $this->query["set"][] = str_replace("?", $this->parent->escape($replace), $column);
  2325. }
  2326. return $this;
  2327. }
  2328. /**
  2329. * add a select statement to insert query
  2330. * @param string|mysqlClass_Select $subSelect
  2331. * @return mysqlClass_Insert
  2332. */
  2333. public function select($subSelect)
  2334. {
  2335. if( count($this->query["values"]) > 0 || count($this->query["set"]) > 0 )
  2336. {
  2337. $this->parent->createError(self::MESSAGE_AFTER_SELECT);
  2338. return $this;
  2339. }
  2340. if( is_string($subSelect) || $subSelect instanceof mysqlClass_Select )
  2341. {
  2342. $this->query["select"] = $subSelect;
  2343. }
  2344. return $this;
  2345. }
  2346. /**
  2347. * add 'onDuplicate' to query
  2348. * @param array|string $update
  2349. * @param string $replace
  2350. * @return mysqlClass_Insert
  2351. */
  2352. public function onDuplicate($update, $replace = NULL)
  2353. {
  2354. if( is_null($replace) )
  2355. {
  2356. if( is_array($update) )
  2357. {
  2358. foreach( $update as $_update => $_replace )
  2359. {
  2360. if( !is_numeric($_update) )
  2361. $this->query["duplicate"][] = str_replace("?", $this->parent->escape($_replace), $_update);
  2362. else
  2363. $this->query["duplicate"][] = $_replace;
  2364. }
  2365. }
  2366. else
  2367. {
  2368. $this->query["duplicate"][] = $update;
  2369. }
  2370. }
  2371. else
  2372. {
  2373. $this->query["duplicate"][] = str_replace("?", $this->parent->escape($replace), $update);
  2374. }
  2375. return $this;
  2376. }
  2377. /**
  2378. * alias of 'onDuplicate'
  2379. * @param array|string $update
  2380. * @param string $replace
  2381. * @return mysqlClass_Insert
  2382. */
  2383. public function duplicate($update, $replace = NULL)
  2384. {
  2385. return $this->onDuplicate($update, $replace);
  2386. }
  2387. /*
  2388. ** build
  2389. */
  2390. /**
  2391. * build mysql insert query string
  2392. * @param integer $formatOffset
  2393. * @return string
  2394. */
  2395. public function build($formatOffset = 0)
  2396. {
  2397. $this->formatOffset += $formatOffset;
  2398. $offset = str_pad("", $this->formatOffset, " ");
  2399. // end if no table is set
  2400. if( is_null($this->query["table"]) ) return NULL;
  2401. $query = $this->format ? $offset . "INSERT " : "INSERT ";
  2402. // low priority
  2403. if( $this->query["low"] ) $query .= $this->format ? "\n" . $offset . " LOW_PRIORITY " : "LOW_PRIORITY ";
  2404. // delayed
  2405. if( $this->query["delayed"] ) $query .= $this->format ? "\n" . $offset . " DELAYED " : "DELAYED ";
  2406. // high priority
  2407. if( $this->query["high"] ) $query .= $this->format ? "\n" . $offset . " HIGH_PRIORITY " : "HIGH_PRIORITY ";
  2408. // ignore
  2409. if( $this->query["ignore"] ) $query .= $this->format ? "\n" . $offset . " IGNORE \n" : "IGNORE ";
  2410. $query .= $this->format ? $offset . "INTO " : "INTO ";
  2411. // table
  2412. $query .= $this->format ? "\n" . $offset . " " . $this->query["table"] . "\n" : $this->query["table"] . " ";
  2413. // columns
  2414. if( !empty($this->query["columns"]) )
  2415. {
  2416. if( $this->format )
  2417. {
  2418. $query .= $offset . " (";
  2419. for( $i = 0; $i < count($this->query["columns"]); $i++ )
  2420. {
  2421. $query .= " " . $this->query["columns"][$i];
  2422. $query .= $i < count($this->query["columns"]) - 1 ? "," : NULL;
  2423. }
  2424. $query .= " ) \n";
  2425. }
  2426. else
  2427. $query .= "(" . join(",", $this->query["columns"]) . ") ";
  2428. if( !empty($this->query["values"]) )
  2429. {
  2430. $query .= $this->format ? "VALUES\n" : "VALUES ";
  2431. for( $i = 0; $i < count($this->query["values"]); $i++ )
  2432. {
  2433. if( $this->format )
  2434. {
  2435. $query .= $offset . " " . "( " . join(", ", $this->query["values"][$i]) . " )";
  2436. $query .= $i < count($this->query["values"]) - 1 ? ",\n" : NULL;
  2437. }
  2438. else
  2439. {
  2440. $query .= "(" . join(",", $this->query["values"][$i]) . ")";
  2441. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  2442. }
  2443. }
  2444. $query .= $this->format ? "\n" : " ";
  2445. }
  2446. }
  2447. // set
  2448. else if( !empty($this->query["set"]) )
  2449. {
  2450. $query .= $this->format ? "SET\n" : "SET ";
  2451. for( $i = 0; $i < count($this->query["set"]); $i++ )
  2452. {
  2453. if( $this->format )
  2454. {
  2455. $query .= $offset . " " . $this->query["set"][$i] . "";
  2456. $query .= $i < count($this->query["set"]) - 1 ? ", \n" : NULL;
  2457. }
  2458. else
  2459. {
  2460. $query .= "(" . join(",", $this->query["set"]) . ")";
  2461. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  2462. }
  2463. }
  2464. $query .= $this->format ? "\n" : " ";
  2465. }
  2466. // select
  2467. if( !is_null($this->query["select"]) )
  2468. {
  2469. if( is_string($this->query["select"]) )
  2470. {
  2471. if( $this->format )
  2472. $query .= $offset . " ( " . $this->query["select"] . " ) \n";
  2473. else
  2474. $query .= "(" . $this->query["select"] . ") ";
  2475. }
  2476. else
  2477. {
  2478. $select = $this->query["select"];
  2479. if( $select instanceof mysqlClass_Select )
  2480. {
  2481. if( $this->format )
  2482. $query .= $offset . " (" . trim($select->build($this->formatOffset + 4)) . ") \n";
  2483. else
  2484. $query .= "(" . $select->build() . ") ";
  2485. }
  2486. }
  2487. }
  2488. // on duplicate
  2489. if( !empty($this->query["duplicate"]) )
  2490. {
  2491. if( $this->format )
  2492. {
  2493. $query .= "ON DUPLICATE KEY UPDATE \n";
  2494. for( $i = 0; $i < count($this->query["duplicate"]); $i++ )
  2495. {
  2496. $query .= $offset . " " . $this->query["duplicate"][$i];
  2497. $query .= $i < count($this->query["duplicate"]) - 1 ? "," : NULL;
  2498. $query .= " \n";
  2499. }
  2500. }
  2501. else
  2502. {
  2503. $query .= "ON DUPLICATE KEY UPDATE " . join(",", $this->query["duplicate"]) . " ";
  2504. }
  2505. }
  2506. return $query;
  2507. }
  2508. }
  2509. /**
  2510. * Frosted MySQL Library Replace Query Class
  2511. * - - - - - - - - - -
  2512. * Add "REPLACE" functionality to Frosted MySQL Library and will not work without them.
  2513. * - - - - - - - - - -
  2514. * Licensed under MIT license
  2515. * - - - - - - - - - -
  2516. * @Creator Daniel 'Eisbehr' Kern
  2517. * @Require PHP5
  2518. * @Version 3.0
  2519. * @Date 01.08.2013
  2520. * @Update 01.08.2013
  2521. * - - - - - - - - - -
  2522. */
  2523. class mysqlClass_Replace extends mysqlClass_Abstract implements mysqlClass_Queries
  2524. {
  2525. /**
  2526. * insert error messages
  2527. * @var string
  2528. */
  2529. const MESSAGE_AFTER_FIELDS = "you cannot add columns after using 'set' or 'select'";
  2530. const MESSAGE_AFTER_SET = "you cannot use 'set' after adding columns or a select";
  2531. const MESSAGE_AFTER_SELECT = "you cannot use 'select' after adding values or 'set'";
  2532. const MESSAGE_BEFORE_VALUES = "you have to specify a column list before adding values";
  2533. const MESSAGE_VALUES_COUNT = "value count doesn't match columns";
  2534. const MESSAGE_VALUES_MISSING = "columns not found in values";
  2535. /*
  2536. ** public
  2537. */
  2538. /**
  2539. * reset insert class
  2540. * @param boolean $format
  2541. * @return mysqlClass_Select
  2542. */
  2543. public function resetQuery($format)
  2544. {
  2545. parent::resetQuery($format);
  2546. $this->query["table"] = NULL;
  2547. $this->query["low"] = false;
  2548. $this->query["delayed"] = false;
  2549. $this->query["ignore"] = false;
  2550. $this->query["columns"] = array();
  2551. $this->query["values"] = array();
  2552. $this->query["set"] = array();
  2553. $this->query["select"] = NULL;
  2554. return $this;
  2555. }
  2556. /*
  2557. ** query related
  2558. */
  2559. /**
  2560. * add table to insert query
  2561. * @param string $table
  2562. * @return mysqlClass_Insert
  2563. */
  2564. public function table($table)
  2565. {
  2566. if( is_string($table) )
  2567. $this->query["table"] = $table;
  2568. else if( is_array($table) )
  2569. foreach( $table as $_table => $_name )
  2570. if( !is_numeric($_table) )
  2571. $this->query["table"] = $_table;
  2572. else
  2573. $this->query["table"] = $_name;
  2574. return $this;
  2575. }
  2576. /**
  2577. * alias of 'table'
  2578. * @param string $table
  2579. * @return mysqlClass_Insert
  2580. */
  2581. public function into($table)
  2582. {
  2583. return $this->table($table);
  2584. }
  2585. /**
  2586. * add 'low priority' to query
  2587. * @param boolean $low
  2588. * @return mysqlClass_Insert
  2589. */
  2590. public function lowPriority($low = true)
  2591. {
  2592. if( (bool)$low )
  2593. {
  2594. $this->query["delayed"] = false;
  2595. $this->query["high"] = false;
  2596. }
  2597. $this->query["low"] = (bool)$low;
  2598. return $this;
  2599. }
  2600. /**
  2601. * add 'delayed' to insert query
  2602. * @param boolean $delayed
  2603. * @return mysqlClass_Insert
  2604. */
  2605. public function delayed($delayed = true)
  2606. {
  2607. if( (bool)$delayed )
  2608. {
  2609. $this->query["low"] = false;
  2610. $this->query["high"] = false;
  2611. }
  2612. $this->query["delayed"] = (bool)$delayed;
  2613. return $this;
  2614. }
  2615. /**
  2616. * add 'ignore' to insert query
  2617. * @param boolean $ignore
  2618. * @return mysqlClass_Insert
  2619. */
  2620. public function ignore($ignore = true)
  2621. {
  2622. $this->query["ignore"] = (bool)$ignore;
  2623. return $this;
  2624. }
  2625. /**
  2626. * add columns to insert query
  2627. * @param string|array $columns
  2628. * @return mysqlClass_Insert
  2629. */
  2630. public function columns($columns)
  2631. {
  2632. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2633. {
  2634. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2635. return $this;
  2636. }
  2637. if( func_num_args() == 1 && is_string($columns) && !in_array($columns, $this->query["columns"]) )
  2638. {
  2639. $this->query["columns"][] = $columns;
  2640. return $this;
  2641. }
  2642. foreach( func_get_args() as $column )
  2643. {
  2644. if( !is_array($column) && !in_array($column, $this->query["columns"]) )
  2645. {
  2646. $this->query["columns"][] = $column;
  2647. }
  2648. else
  2649. {
  2650. foreach( $column as $_column )
  2651. if( !in_array($_column, $this->query["columns"]) )
  2652. $this->query["columns"][] = $_column;
  2653. }
  2654. }
  2655. return $this;
  2656. }
  2657. /**
  2658. * alias of "columns"
  2659. * @param string|array $fields
  2660. * @return mysqlClass_Insert
  2661. */
  2662. public function fields($fields)
  2663. {
  2664. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2665. {
  2666. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2667. return $this;
  2668. }
  2669. if( func_num_args() == 1 && is_string($fields) && !in_array($fields, $this->query["columns"]) )
  2670. {
  2671. $this->query["columns"][] = $fields;
  2672. return $this;
  2673. }
  2674. return call_user_func_array(array($this, "columns"), func_get_args());
  2675. }
  2676. /**
  2677. * add 'values' to insert query
  2678. * @param string|array $values
  2679. * @return mysqlClass_Insert
  2680. */
  2681. public function values($values)
  2682. {
  2683. $columnCount = count($this->query["columns"]);
  2684. if( $columnCount == 0 )
  2685. {
  2686. $this->parent->createError(self::MESSAGE_BEFORE_VALUES);
  2687. return $this;
  2688. }
  2689. if( count($this->query["set"]) > 0 || !is_null($this->query["select"]) )
  2690. {
  2691. $this->parent->createError(self::MESSAGE_AFTER_FIELDS);
  2692. return $this;
  2693. }
  2694. if( func_num_args() == 1 && $columnCount == 1 && !is_array($values) )
  2695. {
  2696. $this->query["values"][] = array($values);
  2697. return $this;
  2698. }
  2699. // count params
  2700. $count = 0;
  2701. $values = array();
  2702. foreach( func_get_args() as $value )
  2703. {
  2704. if( !is_array($value) )
  2705. {
  2706. $count++;
  2707. $values[] = $this->parent->escape($value);
  2708. }
  2709. else
  2710. {
  2711. foreach( $value as $_key => $_value )
  2712. {
  2713. $count++;
  2714. if( is_numeric($_key) )
  2715. $values[] = $this->parent->escape($_value);
  2716. else
  2717. $values[$_key] = $this->parent->escape($_value);
  2718. }
  2719. }
  2720. }
  2721. // check if params count match fields
  2722. if( $count == $columnCount )
  2723. {
  2724. $this->query["values"][] = $values;
  2725. }
  2726. // check if fields names are in values
  2727. else if( $count > $columnCount )
  2728. {
  2729. $_values = array();
  2730. foreach( $this->query["columns"] as $column )
  2731. {
  2732. if( !isset($values[$column]) ) break;
  2733. $_values[] = $values[$column];
  2734. }
  2735. if( count($_values) == $columnCount )
  2736. $this->query["values"][] = $_values;
  2737. else
  2738. $this->parent->createError(self::MESSAGE_VALUES_MISSING);
  2739. }
  2740. // values doesn't match
  2741. else
  2742. {
  2743. $this->parent->createError(self::MESSAGE_VALUES_COUNT);
  2744. }
  2745. return $this;
  2746. }
  2747. /**
  2748. * add 'set' to insert query
  2749. * @param string|array $column
  2750. * @param string $replace
  2751. * @return mysqlClass_Insert
  2752. */
  2753. public function set($column, $replace = NULL)
  2754. {
  2755. if( count($this->query["columns"]) > 0 || !is_null($this->query["select"]) )
  2756. {
  2757. $this->parent->createError(self::MESSAGE_AFTER_SET);
  2758. return $this;
  2759. }
  2760. if( is_null($replace) )
  2761. {
  2762. if( is_array($column) )
  2763. {
  2764. foreach( $column as $_column => $_replace )
  2765. {
  2766. if( !is_numeric($_column) )
  2767. if( strpos($_column, "?") === false && strpos($column, "=") === false )
  2768. $this->query["set"][] = $_column . " = " . $this->parent->escape($_replace);
  2769. else
  2770. $this->query["set"][] = str_replace("?", $this->parent->escape($_replace), $_column);
  2771. else
  2772. $this->query["set"][] = $_replace;
  2773. }
  2774. }
  2775. else
  2776. {
  2777. $this->query["set"][] = $column;
  2778. }
  2779. }
  2780. else
  2781. {
  2782. if( strpos($column, "?") === false && strpos($column, "=") === false )
  2783. $this->query["set"][] = $column . " = " . $this->parent->escape($replace);
  2784. else
  2785. $this->query["set"][] = str_replace("?", $this->parent->escape($replace), $column);
  2786. }
  2787. return $this;
  2788. }
  2789. /**
  2790. * add a select statement to insert query
  2791. * @param string|mysqlClass_Select $subSelect
  2792. * @return mysqlClass_Insert
  2793. */
  2794. public function select($subSelect)
  2795. {
  2796. if( count($this->query["values"]) > 0 || count($this->query["set"]) > 0 )
  2797. {
  2798. $this->parent->createError(self::MESSAGE_AFTER_SELECT);
  2799. return $this;
  2800. }
  2801. if( is_string($subSelect) || $subSelect instanceof mysqlClass_Select )
  2802. {
  2803. $this->query["select"] = $subSelect;
  2804. }
  2805. return $this;
  2806. }
  2807. /*
  2808. ** build
  2809. */
  2810. /**
  2811. * build mysql insert query string
  2812. * @param integer $formatOffset
  2813. * @return string
  2814. */
  2815. public function build($formatOffset = 0)
  2816. {
  2817. $this->formatOffset += $formatOffset;
  2818. $offset = str_pad("", $this->formatOffset, " ");
  2819. // end if no table is set
  2820. if( is_null($this->query["table"]) ) return NULL;
  2821. $query = $this->format ? $offset . "REPLACE " : "REPLACE ";
  2822. // low priority
  2823. if( $this->query["low"] ) $query .= $this->format ? "\n" . $offset . " LOW_PRIORITY " : "LOW_PRIORITY ";
  2824. // delayed
  2825. if( $this->query["delayed"] ) $query .= $this->format ? "\n" . $offset . " DELAYED " : "DELAYED ";
  2826. // ignore
  2827. if( $this->query["ignore"] ) $query .= $this->format ? "\n" . $offset . " IGNORE \n" : "IGNORE ";
  2828. $query .= $this->format ? $offset . "INTO " : "INTO ";
  2829. // table
  2830. $query .= $this->format ? "\n" . $offset . " " . $this->query["table"] . "\n" : $this->query["table"] . " ";
  2831. // columns
  2832. if( !empty($this->query["columns"]) )
  2833. {
  2834. if( $this->format )
  2835. {
  2836. $query .= $offset . " (";
  2837. for( $i = 0; $i < count($this->query["columns"]); $i++ )
  2838. {
  2839. $query .= " " . $this->query["columns"][$i];
  2840. $query .= $i < count($this->query["columns"]) - 1 ? "," : NULL;
  2841. }
  2842. $query .= " ) \n";
  2843. }
  2844. else
  2845. $query .= "(" . join(",", $this->query["columns"]) . ") ";
  2846. if( !empty($this->query["values"]) )
  2847. {
  2848. $query .= $this->format ? "VALUES\n" : "VALUES ";
  2849. for( $i = 0; $i < count($this->query["values"]); $i++ )
  2850. {
  2851. if( $this->format )
  2852. {
  2853. $query .= $offset . " " . "( " . join(", ", $this->query["values"][$i]) . " )";
  2854. $query .= $i < count($this->query["values"]) - 1 ? ",\n" : NULL;
  2855. }
  2856. else
  2857. {
  2858. $query .= "(" . join(",", $this->query["values"][$i]) . ")";
  2859. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  2860. }
  2861. }
  2862. $query .= $this->format ? "\n" : " ";
  2863. }
  2864. }
  2865. // set
  2866. else if( !empty($this->query["set"]) )
  2867. {
  2868. $query .= $this->format ? "SET\n" : "SET ";
  2869. for( $i = 0; $i < count($this->query["set"]); $i++ )
  2870. {
  2871. if( $this->format )
  2872. {
  2873. $query .= $offset . " " . $this->query["set"][$i] . "";
  2874. $query .= $i < count($this->query["set"]) - 1 ? ", \n" : NULL;
  2875. }
  2876. else
  2877. {
  2878. $query .= "(" . join(",", $this->query["set"]) . ")";
  2879. $query .= $i < count($this->query["values"]) - 1 ? "," : NULL;
  2880. }
  2881. }
  2882. $query .= $this->format ? "\n" : " ";
  2883. }
  2884. // select
  2885. if( !is_null($this->query["select"]) )
  2886. {
  2887. if( is_string($this->query["select"]) )
  2888. {
  2889. if( $this->format )
  2890. $query .= $offset . " ( " . $this->query["select"] . " ) \n";
  2891. else
  2892. $query .= "(" . $this->query["select"] . ") ";
  2893. }
  2894. else
  2895. {
  2896. $select = $this->query["select"];
  2897. if( $select instanceof mysqlClass_Select )
  2898. {
  2899. if( $this->format )
  2900. $query .= $offset . " (" . trim($select->build($this->formatOffset + 4)) . ") \n";
  2901. else
  2902. $query .= "(" . $select->build() . ") ";
  2903. }
  2904. }
  2905. }
  2906. return $query;
  2907. }
  2908. }
  2909. /**
  2910. * Frosted MySQL Library Select Query Class
  2911. * - - - - - - - - - -
  2912. * Add "SELECT" functionality to Frosted MySQL Library and will not work without them.
  2913. * - - - - - - - - - -
  2914. * Licensed under MIT license
  2915. * - - - - - - - - - -
  2916. * @Creator Daniel 'Eisbehr' Kern
  2917. * @Require PHP5
  2918. * @Version 3.0
  2919. * @Date 01.08.2013
  2920. * @Update 01.08.2013
  2921. * - - - - - - - - - -
  2922. */
  2923. class mysqlClass_Select extends mysqlClass_Abstract implements mysqlClass_Queries
  2924. {
  2925. /**
  2926. * reset select class
  2927. * @param boolean $format
  2928. * @return mysqlClass_Select
  2929. */
  2930. public function resetQuery($format)
  2931. {
  2932. parent::resetQuery($format);
  2933. $this->query["all"] = false;
  2934. $this->query["distinct"] = false;
  2935. $this->query["row"] = false;
  2936. $this->query["high"] = false;
  2937. $this->query["straight"] = false;
  2938. $this->query["columns"] = array();
  2939. $this->query["from"] = array();
  2940. $this->query["join"] = array();
  2941. $this->query["where"] = array();
  2942. $this->query["group"] = array();
  2943. $this->query["rollup"] = false;
  2944. $this->query["having"] = array();
  2945. $this->query["order"] = array();
  2946. $this->query["limit"] = NULL;
  2947. $this->query["procedure"] = NULL;
  2948. $this->query["update"] = false;
  2949. $this->query["lock"] = false;
  2950. $this->query["union"] = NULL;
  2951. return $this;
  2952. }
  2953. /*
  2954. ** query related
  2955. */
  2956. /**
  2957. * add 'all' to query
  2958. * @param boolean $all
  2959. * @return mysqlClass_Select
  2960. */
  2961. public function all($all = true)
  2962. {
  2963. if( (bool)$all )
  2964. {
  2965. $this->query["distinct"] = false;
  2966. $this->query["row"] = false;
  2967. }
  2968. $this->query["all"] = (bool)$all;
  2969. return $this;
  2970. }
  2971. /**
  2972. * add 'distinct' to query
  2973. * @param boolean $distinct
  2974. * @return mysqlClass_Select
  2975. */
  2976. public function distinct($distinct = true)
  2977. {
  2978. if( (bool)$distinct )
  2979. {
  2980. $this->query["all"] = false;
  2981. $this->query["row"] = false;
  2982. }
  2983. $this->query["distinct"] = (bool)$distinct;
  2984. return $this;
  2985. }
  2986. /**
  2987. * add 'distinct row' to query
  2988. * @param boolean $distinctRow
  2989. * @return mysqlClass_Select
  2990. */
  2991. public function distinctRow($distinctRow = true)
  2992. {
  2993. if( (bool)$distinctRow )
  2994. {
  2995. $this->query["all"] = false;
  2996. $this->query["distinct"] = false;
  2997. }
  2998. $this->query["row"] = (bool)$distinctRow;
  2999. return $this;
  3000. }
  3001. /**
  3002. * add 'high priority' to query
  3003. * @param boolean $high
  3004. * @return mysqlClass_Select
  3005. */
  3006. public function highPriority($high = true)
  3007. {
  3008. $this->query["high"] = (bool)$high;
  3009. return $this;
  3010. }
  3011. /**
  3012. * add 'straight join' to query
  3013. * @param boolean $straightJoin
  3014. * @return mysqlClass_Select
  3015. */
  3016. public function straight($straightJoin = true)
  3017. {
  3018. $this->query["straight"] = (bool)$straightJoin;
  3019. return $this;
  3020. }
  3021. /**
  3022. * add columns to select
  3023. * @param string|array $column
  3024. * @return mysqlClass_Select
  3025. */
  3026. public function columns($column = "*")
  3027. {
  3028. // only one string is given
  3029. if( func_num_args() == 1 )
  3030. {
  3031. // string
  3032. if( is_string($column) )
  3033. {
  3034. $this->query["columns"][] = $column;
  3035. }
  3036. // array
  3037. else if( is_array($column) )
  3038. {
  3039. foreach( $column as $field => $name )
  3040. {
  3041. if( !is_numeric($field) )
  3042. {
  3043. if( $name instanceof mysqlClass_Select )
  3044. {
  3045. $this->query["columns"][] = array($name, $field);
  3046. }
  3047. else
  3048. $this->query["columns"][] = $field . " AS " . $name;
  3049. }
  3050. else
  3051. {
  3052. if( $name instanceof mysqlClass_Select )
  3053. $this->query["columns"][] = $name;
  3054. else
  3055. $this->columns($name);
  3056. }
  3057. }
  3058. }
  3059. // sub select
  3060. else if( $column instanceof mysqlClass_Select )
  3061. {
  3062. $this->query["columns"][] = $column;
  3063. }
  3064. return $this;
  3065. }
  3066. foreach( func_get_args() as $param )
  3067. {
  3068. if( is_string($param) )
  3069. $this->query["columns"][] = $param;
  3070. else
  3071. $this->columns($param);
  3072. }
  3073. return $this;
  3074. }
  3075. /**
  3076. * add 'from' to query
  3077. * @param string|array $table,...
  3078. * @return mysqlClass_Select
  3079. */
  3080. public function from($table)
  3081. {
  3082. // only one string is set
  3083. if( func_num_args() == 1 && is_string($table) )
  3084. {
  3085. $this->query["from"][] = $table;
  3086. return $this;
  3087. }
  3088. // add all tables to query
  3089. foreach( func_get_args() as $param )
  3090. {
  3091. if( !is_array($param) )
  3092. $this->query["from"][] = $param;
  3093. else
  3094. foreach( $param as $database => $name )
  3095. {
  3096. if( !is_numeric($database) )
  3097. $this->query["from"][] = $database . " AS " . $name;
  3098. else
  3099. $this->query["from"][] = $name;
  3100. }
  3101. }
  3102. return $this;
  3103. }
  3104. /**
  3105. * add join to query
  3106. * @param string $type
  3107. * @param array $tables
  3108. * @return mysqlClass_Select
  3109. */
  3110. private function addJoin($type, $tables)
  3111. {
  3112. $join = array("type" => $type, "tables" => array(), "on" => array(), "using" => array());
  3113. // format tables
  3114. foreach( $tables as $_tables )
  3115. if( is_array($_tables) )
  3116. foreach( $_tables as $table => $name )
  3117. if( !is_numeric($table) )
  3118. $join["tables"][] = $table . " AS " . $name;
  3119. else
  3120. $join["tables"][] = $name;
  3121. else
  3122. $join["tables"][] = $_tables;
  3123. // add join
  3124. $this->query["join"][] = $join;
  3125. return $this;
  3126. }
  3127. /**
  3128. * add 'join' to query
  3129. * @param string $table
  3130. * @return mysqlClass_Select
  3131. */
  3132. public function join($table)
  3133. {
  3134. // prevent php debug notification
  3135. if( $table );
  3136. return $this->addJoin("JOIN", func_get_args());
  3137. }
  3138. /**
  3139. * add 'join' to query
  3140. * @param string $table
  3141. * @return mysqlClass_Select
  3142. */
  3143. public function straightJoin($table)
  3144. {
  3145. // prevent php debug notification
  3146. if( $table );
  3147. return $this->addJoin("STRAIGHT_JOIN", func_get_args());
  3148. }
  3149. /**
  3150. * add 'left join' to query
  3151. * @param string $table
  3152. * @return mysqlClass_Select
  3153. */
  3154. public function leftJoin($table)
  3155. {
  3156. // prevent php debug notification
  3157. if( $table );
  3158. return $this->addJoin("LEFT JOIN", func_get_args());
  3159. }
  3160. /**
  3161. * add 'right join' to query
  3162. * @param string $table
  3163. * @return mysqlClass_Select
  3164. */
  3165. public function rightJoin($table)
  3166. {
  3167. // prevent php debug notification
  3168. if( $table );
  3169. return $this->addJoin("RIGHT JOIN", func_get_args());
  3170. }
  3171. /**
  3172. * add 'inner join' to query
  3173. * @param string $table
  3174. * @return mysqlClass_Select
  3175. */
  3176. public function innerJoin($table)
  3177. {
  3178. // prevent php debug notification
  3179. if( $table );
  3180. return $this->addJoin("INNER JOIN", func_get_args());
  3181. }
  3182. /**
  3183. * add 'cross join' to query
  3184. * @param string $table
  3185. * @return mysqlClass_Select
  3186. */
  3187. public function crossJoin($table)
  3188. {
  3189. // prevent php debug notification
  3190. if( $table );
  3191. return $this->addJoin("CROSS JOIN", func_get_args());
  3192. }
  3193. /**
  3194. * add 'left outer join' to query
  3195. * @param string $table
  3196. * @return mysqlClass_Select
  3197. */
  3198. public function leftOuterJoin($table)
  3199. {
  3200. // prevent php debug notification
  3201. if( $table );
  3202. return $this->addJoin("LEFT OUTER JOIN", func_get_args());
  3203. }
  3204. /**
  3205. * add 'right outer join' to query
  3206. * @param string $table
  3207. * @return mysqlClass_Select
  3208. */
  3209. public function rightOuterJoin($table)
  3210. {
  3211. // prevent php debug notification
  3212. if( $table );
  3213. return $this->addJoin("RIGHT OUTER JOIN", func_get_args());
  3214. }
  3215. /**
  3216. * add 'natural join' to query
  3217. * @param string $table
  3218. * @return mysqlClass_Select
  3219. */
  3220. public function naturalJoin($table)
  3221. {
  3222. // prevent php debug notification
  3223. if( $table );
  3224. return $this->addJoin("NATURAL JOIN", func_get_args());
  3225. }
  3226. /**
  3227. * add 'natural left join' to query
  3228. * @param string $table
  3229. * @return mysqlClass_Select
  3230. */
  3231. public function naturalLeftJoin($table)
  3232. {
  3233. // prevent php debug notification
  3234. if( $table );
  3235. return $this->addJoin("NATURAL LEFT JOIN", func_get_args());
  3236. }
  3237. /**
  3238. * add 'natural left outer join' to query
  3239. * @param string $table
  3240. * @return mysqlClass_Select
  3241. */
  3242. public function naturalLeftOuterJoin($table)
  3243. {
  3244. // prevent php debug notification
  3245. if( $table );
  3246. return $this->addJoin("NATURAL LEFT OUTER JOIN", func_get_args());
  3247. }
  3248. /**
  3249. * add 'natural right join' to query
  3250. * @param string $table
  3251. * @return mysqlClass_Select
  3252. */
  3253. public function naturalRightJoin($table)
  3254. {
  3255. // prevent php debug notification
  3256. if( $table );
  3257. return $this->addJoin("NATURAL RIGHT JOIN", func_get_args());
  3258. }
  3259. /**
  3260. * add 'natural right outer join' to query
  3261. * @param string $table
  3262. * @return mysqlClass_Select
  3263. */
  3264. public function naturalRightOuterJoin($table)
  3265. {
  3266. // prevent php debug notification
  3267. if( $table );
  3268. return $this->addJoin("NATURAL RIGHT OUTER JOIN", func_get_args());
  3269. }
  3270. /**
  3271. * add 'on' to last join in query
  3272. * @param string $on
  3273. * @param string $replace
  3274. * @param boolean $nextRelation
  3275. * @return mysqlClass_Select
  3276. */
  3277. public function on($on, $replace = NULL, $nextRelation = mysqlClass::JOIN_AND)
  3278. {
  3279. $last = count($this->query["join"]) - 1;
  3280. if( $last >= 0 )
  3281. {
  3282. if( $replace != NULL )
  3283. {
  3284. $this->query["join"][$last]["on"][] = str_replace("?", $this->parent->escape($replace), $on);
  3285. $this->query["join"][$last]["on"][] = $nextRelation == mysqlClass::JOIN_OR ? mysqlClass::JOIN_OR : mysqlClass::JOIN_AND;
  3286. }
  3287. else
  3288. {
  3289. $this->query["join"][$last]["on"][] = $on;
  3290. $this->query["join"][$last]["on"][] = $nextRelation == mysqlClass::JOIN_OR ? mysqlClass::JOIN_OR : mysqlClass::JOIN_AND;
  3291. }
  3292. }
  3293. return $this;
  3294. }
  3295. /**
  3296. * add or related 'on' to last join in query
  3297. * @param string $on
  3298. * @param string $replace
  3299. * @param boolean $nextRelation
  3300. * @return mysqlClass_Select
  3301. */
  3302. public function orOn($on, $replace = NULL, $nextRelation = mysqlClass::JOIN_AND)
  3303. {
  3304. $last = count($this->query["join"]) - 1;
  3305. if( $last >= 0 )
  3306. {
  3307. $lastOn = count($this->query["join"][$last]["on"]) - 1;
  3308. if( $lastOn >= 0 )
  3309. $this->query["join"][$last]["on"][$lastOn] = mysqlClass::JOIN_OR;
  3310. }
  3311. return $this->on($on, $replace, $nextRelation);
  3312. }
  3313. /**
  3314. * add 'using' to last join in query
  3315. * @param string $column
  3316. * @return mysqlClass_Select
  3317. */
  3318. public function using($column)
  3319. {
  3320. // prevent php debug notification
  3321. if( $column );
  3322. // get last join id
  3323. $last = count($this->query["join"]) - 1;
  3324. if( $last >= 0 )
  3325. foreach( func_get_args() as $columns )
  3326. if( is_array($columns) )
  3327. {
  3328. foreach( $columns as $column )
  3329. if( !in_array($column, $this->query["join"][$last]["using"]) )
  3330. $this->query["join"][$last]["using"][] = $column;
  3331. }
  3332. else
  3333. {
  3334. if( !in_array($columns, $this->query["join"][$last]["using"]) )
  3335. $this->query["join"][$last]["using"][] = $columns;
  3336. }
  3337. return $this;
  3338. }
  3339. /**
  3340. * add 'where' to query
  3341. * @param string $condition
  3342. * @param string $replace
  3343. * @param string $nextRelation
  3344. * @return mysqlClass_Select
  3345. */
  3346. public function where($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  3347. {
  3348. // add condition
  3349. if( !is_null($replace) )
  3350. {
  3351. if( is_array($replace) )
  3352. {
  3353. // escape all values
  3354. foreach( $replace as &$value ) $value = $this->parent->escape($value);
  3355. // format sub-query
  3356. if( $this->format )
  3357. {
  3358. $condition = str_replace("ANY(?)", "\nANY\n(\n ?\n)", $condition);
  3359. $condition = str_replace("IN(?)", "\nIN\n(\n ?\n)", $condition);
  3360. $condition = str_replace("SOME(?)", "\nSOME\n(\n ?\n)", $condition);
  3361. }
  3362. $glue = $this->format ? ",\n " : ",";
  3363. $this->query["where"][] = str_replace("?", join($glue, $replace), $condition);
  3364. }
  3365. else if( $replace instanceof mysqlClass_Select )
  3366. $this->query["where"][] = array($condition, $replace);
  3367. else
  3368. $this->query["where"][] = str_replace("?", $this->parent->escape($replace), $condition);
  3369. }
  3370. else
  3371. $this->query["where"][] = $condition;
  3372. // add relation
  3373. if( strtoupper($nextRelation) == mysqlClass::WHERE_OR )
  3374. $this->query["where"][] = mysqlClass::WHERE_OR;
  3375. else
  3376. $this->query["where"][] = mysqlClass::WHERE_AND;
  3377. return $this;
  3378. }
  3379. /**
  3380. * add 'or' related 'where' to query
  3381. * @param string $condition
  3382. * @param string $replace
  3383. * @param string $nextRelation
  3384. * @return mysqlClass_Select
  3385. */
  3386. public function orWhere($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  3387. {
  3388. if( !empty($this->query["where"]) )
  3389. $this->query["where"][(count($this->query["where"]) - 1)] = mysqlClass::WHERE_OR;
  3390. return $this->where($condition, $replace, $nextRelation);
  3391. }
  3392. /**
  3393. * add 'group by' to query
  3394. * @param string $field
  3395. * @param string $order
  3396. * @return mysqlClass_Select
  3397. */
  3398. public function groupBy($field, $order = mysqlClass::GROUP_ASC)
  3399. {
  3400. if( strtoupper($order) == mysqlClass::GROUP_DESC )
  3401. $this->query["group"][] = $field . " " . mysqlClass::GROUP_DESC;
  3402. else
  3403. $this->query["group"][] = $field . " " . mysqlClass::GROUP_ASC;
  3404. return $this;
  3405. }
  3406. /**
  3407. * alias of 'groupBy'
  3408. * @param string $field
  3409. * @param string $order
  3410. * @return mysqlClass_Select
  3411. */
  3412. public function group($field, $order = mysqlClass::GROUP_ASC)
  3413. {
  3414. return $this->groupBy($field, $order);
  3415. }
  3416. /**
  3417. * add 'with rollup' to query
  3418. * @param boolean $rollup
  3419. * @return mysqlClass_Select
  3420. */
  3421. public function withRollup($rollup = true)
  3422. {
  3423. $this->query["rollup"] = (bool)$rollup;
  3424. return $this;
  3425. }
  3426. /**
  3427. * add 'having' to group
  3428. * @param string $condition
  3429. * @param string $replace
  3430. * @param string $nextRelation
  3431. * @return mysqlClass_Select
  3432. */
  3433. public function having($condition, $replace = NULL, $nextRelation = mysqlClass::HAVING_AND)
  3434. {
  3435. // add condition
  3436. if( !is_null($replace) )
  3437. {
  3438. if( is_array($replace) )
  3439. {
  3440. foreach( $replace as &$value )
  3441. $value = $this->parent->escape($value);
  3442. if( $this->format )
  3443. $condition = str_replace("IN(?)", "\nIN\n(\n ?\n)", $condition);
  3444. $glue = $this->format ? ",\n " : ",";
  3445. $this->query["having"][] = str_replace("?", join($glue, $replace), $condition);
  3446. }
  3447. else if( $replace instanceof mysqlClass_Select )
  3448. {
  3449. $this->query["having"][] = array($condition, $replace);
  3450. }
  3451. else
  3452. $this->query["having"][] = str_replace("?", $this->parent->escape($replace), $condition);
  3453. }
  3454. else
  3455. $this->query["having"][] = $condition;
  3456. // add relation
  3457. if( strtoupper($nextRelation) == mysqlClass::HAVING_OR )
  3458. $this->query["having"][] = mysqlClass::HAVING_OR;
  3459. else
  3460. $this->query["having"][] = mysqlClass::HAVING_AND;
  3461. return $this;
  3462. }
  3463. /**
  3464. * add to previous 'or' related 'having' to query
  3465. * @param string $condition
  3466. * @param string $replace
  3467. * @return mysqlClass_Select
  3468. */
  3469. public function orHaving($condition, $replace = NULL)
  3470. {
  3471. if( !empty($this->query["having"]) )
  3472. {
  3473. $this->query["having"][(count($this->query["having"]) - 1)] = mysqlClass::HAVING_OR;
  3474. }
  3475. return $this->having($condition, $replace, mysqlClass::HAVING_AND);
  3476. }
  3477. /**
  3478. * add 'order' to query
  3479. * @param string $field
  3480. * @param string $order
  3481. * @return mysqlClass_Select
  3482. */
  3483. public function orderBy($field, $order = mysqlClass::ORDER_ASC)
  3484. {
  3485. if( strtoupper($order) == mysqlClass::ORDER_DESC )
  3486. $this->query["order"][] = $field . " " . mysqlClass::ORDER_DESC;
  3487. else
  3488. $this->query["order"][] = $field . " " . mysqlClass::ORDER_ASC;
  3489. return $this;
  3490. }
  3491. /**
  3492. * alias of 'orderBy'
  3493. * @param string $field
  3494. * @param string $order
  3495. * @return mysqlClass_Select
  3496. */
  3497. public function order($field, $order = mysqlClass::ORDER_ASC)
  3498. {
  3499. return $this->orderBy($field, $order);
  3500. }
  3501. /**
  3502. * add 'limit' to query
  3503. * @param integer $limit
  3504. * @param integer $offset
  3505. * @return mysqlClass_Select
  3506. */
  3507. public function limit($limit, $offset = NULL)
  3508. {
  3509. $this->query["limit"] = $limit;
  3510. if( !is_null($offset) && is_numeric($offset) )
  3511. {
  3512. $this->query["limit"] = $offset . ", " . $limit;
  3513. }
  3514. return $this;
  3515. }
  3516. /**
  3517. * add 'procedure' to query
  3518. * @param string $procedure
  3519. * @param string|array $arguments
  3520. * @return mysqlClass_Select
  3521. */
  3522. public function procedure($procedure, $arguments = array())
  3523. {
  3524. // prevent php debug notification
  3525. if( $arguments );
  3526. if( func_num_args() == 1 )
  3527. {
  3528. $this->query["procedure"] = $procedure;
  3529. }
  3530. else if( func_num_args() == 2 )
  3531. {
  3532. if( is_array($arguments) )
  3533. $this->query["procedure"] = $procedure . "(" . join(",", $arguments) . ")";
  3534. else
  3535. $this->query["procedure"] = $procedure . "(" . $arguments . ")";
  3536. }
  3537. else if( func_num_args() >= 2 )
  3538. {
  3539. $arguments = func_get_args();
  3540. $procedure = array_shift($arguments);
  3541. $list = array();
  3542. foreach( $arguments as $argument )
  3543. {
  3544. if( is_array($argument) )
  3545. $list = array_merge($list, $argument);
  3546. else
  3547. $list[] = $argument;
  3548. }
  3549. $this->query["procedure"] = $procedure . "(" . join(",", $list) . ")";
  3550. }
  3551. return $this;
  3552. }
  3553. /**
  3554. * add 'with rollup' to query
  3555. * @param boolean $update
  3556. * @return mysqlClass_Select
  3557. */
  3558. public function forUpdate($update = true)
  3559. {
  3560. if( (bool)$update )
  3561. {
  3562. $this->query["lock"] = false;
  3563. }
  3564. $this->query["update"] = (bool)$update;
  3565. return $this;
  3566. }
  3567. /**
  3568. * add 'with rollup' to query
  3569. * @param boolean $lock
  3570. * @return mysqlClass_Select
  3571. */
  3572. public function lockInShareMode($lock = true)
  3573. {
  3574. if( (bool)$lock )
  3575. {
  3576. $this->query["update"] = false;
  3577. }
  3578. $this->query["lock"] = (bool)$lock;
  3579. return $this;
  3580. }
  3581. /**
  3582. * add a union select to query
  3583. * @param mysqlClass_Select|string $select
  3584. * @return mysqlClass_Select
  3585. */
  3586. public function union($select)
  3587. {
  3588. $this->query["union"] = $select;
  3589. return $this;
  3590. }
  3591. /*
  3592. ** build
  3593. */
  3594. /**
  3595. * build mysql select query string
  3596. * @param integer $formatOffset
  3597. * @return string
  3598. */
  3599. public function build($formatOffset = 0)
  3600. {
  3601. $this->formatOffset += $formatOffset;
  3602. $offset = str_pad("", $this->formatOffset, " ");
  3603. // end if no table is set
  3604. if( empty($this->query["from"]) ) return NULL;
  3605. $query = $this->format ? $offset . "SELECT " : "SELECT ";
  3606. // all
  3607. if( $this->query["all"] ) $query .= $this->format ? "\n" . $offset . " ALL " : "ALL ";
  3608. // distinct
  3609. if( $this->query["distinct"] ) $query .= $this->format ? "\n" . $offset . " DISTINCT " : "DISTINCT ";
  3610. // distinct row
  3611. if( $this->query["row"] ) $query .= $this->format ? "\n" . $offset . " DISTINCTROW " : "DISTINCTROW ";
  3612. // high priority
  3613. if( $this->query["high"] ) $query .= $this->format ? "\n" . $offset . " HIGH_PRIORITY " : "HIGH_PRIORITY ";
  3614. // straight
  3615. if( $this->query["straight"] ) $query .= $this->format ? "\n" . $offset . " STRAIGHT_JOIN " : "STRAIGHT_JOIN ";
  3616. $query .= $this->format ? $offset . "\n" : NULL;
  3617. // columns
  3618. if( !empty($this->query["columns"]) )
  3619. {
  3620. if( $this->format )
  3621. {
  3622. for( $i = 0; $i < count($this->query["columns"]); $i++ )
  3623. {
  3624. $value = $this->query["columns"][$i];
  3625. if( is_array($value) )
  3626. {
  3627. if( $value[0] instanceof mysqlClass_Select )
  3628. {
  3629. $value[0] = $value[0]->build($this->formatOffset + 4);
  3630. $value[0] = trim($value[0]);
  3631. }
  3632. $this->query["columns"][$i] = "(" . $value[0] . ") AS " . $value[1];
  3633. }
  3634. else if( $value instanceof mysqlClass_Select )
  3635. {
  3636. $this->query["columns"][$i] = "(" . $value->build($this->formatOffset + 4) . ")";
  3637. }
  3638. $query .= $offset . " " . $this->query["columns"][$i];
  3639. $query .= $i < count($this->query["columns"]) - 1 ? "," : NULL;
  3640. $query .= " \n";
  3641. }
  3642. }
  3643. else
  3644. {
  3645. for( $i = 0; $i < count($this->query["columns"]); $i++ )
  3646. {
  3647. if( is_array($this->query["columns"][$i]) )
  3648. {
  3649. $select = $this->query["columns"][$i][0];
  3650. if( $select instanceof mysqlClass_Select )
  3651. $select = $select->build();
  3652. $this->query["columns"][$i] = "(" . $select . ") AS " . $this->query["columns"][$i][1];
  3653. }
  3654. else if( $this->query["columns"][$i] instanceof mysqlClass_Select )
  3655. {
  3656. $select = $this->query["columns"][$i];
  3657. if( $select instanceof mysqlClass_Select )
  3658. $select = $select->build();
  3659. $this->query["columns"][$i] = "(" . $select . ")";
  3660. }
  3661. }
  3662. $query .= join(",", $this->query["columns"]) . " ";
  3663. }
  3664. }
  3665. else
  3666. {
  3667. $query .= $this->format ? $offset . " *\n" : "* ";
  3668. }
  3669. // from
  3670. if( !empty($this->query["from"]) )
  3671. {
  3672. if( $this->format )
  3673. {
  3674. $query .= $offset . "FROM \n";
  3675. for( $i = 0; $i < count($this->query["from"]); $i++ )
  3676. {
  3677. $query .= $offset . " " . $this->query["from"][$i];
  3678. $query .= $i < count($this->query["from"]) - 1 ? "," : NULL;
  3679. $query .= " \n";
  3680. }
  3681. }
  3682. else
  3683. {
  3684. $query .= "FROM " . join(",", $this->query["from"]) . " ";
  3685. }
  3686. }
  3687. // join
  3688. if( !empty($this->query["join"]) )
  3689. {
  3690. foreach( $this->query["join"] as $join )
  3691. {
  3692. $query .= $this->format ? $offset . $join["type"] . "\n" : $join["type"] . " ";
  3693. if( $this->format )
  3694. {
  3695. for( $i = 0; $i < count($join["tables"]); $i++ )
  3696. {
  3697. $query .= $offset . " " . $join["tables"][$i];
  3698. $query .= $i < count($join["tables"]) - 1 ? "," : NULL;
  3699. $query .= " \n";
  3700. }
  3701. if( !empty($join["on"]) )
  3702. {
  3703. $query .= $offset . "ON\n";
  3704. for( $i = 0; $i < count($join["on"]); $i = $i + 2 )
  3705. {
  3706. $query .= $offset . " " . $join["on"][$i];
  3707. $query .= $i < count($join["on"]) - 2 ? " \n" . $offset . $join["on"][$i + 1] . " " : NULL;
  3708. $query .= " \n";
  3709. }
  3710. }
  3711. else if( !empty($join["using"]) )
  3712. {
  3713. $query .= $offset . "USING\n";
  3714. $query .= $offset . "(\n";
  3715. for( $i = 0; $i < count($join["using"]); $i++ )
  3716. {
  3717. $query .= $offset . " " . $join["using"][$i];
  3718. $query .= $i < count($join["using"]) - 1 ? "," : NULL;
  3719. $query .= " \n";
  3720. }
  3721. $query .= $offset . ")\n";
  3722. }
  3723. }
  3724. else
  3725. {
  3726. // tables
  3727. $query .= join(",", $join["tables"]) . " ";
  3728. // on
  3729. if( !empty($join["on"]) )
  3730. {
  3731. $on = array_slice($join["on"], 0, -1);
  3732. $query .= "ON " . join(" ", $on) . " ";
  3733. }
  3734. // using
  3735. else
  3736. $query .= "USING (" . join(",", $join["using"]) . ") ";
  3737. }
  3738. }
  3739. }
  3740. // where
  3741. if( !empty($this->query["where"]) )
  3742. {
  3743. if( $this->format )
  3744. {
  3745. $query .= $offset . "WHERE \n";
  3746. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  3747. {
  3748. if( is_array($this->query["where"][$i]) )
  3749. {
  3750. $select = $this->query["where"][$i][1];
  3751. if( $select instanceof mysqlClass_Select )
  3752. {
  3753. $select = $select->build($this->formatOffset + 4);
  3754. $select = trim($select);
  3755. }
  3756. $query .= $offset . " " . str_replace("?", "\n" . $offset . " (" . $select . ")", $this->query["where"][$i][0]);
  3757. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  3758. $query .= " \n";
  3759. }
  3760. else
  3761. {
  3762. $query .= $offset . " " . $this->query["where"][$i];
  3763. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  3764. $query .= " \n";
  3765. }
  3766. }
  3767. }
  3768. else
  3769. {
  3770. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  3771. {
  3772. if( is_array($this->query["where"][$i]) )
  3773. {
  3774. $select = $this->query["where"][$i][1];
  3775. if( $select instanceof mysqlClass_Select )
  3776. $select = $select->build();
  3777. $this->query["where"][$i] = str_replace("?", "(" . $select . ")", $this->query["where"][$i][0]);
  3778. }
  3779. }
  3780. $where = array_slice($this->query["where"], 0, -1);
  3781. $query .= "WHERE " . join(" ", $where) . " ";
  3782. }
  3783. }
  3784. // group by
  3785. if( !empty($this->query["group"]) )
  3786. {
  3787. if( $this->format )
  3788. {
  3789. $query .= $offset . "GROUP BY \n";
  3790. for( $i = 0; $i < count($this->query["group"]); $i++ )
  3791. {
  3792. $query .= $offset . " " . $this->query["group"][$i];
  3793. $query .= $i < count($this->query["group"]) - 1 ? "," : NULL;
  3794. $query .= " \n";
  3795. }
  3796. }
  3797. else
  3798. {
  3799. $query .= "GROUP BY " . join(",", $this->query["group"]) . " ";
  3800. }
  3801. // rollup
  3802. if( $this->query["rollup"] )
  3803. $query .= $this->format ? "WITH ROLLUP \n" : "WITH ROLLUP ";
  3804. // having
  3805. if( !empty($this->query["having"]) )
  3806. {
  3807. if( $this->format )
  3808. {
  3809. $query .= $offset . "HAVING \n";
  3810. for( $i = 0; $i < count($this->query["having"]); $i = $i + 2 )
  3811. {
  3812. if( is_array($this->query["having"][$i]) )
  3813. {
  3814. $select = $this->query["having"][$i][1];
  3815. if( $select instanceof mysqlClass_Select )
  3816. {
  3817. $select = $select->build($this->formatOffset + 4);
  3818. $select = trim($select);
  3819. }
  3820. $query .= $offset . " " . str_replace("?", "\n" . $offset . " (" . $select . ")", $this->query["having"][$i][0]);
  3821. $query .= $i < count($this->query["having"]) - 2 ? " \n" . $this->query["having"][$i + 1] . " " : NULL;
  3822. $query .= " \n";
  3823. }
  3824. else
  3825. {
  3826. $query .= $offset . " " . $this->query["having"][$i];
  3827. $query .= $i < count($this->query["having"]) - 2 ? " \n" . $this->query["having"][$i + 1] . " " : NULL;
  3828. $query .= " \n";
  3829. }
  3830. }
  3831. }
  3832. else
  3833. {
  3834. for( $i = 0; $i < count($this->query["having"]); $i = $i + 2 )
  3835. {
  3836. if( is_array($this->query["having"][$i]) )
  3837. {
  3838. $select = $this->query["having"][$i][1];
  3839. if( $select instanceof mysqlClass_Select )
  3840. $select = $select->build();
  3841. $this->query["having"][$i] = str_replace("?", "(" . $select . ")", $this->query["having"][$i][0]);
  3842. $this->query["having"][$i] .= $i < count($this->query["having"]) - 2 ? " " . $this->query["having"][$i + 1] . " " : NULL;
  3843. }
  3844. }
  3845. $having = array_slice($this->query["having"], 0, -1);
  3846. $query .= "HAVING " . join(" ", $having) . " ";
  3847. }
  3848. }
  3849. }
  3850. // order
  3851. if( !empty($this->query["order"]) )
  3852. {
  3853. if( $this->format )
  3854. {
  3855. $query .= $offset . "ORDER BY \n";
  3856. for( $i = 0; $i < count($this->query["order"]); $i++ )
  3857. {
  3858. $query .= $offset . " " . $this->query["order"][$i];
  3859. $query .= $i < count($this->query["order"]) - 1 ? "," : NULL;
  3860. $query .= " \n";
  3861. }
  3862. }
  3863. else
  3864. {
  3865. $query .= "ORDER BY " . join(",", $this->query["order"]) . " ";
  3866. }
  3867. }
  3868. // limit
  3869. if( !empty($this->query["limit"]) )
  3870. {
  3871. if( $this->format )
  3872. $query .= $offset . "LIMIT \n" . $offset . " " . $this->query["limit"] . "\n";
  3873. else
  3874. $query .= "LIMIT " . $this->query["limit"] . " ";
  3875. }
  3876. // procedure
  3877. if( !empty($this->query["procedure"]) )
  3878. {
  3879. if( $this->format )
  3880. $query .= $offset . "PROCEDURE \n" . $offset . " " . $this->query["procedure"] . " ";
  3881. else
  3882. $query .= "PROCEDURE " . $this->query["procedure"] . " ";
  3883. }
  3884. // for update
  3885. if( $this->query["update"] )
  3886. $query .= $this->format ? $offset . "FOR UPDATE \n" : "FOR UPDATE ";
  3887. // lock in share mode
  3888. if( $this->query["lock"] )
  3889. $query .= $this->format ? $offset . "LOCK IN SHARE MODE \n" : "LOCK IN SHARE MODE ";
  3890. // union
  3891. if( !is_null($this->query["union"]) )
  3892. {
  3893. $select = $this->query["union"];
  3894. if( is_string($select) )
  3895. if( $this->format )
  3896. $query = "(" . $query. ") \nUNION \n(\n" . trim($select) . ")";
  3897. else
  3898. $query = "(" . $query. ") UNION (" . $select . ")";
  3899. if( $select instanceof mysqlClass_Select )
  3900. if( $this->format )
  3901. $query = "(" . $query. ") \nUNION \n(\n" . trim($select->build()) . ")";
  3902. else
  3903. $query = "(" . $query. ") UNION (" . $select->build() . ")";
  3904. }
  3905. return $query;
  3906. }
  3907. }
  3908. /**
  3909. * Frosted MySQL Library Truncate Query Class
  3910. * - - - - - - - - - -
  3911. * Add "TRUNCATE" functionality to Frosted MySQL Library and will not work without them.
  3912. * - - - - - - - - - -
  3913. * Licensed under MIT license
  3914. * - - - - - - - - - -
  3915. * @Creator Daniel 'Eisbehr' Kern
  3916. * @Require PHP5
  3917. * @Version 3.0
  3918. * @Date 01.08.2013
  3919. * @Update 01.08.2013
  3920. * - - - - - - - - - -
  3921. */
  3922. class mysqlClass_Truncate extends mysqlClass_Abstract implements mysqlClass_Queries
  3923. {
  3924. /**
  3925. * reset update class
  3926. * @param boolean $format
  3927. * @return mysqlClass_Truncate
  3928. */
  3929. public function resetQuery($format)
  3930. {
  3931. parent::resetQuery($format);
  3932. $this->query["table"] = NULL;
  3933. return $this;
  3934. }
  3935. /*
  3936. ** query related
  3937. */
  3938. /**
  3939. * add tables to query
  3940. * @param string|array $table
  3941. * @return mysqlClass_Truncate
  3942. */
  3943. public function table($table)
  3944. {
  3945. if( !is_array($table) )
  3946. $this->query["table"] = $table;
  3947. else
  3948. foreach( $table as $database => $name )
  3949. {
  3950. if( !is_numeric($database) )
  3951. $this->query["table"] = $database;
  3952. else
  3953. $this->query["table"] = $name;
  3954. }
  3955. return $this;
  3956. }
  3957. /*
  3958. ** build
  3959. */
  3960. /**
  3961. * build mysql update query string
  3962. * @param integer $formatOffset
  3963. * @return string
  3964. */
  3965. public function build($formatOffset = 0)
  3966. {
  3967. // end if no table is set
  3968. if( empty($this->query["table"]) ) return NULL;
  3969. if( $this->format )
  3970. {
  3971. $this->formatOffset += $formatOffset;
  3972. $offset = str_pad("", $this->formatOffset, " ");
  3973. return "TRUNCATE TABLE\n" . $offset . " " . $this->query["table"];
  3974. }
  3975. return "TRUNCATE TABLE " . $this->query["table"];
  3976. }
  3977. }
  3978. /**
  3979. * Frosted MySQL Library Update Query Class
  3980. * - - - - - - - - - -
  3981. * Add "UPDATE" functionality to Frosted MySQL Library and will not work without them.
  3982. * - - - - - - - - - -
  3983. * Licensed under MIT license
  3984. * - - - - - - - - - -
  3985. * @Creator Daniel 'Eisbehr' Kern
  3986. * @Require PHP5
  3987. * @Version 3.0
  3988. * @Date 01.08.2013
  3989. * @Update 01.08.2013
  3990. * - - - - - - - - - -
  3991. */
  3992. class mysqlClass_Update extends mysqlClass_Abstract implements mysqlClass_Queries
  3993. {
  3994. /**
  3995. * update error messages
  3996. * @var string
  3997. */
  3998. const MESSAGE_ORDER = "you cannot use 'order' if you update more than one table";
  3999. const MESSAGE_LIMIT = "you cannot use 'limit' if you update more than one table";
  4000. /*
  4001. ** public
  4002. */
  4003. /**
  4004. * reset update class
  4005. * @param boolean $format
  4006. * @return mysqlClass_Update
  4007. */
  4008. public function resetQuery($format)
  4009. {
  4010. parent::resetQuery($format);
  4011. $this->query["tables"] = array();
  4012. $this->query["low"] = false;
  4013. $this->query["ignore"] = false;
  4014. $this->query["set"] = array();
  4015. $this->query["where"] = array();
  4016. $this->query["order"] = array();
  4017. $this->query["limit"] = NULL;
  4018. return $this;
  4019. }
  4020. /*
  4021. ** query related
  4022. */
  4023. /**
  4024. * add 'low priority' to query
  4025. * @param boolean $low
  4026. * @return mysqlClass_Update
  4027. */
  4028. public function lowPriority($low = true)
  4029. {
  4030. $this->query["low"] = (bool)$low;
  4031. return $this;
  4032. }
  4033. /**
  4034. * add 'ignore' to query
  4035. * @param boolean $ignore
  4036. * @return mysqlClass_Update
  4037. */
  4038. public function ignore($ignore = true)
  4039. {
  4040. $this->query["ignore"] = (bool)$ignore;
  4041. return $this;
  4042. }
  4043. /**
  4044. * add tables to query
  4045. * @param string|array $table
  4046. * @return mysqlClass_Update
  4047. */
  4048. public function table($table)
  4049. {
  4050. // only one string is set
  4051. if( func_num_args() == 1 && is_string($table) )
  4052. {
  4053. $this->query["tables"][] = $table;
  4054. return $this;
  4055. }
  4056. // add all tables to query
  4057. foreach( func_get_args() as $param )
  4058. {
  4059. if( !is_array($param) )
  4060. $this->query["tables"][] = $param;
  4061. else
  4062. foreach( $param as $database => $name )
  4063. {
  4064. if( !is_numeric($database) )
  4065. $this->query["tables"][] = $database . " AS " . $name;
  4066. else
  4067. $this->query["tables"][] = $name;
  4068. }
  4069. }
  4070. return $this;
  4071. }
  4072. /**
  4073. * add 'set' to query
  4074. * @param string|array $column
  4075. * @param string $replace
  4076. * @return mysqlClass_Update
  4077. */
  4078. public function set($column, $replace = NULL)
  4079. {
  4080. if( is_null($replace) )
  4081. {
  4082. if( is_array($column) )
  4083. {
  4084. foreach( $column as $_column => $_replace )
  4085. {
  4086. if( !is_numeric($_column) )
  4087. $this->query["set"][] = str_replace("?", $this->parent->escape($_replace), $_column);
  4088. else
  4089. $this->query["set"][] = $_replace;
  4090. }
  4091. }
  4092. else
  4093. {
  4094. $this->query["set"][] = $column;
  4095. }
  4096. }
  4097. else
  4098. {
  4099. $this->query["set"][] = str_replace("?", $this->parent->escape($replace), $column);
  4100. }
  4101. return $this;
  4102. }
  4103. /**
  4104. * add 'where' to query
  4105. * @param string $condition
  4106. * @param string $replace
  4107. * @param string $nextRelation
  4108. * @return mysqlClass_Update
  4109. */
  4110. public function where($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  4111. {
  4112. // add condition
  4113. if( !is_null($replace) )
  4114. {
  4115. if( is_array($replace) )
  4116. {
  4117. // escape all values
  4118. foreach( $replace as &$value ) $value = $this->parent->escape($value);
  4119. // format sub-query
  4120. if( $this->format )
  4121. {
  4122. $condition = str_replace("ANY(?)", "\nANY\n(\n ?\n)", $condition);
  4123. $condition = str_replace("IN(?)", "\nIN\n(\n ?\n)", $condition);
  4124. $condition = str_replace("SOME(?)", "\nSOME\n(\n ?\n)", $condition);
  4125. }
  4126. $glue = $this->format ? ",\n " : ",";
  4127. $this->query["where"][] = str_replace("?", join($glue, $replace), $condition);
  4128. }
  4129. else if( $replace instanceof mysqlClass_Select )
  4130. $this->query["where"][] = array($condition, $replace);
  4131. else
  4132. $this->query["where"][] = str_replace("?", $this->parent->escape($replace), $condition);
  4133. }
  4134. else
  4135. $this->query["where"][] = $condition;
  4136. // add next relation
  4137. if( strtoupper($nextRelation) == mysqlClass::WHERE_OR )
  4138. $this->query["where"][] = mysqlClass::WHERE_OR;
  4139. else
  4140. $this->query["where"][] = mysqlClass::WHERE_AND;
  4141. return $this;
  4142. }
  4143. /**
  4144. * add 'or' related 'where' to query
  4145. * @param string $condition
  4146. * @param string $replace
  4147. * @param string $nextRelation
  4148. * @return mysqlClass_Update
  4149. */
  4150. public function orWhere($condition, $replace = NULL, $nextRelation = mysqlClass::WHERE_AND)
  4151. {
  4152. if( !empty($this->query["where"]) )
  4153. $this->query["where"][(count($this->query["where"]) - 1)] = mysqlClass::WHERE_OR;
  4154. return $this->where($condition, $replace, $nextRelation);
  4155. }
  4156. /**
  4157. * add 'order' to query
  4158. * @param string $field
  4159. * @param string $order
  4160. * @return mysqlClass_Update
  4161. */
  4162. public function orderBy($field, $order = mysqlClass::ORDER_ASC)
  4163. {
  4164. if( count($this->query["tables"]) >= 2 )
  4165. {
  4166. $this->parent->createError(self::MESSAGE_ORDER);
  4167. return $this;
  4168. }
  4169. if( strtoupper($order) == mysqlClass::ORDER_DESC )
  4170. $this->query["order"][] = $field . " " . mysqlClass::ORDER_DESC;
  4171. else
  4172. $this->query["order"][] = $field . " " . mysqlClass::ORDER_ASC;
  4173. return $this;
  4174. }
  4175. /**
  4176. * alias of 'orderBy'
  4177. * @param string $field
  4178. * @param string $order
  4179. * @return mysqlClass_Update
  4180. */
  4181. public function order($field, $order = mysqlClass::ORDER_ASC)
  4182. {
  4183. return $this->orderBy($field, $order);
  4184. }
  4185. /**
  4186. * add 'limit' to query
  4187. * @param integer $limit
  4188. * @return mysqlClass_Update
  4189. */
  4190. public function limit($limit)
  4191. {
  4192. if( count($this->query["tables"]) >= 2 )
  4193. {
  4194. $this->parent->createError(self::MESSAGE_LIMIT);
  4195. return $this;
  4196. }
  4197. $this->query["limit"] = $limit;
  4198. return $this;
  4199. }
  4200. /*
  4201. ** build
  4202. */
  4203. /**
  4204. * build mysql update query string
  4205. * @param integer $formatOffset
  4206. * @return string
  4207. */
  4208. public function build($formatOffset = 0)
  4209. {
  4210. $this->formatOffset += $formatOffset;
  4211. $offset = str_pad("", $this->formatOffset, " ");
  4212. // end if no table is set
  4213. if( empty($this->query["tables"]) ) return NULL;
  4214. $query = $this->format ? $offset . "UPDATE " : "UPDATE ";
  4215. // low priority
  4216. if( $this->query["low"] ) $query .= "LOW_PRIORITY ";
  4217. // ignore
  4218. if( $this->query["ignore"] ) $query .= "IGNORE ";
  4219. $query .= $this->format ? $offset . "\n" : NULL;
  4220. // tables
  4221. if( count($this->query["tables"]) == 1 )
  4222. $query .= $this->format ? $offset . " " . $this->query["tables"][0] . "\n" : $this->query["tables"][0] . " ";
  4223. else if( $this->format )
  4224. for( $i = 0; $i < count($this->query["tables"]); $i++ )
  4225. {
  4226. $query .= $offset . " " . $this->query["tables"][$i] . "";
  4227. $query .= $i < count($this->query["tables"]) - 1 ? "," : NULL;
  4228. $query .= "\n";
  4229. }
  4230. else
  4231. $query .= join(",", $this->query["tables"]) . " ";
  4232. // set
  4233. if( !empty($this->query["set"]) )
  4234. {
  4235. $query .= $this->format ? "SET\n" : "SET ";
  4236. if( $this->format )
  4237. for( $i = 0; $i < count($this->query["set"]); $i++ )
  4238. {
  4239. $query .= $offset . " " . $this->query["set"][$i] . "";
  4240. $query .= $i < count($this->query["set"]) - 1 ? ", \n" : NULL;
  4241. }
  4242. else
  4243. $query .= join(",", $this->query["set"]);
  4244. $query .= $this->format ? "\n" : " ";
  4245. }
  4246. // where
  4247. if( !empty($this->query["where"]) )
  4248. {
  4249. if( $this->format )
  4250. {
  4251. $query .= $offset . "WHERE \n";
  4252. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  4253. {
  4254. if( is_array($this->query["where"][$i]) )
  4255. {
  4256. $select = $this->query["where"][$i][1];
  4257. if( $select instanceof mysqlClass_Select )
  4258. {
  4259. $select = $select->build($this->formatOffset + 4);
  4260. $select = trim($select);
  4261. }
  4262. $query .= $offset . " " . str_replace("?", "\n" . $offset . " (" . $select . ")", $this->query["where"][$i][0]);
  4263. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  4264. $query .= " \n";
  4265. }
  4266. else
  4267. {
  4268. $query .= $offset . " " . $this->query["where"][$i];
  4269. $query .= $i < count($this->query["where"]) - 2 ? " \n" . $offset . $this->query["where"][$i + 1] . " " : NULL;
  4270. $query .= " \n";
  4271. }
  4272. }
  4273. }
  4274. else
  4275. {
  4276. for( $i = 0; $i < count($this->query["where"]); $i = $i + 2 )
  4277. {
  4278. if( is_array($this->query["where"][$i]) )
  4279. {
  4280. $select = $this->query["where"][$i][1];
  4281. if( $select instanceof mysqlClass_Select )
  4282. $select = $select->build();
  4283. $this->query["where"][$i] = str_replace("?", "(" . $select . ")", $this->query["where"][$i][0]);
  4284. }
  4285. }
  4286. $where = array_slice($this->query["where"], 0, -1);
  4287. $query .= "WHERE " . join(" ", $where) . " ";
  4288. }
  4289. }
  4290. // add order
  4291. if( !empty($this->query["order"]) && count($this->query["tables"]) == 1 )
  4292. {
  4293. if( $this->format )
  4294. {
  4295. $query .= $offset . "ORDER BY \n";
  4296. for( $i = 0; $i < count($this->query["order"]); $i++ )
  4297. {
  4298. $query .= $offset . " " . $this->query["order"][$i];
  4299. $query .= $i < count($this->query["order"]) - 1 ? "," : NULL;
  4300. $query .= " \n";
  4301. }
  4302. }
  4303. else
  4304. {
  4305. $query .= "ORDER BY " . join(",", $this->query["order"]) . " ";
  4306. }
  4307. }
  4308. // add limit
  4309. if( !empty($this->query["limit"]) && count($this->query["tables"]) == 1 )
  4310. {
  4311. $query .= $this->format ? $offset . "LIMIT \n" . $offset . " " : "LIMIT ";
  4312. $query .= $this->query["limit"];
  4313. }
  4314. return $query;
  4315. }
  4316. }
  4317. /*
  4318. ** collection classes
  4319. */
  4320. /**
  4321. * MySQL Collection Class
  4322. * - - - - - - - - - -
  4323. * Collection to further handle or filter mysql results by mysqlClass.
  4324. * - - - - - - - - - -
  4325. * Licensed under MIT license
  4326. * - - - - - - - - - -
  4327. * @Creator Daniel 'Eisbehr' Kern
  4328. * @Require PHP5
  4329. * @Version 3.0
  4330. * @Date 01.08.2013
  4331. * @Update 01.08.2013
  4332. * - - - - - - - - - -
  4333. */
  4334. class mysqlClass_Collection implements IteratorAggregate, Countable, ArrayAccess
  4335. {
  4336. /**
  4337. * collection rows
  4338. * @var mysqlClass_CollectionItem array
  4339. */
  4340. private $rows = array();
  4341. /**
  4342. * active filters
  4343. * @var array
  4344. */
  4345. private $filters = array();
  4346. /**
  4347. * active filters
  4348. * @var boolean
  4349. */
  4350. private $isFiltersLoaded = true;
  4351. /**
  4352. * total records
  4353. * @var integer
  4354. */
  4355. private $totalRecords = 0;
  4356. /**
  4357. * logical operators
  4358. * @var string
  4359. */
  4360. const LOGIC_EQ = "eq";
  4361. const LOGIC_SEQ = "seq";
  4362. const LOGIC_NEQ = "neq";
  4363. const LOGIC_SNEQ = "sneq";
  4364. const LOGIC_LT = "lt";
  4365. const LOGIC_GT = "gt";
  4366. const LOGIC_LTE = "lte";
  4367. const LOGIC_GTE = "gte";
  4368. const LOGIC_LIKE = "like";
  4369. const LOGIC_IN = "in";
  4370. /*
  4371. ** public
  4372. */
  4373. /**
  4374. * destructor
  4375. */
  4376. public function __destruct()
  4377. {
  4378. unset($this->rows);
  4379. unset($this->filters);
  4380. }
  4381. /*
  4382. ** item getter
  4383. */
  4384. /**
  4385. * get all collection items as array
  4386. * @return array
  4387. */
  4388. public function getItems()
  4389. {
  4390. return $this->rows;
  4391. }
  4392. /**
  4393. * get collection size
  4394. * @return integer
  4395. */
  4396. public function getSize()
  4397. {
  4398. return $this->totalRecords;
  4399. }
  4400. /**
  4401. * gets an specific collection item by position
  4402. * @param int $position
  4403. * @return mysqlClass_CollectionItem
  4404. */
  4405. public function getItem($position)
  4406. {
  4407. if( $position >= 0 && $position < $this->totalRecords )
  4408. {
  4409. return array_slice($this->rows, $position, 1);
  4410. }
  4411. return false;
  4412. }
  4413. /**
  4414. * get collection item by id
  4415. * @param mixed $id
  4416. * @return mysqlClass_CollectionItem
  4417. */
  4418. public function getItemById($id)
  4419. {
  4420. if( isset($this->rows[$id]) )
  4421. {
  4422. return $this->rows[$id];
  4423. }
  4424. return false;
  4425. }
  4426. /**
  4427. * get first item in collection
  4428. * @return mysqlClass_CollectionItem
  4429. */
  4430. public function getFirstItem()
  4431. {
  4432. if( !empty($this->rows) )
  4433. {
  4434. return array_slice($this->rows, 0, 1);
  4435. }
  4436. return false;
  4437. }
  4438. /**
  4439. * get last item in collection
  4440. * @return mysqlClass_CollectionItem
  4441. */
  4442. public function getLastItem()
  4443. {
  4444. if( !empty($this->rows) )
  4445. {
  4446. return array_slice($this->rows, -1, 1);
  4447. }
  4448. return false;
  4449. }
  4450. /**
  4451. * get first collection item by column value
  4452. * @param string $column
  4453. * @param mixed $value
  4454. * @return mysqlClass_CollectionItem
  4455. */
  4456. public function getItemByColumnValue($column, $value)
  4457. {
  4458. foreach( $this->rows as $item )
  4459. {
  4460. if( $item instanceof mysqlClass_CollectionItem && $item->getData($column) === $value )
  4461. {
  4462. return $item;
  4463. }
  4464. }
  4465. return false;
  4466. }
  4467. /**
  4468. * get all collection items by column value
  4469. * @param string $column
  4470. * @param mixed $value
  4471. * @return array
  4472. */
  4473. public function getItemsByColumnValue($column, $value)
  4474. {
  4475. $items = array();
  4476. foreach( $this->rows as $item )
  4477. {
  4478. if( $item instanceof mysqlClass_CollectionItem && $item->getData($column) === $value )
  4479. {
  4480. $items[] = $item;
  4481. }
  4482. }
  4483. return $items;
  4484. }
  4485. /**
  4486. * retrieve empty collection item
  4487. * @return mysqlClass_CollectionItem
  4488. */
  4489. public function getNewEmptyItem()
  4490. {
  4491. return new mysqlClass_CollectionItem();
  4492. }
  4493. /**
  4494. * get a new collection item with default data
  4495. * @param array $data
  4496. * @return mysqlClass_CollectionItem
  4497. */
  4498. public function getNewItemWithData($data = array())
  4499. {
  4500. $item = new mysqlClass_CollectionItem();
  4501. foreach( $data as $key => $value )
  4502. if( !empty($key) )
  4503. $item->setData($key, $value);
  4504. return $item;
  4505. }
  4506. /*
  4507. ** getter
  4508. */
  4509. /**
  4510. * retrieve all item ids
  4511. * @return array
  4512. */
  4513. public function getAllIds()
  4514. {
  4515. return array_keys($this->rows);
  4516. }
  4517. /**
  4518. * retrieve column values from all collection items
  4519. * @param string $columnName
  4520. * @param boolean $unique
  4521. * @return array
  4522. */
  4523. public function getColumnValues($columnName, $unique = false)
  4524. {
  4525. $columnValues = array();
  4526. foreach( $this->rows as $item )
  4527. {
  4528. if( !($item instanceof mysqlClass_CollectionItem) )
  4529. continue;
  4530. $value = $item->getData($columnName);
  4531. if( $unique )
  4532. {
  4533. if( !in_array($value, $columnValues) ) $columnValues[] = $value;
  4534. }
  4535. else
  4536. {
  4537. $columnValues[] = $value;
  4538. }
  4539. }
  4540. return $columnValues;
  4541. }
  4542. /**
  4543. * implementation of IteratorAggregate
  4544. * @return ArrayIterator
  4545. */
  4546. public function getIterator()
  4547. {
  4548. return new ArrayIterator($this->rows);
  4549. }
  4550. /*
  4551. ** public methods
  4552. */
  4553. /**
  4554. * add an item to collection
  4555. * @param mysqlClass_CollectionItem $item
  4556. * @throws Exception
  4557. * @return mysqlClass_Collection
  4558. */
  4559. public function addItem($item)
  4560. {
  4561. $itemId = $item->getData("id");
  4562. if( !is_null($itemId) )
  4563. {
  4564. if( isset($this->rows[$itemId]) )
  4565. {
  4566. throw new Exception("item with the same id '" . $itemId . "' already exists");
  4567. }
  4568. $this->rows[$itemId] = $item;
  4569. }
  4570. else
  4571. {
  4572. $this->rows[] = $item;
  4573. }
  4574. $this->totalRecords++;
  4575. return $this;
  4576. }
  4577. /**
  4578. * set data for all collection items
  4579. * @param string $key
  4580. * @param mixed $value
  4581. * @return mysqlClass_Collection
  4582. */
  4583. public function setDataToAll($key, $value=null)
  4584. {
  4585. if( is_array($key) )
  4586. {
  4587. foreach( $key as $_key => $_value )
  4588. {
  4589. $this->setDataToAll($_key, $_value);
  4590. }
  4591. return $this;
  4592. }
  4593. foreach( $this->rows as $item )
  4594. {
  4595. if( $item instanceof mysqlClass_CollectionItem)
  4596. $item->setData($key, $value);
  4597. }
  4598. return $this;
  4599. }
  4600. /**
  4601. * return the index of given object or id
  4602. * @param mysqlClass_CollectionItem|string|integer $object
  4603. * @return integer
  4604. */
  4605. public function indexOf($object)
  4606. {
  4607. $position = 0;
  4608. if( $object instanceof mysqlClass_CollectionItem )
  4609. {
  4610. $object = $object->getData("id");
  4611. }
  4612. foreach( $this->rows as $id => $item)
  4613. {
  4614. if( $id === $object )
  4615. {
  4616. return $position;
  4617. }
  4618. ++$position;
  4619. }
  4620. return false;
  4621. }
  4622. /**
  4623. * check if item id exists in collection
  4624. * @param integer|string $id
  4625. * @return boolean
  4626. */
  4627. public function exists($id)
  4628. {
  4629. return isset($this->rows[$id]);
  4630. }
  4631. /**
  4632. * check if the collection is empty or not
  4633. * @return boolean
  4634. */
  4635. public function isEmpty()
  4636. {
  4637. if( $this->totalRecords == 0 )
  4638. {
  4639. return true;
  4640. }
  4641. return false;
  4642. }
  4643. /**
  4644. * check if given object exists in collection
  4645. * @param mysqlClass_CollectionItem $item
  4646. * @return bool
  4647. */
  4648. public function contains($item)
  4649. {
  4650. if( $item instanceof mysqlClass_CollectionItem )
  4651. {
  4652. return isset($this->rows[$item->getData("id")]);
  4653. }
  4654. return false;
  4655. }
  4656. /**
  4657. * get collection item count
  4658. * @return integer
  4659. */
  4660. public function count()
  4661. {
  4662. return count($this->rows);
  4663. }
  4664. /**
  4665. * alias of count
  4666. * @return integer
  4667. */
  4668. public function length()
  4669. {
  4670. return $this->count();
  4671. }
  4672. /**
  4673. * serializes collection items
  4674. * @return string
  4675. */
  4676. public function serialize()
  4677. {
  4678. return serialize($this->rows);
  4679. }
  4680. /**
  4681. * unserialize data and store into collection
  4682. * @param string $data
  4683. */
  4684. public function unserialize($data)
  4685. {
  4686. $this->rows = unserialize($data);
  4687. }
  4688. /**
  4689. * remove item from collection by item id
  4690. * @param string|integer $id
  4691. * @return mysqlClass_Collection
  4692. */
  4693. public function removeItemById($id)
  4694. {
  4695. if(isset($this->rows[$id]))
  4696. {
  4697. unset($this->rows[$id]);
  4698. $this->totalRecords--;
  4699. }
  4700. return $this;
  4701. }
  4702. /**
  4703. * clear collection items
  4704. * @return mysqlClass_Collection
  4705. */
  4706. public function clear()
  4707. {
  4708. $this->rows = array();
  4709. return $this;
  4710. }
  4711. /**
  4712. * reset collection
  4713. * @return mysqlClass_Collection
  4714. */
  4715. public function reset()
  4716. {
  4717. return $this->clear();
  4718. }
  4719. /*
  4720. ** filter
  4721. */
  4722. /**
  4723. * adds an column to filter
  4724. * @param string $column
  4725. * @param string $value
  4726. * @param string $logic
  4727. * @return mysqlClass_Collection
  4728. */
  4729. public function addColumnToFilter($column, $value, $logic = self::LOGIC_EQ)
  4730. {
  4731. $filter = array();
  4732. $filter["field"] = $column;
  4733. $filter["value"] = $value;
  4734. $filter["logic"] = strtolower($logic);
  4735. $this->filters[] = $filter;
  4736. $this->filterCollection($column, $value, $logic);
  4737. return $this;
  4738. }
  4739. /**
  4740. * alias of addColumnToFilter
  4741. * @param string $field
  4742. * @param string $value
  4743. * @param string $logic
  4744. * @return mysqlClass_Collection
  4745. */
  4746. public function addFieldToFilter($field, $value, $logic = self::LOGIC_EQ)
  4747. {
  4748. return $this->addColumnToFilter($field, $value, $logic);
  4749. }
  4750. /**
  4751. * gets an collection of filtered items
  4752. * @param string $field
  4753. * @param string $value
  4754. * @param string $logic
  4755. * @return mysqlClass_Collection
  4756. */
  4757. public function filterCollection($field, $value, $logic = self::LOGIC_EQ)
  4758. {
  4759. $filteredCollection = new self();
  4760. // only convert value once
  4761. if( $logic == self::LOGIC_IN )
  4762. $value = is_array($value) ? $value : explode(",", $value);
  4763. foreach( $this->rows as $item )
  4764. {
  4765. if( !($item instanceof mysqlClass_CollectionItem) )
  4766. continue;
  4767. switch( $logic )
  4768. {
  4769. case self::LOGIC_IN:
  4770. if( in_array($item->getData($field), $value) ) $filteredCollection->addItem($item);
  4771. break;
  4772. case self::LOGIC_LIKE:
  4773. if( strpos(strtolower($item->getData($field)), strtolower($value)) !== false ) $filteredCollection->addItem($item);
  4774. break;
  4775. case self::LOGIC_GT:
  4776. if( intval($item->getData($field)) > intval($value) ) $filteredCollection->addItem($item);
  4777. break;
  4778. case self::LOGIC_LT:
  4779. if( intval($item->getData($field)) < intval($value) ) $filteredCollection->addItem($item);
  4780. break;
  4781. case self::LOGIC_GTE:
  4782. if( intval($item->getData($field)) >= intval($value) ) $filteredCollection->addItem($item);
  4783. break;
  4784. case self::LOGIC_LTE:
  4785. if( intval($item->getData($field)) <= intval($value) ) $filteredCollection->addItem($item);
  4786. break;
  4787. case self::LOGIC_NEQ:
  4788. if( $item->getData($field) != $value ) $filteredCollection->addItem($item);
  4789. break;
  4790. case self::LOGIC_SNEQ:
  4791. if( $item->getData($field) !== $value ) $filteredCollection->addItem($item);
  4792. break;
  4793. case self::LOGIC_SEQ:
  4794. if( $item->getData($field) === $value ) $filteredCollection->addItem($item);
  4795. break;
  4796. case self::LOGIC_EQ:
  4797. default:
  4798. if( $item->getData($field) == $value ) $filteredCollection->addItem($item);
  4799. break;
  4800. }
  4801. }
  4802. $this->isFiltersLoaded = true;
  4803. $this->rows = $filteredCollection->getItems();
  4804. unset($filteredCollection);
  4805. return $this;
  4806. }
  4807. /*
  4808. ** callbacks
  4809. */
  4810. /**
  4811. * walk through the collection and returns array with results
  4812. * @param string $callback
  4813. * @param array $arguments
  4814. * @return array
  4815. */
  4816. public function walk($callback, $arguments = array())
  4817. {
  4818. $results = array();
  4819. foreach( $this->rows as $id => $item )
  4820. {
  4821. array_unshift($arguments, $item);
  4822. $results[$id] = call_user_func_array($callback, $arguments);
  4823. }
  4824. return $results;
  4825. }
  4826. /**
  4827. *
  4828. * @param $callback
  4829. * @param array $arguments
  4830. * @return mysqlClass_Collection
  4831. */
  4832. public function each($callback, $arguments = array())
  4833. {
  4834. foreach( $this->rows as $id => $item )
  4835. {
  4836. array_unshift($arguments, $item);
  4837. $this->rows[$id] = call_user_func_array($callback, $arguments);
  4838. }
  4839. return $this;
  4840. }
  4841. /*
  4842. ** output
  4843. */
  4844. /**
  4845. * return collection as xml
  4846. * @return string
  4847. */
  4848. public function toXml()
  4849. {
  4850. $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  4851. $xml .= "<collection>\n";
  4852. $xml .= " <totalRecords>" . $this->totalRecords . "</totalRecords>\n";
  4853. $xml .= " <items>\n";
  4854. foreach( $this->rows as $item )
  4855. {
  4856. if( $item instanceof mysqlClass_CollectionItem )
  4857. $xml .= $item->toXml(true);
  4858. }
  4859. $xml .= " <items>\n";
  4860. $xml .= "<collection>\n";
  4861. return $xml;
  4862. }
  4863. /**
  4864. * return collection as array
  4865. * @param array $requiredFields
  4866. * @return array
  4867. */
  4868. public function toArray($requiredFields = array())
  4869. {
  4870. $array = array();
  4871. $array["totalRecords"] = $this->totalRecords;
  4872. $array["items"] = array();
  4873. foreach( $this->rows as $id => $item )
  4874. {
  4875. if( $item instanceof mysqlClass_CollectionItem )
  4876. $array["items"][$id] = $item->toArray($requiredFields);
  4877. }
  4878. return $array;
  4879. }
  4880. /**
  4881. * return collection as string
  4882. * @return string
  4883. */
  4884. public function toString()
  4885. {
  4886. return $this->serialize();
  4887. }
  4888. /*
  4889. ** array access
  4890. */
  4891. /**
  4892. * implementation of ArrayAccess
  4893. * @param string $id
  4894. * @param mixed $value
  4895. */
  4896. public function offsetSet($id, $value)
  4897. {
  4898. $this->rows[$id] = $value;
  4899. }
  4900. /**
  4901. * implementation of ArrayAccess
  4902. * @param string $id
  4903. * @return boolean
  4904. */
  4905. public function offsetExists($id)
  4906. {
  4907. return isset($this->rows[$id]);
  4908. }
  4909. /**
  4910. * implementation of ArrayAccess
  4911. * @param string $id
  4912. */
  4913. public function offsetUnset($id)
  4914. {
  4915. unset($this->rows[$id]);
  4916. }
  4917. /**
  4918. * implementation of ArrayAccess
  4919. * @param string $id
  4920. * @return mysqlClass_CollectionItem
  4921. */
  4922. public function offsetGet($id)
  4923. {
  4924. return isset($this->rows[$id]) ? $this->rows[$id] : false;
  4925. }
  4926. }
  4927. /**
  4928. * MySQL Collection Item Class
  4929. * - - - - - - - - - -
  4930. * Item representation of mysqlClass_Collection.
  4931. * - - - - - - - - - -
  4932. * Licensed under MIT license
  4933. * - - - - - - - - - -
  4934. * @Creator Daniel 'Eisbehr' Kern
  4935. * @Require PHP5
  4936. * @Version 3.0
  4937. * @Date 01.08.2013
  4938. * @Update 01.08.2013
  4939. * - - - - - - - - - -
  4940. */
  4941. class mysqlClass_CollectionItem
  4942. {
  4943. /**
  4944. * internal data storage array
  4945. * @var mixed array
  4946. */
  4947. private $data = array();
  4948. /**
  4949. * if some data was changed
  4950. * @var boolean
  4951. */
  4952. private $hasChangedData = false;
  4953. /**
  4954. * cache for formatted names
  4955. * @var string array
  4956. */
  4957. private $formatNameCache = array();
  4958. /*
  4959. ** public
  4960. */
  4961. /**
  4962. * handle all function calls the class didn't know
  4963. * @param string $method
  4964. * @param mixed array $args
  4965. * @return mixed
  4966. */
  4967. public function __call($method, $args)
  4968. {
  4969. $type = substr($method, 0, 3);
  4970. $key = $this->formatFunctionName(substr($method, 3));
  4971. if( $type == "get" )
  4972. {
  4973. return $this->getData($key);
  4974. }
  4975. if( $type == "set" )
  4976. {
  4977. $param = isset($args[0]) ? $args[0] : NULL;
  4978. return $this->setData($key, $param);
  4979. }
  4980. if( $type == "uns" )
  4981. {
  4982. return $this->unsetData($key);
  4983. }
  4984. if( $type == "has" )
  4985. {
  4986. return $this->hasData($key);
  4987. }
  4988. trigger_error("function not found " . get_class($this) . "::" . $method . "();", E_USER_ERROR);
  4989. return false;
  4990. }
  4991. /**
  4992. * helper function to set internal data
  4993. * @param string $key
  4994. * @param mixed $value
  4995. * @return mysqlClass_CollectionItem
  4996. */
  4997. public function setData($key, $value)
  4998. {
  4999. $this->data[$key] = $value;
  5000. $this->setDataChanged();
  5001. return $this;
  5002. }
  5003. /**
  5004. * helper function to get internal data
  5005. * @param string $key
  5006. * @return mixed
  5007. */
  5008. public function getData($key = NULL)
  5009. {
  5010. if( $key == NULL )
  5011. {
  5012. return $this->data;
  5013. }
  5014. if( isset($this->data[$key]) )
  5015. {
  5016. return $this->data[$key];
  5017. }
  5018. return NULL;
  5019. }
  5020. /**
  5021. * helper function to unset internal data
  5022. * @param string $key
  5023. * @return mysqlClass_CollectionItem
  5024. */
  5025. public function unsetData($key = NULL)
  5026. {
  5027. if( $key == NULL )
  5028. {
  5029. $this->data = array();
  5030. return $this;
  5031. }
  5032. unset($this->data[$key]);
  5033. $this->setDataChanged();
  5034. return $this;
  5035. }
  5036. /**
  5037. * helper function to check if data is set
  5038. * @param string $key
  5039. * @return boolean
  5040. */
  5041. public function hasData($key = NULL)
  5042. {
  5043. if( $key == NULL )
  5044. {
  5045. return empty($this->data);
  5046. }
  5047. return isset($this->data[$key]);
  5048. }
  5049. /**
  5050. * check if some data is set
  5051. * @return boolean
  5052. */
  5053. public function isEmpty()
  5054. {
  5055. if( empty($this->data) )
  5056. {
  5057. return true;
  5058. }
  5059. return false;
  5060. }
  5061. /**
  5062. * if some data is changed
  5063. * @return boolean
  5064. */
  5065. public function hasChangedData()
  5066. {
  5067. return $this->hasChangedData;
  5068. }
  5069. /**
  5070. * clear changed data info
  5071. * @return mysqlClass_CollectionItem
  5072. */
  5073. public function clearDataChanged()
  5074. {
  5075. $this->setDataChanged(false);
  5076. return $this;
  5077. }
  5078. /**
  5079. * get item as xml
  5080. * @param boolean $itemOnly
  5081. * @return string
  5082. */
  5083. public function toXml($itemOnly = false)
  5084. {
  5085. $xml = "";
  5086. if( !$itemOnly )
  5087. {
  5088. $xml .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  5089. $xml .= "<data>\n";
  5090. }
  5091. $xml .= " <item>\n";
  5092. foreach( $this->data as $key => $value )
  5093. {
  5094. $xml .= " <" . $key . ">" . $value . "</" . $key . ">\n";
  5095. }
  5096. $xml .= " </item>\n";
  5097. if( !$itemOnly ) $xml .= "</data>\n";
  5098. return $xml;
  5099. }
  5100. /**
  5101. * return object as array
  5102. * @param array $requiredFields
  5103. * @return array
  5104. */
  5105. public function toArray($requiredFields = array())
  5106. {
  5107. if( !empty($requiredFields) )
  5108. {
  5109. $data = array();
  5110. foreach( $requiredFields as $field )
  5111. $data[$field] = $this->getData($field);
  5112. return $data;
  5113. }
  5114. return $this->data;
  5115. }
  5116. /*
  5117. ** private
  5118. */
  5119. /**
  5120. * formats the name of the called function
  5121. * @param string $name
  5122. * @return string
  5123. */
  5124. private function formatFunctionName($name)
  5125. {
  5126. if( isset($this->formatNameCache[$name]) )
  5127. return $this->formatNameCache[$name];
  5128. $format = preg_replace('/(.)([A-Z])/', "$1_$2", $name);
  5129. $format = strtolower($format);
  5130. $this->formatNameCache[$name] = $format;
  5131. return $format;
  5132. }
  5133. /**
  5134. * set the changed status
  5135. * @param boolean $changed
  5136. * @return void
  5137. */
  5138. private function setDataChanged($changed = true)
  5139. {
  5140. $this->hasChangedData = $changed;
  5141. return;
  5142. }
  5143. }
  5144. /*
  5145. ** exception classes
  5146. */
  5147. /**
  5148. * Frosted MySQL Library Exception Classes
  5149. * - - - - - - - - - -
  5150. * Add special exception names to Frosted MySQL Library.
  5151. * - - - - - - - - - -
  5152. * Licensed under MIT license
  5153. * - - - - - - - - - -
  5154. * @Creator Daniel 'Eisbehr' Kern
  5155. * @Require PHP5
  5156. * @Version 3.0
  5157. * @Date 01.08.2013
  5158. * @Update 01.08.2013
  5159. * - - - - - - - - - -
  5160. */
  5161. class mysqlClass_Connection_Exception extends Exception {}
  5162. class mysqlClass_Database_Exception extends Exception {}
  5163. class mysqlClass_Query_Exception extends Exception {}
  5164. class mysqlClass_Permission_Exception extends Exception {}
  5165. class mysqlClass_Create_Exception extends Exception {}
  5166. class mysqlClass_Unknown_Function_Exception extends Exception {}