+ * $qb = $conn->createQueryBuilder()
+ * ->insert('users')
+ * ->values(
+ * array(
+ * 'name' => '?',
+ * 'password' => '?'
+ * )
+ * );
+ *
+ *
+ * @param string $insert The table into which the rows should be inserted.
+ *
+ * @return QueryBuilder This QueryBuilder instance.
+ */
+ public function insert($insert = null)
+ {
+ $this->type = self::INSERT;
+
+ if ( ! $insert) {
+ return $this;
+ }
+
+ return $this->add('from', array(
+ 'table' => $insert
+ ));
+ }
+
/**
* Creates and adds a query root corresponding to the table identified by the
* given alias, forming a cartesian product with any existing query roots.
@@ -546,12 +605,12 @@ class QueryBuilder
* ->from('users', 'u')
*
*
- * @param string $from The table.
- * @param string $alias The alias of the table.
+ * @param string $from The table.
+ * @param string|null $alias The alias of the table.
*
- * @return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
+ * @return QueryBuilder This QueryBuilder instance.
*/
- public function from($from, $alias)
+ public function from($from, $alias = null)
{
return $this->add('from', array(
'table' => $from,
@@ -716,7 +775,7 @@ class QueryBuilder
*/
public function where($predicates)
{
- if ( ! (func_num_args() == 1 && $predicates instanceof CompositeExpression) ) {
+ if ( ! (func_num_args() == 1 && $predicates instanceof CompositeExpression)) {
$predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
}
@@ -743,8 +802,8 @@ class QueryBuilder
*/
public function andWhere($where)
{
- $where = $this->getQueryPart('where');
$args = func_get_args();
+ $where = $this->getQueryPart('where');
if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) {
$where->addMultiple($args);
@@ -776,8 +835,8 @@ class QueryBuilder
*/
public function orWhere($where)
{
- $where = $this->getQueryPart('where');
$args = func_get_args();
+ $where = $this->getQueryPart('where');
if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) {
$where->addMultiple($args);
@@ -842,6 +901,56 @@ class QueryBuilder
return $this->add('groupBy', $groupBy, true);
}
+ /**
+ * Sets a value for a column in an insert query.
+ *
+ *
+ * $qb = $conn->createQueryBuilder()
+ * ->insert('users')
+ * ->values(
+ * array(
+ * 'name' => '?'
+ * )
+ * )
+ * ->setValue('password', '?');
+ *
+ *
+ * @param string $column The column into which the value should be inserted.
+ * @param string $value The value that should be inserted into the column.
+ *
+ * @return QueryBuilder This QueryBuilder instance.
+ */
+ public function setValue($column, $value)
+ {
+ $this->sqlParts['values'][$column] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Specifies values for an insert query indexed by column names.
+ * Replaces any previous values, if any.
+ *
+ *
+ * $qb = $conn->createQueryBuilder()
+ * ->insert('users')
+ * ->values(
+ * array(
+ * 'name' => '?',
+ * 'password' => '?'
+ * )
+ * );
+ *
+ *
+ * @param array $values The values to specify for the insert query indexed by column names.
+ *
+ * @return QueryBuilder This QueryBuilder instance.
+ */
+ public function values(array $values)
+ {
+ return $this->add('values', $values);
+ }
+
/**
* Specifies a restriction over the groups of the query.
* Replaces any previous having restrictions, if any.
@@ -869,8 +978,8 @@ class QueryBuilder
*/
public function andHaving($having)
{
- $having = $this->getQueryPart('having');
$args = func_get_args();
+ $having = $this->getQueryPart('having');
if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) {
$having->addMultiple($args);
@@ -892,8 +1001,8 @@ class QueryBuilder
*/
public function orHaving($having)
{
- $having = $this->getQueryPart('having');
$args = func_get_args();
+ $having = $this->getQueryPart('having');
if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) {
$having->addMultiple($args);
@@ -1000,33 +1109,83 @@ class QueryBuilder
{
$query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM ';
+ $query .= implode(', ', $this->getFromClauses())
+ . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
+ . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '')
+ . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '')
+ . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : '');
+
+ if ($this->isLimitQuery()) {
+ return $this->connection->getDatabasePlatform()->modifyLimitQuery(
+ $query,
+ $this->maxResults,
+ $this->firstResult
+ );
+ }
+
+ return $query;
+ }
+
+ /**
+ * @return string[]
+ */
+ private function getFromClauses()
+ {
$fromClauses = array();
$knownAliases = array();
// Loop through all FROM clauses
foreach ($this->sqlParts['from'] as $from) {
- $knownAliases[$from['alias']] = true;
- $fromClause = $from['table'] . ' ' . $from['alias']
- . $this->getSQLForJoins($from['alias'], $knownAliases);
+ if ($from['alias'] === null) {
+ $tableSql = $from['table'];
+ $tableReference = $from['table'];
+ } else {
+ $tableSql = $from['table'] . ' ' . $from['alias'];
+ $tableReference = $from['alias'];
+ }
+
+ $knownAliases[$tableReference] = true;
- $fromClauses[$from['alias']] = $fromClause;
+ $fromClauses[$tableReference] = $tableSql . $this->getSQLForJoins($tableReference, $knownAliases);
}
+ $this->verifyAllAliasesAreKnown($knownAliases);
+
+ return $fromClauses;
+ }
+
+ /**
+ * @param array $knownAliases
+ *
+ * @throws QueryException
+ */
+ private function verifyAllAliasesAreKnown(array $knownAliases)
+ {
foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
- if ( ! isset($knownAliases[$fromAlias]) ) {
+ if ( ! isset($knownAliases[$fromAlias])) {
throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases));
}
}
+ }
- $query .= implode(', ', $fromClauses)
- . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
- . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '')
- . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '')
- . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : '');
+ /**
+ * @return bool
+ */
+ private function isLimitQuery()
+ {
+ return $this->maxResults !== null || $this->firstResult !== null;
+ }
- return ($this->maxResults === null && $this->firstResult == null)
- ? $query
- : $this->connection->getDatabasePlatform()->modifyLimitQuery($query, $this->maxResults, $this->firstResult);
+ /**
+ * Converts this instance into an INSERT string in SQL.
+ *
+ * @return string
+ */
+ private function getSQLForInsert()
+ {
+ return 'INSERT INTO ' . $this->sqlParts['from']['table'] .
+ ' (' . implode(', ', array_keys($this->sqlParts['values'])) . ')' .
+ ' VALUES(' . implode(', ', $this->sqlParts['values']) . ')';
}
/**
@@ -1038,8 +1197,8 @@ class QueryBuilder
{
$table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
$query = 'UPDATE ' . $table
- . ' SET ' . implode(", ", $this->sqlParts['set'])
- . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
+ . ' SET ' . implode(", ", $this->sqlParts['set'])
+ . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
return $query;
}
@@ -1097,9 +1256,9 @@ class QueryBuilder
*
* @return string the placeholder name used.
*/
- public function createNamedParameter( $value, $type = \PDO::PARAM_STR, $placeHolder = null )
+ public function createNamedParameter($value, $type = \PDO::PARAM_STR, $placeHolder = null)
{
- if ( $placeHolder === null ) {
+ if ($placeHolder === null) {
$this->boundCounter++;
$placeHolder = ":dcValue" . $this->boundCounter;
}
@@ -1134,6 +1293,7 @@ class QueryBuilder
{
$this->boundCounter++;
$this->setParameter($this->boundCounter, $value, $type);
+
return "?";
}
@@ -1149,11 +1309,16 @@ class QueryBuilder
if (isset($this->sqlParts['join'][$fromAlias])) {
foreach ($this->sqlParts['join'][$fromAlias] as $join) {
+ if (array_key_exists($join['joinAlias'], $knownAliases)) {
+ throw QueryException::nonUniqueAlias($join['joinAlias'], array_keys($knownAliases));
+ }
$sql .= ' ' . strtoupper($join['joinType'])
- . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
- . ' ON ' . ((string) $join['joinCondition']);
+ . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
+ . ' ON ' . ((string) $join['joinCondition']);
$knownAliases[$join['joinAlias']] = true;
+ }
+ foreach ($this->sqlParts['join'][$fromAlias] as $join) {
$sql .= $this->getSQLForJoins($join['joinAlias'], $knownAliases);
}
}
@@ -1175,13 +1340,13 @@ class QueryBuilder
$this->sqlParts[$part][$idx] = clone $element;
}
}
- } else if (is_object($elements)) {
+ } elseif (is_object($elements)) {
$this->sqlParts[$part] = clone $elements;
}
}
foreach ($this->params as $name => $param) {
- if(is_object($param)){
+ if (is_object($param)) {
$this->params[$name] = clone $param;
}
}
diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php
index aeeaab396d..92c9336d6e 100644
--- a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php
+++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php
@@ -38,4 +38,17 @@ class QueryException extends DBALException
"any FROM or JOIN clause table. The currently registered " .
"aliases are: " . implode(", ", $registeredAliases) . ".");
}
+
+ /**
+ * @param string $alias
+ * @param array $registeredAliases
+ *
+ * @return \Doctrine\DBAL\Query\QueryException
+ */
+ static public function nonUniqueAlias($alias, $registeredAliases)
+ {
+ return new self("The given alias '" . $alias . "' is not unique " .
+ "in FROM and JOIN clause table. The currently registered " .
+ "aliases are: " . implode(", ", $registeredAliases) . ".");
+ }
}
diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php
index cd1e0c7795..a9037ffc5f 100644
--- a/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php
+++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php
@@ -35,6 +35,7 @@ class SQLParserUtils
const ESCAPED_SINGLE_QUOTED_TEXT = "'(?:[^'\\\\]|\\\\'?)*'";
const ESCAPED_DOUBLE_QUOTED_TEXT = '"(?:[^"\\\\]|\\\\"?)*"';
const ESCAPED_BACKTICK_QUOTED_TEXT = '`(?:[^`\\\\]|\\\\`?)*`';
+ const ESCAPED_BRACKET_QUOTED_TEXT = '\[(?:[^\]])*\]';
/**
* Gets an array of the placeholders in an sql statements as keys and their positions in the query string.
@@ -89,6 +90,11 @@ class SQLParserUtils
$arrayPositions = array();
$bindIndex = -1;
+ if ($isPositional) {
+ ksort($params);
+ ksort($types);
+ }
+
foreach ($types as $name => $type) {
++$bindIndex;
@@ -112,6 +118,8 @@ class SQLParserUtils
if ($isPositional) {
$paramOffset = 0;
$queryOffset = 0;
+ $params = array_values($params);
+ $types = array_values($types);
foreach ($paramPos as $needle => $needlePos) {
if ( ! isset($arrayPositions[$needle])) {
@@ -195,8 +203,9 @@ class SQLParserUtils
{
$literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' .
self::ESCAPED_DOUBLE_QUOTED_TEXT . '|' .
- self::ESCAPED_BACKTICK_QUOTED_TEXT;
- preg_match_all("/([^'\"`]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE);
+ self::ESCAPED_BACKTICK_QUOTED_TEXT . '|' .
+ self::ESCAPED_BRACKET_QUOTED_TEXT;
+ preg_match_all("/([^'\"`\[]+)(?:$literal)?/s", $statement, $fragments, PREG_OFFSET_CAPTURE);
return $fragments[1];
}
diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php
index 6ac6e9051f..25c7209c7b 100644
--- a/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php
+++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php
@@ -24,7 +24,7 @@ namespace Doctrine\DBAL;
/**
* Doctrine\DBAL\ConnectionException
*
- * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
* @link www.doctrine-project.org
* @since 2.4
* @author Lars Strojny