2013-06-21 00:32:08 +02:00
|
|
|
<?php
|
|
|
|
|
2016-06-15 06:03:16 +02:00
|
|
|
namespace SilverStripe\ORM\Queries;
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
use Convert;
|
2016-06-23 01:37:22 +02:00
|
|
|
use SilverStripe\ORM\Connect\SS_Query;
|
2016-06-15 06:03:16 +02:00
|
|
|
use SilverStripe\ORM\DB;
|
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Abstract base class for an object representing an SQL query.
|
|
|
|
* The various parts of the SQL query can be manipulated individually.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @package framework
|
2016-06-15 06:03:16 +02:00
|
|
|
* @subpackage orm
|
2013-06-21 00:32:08 +02:00
|
|
|
*/
|
|
|
|
abstract class SQLExpression {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Keep an internal register of find/replace pairs to execute when it's time to actually get the
|
|
|
|
* query SQL.
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $replacementsOld = array();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Keep an internal register of find/replace pairs to execute when it's time to actually get the
|
|
|
|
* query SQL.
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $replacementsNew = array();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Swap some text in the SQL query with another.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* Note that values in parameters will not be replaced
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @param string $old The old text (escaped)
|
|
|
|
* @param string $new The new text (escaped)
|
|
|
|
*/
|
|
|
|
public function replaceText($old, $new) {
|
|
|
|
$this->replacementsOld[] = $old;
|
|
|
|
$this->replacementsNew[] = $new;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Return the generated SQL string for this query
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @todo Is it ok for this to consider parameters? Test cases here!
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function __toString() {
|
|
|
|
try {
|
|
|
|
$sql = $this->sql($parameters);
|
|
|
|
if(!empty($parameters)) {
|
|
|
|
$sql .= " <" . var_export($parameters, true) . ">";
|
|
|
|
}
|
|
|
|
return $sql;
|
|
|
|
} catch(Exception $e) {
|
|
|
|
return "<sql query>";
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Swap the use of one table with another.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @param string $old Name of the old table (unquoted, escaped)
|
|
|
|
* @param string $new Name of the new table (unquoted, escaped)
|
|
|
|
*/
|
|
|
|
public function renameTable($old, $new) {
|
|
|
|
$this->replaceText("`$old`", "`$new`");
|
|
|
|
$this->replaceText("\"$old\"", "\"$new\"");
|
|
|
|
$this->replaceText(Convert::symbol2sql($old), Convert::symbol2sql($new));
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Determine if this query is empty, and thus cannot be executed
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @return bool Flag indicating that this query is empty
|
|
|
|
*/
|
|
|
|
abstract public function isEmpty();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Generate the SQL statement for this query.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @param array $parameters Out variable for parameters required for this query
|
|
|
|
* @return string The completed SQL query
|
|
|
|
*/
|
|
|
|
public function sql(&$parameters = array()) {
|
|
|
|
// Build each component as needed
|
|
|
|
$sql = DB::build_sql($this, $parameters);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
if(empty($sql)) return null;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
if($this->replacementsOld) {
|
|
|
|
$sql = str_replace($this->replacementsOld, $this->replacementsNew, $sql);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
return $sql;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Execute this query.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @return SS_Query
|
|
|
|
*/
|
|
|
|
public function execute() {
|
|
|
|
$sql = $this->sql($parameters);
|
|
|
|
return DB::prepared_query($sql, $parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies the query parameters contained in this object to another
|
|
|
|
* SQLExpression
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2016-05-25 07:30:01 +02:00
|
|
|
* @param SQLExpression $object The object to copy properties to
|
2013-06-21 00:32:08 +02:00
|
|
|
*/
|
|
|
|
protected function copyTo(SQLExpression $object) {
|
|
|
|
$target = array_keys(get_object_vars($object));
|
|
|
|
foreach(get_object_vars($this) as $variable => $value) {
|
|
|
|
if(in_array($variable, $target)) {
|
|
|
|
$object->$variable = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|