diff --git a/.gitignore b/.gitignore index 53b0f71..5a913a0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .project .vagrant .phpunit.result.cache +*.cache *-console.log .crate-docs /composer.lock diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..94aaa75 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,28 @@ +in(__DIR__) + ->exclude('build') + ->exclude('vendor') +; + +return (new PhpCsFixer\Config()) + ->setUnsupportedPhpVersionAllowed(true) + ->setRules([ + // '@auto' => true, + // '@PHP7x3Migration' => true, + // '@PSR1' => true, + // '@PSR2' => true, + // '@PSR12' => true, + // '@Symfony' => true, + // 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => true, + // 'strict_param' => true, + ]) + ->setFinder($finder) + ; + +?> diff --git a/CHANGES.txt b/CHANGES.txt index d70514a..99dd0b2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,8 @@ CHANGES for crate-dbal Unreleased ========== +- Added support for Doctrine DBAL 3, dropped support for Doctrine DBAL 2. + 2025/11/13 4.0.3 ================ diff --git a/composer.json b/composer.json index 3b7f755..7b7da2f 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "prefer-stable": true, "require": { "php": "^8.0|^8.1|^8.2|^8.3|^8.4|^8.5", - "doctrine/dbal": "^2", + "doctrine/dbal": "^3", "crate/crate-pdo": "^2", "ext-pdo": "*" }, @@ -27,12 +27,14 @@ }, "require-dev": { "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "^3.5" + "friendsofphp/php-cs-fixer": "^3.89" }, "autoload-dev": { "psr-0": { - "Crate\\Test": "test", - "Doctrine\\Tests": "vendor/doctrine/dbal/tests" + "Crate\\Test": "test" + }, + "psr-4": { + "Doctrine\\DBAL\\Tests\\": "vendor/doctrine/dbal/tests" } }, "config": { @@ -42,7 +44,7 @@ }, "scripts": { "test": "XDEBUG_MODE=coverage phpunit --coverage-clover build/logs/clover.xml", - "check-style": "phpcs", - "fix-style": "phpcbf" + "check-style": "php-cs-fixer check", + "fix-style": "php-cs-fixer fix" } } diff --git a/docs/appendices/data-types.rst b/docs/appendices/data-types.rst index e5786b4..bef578d 100644 --- a/docs/appendices/data-types.rst +++ b/docs/appendices/data-types.rst @@ -89,8 +89,8 @@ Here's an example of how the ``MapType`` can be used: $objDefinition = array( 'type' => MapType::STRICT, 'fields' => array( - new Column('id', Type::getType('integer'), array()), - new Column('name', Type::getType('string'), array()), + new Column('id', Type::getType('integer'), array()), + new Column('name', Type::getType('string'), array()), ), ); $table->addColumn( diff --git a/docs/appendices/table-options.rst b/docs/appendices/table-options.rst index 87471e0..0bb0c25 100644 --- a/docs/appendices/table-options.rst +++ b/docs/appendices/table-options.rst @@ -18,7 +18,7 @@ Example: $options = []; $options['sharding_shards'] = 5; - $myTable = new Table('my_table', [], [], [], 0, $options); + $myTable = new Table('my_table', [], [], [], [], $options); Sharding Options @@ -66,7 +66,7 @@ Example on how to adjust the replicas: $options = []; $options['table_options'] = []; $options['table_options']['number_of_replicas'] = '2'; - $myTable = new Table('my_table', [], [], [], 0, $options); + $myTable = new Table('my_table', [], [], [], [], $options); .. _CrateDB CREATE TABLE Documentation: https://cratedb.com/docs/crate/reference/en/latest/sql/statements/create-table.html diff --git a/docs/connect.rst b/docs/connect.rst index 119deac..3a4cfe8 100644 --- a/docs/connect.rst +++ b/docs/connect.rst @@ -29,14 +29,16 @@ If you plan to query CrateDB via DBAL, you can get a connection from the .. code-block:: php + use Doctrine\DBAL\DriverManager; + $params = array( 'driverClass' => 'Crate\DBAL\Driver\PDOCrate\Driver', 'user' => 'crate', 'host' => 'localhost', 'port' => 4200 ); - $connection = \Doctrine\DBAL\DriverManager::getConnection($params); - $schemaManager = $connection->getSchemaManager(); + $connection = DriverManager::getConnection($params); + $schemaManager = $connection->createSchemaManager(); With these connection parameters, the ``DriverManager`` will attempt to authenticate as ``crate`` with a CrateDB node listening on ``localhost:4200``. diff --git a/examples/objects.php b/examples/objects.php new file mode 100644 index 0000000..4c4f61e --- /dev/null +++ b/examples/objects.php @@ -0,0 +1,62 @@ + MapType::STRICT, + 'fields' => array( + new Column('id', Type::getType('integer'), array()), + new Column('name', Type::getType('string'), array()), + ), +); +$table->addColumn( + 'data', + MapType::NAME, + array('platformOptions' => $objDefinition), +); + +// Register driver. +$dsnParser = new DsnParser(array('crate' => 'Crate\DBAL\Driver\PDOCrate\Driver')); + +// Connect to database. +$connectionParams = $dsnParser->parse('crate://crate:crate@localhost:4200/'); +$connection = DriverManager::getConnection($connectionParams); +$schemaManager = $connection->createSchemaManager(); + +// Provision database table. +try { + $schemaManager->dropTable($table->getName()); +} catch (TableNotFoundException) { +} +$schemaManager->createTable($table); + +// Insert data. +$connection->insert('example', array('data' => array('id' => 42, 'name' => 'foo')), array('data' => 'map')); +$connection->insert('example', array('data' => array('id' => 43, 'name' => 'bar')), array('data' => 'map')); +$connection->executeStatement('REFRESH TABLE example'); + +// Query data. +$result = $connection->executeQuery('SELECT * FROM example'); +print_r($result->fetchAllAssociative()); + +?> diff --git a/src/Crate/DBAL/Driver/PDOCrate/CrateStatement.php b/src/Crate/DBAL/Driver/PDOCrate/CrateStatement.php index fb26dac..54c384e 100644 --- a/src/Crate/DBAL/Driver/PDOCrate/CrateStatement.php +++ b/src/Crate/DBAL/Driver/PDOCrate/CrateStatement.php @@ -1,4 +1,5 @@ $options + */ + public function __construct(PDOInterface $pdo, $sql, $options = []) + { + $this->pdo = $pdo; + $this->stmt = $pdo->prepare($sql, $options); + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindValue() instead.', + ); + } + try { + $this->stmt->execute($params); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + return new Result($this); + } + + /** + * {@inheritDoc} + */ + public function columnCount(): int + { + return $this->stmt->columnCount(); + } + + /** + * {@inheritDoc} + */ + public function rowCount(): int + { + return $this->stmt->rowCount(); + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + return $this->stmt->bindValue($param, $value, $type); + } + + /** + * @deprecated Use bindValue() instead. + * {@inheritDoc} + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + 'Statement::bindParam() was deprecated. Please use Statement::bindValue() instead.', + ); + return $this->stmt->bindParam($param, $variable, $type, $length); + } + + /** + * {@inheritDoc} + */ + public function fetch( + $fetch_style = PDO::FETCH_ASSOC, + $cursor_orientation = PDO::FETCH_ORI_NEXT, + $cursor_offset = 0, + ) { + return $this->stmt->fetch($fetch_style, $cursor_orientation, $cursor_offset); + } + + public function fetchColumn($column_number = 0) + { + return $this->stmt->fetchColumn($column_number); + } + + /** + * {@inheritDoc} + */ + public function closeCursor(): bool + { + try { + return $this->stmt->closeCursor(); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Gets the wrapped CrateDB PDOStatement. + * + * @return PDOStatement + */ + public function getWrappedStatement(): PDOStatement + { + return $this->stmt; + } } diff --git a/src/Crate/DBAL/Driver/PDOCrate/Driver.php b/src/Crate/DBAL/Driver/PDOCrate/Driver.php index 4734406..445e0e8 100644 --- a/src/Crate/DBAL/Driver/PDOCrate/Driver.php +++ b/src/Crate/DBAL/Driver/PDOCrate/Driver.php @@ -1,4 +1,5 @@ constructPdoDsn($params), $username, $password, $driverOptions); } @@ -50,7 +59,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function constructPdoDsn(array $params) + private function constructPdoDsn(array $params): string { $dsn = self::NAME . ':'; if (isset($params['host']) && $params['host'] != '') { @@ -66,23 +75,24 @@ private function constructPdoDsn(array $params) /** * {@inheritDoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform(): AbstractPlatform { - return new CratePlatform(); + return new CratePlatform4(); } /** * {@inheritDoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager { - return new CrateSchemaManager($conn); + // Added by Doctrine 3. + return new CrateSchemaManager($conn, $platform); } /** * {@inheritDoc} */ - public function getName() + public function getName(): string { return self::NAME; } @@ -90,7 +100,7 @@ public function getName() /** * {@inheritDoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn): string|null { return null; } @@ -98,7 +108,7 @@ public function getDatabase(Connection $conn) /** * {@inheritDoc} */ - public function createDatabasePlatformForVersion($version) + public function createDatabasePlatformForVersion($version): AbstractPlatform { if (version_compare($version, self::VERSION_057, "<")) { return new CratePlatform(); @@ -108,4 +118,13 @@ public function createDatabasePlatformForVersion($version) return new CratePlatform4(); } } + + /** + * {@inheritDoc} + */ + public function getExceptionConverter(): ExceptionConverter + { + // Added by Doctrine 3. + return new ExceptionConverter(); + } } diff --git a/src/Crate/DBAL/Driver/PDOCrate/ExceptionConverter.php b/src/Crate/DBAL/Driver/PDOCrate/ExceptionConverter.php new file mode 100644 index 0000000..c2de88c --- /dev/null +++ b/src/Crate/DBAL/Driver/PDOCrate/ExceptionConverter.php @@ -0,0 +1,58 @@ +getCode()) { + case '4000': + return new SyntaxErrorException($exception, $query); + + case '4008': + case '4043': + return new InvalidFieldNameException($exception, $query); + + case '4041': + return new TableNotFoundException($exception, $query); + + case '4045': + return new SchemaDoesNotExist($exception, $query); + + case '4091': + return new UniqueConstraintViolationException($exception, $query); + + case '4093': + return new TableExistsException($exception, $query); + } + + // Prior to fixing https://bugs.php.net/bug.php?id=64705 (PHP 7.4.10), + // in some cases (mainly connection errors) the PDO exception wouldn't provide a SQLSTATE via its code. + // We have to match against the SQLSTATE in the error message in these cases. + if ($exception->getCode() === 7 && strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) { + return new ConnectionException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/src/Crate/DBAL/Driver/PDOCrate/PDOConnection.php b/src/Crate/DBAL/Driver/PDOCrate/PDOConnection.php index 38840ab..051ff4f 100644 --- a/src/Crate/DBAL/Driver/PDOCrate/PDOConnection.php +++ b/src/Crate/DBAL/Driver/PDOCrate/PDOConnection.php @@ -1,4 +1,5 @@ setAttribute(\PDO::ATTR_STATEMENT_CLASS, CrateStatement::class); - $this->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + $this->connection = new PDOCrateDB($dsn, $user, $password, $options); + // FIXME: `[PDOStatement::class, []]` might be correct, but fails in `crate-pdo`. + $this->connection->setAttribute(PDO::ATTR_STATEMENT_CLASS, PDOStatement::class); + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + + public function getServerVersion(): string + { + // Unable to detect platform version. + // TODO: Need to retrieve and propagate CrateDB server version here? + return "5.0.0"; + } + + public function getNativeConnection(): PDOCrateDB + { + return $this->connection; } /** - * Checks whether a query is required to retrieve the database server version. + * {@inheritDoc} * - * @return boolean True if a query is required to retrieve the database server version, false otherwise. + * References: + * - https://github.com/doctrine/dbal/issues/2025 + * - https://github.com/doctrine/dbal/pull/517 + * - https://github.com/doctrine/dbal/pull/373 */ - public function requiresQueryForServerVersion() + public function prepare($sql, $options = []): CrateStatement + { + try { + return new CrateStatement($this->connection, $sql, $options); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritDoc} + */ + public function exec($sql): int + { + try { + $result = $this->connection->exec($sql); + assert($result !== false); + return $result; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function query(string $sql): ResultInterface + { + try { + $stmt = $this->prepare($sql); + $stmt->execute(); + return new Result($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function quote($value, $type = ParameterType::STRING): string + { + try { + return $this->connection->quote($value, $type); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function lastInsertId($name = null): string + { + try { + return $this->connection->lastInsertId($name); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function beginTransaction(): void + { + } + + public function commit(): void + { + } + + public function rollBack(): void { - return false; } } diff --git a/src/Crate/DBAL/Driver/PDOCrate/Result.php b/src/Crate/DBAL/Driver/PDOCrate/Result.php new file mode 100644 index 0000000..b371dec --- /dev/null +++ b/src/Crate/DBAL/Driver/PDOCrate/Result.php @@ -0,0 +1,108 @@ +statement = $statement; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric(): false|array + { + return $this->fetch(PDO::FETCH_NUM); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative(): false|array + { + return $this->fetch(PDO::FETCH_ASSOC); + } + + /** + * {@inheritDoc} + */ + public function fetchOne(): mixed + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + try { + return $this->statement->rowCount(); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function columnCount(): int + { + try { + return $this->statement->columnCount(); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function free(): void + { + $this->statement->closeCursor(); + } + + /** + * @phpstan-param PDO::FETCH_* $mode + * + * @return mixed + * + * @throws Exception + */ + private function fetch(int $mode) + { + try { + return $this->statement->fetch($mode); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } +} diff --git a/src/Crate/DBAL/Platforms/CratePlatform.php b/src/Crate/DBAL/Platforms/CratePlatform.php index a18e5ce..9b32f94 100644 --- a/src/Crate/DBAL/Platforms/CratePlatform.php +++ b/src/Crate/DBAL/Platforms/CratePlatform.php @@ -1,4 +1,5 @@ initializeDoctrineTypeMappings(); if (!Type::hasType(MapType::NAME)) { Type::addType(MapType::NAME, 'Crate\DBAL\Types\MapType'); @@ -62,7 +62,7 @@ public function __construct() /** * {@inheritDoc} */ - public function getSubstringExpression($value, $from = 0, $length = null) + public function getSubstringExpression($value, $from = 0, $length = null): string { if ($length === null) { return 'SUBSTR(' . $value . ', ' . $from . ')'; @@ -82,7 +82,7 @@ public function getNowExpression() /** * {@inheritDoc} */ - public function getRegexpExpression() + public function getRegexpExpression(): string { return 'LIKE'; } @@ -90,7 +90,7 @@ public function getRegexpExpression() /** * {@inheritDoc} */ - public function getDateDiffExpression($date1, $date2) + public function getDateDiffExpression($date1, $date2): string { throw DBALException::notSupported(__METHOD__); } @@ -98,7 +98,7 @@ public function getDateDiffExpression($date1, $date2) /** * {@inheritDoc} */ - public function supportsSequences() + public function supportsSequences(): bool { return false; } @@ -109,7 +109,7 @@ public function supportsSequences() * * {@inheritDoc} */ - public function supportsSchemas() + public function supportsSchemas(): bool { return false; } @@ -117,7 +117,7 @@ public function supportsSchemas() /** * {@inheritDoc} */ - public function supportsIdentityColumns() + public function supportsIdentityColumns(): bool { return true; } @@ -133,7 +133,7 @@ public function supportsIndexes() /** * {@inheritDoc} */ - public function supportsCommentOnStatement() + public function supportsCommentOnStatement(): bool { return false; } @@ -173,7 +173,7 @@ public function prefersSequences() /** * {@inheritDoc} */ - public function getListDatabasesSQL() + public function getListDatabasesSQL(): string { throw DBALException::notSupported(__METHOD__); } @@ -251,7 +251,7 @@ protected function getTableWhereClauseFormat() /** * {@inheritDoc} */ - public function getAlterTableSQL(TableDiff $diff) + public function getAlterTableSQL(TableDiff $diff): array { $sql = array(); $commentsSQL = array(); @@ -286,7 +286,7 @@ public function getAlterTableSQL(TableDiff $diff) throw DBALException::notSupported("Alter Table: rename table"); } - $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); + $sql = array_merge($sql, $this->getPreAlterTableIndexForeignKeySQL($diff), $commentsSQL); } return array_merge($sql, $tableSql, $columnSql); @@ -295,7 +295,7 @@ public function getAlterTableSQL(TableDiff $diff) /** * {@inheritDoc} */ - public function getColumnDeclarationSQL($name, array $column) + public function getColumnDeclarationSQL($name, array $column): string { if (isset($column['columnDefinition'])) { $columnDef = $this->getCustomTypeDeclarationSQL($column); @@ -309,9 +309,11 @@ public function getColumnDeclarationSQL($name, array $column) /** * Generate table index column declaration + * @param string $name + * @param Index $index * @codeCoverageIgnore */ - public function getIndexDeclarationSQL($name, Index $index) + public function getIndexDeclarationSQL($name, Index $index): string { $columns = $index->getQuotedColumns($this); $name = new Identifier($name); @@ -321,7 +323,7 @@ public function getIndexDeclarationSQL($name, Index $index) } return 'INDEX ' . $name->getQuotedName($this) . - ' USING FULLTEXT ('. $this->getIndexFieldDeclarationListSQL($columns) . ')'; + ' USING FULLTEXT ('. $this->getIndexFieldDeclarationListSQL($index) . ')'; } /** @@ -329,7 +331,7 @@ public function getIndexDeclarationSQL($name, Index $index) * * Crate wants boolean values converted to the strings 'true'/'false'. */ - public function convertBooleans($item) + public function convertBooleans($item): mixed { if (is_array($item)) { foreach ($item as $key => $value) { @@ -353,7 +355,7 @@ public function convertBooleans($item) /** * {@inheritDoc} */ - public function getBooleanTypeDeclarationSQL(array $field) + public function getBooleanTypeDeclarationSQL(array $field): string { return 'BOOLEAN'; } @@ -361,7 +363,7 @@ public function getBooleanTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getIntegerTypeDeclarationSQL(array $field) + public function getIntegerTypeDeclarationSQL(array $field): string { return 'INTEGER'; } @@ -369,7 +371,7 @@ public function getIntegerTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getBigIntTypeDeclarationSQL(array $field) + public function getBigIntTypeDeclarationSQL(array $field): string { return 'LONG'; } @@ -377,7 +379,7 @@ public function getBigIntTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getSmallIntTypeDeclarationSQL(array $field) + public function getSmallIntTypeDeclarationSQL(array $field): string { return 'SHORT'; } @@ -385,7 +387,7 @@ public function getSmallIntTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getFloatDeclarationSQL(array $field) + public function getFloatDeclarationSQL(array $field): string { return 'DOUBLE'; } @@ -393,7 +395,7 @@ public function getFloatDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getDecimalTypeDeclarationSQL(array $columnDef) + public function getDecimalTypeDeclarationSQL(array $columnDef): string { return 'DOUBLE'; } @@ -401,7 +403,7 @@ public function getDecimalTypeDeclarationSQL(array $columnDef) /** * {@inheritDoc} */ - public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration): string { return 'TIMESTAMP'; } @@ -409,7 +411,7 @@ public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) /** * {@inheritDoc} */ - public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration): string { return 'TIMESTAMP'; } @@ -417,7 +419,7 @@ public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) /** * {@inheritDoc} */ - public function getDateTypeDeclarationSQL(array $fieldDeclaration) + public function getDateTypeDeclarationSQL(array $fieldDeclaration): string { return 'TIMESTAMP'; } @@ -425,7 +427,7 @@ public function getDateTypeDeclarationSQL(array $fieldDeclaration) /** * {@inheritDoc} */ - public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + public function getTimeTypeDeclarationSQL(array $fieldDeclaration): string { return 'TIMESTAMP'; } @@ -433,15 +435,18 @@ public function getTimeTypeDeclarationSQL(array $fieldDeclaration) /** * {@inheritDoc} */ - protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef): string { return ''; } /** * {@inheritDoc} + * @param false|int $length + * @param $fixed */ - protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed): string { return 'STRING'; } @@ -449,7 +454,7 @@ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) /** * {@inheritDoc} */ - public function getClobTypeDeclarationSQL(array $field) + public function getClobTypeDeclarationSQL(array $field): string { return 'STRING'; } @@ -475,7 +480,7 @@ public function getSQLResultCasing($column) /** * {@inheritDoc} */ - public function getDateTimeTzFormatString() + public function getDateTimeTzFormatString(): string { return self::TIMESTAMP_FORMAT_TZ; } @@ -483,7 +488,7 @@ public function getDateTimeTzFormatString() /** * {@inheritDoc} */ - public function getDateTimeFormatString() + public function getDateTimeFormatString(): string { return self::TIMESTAMP_FORMAT; } @@ -491,7 +496,7 @@ public function getDateTimeFormatString() /** * {@inheritDoc} */ - public function getDateFormatString() + public function getDateFormatString(): string { return self::TIMESTAMP_FORMAT; } @@ -499,7 +504,7 @@ public function getDateFormatString() /** * {@inheritDoc} */ - public function getTimeFormatString() + public function getTimeFormatString(): string { return self::TIMESTAMP_FORMAT; } @@ -507,7 +512,7 @@ public function getTimeFormatString() /** * {@inheritDoc} */ - public function getTruncateTableSQL($tableName, $cascade = false) + public function getTruncateTableSQL($tableName, $cascade = false): string { throw DBALException::notSupported(__METHOD__); } @@ -523,7 +528,7 @@ public function getReadLockSQL() /** * {@inheritDoc} */ - protected function initializeDoctrineTypeMappings() + protected function initializeDoctrineTypeMappings(): void { $this->doctrineTypeMapping = array( 'short' => 'smallint', @@ -544,7 +549,7 @@ protected function initializeDoctrineTypeMappings() /** * {@inheritDoc} */ - public function getDoctrineTypeMapping($dbType) + public function getDoctrineTypeMapping($dbType): string { // typed arrays will always end up in the same generic php array type if (substr_compare($dbType, 'array', -5) === 0) { @@ -573,7 +578,7 @@ protected function getReservedKeywordsClass() /** * {@inheritDoc} */ - public function getBlobTypeDeclarationSQL(array $field) + public function getBlobTypeDeclarationSQL(array $field): string { throw DBALException::notSupported(__METHOD__); } @@ -588,7 +593,7 @@ public function getBlobTypeDeclarationSQL(array $field) * * @return array The sequence of SQL statements. */ - public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES) + public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES): array { if (!is_int($createFlags)) { $msg = "Second argument of CratePlatform::getCreateTableSQL() has to be integer."; @@ -605,7 +610,7 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE $options['indexes'] = array(); $options['primary'] = array(); - if (($createFlags&self::CREATE_INDEXES) > 0) { + if (($createFlags & self::CREATE_INDEXES) > 0) { foreach ($table->getIndexes() as $index) { /* @var $index Index */ if ($index->isPrimary()) { @@ -671,7 +676,8 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE /** * {@inheritDoc} */ - protected function _getCreateTableSQL($name, array $columns, array $options = array()) + // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function _getCreateTableSQL($name, array $columns, array $options = array()): array { $columnListSql = $this->getColumnDeclarationListSQL($columns); @@ -685,7 +691,7 @@ protected function _getCreateTableSQL($name, array $columns, array $options = ar $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition); } } - + if (isset($options['foreignKeys'])) { throw DBALException::notSupported("Create Table: foreign keys"); } @@ -794,7 +800,8 @@ public static function prepareColumnData(AbstractPlatform $platform, $column, $p $columnData['unique'] = false; $columnData['version'] = $column->hasPlatformOption("version") ? $column->getPlatformOption("version") : false; - if (strtolower($columnData['type']) == $platform->getVarcharTypeDeclarationSQLSnippet(0, false) + if (strtolower($columnData['type']->getName()) == + strtolower($platform->getVarcharTypeDeclarationSQLSnippet(0, false)) && $columnData['length'] === null) { $columnData['length'] = 255; } @@ -817,7 +824,7 @@ public static function prepareColumnData(AbstractPlatform $platform, $column, $p /** * {@inheritDoc} */ - public function getCreateDatabaseSQL($database) + public function getCreateDatabaseSQL($database): string { throw DBALException::notSupported(__METHOD__); } @@ -825,23 +832,23 @@ public function getCreateDatabaseSQL($database) /** * {@inheritDoc} */ - public function getDropDatabaseSQL($database) + public function getDropDatabaseSQL($database): string { throw DBALException::notSupported(__METHOD__); } - + /** * {@inheritDoc} */ - public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table): string { throw DBALException::notSupported(__METHOD__); } - + /** * {@inheritDoc} */ - public function getGuidTypeDeclarationSQL(array $field) + public function getGuidTypeDeclarationSQL(array $field): string { throw DBALException::notSupported(__METHOD__); } @@ -852,10 +859,19 @@ public function getGuidTypeDeclarationSQL(array $field) * * @return string */ - public function getTableOptionsSQL(string $table) : string + public function getTableOptionsSQL(string $table): string { return "SELECT clustered_by, number_of_shards, partitioned_by, number_of_replicas, column_policy, settings " . "FROM information_schema.tables c " . "WHERE " . $this->getTableWhereClause($table); } + + /** + * {@inheritDoc} + */ + public function getCurrentDatabaseExpression(): string + { + // Added by Doctrine 3. + return 'CURRENT_DATABASE()'; + } } diff --git a/src/Crate/DBAL/Platforms/CratePlatform1.php b/src/Crate/DBAL/Platforms/CratePlatform1.php index 924a76e..e0e0b75 100644 --- a/src/Crate/DBAL/Platforms/CratePlatform1.php +++ b/src/Crate/DBAL/Platforms/CratePlatform1.php @@ -1,4 +1,5 @@ doctrineTypeMapping = array( 'integer' => 'integer', @@ -54,7 +55,7 @@ protected function initializeDoctrineTypeMappings() /** * {@inheritDoc} */ - public function getBigIntTypeDeclarationSQL(array $field) + public function getBigIntTypeDeclarationSQL(array $field): string { return 'BIGINT'; } @@ -62,7 +63,7 @@ public function getBigIntTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getSmallIntTypeDeclarationSQL(array $field) + public function getSmallIntTypeDeclarationSQL(array $field): string { return 'SMALLINT'; } @@ -70,7 +71,7 @@ public function getSmallIntTypeDeclarationSQL(array $field) /** * {@inheritDoc} */ - public function getFloatDeclarationSQL(array $field) + public function getFloatDeclarationSQL(array $field): string { return 'DOUBLE PRECISION'; } @@ -78,7 +79,7 @@ public function getFloatDeclarationSQL(array $field) /** * {@inheritDoc} */ - protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed): string { return 'TEXT'; } @@ -86,7 +87,7 @@ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) /** * {@inheritDoc} */ - public function getClobTypeDeclarationSQL(array $field) + public function getClobTypeDeclarationSQL(array $field): string { return 'TEXT'; } diff --git a/src/Crate/DBAL/Platforms/Keywords/CrateKeywords.php b/src/Crate/DBAL/Platforms/Keywords/CrateKeywords.php index 18a435b..830fbbe 100644 --- a/src/Crate/DBAL/Platforms/Keywords/CrateKeywords.php +++ b/src/Crate/DBAL/Platforms/Keywords/CrateKeywords.php @@ -1,4 +1,5 @@ + */ class CrateSchemaManager extends AbstractSchemaManager { /** * {@inheritdoc} * */ - protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null): array { $buffer = []; foreach ($tableIndexes as $row) { @@ -51,7 +60,8 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null /** * {@inheritDoc} */ - protected function _getPortableTableColumnDefinition($tableColumn) + // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore + protected function _getPortableTableColumnDefinition($tableColumn): Column { $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); @@ -88,6 +98,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) /** * {@inheritDoc} */ + // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore protected function _getPortableTablesList($tables) { $tableNames = array(); @@ -105,7 +116,7 @@ protected function _getPortableTablesList($tables) * * @return array */ - private function flatten(array $array, string $prefix = '') : array + private static function flatten(array $array, string $prefix = ''): array { $result = array(); foreach ($array as $key => $value) { @@ -121,13 +132,13 @@ private function flatten(array $array, string $prefix = '') : array /** * {@inheritDoc} */ - public function listTableDetails($tableName) : Table + public function listTableDetails($name): Table { - $columns = $this->listTableColumns($tableName); - $indexes = $this->listTableIndexes($tableName); + $columns = $this->listTableColumns($name); + $indexes = $this->listTableIndexes($name); $options = []; - $s = $this->_conn->fetchAssoc($this->_platform->getTableOptionsSQL($tableName)); + $s = $this->_conn->fetchAssociative($this->_platform->getTableOptionsSQL($name)); $options['sharding_routing_column'] = $s['clustered_by']; $options['sharding_num_shards'] = $s['number_of_shards']; @@ -135,6 +146,6 @@ public function listTableDetails($tableName) : Table $options['table_options'] = self::flatten($s['settings']); $options['table_options']['number_of_replicas'] = $s['number_of_replicas']; $options['table_options']['column_policy'] = $s['column_policy']; - return new Table($tableName, $columns, $indexes, [], [], $options); + return new Table($name, $columns, $indexes, [], [], $options); } } diff --git a/src/Crate/DBAL/Types/ArrayType.php b/src/Crate/DBAL/Types/ArrayType.php index cd279c7..702e343 100644 --- a/src/Crate/DBAL/Types/ArrayType.php +++ b/src/Crate/DBAL/Types/ArrayType.php @@ -1,4 +1,5 @@ 0 && !(array_keys($value) === range(0, count($value) - 1)))) { return null; @@ -64,7 +65,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform) return $value; } - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue($value, AbstractPlatform $platform): mixed { return $value; } @@ -75,9 +76,9 @@ public function convertToPHPValue($value, AbstractPlatform $platform) * @param array $fieldDeclaration The field declaration. * @param AbstractPlatform $platform The currently used database platform. * @return string - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception */ - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { $options = !array_key_exists('platformOptions', $fieldDeclaration) ? array() : $fieldDeclaration['platformOptions']; @@ -92,11 +93,11 @@ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $pla * * @param array $options * @return string - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception */ - public function getArrayTypeDeclarationSQL(AbstractPlatform $platform, array $field, array $options) + public function getArrayTypeDeclarationSQL(AbstractPlatform $platform, array $field, array $options): string { - $type = array_key_exists('type', $options) ? $options['type'] : Type::STRING; + $type = array_key_exists('type', $options) ? $options['type'] : Types::STRING; return 'ARRAY ( ' . Type::getType($type)->getSQLDeclaration($field, $platform) . ' )'; } } diff --git a/src/Crate/DBAL/Types/MapType.php b/src/Crate/DBAL/Types/MapType.php index 3cfbcd0..f7edb97 100644 --- a/src/Crate/DBAL/Types/MapType.php +++ b/src/Crate/DBAL/Types/MapType.php @@ -1,4 +1,5 @@ 0 && !(array_keys($value) !== range(0, count($value) - 1)))) { + if (!is_array($value) || (count($value) > 0 && array_keys($value) === range(0, count($value) - 1))) { return null; } return $value; } - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue($value, AbstractPlatform $platform): mixed { - return $value == null ?: (array) $value; + if ($value === null) { + return null; + } + return (array) $value; } /** @@ -82,9 +85,9 @@ public function convertToPHPValue($value, AbstractPlatform $platform) * @param array $fieldDeclaration The field declaration. * @param AbstractPlatform $platform The currently used database platform. * @return string - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception */ - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { $options = !array_key_exists('platformOptions', $fieldDeclaration) ? array() : $fieldDeclaration['platformOptions']; @@ -98,9 +101,9 @@ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $pla * @param array $field * * @return string - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception */ - public function getMapTypeDeclarationSQL(AbstractPlatform $platform, array $field, array $options) + public function getMapTypeDeclarationSQL(AbstractPlatform $platform, array $field, array $options): string { $type = array_key_exists('type', $options) ? $options['type'] : MapType::DYNAMIC; diff --git a/src/Crate/DBAL/Types/TimestampType.php b/src/Crate/DBAL/Types/TimestampType.php index 1e17fb3..eb8c269 100644 --- a/src/Crate/DBAL/Types/TimestampType.php +++ b/src/Crate/DBAL/Types/TimestampType.php @@ -1,4 +1,5 @@ getTimestamp()*self::S_TO_MS : null; + ? $value->getTimestamp() * self::S_TO_MS : null; } - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue($value, AbstractPlatform $platform): mixed { if ($value === null || $value instanceof DateTime) { return $value; @@ -61,7 +63,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) } $val = new DateTime(); - $val->setTimestamp($value/self::S_TO_MS); + $val->setTimestamp((int) ($value / self::S_TO_MS)); return $val; } @@ -73,7 +75,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) * @param array $fieldDeclaration The field declaration. * @param AbstractPlatform $platform The currently used database platform. */ - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { return $platform->getDateTimeTypeDeclarationSQL($fieldDeclaration); } diff --git a/test/Crate/Test/DBAL/DBALFunctionalTestCase.php b/test/Crate/Test/DBAL/DBALFunctionalTest.php similarity index 89% rename from test/Crate/Test/DBAL/DBALFunctionalTestCase.php rename to test/Crate/Test/DBAL/DBALFunctionalTest.php index 435eacb..ce5380c 100644 --- a/test/Crate/Test/DBAL/DBALFunctionalTestCase.php +++ b/test/Crate/Test/DBAL/DBALFunctionalTest.php @@ -23,14 +23,16 @@ use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Logging\DebugStack; +use Doctrine\DBAL\Result; +use Doctrine\DBAL\Statement; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; use Throwable; -abstract class DBALFunctionalTestCase extends TestCase +abstract class DBALFunctionalTest extends TestCase { /** - * Shared connection when a TestCase is run alone (outside of it's functional suite) + * Shared connection when a TestCase is run alone (outside its functional suite) * * @var \Doctrine\DBAL\Connection */ @@ -105,17 +107,17 @@ protected function onNotSuccessfulTest(Throwable $e) : void throw $e; } - public function execute($stmt) + public function run_sql($stmt): Result { - return $this->_conn->query($stmt); + return $this->_conn->executeQuery($stmt); } - public function refresh($table_name) + public function refresh($table_name): void { - $this->_conn->query('REFRESH TABLE ' . $table_name); + $this->_conn->executeStatement('REFRESH TABLE ' . $table_name); } - public function prepareStatement($sql) + public function prepareStatement($sql): Statement { return $this->_conn->prepare($sql); } diff --git a/test/Crate/Test/DBAL/Functional/BindingTest.php b/test/Crate/Test/DBAL/Functional/BindingTest.php index 819b151..e6075f2 100644 --- a/test/Crate/Test/DBAL/Functional/BindingTest.php +++ b/test/Crate/Test/DBAL/Functional/BindingTest.php @@ -21,10 +21,9 @@ */ namespace Crate\Test\DBAL\Functional; -use Crate\Test\DBAL\DBALFunctionalTestCase; -use Doctrine\DBAL\DBALException; +use Crate\Test\DBAL\DBALFunctionalTest; -class BindingTestCase extends DBALFunctionalTestCase +class BindingTest extends DBALFunctionalTest { public function testBindPositionalParam() @@ -32,27 +31,29 @@ public function testBindPositionalParam() $name = 'crate'; $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = ?'); - $stmt->bindParam(1, $name); - $stmt->execute(); + $stmt->bindValue(1, $name); + $stmt->executeQuery(); $noName = 'i0ejfNlzSFCloGYtSzddTw'; $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = ? OR master_node = ?'); - $stmt->bindParam(1, $name); - $stmt->bindParam(2, $noName); - $this->assertTrue($stmt->execute()); + $stmt->bindValue(1, $name); + $stmt->bindValue(2, $noName); + $result = $stmt->executeQuery(); + self::assertEquals(1, $result->rowCount()); } public function testBindPositionalValue() { $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = ?'); $stmt->bindValue(1, 'crate'); - $stmt->execute(); + $stmt->executeQuery(); $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = ? OR master_node = ?'); $stmt->bindValue(1, 'crate'); $stmt->bindValue(2, 'i0ejfNlzSFCloGYtSzddTw'); - $this->assertTrue($stmt->execute()); + $result = $stmt->executeQuery(); + self::assertEquals(1, $result->rowCount()); } public function testBindNamedParam() @@ -60,57 +61,57 @@ public function testBindNamedParam() $name = 'crate'; $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = :name'); - $stmt->bindParam('name', $name); - $stmt->execute(); + $stmt->bindValue('name', $name); + $stmt->executeQuery(); $noName = 'i0ejfNlzSFCloGYtSzddTw'; $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = :name OR master_node = :master_node'); - $stmt->bindParam('name', $name); - $stmt->bindParam('master_node', $noName); - $this->assertTrue($stmt->execute()); + $stmt->bindValue('name', $name); + $stmt->bindValue('master_node', $noName); + $result = $stmt->executeQuery(); + self::assertEquals(1, $result->rowCount()); } public function testBindNamedValue() { $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = :name'); $stmt->bindValue('name', 'crate'); - $stmt->execute(); + $stmt->executeQuery(); $stmt = $this->prepareStatement('SELECT * FROM sys.cluster WHERE name = :name OR master_node = :master_node'); $stmt->bindValue('name', 'crate'); $stmt->bindValue('master_node', 'i0ejfNlzSFCloGYtSzddTw'); - $this->assertTrue($stmt->execute()); + $result = $stmt->executeQuery(); + self::assertEquals(1, $result->rowCount()); } public function testBindTimestamp() { - if ($this->_conn->getSchemaManager()->tablesExist("foo")) { - $this->execute("DROP TABLE foo"); + if ($this->_conn->createSchemaManager()->tablesExist("foo")) { + $this->run_sql("DROP TABLE foo"); } - $this->execute("CREATE TABLE foo (id int, ts timestamp) with (number_of_replicas=0)"); - $this->execute("INSERT INTO foo (id, ts) VALUES (1, 1413901591000)"); - $this->execute("INSERT INTO foo (id, ts) VALUES (2, 1413901592000)"); - $this->execute("INSERT INTO foo (id, ts) VALUES (3, 1413901593000)"); - $this->execute("REFRESH TABLE foo"); + $this->run_sql("CREATE TABLE foo (id int, ts timestamp) with (number_of_replicas=0)"); + $this->run_sql("INSERT INTO foo (id, ts) VALUES (1, 1413901591000)"); + $this->run_sql("INSERT INTO foo (id, ts) VALUES (2, 1413901592000)"); + $this->run_sql("INSERT INTO foo (id, ts) VALUES (3, 1413901593000)"); + $this->run_sql("REFRESH TABLE foo"); $date = new \DateTime("2014-10-21 14:26:32"); // => 1413901592000 $stmt = $this->prepareStatement('SELECT * FROM foo WHERE ts > ?'); $stmt->bindValue(1, $date, 'datetimetz'); - $stmt->execute(); - $row = $stmt->fetchAll(); + $row = $stmt->executeQuery()->fetchAllAssociative(); $this->assertEquals($row[0]['id'], 3); $this->assertEquals($row[0]['ts'], 1413901593000); $stmt = $this->prepareStatement('SELECT * FROM foo WHERE ts < ?'); $stmt->bindValue(1, $date, 'datetime'); - $stmt->execute(); - $row = $stmt->fetchAll(); + $row = $stmt->executeQuery()->fetchAllAssociative(); $this->assertEquals($row[0]['id'], 1); $this->assertEquals($row[0]['ts'], 1413901591000); - $this->execute("DROP TABLE foo"); + $this->run_sql("DROP TABLE foo"); } } diff --git a/test/Crate/Test/DBAL/Functional/ConnectionTest.php b/test/Crate/Test/DBAL/Functional/ConnectionTest.php index 94955fd..2e9121f 100644 --- a/test/Crate/Test/DBAL/Functional/ConnectionTest.php +++ b/test/Crate/Test/DBAL/Functional/ConnectionTest.php @@ -21,10 +21,11 @@ */ namespace Crate\Test\DBAL\Functional; -use Crate\Test\DBAL\DBALFunctionalTestCase; use Crate\PDO\PDOCrateDB; +use Crate\Test\DBAL\DBALFunctionalTest; +use Doctrine\DBAL\DriverManager; -class ConnectionTestCase extends DBALFunctionalTestCase +class ConnectionTest extends DBALFunctionalTest { public function setUp() : void { @@ -48,11 +49,11 @@ public function testBasicAuthConnection() 'user' => $auth[0], 'password' => $auth[1], ); - $conn = \Doctrine\DBAL\DriverManager::getConnection($params); - $this->assertEquals($auth[0], $conn->getUsername()); - $this->assertEquals($auth[1], $conn->getPassword()); - $auth_attr = $conn->getWrappedConnection()->getAttribute(PDOCrateDB::CRATE_ATTR_HTTP_BASIC_AUTH); - $this->assertEquals($auth_attr, $auth); + $conn = DriverManager::getConnection($params); + $conn->connect(); + $credentials = $conn->getNativeConnection()->getAttribute(PDOCrateDB::CRATE_ATTR_HTTP_BASIC_AUTH); + + $this->assertEquals(array("crate", "secret"), $credentials); } public function testGetConnection() @@ -66,12 +67,21 @@ public function testGetDriver() $this->assertInstanceOf('Crate\DBAL\Driver\PDOCrate\Driver', $this->_conn->getDriver()); } + /** + * @var \Doctrine\DBAL\Statement $stmt + * + * @return void + * @throws \Doctrine\DBAL\Exception + */ public function testStatement() { $sql = 'SELECT * FROM sys.cluster'; $stmt = $this->_conn->prepare($sql); + + // Well, it's three layers of Statement objects now. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - $this->assertInstanceOf('Crate\PDO\PDOStatement', $stmt->getWrappedStatement()); + $this->assertInstanceOf('Crate\DBAL\Driver\PDOCrate\CrateStatement', $stmt->getWrappedStatement()); + $this->assertInstanceOf('Crate\PDO\PDOStatement', $stmt->getWrappedStatement()->getWrappedStatement()); } diff --git a/test/Crate/Test/DBAL/Functional/DataAccessTest.php b/test/Crate/Test/DBAL/Functional/DataAccessTest.php index 4a3cfbe..ae8175f 100644 --- a/test/Crate/Test/DBAL/Functional/DataAccessTest.php +++ b/test/Crate/Test/DBAL/Functional/DataAccessTest.php @@ -23,16 +23,18 @@ namespace Crate\Test\DBAL\Functional; use Crate\DBAL\Types\MapType; -use Crate\Test\DBAL\DBALFunctionalTestCase; -use Doctrine\DBAL\DBALException; +use Crate\Test\DBAL\DBALFunctionalTest; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types\Types; use PDO; -class DataAccessTestCase extends DBALFunctionalTestCase +class DataAccessTest extends DBALFunctionalTest { static private $generated = false; @@ -43,8 +45,8 @@ public function setUp() : void if (self::$generated === false) { self::$generated = true; /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ - $sm = $this->_conn->getSchemaManager(); - $table = new \Doctrine\DBAL\Schema\Table("fetch_table"); + $sm = $this->_conn->createSchemaManager(); + $table = new Table("fetch_table"); $table->addColumn('test_int', 'integer'); $table->addColumn('test_string', 'string'); $table->addColumn('test_datetime', 'timestamp', array('notnull' => false)); @@ -52,6 +54,7 @@ public function setUp() : void $platformOptions = array( 'type' => MapType::STRICT, 'fields' => array( + // Those intentionally use DBAL types. new Column('id', Type::getType('integer'), array()), new Column('name', Type::getType('string'), array()), new Column('value', Type::getType('float'), array()), @@ -77,7 +80,7 @@ public function setUp() : void public function tearDown() : void { if (self::$generated === true) { - $this->_conn->getSchemaManager()->dropTable('fetch_table'); + $this->_conn->createSchemaManager()->dropTable('fetch_table'); self::$generated = false; } } @@ -90,27 +93,9 @@ public function testPrepareWithBindValue() $stmt->bindValue(1, 1, PDO::PARAM_INT); $stmt->bindValue(2, 'foo', PDO::PARAM_STR); - $stmt->execute(); + $result = $stmt->executeQuery(); - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - $row = array_change_key_case($row, \CASE_LOWER); - $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row); - } - - public function testPrepareWithBindParam() - { - $paramInt = 1; - $paramStr = 'foo'; - - $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $stmt = $this->_conn->prepare($sql); - $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - - $stmt->bindParam(1, $paramInt, PDO::PARAM_INT); - $stmt->bindParam(2, $paramStr, PDO::PARAM_STR); - $stmt->execute(); - - $row = $stmt->fetch(\PDO::FETCH_ASSOC); + $row = $result->fetchAssociative(); $row = array_change_key_case($row, \CASE_LOWER); $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row); } @@ -124,11 +109,11 @@ public function testPrepareWithFetchAll() $stmt = $this->_conn->prepare($sql); $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - $stmt->bindParam(1, $paramInt, PDO::PARAM_INT); - $stmt->bindParam(2, $paramStr, PDO::PARAM_STR); - $stmt->execute(); + $stmt->bindValue(1, $paramInt, PDO::PARAM_INT); + $stmt->bindValue(2, $paramStr, PDO::PARAM_STR); + $result = $stmt->executeQuery(); - $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); + $rows = $result->fetchAllAssociative(); $rows[0] = array_change_key_case($rows[0], \CASE_LOWER); $this->assertEquals(array( 'test_int' => 1, @@ -146,27 +131,6 @@ public function testPrepareWithFetchAll() array('foo','bar')); } - /** - * @group DBAL-228 - */ - public function testPrepareWithFetchAllBoth() - { - $paramInt = 1; - $paramStr = 'foo'; - - $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $stmt = $this->_conn->prepare($sql); - $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - - $stmt->bindParam(1, $paramInt, PDO::PARAM_INT); - $stmt->bindParam(2, $paramStr, PDO::PARAM_STR); - $stmt->execute(); - - $rows = $stmt->fetchAll(\PDO::FETCH_BOTH); - $rows[0] = array_change_key_case($rows[0], \CASE_LOWER); - $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo', 0 => 1, 1 => 'foo'), $rows[0]); - } - public function testPrepareWithFetchColumn() { $paramInt = 1; @@ -176,11 +140,11 @@ public function testPrepareWithFetchColumn() $stmt = $this->_conn->prepare($sql); $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - $stmt->bindParam(1, $paramInt, PDO::PARAM_INT); - $stmt->bindParam(2, $paramStr, PDO::PARAM_STR); - $stmt->execute(); + $stmt->bindValue(1, $paramInt, PDO::PARAM_INT); + $stmt->bindValue(2, $paramStr, PDO::PARAM_STR); + $stmt->executeStatement(); + $column = $stmt->getWrappedStatement()->fetchColumn(); - $column = $stmt->fetchColumn(); $this->assertEquals(1, $column); } @@ -193,13 +157,12 @@ public function testPrepareWithIterator() $stmt = $this->_conn->prepare($sql); $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - $stmt->bindParam(1, $paramInt, PDO::PARAM_INT); - $stmt->bindParam(2, $paramStr, PDO::PARAM_STR); - $stmt->execute(); + $stmt->bindValue(1, $paramInt, PDO::PARAM_INT); + $stmt->bindValue(2, $paramStr, PDO::PARAM_STR); + $result = $stmt->executeQuery(); $rows = array(); - $stmt->setFetchMode(\PDO::FETCH_ASSOC); - foreach ($stmt as $row) { + foreach ($result->iterateAssociative() as $row) { $rows[] = array_change_key_case($row, \CASE_LOWER); } @@ -226,9 +189,9 @@ public function testPrepareWithExecuteParams() $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; $stmt = $this->_conn->prepare($sql); $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt); - $stmt->execute(array($paramInt, $paramStr)); + $result = $stmt->executeQuery(array($paramInt, $paramStr)); - $row = $stmt->fetch(\PDO::FETCH_ASSOC); + $row = $result->fetchAssociative(); $this->assertTrue($row !== false); $row = array_change_key_case($row, \CASE_LOWER); $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row); @@ -237,7 +200,7 @@ public function testPrepareWithExecuteParams() public function testFetchAll() { $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $data = $this->_conn->fetchAll($sql, array(1, 'foo')); + $data = $this->_conn->fetchAllAssociative($sql, array(1, 'foo')); $this->assertEquals(1, count($data)); @@ -249,25 +212,10 @@ public function testFetchAll() $this->assertEquals('foo', $row['test_string']); } - public function testFetchBoth() - { - $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $row = $this->_conn->executeQuery($sql, array(1, 'foo'))->fetch(\PDO::FETCH_BOTH); - - $this->assertTrue($row !== false); - - $row = array_change_key_case($row, \CASE_LOWER); - - $this->assertEquals(1, $row['test_int']); - $this->assertEquals('foo', $row['test_string']); - $this->assertEquals(1, $row[0]); - $this->assertEquals('foo', $row[1]); - } - public function testFetchRow() { $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $row = $this->_conn->fetchAssoc($sql, array(1, 'foo')); + $row = $this->_conn->fetchAssociative($sql, array(1, 'foo')); $this->assertTrue($row !== false); @@ -280,7 +228,7 @@ public function testFetchRow() public function testFetchArray() { $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $row = $this->_conn->fetchArray($sql, array(1, 'foo')); + $row = $this->_conn->fetchNumeric($sql, array(1, 'foo')); $this->assertEquals(1, $row[0]); $this->assertEquals('foo', $row[1]); @@ -289,13 +237,14 @@ public function testFetchArray() public function testFetchColumn() { $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $testInt = $this->_conn->fetchColumn($sql, array(1, 'foo'), 0); + $stmt = $this->_conn->prepare($sql); + $stmt->executeQuery(array(1, 'foo')); + $testInt = $stmt->getWrappedStatement()->fetchColumn(0); $this->assertEquals(1, $testInt); - $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; - $testString = $this->_conn->fetchColumn($sql, array(1, 'foo'), 1); - + $stmt->executeQuery(array(1, 'foo')); + $testString = $stmt->getWrappedStatement()->fetchColumn(1); $this->assertEquals('foo', $testString); } @@ -307,10 +256,10 @@ public function testExecuteQueryBindDateTimeType() $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?'; $stmt = $this->_conn->executeQuery($sql, array(1 => new \DateTime('2010-01-01 10:10:10')), - array(1 => Type::DATETIME) + array(1 => Types::DATETIME_MUTABLE) ); - $this->assertEquals(1, $stmt->fetchColumn()); + $this->assertEquals(1, $stmt->fetchOne()); } /** @@ -321,9 +270,9 @@ public function testExecuteUpdateBindDateTimeType() $datetime = new \DateTime('2010-02-02 20:20:20'); $sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)'; - $affectedRows = $this->_conn->executeUpdate($sql, + $affectedRows = $this->_conn->executeStatement($sql, array(1 => 50, 2 => 'foo', 3 => $datetime), - array(1 => PDO::PARAM_INT, 2 => PDO::PARAM_STR, 3 => Type::DATETIME) + array(1 => PDO::PARAM_INT, 2 => PDO::PARAM_STR, 3 => Types::DATETIME_MUTABLE) ); $this->assertEquals(1, $affectedRows); $this->refresh('fetch_table'); @@ -331,8 +280,8 @@ public function testExecuteUpdateBindDateTimeType() $this->assertEquals(1, $this->_conn->executeQuery( 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?', array(1 => $datetime), - array(1 => Type::DATETIME) - )->fetchColumn()); + array(1 => Types::DATETIME_MUTABLE) + )->fetchOne()); } /** @@ -342,10 +291,10 @@ public function testPrepareQueryBindValueDateTimeType() { $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?'; $stmt = $this->_conn->prepare($sql); - $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Type::DATETIME); - $stmt->execute(); + $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Types::DATETIME_MUTABLE); + $result = $stmt->executeQuery(); - $this->assertEquals(1, $stmt->fetchColumn()); + $this->assertEquals(1, $result->fetchOne()); } /** @@ -361,14 +310,14 @@ public function testNativeArrayListSupport() $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int IN (?) ORDER BY test_int', array(array(100, 101, 102, 103, 104)), array(Connection::PARAM_INT_ARRAY)); - $data = $stmt->fetchAll(PDO::FETCH_NUM); + $data = $stmt->fetchAllNumeric(); $this->assertEquals(5, count($data)); $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data); $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_string IN (?) ORDER BY test_int', array(array('foo100', 'foo101', 'foo102', 'foo103', 'foo104')), array(Connection::PARAM_STR_ARRAY)); - $data = $stmt->fetchAll(PDO::FETCH_NUM); + $data = $stmt->fetchAllNumeric(); $this->assertEquals(5, count($data)); $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data); } @@ -378,7 +327,7 @@ public function testNativeArrayListSupport() */ public function testDateArithmetics() { - $this->markTestSkipped('Data add day expression not supported by crate platform'); + $this->markTestSkipped('Date arithmetics not supported by CrateDB platform'); $p = $this->_conn->getDatabasePlatform(); $sql = 'SELECT '; @@ -405,7 +354,7 @@ public function testQuoteSQLInjection() $this->expectException(DBALException::class); $sql = "SELECT * FROM fetch_table WHERE test_string = bar' OR '1'='1"; - $this->_conn->fetchAll($sql); + $this->_conn->executeQuery($sql); } /** @@ -413,9 +362,9 @@ public function testQuoteSQLInjection() */ public function testBitComparisonExpressionSupport() { - $this->markTestSkipped("Bit comparison expression not supported by crate"); + $this->markTestSkipped("Bit comparison expressions not supported by CrateDB"); - $this->_conn->executeQuery('DELETE FROM fetch_table')->execute(); + $this->_conn->executeStatement('DELETE FROM fetch_table'); $platform = $this->_conn->getDatabasePlatform(); $bitmap = array(); @@ -439,7 +388,7 @@ public function testBitComparisonExpressionSupport() $sql[] = 'FROM fetch_table'; $stmt = $this->_conn->executeQuery(implode(PHP_EOL, $sql)); - $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + $data = $stmt->fetchAllAssociative(); $this->assertEquals(4, count($data)); @@ -464,53 +413,25 @@ public function testBitComparisonExpressionSupport() public function testSetDefaultFetchMode() { - $stmt = $this->_conn->query("SELECT * FROM fetch_table"); - $stmt->setFetchMode(\PDO::FETCH_NUM); - - $row = array_keys($stmt->fetch()); + $result = $this->_conn->executeQuery("SELECT * FROM fetch_table"); + $row = array_keys($result->fetchAllNumeric()); $this->assertEquals(0, count( array_filter($row, function($v) { return ! is_numeric($v); })), "should be no non-numerical elements in the result."); } - /** - * @group DBAL-196 - */ - public function testFetchAllSupportFetchClass() - { - $this->markTestSkipped("PDO::FETCH_CLASS not supported by crate PDO"); - - $this->setupFixture(); - - $sql = "SELECT test_int, test_string, test_datetime FROM fetch_table"; - $stmt = $this->_conn->prepare($sql); - $stmt->execute(); - - $results = $stmt->fetchAll( - \PDO::FETCH_CLASS, - __NAMESPACE__.'\\MyFetchClass' - ); - - $this->assertEquals(1, count($results)); - $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]); - - $this->assertEquals(1, $results[0]->test_int); - $this->assertEquals('foo', $results[0]->test_string); - $this->assertStringStartsWith('2010-01-01T10:10:10', $results[0]->test_datetime); - } - /** * @group DBAL-241 */ public function testFetchAllStyleColumn() { $sql = "DELETE FROM fetch_table"; - $this->_conn->executeUpdate($sql); + $this->_conn->executeStatement($sql); $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo')); $this->_conn->insert('fetch_table', array('test_int' => 10, 'test_string' => 'foo')); $this->refresh("fetch_table"); $sql = "SELECT test_int FROM fetch_table ORDER BY test_int ASC"; - $rows = $this->_conn->query($sql)->fetchAll(\PDO::FETCH_COLUMN); + $rows = $this->_conn->query($sql)->fetchFirstColumn(); $this->assertEquals(array(1, 10), $rows); } @@ -520,12 +441,13 @@ public function testFetchAllStyleColumn() */ public function testSetFetchModeClassFetchAll() { - $this->markTestSkipped("PDO::FETCH_CLASS not supported crate PDO"); + $this->markTestSkipped("PDO::FETCH_CLASS is not supported by the CrateDB PDO driver"); + $this->setupFixture(); $sql = "SELECT * FROM fetch_table"; $stmt = $this->_conn->query($sql); - $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array()); + $stmt->setFetchMode(PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array()); $results = $stmt->fetchAll(); @@ -542,13 +464,13 @@ public function testSetFetchModeClassFetchAll() */ public function testSetFetchModeClassFetch() { - $this->markTestSkipped("PDO::FETCH_CLASS not supported by crate PDO"); + $this->markTestSkipped("PDO::FETCH_CLASS is not supported by the CrateDB PDO driver"); $this->setupFixture(); $sql = "SELECT * FROM fetch_table"; $stmt = $this->_conn->query($sql); - $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array()); + $stmt->setFetchMode(PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array()); $results = array(); while ($row = $stmt->fetch()) { @@ -568,10 +490,10 @@ public function testSetFetchModeClassFetch() */ public function testEmptyFetchColumnReturnsFalse() { - $this->_conn->executeQuery('DELETE FROM fetch_table')->execute(); + $this->_conn->executeStatement('DELETE FROM fetch_table'); $this->refresh("fetch_table"); - $this->assertFalse($this->_conn->fetchColumn('SELECT test_int FROM fetch_table')); - $this->assertFalse($this->_conn->query('SELECT test_int FROM fetch_table')->fetchColumn()); + $this->assertFalse($this->_conn->fetchOne('SELECT test_int FROM fetch_table')); + $this->assertFalse($this->_conn->executeQuery('SELECT test_int FROM fetch_table')->fetchOne()); } /** @@ -581,9 +503,8 @@ public function testSetFetchModeOnDbalStatement() { $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?"; $stmt = $this->_conn->executeQuery($sql, array(1, "foo")); - $stmt->setFetchMode(\PDO::FETCH_NUM); - while ($row = $stmt->fetch()) { + foreach ($stmt->iterateNumeric() as $row) { $this->assertTrue(isset($row[0])); $this->assertTrue(isset($row[1])); } @@ -591,7 +512,7 @@ public function testSetFetchModeOnDbalStatement() private function setupFixture() { - $this->_conn->executeQuery('DELETE FROM fetch_table')->execute(); + $this->_conn->executeStatement('DELETE FROM fetch_table'); $this->_conn->insert('fetch_table', array( 'test_int' => 1, 'test_string' => 'foo', diff --git a/test/Crate/Test/DBAL/Functional/ModifyLimitQueryTest.php b/test/Crate/Test/DBAL/Functional/ModifyLimitQueryTest.php index a0eb173..df67d8c 100644 --- a/test/Crate/Test/DBAL/Functional/ModifyLimitQueryTest.php +++ b/test/Crate/Test/DBAL/Functional/ModifyLimitQueryTest.php @@ -22,11 +22,11 @@ namespace Crate\Test\DBAL\Functional; -use Crate\Test\DBAL\DBALFunctionalTestCase; -use Doctrine\DBAL\DBALException; +use Crate\Test\DBAL\DBALFunctionalTest; +use Doctrine\DBAL\Exception as DBALException; +use Doctrine\DBAL\Schema\Table; - -class ModifyLimitQueryTest extends DBALFunctionalTestCase +class ModifyLimitQueryTest extends DBALFunctionalTest { private static $tableCreated = false; @@ -36,16 +36,16 @@ public function setUp() : void if (!self::$tableCreated) { /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ - $table = new \Doctrine\DBAL\Schema\Table("modify_limit_table"); + $table = new Table("modify_limit_table"); $table->addColumn('test_int', 'integer'); $table->setPrimaryKey(array('test_int')); - $table2 = new \Doctrine\DBAL\Schema\Table("modify_limit_table2"); + $table2 = new Table("modify_limit_table2"); $table2->addColumn('id', 'integer', array('autoincrement' => true)); $table2->addColumn('test_int', 'integer'); $table2->setPrimaryKey(array('id')); - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->createTable($table); $sm->createTable($table2); self::$tableCreated = true; @@ -56,7 +56,7 @@ public function tearDown() : void { parent::tearDown(); if (self::$tableCreated) { - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); try { $sm->dropTable('modify_limit_table'); $sm->dropTable('modify_limit_table2'); @@ -65,7 +65,7 @@ public function tearDown() : void } } - public function testModifyLimitQuerySimpleQuery() + public function testModifyLimitQuerySimpleQuery(): void { $this->_conn->insert('modify_limit_table', array('test_int' => 1)); $this->_conn->insert('modify_limit_table', array('test_int' => 2)); @@ -81,7 +81,7 @@ public function testModifyLimitQuerySimpleQuery() $this->assertLimitResult(array(3, 4), $sql, 2, 2); } - public function testModifyLimitQueryOrderBy() + public function testModifyLimitQueryOrderBy(): void { $this->_conn->insert('modify_limit_table', array('test_int' => 1)); $this->_conn->insert('modify_limit_table', array('test_int' => 2)); @@ -97,7 +97,7 @@ public function testModifyLimitQueryOrderBy() $this->assertLimitResult(array(2, 1), $sql, 2, 2); } - public function testModifyLimitQueryGroupBy() + public function testModifyLimitQueryGroupBy(): void { $this->_conn->insert('modify_limit_table2', array('test_int' => 1, 'id' => 1)); $this->_conn->insert('modify_limit_table2', array('test_int' => 1, 'id' => 2)); @@ -117,7 +117,7 @@ public function assertLimitResult($expectedResults, $sql, $limit, $offset) { $p = $this->_conn->getDatabasePlatform(); $data = array(); - foreach ($this->_conn->fetchAll($p->modifyLimitQuery($sql, $limit, $offset)) AS $row) { + foreach ($this->_conn->executeQuery($p->modifyLimitQuery($sql, $limit, $offset))->fetchAllAssociative() as $row) { $row = array_change_key_case($row, CASE_LOWER); $data[] = $row['test_int']; } diff --git a/test/Crate/Test/DBAL/Functional/NamedParametersTest.php b/test/Crate/Test/DBAL/Functional/NamedParametersTest.php index a2c4de6..6abe52d 100644 --- a/test/Crate/Test/DBAL/Functional/NamedParametersTest.php +++ b/test/Crate/Test/DBAL/Functional/NamedParametersTest.php @@ -2,14 +2,15 @@ namespace Crate\Test\DBAL\Functional; -use Crate\Test\DBAL\DBALFunctionalTestCase; +use Crate\Test\DBAL\DBALFunctionalTest; use Doctrine\DBAL\Connection; -use \PDO; +use Doctrine\DBAL\Schema\Table; +use PDO; /** * @group DDC-1372 */ -class NamedParametersTest extends DBALFunctionalTestCase +class NamedParametersTest extends DBALFunctionalTest { public function ticketProvider() @@ -106,16 +107,16 @@ public function setUp() : void { parent::setUp(); - if (!$this->_conn->getSchemaManager()->tablesExist("ddc1372_foobar")) { + if (!$this->_conn->createSchemaManager()->tablesExist("ddc1372_foobar")) { try { - $table = new \Doctrine\DBAL\Schema\Table("ddc1372_foobar"); + $table = new Table("ddc1372_foobar"); $table->addColumn('id', 'integer'); $table->addColumn('foo','string'); $table->addColumn('bar','string'); $table->setPrimaryKey(array('id')); - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->createTable($table); $this->_conn->insert('ddc1372_foobar', array( @@ -147,9 +148,9 @@ public function setUp() : void public function tearDown() : void { parent::tearDown(); - if ($this->_conn->getSchemaManager()->tablesExist("ddc1372_foobar")) { + if ($this->_conn->createSchemaManager()->tablesExist("ddc1372_foobar")) { try { - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->dropTable('ddc1372_foobar'); } catch(\Exception $e) { $this->fail($e->getMessage()); @@ -167,7 +168,7 @@ public function tearDown() : void public function testTicket($query,$params,$types,$expected) { $stmt = $this->_conn->executeQuery($query, $params, $types); - $result = $stmt->fetchAll(\PDO::FETCH_ASSOC); + $result = $stmt->fetchAllAssociative(); foreach ($result as $k => $v) { $result[$k] = array_change_key_case($v, CASE_LOWER); diff --git a/test/Crate/Test/DBAL/Functional/Schema/SchemaManagerTest.php b/test/Crate/Test/DBAL/Functional/Schema/SchemaManagerTest.php index 00988d9..8f7fef0 100644 --- a/test/Crate/Test/DBAL/Functional/Schema/SchemaManagerTest.php +++ b/test/Crate/Test/DBAL/Functional/Schema/SchemaManagerTest.php @@ -23,13 +23,14 @@ use Crate\DBAL\Types\MapType; use Crate\DBAL\Types\TimestampType; -use Crate\Test\DBAL\DBALFunctionalTestCase; +use Crate\Test\DBAL\DBALFunctionalTest; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\IntegerType; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; -class SchemaManagerTest extends DBALFunctionalTestCase +class SchemaManagerTest extends DBALFunctionalTest { /** * @var \Doctrine\DBAL\Schema\AbstractSchemaManager @@ -39,7 +40,7 @@ class SchemaManagerTest extends DBALFunctionalTestCase public function setUp() : void { parent::setUp(); - $this->_sm = $this->_conn->getSchemaManager(); + $this->_sm = $this->_conn->createSchemaManager(); } public function tearDown() : void @@ -74,17 +75,22 @@ public function testListTables() public function createListTableColumns() { + // Note that DBAL3 no longer accepts string constants on its `Column` ctor, + // so use the `Type::getType()` notation instead when defining columns + // using `new Column(...)`. Also note that the `addColumn` method still DOES + // accept type names. + $table = new Table('list_table_columns'); - $table->addColumn('text', Type::STRING); + $table->addColumn('text', Types::STRING); $table->addColumn('ts', TimestampType::NAME); - $table->addColumn('num_float_double', Type::FLOAT); - $table->addColumn('num_short', Type::SMALLINT); - $table->addColumn('num_int', Type::INTEGER); - $table->addColumn('num_long', Type::BIGINT); + $table->addColumn('num_float_double', Types::FLOAT); + $table->addColumn('num_short', Types::SMALLINT); + $table->addColumn('num_int', Types::INTEGER); + $table->addColumn('num_long', Types::BIGINT); $table->addColumn('id', 'integer', array('notnull' => true)); $table->setPrimaryKey(array('id')); - // OBJECT schema definition via platform options + // OBJECT schema definition via platform options. $mapOpts = array( 'type' => MapType::STRICT, 'fields' => array( @@ -101,7 +107,7 @@ public function createListTableColumns() // ARRAY schema definition via platform options $arrOpts = array( - 'type' => Type::FLOAT, + 'type' => Types::FLOAT, ); $table->addColumn('arr_float', 'array', array('platformOptions'=>$arrOpts)); @@ -209,7 +215,7 @@ protected function createTestTable($name = 'test_table', $data = array()) protected function getTestTable($name, $options=array()) { - $table = new Table($name, array(), array(), array(), false, $options); + $table = new Table($name, array(), array(), array(), array(), $options); $table->setSchemaConfig($this->_sm->createSchemaConfig()); $table->addColumn('id', 'integer', array('notnull' => true)); $table->setPrimaryKey(array('id')); @@ -220,7 +226,7 @@ protected function getTestTable($name, $options=array()) protected function getTestCompositeTable($name) { - $table = new Table($name, array(), array(), array(), false, array()); + $table = new Table($name, array(), array(), array(), array(), array()); $table->setSchemaConfig($this->_sm->createSchemaConfig()); $table->addColumn('id', 'integer', array('notnull' => true)); $table->addColumn('other_id', 'integer', array('notnull' => true)); diff --git a/test/Crate/Test/DBAL/Functional/TableOptionsTest.php b/test/Crate/Test/DBAL/Functional/TableOptionsTest.php index 9f545b7..4dbced8 100644 --- a/test/Crate/Test/DBAL/Functional/TableOptionsTest.php +++ b/test/Crate/Test/DBAL/Functional/TableOptionsTest.php @@ -23,20 +23,18 @@ namespace Crate\Test\DBAL\Functional; -use Crate\DBAL\Platforms\CratePlatform; -use Crate\Test\DBAL\DBALFunctionalTestCase; -use Doctrine\DBAL\DBALException; +use Crate\Test\DBAL\DBALFunctionalTest; use Doctrine\DBAL\Schema\Table; use InvalidArgumentException; -class TableOptionsTest extends DBALFunctionalTestCase { +class TableOptionsTest extends DBALFunctionalTest { public function tearDown() : void { parent::tearDown(); - if ($this->_conn->getSchemaManager()->tablesExist("ddc1372_foobar")) { + if ($this->_conn->createSchemaManager()->tablesExist("table_option_test")) { try { - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->dropTable('table_option_test'); } catch(\Exception $e) { $this->fail($e->getMessage()); @@ -56,7 +54,7 @@ public function testAdditionalTableOptions() $options['table_options']['number_of_replicas'] = '0-2'; $options['table_options']['write.wait_for_active_shards'] = 'ALL'; - $table = new Table('t1', [], [], [], 0, $options); + $table = new Table('t1', [], [], [], [], $options); $table->addColumn('id', 'integer'); $table->addColumn('parted', 'integer'); $table->addColumn('date', 'timestamp'); @@ -80,12 +78,12 @@ public function testGetAdditionalTableOptions() $options['table_options']['number_of_replicas'] = '0-2'; $options['table_options']['write.wait_for_active_shards'] = 'ALL'; - $table = new Table('table_option_test', [], [], [], 0, $options); + $table = new Table('table_option_test', [], [], [], [], $options); $table->addColumn('id', 'integer'); $table->addColumn('parted', 'integer'); $table->addColumn('date', 'timestamp'); - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->createTable($table); $schema = $sm->createSchema(); @@ -106,7 +104,7 @@ public function testPartitionColumnsNotArray() $options = []; $options['partition_columns'] = 'parted'; - $table = new Table('t1', [], [], [], 0, $options); + $table = new Table('t1', [], [], [], [], $options); $table->addColumn('parted', 'integer'); $this->expectException(InvalidArgumentException::class); diff --git a/test/Crate/Test/DBAL/Functional/TypeConversionTest.php b/test/Crate/Test/DBAL/Functional/TypeConversionTest.php index 7ae5f6e..ddc6c45 100644 --- a/test/Crate/Test/DBAL/Functional/TypeConversionTest.php +++ b/test/Crate/Test/DBAL/Functional/TypeConversionTest.php @@ -23,14 +23,14 @@ namespace Crate\Test\DBAL\Functional; use Crate\DBAL\Platforms\CratePlatform; -use Crate\DBAL\Types\TimestampType; -use Crate\Test\DBAL\DBALFunctionalTestCase; use Crate\DBAL\Types\ArrayType; use Crate\DBAL\Types\MapType; +use Crate\DBAL\Types\TimestampType; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use PHPUnit\Framework\TestCase; -class TypeConversionTestCase extends TestCase { +class TypeConversionTest extends TestCase { private $platform; @@ -44,7 +44,7 @@ public function testTimestampType() $input = new \DateTime("2014-10-21 15:23:38"); // datetimetz - $type = Type::getType(Type::DATETIMETZ); + $type = Type::getType(Types::DATETIMETZ_MUTABLE); $expected = $input->format('Y-m-d\TH:i:sO'); $output = $type->convertToDatabaseValue($input, $this->platform); $this->assertEquals($output, $expected); @@ -54,7 +54,7 @@ public function testTimestampType() $this->assertEquals($inputRestored, $input); // datetime - $type = Type::getType(Type::DATETIME); + $type = Type::getType(Types::DATETIME_MUTABLE); $expected = $input->format('Y-m-d\TH:i:s'); $output = $type->convertToDatabaseValue($input, $this->platform); $this->assertEquals($output, $expected); @@ -64,7 +64,7 @@ public function testTimestampType() $this->assertEquals($inputRestored, $input); // date - $type = Type::getType(Type::DATE); + $type = Type::getType(Types::DATE_MUTABLE); $expected = $input->format('Y-m-d\TH:i:s'); $output = $type->convertToDatabaseValue($input, $this->platform); $this->assertEquals($output, $expected); @@ -74,7 +74,7 @@ public function testTimestampType() $this->assertEquals($inputRestored, $input); // time - $type = Type::getType(Type::TIME); + $type = Type::getType(Types::TIME_MUTABLE); $expected = $input->format('Y-m-d\TH:i:s'); $output = $type->convertToDatabaseValue($input, $this->platform); $this->assertEquals($output, $expected); @@ -96,10 +96,11 @@ public function testTimestampType() public function testTimestampTypeNull() { - $types = array(Type::getType(Type::DATETIMETZ), - Type::getType(Type::DATETIME), - Type::getType(Type::DATE), - Type::getType(Type::TIME), + $types = array( + Type::getType(Types::DATETIMETZ_MUTABLE), + Type::getType(Types::DATETIME_MUTABLE), + Type::getType(Types::DATE_MUTABLE), + Type::getType(Types::TIME_MUTABLE), Type::getType(TimestampType::NAME) ); foreach ($types as $type) { diff --git a/test/Crate/Test/DBAL/Functional/Types/MapTypeTest.php b/test/Crate/Test/DBAL/Functional/Types/MapTypeTest.php index 83a5f71..693b000 100644 --- a/test/Crate/Test/DBAL/Functional/Types/MapTypeTest.php +++ b/test/Crate/Test/DBAL/Functional/Types/MapTypeTest.php @@ -25,12 +25,13 @@ use Crate\DBAL\Platforms\CratePlatform; use Crate\DBAL\Types\MapType; -use Crate\Test\DBAL\DBALFunctionalTestCase; +use Crate\Test\DBAL\DBALFunctionalTest; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; -class MapTypeTest extends DBALFunctionalTestCase { +class MapTypeTest extends DBALFunctionalTest { public function testStrictMapTableCreationWithSchemaManager() { $platform = $this->_conn->getDatabasePlatform(); @@ -39,8 +40,8 @@ public function testStrictMapTableCreationWithSchemaManager() { $objDefinition = array( 'type' => MapType::STRICT, 'fields' => array( - new Column('id', Type::getType(Type::INTEGER), array()), - new Column('name', Type::getType(Type::STRING), array()), + new Column('id', Type::getType(Types::INTEGER), array()), + new Column('name', Type::getType(Types::STRING), array()), ), ); $table->addColumn( diff --git a/test/Crate/Test/DBAL/Functional/WriteTest.php b/test/Crate/Test/DBAL/Functional/WriteTest.php index 635a4ff..d5adb8c 100644 --- a/test/Crate/Test/DBAL/Functional/WriteTest.php +++ b/test/Crate/Test/DBAL/Functional/WriteTest.php @@ -23,12 +23,14 @@ namespace Crate\Test\DBAL\Functional; use Crate\DBAL\Types\MapType; -use Crate\Test\DBAL\DBALFunctionalTestCase; +use Crate\Test\DBAL\DBALFunctionalTest; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use PDO; -class WriteTest extends DBALFunctionalTestCase +class WriteTest extends DBALFunctionalTest { static private $generated = false; @@ -39,25 +41,25 @@ public function setUp() : void if (self::$generated === false) { self::$generated = true; /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ - $table = new \Doctrine\DBAL\Schema\Table("write_table"); - $table->addColumn('test_int', Type::INTEGER); - $table->addColumn('test_string', Type::STRING); - $table->addColumn('test_float', Type::FLOAT); - $table->addColumn('test_array', Type::TARRAY, array('columnDefinition'=>'ARRAY(STRING)')); + $table = new Table("write_table"); + $table->addColumn('test_int', Types::INTEGER); + $table->addColumn('test_string', Types::STRING); + $table->addColumn('test_float', Types::FLOAT); + $table->addColumn('test_array', Types::ARRAY, array('columnDefinition'=>'ARRAY(STRING)')); $table->addColumn("test_map", MapType::NAME); - $table->addColumn("test_bool", Type::BOOLEAN); + $table->addColumn("test_bool", Types::BOOLEAN); $platformOptions = array( 'type' => MapType::STRICT, 'fields' => array( - new Column('id', Type::getType(Type::INTEGER), array()), - new Column('name', Type::getType(Type::STRING), array()), - new Column('value', Type::getType(Type::FLOAT), array()), + new Column('id', Type::getType(Types::INTEGER), array()), + new Column('name', Type::getType(Types::STRING), array()), + new Column('value', Type::getType(Types::FLOAT), array()), ), ); $table->addColumn('test_obj', MapType::NAME, array('platformOptions'=>$platformOptions)); - $sm = $this->_conn->getSchemaManager(); + $sm = $this->_conn->createSchemaManager(); $sm->createTable($table); } } @@ -65,7 +67,7 @@ public function setUp() : void public function tearDown() : void { if (self::$generated === true) { - $this->execute('drop table write_table'); + $this->run_sql('drop table write_table'); self::$generated = false; } } @@ -77,19 +79,27 @@ public function tearDown() : void public function testExecuteUpdateFirstTypeIsNull() { $sql = "INSERT INTO write_table (test_string, test_int) VALUES (?, ?)"; - $this->_conn->executeUpdate($sql, array("text", 1111), array(null, PDO::PARAM_INT)); + $this->_conn->executeStatement($sql, array("text", 1111), array(null, PDO::PARAM_INT)); $this->refresh('write_table'); $sql = "SELECT test_obj, test_string, test_int FROM write_table WHERE test_string = ? AND test_int = ?"; - $this->assertEquals($this->_conn->fetchColumn($sql, array("text", 1111)), null); - $this->assertEquals($this->_conn->fetchColumn($sql, array("text", 1111), 1), "text"); - $this->assertEquals($this->_conn->fetchColumn($sql, array("text", 1111), 2), 1111); + $stmt = $this->_conn->prepare($sql); + $nstmt = $stmt->getWrappedStatement(); + + $stmt->executeQuery(array("text", 1111)); + $this->assertEquals(null, $nstmt->fetchColumn(0)); + + $stmt->executeQuery(array("text", 1111)); + $this->assertEquals("text", $nstmt->fetchColumn(1)); + + $stmt->executeQuery(array("text", 1111)); + $this->assertEquals(1111, $nstmt->fetchColumn(2)); } public function testExecuteUpdate() { $sql = "INSERT INTO write_table (test_int) VALUES ( " . $this->_conn->quote(1, PDO::PARAM_INT) . ")"; - $affected = $this->_conn->executeUpdate($sql); + $affected = $this->_conn->executeStatement($sql); $this->assertEquals(1, $affected, "executeUpdate() should return the number of affected rows!"); } @@ -97,7 +107,7 @@ public function testExecuteUpdate() public function testExecuteUpdateWithTypes() { $sql = "INSERT INTO write_table (test_int, test_string) VALUES (?, ?)"; - $affected = $this->_conn->executeUpdate($sql, array(1, 'foo'), array(\PDO::PARAM_INT, \PDO::PARAM_STR)); + $affected = $this->_conn->executeStatement($sql, array(1, 'foo'), array(PDO::PARAM_INT, PDO::PARAM_STR)); $this->assertEquals(1, $affected, "executeUpdate() should return the number of affected rows!"); } @@ -109,9 +119,9 @@ public function testPrepareRowCountReturnsAffectedRows() $stmt->bindValue(1, 1); $stmt->bindValue(2, "foo"); - $stmt->execute(); + $rowcount = $stmt->executeStatement(); - $this->assertEquals(1, $stmt->rowCount()); + $this->assertEquals(1, $rowcount); } public function testPrepareWithPdoTypes() @@ -119,11 +129,11 @@ public function testPrepareWithPdoTypes() $sql = "INSERT INTO write_table (test_int, test_string) VALUES (?, ?)"; $stmt = $this->_conn->prepare($sql); - $stmt->bindValue(1, 1, \PDO::PARAM_INT); - $stmt->bindValue(2, "foo", \PDO::PARAM_STR); - $stmt->execute(); + $stmt->bindValue(1, 1, PDO::PARAM_INT); + $stmt->bindValue(2, "foo", PDO::PARAM_STR); + $rowcount = $stmt->executeStatement(); - $this->assertEquals(1, $stmt->rowCount()); + $this->assertEquals(1, $rowcount); } public function testPrepareWithDbalTypes() @@ -131,13 +141,14 @@ public function testPrepareWithDbalTypes() $sql = "INSERT INTO write_table (test_int, test_string, test_float, test_obj) VALUES (?, ?, ?, ?)"; $stmt = $this->_conn->prepare($sql); + // Those intentionally use the `Type::getType()` notation, and resolve to DBAL type objects. $stmt->bindValue(1, 1, Type::getType('integer')); $stmt->bindValue(2, "foo", Type::getType('string')); $stmt->bindValue(3, 3.141592, Type::getType('float')); $stmt->bindValue(4, array('id'=>1, 'name'=>'christian', 'value'=>1.234), Type::getType('map')); - $stmt->execute(); + $rowcount = $stmt->executeStatement(); - $this->assertEquals(1, $stmt->rowCount()); + $this->assertEquals(1, $rowcount); } public function testPrepareWithDbalTypeNames() @@ -150,9 +161,9 @@ public function testPrepareWithDbalTypeNames() $stmt->bindValue(3, 3.141592, 'float'); $stmt->bindValue(4, array('id'=>1, 'name'=>'christian', 'value'=>1.234), 'map'); $stmt->bindValue(5, true, 'boolean'); - $stmt->execute(); + $rowcount = $stmt->executeStatement(); - $this->assertEquals(1, $stmt->rowCount()); + $this->assertEquals(1, $rowcount); } public function insertRows() @@ -186,11 +197,11 @@ public function testDelete() $this->assertEquals(1, $this->_conn->delete('write_table', array('test_int' => 2))); $this->refresh('write_table'); - $this->assertEquals(1, count($this->_conn->fetchAll('SELECT * FROM write_table'))); + $this->assertCount(1, $this->_conn->fetchAllAssociative('SELECT * FROM write_table')); $this->assertEquals(1, $this->_conn->delete('write_table', array('test_int' => 1))); $this->refresh('write_table'); - $this->assertEquals(0, count($this->_conn->fetchAll('SELECT * FROM write_table'))); + $this->assertCount(0, $this->_conn->fetchAllAssociative('SELECT * FROM write_table')); } public function testUpdate() diff --git a/test/Crate/Test/DBAL/Platforms/CratePlatformTest.php b/test/Crate/Test/DBAL/Platforms/CratePlatformTest.php index f34f9c5..1a124f6 100644 --- a/test/Crate/Test/DBAL/Platforms/CratePlatformTest.php +++ b/test/Crate/Test/DBAL/Platforms/CratePlatformTest.php @@ -28,14 +28,15 @@ use Crate\DBAL\Types\ArrayType; use Crate\DBAL\Types\MapType; use Doctrine\Common\EventManager; -use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Events; +use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\Tests\Platforms\AbstractPlatformTestCase; use Doctrine\DBAL\Types\Type; -use Doctrine\Tests\DBAL\Platforms\AbstractPlatformTestCase; +use Doctrine\DBAL\Types\Types; class CratePlatformTest extends AbstractPlatformTestCase { @@ -104,7 +105,7 @@ public function getGenerateAlterTableSql() : array public function testAlterTableChangeQuotedColumn() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support renaming columns.'); } protected function getQuotedColumnInPrimaryKeySQL() : array @@ -155,7 +156,7 @@ protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string */ public function testQuotesAlterTableRenameColumn() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support renaming columns.'); } protected function getQuotedAlterTableRenameColumnSQL() : array {} @@ -165,17 +166,22 @@ protected function getQuotedAlterTableRenameColumnSQL() : array {} */ public function testQuotesAlterTableChangeColumnLength() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support changing column lengths.'); } protected function getQuotedAlterTableChangeColumnLengthSQL() : array {} + public function testQuotesAlterTableRenameIndex() : void + { + $this->markTestSkipped('Platform does not support renaming indexes.'); + } + /** * @group DBAL-807 */ public function testQuotesAlterTableRenameIndexInSchema() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support renaming indexes.'); } protected function getCommentOnColumnSQL() : array @@ -192,7 +198,7 @@ protected function getCommentOnColumnSQL() : array */ public function testGeneratesAlterTableRenameColumnSQL() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support renaming columns.'); } public function getAlterTableRenameColumnSQL() : array {} @@ -212,7 +218,7 @@ protected function getQuotesTableIdentifiersInAlterTableSQL() : array {} */ public function testGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : void { - $this->markTestSkipped('Platform does not support ALTER TABLE.'); + $this->markTestSkipped('Platform does not support renaming indexes.'); } protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array {} @@ -350,7 +356,7 @@ public function testUnsupportedUniqueIndexConstraint() $this->expectExceptionMessage("Unique constraints are not supported. Use `primary key` instead"); $table = new Table("foo"); - $table->addColumn("unique_string", "string"); + $table->addColumn("unique_string", Types::STRING); $table->addUniqueIndex(array("unique_string")); $this->platform->getCreateTableSQL($table); } @@ -361,7 +367,7 @@ public function testUniqueConstraintInCustomSchemaOptions() $this->expectExceptionMessage("Unique constraints are not supported. Use `primary key` instead"); $table = new Table("foo"); - $table->addColumn("unique_string", "string")->setCustomSchemaOption("unique", true); + $table->addColumn("unique_string", Types::STRING)->setCustomSchemaOption("unique", true); $this->platform->getCreateTableSQL($table); } @@ -370,7 +376,7 @@ public function testGeneratesTableAlterationSql() : void $expectedSql = $this->getGenerateAlterTableSql(); $tableDiff = new TableDiff('mytable'); - $tableDiff->addedColumns['quota'] = new \Doctrine\DBAL\Schema\Column('quota', \Doctrine\DBAL\Types\Type::getType('integer'), array('notnull' => false)); + $tableDiff->addedColumns['quota'] = new Column('quota', Type::getType(Types::INTEGER), array('notnull' => false)); $sql = $this->platform->getAlterTableSQL($tableDiff); @@ -399,7 +405,7 @@ public function testGetAlterTableSqlDispatchEvent() : void $this->platform->setEventManager($eventManager); $tableDiff = new TableDiff('mytable'); - $tableDiff->addedColumns['added'] = new \Doctrine\DBAL\Schema\Column('added', \Doctrine\DBAL\Types\Type::getType('integer'), array()); + $tableDiff->addedColumns['added'] = new Column('added', Type::getType(Types::INTEGER), array()); $this->platform->getAlterTableSQL($tableDiff); } @@ -407,8 +413,8 @@ public function testGetAlterTableSqlDispatchEvent() : void public function testGenerateTableWithMultiColumnUniqueIndex() : void { $table = new Table('test'); - $table->addColumn('foo', 'string', array('notnull' => false, 'length' => 255)); - $table->addColumn('bar', 'string', array('notnull' => false, 'length' => 255)); + $table->addColumn('foo', Types::STRING, array('notnull' => false, 'length' => 255)); + $table->addColumn('bar', Types::STRING, array('notnull' => false, 'length' => 255)); $table->addUniqueIndex(array("foo", "bar")); $this->expectException(DBALException::class); @@ -420,8 +426,8 @@ public function testGenerateTableWithMultiColumnUniqueIndex() : void public function testGenerateTableWithMultiColumnIndex() { $table = new Table('test'); - $table->addColumn('foo', 'string', array('notnull' => false, 'length' => 255)); - $table->addColumn('bar', 'string', array('notnull' => false, 'length' => 255)); + $table->addColumn('foo', Types::STRING, array('notnull' => false, 'length' => 255)); + $table->addColumn('bar', Types::STRING, array('notnull' => false, 'length' => 255)); $table->addIndex(array("foo", "bar")); $sql = $this->platform->getCreateTableSQL($table); @@ -455,8 +461,8 @@ public function testGenerateObjectSQLDeclaration() array('platformOptions'=>array( 'type'=>MapType::STRICT, 'fields'=>array( - new Column('num', Type::getType(Type::INTEGER)), - new Column('text', Type::getType(Type::STRING)), + new Column('num', Type::getType(Types::INTEGER)), + new Column('text', Type::getType(Types::STRING)), new Column('arr', Type::getType(ArrayType::NAME)), new Column('obj', Type::getType(MapType::NAME)), ), @@ -471,7 +477,7 @@ public function testGenerateArraySQLDeclaration() $this->assertEquals($this->getSQLDeclaration($column), 'arr ARRAY ( TEXT )'); $column = new Column('arr', Type::getType(ArrayType::NAME), - array('platformOptions'=> array('type'=>Type::INTEGER))); + array('platformOptions'=> array('type'=>Types::INTEGER))); $this->assertEquals($this->getSQLDeclaration($column), 'arr ARRAY ( INTEGER )'); } @@ -499,11 +505,77 @@ protected function getQuotesReservedKeywordInTruncateTableSQL() : string /** * @return array}> */ - public function asciiStringSqlDeclarationDataProvider() : array + public static function asciiStringSqlDeclarationDataProvider() : array { return [ ['TEXT', ['length' => 12]], ['TEXT', ['length' => 12, 'fixed' => true]], ]; } + + /** @return string[] */ + protected function getAlterTableRenameIndexSQL(): array + { + return [ + 'DROP INDEX idx_foo', + 'CREATE INDEX idx_bar ON mytable (id)', + ]; + } + + public function testAlterTableRenameIndex(): void + { + $this->markTestSkipped('Platform does not support renaming indexes.'); + } + + public function testAlterTableRenameIndexInSchema(): void + { + $this->markTestSkipped('Platform does not support renaming indexes.'); + } + + public function testRegistersCommentedDoctrineMappingTypeImplicitly(): void + { + $type = Type::getType(Types::ARRAY); + $this->platform->registerDoctrineTypeMapping('foo', Types::ARRAY); + + self::assertFalse($this->platform->isCommentedDoctrineType($type)); + } + + public function testCaseInsensitiveDoctrineTypeMappingFromType(): void + { + $type = new class () extends Type { + /** + * {@inheritDoc} + */ + public function getMappedDatabaseTypes(AbstractPlatform $platform): array + { + return ['OBJECT']; + } + + public function getName(): string + { + return 'map'; + } + + /** + * {@inheritDoc} + */ + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getDecimalTypeDeclarationSQL($column); + } + }; + + $typeName = $type->getName(); + $originalType = Type::getType($typeName); + + Type::overrideType($typeName, get_class($type)); + + try { + self::assertSame($typeName, $this->platform->getDoctrineTypeMapping('ObJecT')); + } finally { + Type::overrideType($typeName, get_class($originalType)); + } + + } + }