Doctrine DBAL
4.0-dev | 3.0 | 2.13 |
---|---|---|
N/A | N/A |
Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction.
This is an initial draft [POC] for testing of MSSQL on windows with AppVeyor
This PR creates the initial draft configuration files for AppVeyor CI testing, adjustments may be needed to meet project configuration needs.
For more information see issue #2616
New Feature CI SQL ServerInitial support for MariaDB 10.2.7+.
Doctrine currently does not support MariaDB 10.2.7+. Schema creation/update is triggering infinite schema diffs
Updated: Title updated from 'MariaDB 10.2 support (will also fix version detection), version detection should be considered as new feature.
To circumvent a limitation in the replication protocol, MariaDB 10+ use a prefixed version with '5.5.5-' (for instance
5.5.5-Mariadb-10.0.8-xenial
). This cause issues with the current detection mechanism with both Mysqli and PDOMysql dbal implementations (always detect 5.5.5). While mariadb strips the prefix automatically in theirlibmariadb-client
, most (if not all) of php installations relies onmysqlnd
, so the removal of the prefix5.5.5-
must be made in userland (MysqliConnection.php and AbstractMySQLDriver.php). See https://jira.mariadb.org/browse/MDEV-4088 for reference.
BLOB/TEXT
defaults values (since 10.2.1).~Update: Removed from this P/R... will be made available in a subsequent P/R (due to architecture decision to be made - current doctrine implementation needs to be reworked)
Note that Mysql (as of 5.7.19) is not yet supporting defaults for BLOB and TEXT.
See https://mariadb.com/kb/en/library/blob-and-text-data-types
JSON
type.~Removed from P/R by @lcobucci, probably to reflect the fact that MariaDB alias JSON to MEDIUMTEXT
~The JSON type have been introduced in 10.2.7 as an alias to LONGTEXT. See https://mariadb.com/kb/en/library/json-data-type/ To ensure portability between MySQL/Mariadb, the best is to prefer TEXT type over JSON when defining schema (till a real JSON type appears in Maria).~
CURRENT_TIME
, CURRENT_DATE
as default valuesNote that MySQL (as of 5.7.19) does not support default values CURRENT_TIME and CURRENT_DATE as default values for TIME and DATE columns (CURRENT_TIMESTAMP for DATETIME is supported).
Update: Removed from this PR in favor of #2850... Current doctrine implementation does not handle escaping of defaults (backslashes...), adding it in this P/R should be done for all platforms at once and thus introduce more BC-risks (bugs...). Implementing separately looks safer and should help having this P/R sooner. Both P/R can be done independently.
~While table comments are automatically quoted (
MySQLPlatform::quoteStringLiteral()
) the default column values were not. Defaults values for string literals are now properly quoted.~
In order to allow expressions as default values and distinguish them from literals, Mariadb now quotes default values in
information_schema.column
table. This changes brings a lot of incompatibilities between the (Oracle-)Mysql/MariaDB platforms.Instead of creating a specific SchemaManager for MariaDB, the solution taken in this P/R is to map the introduced changes in the current
MySQLSchemaManager
(method: getMariaDb1027ColumnDefault()).From MariaDB 10.2.7, information schema changes includes:
- NULL is now quoted as 'NULL' (see exceptions in https://jira.mariadb.org/browse/MDEV-14053. Unquoted null is technically possible)
- String defaults are quoted (To save the string 'NULL', set the default as ''NULL'').
- CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME defaults are silently changed to 'current_timestamp()', 'currdate()', 'currtime()'. To prevent schema diff, they are mapped back to their original values.
- (UPDATED) Partial support for default literal escaping have been done. Currently limited on schema introspection. #2850 will bring the support for backslashes in defaults later on but the code is ready.
See https://mariadb.com/kb/en/library/information-schema-columns-table/ for reference and https://jira.mariadb.org/browse/MDEV-13132, https://jira.mariadb.org/browse/MDEV-13341 for history.
Will fix:
- https://github.com/doctrine/dbal/issues/2817 (invalid detection of column default values)
- https://github.com/doctrine/doctrine2/issues/6565 (schema update will alter all tables with columns_default='null')
[x] 7. Support for MariaDB 10.2 reserved keywords.
[x] 8. Added MariaDB 10.2 in travis (both pdo_mysql and mysqli)
None found. Since the extraction of defaults escaping in #2850, there should be no impact on other platforms.
This is a proposal for a Transaction object, as suggested by @guilhermeblanco and @beberlei in doctrine/doctrine2#949; this is a foundation for the proposed ORM feature. This supersedes #571.
This PR makes the following changes to Connection
:
getTransactionManager()
: returns the TransactionManager
Transaction
:
commit()
rollBack()
setRollbackOnly()
isRollbackOnly()
TransactionManager
:
beginTransaction()
isTransactionActive()
getTransactionNestingLevel()
setNestTransactionsWithSavepoints()
getNestTransactionsWithSavepoints()
The new way of dealing with transactions is now:
$transactionManager = $connection->getTransactionManager();
$transaction = $transactionManager->beginTransaction();
// ...
$transaction->commit();
A fluent API is available to configure a transaction:
$transaction = $transactionManager->createTransaction()
->withIsolationLevel(Connection::TRANSACTION_SERIALIZABLE)
->begin();
Calls to commit()
and rollback()
are automatically propagated to nested transactions:
$transaction1 = $transactionManager->beginTransaction();
$transaction2 = $transactionManager->beginTransaction();
$transaction1->commit(); // will commit $transaction2 then $transaction1
Overall, it's not a complicated change, does not introduce any BC break, and passes all existing tests.
New FeatureIt is now possible to use \
, or other escaped characters, in default
values for a column.
Previously this lead to a confusion when diffing actual and expected schema leading to perpetual out of sync schema.
Bug MySQL Schema ManagementAs of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column:
http://dev.mysql.com/doc/refman/5.7/en/json.html
Improvement MySQL Platforms Type Mapping ColumnsThis is a patch for https://github.com/doctrine/dbal/pull/540.
It includes the following bugfixes:
Doctrine\DBAL\Schema\Table
Todo:
tests/travis
?| Q | A |------------- | ----------- | Type | bug | BC Break | no | Fixed issues | #4283
Alternative to closes https://github.com/doctrine/dbal/pull/4284 to fix it correctly and with proper functional tests.
The issue was that MSSQL expects string literal (quoted by '
) for EXEC sp_addextendedproperty
instead of identifier name (quoted by []
).
So this PR now only contains the explicit exceptions so they can be catched RDMBS agnostic.
Below description can be provided externally.
It is best practice to implement retry logic for transactions that are aborted because of deadlocks or timeouts. This makes such method available inside the DBAL and also adds detection for errors where retrying makes sense in the different database drivers.
Deadlocks and timeouts are caused by lock contention and you often can design your application to reduce the likeliness that such an error occurs. But it's impossible to guarantee that such error conditions will never occur. This is why implementing retrying logic for such errors is actually a must when you have to ensure the application does not fail in edge cases or high load. Some references where something similar has already been discussed and implemented:
I chose the name retryable
because it is consistent with transactional
. I think the implementation is quite straight forward and fits very well with the DBAL design.
In our case we had seldomly errors like
Doctrine\\DBAL\\Exception\\DriverException: An exception occurred while executing 'UPDATE product SET modified = ? WHERE id = ?' with params [\"2014-10-15 16:28:55\", \"460315800000\"]:\n\nSQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
Doctrine\\DBAL\\Exception\\DriverException: An exception occurred while executing 'INSERT INTO ... VALUES (...)' with params [\"...\", \"...\"]:\n\nSQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
As you can see even the exception message suggests to retry the transaction. This is now easily possible with
$retryWrapper = new RetryWrapper(function () use ($con) {
return $con->update('tablename', array('field' => 'data'), array('id' => 'myid'));
});
$affectedRows = $retryWrapper();
New Feature Drivers Error Handling Locking Transactions
| Q | A |------------- | ----------- | Type | bug | BC Break | no | Fixed issues |
The binary
and blob
types map BLOB
/BINARY
/VARBINARY
columns to PHP streams. Internally, they use the ParameterType::LARGE_OBJECT
(i. e. \PDO::PARAM_LOB
) binding type, which suggests that efficient handling of PHP stream resources was intended.
However, at least when using the mysqli
driver, stream resources passed into insert()
or update()
are simply cast to strings. As a result, a literal string like "Resource id #126"
will end up in the database.
This PR fixes the issue by correctly processing streams in the MysqliStatement
when they are passed with the ParameterType::LARGE_OBJECT
binding type. It uses the mysqli::send_long_data()
method to pass stream data in chunks to the MySQL server, thus keeping the memory footprint low. This method does not (despite claims to the contrary) allow to bypass the max_allowed_package
size.
Update: The pdo_mysql
driver was already capable of handling streams this way. Now this is covered by tests.
| Q | A |------------- | ----------- | Type | improvement | BC Break | no | Fixed issues | n/a
Minor code tweaks by Php Inspections (EA Ultimate)
Improvement| Q | A |------------- | ----------- | Type | improvement | Fixed issues |
Narrows down the mixed
return type from Type
in extending classes.
| Q | A |------------- | ----------- | Type | improvement
I submitted phpstan/phpstan-src#2036 to phpstan-src to make PDO, PDOException and PDOStatement return more detailed results. phpstan does integration tests for some repositories, including doctrin/dbal, and this PR is to fix the errors with dbal in the integration tests.
Already passed testing in local ✅
Static Analysis| Q | A |------------ | ------ | Version | 3.5.1
DBAL always generates ALTER TABLE for MySQL TEXT columns, even if there's no change. This behavior has been introduced with 3.4.0, before no statement was generated.
ALTER TABLE mshop_media CHANGE preview preview TEXT CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_general_ci`
Create migration that creates a table with TEXT column like this:
CREATE TABLE `mshop_media` (
`preview` text COLLATE utf8mb4_general_ci NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
Then, run migration again and an ALTER TABLE statement wiil be created.
No ALTER TABLE statement generated if the current text column is already up to date.
Bug Requires Feedback| Q | A |------------ | ------ | Version | 3.5.1
When migrating from a TEXT column with a serialized JSON content to a JSON column type, Doctrine DBAL generates an ALTER TABLE statement which contains CHARACTER SET and COLLATION not accepted by MySQL for JSON column types.
Generated statement:
ALTER TABLE mshop_media CHANGE preview preview JSON CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_general_ci`
Create a table with a TEXT column:
CREATE TABLE `mshop_media` (
`preview` text COLLATE utf8mb4_general_ci NOT NULL DEFAULT '{}',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
Then, try to change preview
column to a JSON column type using DBAL API.
Generated statement should be:
ALTER TABLE mshop_media CHANGE preview preview JSON
Bug Requires Feedback
| Q | A |------------ | ------ | New Feature | yes | RFC | yes
First of all, thanks to all maintainers of Doctrine. You make the world better. 👏
It would be neat if doctrine can run multiple queries without waiting for each to finish after executing the next one. Currently I have a use case for a search page, which queries the database several times and the total time of all queries is relatively big, but each query by itself takes no more than 300ms. Getting around this is no trivial task. Only if I could run these queries in parallel. It seems that PHP 8.1 supports something like this with Fibers.
It there currently any limitation to implement parallelism in Doctrine? I'm sure that for most people this is must have feature and it would be very beneficial for the whole community.
New Feature Requires FeedbackRelease 3.5.2
generateCacheKeys()
thanks to @derrabusRelease 3.5.1
Release 4.0.0-beta1
isFullfilledBy()
method thanks to @nexxaidoctrine-dbal
binary thanks to @derrabusstrpos()
calls thanks to @derrabusReturnTypeWillChange
attribute thanks to @derrabusSqlitePlatform
to SQLitePlatform
thanks to @derrabus3119: Added "string" mapping in SqlitePlatform thanks to @DeyV
3081: collate gets suffix '_unicode_ci' which is bad for latin1 thanks to @dominikzogg
2388: CompositeExpression can't handle empty CompositeExpression objects thanks to @IchHabRecht
Release 3.5.0
5766: Deprecate SchemaDiff::toSql() and SchemaDiff::toSaveSql() thanks to @morozov
5761: Improve error message for index SQL creation thanks to @radar3301
%
operator instead of MOD()
in SQLite thanks to @derrabusLOCATE()
emulation on SQLite thanks to @derrabususerDefinedFunctions
driver option for pdo_sqlite
thanks to @derrabusRelease 3.4.6
$tableName
has no namespace. thanks to @kitloongRelease 3.4.5
Release 3.4.4
Release 3.4.3
Release 3.4.2
Release 3.4.1
Release 3.4.0
5500: Table schema clone is not needed in SqlitePlatform thanks to @mvorisek
5488: AbstractSchemaManager::listTableForeignKeys() should support listing for all tables at once thanks to @mvorisek
5419: Remove SchemaDiffVisitor thanks to @morozov
5397: Remove redundant (array) casts thanks to @morozov
Type::getName()
thanks to @greg0ireRelease 3.3.8
assertCount()
when possible thanks to @derrabusRelease 3.3.7
guid
type thanks to @kaznovacRelease 3.3.6
Release 3.3.5
Release 3.3.4
Release 3.3.3
compareSchemas()
calls thanks to @derrabusRelease 2.13.8
mysqli::real_connect()
calls thanks to @iammatiRelease 3.3.2
Release 3.3.1
\Doctrine\DBAL\Statement
vs. \Doctrine\DBAL\Driver\Statement
thanks to @staabmRelease 3.3.0
$lockMode
value range thanks to @derrabusPARAM_ASCII_ARRAY
to Doctrine\DBAL\Connection
thanks to @santojadoctrine-dbal
binary thanks to @derrabusConnection::getNativeConnection()
thanks to @derrabusRelease 3.2.2
Release 3.2.1
_getNestedTransactionSavePointName()
thanks to @derrabusSQLServer2012Platform
thanks to @derrabusRelease 2.13.7
unix_socket
option to the array shape for the connection params thanks to @ste93cryRelease 3.2.0
define()
check thanks to @derrabusdoctrine/cache
in favor of psr/cache
thanks to @derrabusmysqli_report()
call thanks to @derrabusRelease 3.1.5
Release 2.13.6
Release 3.1.4
SECURITY RELEASE: All users are advised to upgrade when using doctrine/dbal 3.0.0 - 3.1.3 due to a critical SQL injection that was fixed: https://github.com/doctrine/dbal/security/advisories/GHSA-r7cj-8hjg-x622
4939: Use CONCAT() with SQL Server to concatenate strings thanks to @morozov
3346: mssql 2016 SQLServer2012Platform::getConcatExpression() missing/wrong thanks to @Lacoi
4935: Workflow for closing stale pull requests thanks to @morozov
Release 2.13.5
ExpressionBuilder::literal()
with default type thanks to @derrabus and @come-ncRelease 3.1.3
4825: Fix version displayed in ConsoleRunner
thanks to @derrabus
4824: Remove pinned platform thanks to @derrabus
?? Simple MySQLi Class This is a simple MySQL Abstraction Layer compatible with PHP 7+ that provides a simple and secure interaction with your databas
Cycle DBAL Secure, multiple SQL dialects (MySQL, PostgreSQL, SQLite, SQLServer), schema introspection, schema declaration, smart identifier wrappers,
Orm What is it Orm is a simple database abstraction layer that supports postgresql. Welcome to join us or star us for encouragement. Requires php 8.1
RedBeanPHP 5 RedBeanPHP is an easy to use ORM tool for PHP. Automatically creates tables and columns as you go No configuration, just fire and forget
Laravel 5 Repositories Laravel 5 Repositories is used to abstract the data layer, making our application more flexible to maintain. See versions: 1.0.
Lada Cache A Redis based, fully automated and scalable database cache layer for Laravel Contributors wanted! Have a look at the open issues and send m
3.0.x 2.9.x 2.8.x Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence for PHP objects. It sits on top o
Laravel Doctrine ORM A drop-in Doctrine ORM 2 implementation for Laravel 5+ $scientist = new Scientist( 'Albert', 'Einstein' ); $scientist->a
Swoole Coroutine PostgreSQL Doctrine DBAL Driver A Doctrine\DBAL\Driver implementation on top of Swoole\Coroutine\PostgreSQL. Getting started Install
doctrine-mongodb-psalm-plugin A Doctrine plugin for Psalm (requires Psalm v4). Installation: $ composer require --dev runtothefather/doctrine-mongodb-
Doctrine Bridge The Doctrine bridge provides integration for Doctrine with various Symfony components. Resources Contributing Report issues and send P
WORK IN PROGRESS! Doctrine PHP mapping driver Alternative mapping driver that allows to write mappings in PHP. Documentation Associations examples TOD
doctrine-Spatial Doctrine-spatial is a doctrine extension. It implements spatial types and functions. As exemple, this extension can help you to know
Doctrine Repository Monadic Helper Description This project provides the necessary classes and services to use Doctrine repositories in a more functio
PostgreSQL enhancements for Doctrine. Provides support for advanced data types (json, jssnb, arrays), text search, array operators and jsonb specific functions.
Please give it a Star if you like the project ?? ❤️ SleekDB - A NoSQL Database made using PHP Full documentation: https://sleekdb.github.io/ SleekDB i
SleekwareDB is a NoSQL database storage service. A database storage service that can be used for various platforms and is easy to integrate. NoSQL API
The lightweight PHP database framework to accelerate development Features Lightweight - Less than 100 KB, portable with only one file Easy - Extremely
Illuminate Database The Illuminate Database component is a full database toolkit for PHP, providing an expressive query builder, ActiveRecord style OR