private function AppendOnDuplicateKeyUpdate(QueryBuilder $QueryBuilder, $TableName, array $Columns, array $PrimaryKeyIdentifiers) { $QueryBuilder->Append(' ON DUPLICATE KEY UPDATE '); $FirstPrimaryKey = true; foreach ($QueryBuilder->Delimit($Columns, ',') as $ColumName => $Column) { $ColumnIdentifier = [$TableName, $ColumName]; if ($FirstPrimaryKey && $Column->IsPrimaryKey()) { /* * Ugly fix/hack to prevent mysql from updating primary key when encountering * a duplicate value on a seperate unique constraint. Sadly Mysql does not support * the more robust 'MERGE' operation. Furthermore there is no clean way to throw a * conditional runtime error in Mysql reliably. * * Example: Persisting a account entity with a unique username, if the user changes * their username and and a duplicate username exists, mysql could attempt to update * the other duplicate row with the new values/primary key. This should not be an * issue as then it will fail with a duplicate primary key but could lead to some * wacky edge cases that I want no part in. */ $QueryBuilder->AppendIdentifier('# = IF(', $ColumnIdentifier); foreach ($QueryBuilder->Delimit($PrimaryKeyIdentifiers, ' AND ') as $PrimaryKeyIdentifier) { $QueryBuilder->AppendIdentifier('# = VALUES(#)', $PrimaryKeyIdentifier); } $QueryBuilder->Append(','); $QueryBuilder->AppendIdentifier('VALUES(#)', $ColumnIdentifier); $QueryBuilder->Append(','); $QueryBuilder->Append('(SELECT 1 UNION ALL SELECT 1))'); $FirstPrimaryKey = false; } else { $QueryBuilder->AppendIdentifier('# = VALUES(#)', $ColumnIdentifier); } } }
protected function AppendCompoundBoolean(QueryBuilder $QueryBuilder, E\CompoundBooleanExpression $Expression) { $LogicalOperatorString = $this->GetBinaryOperatorString($Expression->GetLogicalOperator()); $BooleanExpressions = $Expression->GetBooleanExpressions(); foreach ($QueryBuilder->Delimit($BooleanExpressions, $LogicalOperatorString) as $BooleanExpression) { $this->Append($QueryBuilder, $BooleanExpression); } }
protected function AppendOrderByExpressions(QueryBuilder $QueryBuilder, \SplObjectStorage $ExpressionAscendingMap) { $QueryBuilder->Append(' ORDER BY '); foreach ($QueryBuilder->Delimit($ExpressionAscendingMap, ', ') as $Expression) { $Ascending = $ExpressionAscendingMap[$Expression]; $Direction = $Ascending ? 'ASC' : 'DESC'; $QueryBuilder->AppendExpression($Expression); $QueryBuilder->Append(' ' . $Direction); } }
protected function UpdateQuery(QueryBuilder $QueryBuilder, Relational\Procedure $Procedure) { $TableNames = array_map(function ($Table) { return $Table->GetName(); }, $Procedure->GetTables()); $QueryBuilder->AppendIdentifiers('UPDATE # SET ', $TableNames, ','); foreach ($QueryBuilder->Delimit($Procedure->GetExpressions(), ',') as $Expression) { $QueryBuilder->AppendExpression($Expression); } $this->AppendCriterion($QueryBuilder, $Procedure->GetCriterion()); }
public function AppendDataAsInlineRow(QueryBuilder $QueryBuilder, array $Columns, Relational\ColumnData $ColumnData) { $QueryBuilder->Append(' SELECT '); foreach ($QueryBuilder->Delimit($Columns, ', ') as $Column) { $QueryBuilder->AppendExpression(Expression::PersistData($Column, Expression::Constant($ColumnData[$Column]))); } }