classRelation
final class Relation
One relation as written, with the roles the operator implies.
The sides are kept in the order they were written so that a plan prints back the way it was given. Which end is the parent comes from the operator, not from the order, so a.id < b.a_id and b.a_id > a.id describe the same shape.
A ? next to an end marks that end optional, as it does in DBML: the referencing column may be null, so the row on the other end need not exist.
Properties§
public ColumnRef $leftpublic RelationKind $kindpublic ColumnRef $rightpublic bool $leftOptional = falsepublic bool $rightOptional = falseMethods§
public function __construct(
public ColumnRef $left,
public RelationKind $kind,
public ColumnRef $right,
public bool $leftOptional = false,
public bool $rightOptional = false,
)Initializes the collaborators and declared state for this object.
Parameters
$left | ColumnRef | |
$kind | RelationKind | |
$right | ColumnRef | |
$leftOptional | bool | |
$rightOptional | bool |
Calls 2
- function-call
countline 31 - new CompositeArityMismatchException line 32
public static function oneToMany(
string|ColumnRef $parent,
string|ColumnRef $child,
bool $childOptional = false,
): selfparent.column < child.column: one parent row, several child rows.
Returns
selfTest cases 27
RelationCountsTest::testResolveCountHonorsExplicitRowsAndCardinalitycallsRelationProjectionTest::testIsAlreadyLinkedRequiresEveryCompositeColumncallsRelationProjectionTest::testProjectMapsCompositeKeysWithoutUnrelatedColumnscallsFixturePlanTest::testAPlanBuiltFromAKeyedSpreadCanStillBeExtendedcallsFixturePlanTest::testAStringPartNamesAStandaloneTablecallsFixturePlanTest::testOfAcceptsRelationsWithoutAStringcallsFixturePlanTest::testPartsSpreadFromAKeyedArrayAreStillReadInOrdercallsFixturePlanTest::testWithRelationAddsARelationDirectlycallsPlanPrinterTest::testPrintRelationIncludesOptionalEndpointMarkerscallsPlanPrinterTest::testPrintsASingleRelationWithoutAPlancallsRelationGroupsTest::testGroupCombinesOnlyMatchingLeftEndpointscallsRelationGroupsTest::testGroupKeyIncludesOptionalitycallsStatementPrinterTest::testPrintGroupUsesCompactTargetsOnlyForMultipleRelationscallsRelationTest::testAnOptionalChildMayEndUpWithNoRowscallsRelationTest::testMaximumChildRowsACollectionChildHasNoUpperBoundcallsRelationTest::testMinimumChildRowsARequiredChildIsGeneratedEvenWhenNoneAreGivencallsRelationTest::testNamedConstructorsAlsoTakeColumnRefscallsRelationTest::testNamedConstructorsBuildEachOperatorcallsRelationTest::testNamedConstructorsLeaveTheLeftSideRequiredcallsRelationTest::testNamedConstructorsReadEndpointsWrittenAsStringscallsRelationTest::testOneToManyCanMarkTheChildOptionalcallsRelationTest::testOneToManyLeavesBothSidesRequiredByDefaultcallsRelationTest::testOneToManyMarksOnlyTheRightSideOptionalcallsPlanValidationTest::testRejectColumnsBoundTwiceAcceptsDistinctForeignKeyscallsPlanValidationTest::testRejectUnboundedSelfReferencesAcceptsOptionalChildrencallsPlanValidationTest::testSortByDependencyPreservesIndependentOrdercallsPlanValidationTest::testWaitsForAnyChecksOnlyPendingParentscalls
Called from 1
Calls 3
- new
selfline 44 - static-call ColumnRef::from() line 45
- class-const RelationKind::OneToMany() line 46
public static function manyToOne(
string|ColumnRef $child,
string|ColumnRef $parent,
bool $parentOptional = false,
): selfchild.column > parent.column: the same shape written from the child.
Returns
selfTest cases 7
FixturePlanTest::testOfAcceptsRelationsWithoutAStringcallsRelationGroupsTest::testGroupCombinesOnlyMatchingLeftEndpointscallsRelationTest::testManyToOneCanMarkTheParentOptionalcallsRelationTest::testManyToOneLeavesBothSidesRequiredByDefaultcallsRelationTest::testManyToOneMarksOnlyTheRightSideOptionalcallsRelationTest::testNamedConstructorsBuildEachOperatorcallsRelationTest::testNamedConstructorsLeaveTheLeftSideRequiredcalls
Called from 1
Calls 3
- new
selfline 61 - static-call ColumnRef::from() line 62
- class-const RelationKind::ManyToOne() line 63
public static function oneToOne(
string|ColumnRef $parent,
string|ColumnRef $child,
bool $childOptional = false,
): selfparent.column - child.column: one row on each side.
Returns
selfTest cases 7
RelationCountsTest::testResolveCountHonorsExplicitRowsAndCardinalitycallsRelationTest::testAnOptionalOneToOneChildRangesFromNoneToOnecallsRelationTest::testAOneToOneChildIsCappedAtOneRowcallsRelationTest::testNamedConstructorsBuildEachOperatorcallsRelationTest::testNamedConstructorsLeaveTheLeftSideRequiredcallsRelationTest::testOneToOneLeavesBothSidesRequiredByDefaultcallsRelationTest::testOneToOneMarksOnlyTheRightSideOptionalcalls
Called from 1
Calls 3
- new
selfline 78 - static-call ColumnRef::from() line 79
- class-const RelationKind::OneToOne() line 80
public function minimumChildRows(): intThe fewest child rows to generate when none are given.
A relation written without ? says the child must be there, so an unspecified child is still generated. Marking it optional is what makes "none at all" a possible outcome.
Returns
intCalled from 1
Calls 1
- method-call Relation::childIsOptional() line 96
public function maximumChildRows(): ?intThe most child rows the relation allows, or null where it is unbounded.
Returns
?intCalled from 1
Calls 1
- method-call Relation::childIsCollection() line 104
public function parent(): ColumnRefThe end holding a single row, generated before the other.
Returns
Test cases 2
Called from 5
- method-call SqlFixture\Fixture\Generation\RelationProjection::project() packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:61
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toParent() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:133
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toParent() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:137
- method-call SqlFixture\Plan\FixturePlan::dependentsOf() packages/sql-fixture/src/Plan/FixturePlan.php:230
- method-call SqlFixture\Plan\Relation::columnMap() packages/sql-fixture/src/Plan/Relation.php:158
Calls 2
- method-call RelationKind::parentSide() line 112
- class-const RelationSide::Left() line 112
public function child(): ColumnRefThe end referencing the parent, which may hold several rows.
Returns
Test cases 3
Called from 3
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toChildren() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:152
- method-call SqlFixture\Plan\FixturePlan::dependenciesOf() packages/sql-fixture/src/Plan/FixturePlan.php:217
- method-call SqlFixture\Plan\Relation::columnMap() packages/sql-fixture/src/Plan/Relation.php:157
Calls 2
- method-call RelationKind::childSide() line 120
- class-const RelationSide::Left() line 120
public function parentIsOptional(): boolWhether the parent row may be absent, leaving the reference null.
Returns
boolTest cases 3
Called from 1
Calls 2
- method-call RelationKind::parentSide() line 128
- class-const RelationSide::Left() line 128
public function childIsOptional(): boolWhether the child end was marked optional.
This says nothing the data does not already say, since the number of child rows comes from the values supplied for that table.
Returns
boolTest cases 3
Called from 1
Calls 2
- method-call RelationKind::childSide() line 139
- class-const RelationSide::Left() line 139
public function childIsCollection(): boolReports whether the relation permits multiple child rows.
Returns
boolTest cases 1
Called from 2
Calls 1
- method-call RelationKind::childIsCollection() line 147
public function columnMap(): array<string, string>Map each child column onto the parent column it references.
Returns
array<string, string> Child column => parent columnTest cases 3
Called from 2
Calls 2
- method-call Relation::child() line 157
- method-call Relation::parent() line 158
public function tables(): list<string>Returns
list<string> The tables this relation touches, left end firstTest cases 2
Test cases 70§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 29
RelationTest::testAnOptionalChildMayEndUpWithNoRowscallsRelationTest::testAnOptionalOneToOneChildRangesFromNoneToOnecallsRelationTest::testAOneToOneChildIsCappedAtOneRowcallsRelationTest::testASelfReferenceNamesItsTableOncecallsRelationTest::testBothSidesAreRequiredByDefaultcallsRelationTest::testChildIsCollectionOnlyOneToOneHoldsASingleChildRowcallsRelationTest::testChildIsOptionalAMarkerNextToTheChildMakesTheChildOptionalcallsRelationTest::testColumnMapPairsCompositeKeysPositionallycallsRelationTest::testColumnMapPointsChildColumnsAtParentColumnscallsRelationTest::testColumnMapReadsTheSameWrittenEitherWaycallsRelationTest::testKeepsTheSidesInTheOrderTheyWereWrittencallsRelationTest::testManyToOneCanMarkTheParentOptionalcallsRelationTest::testManyToOneDescribesTheSameShapeWrittenBackwardscallsRelationTest::testManyToOneLeavesBothSidesRequiredByDefaultcallsRelationTest::testManyToOneMarksOnlyTheRightSideOptionalcallsRelationTest::testMaximumChildRowsACollectionChildHasNoUpperBoundcallsRelationTest::testMinimumChildRowsARequiredChildIsGeneratedEvenWhenNoneAreGivencallsRelationTest::testNamedConstructorsAlsoTakeColumnRefscallsRelationTest::testNamedConstructorsBuildEachOperatorcallsRelationTest::testNamedConstructorsLeaveTheLeftSideRequiredcallsRelationTest::testNamedConstructorsReadEndpointsWrittenAsStringscallsRelationTest::testOneToManyCanMarkTheChildOptionalcallsRelationTest::testOneToManyLeavesBothSidesRequiredByDefaultcallsRelationTest::testOneToManyMakesTheLeftSideTheParentcallsRelationTest::testOneToManyMarksOnlyTheRightSideOptionalcallsRelationTest::testOneToOneLeavesBothSidesRequiredByDefaultcallsRelationTest::testOneToOneMarksOnlyTheRightSideOptionalcallsRelationTest::testParentIsOptionalAMarkerNextToTheParentMakesTheParentOptionalcallsRelationTest::testTablesListsBothEndscalls
Other tests reaching this symbol 41
PostgreSqlEndToEndTestcallsSqliteIntegrationTestcallsConnectedTablesTestcallsOverrideSpecsTestcallsRelationCountsTest::testResolveCountHonorsExplicitRowsAndCardinalitycallsRelationProjectionTest::testIsAlreadyLinkedRequiresEveryCompositeColumncallsRelationProjectionTest::testProjectMapsCompositeKeysWithoutUnrelatedColumnscallsRowMaterializerTestcallsGenerationRunTestcallsPlanGeneratorTestcallsPlanSchemaExceptionTestcallsPlanSchemaValidatorTestcallsEndpointValidatorTestcallsFixtureProviderTestcallsConstructorHydrationTestcallsPropertyHydrationTestcallsColumnRefTestcallsFixturePlanTest::testAPlanBuiltFromAKeyedSpreadCanStillBeExtendedcallsFixturePlanTest::testAStringPartNamesAStandaloneTablecallsFixturePlanTest::testOfAcceptsRelationsWithoutAStringcallsFixturePlanTest::testPartsSpreadFromAKeyedArrayAreStillReadInOrdercallsFixturePlanTest::testWithRelationAddsARelationDirectlycallsPlanStatementsTestcallsRelationCursorTestcallsRelationReaderTest::testParseStatementExpandsGroupedTargetscallsPlanParserTestcallsPlanPrinterTest::testPrintRelationIncludesOptionalEndpointMarkerscallsPlanPrinterTest::testPrintsASingleRelationWithoutAPlancallsPlanStructureExceptionTestcallsPlanSyntaxExceptionTestcallsPlanTablesTestcallsRelationGroupsTest::testGroupCombinesOnlyMatchingLeftEndpointscallsRelationGroupsTest::testGroupKeyIncludesOptionalitycallsRelationGroupsTest::testOperatorPreservesBothMarkerscallsStatementPrinterTest::testPrintGroupUsesCompactTargetsOnlyForMultipleRelationscallsPlanValidationTest::testRejectColumnsBoundTwiceAcceptsDistinctForeignKeyscallsPlanValidationTest::testRejectUnboundedSelfReferencesAcceptsOptionalChildrencallsPlanValidationTest::testSortByDependencyPreservesIndependentOrdercallsPlanValidationTest::testWaitsForAnyChecksOnlyPendingParentscallsTableNameTestcallsSqlSchemaProviderTestcalls
Relations§
Instantiated in 1
Static calls 3
- static-call SqlFixture\Plan\FixturePlan::withOneToMany() packages/sql-fixture/src/Plan/FixturePlan.php:144
- static-call SqlFixture\Plan\FixturePlan::withManyToOne() packages/sql-fixture/src/Plan/FixturePlan.php:155
- static-call SqlFixture\Plan\FixturePlan::withOneToOne() packages/sql-fixture/src/Plan/FixturePlan.php:166
Method calls 12
- method-call SqlFixture\Fixture\Generation\RelationCounts::resolveCount() packages/sql-fixture/src/Fixture/Generation/RelationCounts.php:36
- method-call SqlFixture\Fixture\Generation\RelationCounts::resolveCount() packages/sql-fixture/src/Fixture/Generation/RelationCounts.php:37
- method-call SqlFixture\Fixture\Generation\RelationProjection::isAlreadyLinked() packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:41
- method-call SqlFixture\Fixture\Generation\RelationProjection::project() packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:59
- method-call SqlFixture\Fixture\Generation\RelationProjection::project() packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:61
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toParent() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:133
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toParent() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:133
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toParent() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:137
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toChildren() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:152
- method-call SqlFixture\Fixture\Generation\RowMaterializer::toChildren() packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:159
- method-call SqlFixture\Plan\FixturePlan::dependenciesOf() packages/sql-fixture/src/Plan/FixturePlan.php:217
- method-call SqlFixture\Plan\FixturePlan::dependentsOf() packages/sql-fixture/src/Plan/FixturePlan.php:230
Type checks 1
Type declarations 16
- type SqlFixture\Fixture\Generation\RelationCounts packages/sql-fixture/src/Fixture/Generation/RelationCounts.php:30
- type SqlFixture\Fixture\Generation\RelationProjection packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:39
- type SqlFixture\Fixture\Generation\RelationProjection packages/sql-fixture/src/Fixture/Generation/RelationProjection.php:55
- type SqlFixture\Fixture\Generation\RowMaterializer packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:41
- type SqlFixture\Fixture\Generation\RowMaterializer packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:63
- type SqlFixture\Fixture\Generation\RowMaterializer packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:81
- type SqlFixture\Fixture\Generation\RowMaterializer packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:124
- type SqlFixture\Fixture\Generation\RowMaterializer packages/sql-fixture/src/Fixture/Generation/RowMaterializer.php:147
- type SqlFixture\Plan\FixturePlan packages/sql-fixture/src/Plan/FixturePlan.php:75
- type SqlFixture\Plan\FixturePlan packages/sql-fixture/src/Plan/FixturePlan.php:131
- type SqlFixture\Plan\FixturePlan::dependenciesOf() packages/sql-fixture/src/Plan/FixturePlan.php:217
- type SqlFixture\Plan\FixturePlan::dependentsOf() packages/sql-fixture/src/Plan/FixturePlan.php:230
- type SqlFixture\Plan\PlanPrinter packages/sql-fixture/src/Plan/PlanPrinter.php:37
- type SqlFixture\Plan\Printing\RelationGroups packages/sql-fixture/src/Plan/Printing/RelationGroups.php:36
- type SqlFixture\Plan\Printing\RelationGroups packages/sql-fixture/src/Plan/Printing/RelationGroups.php:44
- type SqlFixture\Plan\Printing\StatementPrinter::printGroup() packages/sql-fixture/src/Plan/Printing/StatementPrinter.php:23