silverstripe-framework/src/ORM/Queries/SQLExpression.php

125 lines
3.0 KiB
PHP

<?php
namespace SilverStripe\ORM\Queries;
use SilverStripe\Core\Convert;
use SilverStripe\ORM\Connect\Query;
use SilverStripe\ORM\DB;
use Exception;
/**
* Abstract base class for an object representing an SQL query.
* The various parts of the SQL query can be manipulated individually.
*/
abstract class SQLExpression {
/**
* 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();
/**
* Swap some text in the SQL query with another.
*
* Note that values in parameters will not be replaced
*
* @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;
}
/**
* Return the generated SQL string for this query
*
* @todo Is it ok for this to consider parameters? Test cases here!
*
* @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>";
}
}
/**
* Swap the use of one table with another.
*
* @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));
}
/**
* Determine if this query is empty, and thus cannot be executed
*
* @return bool Flag indicating that this query is empty
*/
abstract public function isEmpty();
/**
* Generate the SQL statement for this query.
*
* @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);
if(empty($sql)) return null;
if($this->replacementsOld) {
$sql = str_replace($this->replacementsOld, $this->replacementsNew, $sql);
}
return $sql;
}
/**
* Execute this query.
*
* @return 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
*
* @param SQLExpression $object The object to copy properties to
*/
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;
}
}
}
}