Query.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. /**
  3. * Database query wrapper. See [Parameterized Statements](database/query/parameterized) for usage and examples.
  4. *
  5. * @package Kohana/Database
  6. * @category Query
  7. * @author Kohana Team
  8. * @copyright (c) Kohana Team
  9. * @license https://koseven.ga/LICENSE.md
  10. */
  11. class Kohana_Database_Query {
  12. // Query type
  13. protected $_type;
  14. // Execute the query during a cache hit
  15. protected $_force_execute = FALSE;
  16. // Cache lifetime
  17. protected $_lifetime = NULL;
  18. // SQL statement
  19. protected $_sql;
  20. // Quoted query parameters
  21. protected $_parameters = [];
  22. // Return results as associative arrays or objects
  23. protected $_as_object = FALSE;
  24. // Parameters for __construct when using object results
  25. protected $_object_params = [];
  26. /**
  27. * Creates a new SQL query of the specified type.
  28. *
  29. * @param integer $type query type: Database::SELECT, Database::INSERT, etc
  30. * @param string $sql query string
  31. * @return void
  32. */
  33. public function __construct($type, $sql)
  34. {
  35. $this->_type = $type;
  36. $this->_sql = $sql;
  37. }
  38. /**
  39. * Return the SQL query string.
  40. *
  41. * @return string
  42. */
  43. public function __toString()
  44. {
  45. try
  46. {
  47. // Return the SQL string
  48. return $this->compile(Database::instance());
  49. }
  50. catch (Exception $e)
  51. {
  52. return Kohana_Exception::text($e);
  53. }
  54. }
  55. /**
  56. * Get the type of the query.
  57. *
  58. * @return integer
  59. */
  60. public function type()
  61. {
  62. return $this->_type;
  63. }
  64. /**
  65. * Enables the query to be cached for a specified amount of time.
  66. *
  67. * @param integer $lifetime number of seconds to cache, 0 deletes it from the cache
  68. * @param boolean $force whether or not to execute the query during a cache hit
  69. * @return $this
  70. * @uses Kohana::$cache_life
  71. */
  72. public function cached($lifetime = NULL, $force = FALSE)
  73. {
  74. if ($lifetime === NULL)
  75. {
  76. // Use the global setting
  77. $lifetime = Kohana::$cache_life;
  78. }
  79. $this->_force_execute = $force;
  80. $this->_lifetime = $lifetime;
  81. return $this;
  82. }
  83. /**
  84. * Returns results as associative arrays
  85. *
  86. * @return $this
  87. */
  88. public function as_assoc()
  89. {
  90. $this->_as_object = FALSE;
  91. $this->_object_params = [];
  92. return $this;
  93. }
  94. /**
  95. * Returns results as objects
  96. *
  97. * @param string $class classname or TRUE for stdClass
  98. * @param array $params
  99. * @return $this
  100. */
  101. public function as_object($class = TRUE, array $params = NULL)
  102. {
  103. $this->_as_object = $class;
  104. if ($params)
  105. {
  106. // Add object parameters
  107. $this->_object_params = $params;
  108. }
  109. return $this;
  110. }
  111. /**
  112. * Set the value of a parameter in the query.
  113. *
  114. * @param string $param parameter key to replace
  115. * @param mixed $value value to use
  116. * @return $this
  117. */
  118. public function param($param, $value)
  119. {
  120. // Add or overload a new parameter
  121. $this->_parameters[$param] = $value;
  122. return $this;
  123. }
  124. /**
  125. * Bind a variable to a parameter in the query.
  126. *
  127. * @param string $param parameter key to replace
  128. * @param mixed $var variable to use
  129. * @return $this
  130. */
  131. public function bind($param, & $var)
  132. {
  133. // Bind a value to a variable
  134. $this->_parameters[$param] =& $var;
  135. return $this;
  136. }
  137. /**
  138. * Add multiple parameters to the query.
  139. *
  140. * @param array $params list of parameters
  141. * @return $this
  142. */
  143. public function parameters(array $params)
  144. {
  145. // Merge the new parameters in
  146. $this->_parameters = $params + $this->_parameters;
  147. return $this;
  148. }
  149. /**
  150. * Compile the SQL query and return it. Replaces any parameters with their
  151. * given values.
  152. *
  153. * @param mixed $db Database instance or name of instance
  154. * @return string
  155. */
  156. public function compile($db = NULL)
  157. {
  158. if ( ! is_object($db))
  159. {
  160. // Get the database instance
  161. $db = Database::instance($db);
  162. }
  163. // Import the SQL locally
  164. $sql = $this->_sql;
  165. if ( ! empty($this->_parameters))
  166. {
  167. // Quote all of the values
  168. $values = array_map([$db, 'quote'], $this->_parameters);
  169. // Replace the values in the SQL
  170. $sql = strtr($sql, $values);
  171. }
  172. return $sql;
  173. }
  174. /**
  175. * Execute the current query on the given database.
  176. *
  177. * @param mixed $db Database instance or name of instance
  178. * @param string result object classname, TRUE for stdClass or FALSE for array
  179. * @param array result object constructor arguments
  180. * @return object Database_Result for SELECT queries
  181. * @return mixed the insert id for INSERT queries
  182. * @return integer number of affected rows for all other queries
  183. */
  184. public function execute($db = NULL, $as_object = NULL, $object_params = NULL)
  185. {
  186. if ( ! is_object($db))
  187. {
  188. // Get the database instance
  189. $db = Database::instance($db);
  190. }
  191. if ($as_object === NULL)
  192. {
  193. $as_object = $this->_as_object;
  194. }
  195. if ($object_params === NULL)
  196. {
  197. $object_params = $this->_object_params;
  198. }
  199. // Compile the SQL query
  200. $sql = $this->compile($db);
  201. if ($this->_lifetime !== NULL AND $this->_type === Database::SELECT)
  202. {
  203. // Set the cache key based on the database instance name and SQL
  204. $cache_key = 'Database::query("'.$db.'", "'.$sql.'")';
  205. // Read the cache first to delete a possible hit with lifetime <= 0
  206. if (($result = Kohana::cache($cache_key, NULL, $this->_lifetime)) !== NULL
  207. AND ! $this->_force_execute)
  208. {
  209. // Return a cached result
  210. return new Database_Result_Cached($result, $sql, $as_object, $object_params);
  211. }
  212. }
  213. // Execute the query
  214. $result = $db->query($this->_type, $sql, $as_object, $object_params);
  215. if (isset($cache_key) AND $this->_lifetime > 0)
  216. {
  217. // Cache the result array
  218. Kohana::cache($cache_key, $result->as_array(), $this->_lifetime);
  219. }
  220. return $result;
  221. }
  222. } // End Database_Query