Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for comments on table in all databases #3512

Merged
merged 1 commit into from Aug 8, 2019

Conversation

moufmouf
Copy link
Contributor

@moufmouf moufmouf commented Apr 12, 2019

Q A
Type improvement
BC Break no

Summary

I opened a previous PR to add support for table level comments on PostgreSQL: #3499

This PR is an attempt to add the same feature on all databases (and not only MySQL / PostgreSQL).

This PR is built on top of #3499 that already adds support to PostgreSQL.

Commit c4d83a7 moves the functional test from PostgreSQL to the abstract functional test case. Obviously, this test will fail as long as all databases do not support table comments.

Closes #3499

@moufmouf moufmouf force-pushed the comments_on_table_in_all_db branch from 177c2d3 to fb9d2b3 Compare Apr 12, 2019
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Apr 12, 2019

Commit fb9d2b3 adds support for table comments in Sqlite.

Those databases still need some love:

  • Oracle
  • SQL Server
  • DB2

@moufmouf moufmouf force-pushed the comments_on_table_in_all_db branch 5 times, most recently from 4fca80f to b55c861 Compare Apr 15, 2019
@moufmouf moufmouf changed the title [WIP] Comments on table in all databases Comments on table in all databases Apr 15, 2019
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Apr 15, 2019

Current status: thanks to this PR, DB comments are now working on SQLServer and SQlite.
I've "skipped" tests on Oracle and DB2 so this PR can be merged (I can open a PR later for Oracle and DB2)

@moufmouf moufmouf changed the title Comments on table in all databases Support for comments on table in SQL Server and Sqlite Apr 15, 2019
@moufmouf moufmouf force-pushed the comments_on_table_in_all_db branch 5 times, most recently from 58c18cc to b7051fe Compare Apr 15, 2019
@moufmouf moufmouf changed the title Support for comments on table in SQL Server and Sqlite Support for comments on table in SQL Server, Sqlite and Oracle Apr 15, 2019
@moufmouf moufmouf changed the title Support for comments on table in SQL Server, Sqlite and Oracle Support for comments on table in all databases Apr 15, 2019
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Apr 15, 2019

.... and support in DB2 and Oracle has been added! \o/

@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Apr 15, 2019

Since all databases now support table level comments, I took the liberty to add a Table::getComment and a Table::setComment method.
In order to avoid causing BC breaks with MySQL user that previously relied on the "comment" option, those methods are simply writing a "comment" option.

We can remove the "comment" option in the next major release.

Copy link
Member

@morozov morozov left a comment

@moufmouf thank you for putting this together. We may need to do a couple of rounds of reviews and changes to work through the newly introduced APIs.

lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php Outdated Show resolved Hide resolved
@@ -1621,6 +1624,17 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE
return array_merge($sql, $columnSql);
}

public function getCommentOnTableSQL(string $tableName, ?string $comment) : string
Copy link
Member

@morozov morozov Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment is usually part of the table declaration (same as name). Should it really be a new public method or it could be used by CREATE/ALTER table internally?

Copy link
Contributor Author

@moufmouf moufmouf Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a good question. I actually tried to mimic what was done with the comments on columns to be consistent.

There is already a public function getCommentOnColumnSQL() method:

* @param string $tableName
* @param string $columnName
* @param string|null $comment
*
* @return string
*/
public function getCommentOnColumnSQL($tableName, $columnName, $comment)
{
$tableName = new Identifier($tableName);
$columnName = new Identifier($columnName);
return sprintf(
'COMMENT ON COLUMN %s.%s IS %s',
$tableName->getQuotedName($this),
$columnName->getQuotedName($this),
$this->quoteStringLiteral((string) $comment)
);
}

If I was to start from zero, I would probably make the method protected, put it in a trait, and "use" this trait directly in the XXXSchemaManager classes. But since there is already a getCommentOnColumnSQL method, I thought it would be better to do something similar.

I'm really open to any change here, if you think there is a better way.

Copy link
Contributor Author

@moufmouf moufmouf Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is useful to have it as a separate method because the statement can be different (typically, this method is overloaded for SQLServer). However, you are right that it is not necessary to have this "public". I'm moving this to "protected".

lib/Doctrine/DBAL/Platforms/DB2Platform.php Show resolved Hide resolved
lib/Doctrine/DBAL/Platforms/DB2Platform.php Outdated Show resolved Hide resolved
lib/Doctrine/DBAL/Platforms/SqlitePlatform.php Outdated Show resolved Hide resolved
{
$table = parent::listTableDetails($tableName);

/** @var DB2Platform $platform */
Copy link
Member

@morozov morozov Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be some repetition of the code like this: most platforms override listTableDetails(), call the parent and add the comment. Probably, this logic should be part of the parent method itself (most of the platforms support comments).

Copy link
Contributor Author

@moufmouf moufmouf Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but there is a catch.

For most DBMS we want to fetch the comments. For MySQL, we fetch the comments + a bunch of metadata.

What we could do is design a method that returns an array of "options" to be applied to the table. Something like:

    public function listTableDetails($tableName)
    {
        // ....
        $options      = $this->getTableOptions($tableName);
        foreach ($options as $key => $value) {
            $table->addOption($key, $value);
        }
        return $table;
    }

Now, for each XXXSchemaManager, we can provide a protected getTableOptions method that is specific to the schema manager. Would that be ok?

lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php Outdated Show resolved Hide resolved
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Apr 16, 2019

@morozov thanks a lot for the review. I took in account most of your comments and added some questions/comments where I'm not completely sure what the best solution is.

@morozov
Copy link
Member

@morozov morozov commented Apr 18, 2019

@moufmouf sorry, I don't have enough time for this issue right now, so please don't take my absence for ignoring. Unless other core team members help you finish the code changes, I'll try to get back to this as soon as I can.

SenseException
SenseException previously requested changes Apr 19, 2019
lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php Outdated Show resolved Hide resolved
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented May 14, 2019

Any more feedback on this?
Ping @morozov

Ocramius
Ocramius previously approved these changes May 14, 2019
Copy link
Member

@Ocramius Ocramius left a comment

LGTM 👍

@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Aug 1, 2019

Trying to revive this stalled PR (sorry, I got a lot of work lately).
I took into account @Ocramius comments regarding the useless trimming of table comments in Sqlite.

I pulled from master in order to get the latest changes and the build is now failing for a reason that seems unrelated to this PR.
@Ocramius @morozov Do you see any more changes to be made?

@morozov
Copy link
Member

@morozov morozov commented Aug 3, 2019

@moufmouf please rebase. All existing issues should be resolved, however MySQL 8 builds may still fail.

@moufmouf moufmouf force-pushed the comments_on_table_in_all_db branch from fcb52fa to d9b9fb2 Compare Aug 5, 2019
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Aug 5, 2019

@morozov Rebase done.

@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Aug 6, 2019

@morozov @Ocramius I think I handled all comments on this PR.

Is there anything else you want me to do or should I let it rest here until it is merged?

(more specifically, OracleSchemaManager is now rated C by Scrutinizer after I added a new method in it, but I don't really see how to make that rating go away)

@morozov
Copy link
Member

@morozov morozov commented Aug 6, 2019

Is there anything else you want me to do or should I let it rest here until it is merged?

I think we're good. Please squash the commits unless you think some of them are relevant fro the history.

@moufmouf moufmouf force-pushed the comments_on_table_in_all_db branch from d9b9fb2 to 62c2a8b Compare Aug 7, 2019
@moufmouf
Copy link
Contributor Author

@moufmouf moufmouf commented Aug 8, 2019

@morozov Squash done.
Thanks a lot for taking the time to review this PR!

morozov
morozov approved these changes Aug 8, 2019
@morozov morozov merged commit 9ff47e7 into doctrine:master Aug 8, 2019
3 of 4 checks passed
@morozov
Copy link
Member

@morozov morozov commented Aug 8, 2019

🚢

@morozov morozov added this to the 2.10.0 milestone Nov 2, 2019
@morozov morozov self-assigned this Nov 2, 2019
rgrellmann added a commit to Rossmann-IT/dbal that referenced this issue Apr 22, 2020
# Release v2.10.0

This is a minor release of Doctrine DBAL that aggregates over 70 fixes and improvements developed by 25 contributors over the last year.

This release focuses on internal code quality improvement and deprecating the functionality identified for removal in the next major release.

## Backwards Compatibility Breaks

This release introduces a minor BC break. Default column values are no longer handled as SQL expressions. They are converted to SQL literals (e.g. escaped). The previous behavior was not portable and was never by design.

Clients must now specify default values in their initial form, not in the form of an SQL literal (e.g. escaped).

**Before:**

```php
$column->setDefault('Foo\\\\Bar\\\\Baz');
```

**After:**

```php
$column->setDefault('Foo\\Bar\\Baz');
```

## Deprecations

- The usage of the `getDriver()`, `getDatabasePlatform()` and `getSchemaManager()` methods of the `ConnectionEventArgs` class has been deprecated.
- The usage of the `getDatabasePlatform()` method of the `SchemaColumnDefinitionEventArgs` class has been deprecated.
- The usage of the `getHost()`, `getPort()`, `getUsername()` and `getPassword()` methods of the `Connection` class has been deprecated.
- Passing multiple SQL statements as an array to `SchemaAlterTableAddColumnEventArgs::addSql()` and the same method in other `SchemaEventArgs`-based classes is deprecated.
- Calling `AbstractSchemaManager::tablesExist()` with a string argument is deprecated.
- Calling `OracleSchemaManager::createDatabase()` without an argument or by passing `NULL` is deprecated.
- Unused schema manager methods are deprecated.
   -  `AbstractSchemaManager::_getPortableFunctionsList()`,
   - `AbstractSchemaManager::_getPortableFunctionDefinition()`,
   - `OracleSchemaManager::_getPortableFunctionDefinition()`,
   - `SqliteSchemaManager::_getPortableTableIndexDefinition()`.
- The usage of `NULL` to indicate empty `$username` or `$password` when calling `Doctrine\DBAL\Driver::connect()` is deprecated.
- Method `Doctrine\DBAL\Platforms::_getAlterTableIndexForeignKeySQL()` has been deprecated as no longer used.
- Property `Doctrine\DBAL\Driver\OCI8\OCI8Statement::$_PARAM` has been deprecated as not used.
- Method `Doctrine\DBAL\Driver::getName()` is deprecated.
- The usage of user-provided `PDO` instance is deprecated.
- `Type::*` constants are deprecated.
- The `Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement::LAST_INSERT_ID_SQL` constant has been deprecated.
- The constants in `Doctrine\DBAL\SQLParserUtils` have been deprecated.
- The `Doctrine\DBAL\Logging\LoggerChain::addLogger` method has been deprecated.

Please see the details in the [UPGRADE.md](UPGRADE.md) documentation.

## New Features and Improvements

- [3674: Add missing MySQL 8.0 reserved keywords](doctrine#3674) thanks to @loilo
- [3512: Support for comments on table in all databases](doctrine#3512) thanks to @moufmouf
- [3418: Add column charset for MySql](doctrine#3418) thanks to @altertable

**MySQL-related changes:**

 - [3668: Quote collation on MySQL](doctrine#3668) thanks to @staudenmeir
 - [3374: Clean up `MySqlPlatform::getListTableIndexesSQL()` fields](doctrine#3374) thanks to @BenMorel
 - [3311: Ensuring correct `ALTER TABLE` statement for creation of an `AUTO INCREMENT` column as new `PRIMARY KEY`](doctrine#3311) thanks to @arnegroskurth

**Driver level changes:**

- [3677: Relax statement type declaration](doctrine#3677) thanks to @greg0ire
- [3521: Maintain platform parameter in connection params](doctrine#3521) thanks to @jwage and @Perf
- [3588: Add commit result bool](doctrine#3588) thanks to @otazniksk

**Schema management:**

- [2960: Handle default values as values, not SQL expressions](doctrine#2960) thanks to @morozov

**Types improvements:**

 - [3356: Extract constants for built-in types from Type to Types](doctrine#3356) thanks to @Majkl578
 - [3354: Extract type factory and registry from Type into TypeRegistry](doctrine#3354) thanks to @Majkl578

**Compatibility with Symfony 5:**

 - [3706: add missing exit codes to ensure Symfony 5 compatibility](doctrine#3706) thanks to @dmaicher
 - [3563: Allow Symfony 5](doctrine#3563) thanks to @nicolas-grekas

**Query Builder:**

 - [3696: Add support for `DISTINCT` clause](doctrine#3696) thanks to @bingo-soft

**Logging:**

 - [3572: Make LoggerChain use constructor to add loggers instead of adder method](doctrine#3572) thanks to @ostrolucky

**Code quality improvements:**

 - [3667: Phpstan fix backport](doctrine#3667) thanks to @morozov
 - [3663: Updated PHPStan to v0.11.15](doctrine#3663) thanks to @morozov
 - [3604: Updated Jetbrains PhpStorm stubs to 2019.1](doctrine#3604) thanks to @morozov
 - [3549: Removed the assertion which doesn't work with a user-provided PDO connection](doctrine#3549) thanks to @morozov
 - [3489: Update doctrine coding standard from 5.0 to 6.0](doctrine#3489) thanks to @amaabdou
 - [3481: Updated PHPStan to v0.11.3](doctrine#3481) thanks to @morozov
 - [3443: PHPStan Level 7](doctrine#3443) thanks to @morozov
 - [3442: PHPStan Level 6](doctrine#3442) thanks to @morozov
 - [3436: PHPStan Level 5](doctrine#3436) thanks to @morozov
 - [3435: PHPStan Level 4](doctrine#3435) thanks to @morozov
 - [3432: Updated PHPStan to v0.11](doctrine#3432) thanks to @morozov

**Test suite improvements:**

 - [3705: Don't skip a test for sqlite](doctrine#3705) thanks to @Federkun
 - [3689: Updated PHPUnit to 8.4.1](doctrine#3689) thanks to @morozov
 - [3664: Refactor usage of MockBuilder's deprecated setMethods()](doctrine#3664) thanks to @baspeeters
 - [3643: Bumped PHPUnit requrement to ^8.3.3, removed dependency on symfony/phpunit-bridge](doctrine#3643) thanks to @morozov
 - [3609: Reworked the mocks generated by Prophecy using PHPUnit](doctrine#3609) thanks to @morozov
 - [3608: Added a unit test for Doctrine\DBAL\Logging\LoggerChain](doctrine#3608) thanks to @morozov
 - [3600: Updated PHPUnit to 8.2.1](doctrine#3600) thanks to @morozov
 - [3575: Enforced parameter and return value types in test classes](doctrine#3575) thanks to @morozov
 - [3566: Upgraded to PHPUnit 8.1.6 and reworked the remaining driver exception mock](doctrine#3566) thanks to @morozov
 - [3555: Removed the rest of mock classes](doctrine#3555) thanks to @morozov
 - [3546: Reworked driver exception tests](doctrine#3546) thanks to @morozov
 - [3530: Improve ExceptionTest::testConnectionExceptionSqLite](doctrine#3530) thanks to @jwage
 - [3474: Remove more hard-coded mock classes](doctrine#3474) thanks to @morozov
 - [3470: Replaced MockPlatform with the ones generated by PHPUnit](doctrine#3470) thanks to @morozov
 - [3468: Marked some test classes abstract](doctrine#3468) thanks to @morozov
 - [3446: Upgraded PHPUnit to 8.0](doctrine#3446) thanks to @morozov

**Documentation improvements:**

 - [3616: Fix typo in docblock](doctrine#3616) thanks to @rdarcy1
 - [3559: add .github/FUNDING.yml](doctrine#3559) thanks to @jwage
 - [3556: Removed 2.8 from README](doctrine#3556) thanks to @morozov
 - [3514: Expand list of keywords in composer.json](doctrine#3514) thanks to @Majkl578
 - [3504: fix doctrine#3479 (typos in example-code in QueryBuilder)](doctrine#3504) thanks to @DavidBruchmann
 - [3503: Fix the branch alias for master](doctrine#3503) thanks to @stof
 - [3463: fixed a typo in PoolingShardConnection phpdoc](doctrine#3463) thanks to @adapik
 - [3408: Removed unused build files](doctrine#3408) thanks to @morozov
 - [3404: Link to Slack instead of Gitter](doctrine#3404) thanks to @greg0ire
 - [3376: Bump version to 2.10.0-DEV](doctrine#3376) thanks to @morozov

**CI improvements:**

 - [3688: Temporarily disable the usage of PHPUnit 8.4 due to a regression](doctrine#3688) thanks to @morozov
 - [3654: fix Appveyor builds](doctrine#3654) thanks to @mmucklo
 - [3644: Using command line options to configure MySQL 8 instead of mounting a config file](doctrine#3644) thanks to @morozov
 - [3509: Enabled the build against IBM DB2 on PHP 7.3 on Travis CI](doctrine#3509) thanks to @morozov
 - [3528: Reworked SQL Server installer on Travis CI](doctrine#3528) thanks to @morozov
 - [3484: Use latest stable versions of sqlsrv and pdo&doctrine#95;sqlsrv on CI](doctrine#3484) thanks to @morozov
 - [3475: Make PHP 7.3 the primary PHP version on Travis CI](doctrine#3475) thanks to @morozov
 - [3473: Avoid database connection from PHPUnit data providers](doctrine#3473) thanks to @morozov
 - [3469: Replaced Xdebug with PCOV for code coverage](doctrine#3469) thanks to @morozov
 - [3405: Travis CI: PHP 7.3 tests on MySQL 8.0](doctrine#3405) thanks to @BenMorel
 - [3394: Grouped PHPStan and PHP&doctrine#95;CodeSniffer for parallel execution](doctrine#3394) thanks to @morozov
 - [3388: Require PHP 7.2, drop <7.2 in Composer & on CI](doctrine#3388) thanks to @morozov
 - [3122: Introduced a smoke testing phase on Travis to run SQLite tests and CS checks first](doctrine#3122) thanks to @morozov

**Deprecations:**

 - [3708: New deprecations for 2.10](doctrine#3708) thanks to @morozov and @jwage
 - [3598: Deprecated some unused code bits](doctrine#3598) thanks to @morozov
 - [3558: Deprecated Driver::getName()](doctrine#3558) thanks to @morozov
 - [3554: The usage of user-provided PDO instance is deprecated](doctrine#3554) thanks to @morozov
 - [3542: Deprecate SQLSrvStatement::LAST&doctrine#95;INSERT&doctrine#95;ID&doctrine#95;SQL constant.](doctrine#3542) thanks to @jwage
 - [3541: Deprecate the public constants in SQLParserUtils](doctrine#3541) thanks to @jwage

# gpg: Signature made Sun Nov  3 17:56:11 2019
# gpg:                using RSA key 374EADAF543AE995
# gpg: Can't check signature: public key not found

# Conflicts:
#	.travis.yml
#	README.md
#	lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
#	lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php
#	lib/Doctrine/DBAL/Schema/Table.php
#	lib/Doctrine/DBAL/Version.php
#	phpcs.xml.dist
#	tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php
#	tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php
#	tests/Doctrine/Tests/DBAL/Functional/MasterSlaveConnectionTest.php
#	tests/Doctrine/Tests/DBAL/Functional/Platform/DefaultExpressionTest.php
#	tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
#	tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php
#	tests/Doctrine/Tests/DBAL/Schema/ComparatorTest.php
#	tests/travis/mysql.docker.travis.xml
#	tests/travis/mysqli.docker.travis.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants