Repository navigation
Render ExpressionInterface check expressions and default the name - #184
Merged
simon-mundy merged 4 commits intoSep 28, 2026
Merged
Conversation
Check documented its expression as string|ExpressionInterface but always wrapped it in a Literal, so an Expression was accepted at construction and threw a TypeError at render. An empty string rendered a bare CONSTRAINT header with no CHECK clause, and the name argument had no default. An ExpressionInterface expression now contributes its own specification and values to the check, so its identifiers and values are quoted by the platform. A plain string stays a literal SQL fragment by design. An empty string throws InvalidArgumentException at construction, matching Expression::setExpression(), and the name defaults to null like PrimaryKey and UniqueKey. Fixes php-db#177 Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
CI installs the newest Mago, and 1.47.5 changed how the analyzer handles nested array shapes: prepareDataHierarchy() re-binds a reference into the MetadataData shape on every loop iteration, which no longer completes in useful time. Re-type the reference as a plain array so the shape is not re-derived per iteration, and adjust the expected findings accordingly. Regenerate the analyzer baseline for the reworded findings in Select, PredicateSet, Profiler and AbstractSql (the issues are unchanged, the messages are not), and reduce the continuation indent of two multi-line conditions in AbstractTableGateway to match the 1.47.4+ formatter. Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
tyrsson
previously approved these changes
Sep 28, 2026
tyrsson
left a comment
Member
There was a problem hiding this comment.
Approved post conflict resolution
simon-mundy
added a commit
to simon-mundy/phpdb
that referenced
this pull request
Sep 28, 2026
All 55 throw sites in src/Sql now call a named constructor. Message text is byte-identical, verified template by template against the original literals. - Add Sql\Predicate\Exception with its own ExceptionInterface, InvalidArgumentException and RuntimeException, holding the 10 templates the predicate classes use, so the messages sit with the classes that raise them rather than concentrating on one component catalogue - Add 24 templates and factories to Sql\Exception\InvalidArgumentException and 6 to Sql\Exception\RuntimeException, the last four covering the Ddl column and check constraint messages added by php-db#183, php-db#184 and php-db#185 - Collapse nine duplicated messages onto one template each, five of which the audit on php-db#189 had missed: the four "intended to work with only the table" copies in Sql, the two parameter-count copies in AbstractSql, the two column key copies in Insert, the two read-only copies in Select, and the subject messages shared by Platform and AbstractPlatform - Fix a copy-paste bug in Platform::getSqlString(), which reported prepareStatement() as the method with no effect - Retype Between's \LogicException and AbstractSql's \ValueError to the package types, so both reach the marker interface - Declare the @throws Predicate::unnest() and Predicate::__get() never had - Cover every factory with a template test, and derive the 46 Sql message assertions from the templates rather than restating them - Re-attribute the two baselined sprintf argument-type entries to the factories that now receive those arguments, and baseline the three halstead readings the refactor shifts - Exclude src/Sql/Exception/ from too-many-methods in mago.toml. The threshold is 10 and a catalogue holds one template per condition a component can report, so the count tracks failure modes rather than anything a split would improve Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
This was referenced Sep 28, 2026
simon-mundy
added a commit
to simon-mundy/phpdb
that referenced
this pull request
Sep 28, 2026
All 55 throw sites in src/Sql now call a named constructor. Message text is byte-identical, verified template by template against the original literals. - Add Sql\Predicate\Exception with its own ExceptionInterface, InvalidArgumentException and RuntimeException, holding the 10 templates the predicate classes use, so the messages sit with the classes that raise them rather than concentrating on one component catalogue, and register both concrete classes in ExceptionHierarchyTest's EXCEPTION_CLASSES map - Add 24 templates and factories to Sql\Exception\InvalidArgumentException and 6 to Sql\Exception\RuntimeException, the last four covering the Ddl column and check constraint messages added by php-db#183, php-db#184 and php-db#185 - Collapse nine duplicated messages onto one template each, five of which the audit on php-db#189 had missed: the four "intended to work with only the table" copies in Sql, the two parameter-count copies in AbstractSql, the two column key copies in Insert, the two read-only copies in Select, and the subject messages shared by Platform and AbstractPlatform - Fix a copy-paste bug in Platform::getSqlString(), which reported prepareStatement() as the method with no effect - Retype Between's \LogicException and AbstractSql's \ValueError to the package types, so both reach the marker interface - Declare the @throws Predicate::unnest() and Predicate::__get() never had - Cover every factory with a template test, and derive the 46 Sql message assertions from the templates rather than restating them - Re-attribute the two baselined sprintf argument-type entries to the factories that now receive those arguments, and baseline the three halstead readings the refactor shifts - Exclude src/Sql/Exception/ from too-many-methods in mago.toml. The threshold is 10 and a catalogue holds one template per condition a component can report, so the count tracks failure modes rather than anything a split would improve Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
simon-mundy
added a commit
to simon-mundy/phpdb
that referenced
this pull request
Sep 29, 2026
All 55 throw sites in src/Sql now call a named constructor. Message text is byte-identical, verified template by template against the original literals. - Add Sql\Predicate\Exception with an InvalidArgumentException and a RuntimeException holding the 10 templates the predicate classes use, so the messages sit with the classes that raise them rather than concentrating on one component catalogue, and register both in ExceptionHierarchyTest's EXCEPTION_CLASSES map. The namespace deliberately has no ExceptionInterface of its own: both classes extend their Sql\Exception counterparts, so they are already caught by Sql\Exception\ExceptionInterface, and a narrower marker would only collapse the same InvalidArgument and Runtime split a second time - Add 24 templates and factories to Sql\Exception\InvalidArgumentException and 6 to Sql\Exception\RuntimeException, the last four covering the Ddl column and check constraint messages added by php-db#183, php-db#184 and php-db#185 - Collapse nine duplicated messages onto one template each, five of which the audit on php-db#189 had missed: the four "intended to work with only the table" copies in Sql, the two parameter-count copies in AbstractSql, the two column key copies in Insert, the two read-only copies in Select, and the subject messages shared by Platform and AbstractPlatform - Fix a copy-paste bug in Platform::getSqlString(), which reported prepareStatement() as the method with no effect - Retype Between's \LogicException and AbstractSql's \ValueError to the package types, so both reach the marker interface - Declare the @throws Predicate::unnest() and Predicate::__get() never had - Cover every factory with a template test, and derive the 46 Sql message assertions from the templates rather than restating them - Re-attribute the two baselined sprintf argument-type entries to the factories that now receive those arguments, and baseline the three halstead readings the refactor shifts - Exclude src/Sql/Exception/ from too-many-methods in mago.toml. The threshold is 10 and a catalogue holds one template per condition a component can report, so the count tracks failure modes rather than anything a split would improve Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
simon-mundy
added a commit
to simon-mundy/phpdb
that referenced
this pull request
Sep 29, 2026
All 55 throw sites in src/Sql now call a named constructor. Message text is byte-identical, verified template by template against the original literals. - Add Sql\Predicate\Exception with an InvalidArgumentException and a RuntimeException holding the 10 templates the predicate classes use, so the messages sit with the classes that raise them rather than concentrating on one component catalogue, and register both in ExceptionHierarchyTest's EXCEPTION_CLASSES map. Neither namespace declares an ExceptionInterface: the package has one marker, PhpDb\Exception\ExceptionInterface, and every class here implements it by inheritance - Add 24 templates and factories to Sql\Exception\InvalidArgumentException and 6 to Sql\Exception\RuntimeException, the last four covering the Ddl column and check constraint messages added by php-db#183, php-db#184 and php-db#185 - Collapse nine duplicated messages onto one template each, five of which the audit on php-db#189 had missed: the four "intended to work with only the table" copies in Sql, the two parameter-count copies in AbstractSql, the two column key copies in Insert, the two read-only copies in Select, and the subject messages shared by Platform and AbstractPlatform - Fix a copy-paste bug in Platform::getSqlString(), which reported prepareStatement() as the method with no effect - Retype Between's \LogicException and AbstractSql's \ValueError to the package types, so both reach the marker interface - Declare the @throws Predicate::unnest() and Predicate::__get() never had - Cover every factory with a template test, and derive the 46 Sql message assertions from the templates rather than restating them - Re-attribute the two baselined sprintf argument-type entries to the factories that now receive those arguments, and baseline the three halstead readings the refactor shifts - Exclude src/Sql/Exception/ from too-many-methods in mago.toml. The threshold is 10 and a catalogue holds one template per condition a component can report, so the count tracks failure modes rather than anything a split would improve Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checknow takesstring|ExpressionInterface $expression, ?string $name = null. AnExpressionInterfaceexpression merges its owngetExpressionData()into the check — specCHECK (<inner spec>), values appended — so identifiers and values inside it are quoted by the platform instead of being flattened into aLiteraland failing with aTypeError. RendersCHECK (a > '1')andCHECK ("a" > "b"). A plain string stays aLiteral; it is an expression slot by design and the docs now say so.An empty string throws
Sql\Exception\InvalidArgumentExceptionat construction, the same exceptionExpression::setExpression()throws, rather than rendering a bareCONSTRAINTheader with noCHECKclause.$namedefaults tonullin line withPrimaryKeyandUniqueKey.Values are always inlined: DDL extends
AbstractSql, notAbstractPreparableSql, and MySQL rejects a parameter marker inside a CHECK anyway (3815).CheckTestcovers the merged expression data, quoted values and identifiers viagetSqlString(),%inside anExpressionwith and without a name, an unnamed check, the column-level inline form ("age" INTEGER NOT NULL CONSTRAINT "chk_age" CHECK (age >= 0)), and the empty-string exception.Fixes #177