Permalink
Browse files

Allow Expression to have parameters. Fixes #3429

  • Loading branch information...
1 parent f8abadb commit f2ff54585629a87b961b30eacd05d65fd5a059ac @cbandy cbandy committed Jul 4, 2011
Showing with 100 additions and 13 deletions.
  1. +20 −10 classes/kohana/database.php
  2. +77 −1 classes/kohana/database/expression.php
  3. +3 −2 classes/kohana/db.php
@@ -416,7 +416,7 @@ public function table_prefix()
* $db->quote('fred'); // 'fred'
*
* Objects passed to this function will be converted to strings.
- * [Database_Expression] objects will use the value of the expression.
+ * [Database_Expression] objects will be compiled.
* [Database_Query] objects will be compiled and converted to a sub-query.
* All other objects will be converted using the `__toString` method.
*
@@ -447,8 +447,8 @@ public function quote($value)
}
elseif ($value instanceof Database_Expression)
{
- // Use a raw expression
- return $value->value();
+ // Compile the expression
+ return $value->compile($this);
}
else
{
@@ -483,6 +483,11 @@ public function quote($value)
* // The value of "column" will be quoted
* $column = $db->quote_column('COUNT("column")');
*
+ * Objects passed to this function will be converted to strings.
+ * [Database_Expression] objects will be compiled.
+ * [Database_Query] objects will be compiled and converted to a sub-query.
+ * All other objects will be converted using the `__toString` method.
+ *
* @param mixed column name or array(column, alias)
* @return string
* @uses Database::quote_identifier
@@ -502,8 +507,8 @@ public function quote_column($column)
}
elseif ($column instanceof Database_Expression)
{
- // Use a raw expression
- $column = $column->value();
+ // Compile the expression
+ $column = $column->compile($this);
}
else
{
@@ -562,6 +567,11 @@ public function quote_column($column)
*
* $table = $db->quote_table($table);
*
+ * Objects passed to this function will be converted to strings.
+ * [Database_Expression] objects will be compiled.
+ * [Database_Query] objects will be compiled and converted to a sub-query.
+ * All other objects will be converted using the `__toString` method.
+ *
* @param mixed table name or array(table, alias)
* @return string
* @uses Database::quote_identifier
@@ -581,8 +591,8 @@ public function quote_table($table)
}
elseif ($table instanceof Database_Expression)
{
- // Use a raw expression
- $table = $table->value();
+ // Compile the expression
+ $table = $table->compile($this);
}
else
{
@@ -630,7 +640,7 @@ public function quote_table($table)
* Quote a database identifier
*
* Objects passed to this function will be converted to strings.
- * [Database_Expression] objects will use the value of the expression.
+ * [Database_Expression] objects will be compiled.
* [Database_Query] objects will be compiled and converted to a sub-query.
* All other objects will be converted using the `__toString` method.
*
@@ -651,8 +661,8 @@ public function quote_identifier($value)
}
elseif ($value instanceof Database_Expression)
{
- // Use a raw expression
- $value = $value->value();
+ // Compile the expression
+ $value = $value->compile($this);
}
else
{
@@ -18,6 +18,9 @@
*/
class Kohana_Database_Expression {
+ // Unquoted parameters
+ protected $_parameters;
+
// Raw expression string
protected $_value;
@@ -26,12 +29,56 @@ class Kohana_Database_Expression {
*
* $expression = new Database_Expression('COUNT(users.id)');
*
+ * @param string $value raw SQL expression string
+ * @param array $parameters unquoted parameter values
* @return void
*/
- public function __construct($value)
+ public function __construct($value, $parameters = array())
{
// Set the expression string
$this->_value = $value;
+ $this->_parameters = $parameters;
+ }
+
+ /**
+ * Bind a variable to a parameter.
+ *
+ * @param string $param parameter key to replace
+ * @param mixed $var variable to use
+ * @return $this
+ */
+ public function bind($param, & $var)
+ {
+ $this->_parameters[$param] =& $var;
+
+ return $this;
+ }
+
+ /**
+ * Set the value of a parameter.
+ *
+ * @param string $param parameter key to replace
+ * @param mixed $value value to use
+ * @return $this
+ */
+ public function param($param, $value)
+ {
+ $this->_parameters[$param] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Add multiple parameter values.
+ *
+ * @param array $params list of parameter values
+ * @return $this
+ */
+ public function parameters(array $params)
+ {
+ $this->_parameters = $params + $this->_parameters;
+
+ return $this;
}
/**
@@ -59,4 +106,33 @@ public function __toString()
return $this->value();
}
+ /**
+ * Compile the SQL expression and return it. Replaces any parameters with
+ * their given values.
+ *
+ * @param mixed Database instance or name of instance
+ * @return string
+ */
+ public function compile($db = NULL)
+ {
+ if ( ! is_object($db))
+ {
+ // Get the database instance
+ $db = Database::instance($db);
+ }
+
+ $value = $this->value();
+
+ if ( ! empty($this->_parameters))
+ {
+ // Quote all of the parameter values
+ $params = array_map(array($db, 'quote'), $this->_parameters);
+
+ // Replace the values in the expression
+ $value = strtr($value, $params);
+ }
+
+ return $value;
+ }
+
} // End Database_Expression
View
@@ -129,11 +129,12 @@ public static function delete($table = NULL)
* $users = ORM::factory('user')->where(DB::expr("BINARY `hash`"), '=', $hash)->find();
*
* @param string expression
+ * @param array parameters
* @return Database_Expression
*/
- public static function expr($string)
+ public static function expr($string, $parameters = array())
{
- return new Database_Expression($string);
+ return new Database_Expression($string, $parameters);
}
} // End DB

0 comments on commit f2ff545

Please sign in to comment.