mirror of
https://github.com/doctrine/orm.git
synced 2026-03-25 23:42:19 +01:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01187c9260 | ||
|
|
404edd418b | ||
|
|
011d3c21eb | ||
|
|
b1ac293a50 | ||
|
|
f4ebded63c | ||
|
|
385b5a2f80 | ||
|
|
fa6fe09647 | ||
|
|
c270eba678 | ||
|
|
2f0eb95c90 | ||
|
|
b13b2e8bab | ||
|
|
ca27cc3f72 | ||
|
|
5fde5801c1 | ||
|
|
18d96fcc02 | ||
|
|
4d2908a065 | ||
|
|
8d250f5921 | ||
|
|
59fd9b5ea7 | ||
|
|
8fcc70cfbe | ||
|
|
7d84a49980 | ||
|
|
bb64fc953d | ||
|
|
e0eb82a3b1 | ||
|
|
79cdcde9ec | ||
|
|
f4524a8bb0 | ||
|
|
d810ea4111 | ||
|
|
107ba93d79 | ||
|
|
706670215d | ||
|
|
ab2b4987b3 | ||
|
|
717ef9106c | ||
|
|
ccae8f7176 | ||
|
|
da18985aca | ||
|
|
1e2ed07731 | ||
|
|
424241f29c | ||
|
|
8230afcde9 | ||
|
|
7cffba8743 | ||
|
|
7e5fe79349 | ||
|
|
efd25484f4 | ||
|
|
271f3480c8 | ||
|
|
aab589b596 | ||
|
|
190218b267 | ||
|
|
181114f2c7 | ||
|
|
3689b76a86 | ||
|
|
75fe18ea5f | ||
|
|
6c73a6b720 | ||
|
|
775d91c2a3 | ||
|
|
64c3f68734 | ||
|
|
2a2a0b2980 | ||
|
|
a438e90046 | ||
|
|
6a670d7d6d | ||
|
|
765521d257 | ||
|
|
5ced62bf83 | ||
|
|
93867f8d77 | ||
|
|
d95e03ba66 | ||
|
|
825ceb6b7a | ||
|
|
de2e2a1d74 | ||
|
|
6780a963f7 | ||
|
|
4d172e2591 | ||
|
|
21a98234d0 | ||
|
|
8a9954e46c | ||
|
|
527fff53cc | ||
|
|
70fb1ecd78 | ||
|
|
73ec483e9d | ||
|
|
8d67eec812 | ||
|
|
a418cf6418 | ||
|
|
6138afdca9 |
49
.doctrine-project.json
Normal file
49
.doctrine-project.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"active": true,
|
||||
"name": "Object Relational Mapper",
|
||||
"shortName": "ORM",
|
||||
"slug": "orm",
|
||||
"docsSlug": "doctrine-orm",
|
||||
"versions": [
|
||||
{
|
||||
"name": "3.0",
|
||||
"branchName": "master",
|
||||
"slug": "latest",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.8",
|
||||
"branchName": "2.8.x",
|
||||
"slug": "2.8",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.7",
|
||||
"branchName": "2.7",
|
||||
"slug": "2.7",
|
||||
"current": true,
|
||||
"aliases": [
|
||||
"current",
|
||||
"stable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "2.6",
|
||||
"branchName": "2.6",
|
||||
"slug": "2.6",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.5",
|
||||
"branchName": "2.5",
|
||||
"slug": "2.5",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.4",
|
||||
"branchName": "2.4",
|
||||
"slug": "2.4",
|
||||
"maintained": false
|
||||
}
|
||||
]
|
||||
}
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,5 +1,6 @@
|
||||
/tests export-ignore
|
||||
/tools export-ignore
|
||||
/.github export-ignore
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.gitmodules export-ignore
|
||||
@@ -11,3 +12,6 @@ CONTRIBUTING.md export-ignore
|
||||
phpunit.xml.dist export-ignore
|
||||
run-all.sh export-ignore
|
||||
phpcs.xml.dist export-ignore
|
||||
phpbench.json export-ignore
|
||||
phpstan.neon export-ignore
|
||||
psalm.xml export-ignore
|
||||
|
||||
46
.github/workflows/coding-standard.yml
vendored
Normal file
46
.github/workflows/coding-standard.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Static Analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
coding-standards:
|
||||
name: "Coding Standards"
|
||||
runs-on: "ubuntu-latest"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 10
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
tools: "cs2pr"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v1"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
|
||||
- name: "Install git-phpcs"
|
||||
run: "wget https://github.com/diff-sniffer/git/releases/download/0.3.2/git-phpcs.phar"
|
||||
|
||||
- name: "Fetch head branch"
|
||||
run: "git remote set-branches --add origin $GITHUB_BASE_REF && git fetch origin $GITHUB_BASE_REF"
|
||||
|
||||
- name: "Run git-phpcs"
|
||||
run: "php git-phpcs.phar origin/$GITHUB_BASE_REF...$GITHUB_SHA --report=checkstyle | cs2pr"
|
||||
284
.github/workflows/continuous-integration.yml
vendored
Normal file
284
.github/workflows/continuous-integration.yml
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
name: "Continuous Integration"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
env:
|
||||
fail-fast: true
|
||||
|
||||
jobs:
|
||||
phpunit-smoke-check:
|
||||
name: "PHPUnit with SQLite"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.2"
|
||||
- "7.3"
|
||||
- "7.4"
|
||||
deps:
|
||||
- "normal"
|
||||
include:
|
||||
- deps: "low"
|
||||
php-version: "7.3"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
extensions: "pdo, pdo_sqlite"
|
||||
coverage: "pcov"
|
||||
ini-values: "zend.assertions=1"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v2"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
if: "${{ matrix.deps == 'normal' }}"
|
||||
|
||||
- name: "Install lowest possible dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-lowest"
|
||||
if: "${{ matrix.deps == 'low' }}"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --coverage-clover=coverage-no-cache.xml"
|
||||
env:
|
||||
ENABLE_SECOND_LEVEL_CACHE: 0
|
||||
|
||||
- name: "Run PHPUnit with Second Level Cache"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-cache.xml"
|
||||
env:
|
||||
ENABLE_SECOND_LEVEL_CACHE: 1
|
||||
|
||||
- name: "Upload coverage file"
|
||||
uses: "actions/upload-artifact@v2"
|
||||
with:
|
||||
name: "phpunit-sqlite-${{ matrix.deps }}-${{ matrix.php-version }}-coverage"
|
||||
path: "coverage*.xml"
|
||||
|
||||
|
||||
phpunit-postgres:
|
||||
name: "PHPUnit with PostgreSQL"
|
||||
runs-on: "ubuntu-20.04"
|
||||
needs: "phpunit-smoke-check"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
postgres-version:
|
||||
- "9.6"
|
||||
- "13"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: "postgres:${{ matrix.postgres-version }}"
|
||||
env:
|
||||
POSTGRES_PASSWORD: "postgres"
|
||||
|
||||
options: >-
|
||||
--health-cmd "pg_isready"
|
||||
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
coverage: "pcov"
|
||||
ini-values: "zend.assertions=1"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v2"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml"
|
||||
|
||||
- name: "Upload coverage file"
|
||||
uses: "actions/upload-artifact@v2"
|
||||
with:
|
||||
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-coverage"
|
||||
path: "coverage.xml"
|
||||
|
||||
|
||||
phpunit-mariadb:
|
||||
name: "PHPUnit with MariaDB"
|
||||
runs-on: "ubuntu-20.04"
|
||||
needs: "phpunit-smoke-check"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
mariadb-version:
|
||||
- "10.5"
|
||||
extension:
|
||||
- "mysqli"
|
||||
- "pdo_mysql"
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: "mariadb:${{ matrix.mariadb-version }}"
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: "doctrine_tests"
|
||||
|
||||
options: >-
|
||||
--health-cmd "mysqladmin ping --silent"
|
||||
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
coverage: "pcov"
|
||||
ini-values: "zend.assertions=1"
|
||||
extensions: "${{ matrix.extension }}"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v2"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml"
|
||||
|
||||
- name: "Upload coverage file"
|
||||
uses: "actions/upload-artifact@v2"
|
||||
with:
|
||||
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-coverage"
|
||||
path: "coverage.xml"
|
||||
|
||||
|
||||
phpunit-mysql:
|
||||
name: "PHPUnit with MySQL"
|
||||
runs-on: "ubuntu-20.04"
|
||||
needs: "phpunit-smoke-check"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
mysql-version:
|
||||
- "5.7"
|
||||
- "8.0"
|
||||
extension:
|
||||
- "mysqli"
|
||||
- "pdo_mysql"
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: "mysql:${{ matrix.mysql-version }}"
|
||||
|
||||
options: >-
|
||||
--health-cmd "mysqladmin ping --silent"
|
||||
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
||||
-e MYSQL_DATABASE=doctrine_tests
|
||||
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
coverage: "pcov"
|
||||
ini-values: "zend.assertions=1"
|
||||
extensions: "${{ matrix.extension }}"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v2"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage-no-cache.xml"
|
||||
env:
|
||||
ENABLE_SECOND_LEVEL_CACHE: 0
|
||||
|
||||
- name: "Run PHPUnit with Second Level Cache"
|
||||
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-no-cache.xml"
|
||||
env:
|
||||
ENABLE_SECOND_LEVEL_CACHE: 1
|
||||
|
||||
- name: "Upload coverage files"
|
||||
uses: "actions/upload-artifact@v2"
|
||||
with:
|
||||
name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-coverage"
|
||||
path: "coverage*.xml"
|
||||
|
||||
upload_coverage:
|
||||
name: "Upload coverage to Codecov"
|
||||
runs-on: "ubuntu-20.04"
|
||||
needs:
|
||||
- "phpunit-smoke-check"
|
||||
- "phpunit-postgres"
|
||||
- "phpunit-mariadb"
|
||||
- "phpunit-mysql"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Download coverage files"
|
||||
uses: "actions/download-artifact@v2"
|
||||
with:
|
||||
path: "reports"
|
||||
|
||||
- name: "Upload to Codecov"
|
||||
uses: "codecov/codecov-action@v1"
|
||||
with:
|
||||
directory: reports
|
||||
56
.github/workflows/release-on-milestone-closed.yml
vendored
Normal file
56
.github/workflows/release-on-milestone-closed.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: "Automatic Releases"
|
||||
|
||||
on:
|
||||
milestone:
|
||||
types:
|
||||
- "closed"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: "Git tag, release & create merge-up PR"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Release"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:release"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
"SHELL_VERBOSITY": "3"
|
||||
|
||||
- name: "Create Merge-Up Pull Request"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
|
||||
- name: "Create and/or Switch to new Release Branch"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
|
||||
- name: "Create new milestones"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:create-milestones"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
70
.github/workflows/static-analysis.yml
vendored
Normal file
70
.github/workflows/static-analysis.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
name: Static Analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
static-analysis-phpstan:
|
||||
name: "PHPStan"
|
||||
runs-on: "ubuntu-latest"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
tools: cs2pr
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v1"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-progress --no-suggest --no-interaction --prefer-dist"
|
||||
|
||||
- name: "Run a static analysis with phpstan/phpstan"
|
||||
run: "php vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
|
||||
|
||||
static-analysis-psalm:
|
||||
name: "Psalm"
|
||||
runs-on: "ubuntu-latest"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
|
||||
- name: "Cache dependencies installed with composer"
|
||||
uses: "actions/cache@v1"
|
||||
with:
|
||||
path: "~/.composer/cache"
|
||||
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: "composer update --no-interaction --no-progress --no-suggest"
|
||||
|
||||
- name: "Run a static analysis with vimeo/psalm"
|
||||
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,3 +14,5 @@ lib/Doctrine/DBAL
|
||||
vendor/
|
||||
/tests/Doctrine/Performance/history.db
|
||||
/.phpcs-cache
|
||||
composer.lock
|
||||
/.phpunit.result.cache
|
||||
|
||||
@@ -1,34 +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
|
||||
|
||||
before_commands:
|
||||
- "composer install --no-dev --prefer-source"
|
||||
|
||||
tools:
|
||||
external_code_coverage:
|
||||
timeout: 3600
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- docs
|
||||
- tools
|
||||
|
||||
build_failure_conditions:
|
||||
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse 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
|
||||
- 'patches.label("Unused Use Statements").new.exists' # No new unused imports patches allowed
|
||||
131
.travis.yml
131
.travis.yml
@@ -1,131 +0,0 @@
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
env:
|
||||
- DB=sqlite
|
||||
- DB=mysql
|
||||
- DB=pgsql
|
||||
|
||||
before_install:
|
||||
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
|
||||
- composer self-update
|
||||
|
||||
install: travis_retry composer validate --strict && composer update --prefer-dist
|
||||
|
||||
script:
|
||||
- if [[ "$DB" == "mysql" || "$DB" == "mariadb" ]]; then mysql -e "CREATE SCHEMA doctrine_tests; GRANT ALL PRIVILEGES ON doctrine_tests.* to travis@'%'"; fi
|
||||
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml
|
||||
- ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: Test
|
||||
env: DB=mariadb
|
||||
addons:
|
||||
mariadb: 10.1
|
||||
|
||||
- stage: Test
|
||||
dist: xenial
|
||||
env: DB=mysql MYSQL_VERSION=5.7
|
||||
php: 7.1
|
||||
services:
|
||||
- mysql
|
||||
before_script:
|
||||
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
|
||||
sudo: required
|
||||
|
||||
- stage: Test
|
||||
dist: xenial
|
||||
env: DB=mysql MYSQL_VERSION=5.7
|
||||
php: 7.2
|
||||
services:
|
||||
- mysql
|
||||
before_script:
|
||||
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
|
||||
sudo: required
|
||||
|
||||
- stage: Test
|
||||
dist: xenial
|
||||
env: DB=mysql MYSQL_VERSION=5.7
|
||||
php: 7.4
|
||||
services:
|
||||
- mysql
|
||||
before_script:
|
||||
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
|
||||
sudo: required
|
||||
|
||||
- stage: Test
|
||||
env: DB=sqlite DEPENDENCIES=low
|
||||
install: travis_retry composer update --prefer-dist --prefer-lowest
|
||||
|
||||
- stage: Test
|
||||
if: type = cron
|
||||
php: 7.3
|
||||
env: DB=sqlite DEV_DEPENDENCIES
|
||||
install:
|
||||
- composer config minimum-stability dev
|
||||
- travis_retry composer update --prefer-dist
|
||||
|
||||
- stage: Test
|
||||
env: DB=sqlite COVERAGE
|
||||
before_script:
|
||||
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,}
|
||||
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
|
||||
script:
|
||||
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --coverage-clover ./build/logs/clover.xml
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar
|
||||
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
|
||||
|
||||
- stage: Code Quality
|
||||
env: DB=none STATIC_ANALYSIS
|
||||
php: 7.4
|
||||
install: travis_retry composer install --prefer-dist
|
||||
before_script:
|
||||
- echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- echo "extension=redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- travis_retry composer require --dev --prefer-dist --prefer-stable phpstan/phpstan:^0.9
|
||||
script: vendor/bin/phpstan analyse -l 1 -c phpstan.neon lib
|
||||
|
||||
- stage: Code Quality
|
||||
env: DB=none BENCHMARK
|
||||
before_script: wget https://phpbench.github.io/phpbench/phpbench.phar https://phpbench.github.io/phpbench/phpbench.phar.pubkey
|
||||
script: php phpbench.phar run -l dots --report=default
|
||||
|
||||
- stage: Code Quality
|
||||
if: NOT type = pull_request
|
||||
env: DB=none CODING_STANDARDS
|
||||
php: 7.4
|
||||
install: travis_retry composer install --prefer-dist
|
||||
script:
|
||||
- ./vendor/bin/phpcs
|
||||
|
||||
- stage: Code Quality
|
||||
if: type = pull_request
|
||||
env: DB=none PULL_REQUEST_CODING_STANDARDS
|
||||
php: 7.1
|
||||
install: travis_retry composer install --prefer-dist
|
||||
script:
|
||||
- |
|
||||
if [ $TRAVIS_BRANCH != "master" ]; then
|
||||
git remote set-branches --add origin $TRAVIS_BRANCH;
|
||||
git fetch origin $TRAVIS_BRANCH;
|
||||
fi
|
||||
- git merge-base origin/$TRAVIS_BRANCH $TRAVIS_PULL_REQUEST_SHA || git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge --unshallow
|
||||
- wget https://github.com/diff-sniffer/git/releases/download/0.2.0/git-phpcs.phar
|
||||
- php git-phpcs.phar origin/$TRAVIS_BRANCH...$TRAVIS_PULL_REQUEST_SHA
|
||||
|
||||
allow_failures:
|
||||
- stage: Code Quality
|
||||
env: DB=none CODING_STANDARDS
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
18
README.md
18
README.md
@@ -1,7 +1,7 @@
|
||||
| [Master][Master] | [2.5][2.5] |
|
||||
| [Master][Master] | [2.7][2.7] |
|
||||
|:----------------:|:----------:|
|
||||
| [![Build status][Master image]][Master] | [![Build status][2.5 image]][2.5] |
|
||||
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][2.5 coverage image]][2.5 coverage] |
|
||||
| [![Build status][Master image]][Master] | [![Build status][2.7 image]][2.7] |
|
||||
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][2.7 coverage image]][2.7 coverage] |
|
||||
|
||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence
|
||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||
@@ -18,9 +18,9 @@ without requiring unnecessary code duplication.
|
||||
|
||||
[Master image]: https://img.shields.io/travis/doctrine/orm/master.svg?style=flat-square
|
||||
[Master]: https://travis-ci.org/doctrine/orm
|
||||
[Master coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/orm/master.svg?style=flat-square
|
||||
[Master coverage]: https://scrutinizer-ci.com/g/doctrine/orm/?branch=master
|
||||
[2.5 image]: https://img.shields.io/travis/doctrine/orm/2.5.svg?style=flat-square
|
||||
[2.5]: https://github.com/doctrine/orm/tree/2.5
|
||||
[2.5 coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/orm/2.5.svg?style=flat-square
|
||||
[2.5 coverage]: https://scrutinizer-ci.com/g/doctrine/orm/?branch=2.5
|
||||
[Master coverage image]: https://codecov.io/gh/doctrine/orm/branch/master/graph/badge.svg
|
||||
[Master coverage]: https://codecov.io/gh/doctrine/orm/branch/master
|
||||
[2.7 image]: https://img.shields.io/travis/doctrine/orm/2.7.svg?style=flat-square
|
||||
[2.7]: https://github.com/doctrine/orm/tree/2.7
|
||||
[2.7 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.7/graph/badge.svg
|
||||
[2.7 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.7
|
||||
|
||||
16
UPGRADE.md
16
UPGRADE.md
@@ -47,7 +47,7 @@ Whole Doctrine\ORM\Tools\Export namespace with all its members have been depreca
|
||||
## Deprecated `Doctrine\ORM\Proxy\Proxy` marker interface
|
||||
|
||||
Proxy objects in Doctrine ORM 3.0 will no longer implement `Doctrine\ORM\Proxy\Proxy` nor
|
||||
`Doctrine\Common\Persistence\Proxy`: instead, they implement
|
||||
`Doctrine\Persistence\Proxy`: instead, they implement
|
||||
`ProxyManager\Proxy\GhostObjectInterface`.
|
||||
|
||||
These related classes have been deprecated:
|
||||
@@ -439,17 +439,17 @@ above you must implement these new methods.
|
||||
|
||||
## Metadata Drivers
|
||||
|
||||
Metadata drivers have been rewritten to reuse code from Doctrine\Common. Anyone who is using the
|
||||
Metadata drivers have been rewritten to reuse code from `Doctrine\Persistence`. Anyone who is using the
|
||||
`Doctrine\ORM\Mapping\Driver\Driver` interface should instead refer to
|
||||
`Doctrine\Common\Persistence\Mapping\Driver\MappingDriver`. Same applies to
|
||||
`Doctrine\Persistence\Mapping\Driver\MappingDriver`. Same applies to
|
||||
`Doctrine\ORM\Mapping\Driver\AbstractFileDriver`: you should now refer to
|
||||
`Doctrine\Common\Persistence\Mapping\Driver\FileDriver`.
|
||||
`Doctrine\Persistence\Mapping\Driver\FileDriver`.
|
||||
|
||||
Also, following mapping drivers have been deprecated, please use their replacements in Doctrine\Common as listed:
|
||||
|
||||
* `Doctrine\ORM\Mapping\Driver\DriverChain` => `Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain`
|
||||
* `Doctrine\ORM\Mapping\Driver\PHPDriver` => `Doctrine\Common\Persistence\Mapping\Driver\PHPDriver`
|
||||
* `Doctrine\ORM\Mapping\Driver\StaticPHPDriver` => `Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver`
|
||||
* `Doctrine\ORM\Mapping\Driver\DriverChain` => `Doctrine\Persistence\Mapping\Driver\MappingDriverChain`
|
||||
* `Doctrine\ORM\Mapping\Driver\PHPDriver` => `Doctrine\Persistence\Mapping\Driver\PHPDriver`
|
||||
* `Doctrine\ORM\Mapping\Driver\StaticPHPDriver` => `Doctrine\Persistence\Mapping\Driver\StaticPHPDriver`
|
||||
|
||||
# Upgrade to 2.2
|
||||
|
||||
@@ -538,7 +538,7 @@ Previously EntityManager#find(null) returned null. It now throws an exception.
|
||||
|
||||
## Interface for EntityRepository
|
||||
|
||||
The EntityRepository now has an interface Doctrine\Common\Persistence\ObjectRepository. This means that your classes that override EntityRepository and extend find(), findOneBy() or findBy() must be adjusted to follow this interface.
|
||||
The EntityRepository now has an interface Doctrine\Persistence\ObjectRepository. This means that your classes that override EntityRepository and extend find(), findOneBy() or findBy() must be adjusted to follow this interface.
|
||||
|
||||
## AnnotationReader changes
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@echo off
|
||||
|
||||
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
|
||||
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
|
||||
GOTO RUN
|
||||
:USE_PEAR_PATH
|
||||
set PHPBIN=%PHP_PEAR_PHP_BIN%
|
||||
:RUN
|
||||
"%PHPBIN%" "@bin_dir@\doctrine" %*
|
||||
@echo off
|
||||
|
||||
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
|
||||
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
|
||||
GOTO RUN
|
||||
:USE_PEAR_PATH
|
||||
set PHPBIN=%PHP_PEAR_PHP_BIN%
|
||||
:RUN
|
||||
"%PHPBIN%" "@bin_dir@\doctrine" %*
|
||||
|
||||
39
ci/github/phpunit/mysqli.xml
Normal file
39
ci/github/phpunit/mysqli.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<var name="db_driver" value="mysqli"/>
|
||||
<var name="db_host" value="127.0.0.1" />
|
||||
<var name="db_port" value="3306"/>
|
||||
<var name="db_user" value="root" />
|
||||
<var name="db_dbname" value="doctrine_tests" />
|
||||
|
||||
<!-- necessary change for some CLI/console output test assertions -->
|
||||
<env name="COLUMNS" value="120"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine DBAL Test Suite">
|
||||
<directory>../../../tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">../../../lib/Doctrine</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
<group>locking_functional</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
||||
40
ci/github/phpunit/pdo_mysql.xml
Normal file
40
ci/github/phpunit/pdo_mysql.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<var name="db_driver" value="pdo_mysql"/>
|
||||
<var name="db_host" value="127.0.0.1" />
|
||||
<var name="db_port" value="3306"/>
|
||||
<var name="db_user" value="root" />
|
||||
<var name="db_dbname" value="doctrine_tests" />
|
||||
|
||||
<!-- necessary change for some CLI/console output test assertions -->
|
||||
<env name="COLUMNS" value="120"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine DBAL Test Suite">
|
||||
<directory>../../../tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">../../../lib/Doctrine</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
<group>locking_functional</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
||||
39
ci/github/phpunit/pdo_pgsql.xml
Normal file
39
ci/github/phpunit/pdo_pgsql.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<var name="db_driver" value="pdo_pgsql"/>
|
||||
<var name="db_host" value="localhost" />
|
||||
<var name="db_user" value="postgres" />
|
||||
<var name="db_password" value="postgres" />
|
||||
<var name="db_dbname" value="doctrine_tests" />
|
||||
|
||||
<!-- necessary change for some CLI/console output test assertions -->
|
||||
<env name="COLUMNS" value="120"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine DBAL Test Suite">
|
||||
<directory>../../../tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">../../../lib/Doctrine</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
<group>locking_functional</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
||||
33
ci/github/phpunit/sqlite.xml
Normal file
33
ci/github/phpunit/sqlite.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<!-- necessary change for some CLI/console output test assertions -->
|
||||
<env name="COLUMNS" value="120"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine DBAL Test Suite">
|
||||
<directory>../../../tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">../../../lib/Doctrine</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
<group>locking_functional</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
||||
@@ -18,21 +18,25 @@
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/annotations": "^1.8",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"doctrine/annotations": "^1.11.1",
|
||||
"doctrine/cache": "^1.9.1",
|
||||
"doctrine/collections": "^1.5",
|
||||
"doctrine/common": "^2.11",
|
||||
"doctrine/common": "^2.11 || ^3.0",
|
||||
"doctrine/dbal": "^2.9.3",
|
||||
"doctrine/event-manager": "^1.1",
|
||||
"doctrine/inflector": "^1.0",
|
||||
"doctrine/instantiator": "^1.3",
|
||||
"doctrine/persistence": "^1.2",
|
||||
"ocramius/package-versions": "^1.2",
|
||||
"doctrine/lexer": "^1.0",
|
||||
"doctrine/persistence": "^1.3.3 || ^2.0",
|
||||
"symfony/console": "^3.0|^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^5.0",
|
||||
"phpunit/phpunit": "^7.5",
|
||||
"symfony/yaml": "^3.4|^4.0|^5.0"
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.12.18",
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"symfony/yaml": "^3.4|^4.0|^5.0",
|
||||
"vimeo/psalm": "^3.11"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
|
||||
|
||||
2793
composer.lock
generated
2793
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -7,4 +7,4 @@ rm build -Rf
|
||||
sphinx-build en build
|
||||
|
||||
sphinx-build -b latex en build/pdf
|
||||
rubber --into build/pdf --pdf build/pdf/Doctrine2ORM.tex
|
||||
rubber --into build/pdf --pdf build/pdf/Doctrine2ORM.tex
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
sudo apt-get update && sudo apt-get install -y python2.7 python-sphinx python-pygments
|
||||
sudo apt-get update && sudo apt-get install -y python2.7 python-sphinx python-pygments
|
||||
|
||||
@@ -22,7 +22,7 @@ into the account can either be of positive or negative money
|
||||
values. Each account has a credit limit and the account is never
|
||||
allowed to have a balance below that value.
|
||||
|
||||
For simplicity we live in a world were money is composed of
|
||||
For simplicity we live in a world where money is composed of
|
||||
integers only. Also we omit the receiver/sender name, stated reason
|
||||
for transfer and the execution date. These all would have to be
|
||||
added on the ``Entry`` object.
|
||||
@@ -32,30 +32,39 @@ Our entities look like:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
namespace Bank\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class Account
|
||||
{
|
||||
/** @Id @GeneratedValue @Column(type="integer") */
|
||||
private $id;
|
||||
|
||||
/** @Column(type="string", unique=true) */
|
||||
private $no;
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Entry", mappedBy="account", cascade={"persist"})
|
||||
* @ORM\Column(type="string", unique=true)
|
||||
*/
|
||||
private $entries;
|
||||
private string $no;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @ORM\OneToMany(targetEntity="Entry", mappedBy="account", cascade={"persist"})
|
||||
*/
|
||||
private $maxCredit = 0;
|
||||
private array $entries;
|
||||
|
||||
public function __construct($no, $maxCredit = 0)
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private int $maxCredit = 0;
|
||||
|
||||
public function __construct(string $no, int $maxCredit = 0)
|
||||
{
|
||||
$this->no = $no;
|
||||
$this->maxCredit = $maxCredit;
|
||||
@@ -64,31 +73,35 @@ Our entities look like:
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class Entry
|
||||
{
|
||||
/** @Id @GeneratedValue @Column(type="integer") */
|
||||
private $id;
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="Account", inversedBy="entries")
|
||||
* @ORM\ManyToOne(targetEntity="Account", inversedBy="entries")
|
||||
*/
|
||||
private $account;
|
||||
private Account $account;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $amount;
|
||||
private int $amount;
|
||||
|
||||
public function __construct($account, $amount)
|
||||
public function __construct(Account $account, int $amount)
|
||||
{
|
||||
$this->account = $account;
|
||||
$this->amount = $amount;
|
||||
// more stuff here, from/to whom, stated reason, execution date and such
|
||||
}
|
||||
|
||||
public function getAmount()
|
||||
public function getAmount(): Amount
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
@@ -146,12 +159,14 @@ collection, which means we can compute this value at runtime:
|
||||
class Account
|
||||
{
|
||||
// .. previous code
|
||||
public function getBalance()
|
||||
|
||||
public function getBalance(): int
|
||||
{
|
||||
$balance = 0;
|
||||
foreach ($this->entries as $entry) {
|
||||
$balance += $entry->getAmount();
|
||||
}
|
||||
|
||||
return $balance;
|
||||
}
|
||||
}
|
||||
@@ -175,13 +190,12 @@ relation with this method:
|
||||
<?php
|
||||
class Account
|
||||
{
|
||||
public function addEntry($amount)
|
||||
public function addEntry(int $amount): void
|
||||
{
|
||||
$this->assertAcceptEntryAllowed($amount);
|
||||
|
||||
$e = new Entry($this, $amount);
|
||||
$this->entries[] = $e;
|
||||
return $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +204,10 @@ Now look at the following test-code for our entities:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class AccountTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AccountTest extends TestCase
|
||||
{
|
||||
public function testAddEntry()
|
||||
{
|
||||
@@ -208,7 +225,7 @@ Now look at the following test-code for our entities:
|
||||
{
|
||||
$account = new Account("123456", $maxCredit = 200);
|
||||
|
||||
$this->setExpectedException("Exception");
|
||||
$this->expectException(Exception::class);
|
||||
$account->addEntry(-1000);
|
||||
}
|
||||
}
|
||||
@@ -219,9 +236,12 @@ To enforce our rule we can now implement the assertion in
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
class Account
|
||||
{
|
||||
private function assertAcceptEntryAllowed($amount)
|
||||
// .. previous code
|
||||
|
||||
private function assertAcceptEntryAllowed(int $amount): void
|
||||
{
|
||||
$futureBalance = $this->getBalance() + $amount;
|
||||
$allowedMinimalBalance = ($this->maxCredit * -1);
|
||||
@@ -266,23 +286,22 @@ entries collection) we want to add an aggregate field called
|
||||
class Account
|
||||
{
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $balance = 0;
|
||||
private int $balance = 0;
|
||||
|
||||
public function getBalance()
|
||||
public function getBalance(): int
|
||||
{
|
||||
return $this->balance;
|
||||
}
|
||||
|
||||
public function addEntry($amount)
|
||||
public function addEntry(int $amount): void
|
||||
{
|
||||
$this->assertAcceptEntryAllowed($amount);
|
||||
|
||||
$e = new Entry($this, $amount);
|
||||
$this->entries[] = $e;
|
||||
$this->balance += $amount;
|
||||
return $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,12 +325,15 @@ potentially lead to inconsistent state. See this example:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
use Bank\Entities\Account;
|
||||
|
||||
// The Account $accId has a balance of 0 and a max credit limit of 200:
|
||||
// request 1 account
|
||||
$account1 = $em->find('Bank\Entities\Account', $accId);
|
||||
$account1 = $em->find(Account::class, $accId);
|
||||
|
||||
// request 2 account
|
||||
$account2 = $em->find('Bank\Entities\Account', $accId);
|
||||
$account2 = $em->find(Account::class, $accId);
|
||||
|
||||
$account1->addEntry(-200);
|
||||
$account2->addEntry(-200);
|
||||
@@ -332,10 +354,14 @@ Optimistic locking is as easy as adding a version column:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
class Account
|
||||
{
|
||||
/** @Column(type="integer") @Version */
|
||||
private $version;
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Version
|
||||
*/
|
||||
private int $version;
|
||||
}
|
||||
|
||||
The previous example would then throw an exception in the face of
|
||||
@@ -349,9 +375,11 @@ the database using a FOR UPDATE.
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
use Bank\Entities\Account;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
|
||||
$account = $em->find('Bank\Entities\Account', $accId, LockMode::PESSIMISTIC_READ);
|
||||
|
||||
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_READ);
|
||||
|
||||
Keeping Updates and Deletes in Sync
|
||||
-----------------------------------
|
||||
@@ -372,5 +400,3 @@ field that offers serious performance benefits over iterating all
|
||||
the related objects that make up an aggregate value. Finally I
|
||||
showed how you can ensure that your aggregate fields do not get out
|
||||
of sync due to race-conditions and concurrent access.
|
||||
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ can be set via ``Query::setHint($name, $value)`` as shown in the
|
||||
previous example with the ``HINT_CUSTOM_TREE_WALKERS`` query hint.
|
||||
|
||||
We will implement a custom Output Walker that allows to specify the
|
||||
SQL\_NO\_CACHE query hint.
|
||||
``SQL_NO_CACHE`` query hint.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -180,7 +180,7 @@ SQL\_NO\_CACHE query hint.
|
||||
|
||||
Our ``MysqlWalker`` will extend the default ``SqlWalker``. We will
|
||||
modify the generation of the SELECT clause, adding the
|
||||
SQL\_NO\_CACHE on those queries that need it:
|
||||
``SQL_NO_CACHE`` on those queries that need it:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ implement the ``NotifyPropertyChanged`` interface from the
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\Common\NotifyPropertyChanged;
|
||||
use Doctrine\Common\PropertyChangedListener;
|
||||
use Doctrine\Persistence\NotifyPropertyChanged;
|
||||
use Doctrine\Persistence\PropertyChangedListener;
|
||||
|
||||
abstract class DomainObject implements NotifyPropertyChanged
|
||||
{
|
||||
|
||||
226
docs/en/make.bat
226
docs/en/make.bat
@@ -1,113 +1,113 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
set SPHINXBUILD=sphinx-build
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORM.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORM.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
set SPHINXBUILD=sphinx-build
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORM.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORM.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
|
||||
@@ -619,22 +619,17 @@ Examples:
|
||||
This annotation is used in the context of relations in
|
||||
:ref:`@ManyToOne <annref_manytoone>`, :ref:`@OneToOne <annref_onetoone>` fields
|
||||
and in the Context of :ref:`@JoinTable <annref_jointable>` nested inside
|
||||
a @ManyToMany. This annotation is not required. If it is not
|
||||
specified the attributes *name* and *referencedColumnName* are
|
||||
inferred from the table and primary key names.
|
||||
|
||||
Required attributes:
|
||||
a @ManyToMany. If this annotation or both *name* and *referencedColumnName*
|
||||
are missing they will be computed considering the field's name and the current
|
||||
:doc:`naming strategy <namingstrategy>`.
|
||||
|
||||
Optional attributes:
|
||||
|
||||
- **name**: Column name that holds the foreign key identifier for
|
||||
this relation. In the context of @JoinTable it specifies the column
|
||||
name in the join table.
|
||||
- **referencedColumnName**: Name of the primary key identifier that
|
||||
is used for joining of this relation.
|
||||
|
||||
Optional attributes:
|
||||
|
||||
|
||||
is used for joining of this relation. Defaults to *id*.
|
||||
- **unique**: Determines whether this relation is exclusive between the
|
||||
affected entities and should be enforced as such on the database
|
||||
constraint level. Defaults to false.
|
||||
|
||||
@@ -18,9 +18,9 @@ This chapter is split into three different sections.
|
||||
|
||||
One tip for working with relations is to read the relation from left to right, where the left word refers to the current Entity. For example:
|
||||
|
||||
- OneToMany - One instance of the current Entity has Many instances (references) to the refered Entity.
|
||||
- ManyToOne - Many instances of the current Entity refer to One instance of the refered Entity.
|
||||
- OneToOne - One instance of the current Entity refers to One instance of the refered Entity.
|
||||
- OneToMany - One instance of the current Entity has Many instances (references) to the referred Entity.
|
||||
- ManyToOne - Many instances of the current Entity refer to One instance of the referred Entity.
|
||||
- OneToOne - One instance of the current Entity refers to One instance of the referred Entity.
|
||||
|
||||
See below for all the possible relations.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Caching
|
||||
=======
|
||||
|
||||
Doctrine provides cache drivers in the ``Common`` package for some
|
||||
of the most popular caching implementations such as APC, Memcache
|
||||
Doctrine provides cache drivers in the ``doctrine/cache`` package for some
|
||||
of the most popular caching implementations such as APCu, Memcache
|
||||
and Xcache. We also provide an ``ArrayCache`` driver which stores
|
||||
the data in a PHP array. Obviously, when using ``ArrayCache``, the
|
||||
cache does not persist between requests, but this is useful for
|
||||
@@ -306,7 +306,7 @@ the result cache.
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('select u from \Entities\User u');
|
||||
$query->useResultCache(true);
|
||||
$query->enableResultCache();
|
||||
|
||||
You can also configure an individual query to use a different
|
||||
result cache driver.
|
||||
@@ -317,19 +317,18 @@ result cache driver.
|
||||
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
|
||||
'/path/to/writable/directory'
|
||||
);
|
||||
$config = new \Doctrine\ORM\Configuration();
|
||||
$query->setResultCacheDriver($cacheDriver);
|
||||
|
||||
.. note::
|
||||
|
||||
Setting the result cache driver on the query will
|
||||
automatically enable the result cache for the query. If you want to
|
||||
disable it pass false to ``useResultCache()``.
|
||||
disable it use ``disableResultCache()``.
|
||||
|
||||
::
|
||||
|
||||
<?php
|
||||
$query->useResultCache(false);
|
||||
$query->disableResultCache();
|
||||
|
||||
|
||||
If you want to set the time the cache has to live you can use the
|
||||
@@ -350,12 +349,12 @@ yourself with the ``setResultCacheId()`` method.
|
||||
$query->setResultCacheId('my_custom_id');
|
||||
|
||||
You can also set the lifetime and cache ID by passing the values as
|
||||
the second and third argument to ``useResultCache()``.
|
||||
the first and second argument to ``enableResultCache()``.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query->useResultCache(true, 3600, 'my_custom_id');
|
||||
$query->enableResultCache(3600, 'my_custom_id');
|
||||
|
||||
Metadata Cache
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@@ -71,8 +71,8 @@ follows:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\Common\NotifyPropertyChanged,
|
||||
Doctrine\Common\PropertyChangedListener;
|
||||
use Doctrine\Persistence\NotifyPropertyChanged,
|
||||
Doctrine\Persistence\PropertyChangedListener;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
|
||||
@@ -491,7 +491,7 @@ Joins between entities without associations were not possible until version
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email');
|
||||
$query = $em->createQuery('SELECT u FROM User u JOIN Banlist b WITH u.email = b.email');
|
||||
|
||||
.. note::
|
||||
The differences between WHERE, WITH and HAVING clauses may be
|
||||
|
||||
@@ -145,49 +145,53 @@ An example for a correct notation can be found in the example
|
||||
Lifecycle Events
|
||||
----------------
|
||||
|
||||
The EntityManager and UnitOfWork trigger a bunch of events during
|
||||
the life-time of their registered entities.
|
||||
The ``EntityManager`` and ``UnitOfWork`` classes trigger a bunch of
|
||||
events during the life-time of their registered entities.
|
||||
|
||||
|
||||
- preRemove - The preRemove event occurs for a given entity before
|
||||
the respective EntityManager remove operation for that entity is
|
||||
executed. It is not called for a DQL DELETE statement.
|
||||
- postRemove - The postRemove event occurs for an entity after the
|
||||
|
||||
- ``preRemove`` - The ``preRemove`` event occurs for a given entity
|
||||
before the respective ``EntityManager`` remove operation for that
|
||||
entity is executed. It is not called for a DQL ``DELETE`` statement.
|
||||
- ``postRemove`` - The ``postRemove`` event occurs for an entity after the
|
||||
entity has been deleted. It will be invoked after the database
|
||||
delete operations. It is not called for a DQL DELETE statement.
|
||||
- prePersist - The prePersist event occurs for a given entity
|
||||
before the respective EntityManager persist operation for that
|
||||
delete operations. It is not called for a DQL ``DELETE`` statement.
|
||||
- ``prePersist`` - The ``prePersist`` event occurs for a given entity
|
||||
before the respective ``EntityManager`` persist operation for that
|
||||
entity is executed. It should be noted that this event is only triggered on
|
||||
*initial* persist of an entity (i.e. it does not trigger on future updates).
|
||||
- postPersist - The postPersist event occurs for an entity after
|
||||
- ``postPersist`` - The ``postPersist`` event occurs for an entity after
|
||||
the entity has been made persistent. It will be invoked after the
|
||||
database insert operations. Generated primary key values are
|
||||
available in the postPersist event.
|
||||
- preUpdate - The preUpdate event occurs before the database
|
||||
update operations to entity data. It is not called for a DQL UPDATE statement
|
||||
nor when the computed changeset is empty.
|
||||
- postUpdate - The postUpdate event occurs after the database
|
||||
update operations to entity data. It is not called for a DQL UPDATE statement.
|
||||
- postLoad - The postLoad event occurs for an entity after the
|
||||
entity has been loaded into the current EntityManager from the
|
||||
- ``preUpdate`` - The ``preUpdate`` event occurs before the database
|
||||
update operations to entity data. It is not called for a DQL
|
||||
``UPDATE`` statement nor when the computed changeset is empty.
|
||||
- ``postUpdate`` - The ``postUpdate`` event occurs after the database
|
||||
update operations to entity data. It is not called for a DQL
|
||||
``UPDATE`` statement.
|
||||
- ``postLoad`` - The postLoad event occurs for an entity after the
|
||||
entity has been loaded into the current ``EntityManager`` from the
|
||||
database or after the refresh operation has been applied to it.
|
||||
- loadClassMetadata - The loadClassMetadata event occurs after the
|
||||
- ``loadClassMetadata`` - The ``loadClassMetadata`` event occurs after the
|
||||
mapping metadata for a class has been loaded from a mapping source
|
||||
(annotations/xml/yaml). This event is not a lifecycle callback.
|
||||
- onClassMetadataNotFound - Loading class metadata for a particular
|
||||
- ``onClassMetadataNotFound`` - Loading class metadata for a particular
|
||||
requested class name failed. Manipulating the given event args instance
|
||||
allows providing fallback metadata even when no actual metadata exists
|
||||
or could be found. This event is not a lifecycle callback.
|
||||
- preFlush - The preFlush event occurs at the very beginning of a flush
|
||||
operation.
|
||||
- onFlush - The onFlush event occurs after the change-sets of all
|
||||
- ``preFlush`` - The ``preFlush`` event occurs at the very beginning of
|
||||
a flush operation.
|
||||
- ``onFlush`` - The ``onFlush`` event occurs after the change-sets of all
|
||||
managed entities are computed. This event is not a lifecycle
|
||||
callback.
|
||||
- postFlush - The postFlush event occurs at the end of a flush operation. This
|
||||
- ``postFlush`` - The ``postFlush`` event occurs at the end of a flush operation. This
|
||||
event is not a lifecycle callback.
|
||||
- onClear - The onClear event occurs when the EntityManager#clear() operation is
|
||||
invoked, after all references to entities have been removed from the unit of
|
||||
work. This event is not a lifecycle callback.
|
||||
- ``onClear`` - The ``onClear`` event occurs when the
|
||||
``EntityManager#clear()`` operation is invoked, after all references
|
||||
to entities have been removed from the unit of work. This event is not
|
||||
a lifecycle callback.
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -199,7 +203,7 @@ the life-time of their registered entities.
|
||||
|
||||
.. warning::
|
||||
|
||||
Note that the postRemove event or any events triggered after an entity removal
|
||||
Note that the ``postRemove`` event or any events triggered after an entity removal
|
||||
can receive an uninitializable proxy in case you have configured an entity to
|
||||
cascade remove relations. In this case, you should load yourself the proxy in
|
||||
the associated pre event.
|
||||
@@ -222,13 +226,13 @@ listeners:
|
||||
- Lifecycle Event Listeners and Subscribers are classes with specific callback
|
||||
methods that receives some kind of ``EventArgs`` instance.
|
||||
|
||||
The EventArgs instance received by the listener gives access to the entity,
|
||||
EntityManager and other relevant data.
|
||||
The ``EventArgs`` instance received by the listener gives access to the entity,
|
||||
``EntityManager`` instance and other relevant data.
|
||||
|
||||
.. note::
|
||||
|
||||
All Lifecycle events that happen during the ``flush()`` of
|
||||
an EntityManager have very specific constraints on the allowed
|
||||
an ``EntityManager`` have very specific constraints on the allowed
|
||||
operations that can be executed. Please read the
|
||||
:ref:`reference-events-implementing-listeners` section very carefully
|
||||
to understand which operations are allowed in which lifecycle event.
|
||||
@@ -410,9 +414,9 @@ sit at a level above the entities and allow you to implement re-usable
|
||||
behaviors across different entity classes.
|
||||
|
||||
Note that they require much more detailed knowledge about the inner
|
||||
workings of the EntityManager and UnitOfWork. Please read the
|
||||
:ref:`reference-events-implementing-listeners` section carefully if you
|
||||
are trying to write your own listener.
|
||||
workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please
|
||||
read the :ref:`reference-events-implementing-listeners` section
|
||||
carefully if you are trying to write your own listener.
|
||||
|
||||
For event subscribers, there are no surprises. They declare the
|
||||
lifecycle events in their ``getSubscribedEvents`` method and provide
|
||||
@@ -423,7 +427,7 @@ A lifecycle event listener looks like the following:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
class MyEventListener
|
||||
{
|
||||
@@ -445,8 +449,8 @@ A lifecycle event subscriber may look like this:
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
|
||||
use Doctrine\EventSubscriber;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
class MyEventSubscriber implements EventSubscriber
|
||||
{
|
||||
@@ -501,16 +505,16 @@ Implementing Event Listeners
|
||||
----------------------------
|
||||
|
||||
This section explains what is and what is not allowed during
|
||||
specific lifecycle events of the UnitOfWork. Although you get
|
||||
passed the EntityManager in all of these events, you have to follow
|
||||
these restrictions very carefully since operations in the wrong
|
||||
event may produce lots of different errors, such as inconsistent
|
||||
specific lifecycle events of the ``UnitOfWork`` class. Although you get
|
||||
passed the ``EntityManager`` instance in all of these events, you have
|
||||
to follow these restrictions very carefully since operations in the
|
||||
wrong event may produce lots of different errors, such as inconsistent
|
||||
data and lost updates/persists/removes.
|
||||
|
||||
For the described events that are also lifecycle callback events
|
||||
the restrictions apply as well, with the additional restriction
|
||||
that (prior to version 2.4) you do not have access to the
|
||||
EntityManager or UnitOfWork APIs inside these events.
|
||||
``EntityManager`` or ``UnitOfWork`` APIs inside these events.
|
||||
|
||||
prePersist
|
||||
~~~~~~~~~~
|
||||
@@ -586,8 +590,8 @@ entities and their associations have been computed. This means, the
|
||||
- Collections scheduled for update
|
||||
- Collections scheduled for removal
|
||||
|
||||
To make use of the onFlush event you have to be familiar with the
|
||||
internal UnitOfWork API, which grants you access to the previously
|
||||
To make use of the ``onFlush`` event you have to be familiar with the
|
||||
internal ``UnitOfWork`` API, which grants you access to the previously
|
||||
mentioned sets. See this example:
|
||||
|
||||
.. code-block:: php
|
||||
@@ -735,7 +739,7 @@ Restrictions for this event:
|
||||
the event to modify primitive field values, e.g. use
|
||||
``$eventArgs->setNewValue($field, $value);`` as in the Alice to Bob example above.
|
||||
- Any calls to ``EntityManager#persist()`` or
|
||||
``EntityManager#remove()``, even in combination with the UnitOfWork
|
||||
``EntityManager#remove()``, even in combination with the ``UnitOfWork``
|
||||
API are strongly discouraged and don't work as expected outside the
|
||||
flush operation.
|
||||
|
||||
@@ -991,4 +995,3 @@ process and manipulate the instance.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,12 +20,17 @@ Metadata and Query caches
|
||||
|
||||
As already mentioned earlier in the chapter about configuring
|
||||
Doctrine, it is strongly discouraged to use Doctrine without a
|
||||
Metadata and Query cache (preferably with APC or Memcache as the
|
||||
cache driver). Operating Doctrine without these caches means
|
||||
Metadata and Query cache.
|
||||
|
||||
Operating Doctrine without these caches means
|
||||
Doctrine will need to load your mapping information on every single
|
||||
request and has to parse each DQL query on every single request.
|
||||
This is a waste of resources.
|
||||
|
||||
The preferred cache driver for metadata and query caches is ``PhpFileCache``.
|
||||
This driver serializes cache items and writes them to a file.
|
||||
This allows for opcode caching to be used and provides high performance in most scenarios.
|
||||
|
||||
See :ref:`integrating-with-the-orm`
|
||||
|
||||
Alternative Query Result Formats
|
||||
|
||||
@@ -289,9 +289,15 @@ column and cascading on delete.
|
||||
|
||||
Overrides
|
||||
---------
|
||||
Used to override a mapping for an entity field or relationship.
|
||||
May be applied to an entity that extends a mapped superclass
|
||||
to override a relationship or field mapping defined by the mapped superclass.
|
||||
|
||||
Used to override a mapping for an entity field or relationship. Can only be
|
||||
applied to an entity that extends a mapped superclass or uses a trait to
|
||||
override a relationship or field mapping defined by the mapped superclass or
|
||||
trait.
|
||||
|
||||
It is not possible to override attributes or associations in entity to entity
|
||||
inheritance scenarios, because this can cause unforseen edge case behavior and
|
||||
increases complexity in ORM internal classes.
|
||||
|
||||
|
||||
Association Override
|
||||
@@ -584,7 +590,7 @@ Things to note:
|
||||
|
||||
- The "attribute override" specifies the overrides base on the property name.
|
||||
- The column type *CANNOT* be changed. If the column type is not equal you get a ``MappingException``
|
||||
- The override can redefine all the columns except the type.
|
||||
- The override can redefine all the attributes except the type.
|
||||
|
||||
Query the Type
|
||||
--------------
|
||||
|
||||
@@ -255,6 +255,21 @@ and for managed entities. If you want to set a type explicitly you can call
|
||||
the third argument to ``setParameter()`` explicitly. It accepts either a PDO
|
||||
type or a DBAL Type name for conversion.
|
||||
|
||||
.. note::
|
||||
|
||||
Even though passing DateTime instance is allowed, it impacts performance
|
||||
as by default there is an attempt to load metadata for object, and if it's not found,
|
||||
type is inferred from the original value.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
// prevents attempt to load metadata for date time class, improving performance
|
||||
$qb->setParameter('date', new \DateTimeImmutable(), Types::DATE_IMMUTABLE)
|
||||
|
||||
If you've got several parameters to bind to your query, you can
|
||||
also use setParameters() instead of setParameter() with the
|
||||
following syntax:
|
||||
@@ -581,4 +596,3 @@ same query of example 6 written using
|
||||
->add('from', new Expr\From('User', 'u'))
|
||||
->add('where', new Expr\Comparison('u.id', '=', '?1'))
|
||||
->add('orderBy', new Expr\OrderBy('u.name', 'ASC'));
|
||||
|
||||
|
||||
@@ -77,11 +77,10 @@ A query region might be something like :
|
||||
Cache Regions
|
||||
-------------
|
||||
|
||||
``Doctrine\ORM\Cache\Region\DefaultRegion`` It's the default implementation.
|
||||
``Doctrine\ORM\Cache\Region\DefaultRegion`` is the default implementation.
|
||||
A simplest cache region compatible with all doctrine-cache drivers but does not support locking.
|
||||
|
||||
``Doctrine\ORM\Cache\Region`` and ``Doctrine\ORM\Cache\ConcurrentRegion``
|
||||
Defines contracts that should be implemented by a cache provider.
|
||||
define contracts that should be implemented by a cache provider.
|
||||
|
||||
It allows you to provide your own cache implementation that might take advantage of specific cache driver.
|
||||
|
||||
@@ -91,11 +90,8 @@ If you want to support locking for ``READ_WRITE`` strategies you should implemen
|
||||
Cache region
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Defines a contract for accessing a particular region.
|
||||
|
||||
``Doctrine\ORM\Cache\Region``
|
||||
|
||||
Defines a contract for accessing a particular cache region.
|
||||
``Doctrine\ORM\Cache\Region`` defines a contract for accessing a particular
|
||||
cache region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Region.html>`_.
|
||||
|
||||
@@ -107,9 +103,7 @@ By default, Doctrine provides a very simple implementation based on file locks `
|
||||
|
||||
If you want to use an ``READ_WRITE`` cache, you should consider providing your own cache region.
|
||||
|
||||
``Doctrine\ORM\Cache\ConcurrentRegion``
|
||||
|
||||
Defines contract for concurrently managed data region.
|
||||
``Doctrine\ORM\Cache\ConcurrentRegion`` defines a contract for concurrently managed data region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/ConcurrentRegion.html>`_.
|
||||
|
||||
@@ -177,7 +171,7 @@ Doctrine allows you to specify configurations and some points of extension for t
|
||||
Enable Second Level Cache
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To enable the second-level-cache, you should provide a cache factory
|
||||
To enable the second-level-cache, you should provide a cache factory.
|
||||
``\Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
|
||||
|
||||
.. code-block:: php
|
||||
@@ -203,11 +197,16 @@ Cache Factory is the main point of extension.
|
||||
|
||||
It allows you to provide a specific implementation of the following components :
|
||||
|
||||
* ``QueryCache`` Store and retrieve query cache results.
|
||||
* ``CachedEntityPersister`` Store and retrieve entity results.
|
||||
* ``CachedCollectionPersister`` Store and retrieve query results.
|
||||
* ``EntityHydrator`` Transform an entity into a cache entry and cache entry into entities
|
||||
* ``CollectionHydrator`` Transform a collection into a cache entry and cache entry into collection
|
||||
``QueryCache``
|
||||
stores and retrieves query cache results.
|
||||
``CachedEntityPersister``
|
||||
stores and retrieves entity results.
|
||||
``CachedCollectionPersister``
|
||||
stores and retrieves query results.
|
||||
``EntityHydrator``
|
||||
transforms entities into a cache entries and cache entries into entities
|
||||
``CollectionHydrator``
|
||||
transforms collections into cache entries and cache entries into collections
|
||||
|
||||
`See API Doc <http://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/DefaultCacheFactory.html>`_.
|
||||
|
||||
@@ -225,8 +224,8 @@ To specify a default lifetime for all regions or specify a different lifetime fo
|
||||
$regionConfig = $cacheConfig->getRegionsConfiguration();
|
||||
|
||||
// Cache Region lifetime
|
||||
$regionConfig->setLifetime('my_entity_region', 3600); // Time to live for a specific region; In seconds
|
||||
$regionConfig->setDefaultLifetime(7200); // Default time to live; In seconds
|
||||
$regionConfig->setLifetime('my_entity_region', 3600); // Time to live for a specific region (in seconds)
|
||||
$regionConfig->setDefaultLifetime(7200); // Default time to live (in seconds)
|
||||
|
||||
|
||||
Cache Log
|
||||
@@ -267,8 +266,9 @@ By providing a cache logger you should be able to get information about all cach
|
||||
// Get the total number of cached entries *not* found in all regions.
|
||||
$logger->getMissCount();
|
||||
|
||||
If you want to get more information you should implement ``\Doctrine\ORM\Cache\Logging\CacheLogger``.
|
||||
and collect all information you want.
|
||||
If you want to get more information you should implement
|
||||
``\Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
|
||||
all the information you want.
|
||||
|
||||
`See API Doc <http://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Logging/CacheLogger.html>`_.
|
||||
|
||||
@@ -277,8 +277,11 @@ Entity cache definition
|
||||
-----------------------
|
||||
* Entity cache configuration allows you to define the caching strategy and region for an entity.
|
||||
|
||||
* ``usage`` Specifies the caching strategy: ``READ_ONLY``, ``NONSTRICT_READ_WRITE``, ``READ_WRITE``. see :ref:`reference-second-level-cache-mode`
|
||||
* ``region`` Optional value that specifies the name of the second level cache region.
|
||||
* ``usage`` specifies the caching strategy: ``READ_ONLY``,
|
||||
``NONSTRICT_READ_WRITE``, ``READ_WRITE``.
|
||||
See :ref:`reference-second-level-cache-mode`.
|
||||
* ``region`` is an optional value that specifies the name of the second
|
||||
level cache region.
|
||||
|
||||
|
||||
.. configuration-block::
|
||||
@@ -579,7 +582,8 @@ The Cache Mode controls how a particular query interacts with the second-level c
|
||||
DELETE / UPDATE queries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
DQL UPDATE / DELETE statements are ported directly into a database and bypass the second-level cache,
|
||||
DQL UPDATE / DELETE statements are ported directly into a database and bypass
|
||||
the second-level cache.
|
||||
Entities that are already cached will NOT be invalidated.
|
||||
However the cached data could be evicted using the cache API or an special query hint.
|
||||
|
||||
@@ -622,7 +626,7 @@ Using the repository query cache
|
||||
--------------------------------
|
||||
|
||||
As well as ``Query Cache`` all persister queries store only identifier values for an individual query.
|
||||
All persister use a single timestamps cache region keeps track of the last update for each persister,
|
||||
All persisters use a single timestamp cache region to keep track of the last update for each persister,
|
||||
When a query is loaded from cache, the timestamp region is checked for the last update for that persister.
|
||||
Using the last update timestamps as part of the query key invalidate the cache key when an update occurs.
|
||||
|
||||
@@ -641,7 +645,7 @@ Using the last update timestamps as part of the query key invalidate the cache k
|
||||
$em->clear();
|
||||
|
||||
// Reload from database.
|
||||
// At this point the query cache key if not logger valid, the select goes straight
|
||||
// At this point the query cache key is no longer valid, the select goes straight to the database
|
||||
$entities = $em->getRepository('Entity\Country')->findAll();
|
||||
|
||||
Cache API
|
||||
@@ -728,4 +732,5 @@ Paginator
|
||||
~~~~~~~~~
|
||||
|
||||
Count queries generated by ``Doctrine\ORM\Tools\Pagination\Paginator`` are not cached by second-level cache.
|
||||
Although entities and query result are cached count queries will hit the database every time.
|
||||
Although entities and query result are cached, count queries will hit the
|
||||
database every time.
|
||||
|
||||
@@ -250,6 +250,12 @@ as follows:
|
||||
- If X is a detached entity, an exception will be thrown on
|
||||
flush.
|
||||
|
||||
.. caution::
|
||||
|
||||
Do not pass detached entities to the persist operation. The persist operation always
|
||||
considers entities that are not yet known to the ``EntityManager`` as new entities
|
||||
(refer to the ``STATE_NEW`` constant inside the ``UnitOfWork``).
|
||||
|
||||
Removing entities
|
||||
-----------------
|
||||
|
||||
@@ -315,7 +321,7 @@ in multiple ways with very different performance impacts.
|
||||
1. If an association is marked as ``CASCADE=REMOVE`` Doctrine 2
|
||||
will fetch this association. If its a Single association it will
|
||||
pass this entity to
|
||||
´EntityManager#remove()``. If the association is a collection, Doctrine will loop over all its elements and pass them to``EntityManager#remove()\`.
|
||||
``EntityManager#remove()``. If the association is a collection, Doctrine will loop over all its elements and pass them to``EntityManager#remove()``.
|
||||
In both cases the cascade remove semantics are applied recursively.
|
||||
For large object graphs this removal strategy can be very costly.
|
||||
2. Using a DQL ``DELETE`` statement allows you to delete multiple
|
||||
@@ -330,6 +336,13 @@ in multiple ways with very different performance impacts.
|
||||
because Doctrine will fetch and remove all associated entities
|
||||
explicitly nevertheless.
|
||||
|
||||
.. note::
|
||||
|
||||
Calling ``remove`` on an entity will remove the object from the identiy
|
||||
map and therefore detach it. Querying the same entity again, for example
|
||||
via a lazy loaded relation, will return a new object.
|
||||
|
||||
|
||||
Detaching entities
|
||||
------------------
|
||||
|
||||
|
||||
@@ -8,9 +8,7 @@ or address are the primary use case for this feature.
|
||||
|
||||
.. note::
|
||||
|
||||
Embeddables can not contain references to entities. They can however compose
|
||||
other embeddables in addition to holding properties with basic ``@Column``
|
||||
mapping.
|
||||
Embeddables can only contain properties with basic ``@Column`` mapping.
|
||||
|
||||
For the purposes of this tutorial, we will assume that you have a ``User``
|
||||
class in your application and you would like to store an address in
|
||||
|
||||
@@ -3,7 +3,7 @@ Extra Lazy Associations
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
In many cases associations between entities can get pretty large. Even in a simple scenario like a blog.
|
||||
In many cases associations between entities can get pretty large. Even in a simple scenario like a blog
|
||||
where posts can be commented, you always have to assume that a post draws hundreds of comments.
|
||||
In Doctrine 2.0 if you accessed an association it would always get loaded completely into memory. This
|
||||
can lead to pretty serious performance problems, if your associations contain several hundreds or thousands
|
||||
|
||||
@@ -488,7 +488,6 @@ classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass="BugRepository")
|
||||
* @ORM\Table(name="bugs")
|
||||
*/
|
||||
class Bug
|
||||
|
||||
@@ -291,6 +291,5 @@ Outlook into the Future
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For the inverse side of a many-to-many associations there will be a way to persist the keys and the order
|
||||
as a third and fourth parameter into the join table. This feature is discussed in `DDC-213 <http://www.doctrine-project.org/jira/browse/DDC-213>`_
|
||||
as a third and fourth parameter into the join table. This feature is discussed in `#2817 <https://github.com/doctrine/orm/issues/2817>`_
|
||||
This feature cannot be implemented for one-to-many associations, because they are never the owning side.
|
||||
|
||||
|
||||
@@ -19,15 +19,14 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\MappingException;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
|
||||
use Doctrine\ORM\Query\Parameter;
|
||||
use Doctrine\ORM\Cache\QueryCacheKey;
|
||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
use Doctrine\Persistence\Mapping\MappingException;
|
||||
|
||||
/**
|
||||
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
||||
@@ -73,6 +72,7 @@ abstract class AbstractQuery
|
||||
* The parameter map of this query.
|
||||
*
|
||||
* @var ArrayCollection|Parameter[]
|
||||
* @psalm-var ArrayCollection<int, Parameter>
|
||||
*/
|
||||
protected $parameters;
|
||||
|
||||
@@ -241,7 +241,7 @@ abstract class AbstractQuery
|
||||
*
|
||||
* @param integer $lifetime
|
||||
*
|
||||
* @return \Doctrine\ORM\AbstractQuery This query instance.
|
||||
* @return static This query instance.
|
||||
*/
|
||||
public function setLifetime($lifetime)
|
||||
{
|
||||
@@ -261,7 +261,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* @param integer $cacheMode
|
||||
*
|
||||
* @return \Doctrine\ORM\AbstractQuery This query instance.
|
||||
* @return static This query instance.
|
||||
*/
|
||||
public function setCacheMode($cacheMode)
|
||||
{
|
||||
@@ -322,11 +322,13 @@ abstract class AbstractQuery
|
||||
*/
|
||||
public function getParameter($key)
|
||||
{
|
||||
$key = Query\Parameter::normalizeName($key);
|
||||
|
||||
$filteredParameters = $this->parameters->filter(
|
||||
function (Query\Parameter $parameter) use ($key) : bool {
|
||||
$parameterName = $parameter->getName();
|
||||
|
||||
return $key === $parameterName || (string) $key === (string) $parameterName;
|
||||
return $key === $parameterName;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -339,11 +341,14 @@ abstract class AbstractQuery
|
||||
* @param ArrayCollection|mixed[] $parameters
|
||||
*
|
||||
* @return static This query instance.
|
||||
*
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
|
||||
*/
|
||||
public function setParameters($parameters)
|
||||
{
|
||||
// BC compatibility with 2.3-
|
||||
if (is_array($parameters)) {
|
||||
/** @psalm-var ArrayCollection<int, Parameter> $parameterCollection */
|
||||
$parameterCollection = new ArrayCollection();
|
||||
|
||||
foreach ($parameters as $key => $value) {
|
||||
@@ -389,9 +394,11 @@ abstract class AbstractQuery
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return array|string
|
||||
* @return mixed[]|string|int|float|bool
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMInvalidArgumentException
|
||||
*
|
||||
* @psalm-return array|scalar
|
||||
*/
|
||||
public function processParameterValue($value)
|
||||
{
|
||||
@@ -469,7 +476,7 @@ abstract class AbstractQuery
|
||||
*/
|
||||
private function translateNamespaces(Query\ResultSetMapping $rsm)
|
||||
{
|
||||
$translate = function ($alias) {
|
||||
$translate = function ($alias) : string {
|
||||
return $this->_em->getClassMetadata($alias)->getName();
|
||||
};
|
||||
|
||||
@@ -630,7 +637,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Defines how long the result cache will be active before expire.
|
||||
*
|
||||
* @param integer $lifetime How long the cache entry is valid.
|
||||
* @param int|null $lifetime How long the cache entry is valid.
|
||||
*
|
||||
* @return static This query instance.
|
||||
*/
|
||||
@@ -965,10 +972,11 @@ abstract class AbstractQuery
|
||||
$this->setParameters($parameters);
|
||||
}
|
||||
|
||||
$setCacheEntry = function() {};
|
||||
$setCacheEntry = static function () : void {
|
||||
};
|
||||
|
||||
if ($this->_hydrationCacheProfile !== null) {
|
||||
list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
|
||||
[$cacheKey, $realCacheKey] = $this->getHydrationCacheId();
|
||||
|
||||
$queryCacheProfile = $this->getHydrationCacheProfile();
|
||||
$cache = $queryCacheProfile->getResultCacheDriver();
|
||||
@@ -982,7 +990,7 @@ abstract class AbstractQuery
|
||||
$result = [];
|
||||
}
|
||||
|
||||
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
|
||||
$setCacheEntry = static function ($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) : void {
|
||||
$result[$realCacheKey] = $data;
|
||||
|
||||
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
|
||||
@@ -1069,7 +1077,7 @@ abstract class AbstractQuery
|
||||
* Will return the configured id if it exists otherwise a hash will be
|
||||
* automatically generated for you.
|
||||
*
|
||||
* @return array ($key, $hash)
|
||||
* @return array<string, string> ($key, $hash)
|
||||
*/
|
||||
protected function getHydrationCacheId()
|
||||
{
|
||||
|
||||
@@ -60,9 +60,6 @@ class DefaultCache implements Cache
|
||||
*/
|
||||
private $defaultQueryCache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
@@ -348,7 +348,9 @@ class DefaultQueryCache implements QueryCache
|
||||
* @param array $assoc
|
||||
* @param mixed $assocValue
|
||||
*
|
||||
* @return array|null
|
||||
* @return mixed[]|null
|
||||
*
|
||||
* @psalm-return array{targetEntity: string, type: mixed, list?: array[], identifier?: array}|null
|
||||
*/
|
||||
private function storeAssociationCache(QueryCacheKey $key, array $assoc, $assocValue)
|
||||
{
|
||||
|
||||
@@ -33,17 +33,17 @@ use Doctrine\ORM\Cache\QueryCacheKey;
|
||||
class StatisticsCacheLogger implements CacheLogger
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
* @var int[]
|
||||
*/
|
||||
private $cacheMissCountMap = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var int[]
|
||||
*/
|
||||
private $cacheHitCountMap = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var int[]
|
||||
*/
|
||||
private $cachePutCountMap = [];
|
||||
|
||||
@@ -142,7 +142,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
*
|
||||
* @param string $regionName The name of the cache region.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getRegionHitCount($regionName)
|
||||
{
|
||||
@@ -154,7 +154,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
*
|
||||
* @param string $regionName The name of the cache region.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getRegionMissCount($regionName)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
*
|
||||
* @param string $regionName The name of the cache region.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getRegionPutCount($regionName)
|
||||
{
|
||||
@@ -222,7 +222,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
/**
|
||||
* Get the total number of put in cache.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getPutCount()
|
||||
{
|
||||
@@ -232,7 +232,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
/**
|
||||
* Get the total number of entries successfully retrieved from cache.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getHitCount()
|
||||
{
|
||||
@@ -242,7 +242,7 @@ class StatisticsCacheLogger implements CacheLogger
|
||||
/**
|
||||
* Get the total number of cached entries *not* found in cache.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getMissCount()
|
||||
{
|
||||
|
||||
@@ -144,7 +144,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection
|
||||
* @param \Doctrine\ORM\Cache\CollectionCacheKey $key
|
||||
*
|
||||
* @return \Doctrine\ORM\PersistentCollection|null
|
||||
* @return object[]|null
|
||||
*/
|
||||
public function loadCollectionCache(PersistentCollection $collection, CollectionCacheKey $key)
|
||||
{
|
||||
|
||||
@@ -283,17 +283,17 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
/**
|
||||
* Generates a string of currently query
|
||||
*
|
||||
* @param array $query
|
||||
* @param string $criteria
|
||||
* @param array $orderBy
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
* @param string $query
|
||||
* @param string[]|Criteria $criteria
|
||||
* @param string[] $orderBy
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getHash($query, $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
{
|
||||
list($params) = ($criteria instanceof Criteria)
|
||||
[$params] = $criteria instanceof Criteria
|
||||
? $this->persister->expandCriteriaParameters($criteria)
|
||||
: $this->persister->expandParameters($criteria);
|
||||
|
||||
@@ -544,19 +544,18 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
|
||||
{
|
||||
$persister = $this->uow->getCollectionPersister($assoc);
|
||||
$hasCache = ($persister instanceof CachedPersister);
|
||||
$key = null;
|
||||
|
||||
if ( ! $hasCache) {
|
||||
return $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
|
||||
return $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $collection);
|
||||
}
|
||||
|
||||
$ownerId = $this->uow->getEntityIdentifier($coll->getOwner());
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = $this->buildCollectionCacheKey($assoc, $ownerId);
|
||||
$list = $persister->loadCollectionCache($coll, $key);
|
||||
$list = $persister->loadCollectionCache($collection, $key);
|
||||
|
||||
if ($list !== null) {
|
||||
if ($this->cacheLogger) {
|
||||
@@ -566,7 +565,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
return $list;
|
||||
}
|
||||
|
||||
$list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
|
||||
$list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $collection);
|
||||
|
||||
$persister->storeCollectionCache($key, $list);
|
||||
|
||||
@@ -580,18 +579,18 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
|
||||
{
|
||||
$persister = $this->uow->getCollectionPersister($assoc);
|
||||
$hasCache = ($persister instanceof CachedPersister);
|
||||
|
||||
if ( ! $hasCache) {
|
||||
return $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
|
||||
return $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $collection);
|
||||
}
|
||||
|
||||
$ownerId = $this->uow->getEntityIdentifier($coll->getOwner());
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = $this->buildCollectionCacheKey($assoc, $ownerId);
|
||||
$list = $persister->loadCollectionCache($coll, $key);
|
||||
$list = $persister->loadCollectionCache($collection, $key);
|
||||
|
||||
if ($list !== null) {
|
||||
if ($this->cacheLogger) {
|
||||
@@ -601,7 +600,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
return $list;
|
||||
}
|
||||
|
||||
$list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
|
||||
$list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $collection);
|
||||
|
||||
$persister->storeCollectionCache($key, $list);
|
||||
|
||||
|
||||
@@ -100,6 +100,12 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister
|
||||
$this->queuedCache['update'][] = $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @param bool $isChanged
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function updateCache($entity, $isChanged)
|
||||
{
|
||||
$class = $this->metadataFactory->getMetadataFor(get_class($entity));
|
||||
|
||||
@@ -249,6 +249,8 @@ class FileLockRegion implements ConcurrentRegion
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function unlock(CacheKey $key, Lock $lock)
|
||||
{
|
||||
|
||||
@@ -25,8 +25,6 @@ use Doctrine\Common\Annotations\CachedReader;
|
||||
use Doctrine\Common\Annotations\SimpleAnnotationReader;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\Cache as CacheDriver;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\Common\Proxy\AbstractProxyFactory;
|
||||
use Doctrine\ORM\Cache\CacheConfiguration;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
@@ -39,6 +37,9 @@ use Doctrine\ORM\Mapping\NamingStrategy;
|
||||
use Doctrine\ORM\Mapping\QuoteStrategy;
|
||||
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
|
||||
use Doctrine\ORM\Repository\RepositoryFactory;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* Configuration container for all configuration options of Doctrine.
|
||||
@@ -441,6 +442,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
* @psalm-return ?class-string
|
||||
*/
|
||||
public function getCustomStringFunction($name)
|
||||
{
|
||||
@@ -493,6 +495,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
* @psalm-return ?class-string
|
||||
*/
|
||||
public function getCustomNumericFunction($name)
|
||||
{
|
||||
@@ -533,6 +536,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string|callable $className Class name or a callable that returns the function.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param class-string|callable $className
|
||||
*/
|
||||
public function addCustomDatetimeFunction($name, $className)
|
||||
{
|
||||
@@ -545,6 +550,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @psalm-return ?class-string $name
|
||||
*/
|
||||
public function getCustomDatetimeFunction($name)
|
||||
{
|
||||
@@ -566,6 +573,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param array $functions The map of custom DQL date/time functions.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array<string, string> $functions
|
||||
*/
|
||||
public function setCustomDatetimeFunctions(array $functions)
|
||||
{
|
||||
@@ -596,6 +605,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string $modeName The hydration mode name.
|
||||
*
|
||||
* @return string|null The hydrator class name.
|
||||
*
|
||||
* @psalm-return ?class-string
|
||||
*/
|
||||
public function getCustomHydrationMode($modeName)
|
||||
{
|
||||
@@ -623,6 +634,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @param string $cmfName
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param class-string $cmfName
|
||||
*/
|
||||
public function setClassMetadataFactoryName($cmfName)
|
||||
{
|
||||
@@ -631,6 +644,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @psalm-return class-string
|
||||
*/
|
||||
public function getClassMetadataFactoryName()
|
||||
{
|
||||
@@ -657,8 +672,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
*
|
||||
* @param string $name The name of the filter.
|
||||
*
|
||||
* @return string The class name of the filter, or null if it is not
|
||||
* @return string|null The class name of the filter, or null if it is not
|
||||
* defined.
|
||||
*
|
||||
* @psalm-return ?class-string
|
||||
*/
|
||||
public function getFilterClassName($name)
|
||||
{
|
||||
@@ -676,7 +693,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository
|
||||
* @throws ORMException If $classname is not an ObjectRepository.
|
||||
*/
|
||||
public function setDefaultRepositoryClassName($className)
|
||||
{
|
||||
@@ -695,6 +712,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* @since 2.2
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-return class-string
|
||||
*/
|
||||
public function getDefaultRepositoryClassName()
|
||||
{
|
||||
@@ -918,3 +937,5 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
$this->_attributes['defaultQueryHints'][$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(MappingDriver::class);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Doctrine\ORM\Decorator;
|
||||
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManagerDecorator;
|
||||
use Doctrine\Persistence\ObjectManagerDecorator;
|
||||
|
||||
/**
|
||||
* Base class for EntityManager decorators
|
||||
@@ -65,7 +65,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
return $this->wrapped->beginTransaction();
|
||||
$this->wrapped->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->wrapped->commit();
|
||||
$this->wrapped->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
return $this->wrapped->rollback();
|
||||
$this->wrapped->rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +153,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return $this->wrapped->close();
|
||||
$this->wrapped->close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,15 +169,15 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function lock($entity, $lockMode, $lockVersion = null)
|
||||
{
|
||||
return $this->wrapped->lock($entity, $lockMode, $lockVersion);
|
||||
$this->wrapped->lock($entity, $lockMode, $lockVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($entityName, $id, $lockMode = null, $lockVersion = null)
|
||||
public function find($className, $id, $lockMode = null, $lockVersion = null)
|
||||
{
|
||||
return $this->wrapped->find($entityName, $id, $lockMode, $lockVersion);
|
||||
return $this->wrapped->find($className, $id, $lockMode, $lockVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +185,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
|
||||
*/
|
||||
public function flush($entity = null)
|
||||
{
|
||||
return $this->wrapped->flush($entity);
|
||||
$this->wrapped->flush($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,10 @@ use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\ORM\Proxy\ProxyFactory;
|
||||
use Doctrine\ORM\Query\FilterCollection;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\Persistence\Mapping\MappingException;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use Throwable;
|
||||
use function ltrim;
|
||||
use const E_USER_DEPRECATED;
|
||||
use function trigger_error;
|
||||
|
||||
@@ -325,7 +328,7 @@ use function trigger_error;
|
||||
*/
|
||||
public function createNamedNativeQuery($name)
|
||||
{
|
||||
list($sql, $rsm) = $this->config->getNamedNativeQuery($name);
|
||||
[$sql, $rsm] = $this->config->getNamedNativeQuery($name);
|
||||
|
||||
return $this->createNativeQuery($sql, $rsm);
|
||||
}
|
||||
@@ -371,7 +374,7 @@ use function trigger_error;
|
||||
/**
|
||||
* Finds an Entity by its identifier.
|
||||
*
|
||||
* @param string $entityName The class name of the entity to find.
|
||||
* @param string $className The class name of the entity to find.
|
||||
* @param mixed $id The identity of the entity to find.
|
||||
* @param integer|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
|
||||
* or NULL if no specific lock mode should be used
|
||||
@@ -386,9 +389,9 @@ use function trigger_error;
|
||||
* @throws TransactionRequiredException
|
||||
* @throws ORMException
|
||||
*/
|
||||
public function find($entityName, $id, $lockMode = null, $lockVersion = null)
|
||||
public function find($className, $id, $lockMode = null, $lockVersion = null)
|
||||
{
|
||||
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
|
||||
$class = $this->metadataFactory->getMetadataFor(ltrim($className, '\\'));
|
||||
|
||||
if ($lockMode !== null) {
|
||||
$this->checkLockRequirements($lockMode, $class);
|
||||
@@ -546,9 +549,9 @@ use function trigger_error;
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws ORMInvalidArgumentException if a non-null non-string value is given
|
||||
* @throws \Doctrine\Common\Persistence\Mapping\MappingException if a $entityName is given, but that entity is not
|
||||
* found in the mappings
|
||||
* @throws ORMInvalidArgumentException If a non-null non-string value is given.
|
||||
* @throws MappingException If a $entityName is given, but that entity is not
|
||||
* found in the mappings.
|
||||
*/
|
||||
public function clear($entityName = null)
|
||||
{
|
||||
@@ -729,7 +732,7 @@ use function trigger_error;
|
||||
*
|
||||
* @param string $entityName The name of the entity.
|
||||
*
|
||||
* @return \Doctrine\Common\Persistence\ObjectRepository|\Doctrine\ORM\EntityRepository The repository class.
|
||||
* @return ObjectRepository|EntityRepository The repository class.
|
||||
*/
|
||||
public function getRepository($entityName)
|
||||
{
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
/**
|
||||
* EntityManager interface
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\Common\Inflector\Inflector;
|
||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
/**
|
||||
* An EntityRepository serves as a repository for entities with generic as well as
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Event;
|
||||
|
||||
use Doctrine\Common\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
|
||||
|
||||
/**
|
||||
* Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Event;
|
||||
|
||||
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetadataEventArgs;
|
||||
use Doctrine\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetadataEventArgs;
|
||||
|
||||
/**
|
||||
* Class that holds event arguments for a loadMetadata event.
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
|
||||
namespace Doctrine\ORM\Event;
|
||||
|
||||
use Doctrine\Common\Persistence\Event\ManagerEventArgs;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\Event\ManagerEventArgs;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* Class that holds event arguments for a `onClassMetadataNotFound` event.
|
||||
@@ -84,3 +85,4 @@ class OnClassMetadataNotFoundEventArgs extends ManagerEventArgs
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -38,7 +38,7 @@ class OnClearEventArgs extends \Doctrine\Common\EventArgs
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
private $entityClass;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ abstract class AbstractIdGenerator
|
||||
* By default, this method returns FALSE. Generators that have this requirement
|
||||
* must override this method and return TRUE.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isPostInsertGenerator()
|
||||
{
|
||||
|
||||
@@ -228,14 +228,14 @@ abstract class AbstractHydrator
|
||||
*
|
||||
* Template method.
|
||||
*
|
||||
* @param array $data The row data.
|
||||
* @param array $result The result to fill.
|
||||
* @param mixed[] $row The row data.
|
||||
* @param mixed[] $result The result to fill.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws HydrationException
|
||||
*/
|
||||
protected function hydrateRowData(array $data, array &$result)
|
||||
protected function hydrateRowData(array $row, array &$result)
|
||||
{
|
||||
throw new HydrationException("hydrateRowData() not implemented by this hydrator.");
|
||||
}
|
||||
@@ -260,8 +260,19 @@ abstract class AbstractHydrator
|
||||
* @param array &$id Dql-Alias => ID-Hash.
|
||||
* @param array &$nonemptyComponents Does this DQL-Alias has at least one non NULL value?
|
||||
*
|
||||
* @return array An array with all the fields (name => value) of the data row,
|
||||
* grouped by their component alias.
|
||||
* @return array<string, array<string, mixed>> An array with all the fields
|
||||
* (name => value) of the data
|
||||
* row, grouped by their
|
||||
* component alias.
|
||||
*
|
||||
* @psalm-return array{
|
||||
* data: array<array-key, array>,
|
||||
* newObjects?: array<array-key, array{
|
||||
* class: mixed,
|
||||
* args?: array
|
||||
* }>,
|
||||
* scalars?: array
|
||||
* }
|
||||
*/
|
||||
protected function gatherRowData(array $data, array &$id, array &$nonemptyComponents)
|
||||
{
|
||||
|
||||
@@ -47,8 +47,8 @@ class ScalarHydrator extends AbstractHydrator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function hydrateRowData(array $data, array &$result)
|
||||
protected function hydrateRowData(array $row, array &$result)
|
||||
{
|
||||
$result[] = $this->gatherScalarRowData($data);
|
||||
$result[] = $this->gatherScalarRowData($row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Doctrine\ORM\Internal\Hydration;
|
||||
use PDO;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Query;
|
||||
use function array_keys;
|
||||
use function in_array;
|
||||
|
||||
class SimpleObjectHydrator extends AbstractHydrator
|
||||
@@ -77,7 +78,7 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function hydrateRowData(array $sqlResult, array &$result)
|
||||
protected function hydrateRowData(array $row, array &$result)
|
||||
{
|
||||
$entityName = $this->class->name;
|
||||
$data = [];
|
||||
@@ -92,27 +93,27 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
$discrColumnName = $metaMappingDiscrColumnName;
|
||||
}
|
||||
|
||||
if ( ! isset($sqlResult[$discrColumnName])) {
|
||||
if (! isset($row[$discrColumnName])) {
|
||||
throw HydrationException::missingDiscriminatorColumn($entityName, $discrColumnName, key($this->_rsm->aliasMap));
|
||||
}
|
||||
|
||||
if ($sqlResult[$discrColumnName] === '') {
|
||||
if ($row[$discrColumnName] === '') {
|
||||
throw HydrationException::emptyDiscriminatorValue(key($this->_rsm->aliasMap));
|
||||
}
|
||||
|
||||
$discrMap = $this->class->discriminatorMap;
|
||||
|
||||
if ( ! isset($discrMap[$sqlResult[$discrColumnName]])) {
|
||||
throw HydrationException::invalidDiscriminatorValue($sqlResult[$discrColumnName], array_keys($discrMap));
|
||||
if (! isset($discrMap[$row[$discrColumnName]])) {
|
||||
throw HydrationException::invalidDiscriminatorValue($row[$discrColumnName], array_keys($discrMap));
|
||||
}
|
||||
|
||||
$entityName = $discrMap[$sqlResult[$discrColumnName]];
|
||||
$discrColumnValue = $sqlResult[$discrColumnName];
|
||||
$entityName = $discrMap[$row[$discrColumnName]];
|
||||
$discrColumnValue = $row[$discrColumnName];
|
||||
|
||||
unset($sqlResult[$discrColumnName]);
|
||||
unset($row[$discrColumnName]);
|
||||
}
|
||||
|
||||
foreach ($sqlResult as $column => $value) {
|
||||
foreach ($row as $column => $value) {
|
||||
// An ObjectHydrator should be used instead of SimpleObjectHydrator
|
||||
if (isset($this->_rsm->relationMap[$column])) {
|
||||
throw new \Exception(sprintf('Unable to retrieve association information for column "%s"', $column));
|
||||
|
||||
@@ -89,7 +89,7 @@ final class HydrationCompleteHandler
|
||||
$this->deferredPostLoadInvocations = [];
|
||||
|
||||
foreach ($toInvoke as $classAndEntity) {
|
||||
list($class, $invoke, $entity) = $classAndEntity;
|
||||
[$class, $invoke, $entity] = $classAndEntity;
|
||||
|
||||
$this->listenersInvoker->invoke(
|
||||
$class,
|
||||
|
||||
@@ -58,7 +58,7 @@ class AssociationBuilder
|
||||
/**
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function mappedBy($fieldName)
|
||||
{
|
||||
@@ -70,7 +70,7 @@ class AssociationBuilder
|
||||
/**
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function inversedBy($fieldName)
|
||||
{
|
||||
@@ -80,7 +80,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadeAll()
|
||||
{
|
||||
@@ -90,7 +90,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadePersist()
|
||||
{
|
||||
@@ -100,7 +100,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadeRemove()
|
||||
{
|
||||
@@ -110,7 +110,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadeMerge()
|
||||
{
|
||||
@@ -120,7 +120,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadeDetach()
|
||||
{
|
||||
@@ -130,7 +130,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function cascadeRefresh()
|
||||
{
|
||||
@@ -140,7 +140,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function fetchExtraLazy()
|
||||
{
|
||||
@@ -150,7 +150,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function fetchEager()
|
||||
{
|
||||
@@ -160,7 +160,7 @@ class AssociationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function fetchLazy()
|
||||
{
|
||||
@@ -179,7 +179,7 @@ class AssociationBuilder
|
||||
* @param string|null $onDelete
|
||||
* @param string|null $columnDef
|
||||
*
|
||||
* @return AssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ class AssociationBuilder
|
||||
/**
|
||||
* Sets field as primary key.
|
||||
*
|
||||
* @return self
|
||||
* @return static
|
||||
*/
|
||||
public function makePrimaryKey()
|
||||
{
|
||||
@@ -210,7 +210,7 @@ class AssociationBuilder
|
||||
/**
|
||||
* Removes orphan entities when detached from their parent.
|
||||
*
|
||||
* @return self
|
||||
* @return static
|
||||
*/
|
||||
public function orphanRemoval()
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Marks the class as mapped superclass.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setMappedSuperClass()
|
||||
{
|
||||
@@ -70,7 +70,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Marks the class as embeddable.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setEmbeddable()
|
||||
{
|
||||
@@ -107,7 +107,7 @@ class ClassMetadataBuilder
|
||||
*
|
||||
* @param string $repositoryClassName
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setCustomRepositoryClass($repositoryClassName)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Marks class read only.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setReadOnly()
|
||||
{
|
||||
@@ -133,7 +133,7 @@ class ClassMetadataBuilder
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setTable($name)
|
||||
{
|
||||
@@ -148,7 +148,7 @@ class ClassMetadataBuilder
|
||||
* @param array $columns
|
||||
* @param string $name
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addIndex(array $columns, $name)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ class ClassMetadataBuilder
|
||||
* @param array $columns
|
||||
* @param string $name
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addUniqueConstraint(array $columns, $name)
|
||||
{
|
||||
@@ -186,7 +186,7 @@ class ClassMetadataBuilder
|
||||
* @param string $name
|
||||
* @param string $dqlQuery
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addNamedQuery($name, $dqlQuery)
|
||||
{
|
||||
@@ -203,7 +203,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Sets class as root of a joined table inheritance hierarchy.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setJoinedTableInheritance()
|
||||
{
|
||||
@@ -215,7 +215,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Sets class as root of a single table inheritance hierarchy.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setSingleTableInheritance()
|
||||
{
|
||||
@@ -231,7 +231,7 @@ class ClassMetadataBuilder
|
||||
* @param string $type
|
||||
* @param int $length
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setDiscriminatorColumn($name, $type = 'string', $length = 255)
|
||||
{
|
||||
@@ -252,7 +252,7 @@ class ClassMetadataBuilder
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addDiscriminatorMapClass($name, $class)
|
||||
{
|
||||
@@ -264,7 +264,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Sets deferred explicit change tracking policy.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setChangeTrackingPolicyDeferredExplicit()
|
||||
{
|
||||
@@ -276,7 +276,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Sets notify change tracking policy.
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setChangeTrackingPolicyNotify()
|
||||
{
|
||||
@@ -291,7 +291,7 @@ class ClassMetadataBuilder
|
||||
* @param string $methodName
|
||||
* @param string $event
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addLifecycleEvent($methodName, $event)
|
||||
{
|
||||
@@ -307,7 +307,7 @@ class ClassMetadataBuilder
|
||||
* @param string $type
|
||||
* @param array $mapping
|
||||
*
|
||||
* @return ClassMetadataBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addField($name, $type, array $mapping = [])
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function length($length)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param bool $flag
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function nullable($flag = true)
|
||||
{
|
||||
@@ -102,7 +102,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param bool $flag
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function unique($flag = true)
|
||||
{
|
||||
@@ -116,7 +116,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function columnName($name)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param int $p
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function precision($p)
|
||||
{
|
||||
@@ -144,7 +144,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param int $s
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function scale($s)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ class FieldBuilder
|
||||
/**
|
||||
* Sets field as primary key.
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function makePrimaryKey()
|
||||
{
|
||||
@@ -182,7 +182,7 @@ class FieldBuilder
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function option($name, $value)
|
||||
{
|
||||
@@ -194,7 +194,7 @@ class FieldBuilder
|
||||
/**
|
||||
* @param string $strategy
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function generatedValue($strategy = 'AUTO')
|
||||
{
|
||||
@@ -206,7 +206,7 @@ class FieldBuilder
|
||||
/**
|
||||
* Sets field versioned.
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function isVersionField()
|
||||
{
|
||||
@@ -222,7 +222,7 @@ class FieldBuilder
|
||||
* @param int $allocationSize
|
||||
* @param int $initialValue
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setSequenceGenerator($sequenceName, $allocationSize = 1, $initialValue = 1)
|
||||
{
|
||||
@@ -240,7 +240,7 @@ class FieldBuilder
|
||||
*
|
||||
* @param string $def
|
||||
*
|
||||
* @return FieldBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function columnDefinition($def)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return ManyToManyAssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setJoinTable($name)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
|
||||
* @param string|null $onDelete
|
||||
* @param string|null $columnDef
|
||||
*
|
||||
* @return ManyToManyAssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function addInverseJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ class OneToManyAssociationBuilder extends AssociationBuilder
|
||||
/**
|
||||
* @param array $fieldNames
|
||||
*
|
||||
* @return OneToManyAssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setOrderBy(array $fieldNames)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ class OneToManyAssociationBuilder extends AssociationBuilder
|
||||
/**
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return OneToManyAssociationBuilder
|
||||
* @return static
|
||||
*/
|
||||
public function setIndexBy($fieldName)
|
||||
{
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
|
||||
use Doctrine\Common\Persistence\Mapping\ReflectionService;
|
||||
use Doctrine\DBAL\Platforms;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
|
||||
@@ -30,8 +27,14 @@ use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\Id\BigIntegerIdentityGenerator;
|
||||
use Doctrine\ORM\Id\IdentityGenerator;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Persistence\Mapping\ReflectionService;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use function assert;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
|
||||
@@ -57,7 +60,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
private $targetPlatform;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
|
||||
* @var MappingDriver
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
@@ -276,6 +279,11 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
if ( ! $class->discriminatorColumn) {
|
||||
throw MappingException::missingDiscriminatorColumn($class->name);
|
||||
}
|
||||
foreach ($class->subClasses as $subClass) {
|
||||
if ((new ReflectionClass($subClass))->name !== $subClass) {
|
||||
throw MappingException::invalidClassInDiscriminatorMap($subClass, $class->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
|
||||
// second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
|
||||
@@ -402,7 +410,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
|
||||
{
|
||||
foreach ($parentClass->fieldMappings as $mapping) {
|
||||
if (! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass && ! $parentClass->isEmbeddedClass) {
|
||||
if (! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
|
||||
$mapping['inherited'] = $parentClass->name;
|
||||
}
|
||||
if (! isset($mapping['declared'])) {
|
||||
@@ -470,6 +478,10 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
private function addNestedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass, $prefix)
|
||||
{
|
||||
foreach ($subClass->embeddedClasses as $property => $embeddableClass) {
|
||||
if (isset($embeddableClass['inherited'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
|
||||
|
||||
$parentClass->mapEmbedded(
|
||||
@@ -777,9 +789,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
*/
|
||||
protected function isEntity(ClassMetadataInterface $class)
|
||||
{
|
||||
assert($class instanceof ClassMetadata);
|
||||
|
||||
return $class->isMappedSuperclass === false && $class->isEmbeddedClass === false;
|
||||
return isset($class->isMappedSuperclass) && $class->isMappedSuperclass === false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,3 +804,6 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
return $this->targetPlatform;
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadataInterface::class);
|
||||
interface_exists(ReflectionService::class);
|
||||
|
||||
@@ -20,14 +20,18 @@
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Doctrine\Instantiator\Instantiator;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use ReflectionClass;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Instantiator\Instantiator;
|
||||
use Doctrine\ORM\Cache\CacheException;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\ReflectionService;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use RuntimeException;
|
||||
use function count;
|
||||
use function explode;
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
|
||||
@@ -251,7 +255,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* The name of the custom repository class used for the entity class.
|
||||
* (Optional).
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
* @psalm-var ?class-string
|
||||
*/
|
||||
public $customRepositoryClassName;
|
||||
|
||||
@@ -392,6 +397,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* Whether a unique constraint should be generated for the column.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @psalm-var array<string, array{type: string, fieldName: string, columnName: string, inherited: class-string}>
|
||||
*/
|
||||
public $fieldMappings = [];
|
||||
|
||||
@@ -639,7 +646,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* The ReflectionProperty instances of the mapped class.
|
||||
*
|
||||
* @var \ReflectionProperty[]
|
||||
* @var ReflectionProperty[]|null[]
|
||||
*/
|
||||
public $reflFields = [];
|
||||
|
||||
@@ -666,7 +673,9 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* Gets the ReflectionProperties of the mapped class.
|
||||
*
|
||||
* @return array An array of ReflectionProperty instances.
|
||||
* @return ReflectionProperty[]|null[] An array of ReflectionProperty instances.
|
||||
*
|
||||
* @psalm-return array<ReflectionProperty|null>
|
||||
*/
|
||||
public function getReflectionProperties()
|
||||
{
|
||||
@@ -678,7 +687,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return \ReflectionProperty
|
||||
* @return ReflectionProperty
|
||||
*/
|
||||
public function getReflectionProperty($name)
|
||||
{
|
||||
@@ -688,7 +697,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* Gets the ReflectionProperty for the single identifier field.
|
||||
*
|
||||
* @return \ReflectionProperty
|
||||
* @return ReflectionProperty
|
||||
*
|
||||
* @throws BadMethodCallException If the class has a composite identifier.
|
||||
*/
|
||||
@@ -804,7 +813,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* - reflClass (ReflectionClass)
|
||||
* - reflFields (ReflectionProperty array)
|
||||
*
|
||||
* @return array The names of all the fields that should be serialized.
|
||||
* @return string[] The names of all the fields that should be serialized.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
@@ -914,7 +923,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* Restores some state that can not be serialized/unserialized.
|
||||
*
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ReflectionService $reflService
|
||||
* @param ReflectionService $reflService
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -975,7 +984,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ReflectionService $reflService The reflection service.
|
||||
* @param ReflectionService $reflService The reflection service.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -1037,7 +1046,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* Validates lifecycle callbacks.
|
||||
*
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ReflectionService $reflService
|
||||
* @param ReflectionService $reflService
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
@@ -1095,7 +1104,10 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* @param string $fieldName
|
||||
* @param array $cache
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-param array{usage: mixed, region: mixed} $cache
|
||||
* @psalm-return array{usage: mixed, region: mixed}
|
||||
*/
|
||||
public function getAssociationCacheDefaults($fieldName, array $cache)
|
||||
{
|
||||
@@ -1444,9 +1456,25 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param array $mapping The mapping.
|
||||
*
|
||||
* @return array The updated mapping.
|
||||
* @return mixed[] The updated mapping.
|
||||
*
|
||||
* @throws MappingException If something is wrong with the mapping.
|
||||
*
|
||||
* @psalm-return array{
|
||||
* mappedBy: mixed,
|
||||
* inversedBy: mixed,
|
||||
* isOwningSide: bool,
|
||||
* sourceEntity: string,
|
||||
* targetEntity: string,
|
||||
* fieldName: mixed,
|
||||
* fetch: mixed,
|
||||
* cascade: array<array-key,string>,
|
||||
* isCascadeRemove: bool,
|
||||
* isCascadePersist: bool,
|
||||
* isCascadeRefresh: bool,
|
||||
* isCascadeMerge: bool,
|
||||
* isCascadeDetach: bool
|
||||
* }
|
||||
*/
|
||||
protected function _validateAndCompleteAssociationMapping(array $mapping)
|
||||
{
|
||||
@@ -1564,10 +1592,12 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param array $mapping The mapping to validate & complete.
|
||||
*
|
||||
* @return array The validated & completed mapping.
|
||||
* @return mixed[] The validated & completed mapping.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws MappingException
|
||||
*
|
||||
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool, isCascadeRemove: bool}
|
||||
*/
|
||||
protected function _validateAndCompleteOneToOneMapping(array $mapping)
|
||||
{
|
||||
@@ -1655,10 +1685,27 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param array $mapping The mapping to validate and complete.
|
||||
*
|
||||
* @return array The validated and completed mapping.
|
||||
* @return mixed[] The validated and completed mapping.
|
||||
*
|
||||
* @throws MappingException
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @psalm-return array{
|
||||
* mappedBy: mixed,
|
||||
* inversedBy: mixed,
|
||||
* isOwningSide: bool,
|
||||
* sourceEntity: string,
|
||||
* targetEntity: string,
|
||||
* fieldName: mixed,
|
||||
* fetch: int|mixed,
|
||||
* cascade: array<array-key,string>,
|
||||
* isCascadeRemove: bool,
|
||||
* isCascadePersist: bool,
|
||||
* isCascadeRefresh: bool,
|
||||
* isCascadeMerge: bool,
|
||||
* isCascadeDetach: bool,
|
||||
* orphanRemoval: bool
|
||||
* }
|
||||
*/
|
||||
protected function _validateAndCompleteOneToManyMapping(array $mapping)
|
||||
{
|
||||
@@ -1682,9 +1729,11 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param array $mapping The mapping to validate & complete.
|
||||
*
|
||||
* @return array The validated & completed mapping.
|
||||
* @return mixed[] The validated & completed mapping.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool}
|
||||
*/
|
||||
protected function _validateAndCompleteManyToManyMapping(array $mapping)
|
||||
{
|
||||
@@ -1861,7 +1910,9 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*
|
||||
* @param array|null $fieldNames
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public function getColumnNames(array $fieldNames = null)
|
||||
{
|
||||
@@ -2142,6 +2193,13 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
$mapping = $this->associationMappings[$fieldName];
|
||||
|
||||
//if (isset($mapping['inherited']) && (count($overrideMapping) !== 1 || ! isset($overrideMapping['fetch']))) {
|
||||
// TODO: Deprecate overriding the fetch mode via association override for 3.0,
|
||||
// users should do this with a listener and a custom attribute/annotation
|
||||
// TODO: Enable this exception in 2.8
|
||||
//throw MappingException::illegalOverrideOfInheritedProperty($this->name, $fieldName);
|
||||
//}
|
||||
|
||||
if (isset($overrideMapping['joinColumns'])) {
|
||||
$mapping['joinColumns'] = $overrideMapping['joinColumns'];
|
||||
}
|
||||
@@ -2200,6 +2258,11 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
$mapping = $this->fieldMappings[$fieldName];
|
||||
|
||||
//if (isset($mapping['inherited'])) {
|
||||
// TODO: Enable this exception in 2.8
|
||||
//throw MappingException::illegalOverrideOfInheritedProperty($this->name, $fieldName);
|
||||
//}
|
||||
|
||||
if (isset($mapping['id'])) {
|
||||
$overrideMapping['id'] = $mapping['id'];
|
||||
}
|
||||
@@ -2297,7 +2360,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
if (isset($table['name'])) {
|
||||
// Split schema and table name from a table name like "myschema.mytable"
|
||||
if (strpos($table['name'], '.') !== false) {
|
||||
list($this->table['schema'], $table['name']) = explode('.', $table['name'], 2);
|
||||
[$this->table['schema'], $table['name']] = explode('.', $table['name'], 2);
|
||||
}
|
||||
|
||||
if ($table['name'][0] === '`') {
|
||||
@@ -2523,7 +2586,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
if (!isset($field['column'])) {
|
||||
$fieldName = $field['name'];
|
||||
if (strpos($fieldName, '.')) {
|
||||
list(, $fieldName) = explode('.', $fieldName);
|
||||
[, $fieldName] = explode('.', $fieldName);
|
||||
}
|
||||
|
||||
$resultMapping['entities'][$key]['fields'][$k]['column'] = $fieldName;
|
||||
@@ -2625,6 +2688,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* @param string $repositoryClassName The class name of the custom mapper.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param class-string $repositoryClassName
|
||||
*/
|
||||
public function setCustomRepositoryClass($repositoryClassName)
|
||||
{
|
||||
@@ -3253,6 +3318,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* @param string|null $className
|
||||
*
|
||||
* @return string|null null if the input value is null
|
||||
*
|
||||
* @psalm-param ?class-string $className
|
||||
*/
|
||||
public function fullyQualifiedClassName($className)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ class DefaultEntityListenerResolver implements EntityListenerResolver
|
||||
{
|
||||
/**
|
||||
* @var array Map to store entity listener instances.
|
||||
*
|
||||
* @psalm-var array<class-string, object>
|
||||
*/
|
||||
private $instances = [];
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\Mapping;
|
||||
use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* The AnnotationDriver reads the mapping metadata from docblock annotations.
|
||||
@@ -39,12 +40,12 @@ use Doctrine\ORM\Mapping\MappingException;
|
||||
class AnnotationDriver extends AbstractAnnotationDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @var int[]
|
||||
* @psalm-var array<class-string, int>
|
||||
*/
|
||||
protected $entityAnnotationClasses = [
|
||||
Mapping\Entity::class => 1,
|
||||
Mapping\MappedSuperclass::class => 2,
|
||||
Mapping\Embeddable::class => 3,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -274,11 +275,8 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
}
|
||||
|
||||
// Evaluate annotations on properties/fields
|
||||
/* @var $property \ReflectionProperty */
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
|
||||
||
|
||||
$metadata->isEmbeddedClass && $property->getDeclaringClass()->getName() !== $class->getName()
|
||||
||
|
||||
$metadata->isInheritedField($property->name)
|
||||
||
|
||||
@@ -344,7 +342,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
'initialValue' => $seqGeneratorAnnot->initialValue
|
||||
]
|
||||
);
|
||||
} else if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
|
||||
} elseif ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Id\TableGenerator')) {
|
||||
throw MappingException::tableIdGeneratorNotImplemented($className);
|
||||
} else if ($customGeneratorAnnot = $this->reader->getPropertyAnnotation($property, Mapping\CustomIdGenerator::class)) {
|
||||
$metadata->setCustomGeneratorDefinition(
|
||||
@@ -507,7 +505,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
$hasMapping = false;
|
||||
$listenerClass = new \ReflectionClass($listenerClassName);
|
||||
|
||||
/* @var $method \ReflectionMethod */
|
||||
foreach ($listenerClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
// find method callbacks.
|
||||
$callbacks = $this->getMethodCallbacks($method);
|
||||
@@ -527,7 +524,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
|
||||
// Evaluate @HasLifecycleCallbacks annotation
|
||||
if (isset($classAnnotations[Mapping\HasLifecycleCallbacks::class])) {
|
||||
/* @var $method \ReflectionMethod */
|
||||
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
foreach ($this->getMethodCallbacks($method) as $value) {
|
||||
$metadata->addLifecycleCallback($value[0], $value[1]);
|
||||
@@ -560,7 +556,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
*
|
||||
* @param \ReflectionMethod $method
|
||||
*
|
||||
* @return array
|
||||
* @return callable[]
|
||||
*/
|
||||
private function getMethodCallbacks(\ReflectionMethod $method)
|
||||
{
|
||||
@@ -608,7 +604,17 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
* Parse the given JoinColumn as array
|
||||
*
|
||||
* @param Mapping\JoinColumn $joinColumn
|
||||
* @return array
|
||||
*
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return array{
|
||||
* name: string,
|
||||
* unique: bool,
|
||||
* nullable: bool,
|
||||
* onDelete: mixed,
|
||||
* columnDefinition: string,
|
||||
* referencedColumnName: string
|
||||
* }
|
||||
*/
|
||||
private function joinColumnToArray(Mapping\JoinColumn $joinColumn)
|
||||
{
|
||||
@@ -628,7 +634,20 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
* @param string $fieldName
|
||||
* @param Mapping\Column $column
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return array{
|
||||
* fieldName: string,
|
||||
* type: mixed,
|
||||
* scale: int,
|
||||
* length: int,
|
||||
* unique: bool,
|
||||
* nullable: bool,
|
||||
* precision: int,
|
||||
* options?: mixed[],
|
||||
* columnName?: string,
|
||||
* columnDefinition?: string
|
||||
* }
|
||||
*/
|
||||
private function columnToArray($fieldName, Mapping\Column $column)
|
||||
{
|
||||
@@ -674,3 +693,5 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
return new self($reader, $paths);
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -20,15 +20,17 @@
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Inflector\Inflector;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
|
||||
use Doctrine\DBAL\Schema\SchemaException;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use function interface_exists;
|
||||
use function preg_replace;
|
||||
|
||||
/**
|
||||
@@ -387,6 +389,22 @@ class DatabaseDriver implements MappingDriver
|
||||
* @param \Doctrine\DBAL\Schema\Column $column
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @psalm-return array{
|
||||
* fieldName: string,
|
||||
* columnName: string,
|
||||
* type: string,
|
||||
* nullable: bool,
|
||||
* options?: array{
|
||||
* unsigned?: bool,
|
||||
* fixed?: bool,
|
||||
* comment?: string,
|
||||
* default?: string
|
||||
* },
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* length?: int|null
|
||||
* }
|
||||
*/
|
||||
private function buildFieldMapping($tableName, Column $column)
|
||||
{
|
||||
@@ -487,7 +505,9 @@ class DatabaseDriver implements MappingDriver
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Table $table
|
||||
*
|
||||
* @return array
|
||||
* @return ForeignKeyConstraint[]
|
||||
*
|
||||
* @psalm-return array<string, ForeignKeyConstraint>
|
||||
*/
|
||||
private function getTableForeignKeys(Table $table)
|
||||
{
|
||||
@@ -501,7 +521,7 @@ class DatabaseDriver implements MappingDriver
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Table $table
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
private function getTablePrimaryKeys(Table $table)
|
||||
{
|
||||
@@ -555,3 +575,5 @@ class DatabaseDriver implements MappingDriver
|
||||
return Inflector::camelize($columnName);
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain instead
|
||||
* @deprecated this driver will be removed. Use Doctrine\Persistence\Mapping\Driver\MappingDriverChain instead
|
||||
*/
|
||||
class DriverChain extends MappingDriverChain
|
||||
{
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver as CommonPHPDriver;
|
||||
use Doctrine\Persistence\Mapping\Driver\PHPDriver as CommonPHPDriver;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver instead
|
||||
* @deprecated this driver will be removed. Use Doctrine\Persistence\Mapping\Driver\PHPDriver instead
|
||||
*/
|
||||
class PHPDriver extends CommonPHPDriver
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
|
||||
use Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator;
|
||||
|
||||
/**
|
||||
* XmlDriver that additionally looks for mapping information in a global file.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
|
||||
use Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator;
|
||||
|
||||
/**
|
||||
* YamlDriver that additionally looks for mapping information in a global file.
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver as CommonStaticPHPDriver;
|
||||
use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver as CommonStaticPHPDriver;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver instead
|
||||
* @deprecated this driver will be removed. Use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver instead
|
||||
*/
|
||||
class StaticPHPDriver extends CommonStaticPHPDriver
|
||||
{
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use SimpleXMLElement;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
|
||||
use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata as Metadata;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\Driver\FileDriver;
|
||||
use SimpleXMLElement;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* XmlDriver is a metadata driver that enables mapping through XML files.
|
||||
@@ -670,13 +671,12 @@ class XmlDriver extends FileDriver
|
||||
*
|
||||
* @param SimpleXMLElement $options The XML element.
|
||||
*
|
||||
* @return array The options array.
|
||||
* @return mixed[] The options array.
|
||||
*/
|
||||
private function _parseOptions(SimpleXMLElement $options)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
/* @var $option SimpleXMLElement */
|
||||
foreach ($options as $option) {
|
||||
if ($option->count()) {
|
||||
$value = $this->_parseOptions($option->children());
|
||||
@@ -705,7 +705,16 @@ class XmlDriver extends FileDriver
|
||||
*
|
||||
* @param SimpleXMLElement $joinColumnElement The XML element.
|
||||
*
|
||||
* @return array The mapping array.
|
||||
* @return mixed[] The mapping array.
|
||||
*
|
||||
* @psalm-return array{
|
||||
* name: string,
|
||||
* referencedColumnName: string,
|
||||
* unique?: bool,
|
||||
* nullable?: bool,
|
||||
* onDelete?: string,
|
||||
* columnDefinition?: string
|
||||
* }
|
||||
*/
|
||||
private function joinColumnToArray(SimpleXMLElement $joinColumnElement)
|
||||
{
|
||||
@@ -734,12 +743,24 @@ class XmlDriver extends FileDriver
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given field as array.
|
||||
*
|
||||
* @param SimpleXMLElement $fieldMapping
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
* Parses the given field as array.
|
||||
*
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return array{
|
||||
* fieldName: string,
|
||||
* type?: string,
|
||||
* columnName?: string,
|
||||
* length?: int,
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* unique?: bool,
|
||||
* nullable?: bool,
|
||||
* version?: bool,
|
||||
* columnDefinition?: string,
|
||||
* options?: array
|
||||
* }
|
||||
*/
|
||||
private function columnToArray(SimpleXMLElement $fieldMapping)
|
||||
{
|
||||
$mapping = [
|
||||
@@ -794,7 +815,9 @@ class XmlDriver extends FileDriver
|
||||
*
|
||||
* @param SimpleXMLElement $cacheMapping
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return array{usage: mixed, region: string|null}
|
||||
*/
|
||||
private function cacheToArray(SimpleXMLElement $cacheMapping)
|
||||
{
|
||||
@@ -820,12 +843,13 @@ class XmlDriver extends FileDriver
|
||||
*
|
||||
* @param SimpleXMLElement $cascadeElement The cascade element.
|
||||
*
|
||||
* @return array The list of cascade options.
|
||||
* @return string[] The list of cascade options.
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
private function _getCascadeMappings(SimpleXMLElement $cascadeElement)
|
||||
{
|
||||
$cascades = [];
|
||||
/* @var $action SimpleXmlElement */
|
||||
foreach ($cascadeElement->children() as $action) {
|
||||
// According to the JPA specifications, XML uses "cascade-persist"
|
||||
// instead of "persist". Here, both variations
|
||||
@@ -879,3 +903,5 @@ class XmlDriver extends FileDriver
|
||||
return ($flag == "true" || $flag == "1");
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata as Metadata;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\Driver\FileDriver;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use function interface_exists;
|
||||
use function trigger_error;
|
||||
|
||||
/**
|
||||
@@ -683,7 +684,17 @@ class YamlDriver extends FileDriver
|
||||
*
|
||||
* @param array $joinColumnElement The array join column element.
|
||||
*
|
||||
* @return array The mapping array.
|
||||
* @return mixed[] The mapping array.
|
||||
*
|
||||
* @psalm-return array{
|
||||
* referencedColumnName?: string,
|
||||
* name?: string,
|
||||
* fieldName?: string,
|
||||
* unique?: bool,
|
||||
* nullable?: bool,
|
||||
* onDelete?: mixed,
|
||||
* columnDefinition?: mixed
|
||||
* }
|
||||
*/
|
||||
private function joinColumnToArray($joinColumnElement)
|
||||
{
|
||||
@@ -725,7 +736,21 @@ class YamlDriver extends FileDriver
|
||||
* @param string $fieldName
|
||||
* @param array $column
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return array{
|
||||
* fieldName: string,
|
||||
* type?: string,
|
||||
* columnName?: mixed,
|
||||
* length?: mixed,
|
||||
* precision?: mixed,
|
||||
* scale?: mixed,
|
||||
* unique?: bool,
|
||||
* options?: mixed,
|
||||
* nullable?: mixed,
|
||||
* version?: mixed,
|
||||
* columnDefinition?: mixed
|
||||
* }
|
||||
*/
|
||||
private function columnToArray($fieldName, $column)
|
||||
{
|
||||
@@ -786,9 +811,12 @@ class YamlDriver extends FileDriver
|
||||
/**
|
||||
* Parse / Normalize the cache configuration
|
||||
*
|
||||
* @param array $cacheMapping
|
||||
* @param mixed[] $cacheMapping
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-param array{usage: mixed, region: null|string} $cacheMapping
|
||||
* @psalm-return array{usage: mixed, region: null|string}
|
||||
*/
|
||||
private function cacheToArray($cacheMapping)
|
||||
{
|
||||
@@ -817,3 +845,5 @@ class YamlDriver extends FileDriver
|
||||
return Yaml::parse(file_get_contents($file));
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -34,6 +34,8 @@ interface EntityListenerResolver
|
||||
* @param string $className The fully-qualified class name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param class-string $className
|
||||
*/
|
||||
function clear($className = null);
|
||||
|
||||
@@ -43,6 +45,8 @@ interface EntityListenerResolver
|
||||
* @param string $className The fully-qualified class name
|
||||
*
|
||||
* @return object An entity listener
|
||||
*
|
||||
* @psalm-param class-string $className
|
||||
*/
|
||||
function resolve($className);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* A MappingException indicates that something is wrong with the mapping setup.
|
||||
*
|
||||
@@ -820,4 +822,16 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function illegalOverrideOfInheritedProperty($className, $propertyName)
|
||||
{
|
||||
return new self(
|
||||
sprintf(
|
||||
'Override for %s::%s is only allowed for attributes/associations ' .
|
||||
'declared on a mapped superclass or a trait.',
|
||||
$className,
|
||||
$propertyName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Reflection;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ReflectionService;
|
||||
use Doctrine\Persistence\Mapping\ReflectionService;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
@@ -52,9 +52,11 @@ final class ReflectionPropertiesGetter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $className
|
||||
* @param string $className
|
||||
*
|
||||
* @return ReflectionProperty[] indexed by property internal name
|
||||
*
|
||||
* @psalm-param class-string $className
|
||||
*/
|
||||
public function getProperties($className)
|
||||
{
|
||||
@@ -79,8 +81,10 @@ final class ReflectionPropertiesGetter
|
||||
* @param string $className
|
||||
*
|
||||
* @return ReflectionClass[]
|
||||
*
|
||||
* @psalm-return list<ReflectionClass>
|
||||
*/
|
||||
private function getHierarchyClasses($className)
|
||||
private function getHierarchyClasses($className) : array
|
||||
{
|
||||
$classes = [];
|
||||
$parentClassName = $className;
|
||||
@@ -97,13 +101,17 @@ final class ReflectionPropertiesGetter
|
||||
return $classes;
|
||||
}
|
||||
|
||||
// phpcs:disable SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod
|
||||
/**
|
||||
* @param ReflectionClass $reflectionClass
|
||||
*
|
||||
* @return ReflectionProperty[]
|
||||
*
|
||||
* @psalm-return array<string, ReflectionProperty>
|
||||
*/
|
||||
private function getClassProperties(ReflectionClass $reflectionClass)
|
||||
private function getClassProperties(ReflectionClass $reflectionClass) : array
|
||||
{
|
||||
// phpcs:enable SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod
|
||||
$properties = $reflectionClass->getProperties();
|
||||
|
||||
return array_filter(
|
||||
|
||||
@@ -37,9 +37,9 @@ final class NativeQuery extends AbstractQuery
|
||||
*
|
||||
* @param string $sql
|
||||
*
|
||||
* @return NativeQuery This query instance.
|
||||
* @return self This query instance.
|
||||
*/
|
||||
public function setSQL($sql)
|
||||
public function setSQL($sql) : self
|
||||
{
|
||||
$this->_sql = $sql;
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\Cache\Cache as CacheDriver;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use Exception;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Base exception class for all ORM exceptions.
|
||||
@@ -108,7 +110,7 @@ class ORMException extends Exception
|
||||
* @param string $given
|
||||
* @param string $expected
|
||||
*
|
||||
* @return \Doctrine\ORM\ORMInvalidArgumentException
|
||||
* @return \Doctrine\ORM\ORMException
|
||||
*/
|
||||
public static function unexpectedAssociationValue($class, $association, $given, $expected)
|
||||
{
|
||||
@@ -295,7 +297,11 @@ class ORMException extends Exception
|
||||
*/
|
||||
public static function invalidEntityRepository($className)
|
||||
{
|
||||
return new self("Invalid repository class '".$className."'. It must be a Doctrine\Common\Persistence\ObjectRepository.");
|
||||
return new self(sprintf(
|
||||
"Invalid repository class '%s'. It must be a %s.",
|
||||
$className,
|
||||
ObjectRepository::class
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ class OptimisticLockException extends ORMException
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @param object $entity
|
||||
* @param object|null $entity
|
||||
*/
|
||||
public function __construct($msg, $entity)
|
||||
{
|
||||
|
||||
@@ -337,6 +337,8 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
@@ -510,6 +512,8 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
@@ -569,9 +573,11 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* Internal note: Tried to implement Serializable first but that did not work well
|
||||
* with circular references. This solution seems simpler and works well.
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*
|
||||
* @psalm-return array{0: string, 1: string}
|
||||
*/
|
||||
public function __sleep()
|
||||
public function __sleep() : array
|
||||
{
|
||||
return ['collection', 'initialized'];
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
return; // ignore inverse side
|
||||
}
|
||||
|
||||
list($deleteSql, $deleteTypes) = $this->getDeleteRowSQL($collection);
|
||||
list($insertSql, $insertTypes) = $this->getInsertRowSQL($collection);
|
||||
[$deleteSql, $deleteTypes] = $this->getDeleteRowSQL($collection);
|
||||
[$insertSql, $insertTypes] = $this->getInsertRowSQL($collection);
|
||||
|
||||
foreach ($collection->getDeleteDiff() as $element) {
|
||||
$this->conn->executeUpdate(
|
||||
@@ -136,7 +136,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$types[] = PersisterHelper::getTypeOfColumn($referencedName, $sourceClass, $this->em);
|
||||
}
|
||||
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($mapping);
|
||||
[$joinTargetEntitySQL, $filterSql] = $this->getFilterSql($mapping);
|
||||
|
||||
if ($filterSql) {
|
||||
$conditions[] = $filterSql;
|
||||
@@ -188,7 +188,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
|
||||
}
|
||||
|
||||
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictionsWithKey($collection, $key, true);
|
||||
[$quotedJoinTable, $whereClauses, $params, $types] = $this->getJoinTableRestrictionsWithKey(
|
||||
$collection,
|
||||
$key,
|
||||
true
|
||||
);
|
||||
|
||||
$sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
|
||||
|
||||
@@ -204,7 +208,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
return false;
|
||||
}
|
||||
|
||||
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictions($collection, $element, true);
|
||||
[$quotedJoinTable, $whereClauses, $params, $types] = $this->getJoinTableRestrictions(
|
||||
$collection,
|
||||
$element,
|
||||
true
|
||||
);
|
||||
|
||||
$sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
|
||||
|
||||
@@ -288,6 +296,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @return string[] ordered tuple:
|
||||
* - JOIN condition to add to the SQL
|
||||
* - WHERE condition to add to the SQL
|
||||
*
|
||||
* @psalm-return array{0: string, 1: string}
|
||||
*/
|
||||
public function getFilterSql($mapping)
|
||||
{
|
||||
@@ -335,7 +345,9 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*
|
||||
* @param array $mapping
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
protected function getOnConditionSQL($mapping)
|
||||
{
|
||||
@@ -361,9 +373,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @override
|
||||
* @return string
|
||||
*/
|
||||
protected function getDeleteSQL(PersistentCollection $collection)
|
||||
{
|
||||
@@ -381,10 +391,9 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Internal note: Order of the parameters must be the same as the order of the columns in getDeleteSql.
|
||||
* @override
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getDeleteSQLParameters(PersistentCollection $collection)
|
||||
{
|
||||
@@ -416,6 +425,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*
|
||||
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
|
||||
* of types for bound parameters
|
||||
*
|
||||
* @psalm-return array{0: string, 1: list<string>}
|
||||
*/
|
||||
protected function getDeleteRowSQL(PersistentCollection $collection)
|
||||
{
|
||||
@@ -452,6 +463,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @psalm-return list<mixed>
|
||||
*/
|
||||
protected function getDeleteRowSQLParameters(PersistentCollection $collection, $element)
|
||||
{
|
||||
@@ -465,6 +478,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*
|
||||
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
|
||||
* of types for bound parameters
|
||||
*
|
||||
* @psalm-return array{0: string, 1: list<string>}
|
||||
*/
|
||||
protected function getInsertRowSQL(PersistentCollection $collection)
|
||||
{
|
||||
@@ -503,6 +518,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @psalm-return list<mixed>
|
||||
*/
|
||||
protected function getInsertRowSQLParameters(PersistentCollection $collection, $element)
|
||||
{
|
||||
@@ -516,7 +533,9 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection
|
||||
* @param object $element
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*
|
||||
* @psalm-return list<mixed>
|
||||
*/
|
||||
private function collectJoinTableColumnParameters(PersistentCollection $collection, $element)
|
||||
{
|
||||
@@ -564,6 +583,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* - where clauses to be added for filtering
|
||||
* - parameters to be bound for filtering
|
||||
* - types of the parameters to be bound for filtering
|
||||
*
|
||||
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
*/
|
||||
private function getJoinTableRestrictionsWithKey(PersistentCollection $collection, $key, $addFilters)
|
||||
{
|
||||
@@ -628,7 +649,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
|
||||
if ($addFilters) {
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
|
||||
[$joinTargetEntitySQL, $filterSql] = $this->getFilterSql($filterMapping);
|
||||
|
||||
if ($filterSql) {
|
||||
$quotedJoinTable .= ' ' . $joinTargetEntitySQL;
|
||||
@@ -649,6 +670,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* - where clauses to be added for filtering
|
||||
* - parameters to be bound for filtering
|
||||
* - types of the parameters to be bound for filtering
|
||||
*
|
||||
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
*/
|
||||
private function getJoinTableRestrictions(PersistentCollection $collection, $element, $addFilters)
|
||||
{
|
||||
@@ -694,7 +717,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
if ($addFilters) {
|
||||
$quotedJoinTable .= ' t';
|
||||
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
|
||||
[$joinTargetEntitySQL, $filterSql] = $this->getFilterSql($filterMapping);
|
||||
|
||||
if ($filterSql) {
|
||||
$quotedJoinTable .= ' ' . $joinTargetEntitySQL;
|
||||
@@ -725,7 +748,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
|
||||
$valueVisitor->dispatch($expression);
|
||||
|
||||
list(, $types) = $valueVisitor->getParamsAndTypes();
|
||||
[, $types] = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function delete(PersistentCollection $collection)
|
||||
{
|
||||
|
||||
@@ -92,7 +92,6 @@ class BasicEntityPersister implements EntityPersister
|
||||
*/
|
||||
static private $comparisonMap = [
|
||||
Comparison::EQ => '= %s',
|
||||
Comparison::IS => '= %s',
|
||||
Comparison::NEQ => '!= %s',
|
||||
Comparison::GT => '> %s',
|
||||
Comparison::GTE => '>= %s',
|
||||
@@ -361,6 +360,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
return Type::getType($fieldMapping['type'])->convertToPHPValue($value, $this->platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]|null[]|string[]
|
||||
*
|
||||
* @psalm-return list<int|null|string>
|
||||
*/
|
||||
private function extractIdentifierTypes(array $id, ClassMetadata $versionedClass) : array
|
||||
{
|
||||
$types = [];
|
||||
@@ -448,9 +452,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
|
||||
foreach ($this->class->identifier as $idField) {
|
||||
if ( ! isset($this->class->associationMappings[$idField])) {
|
||||
$params[] = $identifier[$idField];
|
||||
$types[] = $this->class->fieldMappings[$idField]['type'];
|
||||
$where[] = $this->quoteStrategy->getColumnName($idField, $this->class, $this->platform);
|
||||
$params[] = $identifier[$idField];
|
||||
$types[] = $this->class->fieldMappings[$idField]['type'];
|
||||
$where[] = $this->quoteStrategy->getColumnName($idField, $this->class, $this->platform);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -602,7 +606,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
*
|
||||
* @param object $entity The entity for which to prepare the data.
|
||||
*
|
||||
* @return array The prepared data.
|
||||
* @return mixed[][] The prepared data.
|
||||
*
|
||||
* @psalm-return array<string, array<array-key, mixed|null>>
|
||||
*/
|
||||
protected function prepareUpdateData($entity)
|
||||
{
|
||||
@@ -689,9 +695,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
*
|
||||
* @param object $entity The entity for which to prepare the data.
|
||||
*
|
||||
* @return array The prepared data for the tables to update.
|
||||
* @return mixed[][] The prepared data for the tables to update.
|
||||
*
|
||||
* @see prepareUpdateData
|
||||
*
|
||||
* @psalm-return array<string, mixed[]>
|
||||
*/
|
||||
protected function prepareInsertData($entity)
|
||||
{
|
||||
@@ -714,7 +722,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
$this->switchPersisterContext(null, $limit);
|
||||
|
||||
$sql = $this->getSelectSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
[$params, $types] = $this->expandParameters($criteria);
|
||||
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
||||
|
||||
if ($entity !== null) {
|
||||
@@ -806,7 +814,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
public function refresh(array $id, $entity, $lockMode = null)
|
||||
{
|
||||
$sql = $this->getSelectSQL($id, null, $lockMode);
|
||||
list($params, $types) = $this->expandParameters($id);
|
||||
[$params, $types] = $this->expandParameters($id);
|
||||
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
||||
|
||||
$hydrator = $this->em->newHydrator(Query::HYDRATE_OBJECT);
|
||||
@@ -820,7 +828,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
{
|
||||
$sql = $this->getCountSQL($criteria);
|
||||
|
||||
list($params, $types) = ($criteria instanceof Criteria)
|
||||
[$params, $types] = $criteria instanceof Criteria
|
||||
? $this->expandCriteriaParameters($criteria)
|
||||
: $this->expandParameters($criteria);
|
||||
|
||||
@@ -837,7 +845,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
$offset = $criteria->getFirstResult();
|
||||
$query = $this->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
|
||||
|
||||
list($params, $types) = $this->expandCriteriaParameters($criteria);
|
||||
[$params, $types] = $this->expandCriteriaParameters($criteria);
|
||||
|
||||
$stmt = $this->conn->executeQuery($query, $params, $types);
|
||||
$hydrator = $this->em->newHydrator(($this->currentPersisterContext->selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
|
||||
@@ -863,14 +871,14 @@ class BasicEntityPersister implements EntityPersister
|
||||
|
||||
$valueVisitor->dispatch($expression);
|
||||
|
||||
list($params, $types) = $valueVisitor->getParamsAndTypes();
|
||||
[$params, $types] = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
foreach ($params as $param) {
|
||||
$sqlParams = array_merge($sqlParams, $this->getValues($param));
|
||||
}
|
||||
|
||||
foreach ($types as $type) {
|
||||
list ($field, $value) = $type;
|
||||
[$field, $value] = $type;
|
||||
$sqlTypes = array_merge($sqlTypes, $this->getTypes($field, $value, $this->class));
|
||||
}
|
||||
|
||||
@@ -885,7 +893,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
$this->switchPersisterContext($offset, $limit);
|
||||
|
||||
$sql = $this->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
[$params, $types] = $this->expandParameters($criteria);
|
||||
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
||||
|
||||
$hydrator = $this->em->newHydrator(($this->currentPersisterContext->selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
|
||||
@@ -955,11 +963,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
|
||||
{
|
||||
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity);
|
||||
|
||||
return $this->loadCollectionFromStatement($assoc, $stmt, $coll);
|
||||
return $this->loadCollectionFromStatement($assoc, $stmt, $collection);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1030,7 +1038,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
|
||||
list($params, $types) = $this->expandToManyParameters($parameters);
|
||||
[$params, $types] = $this->expandToManyParameters($parameters);
|
||||
|
||||
return $this->conn->executeQuery($sql, $params, $types);
|
||||
}
|
||||
@@ -1134,7 +1142,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
protected final function getOrderBySQL(array $orderBy, $baseTableAlias)
|
||||
final protected function getOrderBySQL(array $orderBy, $baseTableAlias) : string
|
||||
{
|
||||
$orderByList = [];
|
||||
|
||||
@@ -1419,7 +1427,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
* Subclasses should override this method to alter or change the list of
|
||||
* columns placed in the INSERT statements used by the persister.
|
||||
*
|
||||
* @return array The list of columns.
|
||||
* @return string[] The list of columns.
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
protected function getInsertColumnList()
|
||||
{
|
||||
@@ -1536,7 +1546,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
. $where
|
||||
. $lockSql;
|
||||
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
[$params, $types] = $this->expandParameters($criteria);
|
||||
|
||||
$this->conn->executeQuery($sql, $params, $types);
|
||||
}
|
||||
@@ -1544,7 +1554,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Gets the FROM and optionally JOIN conditions to lock the entity managed by this persister.
|
||||
*
|
||||
* @param integer $lockMode One of the Doctrine\DBAL\LockMode::* constants.
|
||||
* @param int|null $lockMode One of the Doctrine\DBAL\LockMode::* constants.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1656,13 +1666,13 @@ class BasicEntityPersister implements EntityPersister
|
||||
* @return string[]
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
private function getSelectConditionStatementColumnSQL($field, $assoc = null)
|
||||
{
|
||||
if (isset($this->class->fieldMappings[$field])) {
|
||||
$className = (isset($this->class->fieldMappings[$field]['inherited']))
|
||||
? $this->class->fieldMappings[$field]['inherited']
|
||||
: $this->class->name;
|
||||
$className = $this->class->fieldMappings[$field]['inherited'] ?? $this->class->name;
|
||||
|
||||
return [$this->getSQLTableAlias($className) . '.' . $this->quoteStrategy->getColumnName($field, $this->class, $this->platform)];
|
||||
}
|
||||
@@ -1753,11 +1763,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $collection)
|
||||
{
|
||||
$stmt = $this->getOneToManyStatement($assoc, $sourceEntity);
|
||||
|
||||
return $this->loadCollectionFromStatement($assoc, $stmt, $coll);
|
||||
return $this->loadCollectionFromStatement($assoc, $stmt, $collection);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1813,7 +1823,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
|
||||
list($params, $types) = $this->expandToManyParameters($parameters);
|
||||
[$params, $types] = $this->expandToManyParameters($parameters);
|
||||
|
||||
return $this->conn->executeQuery($sql, $params, $types);
|
||||
}
|
||||
@@ -1847,8 +1857,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
* - value to be bound
|
||||
* - class to which the field belongs to
|
||||
*
|
||||
* @return mixed[][]
|
||||
*
|
||||
* @return array
|
||||
* @psalm-return array{0: array, 1: list<mixed>}
|
||||
*/
|
||||
private function expandToManyParameters($criteria)
|
||||
{
|
||||
@@ -1874,9 +1885,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
* @param mixed $value
|
||||
* @param ClassMetadata $class
|
||||
*
|
||||
* @return array
|
||||
* @return int[]|null[]|string[]
|
||||
*
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*
|
||||
* @psalm-return list<int|null|string>
|
||||
*/
|
||||
private function getTypes($field, $value, ClassMetadata $class)
|
||||
{
|
||||
@@ -1989,11 +2002,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
. $this->getLockTablesSql(null)
|
||||
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
|
||||
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
[$params, $types] = $this->expandParameters($criteria);
|
||||
|
||||
if (null !== $extraConditions) {
|
||||
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
|
||||
list($criteriaParams, $criteriaTypes) = $this->expandCriteriaParameters($extraConditions);
|
||||
[$criteriaParams, $criteriaTypes] = $this->expandCriteriaParameters($extraConditions);
|
||||
|
||||
$params = array_merge($params, $criteriaParams);
|
||||
$types = array_merge($types, $criteriaTypes);
|
||||
@@ -2026,7 +2039,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param string $columnName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSQLColumnAlias($columnName)
|
||||
{
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Persisters\Entity;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
* A swappable persister context to use as a container for the current
|
||||
|
||||
@@ -86,7 +86,7 @@ interface EntityPersister
|
||||
/**
|
||||
* Expands the parameters from the given criteria and use the correct binding types if found.
|
||||
*
|
||||
* @param $criteria
|
||||
* @param string[] $criteria
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,8 @@ use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Utility\PersisterHelper;
|
||||
|
||||
use function array_combine;
|
||||
|
||||
/**
|
||||
* The joined subclass persister maps a single entity instance to several tables in the
|
||||
* database as it is defined by the <tt>Class Table Inheritance</tt> strategy.
|
||||
|
||||
@@ -93,7 +93,9 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
/**
|
||||
* Returns the Parameters and Types necessary for matching the last visited expression.
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[][]
|
||||
*
|
||||
* @psalm-return array{0: array, 1: array}
|
||||
*/
|
||||
public function getParamsAndTypes()
|
||||
{
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Proxy;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Common\Proxy\AbstractProxyFactory;
|
||||
use Doctrine\Common\Proxy\Proxy as BaseProxy;
|
||||
use Doctrine\Common\Proxy\ProxyDefinition;
|
||||
@@ -29,6 +28,8 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Persisters\Entity\EntityPersister;
|
||||
use Doctrine\ORM\EntityNotFoundException;
|
||||
use Doctrine\ORM\Utility\IdentifierFlattener;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use function interface_exists;
|
||||
|
||||
/**
|
||||
* This factory is used to create proxy objects for entities at runtime.
|
||||
@@ -118,12 +119,11 @@ class ProxyFactory extends AbstractProxyFactory
|
||||
/**
|
||||
* Creates a closure capable of initializing a proxy
|
||||
*
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $classMetadata
|
||||
* @param \Doctrine\ORM\Persisters\Entity\EntityPersister $entityPersister
|
||||
*
|
||||
* @return \Closure
|
||||
*
|
||||
* @throws \Doctrine\ORM\EntityNotFoundException
|
||||
*
|
||||
* @psalm-return \Closure(BaseProxy):void
|
||||
*/
|
||||
private function createInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister)
|
||||
{
|
||||
@@ -172,12 +172,11 @@ class ProxyFactory extends AbstractProxyFactory
|
||||
/**
|
||||
* Creates a closure capable of finalizing state a cloned proxy
|
||||
*
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $classMetadata
|
||||
* @param \Doctrine\ORM\Persisters\Entity\EntityPersister $entityPersister
|
||||
*
|
||||
* @return \Closure
|
||||
*
|
||||
* @throws \Doctrine\ORM\EntityNotFoundException
|
||||
*
|
||||
* @psalm-return \Closure(BaseProxy):void
|
||||
*/
|
||||
private function createCloner(ClassMetadata $classMetadata, EntityPersister $entityPersister)
|
||||
{
|
||||
@@ -211,3 +210,5 @@ class ProxyFactory extends AbstractProxyFactory
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface_exists(ClassMetadata::class);
|
||||
|
||||
@@ -22,6 +22,9 @@ namespace Doctrine\ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Query\AST\DeleteStatement;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\ORM\Query\AST\UpdateStatement;
|
||||
use Doctrine\ORM\Query\Exec\AbstractSqlExecutor;
|
||||
use Doctrine\ORM\Query\Parameter;
|
||||
use Doctrine\ORM\Query\ParameterTypeInferer;
|
||||
@@ -213,9 +216,7 @@ final class Query extends AbstractQuery
|
||||
/**
|
||||
* Returns the corresponding AST for this DQL query.
|
||||
*
|
||||
* @return \Doctrine\ORM\Query\AST\SelectStatement |
|
||||
* \Doctrine\ORM\Query\AST\UpdateStatement |
|
||||
* \Doctrine\ORM\Query\AST\DeleteStatement
|
||||
* @return SelectStatement|UpdateStatement|DeleteStatement
|
||||
*/
|
||||
public function getAST()
|
||||
{
|
||||
@@ -325,7 +326,7 @@ final class Query extends AbstractQuery
|
||||
$this->evictEntityCacheRegion();
|
||||
}
|
||||
|
||||
list($sqlParams, $types) = $this->processParameterMappings($paramMappings);
|
||||
[$sqlParams, $types] = $this->processParameterMappings($paramMappings);
|
||||
|
||||
$this->evictResultSetCache(
|
||||
$executor,
|
||||
@@ -364,11 +365,11 @@ final class Query extends AbstractQuery
|
||||
{
|
||||
$AST = $this->getAST();
|
||||
|
||||
if ($AST instanceof \Doctrine\ORM\Query\AST\SelectStatement) {
|
||||
if ($AST instanceof SelectStatement) {
|
||||
throw new QueryException('The hint "HINT_CACHE_EVICT" is not valid for select statements.');
|
||||
}
|
||||
|
||||
$className = ($AST instanceof \Doctrine\ORM\Query\AST\DeleteStatement)
|
||||
$className = $AST instanceof DeleteStatement
|
||||
? $AST->deleteClause->abstractSchemaName
|
||||
: $AST->updateClause->abstractSchemaName;
|
||||
|
||||
@@ -380,11 +381,13 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param array $paramMappings
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[][]
|
||||
*
|
||||
* @throws Query\QueryException
|
||||
*
|
||||
* @psalm-return array{0: list<mixed>, 1: array}
|
||||
*/
|
||||
private function processParameterMappings($paramMappings)
|
||||
private function processParameterMappings($paramMappings) : array
|
||||
{
|
||||
$sqlParams = [];
|
||||
$types = [];
|
||||
@@ -429,7 +432,11 @@ final class Query extends AbstractQuery
|
||||
return [$sqlParams, $types];
|
||||
}
|
||||
|
||||
/** @return mixed[] tuple of (value, type) */
|
||||
/**
|
||||
* @return mixed[] tuple of (value, type)
|
||||
*
|
||||
* @psalm-return array{0: mixed, 1: mixed}
|
||||
*/
|
||||
private function resolveParameterValue(Parameter $parameter) : array
|
||||
{
|
||||
if ($parameter->typeWasSpecified()) {
|
||||
@@ -466,9 +473,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param \Doctrine\Common\Cache\Cache|null $queryCache Cache driver.
|
||||
*
|
||||
* @return Query This query instance.
|
||||
* @return self This query instance.
|
||||
*/
|
||||
public function setQueryCacheDriver($queryCache)
|
||||
public function setQueryCacheDriver($queryCache) : self
|
||||
{
|
||||
$this->_queryCache = $queryCache;
|
||||
|
||||
@@ -480,9 +487,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param boolean $bool
|
||||
*
|
||||
* @return Query This query instance.
|
||||
* @return self This query instance.
|
||||
*/
|
||||
public function useQueryCache($bool)
|
||||
public function useQueryCache($bool) : self
|
||||
{
|
||||
$this->_useQueryCache = $bool;
|
||||
|
||||
@@ -509,9 +516,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param integer $timeToLive How long the cache entry is valid.
|
||||
*
|
||||
* @return Query This query instance.
|
||||
* @return self This query instance.
|
||||
*/
|
||||
public function setQueryCacheLifetime($timeToLive)
|
||||
public function setQueryCacheLifetime($timeToLive) : self
|
||||
{
|
||||
if ($timeToLive !== null) {
|
||||
$timeToLive = (int) $timeToLive;
|
||||
@@ -537,9 +544,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param boolean $expire Whether or not to force query cache expiration.
|
||||
*
|
||||
* @return Query This query instance.
|
||||
* @return self This query instance.
|
||||
*/
|
||||
public function expireQueryCache($expire = true)
|
||||
public function expireQueryCache($expire = true) : self
|
||||
{
|
||||
$this->_expireQueryCache = $expire;
|
||||
|
||||
@@ -571,10 +578,8 @@ final class Query extends AbstractQuery
|
||||
* Sets a DQL query string.
|
||||
*
|
||||
* @param string $dqlQuery DQL Query.
|
||||
*
|
||||
* @return \Doctrine\ORM\AbstractQuery
|
||||
*/
|
||||
public function setDQL($dqlQuery)
|
||||
public function setDQL($dqlQuery) : self
|
||||
{
|
||||
if ($dqlQuery !== null) {
|
||||
$this->_dql = $dqlQuery;
|
||||
@@ -626,9 +631,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param int|null $firstResult The first result to return.
|
||||
*
|
||||
* @return Query This query object.
|
||||
* @return self This query object.
|
||||
*/
|
||||
public function setFirstResult($firstResult)
|
||||
public function setFirstResult($firstResult) : self
|
||||
{
|
||||
$this->_firstResult = $firstResult;
|
||||
$this->_state = self::STATE_DIRTY;
|
||||
@@ -652,9 +657,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param integer|null $maxResults
|
||||
*
|
||||
* @return Query This query object.
|
||||
* @return self This query object.
|
||||
*/
|
||||
public function setMaxResults($maxResults)
|
||||
public function setMaxResults($maxResults) : self
|
||||
{
|
||||
$this->_maxResults = $maxResults;
|
||||
$this->_state = self::STATE_DIRTY;
|
||||
@@ -716,11 +721,9 @@ final class Query extends AbstractQuery
|
||||
*
|
||||
* @param int $lockMode
|
||||
*
|
||||
* @return Query
|
||||
*
|
||||
* @throws TransactionRequiredException
|
||||
*/
|
||||
public function setLockMode($lockMode)
|
||||
public function setLockMode($lockMode) : self
|
||||
{
|
||||
if (in_array($lockMode, [LockMode::NONE, LockMode::PESSIMISTIC_READ, LockMode::PESSIMISTIC_WRITE], true)) {
|
||||
if ( ! $this->_em->getConnection()->isTransactionActive()) {
|
||||
|
||||
@@ -105,7 +105,7 @@ class TrimFunction extends FunctionNode
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
private function getTrimMode()
|
||||
{
|
||||
|
||||
@@ -48,4 +48,4 @@ class ParenthesisExpression extends Node
|
||||
{
|
||||
return $walker->walkParenthesisExpression($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Doctrine\ORM\Query\AST;
|
||||
class SimpleSelectExpression extends Node
|
||||
{
|
||||
/**
|
||||
* @var Node
|
||||
* @var Node|string
|
||||
*/
|
||||
public $expression;
|
||||
|
||||
@@ -42,7 +42,7 @@ class SimpleSelectExpression extends Node
|
||||
public $fieldIdentificationVariable;
|
||||
|
||||
/**
|
||||
* @param Node $expression
|
||||
* @param Node|string $expression
|
||||
*/
|
||||
public function __construct($expression)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Doctrine\ORM\Query\AST;
|
||||
class WhereClause extends Node
|
||||
{
|
||||
/**
|
||||
* @var ConditionalExpression
|
||||
* @var ConditionalExpression|ConditionalTerm
|
||||
*/
|
||||
public $conditionalExpression;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
abstract class AbstractSqlExecutor
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
* @var mixed[]|string
|
||||
*/
|
||||
protected $_sqlStatements;
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class AbstractSqlExecutor
|
||||
/**
|
||||
* Gets the SQL statements that are executed by the executor.
|
||||
*
|
||||
* @return array All the SQL update statements.
|
||||
* @return mixed[]|string All the SQL update statements.
|
||||
*/
|
||||
public function getSqlStatements()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Doctrine\ORM\Query\Exec;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\AST\DeleteStatement;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Utility\PersisterHelper;
|
||||
use Throwable;
|
||||
|
||||
@@ -57,8 +59,8 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
|
||||
* Internal note: Any SQL construction and preparation takes place in the constructor for
|
||||
* best performance. With a query cache the executor will be cached.
|
||||
*
|
||||
* @param \Doctrine\ORM\Query\AST\Node $AST The root AST node of the DQL query.
|
||||
* @param \Doctrine\ORM\Query\SqlWalker $sqlWalker The walker used for SQL generation from the AST.
|
||||
* @param DeleteStatement $AST The root AST node of the DQL query.
|
||||
* @param SqlWalker $sqlWalker The walker used for SQL generation from the AST.
|
||||
*/
|
||||
public function __construct(AST\Node $AST, $sqlWalker)
|
||||
{
|
||||
@@ -116,6 +118,8 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function execute(Connection $conn, array $params, array $types)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user