From 0399fd4fa5429f0da3b87a0bfc23ccae6c8d74f0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2020 02:15:27 +0000 Subject: [PATCH] Bump doctrine/dbal from 2.9.2 to 2.10.1 Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 2.9.2 to 2.10.1. - [Release notes](https://github.com/doctrine/dbal/releases) - [Commits](https://github.com/doctrine/dbal/compare/v2.9.2...v2.10.1) Signed-off-by: dependabot-preview[bot] Signed-off-by: Christoph Wurst --- composer.json | 2 +- composer.lock | 117 ++- composer/autoload_classmap.php | 4 +- composer/autoload_static.php | 4 +- composer/installed.json | 119 ++- doctrine/cache/README.md | 2 +- doctrine/cache/docs/en/index.rst | 274 ----- .../lib/Doctrine/Common/Cache/ApcCache.php | 3 +- .../Doctrine/Common/Cache/CacheProvider.php | 2 +- .../lib/Doctrine/Common/Cache/ChainCache.php | 3 +- .../Common/Cache/CouchbaseBucketCache.php | 4 +- .../Doctrine/Common/Cache/CouchbaseCache.php | 5 +- .../Doctrine/Common/Cache/ExtMongoDBCache.php | 6 +- .../lib/Doctrine/Common/Cache/FileCache.php | 21 +- .../Doctrine/Common/Cache/InvalidCacheId.php | 25 + .../Common/Cache/LegacyMongoDBCache.php | 3 +- .../Doctrine/Common/Cache/MemcacheCache.php | 6 +- .../Doctrine/Common/Cache/MemcachedCache.php | 40 + .../Doctrine/Common/Cache/MongoDBCache.php | 4 +- .../Common/Cache/MultiDeleteCache.php | 3 +- .../Doctrine/Common/Cache/MultiGetCache.php | 4 +- .../Doctrine/Common/Cache/MultiPutCache.php | 3 +- .../Doctrine/Common/Cache/PhpFileCache.php | 2 +- .../lib/Doctrine/Common/Cache/PredisCache.php | 2 +- .../lib/Doctrine/Common/Cache/RedisCache.php | 42 +- .../lib/Doctrine/Common/Cache/RiakCache.php | 228 ----- .../Doctrine/Common/Cache/SQLite3Cache.php | 4 +- .../lib/Doctrine/Common/Cache/Version.php | 2 +- .../lib/Doctrine/Common/Cache/XcacheCache.php | 10 +- .../Doctrine/Common/Cache/ZendDataCache.php | 1 + doctrine/dbal/.appveyor.yml | 27 +- doctrine/dbal/.doctrine-project.json | 55 + doctrine/dbal/.github/FUNDING.yml | 3 + .../dbal/.github/ISSUE_TEMPLATE/BC_Break.md | 37 + doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md | 34 + .../.github/ISSUE_TEMPLATE/Feature_Request.md | 18 + .../ISSUE_TEMPLATE/Support_Question.md | 20 + .../dbal/.github/PULL_REQUEST_TEMPLATE.md | 11 + doctrine/dbal/.scrutinizer.yml | 2 +- doctrine/dbal/README.md | 31 +- doctrine/dbal/UPGRADE.md | 95 +- doctrine/dbal/composer.json | 38 +- doctrine/dbal/composer.lock | 946 +++++++++++------- .../DBAL/Cache/ResultCacheStatement.php | 17 +- .../dbal/lib/Doctrine/DBAL/Configuration.php | 4 +- .../dbal/lib/Doctrine/DBAL/Connection.php | 179 ++-- .../Connections/MasterSlaveConnection.php | 10 +- .../dbal/lib/Doctrine/DBAL/DBALException.php | 33 +- doctrine/dbal/lib/Doctrine/DBAL/Driver.php | 4 + .../DBAL/Driver/DrizzlePDOMySql/Driver.php | 2 + .../DBAL/Driver/IBMDB2/DB2Connection.php | 9 +- .../Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php | 4 +- .../DBAL/Driver/IBMDB2/DB2Statement.php | 24 +- .../Doctrine/DBAL/Driver/Mysqli/Driver.php | 2 +- .../DBAL/Driver/Mysqli/MysqliStatement.php | 105 +- .../lib/Doctrine/DBAL/Driver/OCI8/Driver.php | 8 +- .../DBAL/Driver/OCI8/OCI8Connection.php | 54 +- .../DBAL/Driver/OCI8/OCI8Exception.php | 6 +- .../DBAL/Driver/OCI8/OCI8Statement.php | 73 +- .../Doctrine/DBAL/Driver/PDOConnection.php | 26 +- .../Doctrine/DBAL/Driver/PDOIbm/Driver.php | 2 + .../Doctrine/DBAL/Driver/PDOMySql/Driver.php | 2 + .../Doctrine/DBAL/Driver/PDOPgSql/Driver.php | 2 + .../Doctrine/DBAL/Driver/PDOSqlite/Driver.php | 2 + .../Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php | 39 +- .../lib/Doctrine/DBAL/Driver/PDOStatement.php | 67 +- .../DBAL/Driver/SQLAnywhere/Driver.php | 2 + .../SQLAnywhere/SQLAnywhereException.php | 9 - .../SQLAnywhere/SQLAnywhereStatement.php | 10 +- .../Doctrine/DBAL/Driver/SQLSrv/Driver.php | 2 + .../DBAL/Driver/SQLSrv/SQLSrvConnection.php | 21 +- .../DBAL/Driver/SQLSrv/SQLSrvException.php | 4 +- .../DBAL/Driver/SQLSrv/SQLSrvStatement.php | 29 +- .../lib/Doctrine/DBAL/Driver/Statement.php | 2 +- .../DBAL/Driver/StatementIterator.php | 4 +- .../dbal/lib/Doctrine/DBAL/DriverManager.php | 9 +- .../DBAL/Event/ConnectionEventArgs.php | 6 + .../SchemaAlterTableAddColumnEventArgs.php | 9 +- .../SchemaAlterTableChangeColumnEventArgs.php | 9 +- .../DBAL/Event/SchemaAlterTableEventArgs.php | 9 +- .../SchemaAlterTableRemoveColumnEventArgs.php | 9 +- .../SchemaAlterTableRenameColumnEventArgs.php | 9 +- .../Event/SchemaColumnDefinitionEventArgs.php | 2 + .../SchemaCreateTableColumnEventArgs.php | 9 +- .../DBAL/Event/SchemaCreateTableEventArgs.php | 18 +- .../DBAL/Event/SchemaDropTableEventArgs.php | 5 - .../lib/Doctrine/DBAL/Logging/LoggerChain.php | 10 + .../DBAL/Platforms/AbstractPlatform.php | 71 +- .../Doctrine/DBAL/Platforms/DB2Platform.php | 34 +- .../DBAL/Platforms/DrizzlePlatform.php | 12 +- .../Platforms/Keywords/MySQL80Keywords.php | 3 + .../DBAL/Platforms/MariaDb1027Platform.php | 4 +- .../DBAL/Platforms/MySQL57Platform.php | 4 +- .../Doctrine/DBAL/Platforms/MySqlPlatform.php | 60 +- .../DBAL/Platforms/OraclePlatform.php | 39 +- .../DBAL/Platforms/PostgreSQL92Platform.php | 4 +- .../DBAL/Platforms/PostgreSQL94Platform.php | 4 +- .../DBAL/Platforms/PostgreSqlPlatform.php | 30 +- .../DBAL/Platforms/SQLAnywherePlatform.php | 23 +- .../DBAL/Platforms/SQLServerPlatform.php | 136 +-- .../DBAL/Platforms/SqlitePlatform.php | 70 +- .../Doctrine/DBAL/Portability/Connection.php | 4 +- .../Doctrine/DBAL/Portability/Statement.php | 18 +- .../Query/Expression/ExpressionBuilder.php | 4 +- .../lib/Doctrine/DBAL/Query/QueryBuilder.php | 64 +- .../dbal/lib/Doctrine/DBAL/README.markdown | 0 .../dbal/lib/Doctrine/DBAL/SQLParserUtils.php | 78 +- .../Doctrine/DBAL/Schema/AbstractAsset.php | 2 +- .../DBAL/Schema/AbstractSchemaManager.php | 61 +- .../dbal/lib/Doctrine/DBAL/Schema/Column.php | 4 +- .../lib/Doctrine/DBAL/Schema/ColumnDiff.php | 2 +- .../lib/Doctrine/DBAL/Schema/Comparator.php | 11 +- .../Doctrine/DBAL/Schema/DB2SchemaManager.php | 31 +- .../DBAL/Schema/ForeignKeyConstraint.php | 46 +- .../dbal/lib/Doctrine/DBAL/Schema/Index.php | 4 +- .../DBAL/Schema/MySqlSchemaManager.php | 62 +- .../DBAL/Schema/OracleSchemaManager.php | 27 +- .../DBAL/Schema/PostgreSqlSchemaManager.php | 48 +- .../DBAL/Schema/SQLAnywhereSchemaManager.php | 9 +- .../DBAL/Schema/SQLServerSchemaManager.php | 67 +- .../dbal/lib/Doctrine/DBAL/Schema/Schema.php | 8 +- .../lib/Doctrine/DBAL/Schema/SchemaDiff.php | 2 +- .../lib/Doctrine/DBAL/Schema/Sequence.php | 11 +- .../DBAL/Schema/SqliteSchemaManager.php | 64 +- .../SingleDatabaseSynchronizer.php | 8 +- .../dbal/lib/Doctrine/DBAL/Schema/Table.php | 50 +- .../lib/Doctrine/DBAL/Schema/TableDiff.php | 12 +- .../Visitor/CreateSchemaSqlCollector.php | 2 +- .../Schema/Visitor/DropSchemaSqlCollector.php | 3 + .../Doctrine/DBAL/Schema/Visitor/Graphviz.php | 9 +- .../Schema/Visitor/RemoveNamespacedAssets.php | 1 + .../DBAL/Sharding/PoolingShardConnection.php | 20 +- .../SQLAzureFederationsSynchronizer.php | 9 +- .../SQLAzure/SQLAzureShardManager.php | 6 - doctrine/dbal/lib/Doctrine/DBAL/Statement.php | 4 +- .../Tools/Console/Command/ImportCommand.php | 17 +- .../Tools/Console/Command/RunSqlCommand.php | 6 + .../dbal/lib/Doctrine/DBAL/Tools/Dumper.php | 10 +- .../lib/Doctrine/DBAL/Types/ArrayType.php | 4 +- .../lib/Doctrine/DBAL/Types/BigIntType.php | 2 +- .../lib/Doctrine/DBAL/Types/BinaryType.php | 6 +- .../dbal/lib/Doctrine/DBAL/Types/BlobType.php | 6 +- .../lib/Doctrine/DBAL/Types/BooleanType.php | 2 +- .../Doctrine/DBAL/Types/DateImmutableType.php | 2 +- .../Doctrine/DBAL/Types/DateIntervalType.php | 2 +- .../DBAL/Types/DateTimeImmutableType.php | 2 +- .../lib/Doctrine/DBAL/Types/DateTimeType.php | 2 +- .../DBAL/Types/DateTimeTzImmutableType.php | 2 +- .../Doctrine/DBAL/Types/DateTimeTzType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/DateType.php | 2 +- .../lib/Doctrine/DBAL/Types/DecimalType.php | 2 +- .../lib/Doctrine/DBAL/Types/FloatType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/GuidType.php | 2 +- .../lib/Doctrine/DBAL/Types/IntegerType.php | 2 +- .../lib/Doctrine/DBAL/Types/JsonArrayType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/JsonType.php | 2 +- .../lib/Doctrine/DBAL/Types/ObjectType.php | 4 +- .../Doctrine/DBAL/Types/SimpleArrayType.php | 2 +- .../lib/Doctrine/DBAL/Types/SmallIntType.php | 2 +- .../lib/Doctrine/DBAL/Types/StringType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/TextType.php | 2 +- .../Doctrine/DBAL/Types/TimeImmutableType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/TimeType.php | 2 +- .../dbal/lib/Doctrine/DBAL/Types/Type.php | 237 +++-- .../lib/Doctrine/DBAL/Types/TypeRegistry.php | 118 +++ .../dbal/lib/Doctrine/DBAL/Types/Types.php | 43 + .../DBAL/Types/VarDateTimeImmutableType.php | 2 +- doctrine/dbal/lib/Doctrine/DBAL/Version.php | 2 +- doctrine/dbal/phpcs.xml.dist | 22 +- doctrine/dbal/phpstan.neon.dist | 58 ++ doctrine/event-manager/.doctrine-project.json | 18 + doctrine/event-manager/.scrutinizer.yml | 29 - doctrine/event-manager/composer.json | 17 +- doctrine/event-manager/docs/en/index.rst | 22 - .../event-manager/docs/en/reference/index.rst | 133 --- doctrine/event-manager/docs/en/sidebar.rst | 4 - .../lib/Doctrine/Common/EventArgs.php | 3 +- .../lib/Doctrine/Common/EventManager.php | 1 + 178 files changed, 3022 insertions(+), 2150 deletions(-) delete mode 100644 doctrine/cache/docs/en/index.rst create mode 100644 doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php delete mode 100644 doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php create mode 100644 doctrine/dbal/.doctrine-project.json create mode 100644 doctrine/dbal/.github/FUNDING.yml create mode 100644 doctrine/dbal/.github/ISSUE_TEMPLATE/BC_Break.md create mode 100644 doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md create mode 100644 doctrine/dbal/.github/ISSUE_TEMPLATE/Feature_Request.md create mode 100644 doctrine/dbal/.github/ISSUE_TEMPLATE/Support_Question.md create mode 100644 doctrine/dbal/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 doctrine/dbal/lib/Doctrine/DBAL/README.markdown create mode 100644 doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php create mode 100644 doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php create mode 100644 doctrine/dbal/phpstan.neon.dist create mode 100644 doctrine/event-manager/.doctrine-project.json delete mode 100644 doctrine/event-manager/.scrutinizer.yml delete mode 100644 doctrine/event-manager/docs/en/index.rst delete mode 100644 doctrine/event-manager/docs/en/reference/index.rst delete mode 100644 doctrine/event-manager/docs/en/sidebar.rst diff --git a/composer.json b/composer.json index 5895c7c36..9ad80fff0 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "christophwurst/id3parser": "^0.1.1", "deepdiver/zipstreamer": "1.1.1", "deepdiver1975/tarstreamer": "v2.0.0", - "doctrine/dbal": "2.9.2", + "doctrine/dbal": "2.10.1", "guzzlehttp/guzzle": "6.5.2", "icewind/searchdav": "1.0.2", "icewind/streams": "v0.7.1", diff --git a/composer.lock b/composer.lock index efc9e040c..ffc4eb5f2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "804a031329d81370401cee94d194c409", + "content-hash": "6f296b021db5897861901632a4d79a90", "packages": [ { "name": "aws/aws-sdk-php", @@ -332,16 +332,16 @@ }, { "name": "doctrine/cache", - "version": "v1.8.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "url": "https://api.github.com/repos/doctrine/cache/zipball/382e7f4db9a12dc6c19431743a2b096041bcdd62", + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62", "shasum": "" }, "require": { @@ -352,7 +352,7 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" @@ -363,7 +363,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.9.x-dev" } }, "autoload": { @@ -376,6 +376,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -384,10 +388,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -397,13 +397,20 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "https://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ + "abstraction", + "apcu", "cache", - "caching" + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ], - "time": "2018-08-21T18:01:43+00:00" + "time": "2019-11-29T15:36:20+00:00" }, { "name": "doctrine/collections", @@ -555,31 +562,30 @@ }, { "name": "doctrine/dbal", - "version": "v2.9.2", + "version": "v2.10.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", + "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", "shasum": "" }, "require": { "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.1" + "php": "^7.2" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "jetbrains/phpstorm-stubs": "^2018.1.2", - "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.4", - "symfony/console": "^2.0.5|^3.0|^4.0", - "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + "doctrine/coding-standard": "^6.0", + "jetbrains/phpstorm-stubs": "^2019.1", + "phpstan/phpstan": "^0.11.3", + "phpunit/phpunit": "^8.4.1", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -590,7 +596,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.9.x-dev", + "dev-master": "2.10.x-dev", "dev-develop": "3.0.x-dev" } }, @@ -604,6 +610,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -612,10 +622,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -626,27 +632,38 @@ "keywords": [ "abstraction", "database", + "db2", "dbal", + "mariadb", + "mssql", "mysql", - "persistence", + "oci8", + "oracle", + "pdo", "pgsql", - "php", - "queryobject" - ], - "time": "2018-12-31T03:27:51+00:00" + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "time": "2020-01-04T12:56:21+00:00" }, { "name": "doctrine/event-manager", - "version": "v1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + "reference": "629572819973f13486371cb611386eb17851e85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/629572819973f13486371cb611386eb17851e85c", + "reference": "629572819973f13486371cb611386eb17851e85c", "shasum": "" }, "require": { @@ -656,7 +673,7 @@ "doctrine/common": "<2.9@dev" }, "require-dev": { - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.0" }, "type": "library", @@ -675,6 +692,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -683,10 +704,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -700,14 +717,16 @@ "email": "ocramius@gmail.com" } ], - "description": "Doctrine Event Manager component", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ "event", - "eventdispatcher", - "eventmanager" + "event dispatcher", + "event manager", + "event system", + "events" ], - "time": "2018-06-11T11:59:03+00:00" + "time": "2019-11-10T09:48:07+00:00" }, { "name": "doctrine/inflector", diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index 4fdfc4734..7fdc0e955 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -572,6 +572,7 @@ 'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php', 'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php', 'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php', + 'Doctrine\\Common\\Cache\\InvalidCacheId' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php', 'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php', 'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php', 'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php', @@ -583,7 +584,6 @@ 'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php', 'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php', 'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php', - 'Doctrine\\Common\\Cache\\RiakCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php', 'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php', 'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php', 'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php', @@ -910,6 +910,8 @@ 'Doctrine\\DBAL\\Types\\TimeImmutableType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php', 'Doctrine\\DBAL\\Types\\TimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php', 'Doctrine\\DBAL\\Types\\Type' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php', + 'Doctrine\\DBAL\\Types\\TypeRegistry' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php', + 'Doctrine\\DBAL\\Types\\Types' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php', 'Doctrine\\DBAL\\Types\\VarDateTimeImmutableType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.php', 'Doctrine\\DBAL\\Types\\VarDateTimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php', 'Doctrine\\DBAL\\Version' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Version.php', diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 9879819f3..3043f3e11 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -1029,6 +1029,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\Common\\Cache\\FileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php', 'Doctrine\\Common\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php', 'Doctrine\\Common\\Cache\\FlushableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php', + 'Doctrine\\Common\\Cache\\InvalidCacheId' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php', 'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php', 'Doctrine\\Common\\Cache\\MemcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php', 'Doctrine\\Common\\Cache\\MemcachedCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php', @@ -1040,7 +1041,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\Common\\Cache\\PhpFileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php', 'Doctrine\\Common\\Cache\\PredisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php', 'Doctrine\\Common\\Cache\\RedisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php', - 'Doctrine\\Common\\Cache\\RiakCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php', 'Doctrine\\Common\\Cache\\SQLite3Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php', 'Doctrine\\Common\\Cache\\Version' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php', 'Doctrine\\Common\\Cache\\VoidCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php', @@ -1367,6 +1367,8 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Types\\TimeImmutableType' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php', 'Doctrine\\DBAL\\Types\\TimeType' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php', 'Doctrine\\DBAL\\Types\\Type' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php', + 'Doctrine\\DBAL\\Types\\TypeRegistry' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php', + 'Doctrine\\DBAL\\Types\\Types' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php', 'Doctrine\\DBAL\\Types\\VarDateTimeImmutableType' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.php', 'Doctrine\\DBAL\\Types\\VarDateTimeType' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php', 'Doctrine\\DBAL\\Version' => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL/Version.php', diff --git a/composer/installed.json b/composer/installed.json index 5b2f640d8..5b20bcd4d 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -337,17 +337,17 @@ }, { "name": "doctrine/cache", - "version": "v1.8.0", - "version_normalized": "1.8.0.0", + "version": "1.10.0", + "version_normalized": "1.10.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "url": "https://api.github.com/repos/doctrine/cache/zipball/382e7f4db9a12dc6c19431743a2b096041bcdd62", + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62", "shasum": "" }, "require": { @@ -358,7 +358,7 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" @@ -366,11 +366,11 @@ "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, - "time": "2018-08-21T18:01:43+00:00", + "time": "2019-11-29T15:36:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.9.x-dev" } }, "installation-source": "dist", @@ -384,6 +384,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -392,10 +396,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -405,11 +405,18 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "https://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ + "abstraction", + "apcu", "cache", - "caching" + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ] }, { @@ -566,44 +573,43 @@ }, { "name": "doctrine/dbal", - "version": "v2.9.2", - "version_normalized": "2.9.2.0", + "version": "v2.10.1", + "version_normalized": "2.10.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", + "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", "shasum": "" }, "require": { "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.1" + "php": "^7.2" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "jetbrains/phpstorm-stubs": "^2018.1.2", - "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.4", - "symfony/console": "^2.0.5|^3.0|^4.0", - "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + "doctrine/coding-standard": "^6.0", + "jetbrains/phpstorm-stubs": "^2019.1", + "phpstan/phpstan": "^0.11.3", + "phpunit/phpunit": "^8.4.1", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "time": "2018-12-31T03:27:51+00:00", + "time": "2020-01-04T12:56:21+00:00", "bin": [ "bin/doctrine-dbal" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.9.x-dev", + "dev-master": "2.10.x-dev", "dev-develop": "3.0.x-dev" } }, @@ -618,6 +624,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -626,10 +636,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -640,27 +646,38 @@ "keywords": [ "abstraction", "database", + "db2", "dbal", + "mariadb", + "mssql", "mysql", - "persistence", + "oci8", + "oracle", + "pdo", "pgsql", - "php", - "queryobject" + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" ] }, { "name": "doctrine/event-manager", - "version": "v1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + "reference": "629572819973f13486371cb611386eb17851e85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/629572819973f13486371cb611386eb17851e85c", + "reference": "629572819973f13486371cb611386eb17851e85c", "shasum": "" }, "require": { @@ -670,10 +687,10 @@ "doctrine/common": "<2.9@dev" }, "require-dev": { - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.0" }, - "time": "2018-06-11T11:59:03+00:00", + "time": "2019-11-10T09:48:07+00:00", "type": "library", "extra": { "branch-alias": { @@ -691,6 +708,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -699,10 +720,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -716,12 +733,14 @@ "email": "ocramius@gmail.com" } ], - "description": "Doctrine Event Manager component", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ "event", - "eventdispatcher", - "eventmanager" + "event dispatcher", + "event manager", + "event system", + "events" ] }, { diff --git a/doctrine/cache/README.md b/doctrine/cache/README.md index 9d35e9348..bf9a7fe35 100644 --- a/doctrine/cache/README.md +++ b/doctrine/cache/README.md @@ -7,4 +7,4 @@ [![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) [![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) -Cache component extracted from the Doctrine Common project. [Documentation](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/caching.html) +Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/caching.html) diff --git a/doctrine/cache/docs/en/index.rst b/doctrine/cache/docs/en/index.rst deleted file mode 100644 index f08ab41ef..000000000 --- a/doctrine/cache/docs/en/index.rst +++ /dev/null @@ -1,274 +0,0 @@ -Introduction -============ - -Doctrine Cache is a library that provides an interface for caching data. -It comes with implementations for some of the most popular caching data -stores. Here is what the ``Cache`` interface looks like. - -.. code-block:: php - namespace Doctrine\Common\Cache; - - interface Cache - { - public function fetch($id); - public function contains($id); - public function save($id, $data, $lifeTime = 0); - public function delete($id); - public function getStats(); - } - -Here is an example that uses Memcache. - -.. code-block:: php - use Doctrine\Common\Cache\MemcacheCache; - - $memcache = new Memcache(); - $cache = new MemcacheCache(); - $cache->setMemcache($memcache); - - $cache->set('key', 'value'); - - echo $cache->get('key') // prints "value" - -Drivers -======= - -Doctrine ships with several common drivers that you can easily use. -Below you can find information about all the available drivers. - -ApcCache --------- - -The ``ApcCache`` driver uses the ``apc_fetch``, ``apc_exists``, etc. functions that come -with PHP so no additional setup is required in order to use it. - -.. code-block:: php - $cache = new ApcCache(); - -ApcuCache ---------- - -The ``ApcuCache`` driver uses the ``apcu_fetch``, ``apcu_exists``, etc. functions that come -with PHP so no additional setup is required in order to use it. - -.. code-block:: php - $cache = new ApcuCache(); - -ArrayCache ----------- - -The ``ArrayCache`` driver stores the cache data in PHPs memory and is not persisted anywhere. -This can be useful for caching things in memory for a single process when you don't need -the cache to be persistent across processes. - -.. code-block:: php - $cache = new ArrayCache(); - -ChainCache ----------- - -The ``ChainCache`` driver lets you chain multiple other drivers together easily. - -.. code-block:: php - $arrayCache = new ArrayCache(); - $apcuCache = new ApcuCache(); - - $cache = new ChainCache([$arrayCache, $apcuCache]); - -CouchbaseBucketCache --------------------- - -The ``CouchbaseBucketCache`` driver uses Couchbase to store the cache data. - -.. code-block:: php - $bucketName = 'bucket-name'; - - $authenticator = new Couchbase\PasswordAuthenticator(); - $authenticator->username('username')->password('password'); - - $cluster = new CouchbaseCluster('couchbase://127.0.0.1'); - - $cluster->authenticate($authenticator); - $bucket = $cluster->openBucket($bucketName); - - $cache = new CouchbaseBucketCache($bucket); - -FilesystemCache ---------------- - -The ``FilesystemCache`` driver stores the cache data on the local filesystem. - -.. code-block:: php - $cache = new FilesystemCache('/path/to/cache/directory'); - -MemecacheCache --------------- - -The ``MemcacheCache`` drivers stores the cache data in Memcache. - -.. code-block:: php - $memcache = new Memcache(); - $memcache->connect('localhost', 11211); - - $cache = new MemcacheCache(); - $cache->setMemcache($memcache); - -MemcachedCache --------------- - -The ``MemcachedCache`` drivers stores the cache data in Memcached. - -.. code-block:: php - $memcached = new Memcached(); - - $cache = new MemcachedCache(); - $cache->setMemcached($memcached); - -MongoDBCache ------------- - -The ``MongoDBCache`` drivers stores the cache data in a MongoDB collection. - -.. code-block:: php - $manager = new MongoDB\Driver\Manager("mongodb://localhost:27017"); - - $collection = new MongoDB\Collection($manager, 'database_name', 'collection_name'); - - $cache = new MongoDBCache($collection); - -PhpFileCache ------------- - -The ``PhpFileCache`` driver stores the cache data on the local filesystem like the -``FilesystemCache`` driver except the data is serialized using the ``serialize()`` -and ``unserialize()`` functions available in PHP. The files are included so this means -that the data can be cached in PHPs opcache. - -.. code-block:: php - $cache = new PhpFileCache('/path/to/cache/directory'); - -PredisCache ------------ - -The ``PredisCache`` driver stores the cache data in Redis -and depends on the ``predis/predis`` package which can be installed with composer. - -.. code-block:: bash - $ composer require predis/predis - -Then you can use the ``Predis\Client`` class to pass to the ``PredisCache`` class. - -.. code-block:: php - $client = new Predis\Client(); - - $cache = new PredisCache($client); - -RedisCache ----------- - -The ``RedisCache`` driver stores the cache data in Redis and depends on the -``phpredis`` extension which can be found `here `_. - -.. code-block:: php - $redis = new Redis(); - - $cache = new RedisCache($redis); - -RiakCache ---------- - -The ``RiakCache`` driver stores the cache data in Riak and depends on the -``riak`` extension which can be found `here `_. - -.. code-block:: php - $connection = new Riak\Connection('localhost', 8087); - - $bucket = new Riak\Bucket($connection, 'bucket_name'); - - $cache = new RiakCache($bucket); - -SQLite3Cache ------------- - -The ``SQLite3Cache`` driver stores the cache data in a SQLite database and depends on the -``sqlite3`` extension which can be found `here `_. - -.. code-block:: php - $db = new SQLite3('mydatabase.db'); - - $cache = new SQLite3Cache($db, 'table_name'); - -VoidCache ---------- - -The ``VoidCache`` driver does not store the cache data anywhere. This can -be useful for test environments where you don't want to cache the data -anywhere but need to satisfy the dependency for the ``Doctrine\Common\Cache\Cache`` -interface. - -.. code-block:: php - $cache = new VoidCache(); - -WinCacheCache -------------- - -The ``WinCacheCache`` driver uses the ``wincache_ucache_get``, ``wincache_ucache_exists``, etc. functions that come -with the ``wincache`` extension which can be found `here `_. - -.. code-block:: php - $cache = new WinCacheCache(); - -XcacheCache ------------ - -The ``XcacheCache`` driver uses functions that come with the ``xcache`` -extension which can be found `here `_. - -.. code-block:: php - $cache = new XcacheCache(); - -ZendDataCache -------------- - -The ``ZendDataCache`` driver uses the Zend Data Cache API available in the Zend Platform. - -.. code-block:: php - $cache = new ZendDataCache(); - -Custom Drivers -============== - -If you want to implement your own cache driver, you just need to implement -the ``Doctrine\Common\Cache\Cache`` interface. Here is an example implementation -skeleton. - -.. code-block:: php - use Doctrine\Common\Cache\Cache; - - class MyCacheDriver implements Cache - { - public function fetch($id) - { - // fetch $id from the cache - } - - public function contains($id) - { - // check if $id exists in the cache - } - - public function save($id, $data, $lifeTime = 0) - { - // save $data under $id in the cache for $lifetime - } - - public function delete($id) - { - // delete $id from the cache - } - - public function getStats() - { - // get cache stats - } - } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php index 451865e3b..138d49a53 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php @@ -14,8 +14,9 @@ /** * APC cache provider. * - * @link www.doctrine-project.org * @deprecated since version 1.6, use ApcuCache instead + * + * @link www.doctrine-project.org */ class ApcCache extends CacheProvider { diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php index 3be5454fe..43d414f3c 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php @@ -9,7 +9,6 @@ /** * Base class for cache provider implementations. - * */ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiOperationCache { @@ -206,6 +205,7 @@ private function getNamespaceVersion() : int * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. * * @param array $keys Array of keys to retrieve from cache + * * @return array Array of values retrieved for the given keys. */ protected function doFetchMultiple(array $keys) diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php index 1307fae7d..e9762a2cc 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php @@ -2,6 +2,7 @@ namespace Doctrine\Common\Cache; +use Traversable; use function array_values; use function count; use function iterator_to_array; @@ -19,7 +20,7 @@ class ChainCache extends CacheProvider */ public function __construct($cacheProviders = []) { - $this->cacheProviders = $cacheProviders instanceof \Traversable + $this->cacheProviders = $cacheProviders instanceof Traversable ? iterator_to_array($cacheProviders, false) : array_values($cacheProviders); } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php index 098ca6735..b27720c3a 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php @@ -7,6 +7,7 @@ use Couchbase\Bucket; use Couchbase\Document; use Couchbase\Exception; +use RuntimeException; use function phpversion; use function serialize; use function sprintf; @@ -35,7 +36,7 @@ public function __construct(Bucket $bucket) { if (version_compare(phpversion('couchbase'), self::MINIMUM_VERSION) < 0) { // Manager is required to flush cache and pull stats. - throw new \RuntimeException(sprintf('ext-couchbase:^%s is required.', self::MINIMUM_VERSION)); + throw new RuntimeException(sprintf('ext-couchbase:^%s is required.', self::MINIMUM_VERSION)); } $this->bucket = $bucket; @@ -182,6 +183,7 @@ private function normalizeKey(string $id) : string /** * Expiry treated as a unix timestamp instead of an offset if expiry is greater than 30 days. + * * @src https://developer.couchbase.com/documentation/server/4.1/developer-guide/expiry.html */ private function normalizeExpiry(int $expiry) : int diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php index 4c2b9bd2c..2c62c2ea8 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php @@ -9,9 +9,10 @@ /** * Couchbase cache provider. * - * @link www.doctrine-project.org * @deprecated Couchbase SDK 1.x is now deprecated. Use \Doctrine\Common\Cache\CouchbaseBucketCache instead. * https://developer.couchbase.com/documentation/server/current/sdk/php/compatibility-versions-features.html + * + * @link www.doctrine-project.org */ class CouchbaseCache extends CacheProvider { @@ -62,6 +63,7 @@ protected function doSave($id, $data, $lifeTime = 0) if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->couchbase->set($id, $data, (int) $lifeTime); } @@ -91,6 +93,7 @@ protected function doGetStats() $server = explode(':', $servers[0]); $key = $server[0] . ':11210'; $stats = $stats[$key]; + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php index 95ab5be1a..b06f86232 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php @@ -2,9 +2,9 @@ declare(strict_types=1); - namespace Doctrine\Common\Cache; +use DateTime; use MongoDB\BSON\Binary; use MongoDB\BSON\UTCDateTime; use MongoDB\Collection; @@ -62,6 +62,7 @@ protected function doFetch($id) if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); + return false; } @@ -82,6 +83,7 @@ protected function doContains($id) if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); + return false; } @@ -182,7 +184,7 @@ private function isExpired(BSONDocument $document) : bool { return isset($document[MongoDBCache::EXPIRATION_FIELD]) && $document[MongoDBCache::EXPIRATION_FIELD] instanceof UTCDateTime && - $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new \DateTime(); + $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new DateTime(); } private function createExpirationIndex() : void diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php index 184680c0c..4b485205c 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php @@ -2,6 +2,11 @@ namespace Doctrine\Common\Cache; +use FilesystemIterator; +use InvalidArgumentException; +use Iterator; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; use const DIRECTORY_SEPARATOR; use const PATHINFO_DIRNAME; use function bin2hex; @@ -62,13 +67,13 @@ abstract class FileCache extends CacheProvider * @param string $directory The cache directory. * @param string $extension The cache file extension. * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct($directory, $extension = '', $umask = 0002) { // YES, this needs to be *before* createPathIfNeeded() if (! is_int($umask)) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'The umask parameter is required to be integer, was: %s', gettype($umask) )); @@ -76,14 +81,14 @@ public function __construct($directory, $extension = '', $umask = 0002) $this->umask = $umask; if (! $this->createPathIfNeeded($directory)) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'The directory "%s" does not exist and could not be created.', $directory )); } if (! is_writable($directory)) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'The directory "%s" is not writable.', $directory )); @@ -257,11 +262,11 @@ protected function writeFile(string $filename, string $content) : bool return false; } - private function getIterator() : \Iterator + private function getIterator() : Iterator { - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST + return new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST ); } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php b/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php new file mode 100644 index 000000000..0a7fe6596 --- /dev/null +++ b/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php @@ -0,0 +1,25 @@ +isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); + return false; } @@ -75,6 +76,7 @@ protected function doContains($id) if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); + return false; } @@ -161,7 +163,6 @@ private function isExpired(array $document) : bool $document[MongoDBCache::EXPIRATION_FIELD]->sec < time(); } - private function createExpirationIndex() : void { if ($this->expirationIndexCreated) { diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php index 1597ff7b1..42bbd2cea 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -8,9 +8,9 @@ /** * Memcache cache provider. * - * @link www.doctrine-project.org - * * @deprecated + * + * @link www.doctrine-project.org */ class MemcacheCache extends CacheProvider { @@ -65,6 +65,7 @@ protected function doSave($id, $data, $lifeTime = 0) if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->memcache->set($id, $data, 0, (int) $lifeTime); } @@ -91,6 +92,7 @@ protected function doFlush() protected function doGetStats() { $stats = $this->memcache->getStats(); + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php index 6591b926d..da966ae26 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php @@ -3,6 +3,10 @@ namespace Doctrine\Common\Cache; use Memcached; +use function array_keys; +use function preg_match; +use function strlen; +use function strpos; use function time; /** @@ -12,6 +16,8 @@ */ class MemcachedCache extends CacheProvider { + public const CACHE_ID_MAX_LENGTH = 250; + /** @var Memcached|null */ private $memcached; @@ -56,6 +62,10 @@ protected function doFetchMultiple(array $keys) */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { + foreach (array_keys($keysAndValues) as $id) { + $this->validateCacheId($id); + } + if ($lifetime > 30 * 24 * 3600) { $lifetime = time() + $lifetime; } @@ -78,9 +88,12 @@ protected function doContains($id) */ protected function doSave($id, $data, $lifeTime = 0) { + $this->validateCacheId($id); + if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->memcached->set($id, $data, (int) $lifeTime); } @@ -119,6 +132,7 @@ protected function doGetStats() $servers = $this->memcached->getServerList(); $key = $servers[0]['host'] . ':' . $servers[0]['port']; $stats = $stats[$key]; + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], @@ -127,4 +141,30 @@ protected function doGetStats() Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], ]; } + + /** + * Validate the cache id + * + * @see https://github.com/memcached/memcached/blob/1.5.12/doc/protocol.txt#L41-L49 + * + * @param string $id + * + * @return void + * + * @throws InvalidCacheId + */ + private function validateCacheId($id) + { + if (strlen($id) > self::CACHE_ID_MAX_LENGTH) { + throw InvalidCacheId::exceedsMaxLength($id, self::CACHE_ID_MAX_LENGTH); + } + + if (strpos($id, ' ') !== false) { + throw InvalidCacheId::containsUnauthorizedCharacter($id, ' '); + } + + if (preg_match('/[\t\r\n]/', $id) === 1) { + throw InvalidCacheId::containsControlCharacter($id); + } + } } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php index 05ac4f875..861e4dda3 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php @@ -2,6 +2,7 @@ namespace Doctrine\Common\Cache; +use InvalidArgumentException; use MongoCollection; use MongoDB\Collection; use const E_USER_DEPRECATED; @@ -46,6 +47,7 @@ class MongoDBCache extends CacheProvider * * @see http://www.php.net/manual/en/mongo.readpreferences.php * @see http://www.php.net/manual/en/mongo.writeconcerns.php + * * @param MongoCollection|Collection $collection */ public function __construct($collection) @@ -56,7 +58,7 @@ public function __construct($collection) } elseif ($collection instanceof Collection) { $this->provider = new ExtMongoDBCache($collection); } else { - throw new \InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance'); + throw new InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance'); } } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php index b4faa41f9..d099d47b8 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php @@ -5,8 +5,9 @@ /** * Interface for cache drivers that allows to put many items at once. * - * @link www.doctrine-project.org * @deprecated + * + * @link www.doctrine-project.org */ interface MultiDeleteCache { diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php index 7a8e2fd32..e75d6b1c9 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php @@ -5,8 +5,9 @@ /** * Interface for cache drivers that allows to get many items at once. * - * @link www.doctrine-project.org * @deprecated + * + * @link www.doctrine-project.org */ interface MultiGetCache { @@ -14,6 +15,7 @@ interface MultiGetCache * Returns an associative array of values for keys is found in cache. * * @param string[] $keys Array of keys to retrieve from cache + * * @return mixed[] Array of retrieved values, indexed by the specified keys. * Values that couldn't be retrieved are not contained in this array. */ diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php index 7a865e554..6f059c167 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php @@ -5,8 +5,9 @@ /** * Interface for cache drivers that allows to put many items at once. * - * @link www.doctrine-project.org * @deprecated + * + * @link www.doctrine-project.org */ interface MultiPutCache { diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php index 132b15426..c0619991c 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php @@ -32,7 +32,7 @@ public function __construct($directory, $extension = self::EXTENSION, $umask = 0 { parent::__construct($directory, $extension, $umask); - self::$emptyErrorHandler = function () { + self::$emptyErrorHandler = static function () { }; } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php index 40803de16..6430d52d7 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php @@ -69,7 +69,7 @@ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) } // No lifetime, use MSET - $response = $this->client->mset(array_map(function ($value) { + $response = $this->client->mset(array_map(static function ($value) { return serialize($value); }, $keysAndValues)); diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php index 463886042..324570583 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php @@ -4,6 +4,11 @@ use Redis; use function array_combine; +use function array_diff_key; +use function array_fill_keys; +use function array_filter; +use function array_keys; +use function count; use function defined; use function extension_loaded; use function is_bool; @@ -55,17 +60,21 @@ protected function doFetchMultiple(array $keys) $fetchedItems = array_combine($keys, $this->redis->mget($keys)); // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data. - $foundItems = []; - - foreach ($fetchedItems as $key => $value) { - if ($value === false && ! $this->redis->exists($key)) { - continue; + $keysToFilter = array_keys(array_filter($fetchedItems, static function ($item) : bool { + return $item === false; + })); + + if ($keysToFilter) { + $multi = $this->redis->multi(Redis::PIPELINE); + foreach ($keysToFilter as $key) { + $multi->exists($key); } - - $foundItems[$key] = $value; + $existItems = array_filter($multi->exec()); + $missedItemKeys = array_diff_key($keysToFilter, $existItems); + $fetchedItems = array_diff_key($fetchedItems, array_fill_keys($missedItemKeys, true)); } - return $foundItems; + return $fetchedItems; } /** @@ -74,18 +83,14 @@ protected function doFetchMultiple(array $keys) protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { if ($lifetime) { - $success = true; - // Keys have lifetime, use SETEX for each of them + $multi = $this->redis->multi(Redis::PIPELINE); foreach ($keysAndValues as $key => $value) { - if ($this->redis->setex($key, $lifetime, $value)) { - continue; - } - - $success = false; + $multi->setex($key, $lifetime, $value); } + $succeeded = array_filter($multi->exec()); - return $success; + return count($succeeded) == count($keysAndValues); } // No lifetime, use MSET @@ -123,7 +128,7 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return $this->redis->delete($id) >= 0; + return $this->redis->del($id) >= 0; } /** @@ -131,7 +136,7 @@ protected function doDelete($id) */ protected function doDeleteMultiple(array $keys) { - return $this->redis->delete($keys) >= 0; + return $this->redis->del($keys) >= 0; } /** @@ -148,6 +153,7 @@ protected function doFlush() protected function doGetStats() { $info = $this->redis->info(); + return [ Cache::STATS_HITS => $info['keyspace_hits'], Cache::STATS_MISSES => $info['keyspace_misses'], diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php deleted file mode 100644 index 0ae220688..000000000 --- a/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php +++ /dev/null @@ -1,228 +0,0 @@ -bucket = $bucket; - } - - /** - * {@inheritdoc} - */ - protected function doFetch($id) - { - try { - $response = $this->bucket->get($id); - - // No objects found - if (! $response->hasObject()) { - return false; - } - - // Check for attempted siblings - $object = ($response->hasSiblings()) - ? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList()) - : $response->getFirstObject(); - - // Check for expired object - if ($this->isExpired($object)) { - $this->bucket->delete($object); - - return false; - } - - return unserialize($object->getContent()); - } catch (Exception\RiakException $e) { - // Covers: - // - Riak\ConnectionException - // - Riak\CommunicationException - // - Riak\UnexpectedResponseException - // - Riak\NotFoundException - } - - return false; - } - - /** - * {@inheritdoc} - */ - protected function doContains($id) - { - try { - // We only need the HEAD, not the entire object - $input = new Input\GetInput(); - - $input->setReturnHead(true); - - $response = $this->bucket->get($id, $input); - - // No objects found - if (! $response->hasObject()) { - return false; - } - - $object = $response->getFirstObject(); - - // Check for expired object - if ($this->isExpired($object)) { - $this->bucket->delete($object); - - return false; - } - - return true; - } catch (Exception\RiakException $e) { - // Do nothing - } - - return false; - } - - /** - * {@inheritdoc} - */ - protected function doSave($id, $data, $lifeTime = 0) - { - try { - $object = new Object($id); - - $object->setContent(serialize($data)); - - if ($lifeTime > 0) { - $object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime)); - } - - $this->bucket->put($object); - - return true; - } catch (Exception\RiakException $e) { - // Do nothing - } - - return false; - } - - /** - * {@inheritdoc} - */ - protected function doDelete($id) - { - try { - $this->bucket->delete($id); - - return true; - } catch (Exception\BadArgumentsException $e) { - // Key did not exist on cluster already - } catch (Exception\RiakException $e) { - // Covers: - // - Riak\Exception\ConnectionException - // - Riak\Exception\CommunicationException - // - Riak\Exception\UnexpectedResponseException - } - - return false; - } - - /** - * {@inheritdoc} - */ - protected function doFlush() - { - try { - $keyList = $this->bucket->getKeyList(); - - foreach ($keyList as $key) { - $this->bucket->delete($key); - } - - return true; - } catch (Exception\RiakException $e) { - // Do nothing - } - - return false; - } - - /** - * {@inheritdoc} - */ - protected function doGetStats() - { - // Only exposed through HTTP stats API, not Protocol Buffers API - return null; - } - - /** - * Check if a given Riak Object have expired. - */ - private function isExpired(Object $object) : bool - { - $metadataMap = $object->getMetadataMap(); - - return isset($metadataMap[self::EXPIRES_HEADER]) - && $metadataMap[self::EXPIRES_HEADER] < time(); - } - - /** - * On-read conflict resolution. Applied approach here is last write wins. - * Specific needs may override this method to apply alternate conflict resolutions. - * - * {@internal Riak does not attempt to resolve a write conflict, and store - * it as sibling of conflicted one. By following this approach, it is up to - * the next read to resolve the conflict. When this happens, your fetched - * object will have a list of siblings (read as a list of objects). - * In our specific case, we do not care about the intermediate ones since - * they are all the same read from storage, and we do apply a last sibling - * (last write) wins logic. - * If by any means our resolution generates another conflict, it'll up to - * next read to properly solve it.} - * - * @param string $id - * @param string $vClock - * @param array $objectList - * - * @return Object - */ - protected function resolveConflict($id, $vClock, array $objectList) - { - // Our approach here is last-write wins - $winner = $objectList[count($objectList) - 1]; - - $putInput = new Input\PutInput(); - $putInput->setVClock($vClock); - - $mergedObject = new Object($id); - $mergedObject->setContent($winner->getContent()); - - $this->bucket->put($mergedObject, $putInput); - - return $mergedObject; - } -} diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php b/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php index 8b3111f4a..56deb0774 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php @@ -113,7 +113,7 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - list($idField) = $this->getFields(); + [$idField] = $this->getFields(); $statement = $this->sqlite->prepare(sprintf( 'DELETE FROM %s WHERE %s = :id', @@ -151,7 +151,7 @@ protected function doGetStats() */ private function findById($id, bool $includeData = true) : ?array { - list($idField) = $fields = $this->getFields(); + [$idField] = $fields = $this->getFields(); if (! $includeData) { $key = array_search(static::DATA_FIELD, $fields); diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Version.php b/doctrine/cache/lib/Doctrine/Common/Cache/Version.php index dbf55f42b..834b5b7d4 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/Version.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/Version.php @@ -4,5 +4,5 @@ class Version { - public const VERSION = '1.8.0'; + public const VERSION = '1.9.0-DEV'; } diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php index 2d5c10abe..9b3a485ed 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php @@ -2,6 +2,7 @@ namespace Doctrine\Common\Cache; +use BadMethodCallException; use const XC_TYPE_VAR; use function ini_get; use function serialize; @@ -16,9 +17,9 @@ /** * Xcache cache driver. * - * @link www.doctrine-project.org - * * @deprecated + * + * @link www.doctrine-project.org */ class XcacheCache extends CacheProvider { @@ -71,12 +72,12 @@ protected function doFlush() * * @return void * - * @throws \BadMethodCallException When xcache.admin.enable_auth is On. + * @throws BadMethodCallException When xcache.admin.enable_auth is On. */ protected function checkAuthorization() { if (ini_get('xcache.admin.enable_auth')) { - throw new \BadMethodCallException( + throw new BadMethodCallException( 'To use all features of \Doctrine\Common\Cache\XcacheCache, ' . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.' ); @@ -91,6 +92,7 @@ protected function doGetStats() $this->checkAuthorization(); $info = xcache_info(XC_TYPE_VAR, 0); + return [ Cache::STATS_HITS => $info['hits'], Cache::STATS_MISSES => $info['misses'], diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php index 275f3c497..a6b67ef8b 100644 --- a/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php +++ b/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php @@ -55,6 +55,7 @@ protected function doFlush() if (empty($namespace)) { return zend_shm_cache_clear(); } + return zend_shm_cache_clear($namespace); } diff --git a/doctrine/dbal/.appveyor.yml b/doctrine/dbal/.appveyor.yml index 636c269d8..352719e26 100644 --- a/doctrine/dbal/.appveyor.yml +++ b/doctrine/dbal/.appveyor.yml @@ -22,21 +22,21 @@ environment: driver: sqlsrv db_version: sql2008r2sp2 coverage: yes - php: 7.2 + php: 7.3 - db: mssql driver: sqlsrv db_version: sql2012sp1 - php: 7.2 + php: 7.3 coverage: yes - db: mssql driver: sqlsrv db_version: sql2017 coverage: no - php: 7.2 + php: 7.3 - db: mssql driver: pdo_sqlsrv db_version: sql2017 - php: 7.2 + php: 7.3 coverage: yes init: @@ -49,7 +49,7 @@ install: - ps: | # Check if installation is cached if (!(Test-Path c:\tools\php)) { - appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') + appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version 7.3.12 # install sqlite appveyor-retry cinst -y sqlite Get-ChildItem -Path c:\tools\php @@ -79,7 +79,7 @@ install: $destination = "c:\tools\php\ext\php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc15-x64.zip" Invoke-WebRequest $source -OutFile $destination 7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc15-x64.zip > $null - $DLLVersion = "2.6.0" + $DLLVersion = (Invoke-WebRequest "https://pecl.php.net/rest/r/xdebug/stable.txt").Content $source = "https://xdebug.org/files/php_xdebug-$($DLLVersion)-$($env:php)-vc15-nts-x86_64.dll" $destination = "c:\tools\php\ext\php_xdebug.dll" Invoke-WebRequest $source -OutFile $destination @@ -118,7 +118,6 @@ install: } # install composer dependencies - cd C:\projects\dbal - - rm composer.lock - appveyor-retry composer self-update - appveyor-retry composer install --no-progress --prefer-dist @@ -131,17 +130,25 @@ before_test: } test_script: - - cd C:\projects\dbal - ps: >- if ($env:db_version) { $env:phpunit_config = "tests\appveyor\$($env:db).$($env:db_version).$($env:driver).appveyor.xml" } else { $env:phpunit_config = "tests\appveyor\$($env:db).$($env:driver).appveyor.xml" } - - ps: >- + if ($env:coverage -eq "yes") { vendor\bin\phpunit -c $($env:phpunit_config) --coverage-clover clover.xml - appveyor-retry ocular code-coverage:upload --format=php-clover clover.xml } else { vendor\bin\phpunit -c $($env:phpunit_config) } + + if ($LastExitCode -ne 0) { + $host.SetShouldExit($LastExitCode) + } + +after_test: + - ps: >- + if ($env:coverage -eq "yes") { + appveyor-retry ocular code-coverage:upload --format=php-clover clover.xml + } diff --git a/doctrine/dbal/.doctrine-project.json b/doctrine/dbal/.doctrine-project.json new file mode 100644 index 000000000..7b97cb451 --- /dev/null +++ b/doctrine/dbal/.doctrine-project.json @@ -0,0 +1,55 @@ +{ + "active": true, + "name": "Database Abstraction Layer", + "shortName": "DBAL", + "slug": "dbal", + "docsSlug": "doctrine-dbal", + "versions": [ + { + "name": "3.0", + "branchName": "develop", + "slug": "latest", + "upcoming": true + }, + { + "name": "2.10", + "branchName": "master", + "slug": "2.10", + "upcoming": true + }, + { + "name": "2.9", + "branchName": "2.9", + "slug": "2.9", + "current": true, + "aliases": [ + "current", + "stable" + ] + }, + { + "name": "2.8", + "branchName": "2.8", + "slug": "2.8", + "maintained": false + }, + { + "name": "2.7", + "branchName": "2.7", + "slug": "2.7", + "maintained": false + }, + { + "name": "2.6", + "branchName": "2.6", + "slug": "2.6", + "maintained": false + }, + { + "name": "2.5", + "branchName": "2.5", + "slug": "2.5", + "maintained": false + } + ] +} diff --git a/doctrine/dbal/.github/FUNDING.yml b/doctrine/dbal/.github/FUNDING.yml new file mode 100644 index 000000000..84fcd6afa --- /dev/null +++ b/doctrine/dbal/.github/FUNDING.yml @@ -0,0 +1,3 @@ +patreon: phpdoctrine +tidelift: packagist/doctrine%2Fdbal +custom: https://www.doctrine-project.org/sponsorship.html diff --git a/doctrine/dbal/.github/ISSUE_TEMPLATE/BC_Break.md b/doctrine/dbal/.github/ISSUE_TEMPLATE/BC_Break.md new file mode 100644 index 000000000..c372e7fef --- /dev/null +++ b/doctrine/dbal/.github/ISSUE_TEMPLATE/BC_Break.md @@ -0,0 +1,37 @@ +--- +name: 💥 BC Break +about: Have you encountered an issue during an upgrade? 💣 +--- + + + +### BC Break Report + + + +| Q | A +|------------ | ------ +| BC Break | yes +| Version | x.y.z + +#### Summary + + + +#### Previous behaviour + + + +#### Current behavior + + + +#### How to reproduce + + diff --git a/doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md b/doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md new file mode 100644 index 000000000..2e7d29ca0 --- /dev/null +++ b/doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md @@ -0,0 +1,34 @@ +--- +name: 🐞 Bug Report +about: Something is broken? 🔨 +--- + +### Bug Report + + + +| Q | A +|------------ | ------ +| BC Break | yes/no +| Version | x.y.z + +#### Summary + + + +#### Current behaviour + + + +#### How to reproduce + + + +#### Expected behaviour + + + diff --git a/doctrine/dbal/.github/ISSUE_TEMPLATE/Feature_Request.md b/doctrine/dbal/.github/ISSUE_TEMPLATE/Feature_Request.md new file mode 100644 index 000000000..2620581d6 --- /dev/null +++ b/doctrine/dbal/.github/ISSUE_TEMPLATE/Feature_Request.md @@ -0,0 +1,18 @@ +--- +name: 🎉 Feature Request +about: You have a neat idea that should be implemented? 🎩 +--- + +### Feature Request + + + +| Q | A +|------------ | ------ +| New Feature | yes +| RFC | yes/no +| BC Break | yes/no + +#### Summary + + diff --git a/doctrine/dbal/.github/ISSUE_TEMPLATE/Support_Question.md b/doctrine/dbal/.github/ISSUE_TEMPLATE/Support_Question.md new file mode 100644 index 000000000..d5bccbd15 --- /dev/null +++ b/doctrine/dbal/.github/ISSUE_TEMPLATE/Support_Question.md @@ -0,0 +1,20 @@ +--- +name: ❓ Support Question +about: Have a problem that you can't figure out? 🤔 +--- + + + +| Q | A +|------------ | ----- +| Version | x.y.z + + + +### Support Question + + diff --git a/doctrine/dbal/.github/PULL_REQUEST_TEMPLATE.md b/doctrine/dbal/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..d88b155d0 --- /dev/null +++ b/doctrine/dbal/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ + + +| Q | A +|------------- | ----------- +| Type | bug/feature/improvement +| BC Break | yes/no +| Fixed issues | + +#### Summary + + diff --git a/doctrine/dbal/.scrutinizer.yml b/doctrine/dbal/.scrutinizer.yml index 68b7f3443..a3b8a5621 100644 --- a/doctrine/dbal/.scrutinizer.yml +++ b/doctrine/dbal/.scrutinizer.yml @@ -3,7 +3,7 @@ build: analysis: environment: php: - version: 7.1 + version: 7.2 cache: disabled: false directories: diff --git a/doctrine/dbal/README.md b/doctrine/dbal/README.md index 8a5767338..7495d20d7 100644 --- a/doctrine/dbal/README.md +++ b/doctrine/dbal/README.md @@ -1,12 +1,12 @@ # Doctrine DBAL -| [Master][Master] | [2.8][2.8] | [Develop][develop] | +| [Master][Master] | [2.9][2.9] | [Develop][develop] | |:----------------:|:----------:|:------------------:| -| [![Build status][Master image]][Master] | [![Build status][2.8 image]][2.8] | [![Build status][develop image]][develop] | -| [![Build Status][ContinuousPHP image]][ContinuousPHP] | [![Build Status][ContinuousPHP 2.8 image]][ContinuousPHP] | [![Build Status][ContinuousPHP develop image]][ContinuousPHP] | -| [![Code Coverage][Coverage image]][Scrutinizer Master] | [![Code Coverage][Coverage 2.8 image]][Scrutinizer 2.8] | [![Code Coverage][Coverage develop image]][Scrutinizer develop] | -| [![Code Quality][Quality image]][Scrutinizer Master] | [![Code Quality][Quality 2.8 image]][Scrutinizer 2.8] | [![Code Quality][Quality develop image]][Scrutinizer develop] | -| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.8 image]][AppVeyor 2.8] | [![AppVeyor][AppVeyor develop image]][AppVeyor develop] | +| [![Build status][Master image]][Master] | [![Build status][2.9 image]][2.9] | [![Build status][develop image]][develop] | +| [![Build Status][ContinuousPHP image]][ContinuousPHP] | [![Build Status][ContinuousPHP 2.9 image]][ContinuousPHP] | [![Build Status][ContinuousPHP develop image]][ContinuousPHP] | +| [![Code Coverage][Coverage image]][Scrutinizer Master] | [![Code Coverage][Coverage 2.9 image]][Scrutinizer 2.9] | [![Code Coverage][Coverage develop image]][Scrutinizer develop] | +| [![Code Quality][Quality image]][Scrutinizer Master] | [![Code Quality][Quality 2.9 image]][Scrutinizer 2.9] | [![Code Quality][Quality develop image]][Scrutinizer develop] | +| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.9 image]][AppVeyor 2.9] | [![AppVeyor][AppVeyor develop image]][AppVeyor develop] | Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction. @@ -16,7 +16,6 @@ Powerful database abstraction layer with many features for database schema intro * [Documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/) * [Issue Tracker](https://github.com/doctrine/dbal/issues) - [Master image]: https://img.shields.io/travis/doctrine/dbal/master.svg?style=flat-square [Coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/master.svg?style=flat-square [Quality image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/master.svg?style=flat-square @@ -26,14 +25,16 @@ Powerful database abstraction layer with many features for database schema intro [AppVeyor master]: https://ci.appveyor.com/project/doctrine/dbal/branch/master [AppVeyor master image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/master?svg=true [ContinuousPHP]: https://continuousphp.com/git-hub/doctrine/dbal - [2.8 image]: https://img.shields.io/travis/doctrine/dbal/2.8.svg?style=flat-square - [Coverage 2.8 image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/2.8.svg?style=flat-square - [Quality 2.8 image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/2.8.svg?style=flat-square - [ContinuousPHP 2.8 image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/2.8.svg?style=flat-square - [2.8]: https://github.com/doctrine/dbal/tree/2.8 - [Scrutinizer 2.8]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=2.8 - [AppVeyor 2.8]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.8 - [AppVeyor 2.8 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.8?svg=true + + [2.9 image]: https://img.shields.io/travis/doctrine/dbal/2.9.svg?style=flat-square + [Coverage 2.9 image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/2.9.svg?style=flat-square + [Quality 2.9 image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/2.9.svg?style=flat-square + [ContinuousPHP 2.9 image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/2.9.svg?style=flat-square + [2.9]: https://github.com/doctrine/dbal/tree/2.9 + [Scrutinizer 2.9]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=2.9 + [AppVeyor 2.9]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.9 + [AppVeyor 2.9 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.9?svg=true + [develop]: https://github.com/doctrine/dbal/tree/develop [develop image]: https://img.shields.io/travis/doctrine/dbal/develop.svg?style=flat-square [Coverage develop image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/develop.svg?style=flat-square diff --git a/doctrine/dbal/UPGRADE.md b/doctrine/dbal/UPGRADE.md index 53bf9420d..205bf9919 100644 --- a/doctrine/dbal/UPGRADE.md +++ b/doctrine/dbal/UPGRADE.md @@ -1,3 +1,96 @@ +# Upgrade to 2.10 + +## Deprecated `Doctrine\DBAL\Event\ConnectionEventArgs` methods + +The usage of the `getDriver()`, `getDatabasePlatform()` and `getSchemaManager()` methods of the `ConnectionEventArgs` class has been deprecated. Obtain the underlying connection via `getConnection()` and call the corresponding methods on the connection instance. + +## Deprecated `Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs` methods + +The usage of the `getDatabasePlatform()` method of the `SchemaColumnDefinitionEventArgs` class has been deprecated. Obtain the underlying connection via `getConnection()` and call the corresponding method on the connection instance. + +## Deprecated `Doctrine\DBAL\Connection` methods + +The usage of the `getHost()`, `getPort()`, `getUsername()` and `getPassword()` methods of the `Connection` class has been deprecated as they leak implementation details. + +## Deprecated array of statements in `addSql()` of `SchemaEventArgs`-based classes. + +Passing multiple SQL statements as an array to `SchemaAlterTableAddColumnEventArgs::addSql()` and the same method in other `SchemaEventArgs`-based classes is deprecated. Pass each statement as an individual argument instead. + +## Deprecated calling `AbstractSchemaManager::tablesExist()` with a string argument. + +Instead of passing a string, pass a one-element array. + +## Deprecated calling `OracleSchemaManager::createDatabase()` without an argument or by passing NULL. + +In order to create a database, always pass the database name. + +## Deprecated unused schema manager methods. + +The following methods have been deprecated as unused: + +- `AbstractSchemaManager::_getPortableFunctionsList()`, +- `AbstractSchemaManager::_getPortableFunctionDefinition()`, +- `OracleSchemaManager::_getPortableFunctionDefinition()`, +- `SqliteSchemaManager::_getPortableTableIndexDefinition()`. + +# Deprecations in `Doctrine\DBAL\Driver` + +- The usage of NULL to indicate empty `$username` or `$password` when calling `connect()` is deprecated. Use an empty string instead. + +## Deprecated `Doctrine\DBAL\Platforms::_getAlterTableIndexForeignKeySQL()` + +Method `Doctrine\DBAL\Platforms::_getAlterTableIndexForeignKeySQL()` has been deprecated as no longer used. + +## Deprecated `Doctrine\DBAL\Driver\OCI8\OCI8Statement::$_PARAM` + +Property `Doctrine\DBAL\Driver\OCI8\OCI8Statement::$_PARAM` has been deprecated as not used. + +## Deprecated `Doctrine\DBAL\Driver::getName()` + +Relying on the name of the driver is discouraged. For referencing the driver, use its class name. + +## Deprecated usage of user-provided `PDO` instance + +The usage of user-provided `PDO` instance is deprecated. The known use cases are: + +1. **Persistent PDO connections.** DBAL 3.0 will supported establishing persistent connections, therefore, providing a pre-created persistent PDO connection will be no longer needed. +2. **Sharing `PDO` instance between DBAL and legacy components.** In order to share a PDO instance, initialize the connection in DBAL and access it using `Connection::getWrappedConnection()->getWrappedConnection()`. + +## MINOR BC BREAK: Default values are no longer handled as SQL expressions + +They are converted to SQL literals (e.g. escaped). Clients must now specify default values in their initial form, not in the form of an SQL literal (e.g. escaped). + +Before: + + $column->setDefault('Foo\\\\Bar\\\\Baz'); + +After: + + $column->setDefault('Foo\\Bar\\Baz'); + +## Deprecated `Type::*` constants + +The constants for built-in types have been moved from `Doctrine\DBAL\Types\Type` to a separate class `Doctrine\DBAL\Types\Types`. + +Some of the constants were renamed in the process: +* `TARRAY`-> `ARRAY` +* `DATE` -> `DATE_MUTABLE` +* `DATETIME` -> `DATETIME_MUTABLE` +* `DATETIMETZ` -> `DATETIMETZ_MUTABLE` +* `TIME` -> `TIME_MUTABLE` + +## Deprecated `SQLSrvStatement::LAST_INSERT_ID_SQL` constant + +The `Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement::LAST_INSERT_ID_SQL` constant has been deprecated and will be made private in 3.0. + +## Deprecated `SQLParserUtils` constants + +The constants in `Doctrine\DBAL\SQLParserUtils` have been deprecated and will be made private in 3.0. + +## Deprecated `LoggerChain::addLogger` method + +The `Doctrine\DBAL\Logging\LoggerChain::addLogger` method has been deprecated. Inject list of loggers via constructor instead. + # Upgrade to 2.9 ## Deprecated `Statement::fetchColumn()` with an invalid index @@ -67,7 +160,7 @@ This method now throws SPL ``UnexpectedValueException`` instead of accidentally ## Doctrine\DBAL\Connection::TRANSACTION_* constants deprecated -``Doctrine\DBAL\Connection::TRANSACTION_*`` were moved into ``Doctrine\DBAL\TransactionIsolationLevel`` class without the ``TRANSACTION_`` prefix. +``Doctrine\DBAL\Connection::TRANSACTION_*`` were moved into ``Doctrine\DBAL\TransactionIsolationLevel`` class without the ``TRANSACTION_`` prefix. ## DEPRECATION: direct usage of the PDO APIs in the DBAL API diff --git a/doctrine/dbal/composer.json b/doctrine/dbal/composer.json index 9d5f610c2..4a426e488 100644 --- a/doctrine/dbal/composer.json +++ b/doctrine/dbal/composer.json @@ -3,14 +3,25 @@ "type": "library", "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", "keywords": [ - "php", + "abstraction", + "database", + "dbal", + "db2", + "mariadb", + "mssql", "mysql", "pgsql", - "dbal", - "database", - "abstraction", - "persistence", - "queryobject" + "postgresql", + "oci8", + "oracle", + "pdo", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" ], "homepage": "https://www.doctrine-project.org/projects/dbal.html", "license": "MIT", @@ -21,18 +32,17 @@ {"name": "Jonathan Wage", "email": "jonwage@gmail.com"} ], "require": { - "php": "^7.1", + "php": "^7.2", "ext-pdo": "*", "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "jetbrains/phpstorm-stubs": "^2018.1.2", - "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.4", - "symfony/console": "^2.0.5|^3.0|^4.0", - "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + "doctrine/coding-standard": "^6.0", + "jetbrains/phpstorm-stubs": "^2019.1", + "phpstan/phpstan": "^0.11.3", + "phpunit/phpunit": "^8.4.1", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -49,7 +59,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.9.x-dev", + "dev-master": "2.10.x-dev", "dev-develop": "3.0.x-dev" } } diff --git a/doctrine/dbal/composer.lock b/doctrine/dbal/composer.lock index 0c1562796..aa0428c20 100644 --- a/doctrine/dbal/composer.lock +++ b/doctrine/dbal/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1147a9427c03f98ca063806250633645", + "content-hash": "120172ae44052999ec9a50b1121414cc", "packages": [ { "name": "doctrine/cache", @@ -158,16 +158,16 @@ "packages-dev": [ { "name": "composer/xdebug-handler", - "version": "1.1.0", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08" + "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08", - "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/46867cbf8ca9fb8d60c506895449eb799db1184f", + "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f", "shasum": "" }, "require": { @@ -198,33 +198,31 @@ "Xdebug", "performance" ], - "time": "2018-04-11T15:42:36+00:00" + "time": "2019-05-27T17:52:04+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.4.4", + "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08" + "reference": "e749410375ff6fb7a040a68878c656c2e610b132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/2e41850d5f7797cbb1af7b030d245b3b24e63a08", - "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132", "shasum": "" }, "require": { "composer-plugin-api": "^1.0", "php": "^5.3|^7", - "squizlabs/php_codesniffer": "*" + "squizlabs/php_codesniffer": "^2|^3" }, "require-dev": { "composer/composer": "*", - "wimg/php-compatibility": "^8.0" - }, - "suggest": { - "dealerdirect/qa-tools": "All the PHP QA tools you'll need" + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" }, "type": "composer-plugin", "extra": { @@ -242,13 +240,13 @@ "authors": [ { "name": "Franck Nijhof", - "email": "f.nijhof@dealerdirect.nl", - "homepage": "http://workingatdealerdirect.eu", - "role": "Developer" + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://workingatdealerdirect.eu", + "homepage": "http://www.dealerdirect.com", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", @@ -266,32 +264,32 @@ "stylecheck", "tests" ], - "time": "2017-12-06T16:27:17+00:00" + "time": "2018-10-26T13:21:45+00:00" }, { "name": "doctrine/coding-standard", - "version": "5.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/coding-standard.git", - "reference": "bb8de042a25c4fb59a2c55c350dc55cc00227a8c" + "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/bb8de042a25c4fb59a2c55c350dc55cc00227a8c", - "reference": "bb8de042a25c4fb59a2c55c350dc55cc00227a8c", + "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/d33f69eb98b25aa51ffe3a909f0ec77000af4701", + "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", "php": "^7.1", - "slevomat/coding-standard": "^4.8.0", - "squizlabs/php_codesniffer": "^3.3.2" + "slevomat/coding-standard": "^5.0", + "squizlabs/php_codesniffer": "^3.4.0" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "5.0.x-dev" + "dev-master": "6.0.x-dev" } }, "autoload": { @@ -327,31 +325,33 @@ "standard", "style" ], - "time": "2018-09-24T19:08:56+00:00" + "time": "2019-03-15T12:45:47+00:00" }, { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { @@ -376,12 +376,12 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2019-03-17T17:37:11+00:00" }, { "name": "jean85/pretty-package-versions", @@ -436,20 +436,21 @@ }, { "name": "jetbrains/phpstorm-stubs", - "version": "v2018.1.2", + "version": "v2019.1", "source": { "type": "git", "url": "https://github.com/JetBrains/phpstorm-stubs.git", - "reference": "d5fd088949a717b477a08ed8e24e7e64a814ae10" + "reference": "9e309771f362e979ecfb429303ad7a402c657234" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/d5fd088949a717b477a08ed8e24e7e64a814ae10", - "reference": "d5fd088949a717b477a08ed8e24e7e64a814ae10", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/9e309771f362e979ecfb429303ad7a402c657234", + "reference": "9e309771f362e979ecfb429303ad7a402c657234", "shasum": "" }, "require-dev": { "nikic/php-parser": "v4.0.1", + "php": "^7.1", "phpdocumentor/reflection-docblock": "^4.3", "phpunit/phpunit": "7.1.4" }, @@ -470,20 +471,20 @@ "stubs", "type" ], - "time": "2018-04-25T12:26:46+00:00" + "time": "2019-03-25T16:59:23+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.8.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { @@ -518,43 +519,40 @@ "object", "object graph" ], - "time": "2018-06-11T23:09:50+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "nette/bootstrap", - "version": "v2.4.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/nette/bootstrap.git", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/e1075af05c211915e03e0c86542f3ba5433df4a3", + "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3", "shasum": "" }, "require": { - "nette/di": "~2.4.7", - "nette/utils": "~2.4", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" + "nette/di": "^3.0", + "nette/utils": "^3.0", + "php": ">=7.1" }, "require-dev": { - "latte/latte": "~2.2", - "nette/application": "~2.3", - "nette/caching": "~2.3", - "nette/database": "~2.3", - "nette/forms": "~2.3", - "nette/http": "~2.4.0", - "nette/mail": "~2.3", - "nette/robot-loader": "^2.4.2 || ^3.0", - "nette/safe-stream": "~2.2", - "nette/security": "~2.3", - "nette/tester": "~2.0", - "tracy/tracy": "^2.4.1" + "latte/latte": "^2.2", + "nette/application": "^3.0", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0", + "nette/robot-loader": "^3.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.0", + "tracy/tracy": "^2.6" }, "suggest": { "nette/robot-loader": "to use Configurator::createRobotLoader()", @@ -563,7 +561,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -594,46 +592,50 @@ "configurator", "nette" ], - "time": "2018-05-17T12:52:20+00:00" + "time": "2019-03-26T12:59:07+00:00" }, { "name": "nette/di", - "version": "v2.4.13", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/nette/di.git", - "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca" + "reference": "4aff517a1c6bb5c36fa09733d4cea089f529de6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", - "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "url": "https://api.github.com/repos/nette/di/zipball/4aff517a1c6bb5c36fa09733d4cea089f529de6d", + "reference": "4aff517a1c6bb5c36fa09733d4cea089f529de6d", "shasum": "" }, "require": { "ext-tokenizer": "*", - "nette/neon": "^2.3.3 || ~3.0.0", - "nette/php-generator": "^2.6.1 || ~3.0.0", - "nette/utils": "^2.4.3 || ~3.0.0", - "php": ">=5.6.0" + "nette/neon": "^3.0", + "nette/php-generator": "^3.2.2", + "nette/robot-loader": "^3.2", + "nette/schema": "^1.0", + "nette/utils": "^3.0", + "php": ">=7.1" }, "conflict": { - "nette/bootstrap": "<2.4", - "nette/nette": "<2.2" + "nette/bootstrap": "<3.0" }, "require-dev": { - "nette/tester": "^2.0", + "nette/tester": "^2.2", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" + ], + "files": [ + "src/compatibility.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -663,37 +665,37 @@ "nette", "static" ], - "time": "2018-06-11T08:46:01+00:00" + "time": "2019-08-07T12:11:33+00:00" }, { "name": "nette/finder", - "version": "v2.4.2", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/nette/finder.git", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" + "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", + "url": "https://api.github.com/repos/nette/finder/zipball/6be1b83ea68ac558aff189d640abe242e0306fe2", + "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2", "shasum": "" }, "require": { - "nette/utils": "~2.4", - "php": ">=5.6.0" + "nette/utils": "^2.4 || ~3.0.0", + "php": ">=7.1" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { - "nette/tester": "~2.0", + "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "2.5-dev" } }, "autoload": { @@ -725,35 +727,35 @@ "iterator", "nette" ], - "time": "2018-06-28T11:49:23+00:00" + "time": "2019-02-28T18:13:25+00:00" }, { "name": "nette/neon", - "version": "v2.4.3", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/nette/neon.git", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398" + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb", "shasum": "" }, "require": { "ext-iconv": "*", "ext-json": "*", - "php": ">=5.6.0" + "php": ">=7.0" }, "require-dev": { - "nette/tester": "~2.0", + "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -786,28 +788,25 @@ "nette", "yaml" ], - "time": "2018-03-21T12:12:21+00:00" + "time": "2019-02-05T21:30:40+00:00" }, { "name": "nette/php-generator", - "version": "v3.0.4", + "version": "v3.2.3", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "b381ecacbf5a0b5f99cc0b303d5b0578d409f446" + "reference": "aea6e81437bb238e5f0e5b5ce06337433908e63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/b381ecacbf5a0b5f99cc0b303d5b0578d409f446", - "reference": "b381ecacbf5a0b5f99cc0b303d5b0578d409f446", + "url": "https://api.github.com/repos/nette/php-generator/zipball/aea6e81437bb238e5f0e5b5ce06337433908e63b", + "reference": "aea6e81437bb238e5f0e5b5ce06337433908e63b", "shasum": "" }, "require": { "nette/utils": "^2.4.2 || ~3.0.0", - "php": ">=7.0" - }, - "conflict": { - "nette/nette": "<2.2" + "php": ">=7.1" }, "require-dev": { "nette/tester": "^2.0", @@ -816,7 +815,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -840,7 +839,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.", "homepage": "https://nette.org", "keywords": [ "code", @@ -848,30 +847,27 @@ "php", "scaffolding" ], - "time": "2018-04-26T16:48:20+00:00" + "time": "2019-07-05T13:01:56+00:00" }, { "name": "nette/robot-loader", - "version": "v3.0.4", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", - "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392" + "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/3cf88781a05e0bf4618ae605361afcbaa4d5b392", - "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/0712a0e39ae7956d6a94c0ab6ad41aa842544b5c", + "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c", "shasum": "" }, "require": { "ext-tokenizer": "*", - "nette/finder": "^2.3 || ^3.0", - "nette/utils": "^2.4 || ^3.0", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" + "nette/finder": "^2.5", + "nette/utils": "^3.0", + "php": ">=7.1" }, "require-dev": { "nette/tester": "^2.0", @@ -880,7 +876,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -904,7 +900,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "description": "? Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", "homepage": "https://nette.org", "keywords": [ "autoload", @@ -913,27 +909,81 @@ "nette", "trait" ], - "time": "2018-06-22T09:34:04+00:00" + "time": "2019-03-08T21:57:24+00:00" + }, + { + "name": "nette/schema", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d", + "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d", + "shasum": "" + }, + "require": { + "nette/utils": "^3.0.1", + "php": ">=7.1" + }, + "require-dev": { + "nette/tester": "^2.2", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "time": "2019-04-03T15:53:25+00:00" }, { "name": "nette/utils", - "version": "v2.5.2", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5" + "reference": "bd961f49b211997202bda1d0fbc410905be370d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/183069866dc477fcfbac393ed486aaa6d93d19a5", - "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5", + "url": "https://api.github.com/repos/nette/utils/zipball/bd961f49b211997202bda1d0fbc410905be370d4", + "reference": "bd961f49b211997202bda1d0fbc410905be370d4", "shasum": "" }, "require": { - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" + "php": ">=7.1" }, "require-dev": { "nette/tester": "~2.0", @@ -942,7 +992,7 @@ "suggest": { "ext-gd": "to use Image", "ext-iconv": "to use Strings::webalize() and toAscii()", - "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", "ext-xml": "to use Strings::length() etc. when mbstring is not available" @@ -950,15 +1000,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" - ], - "files": [ - "src/loader.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -995,20 +1042,20 @@ "utility", "validation" ], - "time": "2018-05-02T17:16:08+00:00" + "time": "2019-03-22T01:00:30+00:00" }, { "name": "nikic/php-parser", - "version": "v4.0.2", + "version": "v4.2.3", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "35b8caf75e791ba1b2d24fec1552168d72692b12" + "reference": "e612609022e935f3d0337c1295176505b41188c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/35b8caf75e791ba1b2d24fec1552168d72692b12", - "reference": "35b8caf75e791ba1b2d24fec1552168d72692b12", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/e612609022e935f3d0337c1295176505b41188c8", + "reference": "e612609022e935f3d0337c1295176505b41188c8", "shasum": "" }, "require": { @@ -1016,7 +1063,7 @@ "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.0" + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" }, "bin": [ "bin/php-parse" @@ -1024,7 +1071,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1046,20 +1093,20 @@ "parser", "php" ], - "time": "2018-06-03T11:33:10+00:00" + "time": "2019-08-12T20:17:41+00:00" }, { "name": "ocramius/package-versions", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", "shasum": "" }, "require": { @@ -1068,6 +1115,7 @@ }, "require-dev": { "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", "ext-zip": "*", "infection/infection": "^0.7.1", "phpunit/phpunit": "^7.0.0" @@ -1095,7 +1143,7 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-02-05T13:05:30+00:00" + "time": "2019-02-21T12:16:21+00:00" }, { "name": "phar-io/manifest", @@ -1201,35 +1249,33 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1251,30 +1297,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -1302,41 +1348,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1349,26 +1394,27 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, @@ -1383,8 +1429,8 @@ } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -1412,32 +1458,33 @@ "spy", "stub" ], - "time": "2018-08-05T17:53:17+00:00" + "time": "2019-10-03T11:07:50+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "0.3", + "version": "0.3.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "ed3223362174b8067729930439e139794e9e514a" + "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ed3223362174b8067729930439e139794e9e514a", - "reference": "ed3223362174b8067729930439e139794e9e514a", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/8c4ef2aefd9788238897b678a985e1d5c8df6db4", + "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4", "shasum": "" }, "require": { "php": "~7.1" }, "require-dev": { - "consistence/coding-standard": "^2.0.0", + "consistence/coding-standard": "^3.5", "jakub-onderka/php-parallel-lint": "^0.9.2", "phing/phing": "^2.16.0", - "phpstan/phpstan": "^0.10@dev", + "phpstan/phpstan": "^0.10", "phpunit/phpunit": "^6.3", - "slevomat/coding-standard": "^3.3.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2", "symfony/process": "^3.4 || ^4.0" }, "type": "library", @@ -1458,51 +1505,58 @@ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", - "time": "2018-06-20T17:48:01+00:00" + "time": "2019-06-07T19:13:52+00:00" }, { "name": "phpstan/phpstan", - "version": "0.10.1", + "version": "0.11.15", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "3179cf27542e9e47acb548150e7ca21ca5ab92d6" + "reference": "1be5b3a706db16ac472a4c40ec03cf4c810b118d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3179cf27542e9e47acb548150e7ca21ca5ab92d6", - "reference": "3179cf27542e9e47acb548150e7ca21ca5ab92d6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1be5b3a706db16ac472a4c40ec03cf4c810b118d", + "reference": "1be5b3a706db16ac472a4c40ec03cf4c810b118d", "shasum": "" }, "require": { - "composer/xdebug-handler": "^1.0", + "composer/xdebug-handler": "^1.3.0", "jean85/pretty-package-versions": "^1.0.3", "nette/bootstrap": "^2.4 || ^3.0", "nette/di": "^2.4.7 || ^3.0", "nette/robot-loader": "^3.0.1", + "nette/schema": "^1.0", "nette/utils": "^2.4.5 || ^3.0", - "nikic/php-parser": "^4.0.2", + "nikic/php-parser": "^4.2.3", "php": "~7.1", - "phpstan/phpdoc-parser": "^0.3", + "phpstan/phpdoc-parser": "^0.3.5", "symfony/console": "~3.2 || ~4.0", "symfony/finder": "~3.2 || ~4.0" }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, "require-dev": { - "brianium/paratest": "^2.0", - "consistence/coding-standard": "^3.3", + "brianium/paratest": "^2.0 || ^3.0", + "consistence/coding-standard": "^3.5", "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", - "ext-gd": "*", "ext-intl": "*", "ext-mysqli": "*", + "ext-simplexml": "*", + "ext-soap": "*", "ext-zip": "*", "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", "phing/phing": "^2.16.0", - "phpstan/phpstan-deprecation-rules": "^0.10.2", - "phpstan/phpstan-php-parser": "^0.10", - "phpstan/phpstan-phpunit": "^0.10", - "phpstan/phpstan-strict-rules": "^0.10", - "phpunit/phpunit": "^7.0", - "slevomat/coding-standard": "^4.6.2" + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.5.14 || ^8.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" }, "bin": [ "bin/phpstan" @@ -1510,7 +1564,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "0.10-dev" + "dev-master": "0.11-dev" } }, "autoload": { @@ -1526,44 +1580,44 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2018-07-01T18:22:12+00:00" + "time": "2019-08-18T20:51:53+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "6.0.8", + "version": "7.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "848f78b3309780fef7ec8c4666b7ab4e6b09b22f" + "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/848f78b3309780fef7ec8c4666b7ab4e6b09b22f", - "reference": "848f78b3309780fef7ec8c4666b7ab4e6b09b22f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa0d179a13284c7420fc281fc32750e6cc7c9e2f", + "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", + "phpunit/php-token-stream": "^3.1.1", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1", + "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "theseer/tokenizer": "^1.1.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.2.2" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-xdebug": "^2.7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -1589,7 +1643,7 @@ "testing", "xunit" ], - "time": "2018-10-04T03:41:23+00:00" + "time": "2019-09-17T06:24:36+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1684,16 +1738,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.0.0", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", "shasum": "" }, "require": { @@ -1705,7 +1759,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -1729,20 +1783,20 @@ "keywords": [ "timer" ], - "time": "2018-02-01T13:07:23+00:00" + "time": "2019-06-07T04:22:29+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.0.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", "shasum": "" }, "require": { @@ -1755,7 +1809,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -1778,57 +1832,56 @@ "keywords": [ "tokenizer" ], - "time": "2018-02-01T13:16:43+00:00" + "time": "2019-09-17T06:23:10+00:00" }, { "name": "phpunit/phpunit", - "version": "7.4.0", + "version": "8.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f3837fa1e07758057ae06e8ddec6d06ba183f126" + "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3837fa1e07758057ae06e8ddec6d06ba183f126", - "reference": "f3837fa1e07758057ae06e8ddec6d06ba183f126", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869", + "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.1", + "doctrine/instantiator": "^1.2.0", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.2", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "phpunit/php-invoker": "^2.0.0" }, "bin": [ "phpunit" @@ -1836,7 +1889,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.4-dev" + "dev-master": "8.4-dev" } }, "autoload": { @@ -1862,20 +1915,20 @@ "testing", "xunit" ], - "time": "2018-10-05T04:05:24+00:00" + "time": "2019-10-07T12:57:41+00:00" }, { "name": "psr/log", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { @@ -1909,7 +1962,7 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2018-11-20T15:27:04+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -2022,23 +2075,23 @@ }, { "name": "sebastian/diff", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "366541b989927187c4ca70490a35615d3fef2dce" + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", - "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0", + "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", @@ -2074,32 +2127,35 @@ "unidiff", "unified diff" ], - "time": "2018-06-10T07:54:39+00:00" + "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -2124,20 +2180,20 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -2164,6 +2220,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -2172,17 +2232,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -2191,27 +2247,30 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -2219,7 +2278,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2242,7 +2301,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2019-02-01T05:30:01+00:00" }, { "name": "sebastian/object-enumerator", @@ -2431,6 +2490,52 @@ "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "time": "2018-10-04T04:07:39+00:00" }, + { + "name": "sebastian/type", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "role": "lead", + "email": "sebastian@phpunit.de" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "time": "2019-07-02T08:10:15+00:00" + }, { "name": "sebastian/version", "version": "2.0.1", @@ -2476,29 +2581,30 @@ }, { "name": "slevomat/coding-standard", - "version": "4.8.3", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "32e1ca205fc34920f323582ed29c0602e3897ae3" + "reference": "223f02b6193fe47b7b483bfa5bf75693535482dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/32e1ca205fc34920f323582ed29c0602e3897ae3", - "reference": "32e1ca205fc34920f323582ed29c0602e3897ae3", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/223f02b6193fe47b7b483bfa5bf75693535482dd", + "reference": "223f02b6193fe47b7b483bfa5bf75693535482dd", "shasum": "" }, "require": { "php": "^7.1", - "squizlabs/php_codesniffer": "^3.3.0" + "phpstan/phpdoc-parser": "^0.3.1", + "squizlabs/php_codesniffer": "^3.4.0" }, "require-dev": { "jakub-onderka/php-parallel-lint": "1.0.0", "phing/phing": "2.16.1", - "phpstan/phpstan": "0.9.2", - "phpstan/phpstan-phpunit": "0.9.4", - "phpstan/phpstan-strict-rules": "0.9", - "phpunit/phpunit": "7.3.5" + "phpstan/phpstan": "0.11.1", + "phpstan/phpstan-phpunit": "0.11", + "phpstan/phpstan-strict-rules": "0.11", + "phpunit/phpunit": "8.0.0" }, "type": "phpcodesniffer-standard", "autoload": { @@ -2511,20 +2617,20 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "time": "2018-09-25T21:21:11+00:00" + "time": "2019-03-12T20:26:36+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e" + "reference": "379deb987e26c7cd103a7b387aea178baec96e48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e", - "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48", + "reference": "379deb987e26c7cd103a7b387aea178baec96e48", "shasum": "" }, "require": { @@ -2562,30 +2668,34 @@ "phpcs", "standards" ], - "time": "2018-09-23T23:08:17+00:00" + "time": "2018-12-19T23:57:18+00:00" }, { "name": "symfony/console", - "version": "v4.1.1", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "70591cda56b4b47c55776ac78e157c4bb6c8b43f" + "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/70591cda56b4b47c55776ac78e157c4bb6c8b43f", - "reference": "70591cda56b4b47c55776ac78e157c4bb6c8b43f", + "url": "https://api.github.com/repos/symfony/console/zipball/9dc2299a016497f9ee620be94524e6c0af0280a9", + "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { "symfony/dependency-injection": "<3.4", "symfony/process": "<3.3" }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", "symfony/config": "~3.4|~4.0", @@ -2595,7 +2705,7 @@ "symfony/process": "~3.4|~4.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" @@ -2603,7 +2713,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -2630,7 +2740,75 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-05-31T10:17:53+00:00" + "time": "2019-02-23T15:17:42+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/debug", @@ -2690,16 +2868,16 @@ }, { "name": "symfony/finder", - "version": "v4.1.1", + "version": "v4.3.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb" + "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/84714b8417d19e4ba02ea78a41a975b3efaafddb", - "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb", + "url": "https://api.github.com/repos/symfony/finder/zipball/9638d41e3729459860bb96f6247ccb61faaa45f2", + "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2", "shasum": "" }, "require": { @@ -2708,7 +2886,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2735,54 +2913,40 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-06-19T21:38:16+00:00" + "time": "2019-06-28T13:16:30+00:00" }, { - "name": "symfony/phpunit-bridge", - "version": "v4.0.6", + "name": "symfony/polyfill-ctype", + "version": "v1.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "14ffbbe2a72d0f6339b24eb830dd38cf63ba6630" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/14ffbbe2a72d0f6339b24eb830dd38cf63ba6630", - "reference": "14ffbbe2a72d0f6339b24eb830dd38cf63ba6630", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, "suggest": { - "ext-zip": "Zip support is required when using bin/simple-phpunit", - "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + "ext-ctype": "For best performance" }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", + "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" - }, - "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" + "dev-master": "1.12-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" + "Symfony\\Polyfill\\Ctype\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2791,30 +2955,36 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony PHPUnit Bridge", + "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", - "time": "2018-02-19T16:50:22+00:00" + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.7.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -2826,7 +2996,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -2860,20 +3030,20 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { @@ -2895,33 +3065,33 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "role": "Developer", + "email": "arne@blankerts.de" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2019-06-13T22:48:21+00:00" }, { "name": "webmozart/assert", - "version": "1.3.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -2950,7 +3120,7 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2019-08-24T08:43:50+00:00" } ], "aliases": [], @@ -2959,7 +3129,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.1", + "php": "^7.2", "ext-pdo": "*" }, "platform-dev": [] diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php b/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php index 721709a0d..f04c85249 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php @@ -12,6 +12,7 @@ use PDO; use function array_merge; use function array_values; +use function assert; use function reset; /** @@ -41,7 +42,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement /** @var int */ private $lifetime; - /** @var Statement */ + /** @var ResultStatement */ private $statement; /** @@ -62,7 +63,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement * @param string $realKey * @param int $lifetime */ - public function __construct(Statement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime) + public function __construct(ResultStatement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime) { $this->statement = $stmt; $this->resultCache = $resultCache; @@ -166,7 +167,15 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX */ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) { - $this->data = $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs); + $data = $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs); + + if ($fetchMode === FetchMode::COLUMN) { + foreach ($data as $key => $value) { + $data[$key] = [$value]; + } + } + + $this->data = $data; $this->emptied = true; return $this->data; @@ -196,6 +205,8 @@ public function fetchColumn($columnIndex = 0) */ public function rowCount() { + assert($this->statement instanceof Statement); + return $this->statement->rowCount(); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php b/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php index 9b7b21fb2..2cc0070d0 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php @@ -107,6 +107,7 @@ private function buildSchemaAssetsFilterFromExpression($filterExpression) : call if ($assetName instanceof AbstractAsset) { $assetName = $assetName->getName(); } + return preg_match($filterExpression, $assetName); }; } @@ -116,7 +117,8 @@ private function buildSchemaAssetsFilterFromExpression($filterExpression) : call */ public function setSchemaAssetsFilter(?callable $callable = null) : ?callable { - $this->_attributes['filterSchemaAssetsExpression'] = null; + $this->_attributes['filterSchemaAssetsExpression'] = null; + return $this->_attributes['filterSchemaAssetsExpressionCallable'] = $callable; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Connection.php b/doctrine/dbal/lib/Doctrine/DBAL/Connection.php index 85761fcca..ee6c08635 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Connection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Connection.php @@ -22,7 +22,6 @@ use Exception; use Throwable; use function array_key_exists; -use function array_merge; use function assert; use function func_get_args; use function implode; @@ -149,7 +148,7 @@ class Connection implements DriverConnection /** * The schema manager. * - * @var AbstractSchemaManager + * @var AbstractSchemaManager|null */ protected $_schemaManager; @@ -201,7 +200,6 @@ public function __construct( } $this->platform = $params['platform']; - unset($this->params['platform']); } // Create default config and event manager if none given @@ -244,6 +242,8 @@ public function getDatabase() /** * Gets the hostname of the currently connected database. * + * @deprecated + * * @return string|null */ public function getHost() @@ -254,6 +254,8 @@ public function getHost() /** * Gets the port of the currently connected database. * + * @deprecated + * * @return mixed */ public function getPort() @@ -264,6 +266,8 @@ public function getPort() /** * Gets the username used by this connection. * + * @deprecated + * * @return string|null */ public function getUsername() @@ -274,6 +278,8 @@ public function getUsername() /** * Gets the password used by this connection. * + * @deprecated + * * @return string|null */ public function getPassword() @@ -356,6 +362,8 @@ public function connect() $this->_conn = $this->_driver->connect($this->params, $user, $password, $driverOptions); $this->isConnected = true; + $this->transactionNestingLevel = 0; + if ($this->autoCommit === false) { $this->beginTransaction(); } @@ -460,11 +468,11 @@ private function getDatabasePlatformVersion() */ private function getServerVersion() { + $connection = $this->getWrappedConnection(); + // Automatic platform version detection. - if ($this->_conn instanceof ServerInfoAwareConnection && - ! $this->_conn->requiresQueryForServerVersion() - ) { - return $this->_conn->getServerVersion(); + if ($connection instanceof ServerInfoAwareConnection && ! $connection->requiresQueryForServerVersion()) { + return $connection->getServerVersion(); } // Unable to detect platform version. @@ -599,24 +607,26 @@ public function isTransactionActive() } /** - * Gathers conditions for an update or delete call. + * Adds identifier condition to the query components * - * @param mixed[] $identifiers Input array of columns to values + * @param mixed[] $identifier Map of key columns to their values + * @param string[] $columns Column names + * @param mixed[] $values Column values + * @param string[] $conditions Key conditions * - * @return string[][] a triplet with: - * - the first key being the columns - * - the second key being the values - * - the third key being the conditions + * @throws DBALException */ - private function gatherConditions(array $identifiers) - { - $columns = []; - $values = []; - $conditions = []; + private function addIdentifierCondition( + array $identifier, + array &$columns, + array &$values, + array &$conditions + ) : void { + $platform = $this->getDatabasePlatform(); - foreach ($identifiers as $columnName => $value) { + foreach ($identifier as $columnName => $value) { if ($value === null) { - $conditions[] = $this->getDatabasePlatform()->getIsNullExpression($columnName); + $conditions[] = $platform->getIsNullExpression($columnName); continue; } @@ -624,8 +634,6 @@ private function gatherConditions(array $identifiers) $values[] = $value; $conditions[] = $columnName . ' = ?'; } - - return [$columns, $values, $conditions]; } /** @@ -648,7 +656,9 @@ public function delete($tableExpression, array $identifier, array $types = []) throw InvalidArgumentException::fromEmptyCriteria(); } - [$columns, $values, $conditions] = $this->gatherConditions($identifier); + $columns = $values = $conditions = []; + + $this->addIdentifierCondition($identifier, $columns, $values, $conditions); return $this->executeUpdate( 'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $conditions), @@ -713,19 +723,15 @@ public function getTransactionIsolation() */ public function update($tableExpression, array $data, array $identifier, array $types = []) { - $setColumns = []; - $setValues = []; - $set = []; + $columns = $values = $conditions = $set = []; foreach ($data as $columnName => $value) { - $setColumns[] = $columnName; - $setValues[] = $value; - $set[] = $columnName . ' = ?'; + $columns[] = $columnName; + $values[] = $value; + $set[] = $columnName . ' = ?'; } - [$conditionColumns, $conditionValues, $conditions] = $this->gatherConditions($identifier); - $columns = array_merge($setColumns, $conditionColumns); - $values = array_merge($setValues, $conditionValues); + $this->addIdentifierCondition($identifier, $columns, $values, $conditions); if (is_string(key($types))) { $types = $this->extractTypeValues($columns, $types); @@ -777,7 +783,7 @@ public function insert($tableExpression, array $data, array $types = []) /** * Extract ordered type list from an ordered column list and type map. * - * @param string[] $columnList + * @param int[]|string[] $columnList * @param int[]|string[] $types * * @return int[]|string[] @@ -813,20 +819,15 @@ public function quoteIdentifier($str) } /** - * Quotes a given input parameter. - * - * @param mixed $input The parameter to be quoted. - * @param int|null $type The type of the parameter. - * - * @return string The quoted parameter. + * {@inheritDoc} */ public function quote($input, $type = null) { - $this->connect(); + $connection = $this->getWrappedConnection(); [$value, $bindingType] = $this->getBindingInfo($input, $type); - return $this->_conn->quote($value, $bindingType); + return $connection->quote($value, $bindingType); } /** @@ -886,7 +887,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach return $this->executeCacheQuery($query, $params, $types, $qcp); } - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -897,7 +898,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach if ($params) { [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); - $stmt = $this->_conn->prepare($query); + $stmt = $connection->prepare($query); if ($types) { $this->_bindTypedValues($stmt, $params, $types); $stmt->execute(); @@ -905,7 +906,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach $stmt->execute($params); } } else { - $stmt = $this->_conn->query($query); + $stmt = $connection->query($query); } } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); @@ -934,12 +935,16 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach */ public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) { - $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl(); - if (! $resultCache) { + $resultCache = $qcp->getResultCacheDriver() ?? $this->_config->getResultCacheImpl(); + + if ($resultCache === null) { throw CacheException::noResultDriverConfigured(); } - [$cacheKey, $realKey] = $qcp->generateCacheKeys($query, $params, $types, $this->getParams()); + $connectionParams = $this->getParams(); + unset($connectionParams['platform']); + + [$cacheKey, $realKey] = $qcp->generateCacheKeys($query, $params, $types, $connectionParams); // fetch the row pointers entry $data = $resultCache->fetch($cacheKey); @@ -997,7 +1002,7 @@ public function project($query, array $params, Closure $function) */ public function query() { - $this->connect(); + $connection = $this->getWrappedConnection(); $args = func_get_args(); @@ -1007,7 +1012,7 @@ public function query() } try { - $statement = $this->_conn->query(...$args); + $statement = $connection->query(...$args); } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]); } @@ -1037,7 +1042,7 @@ public function query() */ public function executeUpdate($query, array $params = [], array $types = []) { - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -1048,7 +1053,8 @@ public function executeUpdate($query, array $params = [], array $types = []) if ($params) { [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); - $stmt = $this->_conn->prepare($query); + $stmt = $connection->prepare($query); + if ($types) { $this->_bindTypedValues($stmt, $params, $types); $stmt->execute(); @@ -1057,7 +1063,7 @@ public function executeUpdate($query, array $params = [], array $types = []) } $result = $stmt->rowCount(); } else { - $result = $this->_conn->exec($query); + $result = $connection->exec($query); } } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); @@ -1081,7 +1087,7 @@ public function executeUpdate($query, array $params = [], array $types = []) */ public function exec($statement) { - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -1089,7 +1095,7 @@ public function exec($statement) } try { - $result = $this->_conn->exec($statement); + $result = $connection->exec($statement); } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement); } @@ -1118,9 +1124,7 @@ public function getTransactionNestingLevel() */ public function errorCode() { - $this->connect(); - - return $this->_conn->errorCode(); + return $this->getWrappedConnection()->errorCode(); } /** @@ -1128,9 +1132,7 @@ public function errorCode() */ public function errorInfo() { - $this->connect(); - - return $this->_conn->errorInfo(); + return $this->getWrappedConnection()->errorInfo(); } /** @@ -1147,9 +1149,7 @@ public function errorInfo() */ public function lastInsertId($seqName = null) { - $this->connect(); - - return $this->_conn->lastInsertId($seqName); + return $this->getWrappedConnection()->lastInsertId($seqName); } /** @@ -1173,6 +1173,7 @@ public function transactional(Closure $func) try { $res = $func($this); $this->commit(); + return $res; } catch (Exception $e) { $this->rollBack(); @@ -1227,13 +1228,11 @@ protected function _getNestedTransactionSavePointName() } /** - * Starts a transaction by suspending auto-commit mode. - * - * @return void + * {@inheritDoc} */ public function beginTransaction() { - $this->connect(); + $connection = $this->getWrappedConnection(); ++$this->transactionNestingLevel; @@ -1243,7 +1242,9 @@ public function beginTransaction() if ($logger) { $logger->startQuery('"START TRANSACTION"'); } - $this->_conn->beginTransaction(); + + $connection->beginTransaction(); + if ($logger) { $logger->stopQuery(); } @@ -1256,12 +1257,12 @@ public function beginTransaction() $logger->stopQuery(); } } + + return true; } /** - * Commits the current transaction. - * - * @return void + * {@inheritDoc} * * @throws ConnectionException If the commit failed due to no active transaction or * because the transaction was marked for rollback only. @@ -1275,7 +1276,9 @@ public function commit() throw ConnectionException::commitFailedRollbackOnly(); } - $this->connect(); + $result = true; + + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); @@ -1283,7 +1286,9 @@ public function commit() if ($logger) { $logger->startQuery('"COMMIT"'); } - $this->_conn->commit(); + + $result = $connection->commit(); + if ($logger) { $logger->stopQuery(); } @@ -1300,10 +1305,12 @@ public function commit() --$this->transactionNestingLevel; if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) { - return; + return $result; } $this->beginTransaction(); + + return $result; } /** @@ -1335,7 +1342,7 @@ public function rollBack() throw ConnectionException::noActiveTransaction(); } - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); @@ -1344,7 +1351,7 @@ public function rollBack() $logger->startQuery('"ROLLBACK"'); } $this->transactionNestingLevel = 0; - $this->_conn->rollBack(); + $connection->rollBack(); $this->isRollbackOnly = false; if ($logger) { $logger->stopQuery(); @@ -1383,7 +1390,7 @@ public function createSavepoint($savepoint) throw ConnectionException::savepointsNotSupported(); } - $this->_conn->exec($this->platform->createSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->createSavePoint($savepoint)); } /** @@ -1405,7 +1412,7 @@ public function releaseSavepoint($savepoint) return; } - $this->_conn->exec($this->platform->releaseSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->releaseSavePoint($savepoint)); } /** @@ -1423,13 +1430,13 @@ public function rollbackSavepoint($savepoint) throw ConnectionException::savepointsNotSupported(); } - $this->_conn->exec($this->platform->rollbackSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->rollbackSavePoint($savepoint)); } /** * Gets the wrapped driver connection. * - * @return \Doctrine\DBAL\Driver\Connection + * @return DriverConnection */ public function getWrappedConnection() { @@ -1446,7 +1453,7 @@ public function getWrappedConnection() */ public function getSchemaManager() { - if (! $this->_schemaManager) { + if ($this->_schemaManager === null) { $this->_schemaManager = $this->_driver->getSchemaManager($this); } @@ -1561,8 +1568,8 @@ private function _bindTypedValues($stmt, array $params, array $types) /** * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type. * - * @param mixed $value The value to bind. - * @param int|string $type The type to bind (PDO or DBAL). + * @param mixed $value The value to bind. + * @param int|string|null $type The type to bind (PDO or DBAL). * * @return mixed[] [0] => the (escaped) value, [1] => the binding type. */ @@ -1661,10 +1668,10 @@ public function createQueryBuilder() */ public function ping() { - $this->connect(); + $connection = $this->getWrappedConnection(); - if ($this->_conn instanceof PingableConnection) { - return $this->_conn->ping(); + if ($connection instanceof PingableConnection) { + return $connection->ping(); } try { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php b/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php index d2e4b2c25..ff310d919 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php @@ -11,6 +11,7 @@ use Doctrine\DBAL\Events; use InvalidArgumentException; use function array_rand; +use function assert; use function count; use function func_get_args; @@ -133,7 +134,7 @@ public function connect($connectionName = null) // If we have a connection open, and this is not an explicit connection // change request, then abort right here, because we are already done. // This prevents writes to the slave in case of "keepSlave" option enabled. - if (isset($this->_conn) && $this->_conn && ! $requestedConnectionChange) { + if ($this->_conn !== null && ! $requestedConnectionChange) { return false; } @@ -144,7 +145,7 @@ public function connect($connectionName = null) $forceMasterAsSlave = true; } - if (isset($this->connections[$connectionName]) && $this->connections[$connectionName]) { + if (isset($this->connections[$connectionName])) { $this->_conn = $this->connections[$connectionName]; if ($forceMasterAsSlave && ! $this->keepSlave) { @@ -232,7 +233,7 @@ public function beginTransaction() { $this->connect('master'); - parent::beginTransaction(); + return parent::beginTransaction(); } /** @@ -242,7 +243,7 @@ public function commit() { $this->connect('master'); - parent::commit(); + return parent::commit(); } /** @@ -344,6 +345,7 @@ public function rollbackSavepoint($savepoint) public function query() { $this->connect('master'); + assert($this->_conn instanceof DriverConnection); $args = func_get_args(); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php b/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php index 15bac7f0f..4961af2f3 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\ExceptionConverterDriver; use Doctrine\DBAL\Exception\DriverException; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; use Exception; use Throwable; use function array_map; @@ -17,8 +18,9 @@ use function is_resource; use function is_string; use function json_encode; +use function preg_replace; +use function spl_object_hash; use function sprintf; -use function str_split; class DBALException extends Exception { @@ -128,11 +130,10 @@ public static function unknownDriver($unknownDriverName, array $knownDrivers) } /** - * @param Exception $driverEx - * @param string $sql - * @param mixed[] $params + * @param string $sql + * @param mixed[] $params * - * @return \Doctrine\DBAL\DBALException + * @return self */ public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = []) { @@ -146,9 +147,7 @@ public static function driverExceptionDuringQuery(Driver $driver, Throwable $dri } /** - * @param Exception $driverEx - * - * @return \Doctrine\DBAL\DBALException + * @return self */ public static function driverException(Driver $driver, Throwable $driverEx) { @@ -156,9 +155,7 @@ public static function driverException(Driver $driver, Throwable $driverEx) } /** - * @param Exception $driverEx - * - * @return \Doctrine\DBAL\DBALException + * @return self */ private static function wrapException(Driver $driver, Throwable $driverEx, $msg) { @@ -191,7 +188,7 @@ private static function formatParameters(array $params) if (! is_string($json) || $json === 'null' && is_string($param)) { // JSON encoding failed, this is not a UTF-8 string. - return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"'; + return sprintf('"%s"', preg_replace('/.{2}/', '\\x$0', bin2hex($param))); } return $json; @@ -282,4 +279,16 @@ public static function typeNotFound($name) { return new self('Type to be overwritten ' . $name . ' does not exist.'); } + + public static function typeNotRegistered(Type $type) : self + { + return new self(sprintf('Type of the class %s@%s is not registered.', get_class($type), spl_object_hash($type))); + } + + public static function typeAlreadyRegistered(Type $type) : self + { + return new self( + sprintf('Type of the class %s@%s is already registered.', get_class($type), spl_object_hash($type)) + ); + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver.php index dcb03b294..57493e633 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver.php @@ -14,6 +14,8 @@ interface Driver /** * Attempts to create a connection with the database. * + * The usage of NULL to indicate empty username or password is deprecated. Use an empty string instead. + * * @param mixed[] $params All connection parameters passed by the user. * @param string|null $username The username to use when connecting. * @param string|null $password The password to use when connecting. @@ -42,6 +44,8 @@ public function getSchemaManager(Connection $conn); /** * Gets the name of the driver. * + * @deprecated + * * @return string The name of the driver. */ public function getName(); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php index 851f0ee23..dbf342814 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php @@ -49,6 +49,8 @@ public function getSchemaManager(\Doctrine\DBAL\Connection $conn) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php index bd80e6e49..cb1e6018f 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php @@ -42,13 +42,16 @@ public function __construct(array $params, $username, $password, $driverOptions $isPersistent = (isset($params['persistent']) && $params['persistent'] === true); if ($isPersistent) { - $this->conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions); + $conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions); } else { - $this->conn = db2_connect($params['dbname'], $username, $password, $driverOptions); + $conn = db2_connect($params['dbname'], $username, $password, $driverOptions); } - if (! $this->conn) { + + if ($conn === false) { throw new DB2Exception(db2_conn_errormsg()); } + + $this->conn = $conn; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php index 712cbe419..fe79fe6bd 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -34,11 +34,13 @@ public function connect(array $params, $username = null, $password = null, array $password = null; } - return new DB2Connection($params, $username, $password, $driverOptions); + return new DB2Connection($params, (string) $username, (string) $password, $driverOptions); } /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php index 9c87d4631..af6e852bc 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php @@ -127,16 +127,16 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l } /** - * @param int|string $parameter Parameter position or name - * @param mixed $variable + * @param int $position Parameter position + * @param mixed $variable * * @throws DB2Exception */ - private function bind($parameter, &$variable, int $parameterType, int $dataType) : void + private function bind($position, &$variable, int $parameterType, int $dataType) : void { - $this->bindParam[$parameter] =& $variable; + $this->bindParam[$position] =& $variable; - if (! db2_bind_param($this->stmt, $parameter, 'variable', $parameterType, $dataType)) { + if (! db2_bind_param($this->stmt, $position, 'variable', $parameterType, $dataType)) { throw new DB2Exception(db2_stmt_errormsg()); } } @@ -146,10 +146,6 @@ private function bind($parameter, &$variable, int $parameterType, int $dataType) */ public function closeCursor() { - if (! $this->stmt) { - return false; - } - $this->bindParam = []; if (! db2_free_result($this->stmt)) { @@ -166,11 +162,7 @@ public function closeCursor() */ public function columnCount() { - if (! $this->stmt) { - return false; - } - - return db2_num_fields($this->stmt); + return db2_num_fields($this->stmt) ?: 0; } /** @@ -197,10 +189,6 @@ public function errorInfo() */ public function execute($params = null) { - if (! $this->stmt) { - return false; - } - if ($params === null) { ksort($this->bindParam); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php index aaf4f2bd9..1166e8d4c 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -13,7 +13,7 @@ class Driver extends AbstractMySQLDriver public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { try { - return new MysqliConnection($params, $username, $password, $driverOptions); + return new MysqliConnection($params, (string) $username, (string) $password, $driverOptions); } catch (MysqliException $e) { throw DBALException::driverException($this, $e); } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php index 2bbe0ca8b..43d70853e 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php @@ -11,13 +11,15 @@ use mysqli; use mysqli_stmt; use PDO; -use stdClass; use function array_combine; use function array_fill; +use function assert; use function count; use function feof; use function fread; use function get_resource_type; +use function is_array; +use function is_int; use function is_resource; use function sprintf; use function str_repeat; @@ -40,11 +42,11 @@ class MysqliStatement implements IteratorAggregate, Statement /** @var mysqli_stmt */ protected $_stmt; - /** @var string[]|bool|null */ + /** @var string[]|false|null */ protected $_columnNames; - /** @var mixed[]|null */ - protected $_rowBindedValues; + /** @var mixed[] */ + protected $_rowBindedValues = []; /** @var mixed[] */ protected $_bindedValues; @@ -77,11 +79,15 @@ class MysqliStatement implements IteratorAggregate, Statement public function __construct(mysqli $conn, $prepareString) { $this->_conn = $conn; - $this->_stmt = $conn->prepare($prepareString); - if ($this->_stmt === false) { + + $stmt = $conn->prepare($prepareString); + + if ($stmt === false) { throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno); } + $this->_stmt = $stmt; + $paramCount = $this->_stmt->param_count; if (0 >= $paramCount) { return; @@ -96,18 +102,14 @@ public function __construct(mysqli $conn, $prepareString) */ public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) { - if ($type === null) { - $type = 's'; - } else { - if (! isset(self::$_paramTypeMap[$type])) { - throw new MysqliException(sprintf("Unknown type: '%s'", $type)); - } + assert(is_int($column)); - $type = self::$_paramTypeMap[$type]; + if (! isset(self::$_paramTypeMap[$type])) { + throw new MysqliException(sprintf("Unknown type: '%s'", $type)); } $this->_bindedValues[$column] =& $variable; - $this->types[$column - 1] = $type; + $this->types[$column - 1] = self::$_paramTypeMap[$type]; return true; } @@ -117,19 +119,15 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l */ public function bindValue($param, $value, $type = ParameterType::STRING) { - if ($type === null) { - $type = 's'; - } else { - if (! isset(self::$_paramTypeMap[$type])) { - throw new MysqliException(sprintf("Unknown type: '%s'", $type)); - } + assert(is_int($param)); - $type = self::$_paramTypeMap[$type]; + if (! isset(self::$_paramTypeMap[$type])) { + throw new MysqliException(sprintf("Unknown type: '%s'", $type)); } $this->_values[$param] = $value; $this->_bindedValues[$param] =& $this->_values[$param]; - $this->types[$param - 1] = $type; + $this->types[$param - 1] = self::$_paramTypeMap[$type]; return true; } @@ -141,15 +139,11 @@ public function execute($params = null) { if ($this->_bindedValues !== null) { if ($params !== null) { - if (! $this->_bindValues($params)) { + if (! $this->bindUntypedValues($params)) { throw new MysqliException($this->_stmt->error, $this->_stmt->errno); } } else { - [$types, $values, $streams] = $this->separateBoundValues(); - if (! $this->_stmt->bind_param($types, ...$values)) { - throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); - } - $this->sendLongData($streams); + $this->bindTypedParameters(); } } @@ -160,10 +154,14 @@ public function execute($params = null) if ($this->_columnNames === null) { $meta = $this->_stmt->result_metadata(); if ($meta !== false) { + $fields = $meta->fetch_fields(); + assert(is_array($fields)); + $columnNames = []; - foreach ($meta->fetch_fields() as $col) { + foreach ($fields as $col) { $columnNames[] = $col->name; } + $meta->free(); $this->_columnNames = $columnNames; @@ -207,12 +205,9 @@ public function execute($params = null) } /** - * Split $this->_bindedValues into those values that need to be sent using mysqli::send_long_data() - * and those that can be bound the usual way. - * - * @return array|string> + * Binds parameters with known types previously bound to the statement */ - private function separateBoundValues() + private function bindTypedParameters() { $streams = $values = []; $types = $this->types; @@ -230,15 +225,19 @@ private function separateBoundValues() $streams[$parameter] = $value; $values[$parameter] = null; continue; - } else { - $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING]; } + + $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING]; } $values[$parameter] = $value; } - return [$types, $values, $streams]; + if (! $this->_stmt->bind_param($types, ...$values)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + + $this->sendLongData($streams); } /** @@ -270,7 +269,7 @@ private function sendLongData($streams) * * @return bool */ - private function _bindValues($values) + private function bindUntypedValues(array $values) { $params = []; $types = str_repeat('s', count($values)); @@ -283,7 +282,7 @@ private function _bindValues($values) } /** - * @return mixed[]|false + * @return mixed[]|false|null */ private function _fetch() { @@ -319,6 +318,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX } $values = $this->_fetch(); + if ($values === null) { return false; } @@ -327,28 +327,23 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); } - switch ($fetchMode) { - case FetchMode::NUMERIC: - return $values; + if ($fetchMode === FetchMode::NUMERIC) { + return $values; + } + + assert(is_array($this->_columnNames)); + $assoc = array_combine($this->_columnNames, $values); + assert(is_array($assoc)); + switch ($fetchMode) { case FetchMode::ASSOCIATIVE: - return array_combine($this->_columnNames, $values); + return $assoc; case FetchMode::MIXED: - $ret = array_combine($this->_columnNames, $values); - $ret += $values; - - return $ret; + return $assoc + $values; case FetchMode::STANDARD_OBJECT: - $assoc = array_combine($this->_columnNames, $values); - $ret = new stdClass(); - - foreach ($assoc as $column => $value) { - $ret->$column = $value; - } - - return $ret; + return (object) $assoc; default: throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode)); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php index 872582d80..edda32d6a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -18,10 +18,10 @@ public function connect(array $params, $username = null, $password = null, array { try { return new OCI8Connection( - $username, - $password, + (string) $username, + (string) $password, $this->_constructDsn($params), - $params['charset'] ?? null, + $params['charset'] ?? '', $params['sessionMode'] ?? OCI_DEFAULT, $params['persistent'] ?? false ); @@ -44,6 +44,8 @@ protected function _constructDsn(array $params) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php index 5ebc877a8..c1857936f 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -10,8 +10,6 @@ use const OCI_DEFAULT; use const OCI_NO_AUTO_COMMIT; use function addcslashes; -use function define; -use function defined; use function func_get_args; use function is_float; use function is_int; @@ -39,28 +37,32 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection /** * Creates a Connection to an Oracle Database using oci8 extension. * - * @param string $username - * @param string $password - * @param string $db - * @param string|null $charset - * @param int $sessionMode - * @param bool $persistent + * @param string $username + * @param string $password + * @param string $db + * @param string $charset + * @param int $sessionMode + * @param bool $persistent * * @throws OCI8Exception */ - public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT, $persistent = false) - { - if (! defined('OCI_NO_AUTO_COMMIT')) { - define('OCI_NO_AUTO_COMMIT', 0); - } - - $this->dbh = $persistent + public function __construct( + $username, + $password, + $db, + $charset = '', + $sessionMode = OCI_DEFAULT, + $persistent = false + ) { + $dbh = $persistent ? @oci_pconnect($username, $password, $db, $charset, $sessionMode) : @oci_connect($username, $password, $db, $charset, $sessionMode); - if (! $this->dbh) { + if ($dbh === false) { throw OCI8Exception::fromErrorInfo(oci_error()); } + + $this->dbh = $dbh; } /** @@ -71,17 +73,23 @@ public function __construct($username, $password, $db, $charset = null, $session */ public function getServerVersion() { - if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) { + $version = oci_server_version($this->dbh); + + if ($version === false) { + throw OCI8Exception::fromErrorInfo(oci_error($this->dbh)); + } + + if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) { throw new UnexpectedValueException( sprintf( 'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' . 'Please report this database version string to the Doctrine team.', - oci_server_version($this->dbh) + $version ) ); } - return $version[1]; + return $matches[1]; } /** @@ -222,6 +230,12 @@ public function errorCode() */ public function errorInfo() { - return oci_error($this->dbh); + $error = oci_error($this->dbh); + + if ($error === false) { + return []; + } + + return $error; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php index 9d61ad42d..af3a9d1a7 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php @@ -7,12 +7,16 @@ class OCI8Exception extends AbstractDriverException { /** - * @param mixed[] $error + * @param mixed[]|false $error * * @return \Doctrine\DBAL\Driver\OCI8\OCI8Exception */ public static function fromErrorInfo($error) { + if ($error === false) { + return new self('Database error occurred but no error information was retrieved from the driver.'); + } + return new self($error['message'], null, $error['code']); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php index 8db54c86a..2f8b93238 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php @@ -23,9 +23,11 @@ use const PREG_OFFSET_CAPTURE; use const SQLT_CHR; use function array_key_exists; +use function assert; use function count; use function implode; -use function is_numeric; +use function is_int; +use function is_resource; use function oci_bind_by_name; use function oci_cancel; use function oci_error; @@ -56,7 +58,11 @@ class OCI8Statement implements IteratorAggregate, Statement /** @var OCI8Connection */ protected $_conn; - /** @var string */ + /** + * @deprecated + * + * @var string + */ protected static $_PARAM = ':param'; /** @var int[] */ @@ -92,16 +98,20 @@ class OCI8Statement implements IteratorAggregate, Statement /** * Creates a new OCI8Statement that uses the given connection handle and SQL statement. * - * @param resource $dbh The connection handle. - * @param string $statement The SQL statement. + * @param resource $dbh The connection handle. + * @param string $query The SQL query. */ - public function __construct($dbh, $statement, OCI8Connection $conn) + public function __construct($dbh, $query, OCI8Connection $conn) { - [$statement, $paramMap] = self::convertPositionalToNamedPlaceholders($statement); - $this->_sth = oci_parse($dbh, $statement); - $this->_dbh = $dbh; - $this->_paramMap = $paramMap; - $this->_conn = $conn; + [$query, $paramMap] = self::convertPositionalToNamedPlaceholders($query); + + $stmt = oci_parse($dbh, $query); + assert(is_resource($stmt)); + + $this->_sth = $stmt; + $this->_dbh = $dbh; + $this->_paramMap = $paramMap; + $this->_conn = $conn; } /** @@ -207,10 +217,9 @@ private static function findPlaceholderOrOpeningQuote( /** * Finds closing quote * - * @param string $statement The SQL statement to parse - * @param string $tokenOffset The offset to start searching from - * @param string|null $currentLiteralDelimiter The delimiter of the current string literal - * or NULL if not currently in a literal + * @param string $statement The SQL statement to parse + * @param string $tokenOffset The offset to start searching from + * @param string $currentLiteralDelimiter The delimiter of the current string literal * * @return bool Whether the token was found */ @@ -240,7 +249,7 @@ private static function findClosingQuote( * where the token was found. * * @param string $statement The SQL statement to parse - * @param string $offset The offset to start searching from + * @param int $offset The offset to start searching from * @param string $regex The regex containing token pattern * * @return string|null Token or NULL if not found @@ -249,6 +258,7 @@ private static function findToken($statement, &$offset, $regex) { if (preg_match($regex, $statement, $matches, PREG_OFFSET_CAPTURE, $offset)) { $offset = $matches[0][1]; + return $matches[0][0]; } @@ -266,22 +276,32 @@ public function bindValue($param, $value, $type = ParameterType::STRING) /** * {@inheritdoc} */ - public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null) { - $column = $this->_paramMap[$column] ?? $column; + if (is_int($param)) { + if (! isset($this->_paramMap[$param])) { + throw new OCI8Exception(sprintf('Could not find variable mapping with index %d, in the SQL statement', $param)); + } + + $param = $this->_paramMap[$param]; + } if ($type === ParameterType::LARGE_OBJECT) { $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB); + + $class = 'OCI-Lob'; + assert($lob instanceof $class); + $lob->writeTemporary($variable, OCI_TEMP_BLOB); $variable =& $lob; } - $this->boundValues[$column] =& $variable; + $this->boundValues[$param] =& $variable; return oci_bind_by_name( $this->_sth, - $column, + $param, $variable, $length ?? -1, $this->convertParameterType($type) @@ -327,7 +347,7 @@ public function closeCursor() */ public function columnCount() { - return oci_num_fields($this->_sth); + return oci_num_fields($this->_sth) ?: 0; } /** @@ -348,7 +368,13 @@ public function errorCode() */ public function errorInfo() { - return oci_error($this->_sth); + $error = oci_error($this->_sth); + + if ($error === false) { + return []; + } + + return $error; } /** @@ -358,8 +384,9 @@ public function execute($params = null) { if ($params) { $hasZeroIndex = array_key_exists(0, $params); + foreach ($params as $key => $val) { - if ($hasZeroIndex && is_numeric($key)) { + if ($hasZeroIndex && is_int($key)) { $this->bindValue($key + 1, $val); } else { $this->bindValue($key, $val); @@ -505,6 +532,6 @@ public function fetchColumn($columnIndex = 0) */ public function rowCount() { - return oci_num_rows($this->_sth); + return oci_num_rows($this->_sth) ?: 0; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php index 2155140b2..336542ea5 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -4,7 +4,7 @@ use Doctrine\DBAL\ParameterType; use PDO; -use function count; +use function assert; use function func_get_args; /** @@ -24,7 +24,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection public function __construct($dsn, $user = null, $password = null, ?array $options = null) { try { - parent::__construct($dsn, $user, $password, $options); + parent::__construct($dsn, (string) $user, (string) $password, (array) $options); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (\PDOException $exception) { @@ -69,23 +69,13 @@ public function prepare($prepareString, $driverOptions = []) */ public function query() { - $args = func_get_args(); - $argsCount = count($args); + $args = func_get_args(); try { - if ($argsCount === 4) { - return parent::query($args[0], $args[1], $args[2], $args[3]); - } - - if ($argsCount === 3) { - return parent::query($args[0], $args[1], $args[2]); - } + $stmt = parent::query(...$args); + assert($stmt instanceof \PDOStatement); - if ($argsCount === 2) { - return parent::query($args[0], $args[1]); - } - - return parent::query($args[0]); + return $stmt; } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -105,6 +95,10 @@ public function quote($input, $type = ParameterType::STRING) public function lastInsertId($name = null) { try { + if ($name === null) { + return parent::lastInsertId(); + } + return parent::lastInsertId($name); } catch (\PDOException $exception) { throw new PDOException($exception); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php index 4291e1e17..12fb14ef5 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php @@ -49,6 +49,8 @@ private function _constructPdoDsn(array $params) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php index 59d27d384..dcd4ff518 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -62,6 +62,8 @@ protected function constructPdoDsn(array $params) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php index 972dbadcd..f25cd5cde 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -108,6 +108,8 @@ private function _constructPdoDsn(array $params) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php index 7a28b8310..d08c6a2c8 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -73,6 +73,8 @@ protected function _constructPdoDsn(array $params) /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php index 6543e3239..6d6c4844d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php @@ -16,13 +16,21 @@ class Driver extends AbstractSQLServerDriver */ public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { - [$driverOptions, $connectionOptions] = $this->splitOptions($driverOptions); + $pdoOptions = $dsnOptions = []; + + foreach ($driverOptions as $option => $value) { + if (is_int($option)) { + $pdoOptions[$option] = $value; + } else { + $dsnOptions[$option] = $value; + } + } return new Connection( - $this->_constructPdoDsn($params, $connectionOptions), + $this->_constructPdoDsn($params, $dsnOptions), $username, $password, - $driverOptions + $pdoOptions ); } @@ -57,29 +65,6 @@ private function _constructPdoDsn(array $params, array $connectionOptions) return $dsn . $this->getConnectionOptionsDsn($connectionOptions); } - /** - * Separates a connection options from a driver options - * - * @param int[]|string[] $options - * - * @return int[][]|string[][] - */ - private function splitOptions(array $options) : array - { - $driverOptions = []; - $connectionOptions = []; - - foreach ($options as $optionKey => $optionValue) { - if (is_int($optionKey)) { - $driverOptions[$optionKey] = $optionValue; - } else { - $connectionOptions[$optionKey] = $optionValue; - } - } - - return [$driverOptions, $connectionOptions]; - } - /** * Converts a connection options array to the DSN * @@ -98,6 +83,8 @@ private function getConnectionOptionsDsn(array $connectionOptions) : string /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php index 2aed89fbf..6e61d2255 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -6,6 +6,10 @@ use Doctrine\DBAL\ParameterType; use PDO; use const E_USER_DEPRECATED; +use function array_slice; +use function assert; +use function func_get_args; +use function is_array; use function sprintf; use function trigger_error; @@ -88,7 +92,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l $type = $this->convertParamType($type); try { - return parent::bindParam($column, $variable, $type, $length, $driverOptions); + return parent::bindParam($column, $variable, $type, ...array_slice(func_get_args(), 3)); } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -125,22 +129,14 @@ public function execute($params = null) */ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) { - $fetchMode = $this->convertFetchMode($fetchMode); - - try { - if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { - return parent::fetch(); - } - - if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { - return parent::fetch($fetchMode); - } + $args = func_get_args(); - if ($cursorOffset === 0) { - return parent::fetch($fetchMode, $cursorOrientation); - } + if (isset($args[0])) { + $args[0] = $this->convertFetchMode($args[0]); + } - return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset); + try { + return parent::fetch(...$args); } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -151,22 +147,27 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX */ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) { - $fetchMode = $this->convertFetchMode($fetchMode); + $args = func_get_args(); - try { - if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { - return parent::fetchAll(); - } + if (isset($args[0])) { + $args[0] = $this->convertFetchMode($args[0]); + } - if ($fetchArgument === null && $ctorArgs === null) { - return parent::fetchAll($fetchMode); - } + if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { + $args = []; + } elseif ($fetchArgument === null && $ctorArgs === null) { + $args = [$fetchMode]; + } elseif ($ctorArgs === null) { + $args = [$fetchMode, $fetchArgument]; + } else { + $args = [$fetchMode, $fetchArgument, $ctorArgs]; + } - if ($ctorArgs === null) { - return parent::fetchAll($fetchMode, $fetchArgument); - } + try { + $data = parent::fetchAll(...$args); + assert(is_array($data)); - return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs); + return $data; } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -194,7 +195,7 @@ private function convertParamType(int $type) : int if (! isset(self::PARAM_TYPE_MAP[$type])) { // TODO: next major: throw an exception @trigger_error(sprintf( - 'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0', + 'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine DBAL 3.0', $type ), E_USER_DEPRECATED); @@ -207,19 +208,15 @@ private function convertParamType(int $type) : int /** * Converts DBAL fetch mode to PDO fetch mode * - * @param int|null $fetchMode Fetch mode + * @param int $fetchMode Fetch mode */ - private function convertFetchMode(?int $fetchMode) : ?int + private function convertFetchMode(int $fetchMode) : int { - if ($fetchMode === null) { - return null; - } - if (! isset(self::FETCH_MODE_MAP[$fetchMode])) { // TODO: next major: throw an exception @trigger_error(sprintf( 'Using a PDO fetch mode or their combination (%d given)' . - ' is deprecated and will cause an error in Doctrine 3.0', + ' is deprecated and will cause an error in Doctrine DBAL 3.0', $fetchMode ), E_USER_DEPRECATED); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php index 294d5c7a5..9564dc298 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php @@ -40,6 +40,8 @@ public function connect(array $params, $username = null, $password = null, array /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php index 9f8aac060..0f8bc3e57 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php @@ -4,7 +4,6 @@ use Doctrine\DBAL\Driver\AbstractDriverException; use InvalidArgumentException; -use function is_resource; use function sasql_error; use function sasql_errorcode; use function sasql_sqlstate; @@ -28,14 +27,6 @@ class SQLAnywhereException extends AbstractDriverException */ public static function fromSQLAnywhereError($conn = null, $stmt = null) { - if ($conn !== null && ! is_resource($conn)) { - throw new InvalidArgumentException('Invalid SQL Anywhere connection resource given: ' . $conn); - } - - if ($stmt !== null && ! is_resource($stmt)) { - throw new InvalidArgumentException('Invalid SQL Anywhere statement resource given: ' . $stmt); - } - $state = $conn ? sasql_sqlstate($conn) : sasql_sqlstate(); $code = null; $message = null; diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php index 6354836a4..886bb2458 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php @@ -17,7 +17,7 @@ use function func_num_args; use function gettype; use function is_array; -use function is_numeric; +use function is_int; use function is_object; use function is_resource; use function is_string; @@ -177,9 +177,11 @@ public function execute($params = null) $hasZeroIndex = array_key_exists(0, $params); foreach ($params as $key => $val) { - $key = $hasZeroIndex && is_numeric($key) ? $key + 1 : $key; - - $this->bindValue($key, $val); + if ($hasZeroIndex && is_int($key)) { + $this->bindValue($key + 1, $val); + } else { + $this->bindValue($key, $val); + } } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php index a9be26e9d..848ab5eef 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php @@ -48,6 +48,8 @@ public function connect(array $params, $username = null, $password = null, array /** * {@inheritdoc} + * + * @deprecated */ public function getName() { diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php index f1f9ddd1d..35ad913ff 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php @@ -44,10 +44,13 @@ public function __construct($serverName, $connectionOptions) throw SQLSrvException::fromSqlSrvErrors(); } - $this->conn = sqlsrv_connect($serverName, $connectionOptions); - if (! $this->conn) { + $conn = sqlsrv_connect($serverName, $connectionOptions); + + if ($conn === false) { throw SQLSrvException::fromSqlSrvErrors(); } + + $this->conn = $conn; $this->lastInsertId = new LastInsertId(); } @@ -97,7 +100,9 @@ public function quote($value, $type = ParameterType::STRING) { if (is_int($value)) { return $value; - } elseif (is_float($value)) { + } + + if (is_float($value)) { return sprintf('%F', $value); } @@ -115,7 +120,13 @@ public function exec($statement) throw SQLSrvException::fromSqlSrvErrors(); } - return sqlsrv_rows_affected($stmt); + $rowsAffected = sqlsrv_rows_affected($stmt); + + if ($rowsAffected === false) { + throw SQLSrvException::fromSqlSrvErrors(); + } + + return $rowsAffected; } /** @@ -181,6 +192,6 @@ public function errorCode() */ public function errorInfo() { - return sqlsrv_errors(SQLSRV_ERR_ERRORS); + return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php index 796f5d129..1c1e8c472 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php @@ -16,12 +16,11 @@ class SQLSrvException extends AbstractDriverException */ public static function fromSqlSrvErrors() { - $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); $message = ''; $sqlState = null; $errorCode = null; - foreach ($errors as $error) { + foreach ((array) sqlsrv_errors(SQLSRV_ERR_ERRORS) as $error) { $message .= 'SQLSTATE [' . $error['SQLSTATE'] . ', ' . $error['code'] . ']: ' . $error['message'] . "\n"; if ($sqlState === null) { @@ -34,6 +33,7 @@ public static function fromSqlSrvErrors() $errorCode = $error['code']; } + if (! $message) { $message = 'SQL Server error occurred but no error message was retrieved from driver.'; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php index 147ef76e1..5e7016c5a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php @@ -18,6 +18,7 @@ use function count; use function func_get_args; use function in_array; +use function is_int; use function is_numeric; use function sqlsrv_errors; use function sqlsrv_execute; @@ -122,6 +123,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement /** * Append to any INSERT query to retrieve the last insert id. + * + * @deprecated This constant has been deprecated and will be made private in 3.0 */ public const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;'; @@ -179,7 +182,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l public function closeCursor() { // not having the result means there's nothing to close - if (! $this->result) { + if ($this->stmt === null || ! $this->result) { return true; } @@ -200,7 +203,11 @@ public function closeCursor() */ public function columnCount() { - return sqlsrv_num_fields($this->stmt); + if ($this->stmt === null) { + return 0; + } + + return sqlsrv_num_fields($this->stmt) ?: 0; } /** @@ -221,7 +228,7 @@ public function errorCode() */ public function errorInfo() { - return sqlsrv_errors(SQLSRV_ERR_ERRORS); + return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS); } /** @@ -231,9 +238,13 @@ public function execute($params = null) { if ($params) { $hasZeroIndex = array_key_exists(0, $params); + foreach ($params as $key => $val) { - $key = $hasZeroIndex && is_numeric($key) ? $key + 1 : $key; - $this->bindValue($key, $val); + if ($hasZeroIndex && is_int($key)) { + $this->bindValue($key + 1, $val); + } else { + $this->bindValue($key, $val); + } } } @@ -328,7 +339,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX { // do not try fetching from the statement if it's not expected to contain result // in order to prevent exceptional situation - if (! $this->result) { + if ($this->stmt === null || ! $this->result) { return false; } @@ -406,6 +417,10 @@ public function fetchColumn($columnIndex = 0) */ public function rowCount() { - return sqlsrv_rows_affected($this->stmt); + if ($this->stmt === null) { + return 0; + } + + return sqlsrv_rows_affected($this->stmt) ?: 0; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php index a3ea74a4d..388983e46 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php @@ -48,7 +48,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING); * this will be a parameter name of the form :name. For a prepared statement using * question mark placeholders, this will be the 1-indexed position of the parameter. * @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter. - * @param int|null $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType} + * @param int $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType} * constants. To return an INOUT parameter from a stored procedure, use the bitwise * OR operator to set the PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter. * @param int|null $length You must specify maxlength when using an OUT bind diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php b/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php index 5246b38a4..6b3307da2 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php @@ -6,10 +6,10 @@ class StatementIterator implements IteratorAggregate { - /** @var Statement */ + /** @var ResultStatement */ private $statement; - public function __construct(Statement $statement) + public function __construct(ResultStatement $statement) { $this->statement = $statement; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php b/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php index 658123199..6888d73b0 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php @@ -18,8 +18,10 @@ use function array_keys; use function array_map; use function array_merge; +use function assert; use function class_implements; use function in_array; +use function is_string; use function is_subclass_of; use function parse_str; use function parse_url; @@ -172,7 +174,9 @@ public static function getConnection( // check for existing pdo object if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { throw DBALException::invalidPdoInstance(); - } elseif (isset($params['pdo'])) { + } + + if (isset($params['pdo'])) { $params['pdo']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(PDO::ATTR_DRIVER_NAME); } else { @@ -263,6 +267,8 @@ private static function parseDatabaseUrl(array $params) : array // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $params['url']); + assert(is_string($url)); + $url = parse_url($url); if ($url === false) { @@ -414,6 +420,7 @@ private static function parseDatabaseUrlScheme(array $url, array $params) : arra // URL schemes must not contain underscores, but dashes are ok $driver = str_replace('-', '_', $url['scheme']); + assert(is_string($driver)); // The requested driver from the URL scheme takes precedence over the // default driver from the connection parameters. If the driver is diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php index bb0ca886d..5c71992cc 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php @@ -30,6 +30,8 @@ public function getConnection() } /** + * @deprecated Use ConnectionEventArgs::getConnection() and Connection::getDriver() instead. + * * @return Driver */ public function getDriver() @@ -38,6 +40,8 @@ public function getDriver() } /** + * @deprecated Use ConnectionEventArgs::getConnection() and Connection::getDatabasePlatform() instead. + * * @return AbstractPlatform */ public function getDatabasePlatform() @@ -46,6 +50,8 @@ public function getDatabasePlatform() } /** + * @deprecated Use ConnectionEventArgs::getConnection() and Connection::getSchemaManager() instead. + * * @return AbstractSchemaManager */ public function getSchemaManager() diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php index 2f9edfea6..ff86a93d6 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\TableDiff; use function array_merge; +use function func_get_args; use function is_array; /** @@ -57,17 +58,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php index 55661d5d3..354eb68bc 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\TableDiff; use function array_merge; +use function func_get_args; use function is_array; /** @@ -57,17 +58,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php index 8f5f0ecf5..b10bc7a60 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php @@ -5,6 +5,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\TableDiff; use function array_merge; +use function func_get_args; use function is_array; /** @@ -44,17 +45,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaAlterTableEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php index 1bc9f5901..6e3d6a757 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\TableDiff; use function array_merge; +use function func_get_args; use function is_array; /** @@ -57,17 +58,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php index 911ea8b4a..27e282531 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\TableDiff; use function array_merge; +use function func_get_args; use function is_array; /** @@ -72,17 +73,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php index 19d9f93a3..80d9abe73 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php @@ -97,6 +97,8 @@ public function getConnection() } /** + * @deprecated Use SchemaColumnDefinitionEventArgs::getConnection() and Connection::getDatabasePlatform() instead. + * * @return AbstractPlatform */ public function getDatabasePlatform() diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php index 9d24b8b90..6d78aae5c 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; use function array_merge; +use function func_get_args; use function is_array; /** @@ -57,17 +58,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php index 538617cc3..927a4e4ef 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php @@ -3,9 +3,9 @@ namespace Doctrine\DBAL\Event; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; use function array_merge; +use function func_get_args; use function is_array; /** @@ -16,7 +16,7 @@ class SchemaCreateTableEventArgs extends SchemaEventArgs /** @var Table */ private $table; - /** @var Column[] */ + /** @var mixed[][] */ private $columns; /** @var mixed[] */ @@ -29,8 +29,8 @@ class SchemaCreateTableEventArgs extends SchemaEventArgs private $sql = []; /** - * @param Column[] $columns - * @param mixed[] $options + * @param mixed[][] $columns + * @param mixed[] $options */ public function __construct(Table $table, array $columns, array $options, AbstractPlatform $platform) { @@ -49,7 +49,7 @@ public function getTable() } /** - * @return Column[] + * @return mixed[][] */ public function getColumns() { @@ -73,17 +73,15 @@ public function getPlatform() } /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * * @param string|string[] $sql * * @return \Doctrine\DBAL\Event\SchemaCreateTableEventArgs */ public function addSql($sql) { - if (is_array($sql)) { - $this->sql = array_merge($this->sql, $sql); - } else { - $this->sql[] = $sql; - } + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); return $this; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php index 900b9fbfd..387049791 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php @@ -5,7 +5,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\Table; use InvalidArgumentException; -use function is_string; /** * Event Arguments used when the SQL query for dropping tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform. @@ -28,10 +27,6 @@ class SchemaDropTableEventArgs extends SchemaEventArgs */ public function __construct($table, AbstractPlatform $platform) { - if (! $table instanceof Table && ! is_string($table)) { - throw new InvalidArgumentException('SchemaDropTableEventArgs expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); - } - $this->table = $table; $this->platform = $platform; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php b/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php index 2b5404b25..024afae28 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php @@ -10,9 +10,19 @@ class LoggerChain implements SQLLogger /** @var SQLLogger[] */ private $loggers = []; + /** + * @param SQLLogger[] $loggers + */ + public function __construct(array $loggers = []) + { + $this->loggers = $loggers; + } + /** * Adds a logger in the chain. * + * @deprecated Inject list of loggers via constructor instead + * * @return void */ public function addLogger(SQLLogger $logger) diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 5e4537391..3d833dfaa 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -27,12 +27,14 @@ use Doctrine\DBAL\Types; use Doctrine\DBAL\Types\Type; use InvalidArgumentException; +use UnexpectedValueException; use const E_USER_DEPRECATED; use function addcslashes; use function array_map; use function array_merge; use function array_unique; use function array_values; +use function assert; use function count; use function explode; use function func_get_arg; @@ -144,7 +146,7 @@ abstract class AbstractPlatform /** * Holds the KeywordList instance for the current platform. * - * @var KeywordList + * @var KeywordList|null */ protected $_keywords; @@ -486,6 +488,8 @@ public function isCommentedDoctrineType(Type $doctrineType) $this->initializeCommentedDoctrineTypes(); } + assert(is_array($this->doctrineTypeComments)); + return in_array($doctrineType->getName(), $this->doctrineTypeComments); } @@ -502,6 +506,8 @@ public function markDoctrineTypeCommented($doctrineType) $this->initializeCommentedDoctrineTypes(); } + assert(is_array($this->doctrineTypeComments)); + $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType; } @@ -518,7 +524,7 @@ public function getDoctrineTypeComment(Type $doctrineType) /** * Gets the comment of a passed column modified by potential doctrine type comment hints. * - * @return string + * @return string|null */ protected function getColumnComment(Column $column) { @@ -864,9 +870,9 @@ public function getLowerExpression($str) /** * Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str. * - * @param string $str Literal string. - * @param string $substr Literal string to find. - * @param int|bool $startPos Position to start at, beginning of string by default. + * @param string $str Literal string. + * @param string $substr Literal string to find. + * @param int|false $startPos Position to start at, beginning of string by default. * * @return string * @@ -1419,7 +1425,13 @@ public function getDropTableSQL($table) $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); if ($eventArgs->isDefaultPrevented()) { - return $eventArgs->getSql(); + $sql = $eventArgs->getSql(); + + if ($sql === null) { + throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL'); + } + + return $sql; } } @@ -1595,6 +1607,9 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE $sql = $this->_getCreateTableSQL($tableName, $columns, $options); if ($this->supportsCommentOnStatement()) { + if ($table->hasOption('comment')) { + $sql[] = $this->getCommentOnTableSQL($tableName, $table->getOption('comment')); + } foreach ($table->getColumns() as $column) { $comment = $this->getColumnComment($column); @@ -1609,10 +1624,21 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE return array_merge($sql, $columnSql); } + protected function getCommentOnTableSQL(string $tableName, ?string $comment) : string + { + $tableName = new Identifier($tableName); + + return sprintf( + 'COMMENT ON TABLE %s IS %s', + $tableName->getQuotedName($this), + $this->quoteStringLiteral((string) $comment) + ); + } + /** - * @param string $tableName - * @param string $columnName - * @param string $comment + * @param string $tableName + * @param string $columnName + * @param string|null $comment * * @return string */ @@ -1620,13 +1646,12 @@ public function getCommentOnColumnSQL($tableName, $columnName, $comment) { $tableName = new Identifier($tableName); $columnName = new Identifier($columnName); - $comment = $this->quoteStringLiteral($comment); return sprintf( 'COMMENT ON COLUMN %s.%s IS %s', $tableName->getQuotedName($this), $columnName->getQuotedName($this), - $comment + $this->quoteStringLiteral((string) $comment) ); } @@ -1833,6 +1858,10 @@ protected function getCreateIndexSQLFlags(Index $index) */ public function getCreatePrimaryKeySQL(Index $index, $table) { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; } @@ -2067,11 +2096,14 @@ protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) */ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) { - $tableName = $diff->newName !== false - ? $diff->getNewName()->getQuotedName($this) - : $diff->getName($this)->getQuotedName($this); + $sql = []; + $newName = $diff->getNewName(); - $sql = []; + if ($newName !== false) { + $tableName = $newName->getQuotedName($this); + } else { + $tableName = $diff->getName($this)->getQuotedName($this); + } if ($this->supportsForeignKeyConstraints()) { foreach ($diff->addedForeignKeys as $foreignKey) { @@ -2122,6 +2154,8 @@ protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) /** * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions. * + * @deprecated + * * @return string[] */ protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff) @@ -2293,14 +2327,14 @@ public function getDefaultValueDeclarationSQL($field) return " DEFAULT '" . $this->convertBooleans($default) . "'"; } - return " DEFAULT '" . $default . "'"; + return ' DEFAULT ' . $this->quoteStringLiteral($default); } /** * Obtains DBMS specific SQL code portion needed to set a CHECK constraint * declaration to be used in statements like CREATE TABLE. * - * @param mixed[][] $definition The check definition. + * @param string[]|mixed[][] $definition The check definition. * * @return string DBMS specific SQL code portion needed to set a CHECK constraint. */ @@ -2950,7 +2984,6 @@ public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration); } - /** * Obtains DBMS specific SQL to be used to create date fields in statements * like CREATE TABLE. @@ -3154,7 +3187,7 @@ public function supportsForeignKeyConstraints() */ public function supportsForeignKeyOnUpdate() { - return $this->supportsForeignKeyConstraints() && true; + return $this->supportsForeignKeyConstraints(); } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php index 605122115..25d4163b6 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -6,9 +6,9 @@ use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Identifier; use Doctrine\DBAL\Schema\Index; -use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use function array_merge; use function count; use function current; @@ -97,7 +97,7 @@ public function initializeDoctrineTypeMappings() */ public function isCommentedDoctrineType(Type $doctrineType) { - if ($doctrineType->getName() === Type::BOOLEAN) { + if ($doctrineType->getName() === Types::BOOLEAN) { // We require a commented boolean type in order to distinguish between boolean and smallint // as both (have to) map to the same native type. return true; @@ -502,6 +502,7 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options foreach ($indexes as $definition) { $sqls[] = $this->getCreateIndexSQL($definition, $tableName); } + return $sqls; } @@ -571,7 +572,7 @@ public function getAlterTableSQL(TableDiff $diff) } } - $this->gatherAlterColumnSQL($diff->fromTable, $columnDiff, $sql, $queryParts); + $this->gatherAlterColumnSQL($diff->getName($this), $columnDiff, $sql, $queryParts); } foreach ($diff->renamedColumns as $oldColumnName => $column) { @@ -599,8 +600,14 @@ public function getAlterTableSQL(TableDiff $diff) $sql = array_merge($sql, $commentsSQL); - if ($diff->newName !== false) { - $sql[] = 'RENAME TABLE ' . $diff->getName($this)->getQuotedName($this) . ' TO ' . $diff->getNewName()->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $sql[] = sprintf( + 'RENAME TABLE %s TO %s', + $diff->getName($this)->getQuotedName($this), + $newName->getQuotedName($this) + ); } $sql = array_merge( @@ -616,12 +623,12 @@ public function getAlterTableSQL(TableDiff $diff) /** * Gathers the table alteration SQL for a given column diff. * - * @param Table $table The table to gather the SQL for. + * @param Identifier $table The table to gather the SQL for. * @param ColumnDiff $columnDiff The column diff to evaluate. * @param string[] $sql The sequence of table alteration statements to fill. * @param mixed[] $queryParts The sequence of column alteration clauses to fill. */ - private function gatherAlterColumnSQL(Table $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts) + private function gatherAlterColumnSQL(Identifier $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts) { $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); @@ -893,4 +900,17 @@ protected function getReservedKeywordsClass() { return Keywords\DB2Keywords::class; } + + public function getListTableCommentsSQL(string $table) : string + { + return sprintf( + <<<'SQL' +SELECT REMARKS + FROM SYSIBM.SYSTABLES + WHERE NAME = UPPER( %s ) +SQL + , + $this->quoteStringLiteral($table) + ); + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php index 27aacf422..8f6f09663 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php @@ -47,9 +47,7 @@ public function getIdentifierQuoteCharacter() */ public function getConcatExpression() { - $args = func_get_args(); - - return 'CONCAT(' . implode(', ', (array) $args) . ')'; + return 'CONCAT(' . implode(', ', func_get_args()) . ')'; } /** @@ -480,8 +478,10 @@ public function getAlterTableSQL(TableDiff $diff) $columnSql = []; $queryParts = []; - if ($diff->newName !== false) { - $queryParts[] = 'RENAME TO ' . $diff->getNewName()->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $queryParts[] = 'RENAME TO ' . $newName->getQuotedName($this); } foreach ($diff->addedColumns as $column) { @@ -576,7 +576,7 @@ public function convertBooleans($item) { if (is_array($item)) { foreach ($item as $key => $value) { - if (! is_bool($value) && ! is_numeric($item)) { + if (! is_bool($value) && ! is_numeric($value)) { continue; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL80Keywords.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL80Keywords.php index 4b595d53a..ec1562d24 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL80Keywords.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL80Keywords.php @@ -28,6 +28,7 @@ protected function getKeywords() $keywords = array_merge($keywords, [ 'ADMIN', + 'ARRAY', 'CUBE', 'CUME_DIST', 'DENSE_RANK', @@ -40,7 +41,9 @@ protected function getKeywords() 'JSON_TABLE', 'LAG', 'LAST_VALUE', + 'LATERAL', 'LEAD', + 'MEMBER', 'NTH_VALUE', 'NTILE', 'OF', diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php index 25420a047..6c57082c5 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php @@ -2,7 +2,7 @@ namespace Doctrine\DBAL\Platforms; -use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; /** * Provides the behavior, features and SQL dialect of the MariaDB 10.2 (10.2.7 GA) database platform. @@ -36,6 +36,6 @@ protected function initializeDoctrineTypeMappings() : void { parent::initializeDoctrineTypeMappings(); - $this->doctrineTypeMapping['json'] = Type::JSON; + $this->doctrineTypeMapping['json'] = Types::JSON; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php index 71ef6ca96..1db7d6689 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php @@ -4,7 +4,7 @@ use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\TableDiff; -use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; /** * Provides the behavior, features and SQL dialect of the MySQL 5.7 (5.7.9 GA) database platform. @@ -66,6 +66,6 @@ protected function initializeDoctrineTypeMappings() { parent::initializeDoctrineTypeMappings(); - $this->doctrineTypeMapping['json'] = Type::JSON; + $this->doctrineTypeMapping['json'] = Types::JSON; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 98228fc50..57c448ce9 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -154,11 +154,10 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) $currentDatabase = $this->quoteStringLiteral($currentDatabase); $table = $this->quoteStringLiteral($table); - return 'SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ' . - 'SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ' . - 'CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, ' . - 'NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment ' . - 'FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $table . ' AND TABLE_SCHEMA = ' . $currentDatabase . + return 'SELECT NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, COLUMN_NAME AS Column_Name,' . + ' SUB_PART AS Sub_Part, INDEX_TYPE AS Index_Type' . + ' FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $table . + ' AND TABLE_SCHEMA = ' . $currentDatabase . ' ORDER BY SEQ_IN_INDEX ASC'; } @@ -504,7 +503,7 @@ private function buildTableOptions(array $options) $options['collate'] = $options['charset'] . '_unicode_ci'; } - $tableOptions[] = sprintf('COLLATE %s', $options['collate']); + $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collate']); // Engine if (! isset($options['engine'])) { @@ -520,9 +519,7 @@ private function buildTableOptions(array $options) // Comment if (isset($options['comment'])) { - $comment = trim($options['comment'], " '"); - - $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($comment)); + $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($options['comment'])); } // Row format @@ -554,8 +551,10 @@ public function getAlterTableSQL(TableDiff $diff) { $columnSql = []; $queryParts = []; - if ($diff->newName !== false) { - $queryParts[] = 'RENAME TO ' . $diff->getNewName()->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $queryParts[] = 'RENAME TO ' . $newName->getQuotedName($this); } foreach ($diff->addedColumns as $column) { @@ -613,6 +612,17 @@ public function getAlterTableSQL(TableDiff $diff) $keyColumns = array_unique(array_values($diff->addedIndexes['primary']->getColumns())); $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')'; unset($diff->addedIndexes['primary']); + } elseif (isset($diff->changedIndexes['primary'])) { + // Necessary in case the new primary key includes a new auto_increment column + foreach ($diff->changedIndexes['primary']->getColumns() as $columnName) { + if (isset($diff->addedColumns[$columnName]) && $diff->addedColumns[$columnName]->getAutoincrement()) { + $keyColumns = array_unique(array_values($diff->changedIndexes['primary']->getColumns())); + $queryParts[] = 'DROP PRIMARY KEY'; + $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')'; + unset($diff->changedIndexes['primary']); + break; + } + } } $sql = []; @@ -845,10 +855,14 @@ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) */ protected function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff) { - $sql = []; - $tableName = $diff->newName !== false - ? $diff->getNewName()->getQuotedName($this) - : $diff->getName($this)->getQuotedName($this); + $sql = []; + $newName = $diff->getNewName(); + + if ($newName !== false) { + $tableName = $newName->getQuotedName($this); + } else { + $tableName = $diff->getName($this)->getQuotedName($this); + } foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { if (in_array($foreignKey, $diff->changedForeignKeys, true)) { @@ -943,6 +957,22 @@ protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) return $this->getUnsignedDeclaration($columnDef) . $autoinc; } + /** + * {@inheritDoc} + */ + public function getColumnCharsetDeclarationSQL($charset) + { + return 'CHARACTER SET ' . $charset; + } + + /** + * {@inheritDoc} + */ + public function getColumnCollationDeclarationSQL($collation) + { + return 'COLLATE ' . $this->quoteSingleIdentifier($collation); + } + /** * {@inheritDoc} */ diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 537a566ba..21b13a2d6 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -201,9 +201,13 @@ private function getSequenceCacheSQL(Sequence $sequence) { if ($sequence->getCache() === 0) { return ' NOCACHE'; - } elseif ($sequence->getCache() === 1) { + } + + if ($sequence->getCache() === 1) { return ' NOCACHE'; - } elseif ($sequence->getCache() > 1) { + } + + if ($sequence->getCache() > 1) { return ' CACHE ' . $sequence->getCache(); } @@ -869,8 +873,14 @@ public function getAlterTableSQL(TableDiff $diff) if (! $this->onSchemaAlterTable($diff, $tableSql)) { $sql = array_merge($sql, $commentsSQL); - if ($diff->newName !== false) { - $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $diff->getName($this)->getQuotedName($this), + $newName->getQuotedName($this) + ); } $sql = array_merge( @@ -1172,4 +1182,25 @@ public function getBlobTypeDeclarationSQL(array $field) { return 'BLOB'; } + + public function getListTableCommentsSQL(string $table, ?string $database = null) : string + { + $tableCommentsName = 'user_tab_comments'; + $ownerCondition = ''; + + if ($database !== null && $database !== '/') { + $tableCommentsName = 'all_tab_comments'; + $ownerCondition = ' AND owner = ' . $this->quoteStringLiteral($this->normalizeIdentifier($database)->getName()); + } + + return sprintf( + <<<'SQL' +SELECT comments FROM %s WHERE table_name = %s%s +SQL + , + $tableCommentsName, + $this->quoteStringLiteral($this->normalizeIdentifier($table)->getName()), + $ownerCondition + ); + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php index b302c0ceb..170305614 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php @@ -2,7 +2,7 @@ namespace Doctrine\DBAL\Platforms; -use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use function sprintf; /** @@ -53,7 +53,7 @@ protected function initializeDoctrineTypeMappings() { parent::initializeDoctrineTypeMappings(); - $this->doctrineTypeMapping['json'] = Type::JSON; + $this->doctrineTypeMapping['json'] = Types::JSON; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php index 9db0ecbbd..fb559dea2 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php @@ -2,7 +2,7 @@ namespace Doctrine\DBAL\Platforms; -use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; /** * Provides the behavior, features and SQL dialect of the PostgreSQL 9.4 database platform. @@ -36,6 +36,6 @@ protected function initializeDoctrineTypeMappings() { parent::initializeDoctrineTypeMappings(); - $this->doctrineTypeMapping['jsonb'] = Type::JSON; + $this->doctrineTypeMapping['jsonb'] = Types::JSON; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index cb4603f51..e570dc04a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -614,8 +614,14 @@ public function getAlterTableSQL(TableDiff $diff) if (! $this->onSchemaAlterTable($diff, $tableSql)) { $sql = array_merge($sql, $commentsSQL); - if ($diff->newName !== false) { - $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $diff->getName($this)->getQuotedName($this), + $newName->getQuotedName($this) + ); } $sql = array_merge( @@ -815,7 +821,7 @@ private function convertSingleBooleanValue($value, $callback) } if (is_bool($value) || is_numeric($value)) { - return $callback($value ? true : false); + return $callback((bool) $value); } if (! is_string($value)) { @@ -1215,7 +1221,8 @@ public function getDefaultValueDeclarationSQL($field) */ private function isSerialField(array $field) : bool { - return $field['autoincrement'] ?? false === true && isset($field['type']) + return isset($field['type'], $field['autoincrement']) + && $field['autoincrement'] === true && $this->isNumericType($field['type']); } @@ -1245,4 +1252,19 @@ private function getOldColumnComment(ColumnDiff $columnDiff) : ?string { return $columnDiff->fromColumn ? $this->getColumnComment($columnDiff->fromColumn) : null; } + + public function getListTableMetadataSQL(string $table, ?string $schema = null) : string + { + if ($schema !== null) { + $table = $schema . '.' . $table; + } + + return sprintf( + <<<'SQL' +SELECT obj_description(%s::regclass) AS table_comment; +SQL + , + $this->quoteStringLiteral($table) + ); + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php index ec3ef9334..6e3b2fcb9 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -23,7 +23,7 @@ use function get_class; use function implode; use function is_string; -use function preg_replace; +use function preg_match; use function sprintf; use function strlen; use function strpos; @@ -184,9 +184,11 @@ public function getAlterTableSQL(TableDiff $diff) $sql = array_merge($sql, $commentsSQL); - if ($diff->newName !== false) { + $newName = $diff->getNewName(); + + if ($newName !== false) { $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . - $this->getAlterTableRenameTableClause($diff->getNewName()); + $this->getAlterTableRenameTableClause($newName); } $sql = array_merge( @@ -625,12 +627,15 @@ public function getForeignKeyMatchClauseSQL($type) switch ((int) $type) { case self::FOREIGN_KEY_MATCH_SIMPLE: return 'SIMPLE'; + break; case self::FOREIGN_KEY_MATCH_FULL: return 'FULL'; + break; case self::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE: return 'UNIQUE SIMPLE'; + break; case self::FOREIGN_KEY_MATCH_FULL_UNIQUE: return 'UNIQUE FULL'; @@ -1310,9 +1315,15 @@ protected function doModifyLimitQuery($query, $limit, $offset) { $limitOffsetClause = $this->getTopClauseSQL($limit, $offset); - return $limitOffsetClause === '' - ? $query - : preg_replace('/^\s*(SELECT\s+(DISTINCT\s+)?)/i', '\1' . $limitOffsetClause . ' ', $query); + if ($limitOffsetClause === '') { + return $query; + } + + if (! preg_match('/^\s*(SELECT\s+(DISTINCT\s+)?)(.*)/i', $query, $matches)) { + return $query; + } + + return $matches[1] . $limitOffsetClause . ' ' . $matches[3]; } private function getTopClauseSQL(?int $limit, ?int $offset) : string diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php index dc8775e61..a37f7c939 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -10,7 +10,6 @@ use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; -use Doctrine\DBAL\Types; use InvalidArgumentException; use function array_merge; use function array_unique; @@ -26,7 +25,6 @@ use function is_numeric; use function is_string; use function preg_match; -use function preg_replace; use function sprintf; use function str_replace; use function stripos; @@ -249,6 +247,11 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options $defaultConstraintsSql = []; $commentsSql = []; + $tableComment = $options['comment'] ?? null; + if ($tableComment !== null) { + $commentsSql[] = $this->getCommentOnTableSQL($tableName, $tableComment); + } + // @todo does other code breaks because of this? // force primary keys to be not null foreach ($columns as &$column) { @@ -315,12 +318,19 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options */ public function getCreatePrimaryKeySQL(Index $index, $table) { - $flags = ''; + if ($table instanceof Table) { + $identifier = $table->getQuotedName($this); + } else { + $identifier = $table; + } + + $sql = 'ALTER TABLE ' . $identifier . ' ADD PRIMARY KEY'; + if ($index->hasFlag('nonclustered')) { - $flags = ' NONCLUSTERED'; + $sql .= ' NONCLUSTERED'; } - return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + return $sql . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; } /** @@ -334,9 +344,9 @@ public function getCreatePrimaryKeySQL(Index $index, $table) * as column comments are stored in the same property there when * specifying a column's "Description" attribute. * - * @param string $tableName The quoted table name to which the column belongs. - * @param string $columnName The quoted column name to create the comment for. - * @param string $comment The column's comment. + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to create the comment for. + * @param string|null $comment The column's comment. * * @return string */ @@ -584,8 +594,10 @@ public function getAlterTableSQL(TableDiff $diff) $sql = array_merge($sql, $commentsSql); - if ($diff->newName !== false) { - $sql[] = "sp_RENAME '" . $diff->getName($this)->getQuotedName($this) . "', '" . $diff->getNewName()->getName() . "'"; + $newName = $diff->getNewName(); + + if ($newName !== false) { + $sql[] = "sp_RENAME '" . $diff->getName($this)->getQuotedName($this) . "', '" . $newName->getName() . "'"; /** * Rename table's default constraints names @@ -598,10 +610,10 @@ public function getAlterTableSQL(TableDiff $diff) $sql[] = "DECLARE @sql NVARCHAR(MAX) = N''; " . "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' " . "+ REPLACE(dc.name, '" . $this->generateIdentifierName($diff->name) . "', " . - "'" . $this->generateIdentifierName($diff->newName) . "') + ''', ''OBJECT'';' " . + "'" . $this->generateIdentifierName($newName->getName()) . "') + ''', ''OBJECT'';' " . 'FROM sys.default_constraints dc ' . 'JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id ' . - "WHERE tbl.name = '" . $diff->getNewName()->getName() . "';" . + "WHERE tbl.name = '" . $newName->getName() . "';" . 'EXEC sp_executesql @sql'; } @@ -691,9 +703,9 @@ private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff * as column comments are stored in the same property there when * specifying a column's "Description" attribute. * - * @param string $tableName The quoted table name to which the column belongs. - * @param string $columnName The quoted column name to alter the comment for. - * @param string $comment The column's comment. + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to alter the comment for. + * @param string|null $comment The column's comment. * * @return string */ @@ -799,10 +811,10 @@ public function getAddExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_addextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -831,9 +843,9 @@ public function getDropExtendedPropertySQL( ) { return 'EXEC sp_dropextendedproperty ' . 'N' . $this->quoteStringLiteral($name) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -863,10 +875,10 @@ public function getUpdateExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_updateextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -1270,9 +1282,11 @@ protected function doModifyLimitQuery($query, $limit, $offset = null) // Even if the TOP n is very large, the use of a CTE will // allow the SQL Server query planner to optimize it so it doesn't // actually scan the entire range covered by the TOP clause. - $selectPattern = '/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im'; - $replacePattern = sprintf('$1%s $2', $top); - $query = preg_replace($selectPattern, $replacePattern, $query); + if (! preg_match('/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/is', $query, $matches)) { + return $query; + } + + $query = $matches[1] . $top . ' ' . $matches[2]; if (stristr($query, 'ORDER BY')) { // Inner order by is not valid in SQL Server for our purposes @@ -1339,6 +1353,7 @@ private function scrubInnerOrderBy($query) $query = substr($query, 0, $orderByPos) . substr($query, $currentPosition - 1); $offset = $orderByPos; } + return $query; } @@ -1389,7 +1404,7 @@ public function convertBooleans($item) { if (is_array($item)) { foreach ($item as $key => $value) { - if (! is_bool($value) && ! is_numeric($item)) { + if (! is_bool($value) && ! is_numeric($value)) { continue; } @@ -1591,36 +1606,6 @@ public function getBlobTypeDeclarationSQL(array $field) return 'VARBINARY(MAX)'; } - /** - * {@inheritDoc} - */ - public function getDefaultValueDeclarationSQL($field) - { - if (! isset($field['default'])) { - return empty($field['notnull']) ? ' NULL' : ''; - } - - if (! isset($field['type'])) { - return " DEFAULT '" . $field['default'] . "'"; - } - - $type = $field['type']; - - if ($type instanceof Types\PhpIntegerMappingType) { - return ' DEFAULT ' . $field['default']; - } - - if ($type instanceof Types\PhpDateTimeMappingType && $field['default'] === $this->getCurrentTimestampSQL()) { - return ' DEFAULT ' . $this->getCurrentTimestampSQL(); - } - - if ($type instanceof Types\BooleanType) { - return " DEFAULT '" . $this->convertBooleans($field['default']) . "'"; - } - - return " DEFAULT '" . $field['default'] . "'"; - } - /** * {@inheritdoc} * @@ -1676,4 +1661,35 @@ private function generateIdentifierName($identifier) return strtoupper(dechex(crc32($identifier->getName()))); } + + protected function getCommentOnTableSQL(string $tableName, ?string $comment) : string + { + return sprintf( + <<<'SQL' +EXEC sys.sp_addextendedproperty @name=N'MS_Description', + @value=N%s, @level0type=N'SCHEMA', @level0name=N'dbo', + @level1type=N'TABLE', @level1name=N%s +SQL + , + $this->quoteStringLiteral((string) $comment), + $this->quoteStringLiteral($tableName) + ); + } + + public function getListTableMetadataSQL(string $table) : string + { + return sprintf( + <<<'SQL' +SELECT + p.value AS [table_comment] +FROM + sys.tables AS tbl + INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1 +WHERE + (tbl.name=N%s and SCHEMA_NAME(tbl.schema_id)=N'dbo' and p.name=N'MS_Description') +SQL + , + $this->quoteStringLiteral($table) + ); + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 819421d34..02d2482c8 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -23,6 +23,7 @@ use function strlen; use function strpos; use function strtolower; +use function trim; /** * The SqlitePlatform class describes the specifics and dialects of the SQLite @@ -332,7 +333,14 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] } } - $query = ['CREATE TABLE ' . $name . ' (' . $queryFields . ')']; + $tableComment = ''; + if (isset($options['comment'])) { + $comment = trim($options['comment'], " '"); + + $tableComment = $this->getInlineTableCommentSQL($comment); + } + + $query = ['CREATE TABLE ' . $name . ' ' . $tableComment . '(' . $queryFields . ')']; if (isset($options['alter']) && $options['alter'] === true) { return $query; @@ -356,8 +364,8 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] /** * Generate a PRIMARY KEY definition if no autoincrement value is used * - * @param string[] $columns - * @param mixed[] $options + * @param mixed[][] $columns + * @param mixed[] $options */ private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $options) : string { @@ -368,7 +376,7 @@ private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $ $keyColumns = array_unique(array_values($options['primary'])); foreach ($keyColumns as $keyColumn) { - if (isset($columns[$keyColumn]['autoincrement']) && ! empty($columns[$keyColumn]['autoincrement'])) { + if (! empty($columns[$keyColumn]['autoincrement'])) { return ''; } } @@ -605,6 +613,11 @@ public function getInlineColumnCommentSQL($comment) return '--' . str_replace("\n", "\n--", $comment) . "\n"; } + private function getInlineTableCommentSQL(string $comment) : string + { + return $this->getInlineColumnCommentSQL($comment); + } + /** * {@inheritDoc} */ @@ -685,7 +698,12 @@ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) } $sql = []; - $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this); + $tableName = $diff->getNewName(); + + if ($tableName === false) { + $tableName = $diff->getName($this); + } + foreach ($this->getIndexesInAlteredTable($diff) as $index) { if ($index->isPrimary()) { continue; @@ -908,9 +926,14 @@ public function getAlterTableSQL(TableDiff $diff) $sql[] = sprintf('INSERT INTO %s (%s) SELECT %s FROM %s', $newTable->getQuotedName($this), implode(', ', $newColumnNames), implode(', ', $oldColumnNames), $dataTable->getQuotedName($this)); $sql[] = $this->getDropTableSQL($dataTable); - if ($diff->newName && $diff->newName !== $diff->name) { - $renamedTable = $diff->getNewName(); - $sql[] = 'ALTER TABLE ' . $newTable->getQuotedName($this) . ' RENAME TO ' . $renamedTable->getQuotedName($this); + $newName = $diff->getNewName(); + + if ($newName !== false) { + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $newTable->getQuotedName($this), + $newName->getQuotedName($this) + ); } $sql = array_merge($sql, $this->getPostAlterTableIndexForeignKeySQL($diff)); @@ -1028,7 +1051,8 @@ private function getColumnNamesInAlteredTable(TableDiff $diff) $columns[strtolower($columnName)] = $columnName; } - foreach ($diff->addedColumns as $columnName => $column) { + foreach ($diff->addedColumns as $column) { + $columnName = $column->getName(); $columns[strtolower($columnName)] = $columnName; } @@ -1059,12 +1083,14 @@ private function getIndexesInAlteredTable(TableDiff $diff) if (! isset($columnNames[$normalizedColumnName])) { unset($indexes[$key]); continue 2; - } else { - $indexColumns[] = $columnNames[$normalizedColumnName]; - if ($columnName !== $columnNames[$normalizedColumnName]) { - $changed = true; - } } + + $indexColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName === $columnNames[$normalizedColumnName]) { + continue; + } + + $changed = true; } if (! $changed) { @@ -1111,12 +1137,14 @@ private function getForeignKeysInAlteredTable(TableDiff $diff) if (! isset($columnNames[$normalizedColumnName])) { unset($foreignKeys[$key]); continue 2; - } else { - $localColumns[] = $columnNames[$normalizedColumnName]; - if ($columnName !== $columnNames[$normalizedColumnName]) { - $changed = true; - } } + + $localColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName === $columnNames[$normalizedColumnName]) { + continue; + } + + $changed = true; } if (! $changed) { @@ -1127,6 +1155,10 @@ private function getForeignKeysInAlteredTable(TableDiff $diff) } foreach ($diff->removedForeignKeys as $constraint) { + if (! $constraint instanceof ForeignKeyConstraint) { + $constraint = new Identifier($constraint); + } + $constraintName = strtolower($constraint->getName()); if (! strlen($constraintName) || ! isset($foreignKeys[$constraintName])) { continue; diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php b/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php index 32186dcb0..7b4af8a87 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php @@ -121,9 +121,9 @@ public function prepare($statement) */ public function query() { - $this->connect(); + $connection = $this->getWrappedConnection(); - $stmt = $this->_conn->query(...func_get_args()); + $stmt = $connection->query(...func_get_args()); $stmt = new Statement($stmt, $this); $stmt->setFetchMode($this->defaultFetchMode); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php b/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php index 1499ff1bf..514b3be2d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php @@ -2,6 +2,7 @@ namespace Doctrine\DBAL\Portability; +use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\FetchMode; @@ -9,6 +10,7 @@ use IteratorAggregate; use PDO; use function array_change_key_case; +use function assert; use function is_string; use function rtrim; @@ -20,7 +22,7 @@ class Statement implements IteratorAggregate, DriverStatement /** @var int */ private $portability; - /** @var DriverStatement */ + /** @var DriverStatement|ResultStatement */ private $stmt; /** @var int */ @@ -32,7 +34,7 @@ class Statement implements IteratorAggregate, DriverStatement /** * Wraps Statement and applies portability measures. * - * @param DriverStatement $stmt + * @param DriverStatement|ResultStatement $stmt */ public function __construct($stmt, Connection $conn) { @@ -46,6 +48,8 @@ public function __construct($stmt, Connection $conn) */ public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->bindParam($column, $variable, $type, $length); } @@ -54,6 +58,8 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l */ public function bindValue($param, $value, $type = ParameterType::STRING) { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->bindValue($param, $value, $type); } @@ -78,6 +84,8 @@ public function columnCount() */ public function errorCode() { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->errorCode(); } @@ -86,6 +94,8 @@ public function errorCode() */ public function errorInfo() { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->errorInfo(); } @@ -94,6 +104,8 @@ public function errorInfo() */ public function execute($params = null) { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->execute($params); } @@ -228,6 +240,8 @@ public function fetchColumn($columnIndex = 0) */ public function rowCount() { + assert($this->stmt instanceof DriverStatement); + return $this->stmt->rowCount(); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php b/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php index 91f370aec..dfcc31ec7 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php @@ -286,8 +286,8 @@ public function notIn($x, $y) /** * Quotes a given input parameter. * - * @param mixed $input The parameter to be quoted. - * @param string|null $type The type of the parameter. + * @param mixed $input The parameter to be quoted. + * @param int|null $type The type of the parameter. * * @return string */ diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php b/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php index 12584d960..587e26656 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php @@ -52,22 +52,28 @@ class QueryBuilder */ private $connection; + /* + * The default values of SQL parts collection + */ + private const SQL_PARTS_DEFAULTS = [ + 'select' => [], + 'distinct' => false, + 'from' => [], + 'join' => [], + 'set' => [], + 'where' => null, + 'groupBy' => [], + 'having' => null, + 'orderBy' => [], + 'values' => [], + ]; + /** * The array of SQL parts collected. * * @var mixed[] */ - private $sqlParts = [ - 'select' => [], - 'from' => [], - 'join' => [], - 'set' => [], - 'where' => null, - 'groupBy' => [], - 'having' => null, - 'orderBy' => [], - 'values' => [], - ]; + private $sqlParts = self::SQL_PARTS_DEFAULTS; /** * The complete SQL string for this query. @@ -403,7 +409,7 @@ public function getMaxResults() * 'groupBy', 'having' and 'orderBy'. * * @param string $sqlPartName - * @param string $sqlPart + * @param mixed $sqlPart * @param bool $append * * @return $this This QueryBuilder instance. @@ -469,6 +475,25 @@ public function select($select = null) return $this->add('select', $selects); } + /** + * Adds DISTINCT to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->distinct() + * ->from('users', 'u') + * + * + * @return $this This QueryBuilder instance. + */ + public function distinct() : self + { + $this->sqlParts['distinct'] = true; + + return $this; + } + /** * Adds an item that is to be returned in the query result. * @@ -504,7 +529,7 @@ public function addSelect($select = null) * * $qb = $conn->createQueryBuilder() * ->delete('users', 'u') - * ->where('u.id = :user_id'); + * ->where('u.id = :user_id') * ->setParameter(':user_id', 1); * * @@ -866,7 +891,6 @@ public function groupBy($groupBy) return $this->add('groupBy', $groupBy, false); } - /** * Adds a grouping expression to the query. * @@ -874,8 +898,8 @@ public function groupBy($groupBy) * $qb = $conn->createQueryBuilder() * ->select('u.name') * ->from('users', 'u') - * ->groupBy('u.lastLogin'); - * ->addGroupBy('u.createdAt') + * ->groupBy('u.lastLogin') + * ->addGroupBy('u.createdAt'); * * * @param mixed $groupBy The grouping expression. @@ -1084,8 +1108,7 @@ public function resetQueryParts($queryPartNames = null) */ public function resetQueryPart($queryPartName) { - $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName]) - ? [] : null; + $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName]; $this->state = self::STATE_DIRTY; @@ -1099,7 +1122,8 @@ public function resetQueryPart($queryPartName) */ private function getSQLForSelect() { - $query = 'SELECT ' . implode(', ', $this->sqlParts['select']); + $query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') . + implode(', ', $this->sqlParts['select']); $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') @@ -1188,6 +1212,7 @@ private function getSQLForInsert() private function getSQLForUpdate() { $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + return 'UPDATE ' . $table . ' SET ' . implode(', ', $this->sqlParts['set']) . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); @@ -1201,6 +1226,7 @@ private function getSQLForUpdate() private function getSQLForDelete() { $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + return 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/README.markdown b/doctrine/dbal/lib/Doctrine/DBAL/README.markdown deleted file mode 100644 index e69de29bb..000000000 diff --git a/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php b/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php index 537cd9e48..976888384 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php @@ -24,49 +24,93 @@ */ class SQLParserUtils { + /**#@+ + * + * @deprecated Will be removed as internal implementation details. + */ public const POSITIONAL_TOKEN = '\?'; public const NAMED_TOKEN = '(? integer pair (indexed from zero) for a positional statement - * and a string => int[] pair for a named statement. + * For a statement with positional parameters, returns a zero-indexed list of placeholder position. + * For a statement with named parameters, returns a map of placeholder positions to their parameter names. + * + * @deprecated Will be removed as internal implementation detail. * * @param string $statement * @param bool $isPositional * - * @return int[] + * @return int[]|string[] */ public static function getPlaceholderPositions($statement, $isPositional = true) { - $match = $isPositional ? '?' : ':'; + return $isPositional + ? self::getPositionalPlaceholderPositions($statement) + : self::getNamedPlaceholderPositions($statement); + } + + /** + * Returns a zero-indexed list of placeholder position. + * + * @return int[] + */ + private static function getPositionalPlaceholderPositions(string $statement) : array + { + return self::collectPlaceholders( + $statement, + '?', + self::POSITIONAL_TOKEN, + static function (string $_, int $placeholderPosition, int $fragmentPosition, array &$carry) : void { + $carry[] = $placeholderPosition + $fragmentPosition; + } + ); + } + + /** + * Returns a map of placeholder positions to their parameter names. + * + * @return string[] + */ + private static function getNamedPlaceholderPositions(string $statement) : array + { + return self::collectPlaceholders( + $statement, + ':', + self::NAMED_TOKEN, + static function (string $placeholder, int $placeholderPosition, int $fragmentPosition, array &$carry) : void { + $carry[$placeholderPosition + $fragmentPosition] = substr($placeholder, 1); + } + ); + } + + /** + * @return mixed[] + */ + private static function collectPlaceholders(string $statement, string $match, string $token, callable $collector) : array + { if (strpos($statement, $match) === false) { return []; } - $token = $isPositional ? self::POSITIONAL_TOKEN : self::NAMED_TOKEN; - $paramMap = []; + $carry = []; foreach (self::getUnquotedStatementFragments($statement) as $fragment) { preg_match_all('/' . $token . '/', $fragment[0], $matches, PREG_OFFSET_CAPTURE); foreach ($matches[0] as $placeholder) { - if ($isPositional) { - $paramMap[] = $placeholder[1] + $fragment[1]; - } else { - $pos = $placeholder[1] + $fragment[1]; - $paramMap[$pos] = substr($placeholder[0], 1, strlen($placeholder[0])); - } + $collector($placeholder[0], $placeholder[1], $fragment[1], $carry); } } - return $paramMap; + return $carry; } /** @@ -109,14 +153,14 @@ public static function expandListParameters($query, $params, $types) return [$query, $params, $types]; } - $paramPos = self::getPlaceholderPositions($query, $isPositional); - if ($isPositional) { $paramOffset = 0; $queryOffset = 0; $params = array_values($params); $types = array_values($types); + $paramPos = self::getPositionalPlaceholderPositions($query); + foreach ($paramPos as $needle => $needlePos) { if (! isset($arrayPositions[$needle])) { continue; @@ -156,6 +200,8 @@ public static function expandListParameters($query, $params, $types) $typesOrd = []; $paramsOrd = []; + $paramPos = self::getNamedPlaceholderPositions($query); + foreach ($paramPos as $pos => $paramName) { $paramLen = strlen($paramName) + 1; $value = static::extractParam($paramName, $params, true); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php index eb7262e32..45af02f5c 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php @@ -84,7 +84,7 @@ public function getNamespaceName() * The shortest name is stripped of the default namespace. All other * namespaced elements are returned as full-qualified names. * - * @param string $defaultNamespaceName + * @param string|null $defaultNamespaceName * * @return string */ diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index 9b917427f..8e4ffa5f9 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -14,10 +14,12 @@ use function array_intersect; use function array_map; use function array_values; +use function assert; use function call_user_func_array; use function count; use function func_get_args; use function is_array; +use function is_callable; use function preg_match; use function str_replace; use function strtolower; @@ -80,8 +82,11 @@ public function tryMethod() unset($args[0]); $args = array_values($args); + $callback = [$this, $method]; + assert(is_callable($callback)); + try { - return call_user_func_array([$this, $method], $args); + return call_user_func_array($callback, $args); } catch (Throwable $e) { return false; } @@ -141,7 +146,7 @@ public function listSequences($database = null) * this column definition does try to contain the 'primary' field for * the reason that it is not portable across different RDBMS. Use * {@see listTableIndexes($tableName)} to retrieve the primary key - * of a table. We're a RDBMS specifies more details these are held + * of a table. Where a RDBMS specifies more details, these are held * in the platformDetails array. * * @param string $table The name of the table. @@ -183,7 +188,9 @@ public function listTableIndexes($table) /** * Returns true if all the given tables exist. * - * @param string[] $tableNames + * The usage of a string $tableNames is deprecated. Pass a one-element array instead. + * + * @param string|string[] $tableNames * * @return bool */ @@ -268,7 +275,7 @@ public function listTableDetails($tableName) } $indexes = $this->listTableIndexes($tableName); - return new Table($tableName, $columns, $indexes, $foreignKeys, false, []); + return new Table($tableName, $columns, $indexes, $foreignKeys); } /** @@ -678,6 +685,8 @@ protected function getPortableNamespaceDefinition(array $namespace) } /** + * @deprecated + * * @param mixed[][] $functions * * @return mixed[][] @@ -699,6 +708,8 @@ protected function _getPortableFunctionsList($functions) } /** + * @deprecated + * * @param mixed[] $function * * @return mixed @@ -747,14 +758,9 @@ protected function _getPortableTriggerDefinition($trigger) protected function _getPortableSequencesList($sequences) { $list = []; - foreach ($sequences as $value) { - $value = $this->_getPortableSequenceDefinition($value); - - if (! $value) { - continue; - } - $list[] = $value; + foreach ($sequences as $value) { + $list[] = $this->_getPortableSequenceDefinition($value); } return $list; @@ -854,7 +860,7 @@ protected function _getPortableTableIndexesList($tableIndexRows, $tableName = nu $result[$keyName] = [ 'name' => $indexName, 'columns' => [], - 'unique' => $tableIndex['non_unique'] ? false : true, + 'unique' => ! $tableIndex['non_unique'], 'primary' => $tableIndex['primary'], 'flags' => $tableIndex['flags'] ?? [], 'options' => $options, @@ -947,9 +953,9 @@ protected function _getPortableUsersList($users) } /** - * @param mixed[] $user + * @param string[] $user * - * @return mixed[] + * @return string[] */ protected function _getPortableUserDefinition($user) { @@ -996,14 +1002,9 @@ protected function _getPortableViewDefinition($view) protected function _getPortableTableForeignKeysList($tableForeignKeys) { $list = []; - foreach ($tableForeignKeys as $value) { - $value = $this->_getPortableTableForeignKeyDefinition($value); - - if (! $value) { - continue; - } - $list[] = $value; + foreach ($tableForeignKeys as $value) { + $list[] = $this->_getPortableTableForeignKeyDefinition($value); } return $list; @@ -1103,28 +1104,32 @@ public function getSchemaSearchPaths() * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns * the type given as default. * - * @param string $comment - * @param string $currentType + * @param string|null $comment + * @param string $currentType * * @return string */ public function extractDoctrineTypeFromComment($comment, $currentType) { - if (preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { - $currentType = $match[1]; + if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { + return $match[1]; } return $currentType; } /** - * @param string $comment - * @param string $type + * @param string|null $comment + * @param string|null $type * - * @return string + * @return string|null */ public function removeDoctrineTypeFromComment($comment, $type) { + if ($comment === null) { + return null; + } + return str_replace('(DC2Type:' . $type . ')', '', $comment); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php index aef471e06..50724fda7 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php @@ -80,7 +80,7 @@ public function setOptions(array $options) // next major: throw an exception @trigger_error(sprintf( 'The "%s" column option is not supported,' . - ' setting it is deprecated and will cause an error in Doctrine 3.0', + ' setting it is deprecated and will cause an error in Doctrine DBAL 3.0', $name ), E_USER_DEPRECATED); @@ -356,7 +356,7 @@ public function setAutoincrement($flag) } /** - * @param string $comment + * @param string|null $comment * * @return Column */ diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php index cb6459210..1589f98d4 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php @@ -18,7 +18,7 @@ class ColumnDiff /** @var string[] */ public $changedProperties = []; - /** @var Column */ + /** @var Column|null */ public $fromColumn; /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php index 1d8a7275d..9ccaa9a1e 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php @@ -10,7 +10,9 @@ use function array_merge; use function array_shift; use function array_unique; +use function assert; use function count; +use function get_class; use function strtolower; /** @@ -108,6 +110,8 @@ public function compare(Schema $fromSchema, Schema $toSchema) } foreach ($diff->changedTables[$localTableName]->removedForeignKeys as $key => $removedForeignKey) { + assert($removedForeignKey instanceof ForeignKeyConstraint); + // We check if the key is from the removed table if not we skip. if ($tableName !== strtolower($removedForeignKey->getForeignTableName())) { continue; @@ -250,6 +254,7 @@ public function diffTable(Table $table1, Table $table2) // See if index has changed in table 2. $table2Index = $index->isPrimary() ? $table2->getPrimaryKey() : $table2->getIndex($indexName); + assert($table2Index instanceof Index); if (! $this->diffIndex($index, $table2Index)) { continue; @@ -417,7 +422,11 @@ public function diffColumn(Column $column1, Column $column2) $changedProperties = []; - foreach (['type', 'notnull', 'unsigned', 'autoincrement'] as $property) { + if (get_class($properties1['type']) !== get_class($properties2['type'])) { + $changedProperties[] = 'type'; + } + + foreach (['notnull', 'unsigned', 'autoincrement'] as $property) { if ($properties1[$property] === $properties2[$property]) { continue; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php index f5e225512..b1fe64afe 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php @@ -2,14 +2,16 @@ namespace Doctrine\DBAL\Schema; +use Doctrine\DBAL\Platforms\DB2Platform; use Doctrine\DBAL\Types\Type; use const CASE_LOWER; use function array_change_key_case; use function is_resource; +use function preg_match; +use function str_replace; use function strpos; use function strtolower; use function substr; -use function trim; /** * IBM Db2 Schema Manager. @@ -41,14 +43,17 @@ protected function _getPortableTableColumnDefinition($tableColumn) $length = null; $fixed = null; - $unsigned = false; $scale = false; $precision = false; $default = null; if ($tableColumn['default'] !== null && $tableColumn['default'] !== 'NULL') { - $default = trim($tableColumn['default'], "'"); + $default = $tableColumn['default']; + + if (preg_match('/^\'(.*)\'$/s', $default, $matches)) { + $default = str_replace("''", "'", $matches[1]); + } } $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']); @@ -80,7 +85,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) $options = [ 'length' => $length, - 'unsigned' => (bool) $unsigned, + 'unsigned' => false, 'fixed' => (bool) $fixed, 'default' => $default, 'autoincrement' => (bool) $tableColumn['autoincrement'], @@ -179,7 +184,9 @@ protected function _getPortableForeignKeyRuleDef($def) { if ($def === 'C') { return 'CASCADE'; - } elseif ($def === 'N') { + } + + if ($def === 'N') { return 'SET NULL'; } @@ -203,4 +210,18 @@ protected function _getPortableViewDefinition($view) return new View($view['name'], $sql); } + + public function listTableDetails($tableName) : Table + { + $table = parent::listTableDetails($tableName); + + /** @var DB2Platform $platform */ + $platform = $this->_platform; + $sql = $platform->getListTableCommentsSQL($tableName); + + $tableOptions = $this->_conn->fetchAssoc($sql); + $table->addOption('comment', $tableOptions['REMARKS']); + + return $table; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php index 31850d7f2..3c6585e46 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php @@ -3,14 +3,13 @@ namespace Doctrine\DBAL\Schema; use Doctrine\DBAL\Platforms\AbstractPlatform; -use function array_combine; use function array_keys; use function array_map; -use function end; -use function explode; use function in_array; +use function strrpos; use function strtolower; use function strtoupper; +use function substr; /** * An abstraction class for a foreign key constraint. @@ -65,13 +64,11 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint */ public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = []) { - $this->_setName($name); - $identifierConstructorCallback = static function ($column) { - return new Identifier($column); - }; - $this->_localColumnNames = $localColumnNames - ? array_combine($localColumnNames, array_map($identifierConstructorCallback, $localColumnNames)) - : []; + if ($name !== null) { + $this->_setName($name); + } + + $this->_localColumnNames = $this->createIdentifierMap($localColumnNames); if ($foreignTableName instanceof Table) { $this->_foreignTableName = $foreignTableName; @@ -79,12 +76,26 @@ public function __construct(array $localColumnNames, $foreignTableName, array $f $this->_foreignTableName = new Identifier($foreignTableName); } - $this->_foreignColumnNames = $foreignColumnNames - ? array_combine($foreignColumnNames, array_map($identifierConstructorCallback, $foreignColumnNames)) - : []; + $this->_foreignColumnNames = $this->createIdentifierMap($foreignColumnNames); $this->_options = $options; } + /** + * @param string[] $names + * + * @return Identifier[] + */ + private function createIdentifierMap(array $names) : array + { + $identifiers = []; + + foreach ($names as $name) { + $identifiers[$name] = new Identifier($name); + } + + return $identifiers; + } + /** * Returns the name of the referencing table * the foreign key constraint is associated with. @@ -218,9 +229,14 @@ public function getForeignTableName() */ public function getUnqualifiedForeignTableName() { - $parts = explode('.', $this->_foreignTableName->getName()); + $name = $this->_foreignTableName->getName(); + $position = strrpos($name, '.'); + + if ($position !== false) { + $name = substr($name, $position); + } - return strtolower(end($parts)); + return strtolower($name); } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php index 91ffd4724..7a31c7824 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php @@ -243,7 +243,9 @@ public function overrules(Index $other) { if ($other->isPrimary()) { return false; - } elseif ($this->isSimpleIndex() && $other->isUnique()) { + } + + if ($this->isSimpleIndex() && $other->isUnique()) { return false; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index 7bcd5533e..9522faf6a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -9,21 +9,40 @@ use function array_change_key_case; use function array_shift; use function array_values; -use function end; +use function assert; use function explode; +use function is_string; use function preg_match; -use function preg_replace; -use function str_replace; -use function stripslashes; use function strpos; use function strtok; use function strtolower; +use function strtr; /** * Schema manager for the MySql RDBMS. */ class MySqlSchemaManager extends AbstractSchemaManager { + /** + * @see https://mariadb.com/kb/en/library/string-literals/#escape-sequences + */ + private const MARIADB_ESCAPE_SEQUENCES = [ + '\\0' => "\0", + "\\'" => "'", + '\\"' => '"', + '\\b' => "\b", + '\\n' => "\n", + '\\r' => "\r", + '\\t' => "\t", + '\\Z' => "\x1a", + '\\\\' => '\\', + '\\%' => '%', + '\\_' => '_', + + // Internally, MariaDB escapes single quotes using the standard syntax + "''" => "'", + ]; + /** * {@inheritdoc} */ @@ -68,7 +87,7 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null } elseif (strpos($v['index_type'], 'SPATIAL') !== false) { $v['flags'] = ['SPATIAL']; } - $v['length'] = $v['sub_part'] ?? null; + $v['length'] = isset($v['sub_part']) ? (int) $v['sub_part'] : null; $tableIndexes[$k] = $v; } @@ -76,14 +95,6 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null return parent::_getPortableTableIndexesList($tableIndexes, $tableName); } - /** - * {@inheritdoc} - */ - protected function _getPortableSequenceDefinition($sequence) - { - return end($sequence); - } - /** * {@inheritdoc} */ @@ -101,6 +112,8 @@ protected function _getPortableTableColumnDefinition($tableColumn) $dbType = strtolower($tableColumn['type']); $dbType = strtok($dbType, '(), '); + assert(is_string($dbType)); + $length = $tableColumn['length'] ?? strtok('(), '); $fixed = null; @@ -192,6 +205,9 @@ protected function _getPortableTableColumnDefinition($tableColumn) $column = new Column($tableColumn['field'], Type::getType($type), $options); + if (isset($tableColumn['characterset'])) { + $column->setPlatformOption('charset', $tableColumn['characterset']); + } if (isset($tableColumn['collation'])) { $column->setPlatformOption('collation', $tableColumn['collation']); } @@ -220,15 +236,11 @@ private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?str if ($columnDefault === 'NULL' || $columnDefault === null) { return null; } - if ($columnDefault[0] === "'") { - return stripslashes( - str_replace( - "''", - "'", - preg_replace('/^\'(.*)\'$/', '$1', $columnDefault) - ) - ); + + if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches)) { + return strtr($matches[1], self::MARIADB_ESCAPE_SEQUENCES); } + switch ($columnDefault) { case 'current_timestamp()': return $platform->getCurrentTimestampSQL(); @@ -237,6 +249,7 @@ private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?str case 'curtime()': return $platform->getCurrentTimeSQL(); } + return $columnDefault; } @@ -296,13 +309,20 @@ public function listTableDetails($tableName) $tableOptions = $this->_conn->fetchAssoc($sql); + if ($tableOptions === false) { + return $table; + } + $table->addOption('engine', $tableOptions['ENGINE']); + if ($tableOptions['TABLE_COLLATION'] !== null) { $table->addOption('collation', $tableOptions['TABLE_COLLATION']); } + if ($tableOptions['AUTO_INCREMENT'] !== null) { $table->addOption('autoincrement', $tableOptions['AUTO_INCREMENT']); } + $table->addOption('comment', $tableOptions['TABLE_COMMENT']); $table->addOption('create_options', $this->parseCreateOptions($tableOptions['CREATE_OPTIONS'])); diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index 250ec2a26..afe610ddb 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -6,12 +6,14 @@ use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Types\Type; +use Throwable; use const CASE_LOWER; use function array_change_key_case; use function array_values; use function assert; use function preg_match; use function sprintf; +use function str_replace; use function strpos; use function strtolower; use function strtoupper; @@ -31,6 +33,7 @@ public function dropDatabase($database) parent::dropDatabase($database); } catch (DBALException $exception) { $exception = $exception->getPrevious(); + assert($exception instanceof Throwable); if (! $exception instanceof DriverException) { throw $exception; @@ -142,8 +145,10 @@ protected function _getPortableTableColumnDefinition($tableColumn) } if ($tableColumn['data_default'] !== null) { - // Default values returned from database are enclosed in single quotes. - $tableColumn['data_default'] = trim($tableColumn['data_default'], "'"); + // Default values returned from database are represented as literal expressions + if (preg_match('/^\'(.*)\'$/s', $tableColumn['data_default'], $matches)) { + $tableColumn['data_default'] = str_replace("''", "'", $matches[1]); + } } if ($tableColumn['data_precision'] !== null) { @@ -259,6 +264,8 @@ protected function _getPortableSequenceDefinition($sequence) /** * {@inheritdoc} + * + * @deprecated */ protected function _getPortableFunctionDefinition($function) { @@ -279,6 +286,8 @@ protected function _getPortableDatabaseDefinition($database) /** * {@inheritdoc} + * + * Calling this method without an argument or by passing NULL is deprecated. */ public function createDatabase($database = null) { @@ -380,4 +389,18 @@ private function killUserSessions($user) ); } } + + public function listTableDetails($tableName) : Table + { + $table = parent::listTableDetails($tableName); + + /** @var OraclePlatform $platform */ + $platform = $this->_platform; + $sql = $platform->getListTableCommentsSQL($tableName); + + $tableOptions = $this->_conn->fetchAssoc($sql); + $table->addOption('comment', $tableOptions['COMMENTS']); + + return $table; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 168e74ea8..e9608e7c1 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use const CASE_LOWER; use function array_change_key_case; use function array_filter; @@ -20,7 +21,6 @@ use function preg_replace; use function sprintf; use function str_replace; -use function stripos; use function strlen; use function strpos; use function strtolower; @@ -134,8 +134,8 @@ protected function _getPortableTableForeignKeyDefinition($tableForeignKey) { $onUpdate = null; $onDelete = null; - $localColumns = null; - $foreignColumns = null; + $localColumns = []; + $foreignColumns = []; $foreignTable = null; if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { @@ -329,11 +329,9 @@ protected function _getPortableTableColumnDefinition($tableColumn) $autoincrement = true; } - if (preg_match("/^['(](.*)[')]::.*$/", $tableColumn['default'], $matches)) { + if (preg_match("/^['(](.*)[')]::/", $tableColumn['default'], $matches)) { $tableColumn['default'] = $matches[1]; - } - - if (stripos($tableColumn['default'], 'NULL') === 0) { + } elseif (preg_match('/^NULL::/', $tableColumn['default'])) { $tableColumn['default'] = null; } @@ -394,11 +392,12 @@ protected function _getPortableTableColumnDefinition($tableColumn) $length = null; break; case 'text': - $fixed = false; - break; + case '_varchar': case 'varchar': + $tableColumn['default'] = $this->parseDefaultExpression($tableColumn['default']); + $fixed = false; + break; case 'interval': - case '_varchar': $fixed = false; break; case 'char': @@ -456,7 +455,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) $column->setPlatformOption('collation', $tableColumn['collation']); } - if (in_array($column->getType()->getName(), [Type::JSON_ARRAY, Type::JSON], true)) { + if (in_array($column->getType()->getName(), [Types::JSON_ARRAY, Types::JSON], true)) { $column->setPlatformOption('jsonb', $jsonb); } @@ -478,4 +477,31 @@ private function fixVersion94NegativeNumericDefaultValue($defaultValue) return $defaultValue; } + + /** + * Parses a default value expression as given by PostgreSQL + */ + private function parseDefaultExpression(?string $default) : ?string + { + if ($default === null) { + return $default; + } + + return str_replace("''", "'", $default); + } + + public function listTableDetails($tableName) : Table + { + $table = parent::listTableDetails($tableName); + + /** @var PostgreSqlPlatform $platform */ + $platform = $this->_platform; + $sql = $platform->getListTableMetadataSQL($tableName); + + $tableOptions = $this->_conn->fetchAssoc($sql); + + $table->addOption('comment', $tableOptions['table_comment']); + + return $table; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php index 62d5fa88e..c169a6e07 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php @@ -5,6 +5,7 @@ use Doctrine\DBAL\Platforms\SQLAnywherePlatform; use Doctrine\DBAL\Types\Type; use function assert; +use function is_string; use function preg_replace; /** @@ -222,9 +223,9 @@ protected function _getPortableTableIndexesList($tableIndexRows, $tableName = nu */ protected function _getPortableViewDefinition($view) { - return new View( - $view['table_name'], - preg_replace('/^.*\s+as\s+SELECT(.*)/i', 'SELECT$1', $view['view_def']) - ); + $definition = preg_replace('/^.*\s+as\s+SELECT(.*)/i', 'SELECT$1', $view['view_def']); + assert(is_string($definition)); + + return new View($view['table_name'], $definition); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php index 6cd82b2ff..35cdc4508 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php @@ -4,16 +4,19 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\DriverException; +use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Types\Type; use PDOException; +use Throwable; +use function assert; use function count; use function in_array; -use function preg_replace; +use function is_string; +use function preg_match; use function sprintf; use function str_replace; use function strpos; use function strtok; -use function trim; /** * SQL Server Schema Manager. @@ -29,6 +32,7 @@ public function dropDatabase($database) parent::dropDatabase($database); } catch (DBALException $exception) { $exception = $exception->getPrevious(); + assert($exception instanceof Throwable); if (! $exception instanceof DriverException) { throw $exception; @@ -61,7 +65,9 @@ protected function _getPortableSequenceDefinition($sequence) */ protected function _getPortableTableColumnDefinition($tableColumn) { - $dbType = strtok($tableColumn['type'], '(), '); + $dbType = strtok($tableColumn['type'], '(), '); + assert(is_string($dbType)); + $fixed = null; $length = (int) $tableColumn['length']; $default = $tableColumn['default']; @@ -71,15 +77,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) } if ($default !== null) { - while ($default !== ($default2 = preg_replace('/^\((.*)\)$/', '$1', $default))) { - $default = trim($default2, "'"); - - if ($default !== 'getdate()') { - continue; - } - - $default = $this->_platform->getCurrentTimestampSQL(); - } + $default = $this->parseDefaultExpression($default); } switch ($dbType) { @@ -109,7 +107,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) 'length' => $length === 0 || ! in_array($type, ['text', 'string']) ? null : $length, 'unsigned' => false, 'fixed' => (bool) $fixed, - 'default' => $default !== 'NULL' ? $default : null, + 'default' => $default, 'notnull' => (bool) $tableColumn['notnull'], 'scale' => $tableColumn['scale'], 'precision' => $tableColumn['precision'], @@ -126,6 +124,27 @@ protected function _getPortableTableColumnDefinition($tableColumn) return $column; } + private function parseDefaultExpression(string $value) : ?string + { + while (preg_match('/^\((.*)\)$/s', $value, $matches)) { + $value = $matches[1]; + } + + if ($value === 'NULL') { + return null; + } + + if (preg_match('/^\'(.*)\'$/s', $value, $matches)) { + $value = str_replace("''", "'", $matches[1]); + } + + if ($value === 'getdate()') { + return $this->_platform->getCurrentTimestampSQL(); + } + + return $value; + } + /** * {@inheritdoc} */ @@ -216,7 +235,7 @@ protected function getPortableNamespaceDefinition(array $namespace) protected function _getPortableViewDefinition($view) { // @todo - return new View($view['name'], null); + return new View($view['name'], ''); } /** @@ -307,4 +326,24 @@ private function closeActiveDatabaseConnections($database) ) ); } + + /** + * @param string $tableName + */ + public function listTableDetails($tableName) : Table + { + $table = parent::listTableDetails($tableName); + + /** @var SQLServerPlatform $platform */ + $platform = $this->_platform; + $sql = $platform->getListTableMetadataSQL($tableName); + + $tableOptions = $this->_conn->fetchAssoc($sql); + + if ($tableOptions !== false) { + $table->addOption('comment', $tableOptions['table_comment']); + } + + return $table; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php index 7b75f4fb7..5d746654a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php @@ -105,7 +105,9 @@ protected function _addTable(Table $table) throw SchemaException::tableAlreadyExists($tableName); } - if (! $table->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { + if ($namespaceName !== null + && ! $table->isInDefaultNamespace($this->getName()) + && ! $this->hasNamespace($namespaceName)) { $this->createNamespace($namespaceName); } @@ -127,7 +129,9 @@ protected function _addSequence(Sequence $sequence) throw SchemaException::sequenceAlreadyExists($seqName); } - if (! $sequence->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { + if ($namespaceName !== null + && ! $sequence->isInDefaultNamespace($this->getName()) + && ! $this->hasNamespace($namespaceName)) { $this->createNamespace($namespaceName); } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php index 0f2e25fb3..69bf125a8 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php @@ -10,7 +10,7 @@ */ class SchemaDiff { - /** @var Schema */ + /** @var Schema|null */ public $fromSchema; /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php index 24cf4aae0..88891019b 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php @@ -4,7 +4,6 @@ use Doctrine\DBAL\Schema\Visitor\Visitor; use function count; -use function is_numeric; use function sprintf; /** @@ -66,7 +65,7 @@ public function getCache() */ public function setAllocationSize($allocationSize) { - $this->allocationSize = is_numeric($allocationSize) ? (int) $allocationSize : 1; + $this->allocationSize = (int) $allocationSize ?: 1; return $this; } @@ -78,7 +77,7 @@ public function setAllocationSize($allocationSize) */ public function setInitialValue($initialValue) { - $this->initialValue = is_numeric($initialValue) ? (int) $initialValue : 1; + $this->initialValue = (int) $initialValue ?: 1; return $this; } @@ -105,11 +104,13 @@ public function setCache($cache) */ public function isAutoIncrementsFor(Table $table) { - if (! $table->hasPrimaryKey()) { + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { return false; } - $pkColumns = $table->getPrimaryKey()->getColumns(); + $pkColumns = $primaryKey->getColumns(); if (count($pkColumns) !== 1) { return false; diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index 744acedab..ac758015a 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -77,7 +77,7 @@ public function renameTable($name, $newName) */ public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) { - $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff = $this->getTableDiffForAlterForeignKey($table); $tableDiff->addedForeignKeys[] = $foreignKey; $this->alterTable($tableDiff); @@ -88,7 +88,7 @@ public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) */ public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) { - $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff = $this->getTableDiffForAlterForeignKey($table); $tableDiff->changedForeignKeys[] = $foreignKey; $this->alterTable($tableDiff); @@ -99,7 +99,7 @@ public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table */ public function dropForeignKey($foreignKey, $table) { - $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff = $this->getTableDiffForAlterForeignKey($table); $tableDiff->removedForeignKeys[] = $foreignKey; $this->alterTable($tableDiff); @@ -205,7 +205,7 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null $idx = []; $idx['key_name'] = $keyName; $idx['primary'] = false; - $idx['non_unique'] = $tableIndex['unique']?false:true; + $idx['non_unique'] = ! $tableIndex['unique']; $stmt = $this->_conn->executeQuery(sprintf( 'PRAGMA INDEX_INFO (%s)', @@ -224,6 +224,8 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null /** * {@inheritdoc} + * + * @deprecated */ protected function _getPortableTableIndexDefinition($tableIndex) { @@ -283,9 +285,9 @@ protected function _getPortableTableColumnList($table, $database, $tableColumns) continue; } - $type = $this->extractDoctrineTypeFromComment($comment, null); + $type = $this->extractDoctrineTypeFromComment($comment, ''); - if ($type !== null) { + if ($type !== '') { $column->setType(Type::getType($type)); $comment = $this->removeDoctrineTypeFromComment($comment, $type); @@ -324,10 +326,14 @@ protected function _getPortableTableColumnDefinition($tableColumn) if ($default === 'NULL') { $default = null; } + if ($default !== null) { - // SQLite returns strings wrapped in single quotes, so we need to strip them - $default = preg_replace("/^'(.*)'$/", '\1', $default); + // SQLite returns the default value as a literal expression, so we need to parse it + if (preg_match('/^\'(.*)\'$/s', $default, $matches)) { + $default = str_replace("''", "'", $matches[1]); + } } + $notnull = (bool) $tableColumn['notnull']; if (! isset($tableColumn['name'])) { @@ -436,11 +442,12 @@ protected function _getPortableTableForeignKeysList($tableForeignKeys) * * @throws DBALException */ - private function getTableDiffForAlterForeignKey(ForeignKeyConstraint $foreignKey, $table) + private function getTableDiffForAlterForeignKey($table) { if (! $table instanceof Table) { $tableDetails = $this->tryMethod('listTableDetails', $table); - if ($table === false) { + + if ($tableDetails === false) { throw new DBALException(sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)); } @@ -465,6 +472,25 @@ private function parseColumnCollationFromSQL(string $column, string $sql) : ?str return $match[1]; } + private function parseTableCommentFromSQL(string $table, string $sql) : ?string + { + $pattern = '/\s* # Allow whitespace characters at start of line +CREATE\sTABLE # Match "CREATE TABLE" +(?:\W"' . preg_quote($this->_platform->quoteSingleIdentifier($table), '/') . '"\W|\W' . preg_quote($table, '/') + . '\W) # Match table name (quoted and unquoted) +( # Start capture + (?:\s*--[^\n]*\n?)+ # Capture anything that starts with whitespaces followed by -- until the end of the line(s) +)/ix'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); + + return $comment === '' ? null : $comment; + } + private function parseColumnCommentFromSQL(string $column, string $sql) : ?string { $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column) @@ -498,4 +524,22 @@ private function getCreateTableSQL(string $table) : ?string [$table] ) ?: null; } + + /** + * @param string $tableName + */ + public function listTableDetails($tableName) : Table + { + $table = parent::listTableDetails($tableName); + + $tableCreateSql = $this->getCreateTableSQL($tableName) ?? ''; + + $comment = $this->parseTableCommentFromSQL($tableName, $tableCreateSql); + + if ($comment !== null) { + $table->addOption('comment', $comment); + } + + return $table; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php index e51b27f37..dd4b1ca5f 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php @@ -31,7 +31,6 @@ public function getCreateSchema(Schema $createSchema) return $createSchema->toSql($this->platform); } - /** * {@inheritdoc} */ @@ -87,11 +86,14 @@ public function getDropSchema(Schema $dropSchema) } foreach ($dropSchema->getTables() as $table) { - if (! $table->hasPrimaryKey()) { + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { continue; } - $columns = $table->getPrimaryKey()->getColumns(); + $columns = $primaryKey->getColumns(); + if (count($columns) > 1) { continue; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php index 191294d6d..8e613320f 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php @@ -18,9 +18,6 @@ */ class Table extends AbstractAsset { - /** @var string */ - protected $_name = null; - /** @var Column[] */ protected $_columns = []; @@ -37,7 +34,9 @@ class Table extends AbstractAsset protected $_fkConstraints = []; /** @var mixed[] */ - protected $_options = []; + protected $_options = [ + 'create_options' => [], + ]; /** @var SchemaConfig|null */ protected $_schemaConfig = null; @@ -72,7 +71,7 @@ public function __construct($tableName, array $columns = [], array $indexes = [] $this->_addForeignKeyConstraint($constraint); } - $this->_options = $options; + $this->_options = array_merge($this->_options, $options); } /** @@ -98,8 +97,8 @@ protected function _getMaxIdentifierLength() /** * Sets the Primary Key. * - * @param string[] $columnNames - * @param string|bool $indexName + * @param string[] $columnNames + * @param string|false $indexName * * @return self */ @@ -219,7 +218,7 @@ public function renameIndex($oldIndexName, $newIndexName = null) if ($oldIndex->isPrimary()) { $this->dropPrimaryKey(); - return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName); + return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName ?? false); } unset($this->_indexes[$oldIndexName]); @@ -425,7 +424,7 @@ public function addNamedForeignKeyConstraint($name, $foreignTable, array $localC /** * @param string $name - * @param string $value + * @param mixed $value * * @return self */ @@ -592,9 +591,11 @@ public function removeForeignKey($constraintName) */ public function getColumns() { + $primaryKey = $this->getPrimaryKey(); $primaryKeyColumns = []; - if ($this->hasPrimaryKey()) { - $primaryKeyColumns = $this->filterColumns($this->getPrimaryKey()->getColumns()); + + if ($primaryKey !== null) { + $primaryKeyColumns = $this->filterColumns($primaryKey->getColumns()); } return array_merge($primaryKeyColumns, $this->getForeignKeyColumns(), $this->_columns); @@ -611,6 +612,7 @@ private function getForeignKeyColumns() foreach ($this->getForeignKeys() as $foreignKey) { $foreignKeyColumns = array_merge($foreignKeyColumns, $foreignKey->getColumns()); } + return $this->filterColumns($foreignKeyColumns); } @@ -684,10 +686,13 @@ public function getPrimaryKey() */ public function getPrimaryKeyColumns() { - if (! $this->hasPrimaryKey()) { + $primaryKey = $this->getPrimaryKey(); + + if ($primaryKey === null) { throw new DBALException('Table ' . $this->getName() . ' has no primary key.'); } - return $this->getPrimaryKey()->getColumns(); + + return $primaryKey->getColumns(); } /** @@ -823,12 +828,29 @@ public function __clone() * * Trims quotes and lowercases the given identifier. * - * @param string $identifier The identifier to normalize. + * @param string|null $identifier The identifier to normalize. * * @return string The normalized identifier. */ private function normalizeIdentifier($identifier) { + if ($identifier === null) { + return ''; + } + return $this->trimQuotes(strtolower($identifier)); } + + public function setComment(?string $comment) : self + { + // For keeping backward compatibility with MySQL in previous releases, table comments are stored as options. + $this->addOption('comment', $comment); + + return $this; + } + + public function getComment() : ?string + { + return $this->_options['comment'] ?? null; + } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php index 457e1b6a9..1ff2c0ad1 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php @@ -12,7 +12,7 @@ class TableDiff /** @var string */ public $name = null; - /** @var string|bool */ + /** @var string|false */ public $newName = false; /** @@ -92,7 +92,7 @@ class TableDiff */ public $removedForeignKeys = []; - /** @var Table */ + /** @var Table|null */ public $fromTable; /** @@ -139,10 +139,14 @@ public function getName(AbstractPlatform $platform) } /** - * @return Identifier|string|bool + * @return Identifier|false */ public function getNewName() { - return $this->newName ? new Identifier($this->newName) : $this->newName; + if ($this->newName === false) { + return false; + } + + return new Identifier($this->newName); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php index 318c8b262..cc15bc0f6 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php @@ -47,7 +47,7 @@ public function acceptNamespace($namespaceName) */ public function acceptTable(Table $table) { - $this->createTableQueries = array_merge($this->createTableQueries, (array) $this->platform->getCreateTableSQL($table)); + $this->createTableQueries = array_merge($this->createTableQueries, $this->platform->getCreateTableSQL($table)); } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php index 44f5ea80a..81e202312 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php @@ -78,15 +78,18 @@ public function getQueries() { $sql = []; + /** @var ForeignKeyConstraint $fkConstraint */ foreach ($this->constraints as $fkConstraint) { $localTable = $this->constraints[$fkConstraint]; $sql[] = $this->platform->getDropForeignKeySQL($fkConstraint, $localTable); } + /** @var Sequence $sequence */ foreach ($this->sequences as $sequence) { $sql[] = $this->platform->getDropSequenceSQL($sequence); } + /** @var Table $table */ foreach ($this->tables as $table) { $sql[] = $this->platform->getDropTableSQL($table); } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php index 889f96112..d5e94cf6e 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php @@ -8,8 +8,6 @@ use function current; use function file_put_contents; use function in_array; -use function mt_rand; -use function sha1; use function strtolower; /** @@ -41,7 +39,7 @@ public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkCons */ public function acceptSchema(Schema $schema) { - $this->output = 'digraph "' . sha1(mt_rand()) . '" {' . "\n"; + $this->output = 'digraph "' . $schema->getName() . '" {' . "\n"; $this->output .= 'splines = true;' . "\n"; $this->output .= 'overlap = false;' . "\n"; $this->output .= 'outputorder=edgesfirst;' . "\n"; @@ -83,7 +81,10 @@ private function createTableLabel(Table $table) $label .= '' . $columnLabel . ''; $label .= '' . strtolower($column->getType()) . ''; $label .= ''; - if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) { + + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey !== null && in_array($column->getName(), $primaryKey->getColumns())) { $label .= "\xe2\x9c\xb7"; } $label .= ''; diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php index 9b23b3958..001ea2a0d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php @@ -65,6 +65,7 @@ public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkCons // point to nowhere. if (! $this->schema->hasTable($fkConstraint->getForeignTableName())) { $localTable->removeForeignKey($fkConstraint->getName()); + return; } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php index abb5b4004..8d8134127 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php @@ -26,7 +26,7 @@ * - By default, the global shard is selected. If no global shard is configured * an exception is thrown on access. * - Selecting a shard by distribution value delegates the mapping - * "distributionValue" => "client" to the ShardChooser interface. + * "distributionValue" => "client" to the ShardChoser interface. * - An exception is thrown if trying to switch shards during an open * transaction. * @@ -53,7 +53,7 @@ class PoolingShardConnection extends Connection /** @var DriverConnection[] */ private $activeConnections = []; - /** @var int|null */ + /** @var string|int|null */ private $activeShardId; /** @var mixed[] */ @@ -106,7 +106,7 @@ public function __construct(array $params, Driver $driver, ?Configuration $confi /** * Get active shard id. * - * @return int + * @return string|int|null */ public function getActiveShardId() { @@ -164,7 +164,7 @@ public function getPassword() /** * Connects to a given shard. * - * @param mixed $shardId + * @param string|int|null $shardId * * @return bool * @@ -184,15 +184,15 @@ public function connect($shardId = null) throw new ShardingException('Cannot switch shard when transaction is active.'); } - $this->activeShardId = (int) $shardId; + $activeShardId = $this->activeShardId = (int) $shardId; - if (isset($this->activeConnections[$this->activeShardId])) { - $this->_conn = $this->activeConnections[$this->activeShardId]; + if (isset($this->activeConnections[$activeShardId])) { + $this->_conn = $this->activeConnections[$activeShardId]; return false; } - $this->_conn = $this->activeConnections[$this->activeShardId] = $this->connectTo($this->activeShardId); + $this->_conn = $this->activeConnections[$activeShardId] = $this->connectTo($activeShardId); if ($this->_eventManager->hasListeners(Events::postConnect)) { $eventArgs = new ConnectionEventArgs($this); @@ -205,7 +205,7 @@ public function connect($shardId = null) /** * Connects to a specific connection. * - * @param string $shardId + * @param string|int $shardId * * @return \Doctrine\DBAL\Driver\Connection */ @@ -224,7 +224,7 @@ protected function connectTo($shardId) } /** - * @param string|null $shardId + * @param string|int|null $shardId * * @return bool */ diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php index 32d642365..417f674a3 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Schema\Synchronizer\SchemaSynchronizer; use Doctrine\DBAL\Schema\Synchronizer\SingleDatabaseSynchronizer; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use RuntimeException; use function array_merge; @@ -240,12 +241,12 @@ private function getFederationTypeDefaultValue() $federationType = Type::getType($this->shardManager->getDistributionType()); switch ($federationType->getName()) { - case Type::GUID: + case Types::GUID: $defaultValue = '00000000-0000-0000-0000-000000000000'; break; - case Type::INTEGER: - case Type::SMALLINT: - case Type::BIGINT: + case Types::INTEGER: + case Types::SMALLINT: + case Types::BIGINT: $defaultValue = '0'; break; default: diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php index 7c5dfe5c4..d8178ee07 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php @@ -7,8 +7,6 @@ use Doctrine\DBAL\Sharding\ShardManager; use Doctrine\DBAL\Types\Type; use RuntimeException; -use function is_bool; -use function is_scalar; use function sprintf; /** @@ -125,10 +123,6 @@ public function selectShard($distributionValue) throw ShardingException::activeTransaction(); } - if ($distributionValue === null || is_bool($distributionValue) || ! is_scalar($distributionValue)) { - throw ShardingException::noShardDistributionValue(); - } - $platform = $this->conn->getDatabasePlatform(); $sql = sprintf( 'USE FEDERATION %s (%s = %s) WITH RESET, FILTERING = %s;', diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Statement.php b/doctrine/dbal/lib/Doctrine/DBAL/Statement.php index b65fa95e3..09913bb56 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Statement.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Statement.php @@ -217,7 +217,9 @@ public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) { if ($arg2 === null) { return $this->stmt->setFetchMode($fetchMode); - } elseif ($arg3 === null) { + } + + if ($arg3 === null) { return $this->stmt->setFetchMode($fetchMode, $arg2); } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php index 0e8156637..0cd2999c9 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Output\OutputInterface; use const PHP_EOL; use function assert; +use function error_get_last; use function file_exists; use function file_get_contents; use function is_readable; @@ -57,7 +58,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $fileNames = $input->getArgument('file'); if ($fileNames === null) { - return null; + return 0; } foreach ((array) $fileNames as $fileName) { @@ -72,14 +73,22 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new InvalidArgumentException( sprintf("SQL file '%s' does not exist.", $filePath) ); - } elseif (! is_readable($filePath)) { + } + + if (! is_readable($filePath)) { throw new InvalidArgumentException( sprintf("SQL file '%s' does not have read permissions.", $filePath) ); } $output->write(sprintf("Processing file '%s'... ", $filePath)); - $sql = file_get_contents($filePath); + $sql = @file_get_contents($filePath); + + if ($sql === false) { + throw new RuntimeException( + sprintf("Unable to read SQL file '%s': %s", $filePath, error_get_last()['message']) + ); + } if ($conn instanceof PDOConnection) { // PDO Drivers @@ -124,6 +133,6 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - return null; + return 0; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php index 8361219ad..b479baec2 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php @@ -10,7 +10,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; use function is_numeric; +use function is_string; use function stripos; /** @@ -51,6 +53,8 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new RuntimeException("Argument 'SQL' is required in order to execute this command correctly."); } + assert(is_string($sql)); + $depth = $input->getOption('depth'); if (! is_numeric($depth)) { @@ -64,5 +68,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $output->write(Dumper::dump($resultSet, (int) $depth)); + + return 0; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php index d5086adee..3668efbe4 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php @@ -9,6 +9,7 @@ use Doctrine\Common\Persistence\Proxy; use stdClass; use function array_keys; +use function assert; use function class_exists; use function count; use function end; @@ -20,9 +21,11 @@ use function ini_set; use function is_array; use function is_object; +use function is_string; use function ob_get_clean; use function ob_start; use function strip_tags; +use function strlen; use function strrpos; use function substr; use function var_dump; @@ -68,7 +71,10 @@ public static function dump($var, int $maxDepth = 2) : string var_dump($var); try { - return strip_tags(html_entity_decode(ob_get_clean())); + $output = ob_get_clean(); + assert(is_string($output)); + + return strip_tags(html_entity_decode($output)); } finally { ini_set('html_errors', $html); } @@ -171,6 +177,6 @@ private static function getClass($object) : string return $class; } - return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + return substr($class, $pos + strlen(Proxy::MARKER) + 2); } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php index 9bb8e578b..78325ad95 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php @@ -43,7 +43,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) $value = is_resource($value) ? stream_get_contents($value) : $value; - set_error_handler(function (int $code, string $message) : void { + set_error_handler(function (int $code, string $message) : bool { throw ConversionException::conversionFailedUnserialization($this->getName(), $message); }); @@ -59,7 +59,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::TARRAY; + return Types::ARRAY; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php index 1d320d624..69cd5341d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php @@ -15,7 +15,7 @@ class BigIntType extends Type implements PhpIntegerMappingType */ public function getName() { - return Type::BIGINT; + return Types::BIGINT; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php index 14362e840..d604b3bff 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractPlatform; +use function assert; use function fopen; use function fseek; use function fwrite; @@ -34,13 +35,14 @@ public function convertToPHPValue($value, AbstractPlatform $platform) if (is_string($value)) { $fp = fopen('php://temp', 'rb+'); + assert(is_resource($fp)); fwrite($fp, $value); fseek($fp, 0); $value = $fp; } if (! is_resource($value)) { - throw ConversionException::conversionFailed($value, self::BINARY); + throw ConversionException::conversionFailed($value, Types::BINARY); } return $value; @@ -51,7 +53,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::BINARY; + return Types::BINARY; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php index c309f0f06..e4bb22f08 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractPlatform; +use function assert; use function fopen; use function fseek; use function fwrite; @@ -34,13 +35,14 @@ public function convertToPHPValue($value, AbstractPlatform $platform) if (is_string($value)) { $fp = fopen('php://temp', 'rb+'); + assert(is_resource($fp)); fwrite($fp, $value); fseek($fp, 0); $value = $fp; } if (! is_resource($value)) { - throw ConversionException::conversionFailed($value, self::BLOB); + throw ConversionException::conversionFailed($value, Types::BLOB); } return $value; @@ -51,7 +53,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::BLOB; + return Types::BLOB; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php index 976f00e1f..bf9be9b19 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php @@ -39,7 +39,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::BOOLEAN; + return Types::BOOLEAN; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php index 196fc88c7..a4c5d266d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php @@ -15,7 +15,7 @@ class DateImmutableType extends DateType */ public function getName() { - return Type::DATE_IMMUTABLE; + return Types::DATE_IMMUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php index 30e61c9ea..96a446e86 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php @@ -19,7 +19,7 @@ class DateIntervalType extends Type */ public function getName() { - return Type::DATEINTERVAL; + return Types::DATEINTERVAL; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php index fdda50faa..51960a8c3 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php @@ -16,7 +16,7 @@ class DateTimeImmutableType extends DateTimeType */ public function getName() { - return Type::DATETIME_IMMUTABLE; + return Types::DATETIME_IMMUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php index 962d9d38d..65071a6b1 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php @@ -17,7 +17,7 @@ class DateTimeType extends Type implements PhpDateTimeMappingType */ public function getName() { - return Type::DATETIME; + return Types::DATETIME_MUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php index 253c02e00..b88862479 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php @@ -15,7 +15,7 @@ class DateTimeTzImmutableType extends DateTimeTzType */ public function getName() { - return Type::DATETIMETZ_IMMUTABLE; + return Types::DATETIMETZ_IMMUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php index 0b78720ec..6240da892 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php @@ -29,7 +29,7 @@ class DateTimeTzType extends Type implements PhpDateTimeMappingType */ public function getName() { - return Type::DATETIMETZ; + return Types::DATETIMETZ_MUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php index b5ad5356f..15d9362f2 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php @@ -16,7 +16,7 @@ class DateType extends Type */ public function getName() { - return Type::DATE; + return Types::DATE_MUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php index 318cb2476..b2d37f00b 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php @@ -14,7 +14,7 @@ class DecimalType extends Type */ public function getName() { - return Type::DECIMAL; + return Types::DECIMAL; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php index 3ad9aa737..4988d7253 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php @@ -11,7 +11,7 @@ class FloatType extends Type */ public function getName() { - return Type::FLOAT; + return Types::FLOAT; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php index a9ab21537..dd4516505 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php @@ -22,7 +22,7 @@ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $pla */ public function getName() { - return Type::GUID; + return Types::GUID; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php index f04f3c7e0..d7ab8fd80 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php @@ -15,7 +15,7 @@ class IntegerType extends Type implements PhpIntegerMappingType */ public function getName() { - return Type::INTEGER; + return Types::INTEGER; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php index beae80387..bc468fba0 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php @@ -33,7 +33,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::JSON_ARRAY; + return Types::JSON_ARRAY; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonType.php index 00cd3f80f..127f3fa8e 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonType.php @@ -69,7 +69,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::JSON; + return Types::JSON; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php index 081ec483b..82b1a752e 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php @@ -42,7 +42,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) $value = is_resource($value) ? stream_get_contents($value) : $value; - set_error_handler(function (int $code, string $message) : void { + set_error_handler(function (int $code, string $message) : bool { throw ConversionException::conversionFailedUnserialization($this->getName(), $message); }); @@ -58,7 +58,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::OBJECT; + return Types::OBJECT; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php index d23776f5f..31c22b8e6 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php @@ -54,7 +54,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::SIMPLE_ARRAY; + return Types::SIMPLE_ARRAY; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php index bca8a533f..5fa3cb74b 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php @@ -15,7 +15,7 @@ class SmallIntType extends Type implements PhpIntegerMappingType */ public function getName() { - return Type::SMALLINT; + return Types::SMALLINT; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php index 879359a13..e0d1a552f 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php @@ -30,6 +30,6 @@ public function getDefaultLength(AbstractPlatform $platform) */ public function getName() { - return Type::STRING; + return Types::STRING; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php index 635d4f7de..76dd7c48c 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php @@ -32,6 +32,6 @@ public function convertToPHPValue($value, AbstractPlatform $platform) */ public function getName() { - return Type::TEXT; + return Types::TEXT; } } diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php index 8cb870fb3..cc4376955 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php @@ -15,7 +15,7 @@ class TimeImmutableType extends TimeType */ public function getName() { - return Type::TIME_IMMUTABLE; + return Types::TIME_IMMUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php index c9895294e..1eeb2c01d 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php @@ -16,7 +16,7 @@ class TimeType extends Type */ public function getName() { - return Type::TIME; + return Types::TIME_MUTABLE; } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php index ec1ab6813..d39ac2bd3 100644 --- a/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php @@ -5,9 +5,11 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractPlatform; -use function end; -use function explode; +use function array_map; +use function get_class; use function str_replace; +use function strrpos; +use function substr; /** * The base class for so-called Doctrine mapping types. @@ -16,76 +18,119 @@ */ abstract class Type { - public const TARRAY = 'array'; - public const SIMPLE_ARRAY = 'simple_array'; - public const JSON_ARRAY = 'json_array'; - public const JSON = 'json'; - public const BIGINT = 'bigint'; - public const BOOLEAN = 'boolean'; - public const DATETIME = 'datetime'; - public const DATETIME_IMMUTABLE = 'datetime_immutable'; - public const DATETIMETZ = 'datetimetz'; - public const DATETIMETZ_IMMUTABLE = 'datetimetz_immutable'; - public const DATE = 'date'; - public const DATE_IMMUTABLE = 'date_immutable'; - public const TIME = 'time'; - public const TIME_IMMUTABLE = 'time_immutable'; - public const DECIMAL = 'decimal'; - public const INTEGER = 'integer'; - public const OBJECT = 'object'; - public const SMALLINT = 'smallint'; - public const STRING = 'string'; - public const TEXT = 'text'; - public const BINARY = 'binary'; - public const BLOB = 'blob'; - public const FLOAT = 'float'; - public const GUID = 'guid'; - public const DATEINTERVAL = 'dateinterval'; + /** @deprecated Use {@see Types::BIGINT} instead. */ + public const BIGINT = Types::BIGINT; - /** - * Map of already instantiated type objects. One instance per type (flyweight). - * - * @var self[] - */ - private static $_typeObjects = []; + /** @deprecated Use {@see Types::BINARY} instead. */ + public const BINARY = Types::BINARY; + + /** @deprecated Use {@see Types::BLOB} instead. */ + public const BLOB = Types::BLOB; + + /** @deprecated Use {@see Types::BOOLEAN} instead. */ + public const BOOLEAN = Types::BOOLEAN; + + /** @deprecated Use {@see Types::DATE_MUTABLE} instead. */ + public const DATE = Types::DATE_MUTABLE; + + /** @deprecated Use {@see Types::DATE_IMMUTABLE} instead. */ + public const DATE_IMMUTABLE = Types::DATE_IMMUTABLE; + + /** @deprecated Use {@see Types::DATEINTERVAL} instead. */ + public const DATEINTERVAL = Types::DATEINTERVAL; + + /** @deprecated Use {@see Types::DATETIME_MUTABLE} instead. */ + public const DATETIME = Types::DATETIME_MUTABLE; + + /** @deprecated Use {@see Types::DATETIME_IMMUTABLE} instead. */ + public const DATETIME_IMMUTABLE = Types::DATETIME_IMMUTABLE; + + /** @deprecated Use {@see Types::DATETIMETZ_MUTABLE} instead. */ + public const DATETIMETZ = Types::DATETIMETZ_MUTABLE; + + /** @deprecated Use {@see Types::DATETIMETZ_IMMUTABLE} instead. */ + public const DATETIMETZ_IMMUTABLE = Types::DATETIMETZ_IMMUTABLE; + + /** @deprecated Use {@see Types::DECIMAL} instead. */ + public const DECIMAL = Types::DECIMAL; + + /** @deprecated Use {@see Types::FLOAT} instead. */ + public const FLOAT = Types::FLOAT; + + /** @deprecated Use {@see Types::GUID} instead. */ + public const GUID = Types::GUID; + + /** @deprecated Use {@see Types::INTEGER} instead. */ + public const INTEGER = Types::INTEGER; + + /** @deprecated Use {@see Types::JSON} instead. */ + public const JSON = Types::JSON; + + /** @deprecated Use {@see Types::JSON_ARRAY} instead. */ + public const JSON_ARRAY = Types::JSON_ARRAY; + + /** @deprecated Use {@see Types::OBJECT} instead. */ + public const OBJECT = Types::OBJECT; + + /** @deprecated Use {@see Types::SIMPLE_ARRAY} instead. */ + public const SIMPLE_ARRAY = Types::SIMPLE_ARRAY; + + /** @deprecated Use {@see Types::SMALLINT} instead. */ + public const SMALLINT = Types::SMALLINT; + + /** @deprecated Use {@see Types::STRING} instead. */ + public const STRING = Types::STRING; + + /** @deprecated Use {@see Types::ARRAY} instead. */ + public const TARRAY = Types::ARRAY; + + /** @deprecated Use {@see Types::TEXT} instead. */ + public const TEXT = Types::TEXT; + + /** @deprecated Use {@see Types::TIME_MUTABLE} instead. */ + public const TIME = Types::TIME_MUTABLE; + + /** @deprecated Use {@see Types::TIME_IMMUTABLE} instead. */ + public const TIME_IMMUTABLE = Types::TIME_IMMUTABLE; /** * The map of supported doctrine mapping types. - * - * @var string[] */ - private static $_typesMap = [ - self::TARRAY => ArrayType::class, - self::SIMPLE_ARRAY => SimpleArrayType::class, - self::JSON_ARRAY => JsonArrayType::class, - self::JSON => JsonType::class, - self::OBJECT => ObjectType::class, - self::BOOLEAN => BooleanType::class, - self::INTEGER => IntegerType::class, - self::SMALLINT => SmallIntType::class, - self::BIGINT => BigIntType::class, - self::STRING => StringType::class, - self::TEXT => TextType::class, - self::DATETIME => DateTimeType::class, - self::DATETIME_IMMUTABLE => DateTimeImmutableType::class, - self::DATETIMETZ => DateTimeTzType::class, - self::DATETIMETZ_IMMUTABLE => DateTimeTzImmutableType::class, - self::DATE => DateType::class, - self::DATE_IMMUTABLE => DateImmutableType::class, - self::TIME => TimeType::class, - self::TIME_IMMUTABLE => TimeImmutableType::class, - self::DECIMAL => DecimalType::class, - self::FLOAT => FloatType::class, - self::BINARY => BinaryType::class, - self::BLOB => BlobType::class, - self::GUID => GuidType::class, - self::DATEINTERVAL => DateIntervalType::class, + private const BUILTIN_TYPES_MAP = [ + Types::ARRAY => ArrayType::class, + Types::BIGINT => BigIntType::class, + Types::BINARY => BinaryType::class, + Types::BLOB => BlobType::class, + Types::BOOLEAN => BooleanType::class, + Types::DATE_MUTABLE => DateType::class, + Types::DATE_IMMUTABLE => DateImmutableType::class, + Types::DATEINTERVAL => DateIntervalType::class, + Types::DATETIME_MUTABLE => DateTimeType::class, + Types::DATETIME_IMMUTABLE => DateTimeImmutableType::class, + Types::DATETIMETZ_MUTABLE => DateTimeTzType::class, + Types::DATETIMETZ_IMMUTABLE => DateTimeTzImmutableType::class, + Types::DECIMAL => DecimalType::class, + Types::FLOAT => FloatType::class, + Types::GUID => GuidType::class, + Types::INTEGER => IntegerType::class, + Types::JSON => JsonType::class, + Types::JSON_ARRAY => JsonArrayType::class, + Types::OBJECT => ObjectType::class, + Types::SIMPLE_ARRAY => SimpleArrayType::class, + Types::SMALLINT => SmallIntType::class, + Types::STRING => StringType::class, + Types::TEXT => TextType::class, + Types::TIME_MUTABLE => TimeType::class, + Types::TIME_IMMUTABLE => TimeImmutableType::class, ]; + /** @var TypeRegistry|null */ + private static $typeRegistry; + /** - * Prevents instantiation and forces use of the factory method. + * @internal Do not instantiate directly - use {@see Type::addType()} method instead. */ - final private function __construct() + final public function __construct() { } @@ -148,6 +193,29 @@ abstract public function getSQLDeclaration(array $fieldDeclaration, AbstractPlat */ abstract public function getName(); + /** + * @internal This method is only to be used within DBAL for forward compatibility purposes. Do not use directly. + */ + final public static function getTypeRegistry() : TypeRegistry + { + if (self::$typeRegistry === null) { + self::$typeRegistry = self::createTypeRegistry(); + } + + return self::$typeRegistry; + } + + private static function createTypeRegistry() : TypeRegistry + { + $registry = new TypeRegistry(); + + foreach (self::BUILTIN_TYPES_MAP as $name => $class) { + $registry->register($name, new $class()); + } + + return $registry; + } + /** * Factory method to create type instances. * Type instances are implemented as flyweights. @@ -160,14 +228,7 @@ abstract public function getName(); */ public static function getType($name) { - if (! isset(self::$_typeObjects[$name])) { - if (! isset(self::$_typesMap[$name])) { - throw DBALException::unknownColumnType($name); - } - self::$_typeObjects[$name] = new self::$_typesMap[$name](); - } - - return self::$_typeObjects[$name]; + return self::getTypeRegistry()->get($name); } /** @@ -182,11 +243,7 @@ public static function getType($name) */ public static function addType($name, $className) { - if (isset(self::$_typesMap[$name])) { - throw DBALException::typeExists($name); - } - - self::$_typesMap[$name] = $className; + self::getTypeRegistry()->register($name, new $className()); } /** @@ -198,7 +255,7 @@ public static function addType($name, $className) */ public static function hasType($name) { - return isset(self::$_typesMap[$name]); + return self::getTypeRegistry()->has($name); } /** @@ -213,15 +270,7 @@ public static function hasType($name) */ public static function overrideType($name, $className) { - if (! isset(self::$_typesMap[$name])) { - throw DBALException::typeNotFound($name); - } - - if (isset(self::$_typeObjects[$name])) { - unset(self::$_typeObjects[$name]); - } - - self::$_typesMap[$name] = $className; + self::getTypeRegistry()->override($name, new $className()); } /** @@ -245,7 +294,12 @@ public function getBindingType() */ public static function getTypesMap() { - return self::$_typesMap; + return array_map( + static function (Type $type) : string { + return get_class($type); + }, + self::getTypeRegistry()->getMap() + ); } /** @@ -255,9 +309,14 @@ public static function getTypesMap() */ public function __toString() { - $e = explode('\\', static::class); + $type = static::class; + $position = strrpos($type, '\\'); + + if ($position !== false) { + $type = substr($type, $position); + } - return str_replace('Type', '', end($e)); + return str_replace('Type', '', $type); } /** diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php new file mode 100644 index 000000000..7e8093cf7 --- /dev/null +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/TypeRegistry.php @@ -0,0 +1,118 @@ + Map of type names and their corresponding flyweight objects. */ + private $instances = []; + + /** + * Finds a type by the given name. + * + * @throws DBALException + */ + public function get(string $name) : Type + { + if (! isset($this->instances[$name])) { + throw DBALException::unknownColumnType($name); + } + + return $this->instances[$name]; + } + + /** + * Finds a name for the given type. + * + * @throws DBALException + */ + public function lookupName(Type $type) : string + { + $name = $this->findTypeName($type); + + if ($name === null) { + throw DBALException::typeNotRegistered($type); + } + + return $name; + } + + /** + * Checks if there is a type of the given name. + */ + public function has(string $name) : bool + { + return isset($this->instances[$name]); + } + + /** + * Registers a custom type to the type map. + * + * @throws DBALException + */ + public function register(string $name, Type $type) : void + { + if (isset($this->instances[$name])) { + throw DBALException::typeExists($name); + } + + if ($this->findTypeName($type) !== null) { + throw DBALException::typeAlreadyRegistered($type); + } + + $this->instances[$name] = $type; + } + + /** + * Overrides an already defined type to use a different implementation. + * + * @throws DBALException + */ + public function override(string $name, Type $type) : void + { + if (! isset($this->instances[$name])) { + throw DBALException::typeNotFound($name); + } + + if (! in_array($this->findTypeName($type), [$name, null], true)) { + throw DBALException::typeAlreadyRegistered($type); + } + + $this->instances[$name] = $type; + } + + /** + * Gets the map of all registered types and their corresponding type instances. + * + * @internal + * + * @return array + */ + public function getMap() : array + { + return $this->instances; + } + + private function findTypeName(Type $type) : ?string + { + $name = array_search($type, $this->instances, true); + + if ($name === false) { + return null; + } + + return $name; + } +} diff --git a/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php b/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php new file mode 100644 index 000000000..2ffd1061f --- /dev/null +++ b/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php @@ -0,0 +1,43 @@ + - - + + + + + + */lib/* + + + + */lib/* @@ -41,6 +49,7 @@ lib/Doctrine/DBAL/Platforms/AbstractPlatform.php lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php + tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php @@ -60,7 +69,14 @@ - + lib/Doctrine/DBAL/Schema/Comparator.php + + + + lib/Doctrine/DBAL/Types/ArrayType.php + lib/Doctrine/DBAL/Types/ObjectType.php + tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php + diff --git a/doctrine/dbal/phpstan.neon.dist b/doctrine/dbal/phpstan.neon.dist new file mode 100644 index 000000000..4ae1fda3f --- /dev/null +++ b/doctrine/dbal/phpstan.neon.dist @@ -0,0 +1,58 @@ +parameters: + level: 7 + paths: + - %currentWorkingDirectory%/lib + autoload_files: + - %currentWorkingDirectory%/tests/phpstan-polyfill.php + reportUnmatchedIgnoredErrors: false + ignoreErrors: + # extension not available + - '~^(Used )?(Function|Constant) sasql_\S+ not found\.\z~i' + + # removing it would be BC break + - '~^Constructor of class Doctrine\\DBAL\\Schema\\Table has an unused parameter \$idGeneratorType\.\z~' + + # declaring $tableName in AbstractSchemaManager::_getPortableTableIndexesList() non-optional will be a BC break + - '~^Parameter #2 \$table of class Doctrine\\DBAL\\Event\\SchemaIndexDefinitionEventArgs constructor expects string, string\|null given\.\z~' + + # changing these would be a BC break, to be done in next major + - "~^Casting to bool something that's already bool.~" + - "~^Casting to int something that's already int.~" + - '~^Method Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Connection::exec\(\) should return int but returns bool\.\z~' + - '~^Method Doctrine\\DBAL\\Query\\QueryBuilder::execute\(\) should return Doctrine\\DBAL\\Driver\\Statement\|int but returns Doctrine\\DBAL\\Driver\\ResultStatement\.\z~' + - '~^Property Doctrine\\DBAL\\Schema\\Table::\$_primaryKeyName \(string\) does not accept (default value of type )?false\.\z~' + - '~^Property Doctrine\\DBAL\\Schema\\Schema::\$_schemaConfig \(Doctrine\\DBAL\\Schema\\SchemaConfig\) does not accept default value of type false\.\z~' + - '~^Method Doctrine\\DBAL\\Schema\\ForeignKeyConstraint::onEvent\(\) should return string\|null but returns false\.\z~' + - '~^Method Doctrine\\DBAL\\Schema\\(Oracle|PostgreSql|SQLServer)SchemaManager::_getPortableTableDefinition\(\) should return array but returns string\.\z~' + - '~^Method Doctrine\\DBAL\\Platforms\\(|SQLAnywhere|Sqlite)Platform::_getTransactionIsolationLevelSQL\(\) should return string but returns int\.\z~' + - '~^Method Doctrine\\DBAL\\Driver\\OCI8\\OCI8Connection::lastInsertId\(\) should return string but returns (int|false)\.\z~' + - '~^Method Doctrine\\DBAL\\Driver\\SQLSrv\\SQLSrvConnection::errorCode\(\) should return string\|null but returns false\.\z~' + + # https://bugs.php.net/bug.php?id=78126 + - '~^Call to an undefined method Doctrine\\DBAL\\Driver\\PDOConnection::sqliteCreateFunction\(\)\.\z~' + + # https://github.com/phpstan/phpstan/issues/1847 + - '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::unknownAlias\(\) expects array, array given\.\z~' + - '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::nonUniqueAlias\(\) expects array, array given\.\z~' + + # PHPStan is too strict about preg_replace(): https://phpstan.org/r/993dc99f-0d43-4b51-868b-d01f982c1463 + - '~^Method Doctrine\\DBAL\\Platforms\\AbstractPlatform::escapeStringForLike\(\) should return string but returns string|null\.\z~' + + # legacy variadic-like signature + - '~^Method Doctrine\\DBAL(\\.*)?Connection::query\(\) invoked with \d+ parameters?, 0 required\.\z~' + + # some drivers actually do accept 2nd parameter... + - '~^Method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getListTableForeignKeysSQL\(\) invoked with \d+ parameters, 1 required\.\z~' + + # legacy remnants from doctrine/common + - '~^Class Doctrine\\Common\\(Collections\\Collection|Persistence\\Proxy) not found\.\z~' + - '~^.+ on an unknown class Doctrine\\Common\\(Collections\\Collection|Persistence\\Proxy)\.\z~' + + # inheritance variance inference issue + - '~^Method Doctrine\\DBAL\\Driver\\PDOConnection::\w+\(\) should return Doctrine\\DBAL\\Driver\\Statement but returns PDOStatement\.\z~' + + # may not exist when pdo_sqlsrv is not loaded but PDO is + - '~^Access to undefined constant PDO::SQLSRV_ENCODING_BINARY\.\z~' + + # weird class name, represented in stubs as OCI_(Lob|Collection) + - '~unknown class OCI-(Lob|Collection)~' diff --git a/doctrine/event-manager/.doctrine-project.json b/doctrine/event-manager/.doctrine-project.json new file mode 100644 index 000000000..f6feb43c4 --- /dev/null +++ b/doctrine/event-manager/.doctrine-project.json @@ -0,0 +1,18 @@ +{ + "active": true, + "name": "Event Manager", + "slug": "event-manager", + "docsSlug": "doctrine-event-manager", + "versions": [ + { + "name": "1.0", + "branchName": "master", + "slug": "latest", + "current": true, + "aliases": [ + "current", + "stable" + ] + } + ] +} diff --git a/doctrine/event-manager/.scrutinizer.yml b/doctrine/event-manager/.scrutinizer.yml deleted file mode 100644 index 626a47895..000000000 --- a/doctrine/event-manager/.scrutinizer.yml +++ /dev/null @@ -1,29 +0,0 @@ -build: - nodes: - analysis: - environment: - php: - version: 7.1 - cache: - disabled: false - directories: - - ~/.composer/cache - project_setup: - override: true - tests: - override: - - php-scrutinizer-run - - phpcs-run - dependencies: - override: - - composer install -noa - -tools: - external_code_coverage: - timeout: 600 - -build_failure_conditions: - - 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed - - 'issues.label("coding-style").new.exists' # No new coding style issues allowed - - 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity - - 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection diff --git a/doctrine/event-manager/composer.json b/doctrine/event-manager/composer.json index b86855453..c0d3a8475 100644 --- a/doctrine/event-manager/composer.json +++ b/doctrine/event-manager/composer.json @@ -1,8 +1,14 @@ { "name": "doctrine/event-manager", "type": "library", - "description": "Doctrine Event Manager component", - "keywords": ["eventmanager", "eventdispatcher", "event"], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "keywords": [ + "events", + "event", + "event dispatcher", + "event manager", + "event system" + ], "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "license": "MIT", "authors": [ @@ -17,12 +23,15 @@ "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0", - "doctrine/coding-standard": "^4.0" + "doctrine/coding-standard": "^6.0", + "phpunit/phpunit": "^7.0" }, "conflict": { "doctrine/common": "<2.9@dev" }, + "config": { + "sort-packages": true + }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" diff --git a/doctrine/event-manager/docs/en/index.rst b/doctrine/event-manager/docs/en/index.rst deleted file mode 100644 index 4872d3347..000000000 --- a/doctrine/event-manager/docs/en/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -Event Manager Documentation -=========================== - -The Doctrine Event Manager documentation is a reference guide to everything you need -to know about the project. - -Getting Help ------------- - -If this documentation is not helping to answer questions you have about the -Doctrine DBAL, don't panic. You can get help from different sources: - -- Gitter chat room `#doctrine/event-manager `_ -- On `Stack Overflow `_ -- The `Doctrine Mailing List `_ -- Report a bug on `GitHub `_. - -Getting Started ---------------- - -The best way to get started is with the :doc:`Introduction ` section -in the documentation. Use the sidebar to browse other documentation for the Doctrine Event Manager. diff --git a/doctrine/event-manager/docs/en/reference/index.rst b/doctrine/event-manager/docs/en/reference/index.rst deleted file mode 100644 index 2b092859c..000000000 --- a/doctrine/event-manager/docs/en/reference/index.rst +++ /dev/null @@ -1,133 +0,0 @@ -Introduction -============ - -The Doctrine Event Manager is a simple event system used by the various Doctrine projects. It was originally built -for the DBAL and ORM but over time other projects adopted it and now it is available as a standalone library. - -Installation -============ - -The library can easily be installed with composer. - -.. code-block:: sh - - $ composer require doctrine/event-manager - -Setup -===== - -The event system is controlled by the ``Doctrine\Common\EventManager`` class. - -.. code-block:: php - - use Doctrine\Common\EventManager; - - $eventManager = new EventManager(); - -Listeners -========= - -Now you are ready to listen for events. Here is an example of a custom event listener named ``TestEvent``. - -.. code-block:: php - - use Doctrine\Common\EventArgs; - use Doctrine\Common\EventManager; - - final class TestEvent - { - public const preFoo = 'preFoo'; - public const postFoo = 'postFoo'; - - /** @var EventManager */ - private $eventManager; - - /** @var bool */ - public $preFooInvoked = false; - - /** @var bool */ - public $postFooInvoked = false; - - public function __construct(EventManager $eventManager) - { - $eventManager->addEventListener([self::preFoo, self::postFoo], $this); - } - - public function preFoo(EventArgs $eventArgs) : void - { - $this->preFooInvoked = true; - } - - public function postFoo(EventArgs $eventArgs) : void - { - $this->postFooInvoked = true; - } - } - - // Create a new instance - $testEvent = new TestEvent($eventManager); - -Dispatching Events -================== - -Now you can dispatch events with the ``dispatchEvent()`` method. - -.. code-block:: php - - $eventManager->dispatchEvent(TestEvent::preFoo); - $eventManager->dispatchEvent(TestEvent::postFoo); - -Removing Event Listeners -======================== - -You can easily remove a listener with the ``removeEventListener()`` method. - -.. code-block:: php - - $eventManager->removeEventListener([TestEvent::preFoo, TestEvent::postFoo], $testEvent); - -Event Subscribers -================= - -The Doctrine event system also has a simple concept of event subscribers. We can define a simple ``TestEventSubscriber`` class which implements the ``Doctrine\Common\EventSubscriber`` interface with a ``getSubscribedEvents()`` method which returns an array of events it should be subscribed to. - -.. code-block:: php - - use Doctrine\Common\EventSubscriber; - - final class TestEventSubscriber implements EventSubscriber - { - /** @var bool */ - public $preFooInvoked = false; - - public function preFoo() : void - { - $this->preFooInvoked = true; - } - - public function getSubscribedEvents() : array - { - return [TestEvent::preFoo]; - } - } - - $eventSubscriber = new TestEventSubscriber(); - $eventManager->addEventSubscriber($eventSubscriber); - -.. note:: - - The array returned by the ``getSubscribedEvents()`` method is a simple array with the values being the event names. The subscriber must have a method that is named exactly like the event. - -Now when you dispatch an event, any event subscribers will be notified of that event. - -.. code-block:: php - - $eventManager->dispatchEvent(TestEvent::preFoo); - -Now you can check the ``preFooInvoked`` property to see if the event subscriber was notified of the event: - -.. code-block:: php - - if ($eventSubscriber->preFooInvoked) { - // the preFoo method was invoked - } diff --git a/doctrine/event-manager/docs/en/sidebar.rst b/doctrine/event-manager/docs/en/sidebar.rst deleted file mode 100644 index 0672d8d3e..000000000 --- a/doctrine/event-manager/docs/en/sidebar.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. toctree:: - :depth: 3 - - reference/index diff --git a/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php b/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php index 12e6256db..9b9cc0565 100644 --- a/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php +++ b/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php @@ -29,9 +29,8 @@ class EventArgs * The benefit from this is that only one empty instance is instantiated and shared * (otherwise there would be instances for every dispatched in the abovementioned form). * - * @see EventManager::dispatchEvent - * * @link https://msdn.microsoft.com/en-us/library/system.eventargs.aspx + * @see EventManager::dispatchEvent * * @return EventArgs */ diff --git a/doctrine/event-manager/lib/Doctrine/Common/EventManager.php b/doctrine/event-manager/lib/Doctrine/Common/EventManager.php index 2eb6e6172..a0860e37e 100644 --- a/doctrine/event-manager/lib/Doctrine/Common/EventManager.php +++ b/doctrine/event-manager/lib/Doctrine/Common/EventManager.php @@ -1,4 +1,5 @@