PHP Classes

File: docs/architecture/PDO_PAGINATION_TEST_BLUEPRINT.md

Recommend this page to a friend!
  Packages of Mohamed Abdulalim   Persistence   docs/architecture/PDO_PAGINATION_TEST_BLUEPRINT.md   Download  
File: docs/architecture/PDO_PAGINATION_TEST_BLUEPRINT.md
Role: Example script
Content type: text/markdown
Description: Example script
Class: Persistence
Retrieve database table records by a given order
Author: By
Last change:
Date: 20 days ago
Size: 36,847 bytes
 

Contents

Class file image Download

Test Blueprint ? PDO Pagination v1.1.0

??????: Owner-approved Test Blueprint; test implementation is completed and merged. ???? ???????:

docs/architecture/PDO_PAGINATION_CONTRACT.md
docs/architecture/PDO_PAGINATION_RUNTIME_BLUEPRINT.md

Runtime baseline: ?? ??? PDO Pagination Runtime ??? main. ??????: Unit? Regression? Real MySQL Integration? ???? ?????????? ???? CI residue verification ???.

1. ?????

????? ?? PDO Pagination Runtime:

  • ????? ??? Public API ??????? ??????.
  • ???? normalization ????orting ???count ???mapping ???metadata ??? ?? ????.
  • ???? package-owned PDO failures ????? ?????.
  • ???? `PDOException` ???? mapper `Throwable` ??? ?????.
  • ?? ????? transaction.
  • ?? ????? PDO attributes.
  • ???? ?? native MySQL prepared statements.
  • ?? ????? Ordering Runtime ?? Public API.
  • ?? ???? SQL parser ?? Query Builder ?? ?? abstraction ??? ?????.

???? ?????????? ??????? ?????? ?? Ordering ?? ????? ????? ?? Pagination.

2. ??????? ??????? ????????

2.1 Unit Support Doubles

tests/Support/Pdo/Pagination/ScriptedPdo.php
tests/Support/Pdo/Pagination/ScriptedPdoStatement.php

2.2 Unit Tests

tests/Unit/Pdo/Pagination/PageRequestTest.php
tests/Unit/Pdo/Pagination/SortWhitelistTest.php
tests/Unit/Pdo/Pagination/PaginationConfigTest.php
tests/Unit/Pdo/Pagination/PdoPaginationQueryDescriptorTest.php
tests/Unit/Pdo/Pagination/PageResultTest.php
tests/Unit/Pdo/Pagination/PdoPaginatorNormalizationTest.php
tests/Unit/Pdo/Pagination/PdoPaginatorExecutionTest.php
tests/Unit/Pdo/Pagination/PdoPaginatorFailureTest.php

2.3 Regression Tests

tests/Regression/Pdo/Pagination/PaginationPublicApiRegressionTest.php
tests/Regression/Pdo/Pagination/PaginationSqlContractRegressionTest.php
tests/Regression/Exception/PaginationExceptionContractTest.php
tests/Regression/Pdo/Ordering/OrderingPublicApiRegressionTest.php

2.4 MySQL Fixtures and Support

tests/Fixtures/MySql/create_pagination_items_table.sql
tests/Support/MySql/PaginationSchemaManager.php
tests/Support/MySql/PaginationFixture.php
tests/Support/MySql/PaginationIntegrationTestCase.php

2.5 Real MySQL Integration Tests

tests/Integration/Pdo/Pagination/PdoPaginatorQuerySemanticsTest.php
tests/Integration/Pdo/Pagination/PdoPaginatorFailureContractTest.php
tests/Integration/Pdo/Pagination/PdoPaginatorTransactionTest.php

3. ????? ??????? ???????

.github/workflows/ci.yml

??????? ?????? ???????:

  • ????? ???? Pagination ???????? ??? ??? MySQL residue.
  • ????? ??? placeholders ???? execution parameters ???????? ?????? ??????? ????? ????.

??? ?????? ??????:

maa_persistence_test_pagination_items

????? ?? ????? ??? ?? CI architecture ?? versions ?? jobs ?? matrices.

?? ????? phpunit.xml ??? ?????? ???????? ??????? ????? ??????? ??????? ????????.

4. ??????? ??????? ???????

src/
composer.json
phpunit.xml
phpstan.neon
.php-cs-fixer.php
README.md
CHANGELOG.md
PERSISTENCE_PACKAGE_REFERENCE.md
docs/
tests/Unit/Pdo/Ordering/
tests/Integration/Pdo/Ordering/

????????? ?????? ???? docs/ ?? ??? ??? Blueprint ???? ??? ??? ????? ??????????.

????? ?????:

composer.lock

5. ??????? ?????? ??????????

?? ??? PHP:

<?php

declare(strict_types=1);

???????:

  • ?? test class ???? `final`.
  • ??????? PHPUnit 11 APIs ???????.
  • ??????? `DataProvider` ??????? ????????.
  • ?? suppressions ?? PHPStan.
  • ?? `@phpstan-ignore`.
  • ?? baseline ?? `ignoreErrors`.
  • ?? sleeps.
  • ?? randomness.
  • ?? ?????? ??? ????? ???????? PHPUnit.
  • ?? SQLite ??? MySQL.
  • ?? ????? Runtime ?????? ????????.
  • ?? ?????? private methods ??????.
  • ????????? ?????? ???????? Reflection:

    * ????? Public API. * ????? ??? Runtime ??? ????? ????? PHPDoc ????? ?????? ?????? native PHP type? ??? scalar item ???? `PageResult` ?? invalid parameter maps.

  • ?? ????? exception messages ????????? Public API.
  • ????? exception classes ???? bases ???? markers ???? error codes ???.
  • ??? ?????? propagation? ??? ??????? `assertSame()` ?????? ???? ??? Throwable instance.
  • ?????????? ??? ?? ???? ??? PHP 8.2 ??? PHP 8.5.
  • ?? resources ????? ?? ???? ???? `finally`.

6. Unit Support Doubles

6.1 ScriptedPdo

???? ??:

PDO

??? ???? ?????? ??????.

????????:

  • ??????? queue ????? ??:

    * `ScriptedPdoStatement` * ?? ????? `false` ??????? non-throwing prepare failure. * ?? Throwable ??? ???? ?? `prepare()`.

  • ????? ?? SQL ?? ?????? ??? `prepare()` ????????.
  • ????? ??? ???? `prepare()`.
  • ????? ?? ??????? ??:

    * `beginTransaction()` * `commit()` * `rollBack()` * `setAttribute()`

  • ??? ??? ?????? constructor ?????? ???? ????? DSN.
  • ?? ????? ???? Pagination ????.

??? ?? ???? ?????????? ??????:

  • ????? prepare:

    1. total 2. filtered count 3. data

  • ??? ????? data query ??? `filtered === 0`.
  • ????? data query ??? ????? ??? ??? page overflow.
  • ??? ??????? ?? transaction operation.
  • ??? ????? PDO attributes.

6.2 ScriptedPdoStatement

???? ??:

PDOStatement

????? configuration ?????????? ???:

  • `columnCount()`.
  • queue ?????? `fetch(PDO::FETCH_ASSOC)`.
  • queue ?? ???? ????? ?? `errorCode()`.
  • ????? `execute()`:

    * `true` * `false` * Throwable.

  • ????? `bindValue()` ??? ??? parameter:

    * `true` * `false` * Throwable.

  • ????? bind calls ????????:
parameter name
value
PDO parameter type

  • ????? ??? ???? execute ?fetch.
  • ????? ??? ??? array ????? ??????? unexpected fetch state.
  • ????? rows ??? numeric keys ????? ??????? associative-row validation.

????? ??????? PHPUnit mocks ??? ??? doubles ??????? ?????? ?????? ?? PDO? ????? ?? ???? ????????? ????? ?????? ??? PHP 8.2?8.5.

7. PageRequestTest

???? ?? PageRequest value object ??? ??? ???? ??? normalization.

???????:

  • defaults ???? `null`.
  • ???????? ????? page integer ??? ??.
  • ???????? ????? page malformed string ??? ??.
  • ???????? ????? per-page malformed string ??? ??.
  • ???????? ?? whitespace ?? sort values ??? ??.
  • ?? ???? ???? end-user input ??? ??????.
  • ?? ???? methods ???? ?????? ??? constructor.

?? ????? HTTP ?? query parameters ?? PSR-7.

8. SortWhitelistTest

8.1 ??????? ???????

??????:

column
alias.column
schema.table.column

???? quoting ???????:

created_at                  => `created_at`
p.created_at                => `p`.`created_at`
catalog.products.created_at => `catalog`.`products`.`created_at`

?????? public keys:

created_at
_created_at
created_at2

??????:

  • `contains()` exact ?case-sensitive.
  • unknown casing ?? ?????.
  • ??????? ????? ??????? ???? ?? ????? ??? identifier ????.
  • ????? input array ??? ????? ?????? ?? ????? ????? ????????.
  • ?? ???? public getter ??????? ????????.

8.2 ??????? ????????

  • empty whitelist.
  • integer key.
  • empty public key.
  • public key ???? ????.
  • whitespace.
  • hyphen.
  • dot ???? public key.
  • backticks.
  • comments.
  • semicolon.
  • value ??? string.
  • zero segments ??????? ??? empty string.
  • leading dot.
  • trailing dot.
  • empty middle segment.
  • ???? ?? ????? segments.
  • function.
  • parentheses.
  • arithmetic.
  • JSON operator.
  • `CASE`.
  • `COLLATE`.
  • comma.
  • embedded direction.
  • comment.
  • semicolon.
  • `LIMIT`.
  • `OFFSET`.

?? ??????? ????:

InvalidPaginationConfigurationException

quotedIdentifierFor() ?? unknown key ???? ????????? ????.

9. PaginationConfigTest

9.1 valid configuration

????? constructor defaults:

defaultPerPage = 20
minPerPage     = 1
maxPerPage     = 200

??????:

  • custom valid bounds.
  • default key ????? ?? whitelist.
  • tie-breaker key ?????.
  • default ?tie-breaker ??? ???????.
  • ??????? ??????? ?????? ??? ??? identifier.
  • ????? primary ????? ?? ????? tie-breaker.

9.2 invalid configuration

  • `minPerPage = 0`.
  • `minPerPage < 0`.
  • `maxPerPage < minPerPage`.
  • default ??? ?? min.
  • default ???? ?? max.
  • malformed default key.
  • malformed tie-breaker key.
  • default key ??? ????? ?? whitelist.
  • tie-breaker key ??? ?????.
  • empty key.

???? ????:

InvalidPaginationConfigurationException

?? ???? test ????? ????? uniqueness ???? tie-breaker ???? ????? ????????? ??? ??????? caller.

10. PdoPaginationQueryDescriptorTest

10.1 valid descriptor

?????:

  • ?? SQL property ???? ???? ?????? ??? trim ?? rewriting.
  • ?? parameter map ???? ??????? ????????.
  • empty parameter maps ??????.
  • ????? ????????:
int
string
bool
null

  • decimal string ?????.
  • named placeholder ???? leading colon ?? map.
  • constructor ?? ???? SQL.

10.2 SQL rejection

?????? ?? SQL slot ???????:

totalSql
filteredCountSql
dataSql

???????:

  • empty string.
  • whitespace-only.
  • semicolon ?? ???????.
  • semicolon ?? ???????.
  • semicolon ?? ???????.
  • reserved placeholder:
:__pagination_limit
:__pagination_offset
:__pagination_custom

???? ????:

InvalidPaginationQueryException

10.3 parameter rejection

?????? ?? ??????? ??????:

  • integer key.
  • empty key.
  • leading colon.
  • starts with digit.
  • whitespace.
  • hyphen.
  • reserved prefix:
__pagination_limit
__pagination_offset
__pagination_anything

????? ????????:

float
array
object
resource

?? ????? resource ???? finally.

10.4 no-parser contract

??? ????? ?? constructor ?? ????? preflight ???? ????? ???? construction ?? descriptors ?????:

  • missing placeholder correspondence.
  • unused parameter.
  • repeated named placeholder.
  • positional `?`.
  • mixed positional and named placeholders.
  • caller-owned `ORDER BY`.
  • caller-owned `LIMIT`.
  • malformed SQL ?? ????? semicolon ??? reserved prefix.

??? ??????? ?? ????? valid Runtime usage? ???????? ???? ??? ???? ???? constructor-level SQL parsing classifications.

11. PageResultTest

11.1 direct valid construction

?????? construction ????? ????????:

  • list ?? arrays.
  • list ?? objects.
  • empty data ?`filtered > 0`.
  • `filtered > total`.
  • first page.
  • middle page.
  • final page.
  • zero-result state.

11.2 canonical metadata

?????:

$totalPages = $filtered === 0
    ? 0
    : intdiv($filtered - 1, $perPage) + 1;

?:

hasNext     = page < totalPages
hasPrevious = page > 1 && totalPages > 0

11.3 invariant rejection

?? ???? ????:

PaginationExecutionException

???????:

  • associative outer data ??? list.
  • scalar item.
  • resource item.
  • `page < 1`.
  • `perPage < 1`.
  • negative total.
  • negative filtered.
  • negative totalPages.
  • `count(data) > perPage`.
  • malformed sort key.
  • totalPages ??? ????? ??????.
  • page ???? ?? totalPages.
  • zero filtered ?? non-empty data.
  • zero filtered ?? page ??? 1.
  • zero filtered ?? navigation flag true.
  • inconsistent `hasNext`.
  • inconsistent `hasPrevious`.

11.4 serialization

????? envelope ??????:

[
    'data' => [],
    'pagination' => [
        'page' => 1,
        'per_page' => 20,
        'total' => 0,
        'filtered' => 0,
        'total_pages' => 0,
        'has_next' => false,
        'has_previous' => false,
        'sort_by' => 'created_at',
        'sort_direction' => 'DESC',
    ],
]

?????:

  • `toArray()` ?`jsonSerialize()` ????????.
  • ?? ???? `offset`.
  • mapped arrays ??? ??.
  • mapped objects ??? instances ???????? `assertSame()`.
  • ?? ??? ??????? `toArray()` ?? `jsonSerialize()` ??? mapped object ???????.
  • ?? ???? SQL identifiers ?? raw request values.

12. PdoPaginatorNormalizationTest

?????? scripted PDO statements? ?????? ?????? ?? ???? paginate() ???.

12.1 page normalization

???????:

| Input | Expected | | ------------------------ | -------------------------------: | | null | 1 | | '' | 1 | | whitespace | 1 | | malformed alpha | 1 | | decimal | 1 | | exponent | 1 | | sign only | 1 | | 0 | 1 | | negative int | 1 | | negative string | 1 | | 1 | 1 | | '+1' | 1 | | '0002' | 2 | | valid integer | same value | | PHP_INT_MAX | accepted when totalPages permits | | (string) PHP_INT_MAX | accepted | | positive overflow string | 1 | | negative overflow string | 1 |

????? page ???? ?? 1? ??? ?? ???? filtered count ??? ????? ??????.

12.2 per-page normalization

?????? config ?????? ????? ??????? ?????? ???:

defaultPerPage = 20
minPerPage     = 2
maxPerPage     = 50

???????:

| Input | Expected | | ------------------------ | ---------: | | null | 20 | | empty/malformed | 20 | | positive overflow string | 20 | | negative overflow string | 20 | | representable negative | 2 | | 0 | 2 | | 1 | 2 | | 2 | 2 | | valid middle value | same value | | 50 | 50 | | 51 | 50 | | PHP_INT_MAX | 50 | | (string) PHP_INT_MAX | 50 | | '0005' | 5 |

??? ????? ????? ???:

  • representable below-min ? clamp to min.
  • unrepresentable string ? fallback to default.

12.3 sort normalization

sortBy:

  • null ? default.
  • empty/whitespace ? default.
  • malformed ? default.
  • unknown ? default.
  • wrong case ? default.
  • trimmed valid key ? requested key.

sortDirection:

  • `asc`, `ASC`, mixed case ? `ASC`.
  • `desc`, `DESC`, mixed case ? `DESC`.
  • surrounding whitespace ?????.
  • null/empty/invalid ? configured default.

??? result ???? effective public key ???????? ??????? ???.

13. PdoPaginatorExecutionTest

13.1 execution order

????? ???????:

totalSql
filteredCountSql
dataSql

?? ???? ????? data ??? ???? counts.

13.2 separate parameter maps

?????? ????? ?? ????? ??? ???????:

total_tenant
filtered_category
data_active

????? ?? ?? statement ???? ??? map ?????? ?? ???.

13.3 typed binding

?????:

| Value | Type | | ------ | ----------------- | | int | PDO::PARAM_INT | | bool | PDO::PARAM_BOOL | | null | PDO::PARAM_NULL | | string | PDO::PARAM_STR |

???:

:__pagination_limit
:__pagination_offset

?????? ?????? ?? PDO::PARAM_INT.

13.4 final SQL

Distinct identifiers:

{dataSql}
ORDER BY `created_at` DESC, `id` ASC
LIMIT :__pagination_limit
OFFSET :__pagination_offset

Duplicate resolved identifier:

{dataSql}
ORDER BY `id` DESC
LIMIT :__pagination_limit
OFFSET :__pagination_offset

?????:

  • ?? trailing semicolon.
  • raw sort input ?? ???? SQL.
  • directions ???? ?? enum ???.
  • tie-breaker ?? ????? ??? ????? quoted identifier.
  • ????? bind:

    1. data params. 2. internal limit. 3. internal offset.

13.5 zero result

??? filtered === 0:

  • page ??????? 1.
  • totalPages = 0.
  • data = [].
  • flags false.
  • data SQL ?? ??? prepare ???.
  • mapper ?? ???????.
  • primary/tie-breaker lookup ??? ????? ??????? ??? counts.

13.6 overflow

????? requested page ???? ?? totalPages:

  • page ??????? 1.
  • offset = 0.
  • data statement ?????? ??? ?????.
  • execute ??? ?????.
  • ?? retry ????.

13.7 mapper

  • array result.
  • object result.
  • ????? items ?????.
  • ??? object instances ??????.
  • empty fetched data ?? `filtered > 0` ?????.
  • `filtered > total` ?????.
  • mapper ??????? ??? ????? ??? row ?????.

14. PdoPaginatorFailureTest

14.1 package-owned non-throwing failures

?? ???? ????:

PaginationExecutionException

prepare returns false

  • total prepare.
  • filtered-count prepare.
  • data prepare.

bindValue returns false

  • total caller parameter.
  • filtered-count caller parameter.
  • data caller parameter.
  • internal limit.
  • internal offset.

execute returns false

  • total.
  • filtered count.
  • data.

14.2 fetch rules

  • `false` ?? `errorCode() === '00000'` ? EOF ?????.
  • `false` ?? ?? SQLSTATE ??? ? `PaginationExecutionException`.
  • `false` ?? `null` ?? ???? ??? `'00000'` ? failure.
  • count fetch failure.
  • data fetch failure.
  • data fetch failure ??? row ?????:

    * ???? exception. * ?? ???? partial `PageResult`.

  • fetch ???? scalar ? exception.
  • fetch ???? array ??? numeric key ? exception.
  • empty data row ? exception.

14.3 count shape

???:

  • zero rows.
  • ???? ?? row.
  • `columnCount() = 0`.
  • `columnCount() > 1`.
  • row ?????.
  • row ?????? ???????.

14.4 count values

????:

  • integer zero.
  • positive integer.
  • digit string.
  • leading-zero digit string.
  • `(string) PHP_INT_MAX`.

???:

  • negative integer.
  • `false`.
  • `null`.
  • empty string.
  • signed string.
  • decimal.
  • exponent.
  • negative string.
  • greater than `PHP_INT_MAX`.
  • array.
  • object.
  • resource.

14.5 mapper failure

??? mapper result:

null
bool
int
float
string
resource

???????? Reflection invocation ????? ???? ??? ??????? ????? ?????? PHPDoc ???? static analysis.

14.6 Throwable propagation

?????? Throwable instances ?????? ?????? ????? ?? assertSame():

  • `PDOException` ?? prepare.
  • `PDOException` ?? bind.
  • `PDOException` ?? execute.
  • `PDOException` ?? fetch.
  • arbitrary RuntimeException ?? mapper.

????? ???? wrapping ?? previous.

14.7 transaction and attributes through doubles

????? ??? ???????:

beginTransaction
commit
rollBack
setAttribute

15. PaginationPublicApiRegressionTest

?????? Reflection ?????? ??? Public API ???? ??? ????? private implementation.

15.1 inventory

????? ???? ??????? ?????? ???????:

Maatify\Persistence\Pdo\Pagination\PageRequest
Maatify\Persistence\Pdo\Pagination\SortDirectionEnum
Maatify\Persistence\Pdo\Pagination\SortWhitelist
Maatify\Persistence\Pdo\Pagination\PaginationConfig
Maatify\Persistence\Pdo\Pagination\PdoPaginationQueryDescriptor
Maatify\Persistence\Pdo\Pagination\PageResult
Maatify\Persistence\Pdo\Pagination\PdoPaginator

Maatify\Persistence\Exception\InvalidPaginationConfigurationException
Maatify\Persistence\Exception\InvalidPaginationQueryException
Maatify\Persistence\Exception\PaginationExecutionException

????? ??? ???? ??????? ????????:

Maatify\Persistence\Exception\PaginationException
Maatify\Persistence\Pdo\Pagination\PaginatorInterface
Maatify\Persistence\Pdo\Pagination\RowMapperInterface
Maatify\Persistence\Pdo\Pagination\FilterWhitelist
Maatify\Persistence\Pdo\Pagination\SearchBuilder

15.2 modifiers

????? final ?readonly ??????? ????????.

?????:

SortDirectionEnum
ASC = ASC
DESC = DESC

??? public enum methods ??????.

15.3 constructors

????? names? order? native types? nullability? defaults? promoted visibility ???:

  • `PageRequest`.
  • `SortWhitelist`.
  • `PaginationConfig`.
  • `PdoPaginationQueryDescriptor`.
  • `PageResult`.

??? ????? ????? ??????:

filteredCountParams

?? constructor parameter ?public property.

15.4 public methods

SortWhitelist:

contains(string): bool
quotedIdentifierFor(string): string

PdoPaginator:

paginate(
    PDO $pdo,
    PdoPaginationQueryDescriptor $query,
    PageRequest $request,
    PaginationConfig $config,
    callable $mapper,
): PageResult

PageResult:

toArray(): array
jsonSerialize(): array

????? ????? private helper names ?? Public API.

16. PaginationSqlContractRegressionTest

???? ?? scripted doubles:

  • exact final SQL ?? distinct tie-breaker.
  • exact final SQL ?? duplicate resolved identifier.
  • internal placeholder names ??????.
  • no offset field ?? result.
  • fixed result field names ????esting.
  • named-placeholder binding only ?? ???? package-owned params.
  • descriptor ?? ???? SQL parser.
  • positional/mixed/repeated placeholder examples ?? ????? ?? constructor.
  • raw sort key ?? ???? ?? SQL.
  • exact execution order.
  • overflow ?? ???? query ?????.
  • zero filtered ?? ???? data SQL.

??? ?? ???? ??? ??? public descriptor:

PdoPaginationQueryDescriptor

???? request/result:

PageRequest
PageResult

??? ???? ?????????? aliases ?? ????? ?????.

17. PaginationExceptionContractTest

??? ??????? ?? ???????:

  • class `final`.
  • ???? ??:
Maatify\Exceptions\Exception\System\SystemMaatifyException

  • ????:
Maatify\Persistence\Exception\PersistenceException

  • `defaultErrorCode()` ????:
ErrorCodeEnum::MAATIFY_ERROR

  • safety behavior ????? ?? `SystemMaatifyException`.
  • ?? ???? Pagination-specific marker.

????? representative triggers:

  • invalid whitelist/config ? `InvalidPaginationConfigurationException`.
  • invalid descriptor ? `InvalidPaginationQueryException`.
  • package-owned execution failure ? `PaginationExecutionException`.

18. OrderingPublicApiRegressionTest

????? ?????? ????? ?? ????? Pagination ?? ????? Ordering.

????? Public API ??????? ??:

ScopedOrderingConfig
ScopedOrderingManager

????:

  • namespaces.
  • final/readonly.
  • constructor parameters ?? `ScopedOrderingConfig`.
  • public promoted properties.
  • public methods:
quotedTable
quotedIdColumn
quotedOrderColumn
quotedScopeColumn
quotedDeletedAtColumn

?:

getNextPosition
moveWithinScope
rowExistsInScope

?? parameter names/order/types/defaults ???return types.

?? ???? ?????? ???? Ordering ???? ????? ?????????? ???????.

19. MySQL Fixture

19.1 table

?????:

tests/Fixtures/MySql/create_pagination_items_table.sql

????:

maa_persistence_test_pagination_items

????????:

ENGINE=InnoDB
utf8mb4

??????? ????????:

id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
tenant_id      INT UNSIGNED NOT NULL
category       VARCHAR(32) NOT NULL
name           VARCHAR(128) NOT NULL
score          INT NOT NULL
is_active      TINYINT(1) NOT NULL
nullable_code  VARCHAR(32) NULL
created_at     DATETIME(6) NOT NULL
deleted_at     DATETIME(6) NULL

Indexes ??? ?? ????:

  • tenant/base scope.
  • filter columns.
  • `created_at, id` deterministic ordering.

?? FK ??? host tables.

20. MySQL Support

20.1 PaginationSchemaManager

????:

public const TABLE = 'maa_persistence_test_pagination_items';

Methods:

initialize()
reset()
dropTable()

initialize():

  1. drop.
  2. execute fixture.

reset():

TRUNCATE TABLE

dropTable():

DROP TABLE IF EXISTS

20.2 PaginationFixture

???? method ????? ?????? row:

insertItem(
    int $tenantId,
    string $category,
    string $name,
    int $score,
    bool $isActive,
    ?string $nullableCode,
    string $createdAt,
    ?string $deletedAt = null,
): int

  • ?????? prepared statement.
  • ???? inserted id.
  • ?? ?????? randomness.
  • ?? ???? defaults ????? ??? ????????.

20.3 PaginationIntegrationTestCase

Base ?????? ?? Ordering.

??????:

MySqlConnectionFactory
PaginationSchemaManager
PaginationFixture

Lifecycle:

  • `setUpBeforeClass()`:

    * connection. * initialize schema.

  • `setUp()`:

    * rollback ??? transaction ??????. * reset. * fixture ?????.

  • `tearDown()`:

    * rollback ??? transaction ??????. * reset.

  • `tearDownAfterClass()`:

    * rollback. * drop table.

?? ???? ?? Ordering-specific base ??? ?? ???? ?? ????? ??? Ordering tables.

21. PdoPaginatorQuerySemanticsTest

Real MySQL ???.

21.1 total and filtered

Dataset ?????:

  • ???? ?? tenant.
  • active/inactive.
  • ???? ?? category.
  • null/non-null code.
  • soft-deleted row.

totalSql ???? mandatory base scope ???.

filteredCountSql ?dataSql ?????? optional filters.

?????:

  • total ???? base visible dataset.
  • filtered ???? filtered visible dataset.
  • data ??????? ?? filtered.
  • soft-deleted rows ?? ???? ????? ???????? caller SQL.

21.2 no-filter

  • totalSql ?filteredCountSql ???? ?? ????? ????????.
  • parameter maps ??? ??????.
  • total ?filtered ????????.

21.3 parameter types

?? descriptor ???? ??? ????:

tenant_id      => int
category       => string
is_active      => bool
nullable_code  => null

?????? MySQL null-safe comparison:

nullable_code <=> :nullable_code

21.4 native prepares

??? ???????:

PDO::ATTR_EMULATE_PREPARES === false

??? ??????? ??? ?????? ?????.

21.5 sorting

??????:

  • default sort.
  • requested sort.
  • invalid key fallback.
  • invalid direction fallback.
  • ASC.
  • DESC.
  • surrounding whitespace.
  • duplicate primary values ?? unique `id` tie-breaker.
  • ??????? ????? ??????? ?????? ??? ????? ?? ??? rows.
  • public keys ??????? ?????? ??? ??? unique `id` ??????? ??? duplicate ordering term.

21.6 page behavior

  • first page.
  • middle page.
  • final page.
  • page overflow ???? page 1 ?first-page rows.
  • zero filtered ???? empty result.

?????? skip ??????? ??? zero filtered:

  • ?????? `dataSql` ???? ??? table ?? column ??? ??????.
  • ????? filtered count = 0? ??? ??? ???? PDO failure.
  • ?? ?????? semicolon ?? reserved placeholder.

21.7 mapper

  • identity array mapper.
  • DTO/object mapper.
  • ????? mapped items.
  • object instances ??? ?????? mapper.
  • `filtered > total` descriptor ????? ?????? ??? ???? Runtime enforcement.
  • empty data query result ?? positive filtered count ????? ??? ???? metadata.

22. PdoPaginatorFailureContractTest

Real MySQL ???.

22.1 count cardinality

  • exactly one row / one column ?????.
  • zero rows ?????.
  • multiple rows ?????.
  • multiple columns ?????.

???? ??????? SQL ???? ???? ?? ????? ??? parser.

22.2 placeholder failures

??? ????? ????? ?? descriptor constructor ???? ?? ????? paginator.

???????:

  • repeated named placeholder.
  • missing parameter.
  • unused parameter.
  • positional placeholder.
  • mixed positional/named placeholders.

???????? ???? failure ????? ????? ??? ????:

PDOException
??
PaginationExecutionException

???? ????? ?????? ????? PDO.

????? ??????? ?? descriptor constructor ???????.

22.3 mapper failure

  • scalar result ? `PaginationExecutionException`.
  • resource result ? `PaginationExecutionException`.
  • mapper Throwable ???? ???? instance.

22.4 PDO exception propagation

?????? invalid table ?? invalid column ?? count/data execution? ?????:

  • ?????? `PDOException`.
  • ??? `PaginationExecutionException`.
  • ?? wrapping.

?? ???? message ?? vendor-specific numeric code.

23. PdoPaginatorTransactionTest

Real MySQL ???.

23.1 outside transaction

???:

$pdo->inTransaction() === false

??? successful pagination:

$pdo->inTransaction() === false

????? ?? paginator ?? ???? transaction.

23.2 caller-owned transaction

  1. caller ???? transaction.
  2. ???? pagination.
  3. ??????? ?????.
  4. transaction ?? ???? active.
  5. caller ???? rollback ???? `finally`.

????? ?? ???? paginator:

commit
rollback

23.3 attributes unchanged

????? ??? ????:

PDO::ATTR_ERRMODE
PDO::ATTR_DEFAULT_FETCH_MODE
PDO::ATTR_EMULATE_PREPARES
PDO::ATTR_STRINGIFY_FETCHES

??? attributes ???????? ?????? ??????.

????? ?? ???? paginator ?? attribute.

23.4 claim boundary

?? ???? test ?????? ?? assertion ???? ?? ?? external PDO/driver failure ????? ??? transaction state.

?????? ???????:

  • ?????? ???? caller transaction ?? ??????.
  • ?????? ???? transaction ?? ???? ?????.
  • paginator ?? ?????? transaction operations ?????.

24. CI Residue Verification

???? .github/workflows/ci.yml:

???:

maa_persistence_test_pagination_items

??? ????? $tables.

???? query placeholders ???? execute arguments ????? ??????? ???????:

maa_persistence_test_global_ordering
maa_persistence_test_scoped_ordering
maa_persistence_test_pagination_items

?? ??? triggers ?????.

??? CI ??? ?? ????? ?? ?????:

unit
regression
integration
integration ??? ?????
full suite

???? ?? ??? ??? residue ??? ??????? ???????.

25. Coverage Mapping Requirement

??? ?? ????? PR description ?????? ???? ?? ??? ??:

PDO_PAGINATION_CONTRACT.md / Section 21

???? test class ?test method ???? ?????.

?? ?????:

  • ??? ??? ??? ?covered?.
  • ??? ??? test ????.
  • ?????? PHPStan ?? syntax check ?????? ?? behavior test.
  • ?????? Unit doubles ?????? ?? Real MySQL ??? ???? ????? MySQL.
  • ?????? MySQL ???? ?????? ?? package-owned non-throwing failure doubles.

26. ?????? ???????

????:

composer validate --strict

vendor/bin/phpstan analyse -c phpstan.neon --no-progress

vendor/bin/php-cs-fixer fix --dry-run --diff

vendor/bin/phpunit --testsuite unit
vendor/bin/phpunit --testsuite regression
vendor/bin/phpunit --testsuite integration
vendor/bin/phpunit --testsuite integration
vendor/bin/phpunit

git diff --check

????? syntax check ???:

src//*.php
tests//*.php

??? Integration ??? ?? ????? ??? ??? Real MySQL ???????? environment ??????:

PERSISTENCE_TEST_MYSQL_DSN
PERSISTENCE_TEST_MYSQL_USER
PERSISTENCE_TEST_MYSQL_PASSWORD

?? skip ???? ??? ???? environment? ?????? ?????? ????? ???? configuration ????? ??????.

27. ?????? ??????

????? ?????????? ????? ??? ???:

  • ?? Unit tests ?????.
  • ?? Regression tests ?????.
  • ?? Real MySQL Integration tests ?????.
  • ????? Integration ?????.
  • Full suite ?????.
  • PHPStan max ??? errors.
  • Code style ????.
  • MySQL residue ????.
  • ?? skips ??? ??????.
  • ?? suppressions.
  • ?? Runtime changes.
  • ?? Composer changes.
  • ?? Ordering behavior changes.
  • ?? `composer.lock`.
  • ?? ??? ?? Contract Section 21 ????? ??????? ????.

??? ?????????? ?? assertions ??? ????? ???????? ?????? ????? ?? ?????.

28. ???? Jules ??????

??? ?????? ??? ??? Blueprint? Jules ????? ?? ???:

  • ????? ????? ?????????? ?????? ???fixture ???????.
  • ????? residue verification ?????? ???? CI.
  • ????? ?? quality gates.
  • ????? PR ??? ????.

????? ??? Jules:

  • ????? `src/`.
  • ????? Runtime ?????.
  • ????? ???? ?????? ????.
  • ????? Contract ?? Runtime Blueprint.
  • ????? README ?? Package Reference ?? CHANGELOG.
  • ????? Composer.
  • ????? abstraction ??? ?????? ?? ??? ?????.
  • ????? release ?? tag ?? merge.

??? ??? test ?? Runtime defect:

STOP
REPORT EXACT FAILURE
DO NOT MODIFY SRC

29. ????? Jules ??????? ??????

??? ?? ????:

  1. Starting SHA.
  2. PR URL.
  3. Final HEAD SHA.
  4. ????? ??????? ????????.
  5. ??? Unit tests/assertions.
  6. ??? Regression tests/assertions.
  7. ??? Integration tests/assertions.
  8. ????? Integration run ???????.
  9. ????? full suite.
  10. ????? PHPStan.
  11. ????? code style.
  12. ????? MySQL residue.
  13. Contract Section 21 coverage mapping.
  14. ????? ??? ????? `src/`.
  15. ????? ??? ????? Composer ?? docs.
  16. ????? ??? ????? `composer.lock`.
  17. ?? Runtime defect ?????? ??? ??????.

Commit message ?????? ?????????? ??????:

test(pagination): cover PDO pagination contracts

30. ?????? ??????

TEST_BLUEPRINT_STATUS: IMPLEMENTED
NEXT_ACTION: NONE