_type = $type; $this->_sql = $sql; } /** * Return the SQL query string. * * @return string */ final public function __toString() { try { // Return the SQL string return $this->compile(); } catch (\Exception $e) { return $e->getMessage(); } } /** * Get the type of the query. * * @return integer */ public function type() { return $this->_type; } /** * Enables the query to be cached for a specified amount of time. * * @param integer $lifetime number of seconds to cache or null for default * @param string $cache_key name of the cache key to be used or null for default * @param boolean $cache_all if true, cache all results, even empty ones * * @return $this */ public function cached($lifetime = null, $cache_key = null, $cache_all = true) { $this->_lifetime = $lifetime; $this->_cache_all = (bool) $cache_all; is_string($cache_key) and $this->_cache_key = $cache_key; return $this; } /** * Returns results as associative arrays * * @return $this */ public function as_assoc() { $this->_as_object = false; return $this; } /** * Returns results as objects * * @param mixed $class classname or true for stdClass * * @return $this */ public function as_object($class = true) { $this->_as_object = $class; return $this; } /** * Set the value of a parameter in the query. * * @param string $param parameter key to replace * @param mixed $value value to use * * @return $this */ public function param($param, $value) { // Add or overload a new parameter $this->_parameters[$param] = $value; return $this; } /** * Bind a variable to a parameter in the query. * * @param string $param parameter key to replace * @param mixed $var variable to use * * @return $this */ public function bind($param, & $var) { // Bind a value to a variable $this->_parameters[$param] =& $var; return $this; } /** * Add multiple parameters to the query. * * @param array $params list of parameters * * @return $this */ public function parameters(array $params) { // Merge the new parameters in $this->_parameters = $params + $this->_parameters; return $this; } /** * Set a DB connection to use when compiling the SQL * * @param mixed $db * * @return $this */ public function set_connection($db) { if ( ! $db instanceof \Database_Connection) { // Get the database instance $db = \Database_Connection::instance($db); } $this->_connection = $db; return $this; } /** * Compile the SQL query and return it. Replaces any parameters with their * given values. * * @param mixed $db Database instance or instance name * * @return string */ public function compile($db = null) { if ($this->_connection !== null and $db === null) { $db = $this->_connection; } if ( ! $db instanceof \Database_Connection) { // Get the database instance $db = $this->_connection ?: \Database_Connection::instance($db); } // Import the SQL locally $sql = $this->_sql; if ( ! empty($this->_parameters)) { // Quote all of the values $values = array_map(array($db, 'quote'), $this->_parameters); // Replace the values in the SQL $sql = \Str::tr($sql, $values); } return trim($sql); } /** * Execute the current query on the given database. * * @param mixed $db Database instance or name of instance * * @return object Database_Result for SELECT queries * @return mixed the insert id for INSERT queries * @return integer number of affected rows for all other queries */ public function execute($db = null) { if ($this->_connection !== null and $db === null) { $db = $this->_connection; } if ( ! is_object($db)) { // Get the database instance. If this query is a instance of // Database_Query_Builder_Select then use the slave connection if configured $db = \Database_Connection::instance($db, null, ! $this instanceof \Database_Query_Builder_Select); } // Compile the SQL query $sql = $this->compile($db); // make sure we have a SQL type to work with if (is_null($this->_type)) { // get the SQL statement type without having to duplicate the entire statement $stmt = preg_split("/[\s]+/", substr($sql, 0, 10), 2); switch(strtoupper(reset($stmt))) { case 'DESCRIBE': case 'EXECUTE': case 'EXPLAIN': case 'SELECT': case 'SHOW': $this->_type = \DB::SELECT; break; case 'INSERT': case 'REPLACE': $this->_type = \DB::INSERT; break; case 'UPDATE': $this->_type = \DB::UPDATE; break; case 'DELETE': $this->_type = \DB::DELETE; break; default: $this->_type = 0; } } if ($db->caching() and ! empty($this->_lifetime) and $this->_type === \DB::SELECT) { $cache_key = empty($this->_cache_key) ? 'db.'.md5('Database_Connection::query("'.$db.'", "'.$sql.'")') : $this->_cache_key; $cache = \Cache::forge($cache_key); try { $result = $cache->get(); return new \Database_Result_Cached($result, $sql, $this->_as_object); } catch (\CacheNotFoundException $e) {} } // Execute the query \DB::$query_count++; $result = $db->query($this->_type, $sql, $this->_as_object); // Cache the result if needed if (isset($cache) and ($this->_cache_all or $result->count())) { $cache->set_expiration($this->_lifetime)->set_contents($result->as_array())->set(); } return $result; } }