示例#1
0
 /**
  * Walks down a SelectStatement AST node, wrapping it in a COUNT (SELECT DISTINCT)
  *
  * Note that the ORDER BY clause is not removed. Many SQL implementations (e.g. MySQL)
  * are able to cache subqueries. By keeping the ORDER BY clause intact, the limitSubQuery
  * that will most likely be executed next can be read from the native SQL cache.
  *
  * @param SelectStatement $AST
  * @return string
  */
 public function walkSelectStatement(SelectStatement $AST)
 {
     $sql = parent::walkSelectStatement($AST);
     // Find out the SQL alias of the identifier column of the root entity
     // It may be possible to make this work with multiple root entities but that
     // would probably require issuing multiple queries or doing a UNION SELECT
     // so for now, It's not supported.
     // Get the root entity and alias from the AST fromClause
     $from = $AST->fromClause->identificationVariableDeclarations;
     if (count($from) > 1) {
         throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
     }
     $rootClass = $from[0]->rangeVariableDeclaration->abstractSchemaName;
     $rootAlias = $from[0]->rangeVariableDeclaration->aliasIdentificationVariable;
     // Get the identity properties from the metadata
     $rootIdentifier = $this->queryComponents[$rootAlias]['metadata']->identifier;
     // For every identifier, find out the SQL alias by combing through the ResultSetMapping
     $sqlIdentifier = array();
     foreach ($rootIdentifier as $property) {
         foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) {
             if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
                 $sqlIdentifier[$property] = $alias;
             }
         }
     }
     if (count($rootIdentifier) != count($sqlIdentifier)) {
         throw new \RuntimeException(sprintf('Not all identifier properties can be found in the ResultSetMapping: %s', implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier)))));
     }
     // Build the counter query
     return sprintf('SELECT %s AS _dctrn_count FROM (SELECT DISTINCT %s FROM (%s) AS _dctrn_result) AS _dctrn_table', $this->platform->getCountExpression('*'), implode(', ', $sqlIdentifier), $sql);
 }
 /**
  * @group DBAL-374
  */
 public function testQuotedColumnInIndexPropagation()
 {
     $this->markTestSkipped('requires big refactoring of Platforms');
     $table = new Table('`quoted`');
     $table->addColumn('`key`', 'string');
     $table->addIndex(array('key'));
     $sql = $this->_platform->getCreateTableSQL($table);
     $this->assertEquals($this->getQuotedColumnInIndexSQL(), $sql);
 }
 /**
  * Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT
  *
  * @param SelectStatement $AST
  * @return string
  */
 public function walkSelectStatement(SelectStatement $AST)
 {
     $innerSql = parent::walkSelectStatement($AST);
     // Find out the SQL alias of the identifier column of the root entity
     // It may be possible to make this work with multiple root entities but that
     // would probably require issuing multiple queries or doing a UNION SELECT
     // so for now, It's not supported.
     // Get the root entity and alias from the AST fromClause
     $from = $AST->fromClause->identificationVariableDeclarations;
     if (count($from) !== 1) {
         throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
     }
     $rootAlias = $from[0]->rangeVariableDeclaration->aliasIdentificationVariable;
     $rootClass = $this->queryComponents[$rootAlias]['metadata'];
     $rootIdentifier = $rootClass->identifier;
     // For every identifier, find out the SQL alias by combing through the ResultSetMapping
     $sqlIdentifier = array();
     foreach ($rootIdentifier as $property) {
         if (isset($rootClass->fieldMappings[$property])) {
             foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) {
                 if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
                     $sqlIdentifier[$property] = $alias;
                 }
             }
         }
         if (isset($rootClass->associationMappings[$property])) {
             $joinColumn = $rootClass->associationMappings[$property]['joinColumns'][0]['name'];
             foreach (array_keys($this->rsm->metaMappings, $joinColumn) as $alias) {
                 if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
                     $sqlIdentifier[$property] = $alias;
                 }
             }
         }
     }
     if (count($rootIdentifier) != count($sqlIdentifier)) {
         throw new \RuntimeException(sprintf('Not all identifier properties can be found in the ResultSetMapping: %s', implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier)))));
     }
     // Build the counter query
     $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result', implode(', ', $sqlIdentifier), $innerSql);
     if ($this->platform instanceof PostgreSqlPlatform) {
         //http://www.doctrine-project.org/jira/browse/DDC-1958
         $this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql);
     }
     // Apply the limit and offset
     $sql = $this->platform->modifyLimitQuery($sql, $this->maxResults, $this->firstResult);
     // Add the columns to the ResultSetMapping. It's not really nice but
     // it works. Preferably I'd clear the RSM or simply create a new one
     // but that is not possible from inside the output walker, so we dirty
     // up the one we have.
     foreach ($sqlIdentifier as $property => $alias) {
         $this->rsm->addScalarResult($alias, $property);
     }
     return $sql;
 }
示例#4
0
 /**
  * Lock all rows of this entity matching the given criteria with the specified pessimistic lock mode
  *
  * @param array $criteria
  * @param int $lockMode
  * @return void
  */
 public function lock(array $criteria, $lockMode)
 {
     $conditionSql = $this->_getSelectConditionSQL($criteria);
     if ($lockMode == LockMode::PESSIMISTIC_READ) {
         $lockSql = $this->_platform->getReadLockSql();
     } else {
         if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
             $lockSql = $this->_platform->getWriteLockSql();
         }
     }
     $sql = 'SELECT 1 ' . $this->_platform->appendLockHint($this->getLockTablesSql(), $lockMode) . ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql;
     list($params, $types) = $this->expandParameters($criteria);
     $stmt = $this->_conn->executeQuery($sql, $params, $types);
 }
 /**
  * Lock all rows of this entity matching the given criteria with the specified pessimistic lock mode
  *
  * @param array $criteria
  * @param int $lockMode
  * @return void
  */
 public function lock(array $criteria, $lockMode)
 {
     $conditionSql = $this->_getSelectConditionSQL($criteria);
     if ($lockMode == LockMode::PESSIMISTIC_READ) {
         $lockSql = $this->_platform->getReadLockSql();
     } else {
         if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
             $lockSql = $this->_platform->getWriteLockSql();
         }
     }
     $sql = 'SELECT 1 ' . $this->getLockTablesSql() . ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql;
     $params = array_values($criteria);
     $this->_conn->executeQuery($sql, $params);
 }
 /**
  * Lock all rows of this entity matching the given criteria with the specified pessimistic lock mode
  *
  * @param array $criteria
  * @param int $lockMode
  * @return void
  */
 public function lock(array $criteria, $lockMode)
 {
     $conditionSql = $this->_getSelectConditionSQL($criteria);
     if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ) {
         $lockSql = $this->_platform->getReadLockSql();
     } else {
         if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) {
             $lockSql = $this->_platform->getWriteLockSql();
         }
     }
     $sql = 'SELECT 1 FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $this->_getSQLTableAlias($this->_class->name) . ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql;
     $params = array_values($criteria);
     $this->_conn->executeQuery($sql, $params);
 }
 private function getRevisionId()
 {
     if ($this->revisionId === null) {
         $date = date_create("now")->format($this->platform->getDateTimeFormatString());
         if ($this->config->getCurrentUser() != null) {
             $userId = $this->config->getCurrentUser()->getId();
         } else {
             $userId = null;
         }
         $this->conn->insert($this->config->getRevisionTableName(), array('timestamp' => $date, 'user_id' => $userId, 'note' => $this->config->getNote(), 'ipaddress' => $this->config->getIpAddress()));
         $sequenceName = $this->platform->supportsSequences() ? 'REVISIONS_ID_SEQ' : null;
         $this->revisionId = $this->conn->lastInsertId($sequenceName);
     }
     return $this->revisionId;
 }
示例#8
0
 /**
  * Gets the SQL snippet for all join columns of the given class that are to be
  * placed in an SQL SELECT statement.
  *
  * @param $class
  * @return string
  * @todo Not reused... inline?
  */
 private function _getSelectJoinColumnsSQL(ClassMetadata $class)
 {
     $sql = '';
     foreach ($class->associationMappings as $assoc) {
         if ($assoc->isOwningSide && $assoc->isOneToOne()) {
             foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
                 $columnAlias = $srcColumn . $this->_sqlAliasCounter++;
                 $sql .= ', ' . $this->_getSQLTableAlias($this->_class->name) . ".{$srcColumn} AS {$columnAlias}";
                 $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
                 if (!isset($this->_resultColumnNames[$resultColumnName])) {
                     $this->_resultColumnNames[$resultColumnName] = $srcColumn;
                 }
             }
         }
     }
     return $sql;
 }
示例#9
0
 /**
  * Shrani array sprememb entitet v bazo
  *
  * @param array $changes
  */
 protected function saveChanges($changes)
 {
     $sql = "INSERT INTO {$this->tableName} (razred, objectId, upor, datum, tip, data)\n                VALUES (?, ?, ?, ?, ?, ?)";
     $stmt = $this->conn->prepare($sql);
     $date = date_create("now")->format($this->platform->getDateTimeFormatString());
     $user = $this->identity ? $this->identity->getId() : null;
     foreach ($changes as $objectId => $change) {
         $class = get_class($change['entity']);
         $type = $change['type'];
         $data = serialize($change['data']);
         $stmt->bindValue(1, $class, \PDO::PARAM_STR);
         $stmt->bindValue(2, $objectId, \PDO::PARAM_STR);
         $stmt->bindValue(3, $user, \PDO::PARAM_STR);
         $stmt->bindValue(4, $date, \PDO::PARAM_STR);
         $stmt->bindValue(5, $type, \PDO::PARAM_STR);
         $stmt->bindValue(6, $data, \PDO::PARAM_STR);
         $stmt->execute();
     }
 }
 /**
  * Get the SQL Statements to drop the given schema from underlying db.
  *
  * @param Schema $dropSchema
  * @return array
  */
 public function getDropSchema(Schema $dropSchema)
 {
     $visitor = new DropSchemaSqlCollector($this->platform);
     $sm = $this->conn->getSchemaManager();
     $fullSchema = $sm->createSchema();
     foreach ($fullSchema->getTables() as $table) {
         if ($dropSchema->hasTable($table->getName())) {
             $visitor->acceptTable($table);
         }
         foreach ($table->getForeignKeys() as $foreignKey) {
             if (!$dropSchema->hasTable($table->getName())) {
                 continue;
             }
             if (!$dropSchema->hasTable($foreignKey->getForeignTableName())) {
                 continue;
             }
             $visitor->acceptForeignKey($table, $foreignKey);
         }
     }
     if (!$this->platform->supportsSequences()) {
         return $visitor->getQueries();
     }
     foreach ($dropSchema->getSequences() as $sequence) {
         $visitor->acceptSequence($sequence);
     }
     foreach ($dropSchema->getTables() as $table) {
         /* @var $sequence Table */
         if (!$table->hasPrimaryKey()) {
             continue;
         }
         $columns = $table->getPrimaryKey()->getColumns();
         if (count($columns) > 1) {
             continue;
         }
         $checkSequence = $table->getName() . "_" . $columns[0] . "_seq";
         if ($fullSchema->hasSequence($checkSequence)) {
             $visitor->acceptSequence($fullSchema->getSequence($checkSequence));
         }
     }
     return $visitor->getQueries();
 }
示例#11
0
 /**
  * Gets an SQL column alias for a column name.
  *
  * @param string $columnName
  * @return string
  */
 public function getSQLColumnAlias($columnName)
 {
     // Trim the column alias to the maximum identifier length of the platform.
     // If the alias is to long, characters are cut off from the beginning.
     return $this->_platform->getSQLResultCasing(substr($columnName . $this->_sqlAliasCounter++, -$this->_platform->getMaxIdentifierLength()));
 }
示例#12
0
 /**
  * rollbackSavePoint
  * releases given savepoint
  *
  * @param string $savepoint     name of a savepoint to rollback to
  * @return void
  */
 public function rollbackSavepoint($savepoint)
 {
     if (!$this->_platform->supportsSavepoints()) {
         throw ConnectionException::savepointsNotSupported();
     }
     $this->_conn->exec($this->_platform->rollbackSavePoint($savepoint));
 }
示例#13
0
 /**
  * Quote a string so it can be safely used as a table or column name, even if
  * it is a reserved name.
  *
  * Delimiting style depends on the underlying database platform that is being used.
  *
  * NOTE: Just because you CAN use quoted identifiers does not mean
  * you SHOULD use them. In general, they end up causing way more
  * problems than they solve.
  *
  * @param string $str The name to be quoted.
  * @return string The quoted name.
  */
 public function quoteIdentifier($str)
 {
     return $this->_platform->quoteIdentifier($str);
 }
 /**
  * @group DBAL-45
  */
 public function testKeywordList()
 {
     $keywordList = $this->_platform->getReservedKeywordsList();
     $this->assertInstanceOf('Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList', $keywordList);
     $this->assertTrue($keywordList->isKeyword('table'));
 }
 public function testGetCustomColumnDeclarationSql()
 {
     $field = array('columnDefinition' => 'MEDIUMINT(6) UNSIGNED');
     $this->assertEquals('foo MEDIUMINT(6) UNSIGNED', $this->_platform->getColumnDeclarationSQL('foo', $field));
 }
示例#16
0
 /**
  * Sets the transaction isolation level.
  *
  * @param integer $level The level to set.
  */
 public function setTransactionIsolation($level)
 {
     $this->_transactionIsolationLevel = $level;
     return $this->exec($this->_platform->getSetTransactionIsolationSql($level));
 }