@@ -1519,6 +1519,205 @@ public function testRecreateManyToManyOneWayRelationshipFromParent(): void
15191519 $ database ->deleteCollection ('two ' );
15201520 }
15211521
1522+ public function testSelectManyToMany (): void
1523+ {
1524+ /** @var Database $database */
1525+ $ database = static ::getDatabase ();
1526+
1527+ if (!$ database ->getAdapter ()->getSupportForRelationships ()) {
1528+ $ this ->expectNotToPerformAssertions ();
1529+ return ;
1530+ }
1531+
1532+ $ database ->createCollection ('select_m2m_collection1 ' );
1533+ $ database ->createCollection ('select_m2m_collection2 ' );
1534+
1535+ $ database ->createAttribute ('select_m2m_collection1 ' , 'name ' , Database::VAR_STRING , 255 , true );
1536+ $ database ->createAttribute ('select_m2m_collection1 ' , 'type ' , Database::VAR_STRING , 255 , true );
1537+ $ database ->createAttribute ('select_m2m_collection2 ' , 'name ' , Database::VAR_STRING , 255 , true );
1538+ $ database ->createAttribute ('select_m2m_collection2 ' , 'type ' , Database::VAR_STRING , 255 , true );
1539+
1540+ // Many-to-Many Relationship
1541+ $ database ->createRelationship (
1542+ collection: 'select_m2m_collection1 ' ,
1543+ relatedCollection: 'select_m2m_collection2 ' ,
1544+ type: Database::RELATION_MANY_TO_MANY ,
1545+ twoWay: true
1546+ );
1547+
1548+ // Create documents in the first collection
1549+ $ doc1 = $ database ->createDocument ('select_m2m_collection1 ' , new Document ([
1550+ '$id ' => 'doc1 ' ,
1551+ '$permissions ' => [
1552+ Permission::read (Role::any ()),
1553+ Permission::update (Role::any ()),
1554+ Permission::delete (Role::any ()),
1555+ ],
1556+ 'name ' => 'Document 1 ' ,
1557+ 'type ' => 'Type A ' ,
1558+ 'select_m2m_collection2 ' => [
1559+ [
1560+ '$id ' => 'related_doc1 ' ,
1561+ '$permissions ' => [
1562+ Permission::read (Role::any ()),
1563+ Permission::update (Role::any ()),
1564+ Permission::delete (Role::any ()),
1565+ ],
1566+ 'name ' => 'Related Document 1 ' ,
1567+ 'type ' => 'Type B ' ,
1568+ ],
1569+ [
1570+ '$id ' => 'related_doc2 ' ,
1571+ '$permissions ' => [
1572+ Permission::read (Role::any ()),
1573+ Permission::update (Role::any ()),
1574+ Permission::delete (Role::any ()),
1575+ ],
1576+ 'name ' => 'Related Document 2 ' ,
1577+ 'type ' => 'Type C ' ,
1578+ ],
1579+ ],
1580+ ]));
1581+
1582+ // Use select query to get only name of the related documents
1583+ $ docs = $ database ->find ('select_m2m_collection1 ' , [
1584+ Query::select (['name ' , 'select_m2m_collection2.name ' ]),
1585+ ]);
1586+
1587+ $ this ->assertCount (1 , $ docs );
1588+ $ this ->assertEquals ('Document 1 ' , $ docs [0 ]->getAttribute ('name ' ));
1589+ $ this ->assertArrayNotHasKey ('type ' , $ docs [0 ]);
1590+
1591+ $ relatedDocs = $ docs [0 ]->getAttribute ('select_m2m_collection2 ' );
1592+
1593+ $ this ->assertCount (2 , $ relatedDocs );
1594+ $ this ->assertEquals ('Related Document 1 ' , $ relatedDocs [0 ]->getAttribute ('name ' ));
1595+ $ this ->assertEquals ('Related Document 2 ' , $ relatedDocs [1 ]->getAttribute ('name ' ));
1596+ $ this ->assertArrayNotHasKey ('type ' , $ relatedDocs [0 ]);
1597+ $ this ->assertArrayNotHasKey ('type ' , $ relatedDocs [1 ]);
1598+ }
1599+
1600+ public function testSelectAcrossMultipleCollections (): void
1601+ {
1602+ /** @var Database $database */
1603+ $ database = static ::getDatabase ();
1604+
1605+ if (!$ database ->getAdapter ()->getSupportForRelationships ()) {
1606+ $ this ->expectNotToPerformAssertions ();
1607+ return ;
1608+ }
1609+
1610+ // Create collections
1611+ $ database ->createCollection ('artists ' , permissions: [
1612+ Permission::read (Role::any ()),
1613+ Permission::create (Role::any ()),
1614+ Permission::update (Role::any ()),
1615+ Permission::delete (Role::any ())
1616+ ], documentSecurity: false );
1617+ $ database ->createCollection ('albums ' , permissions: [
1618+ Permission::read (Role::any ()),
1619+ Permission::create (Role::any ()),
1620+ Permission::update (Role::any ()),
1621+ Permission::delete (Role::any ())
1622+ ], documentSecurity: false );
1623+ $ database ->createCollection ('tracks ' , permissions: [
1624+ Permission::read (Role::any ()),
1625+ Permission::create (Role::any ()),
1626+ Permission::update (Role::any ()),
1627+ Permission::delete (Role::any ())
1628+ ], documentSecurity: false );
1629+
1630+ // Add attributes
1631+ $ database ->createAttribute ('artists ' , 'name ' , Database::VAR_STRING , 255 , true );
1632+ $ database ->createAttribute ('albums ' , 'name ' , Database::VAR_STRING , 255 , true );
1633+ $ database ->createAttribute ('tracks ' , 'title ' , Database::VAR_STRING , 255 , true );
1634+ $ database ->createAttribute ('tracks ' , 'duration ' , Database::VAR_INTEGER , 0 , true );
1635+
1636+ // Create relationships
1637+ $ database ->createRelationship (
1638+ collection: 'artists ' ,
1639+ relatedCollection: 'albums ' ,
1640+ type: Database::RELATION_MANY_TO_MANY ,
1641+ twoWay: true
1642+ );
1643+
1644+ $ database ->createRelationship (
1645+ collection: 'albums ' ,
1646+ relatedCollection: 'tracks ' ,
1647+ type: Database::RELATION_MANY_TO_MANY ,
1648+ twoWay: true
1649+ );
1650+
1651+ // Create documents
1652+ $ database ->createDocument ('artists ' , new Document ([
1653+ '$id ' => 'artist1 ' ,
1654+ 'name ' => 'The Great Artist ' ,
1655+ 'albums ' => [
1656+ [
1657+ '$id ' => 'album1 ' ,
1658+ 'name ' => 'First Album ' ,
1659+ 'tracks ' => [
1660+ [
1661+ '$id ' => 'track1 ' ,
1662+ 'title ' => 'Hit Song 1 ' ,
1663+ 'duration ' => 180 ,
1664+ ],
1665+ [
1666+ '$id ' => 'track2 ' ,
1667+ 'title ' => 'Hit Song 2 ' ,
1668+ 'duration ' => 220 ,
1669+ ]
1670+ ]
1671+ ],
1672+ [
1673+ '$id ' => 'album2 ' ,
1674+ 'name ' => 'Second Album ' ,
1675+ 'tracks ' => [
1676+ [
1677+ '$id ' => 'track3 ' ,
1678+ 'title ' => 'Ballad 3 ' ,
1679+ 'duration ' => 240 ,
1680+ ]
1681+ ]
1682+ ]
1683+ ]
1684+ ]));
1685+
1686+ // Query with nested select
1687+ $ artists = $ database ->find ('artists ' , [
1688+ Query::select (['name ' , 'albums.name ' , 'albums.tracks.title ' ])
1689+ ]);
1690+
1691+ $ this ->assertCount (1 , $ artists );
1692+ $ artist = $ artists [0 ];
1693+ $ this ->assertEquals ('The Great Artist ' , $ artist ->getAttribute ('name ' ));
1694+ $ this ->assertArrayHasKey ('albums ' , $ artist ->getArrayCopy ());
1695+
1696+ $ albums = $ artist ->getAttribute ('albums ' );
1697+ $ this ->assertCount (2 , $ albums );
1698+
1699+ $ album1 = $ albums [0 ];
1700+ $ this ->assertEquals ('First Album ' , $ album1 ->getAttribute ('name ' ));
1701+ $ this ->assertArrayHasKey ('tracks ' , $ album1 ->getArrayCopy ());
1702+ $ this ->assertArrayNotHasKey ('artists ' , $ album1 ->getArrayCopy ());
1703+
1704+ $ album2 = $ albums [1 ];
1705+ $ this ->assertEquals ('Second Album ' , $ album2 ->getAttribute ('name ' ));
1706+ $ this ->assertArrayHasKey ('tracks ' , $ album2 ->getArrayCopy ());
1707+
1708+ $ album1Tracks = $ album1 ->getAttribute ('tracks ' );
1709+ $ this ->assertCount (2 , $ album1Tracks );
1710+ $ this ->assertEquals ('Hit Song 1 ' , $ album1Tracks [0 ]->getAttribute ('title ' ));
1711+ $ this ->assertArrayNotHasKey ('duration ' , $ album1Tracks [0 ]->getArrayCopy ());
1712+ $ this ->assertEquals ('Hit Song 2 ' , $ album1Tracks [1 ]->getAttribute ('title ' ));
1713+ $ this ->assertArrayNotHasKey ('duration ' , $ album1Tracks [1 ]->getArrayCopy ());
1714+
1715+ $ album2Tracks = $ album2 ->getAttribute ('tracks ' );
1716+ $ this ->assertCount (1 , $ album2Tracks );
1717+ $ this ->assertEquals ('Ballad 3 ' , $ album2Tracks [0 ]->getAttribute ('title ' ));
1718+ $ this ->assertArrayNotHasKey ('duration ' , $ album2Tracks [0 ]->getArrayCopy ());
1719+ }
1720+
15221721 public function testDeleteBulkDocumentsManyToManyRelationship (): void
15231722 {
15241723 /** @var Database $database */
0 commit comments