Skip to content

Commit 29a9903

Browse files
committed
feat: Implement OneToOne entity
And do a lot of refactoring Signed-off-by: Carl Schwan <carlschwan@kde.org>
1 parent 85618b7 commit 29a9903

18 files changed

Lines changed: 906 additions & 522 deletions

File tree

‎apps/comments/composer/composer/installed.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'name' => '__root__',
44
'pretty_version' => 'dev-master',
55
'version' => 'dev-master',
6-
'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
6+
'reference' => '85618b795280107ce542bff646bc0957bc09a452',
77
'type' => 'library',
88
'install_path' => __DIR__ . '/../',
99
'aliases' => array(),
@@ -13,7 +13,7 @@
1313
'__root__' => array(
1414
'pretty_version' => 'dev-master',
1515
'version' => 'dev-master',
16-
'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
16+
'reference' => '85618b795280107ce542bff646bc0957bc09a452',
1717
'type' => 'library',
1818
'install_path' => __DIR__ . '/../',
1919
'aliases' => array(),

‎apps/twofactor_backupcodes/lib/Db/BackupCode.php‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@
99

1010
namespace OCA\TwoFactorBackupCodes\Db;
1111

12-
use OCP\AppFramework\Db\Attribute\Column;
13-
use OCP\AppFramework\Db\Attribute\Entity;
14-
use OCP\AppFramework\Db\Attribute\Id;
15-
use OCP\AppFramework\Db\Attribute\Table;
12+
use OCP\AppFramework\ORM\Attribute\Column;
13+
use OCP\AppFramework\ORM\Attribute\Entity;
14+
use OCP\AppFramework\ORM\Attribute\Id;
1615
use OCP\DB\Types;
1716
use OCP\Snowflake\IGenerator;
1817

19-
#[Entity]
20-
#[Table(name: 'twofactor_backupcodes')]
18+
#[Entity(name: 'twofactor_backupcodes')]
2119
final class BackupCode {
2220
#[Id(generatorClass: IGenerator::class)]
2321
#[Column(name: 'id', type: Types::STRING, length: 64, nullable: false)]

‎apps/twofactor_backupcodes/lib/Db/BackupCodeMapper.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace OCA\TwoFactorBackupCodes\Db;
1111

12-
use OCP\AppFramework\Db\Repository;
12+
use OCP\AppFramework\ORM\Repository;
1313
use OCP\IDBConnection;
1414
use OCP\IUser;
1515

‎lib/composer/composer/autoload_classmap.php‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,11 @@
7676
'OCP\\AppFramework\\Bootstrap\\IBootstrap' => $baseDir . '/lib/public/AppFramework/Bootstrap/IBootstrap.php',
7777
'OCP\\AppFramework\\Bootstrap\\IRegistrationContext' => $baseDir . '/lib/public/AppFramework/Bootstrap/IRegistrationContext.php',
7878
'OCP\\AppFramework\\Controller' => $baseDir . '/lib/public/AppFramework/Controller.php',
79-
'OCP\\AppFramework\\Db\\Attribute\\Column' => $baseDir . '/lib/public/AppFramework/Db/Attribute/Column.php',
80-
'OCP\\AppFramework\\Db\\Attribute\\Entity' => $baseDir . '/lib/public/AppFramework/Db/Attribute/Entity.php',
81-
'OCP\\AppFramework\\Db\\Attribute\\Id' => $baseDir . '/lib/public/AppFramework/Db/Attribute/Id.php',
82-
'OCP\\AppFramework\\Db\\Attribute\\Table' => $baseDir . '/lib/public/AppFramework/Db/Attribute/Table.php',
8379
'OCP\\AppFramework\\Db\\DoesNotExistException' => $baseDir . '/lib/public/AppFramework/Db/DoesNotExistException.php',
8480
'OCP\\AppFramework\\Db\\Entity' => $baseDir . '/lib/public/AppFramework/Db/Entity.php',
8581
'OCP\\AppFramework\\Db\\IMapperException' => $baseDir . '/lib/public/AppFramework/Db/IMapperException.php',
8682
'OCP\\AppFramework\\Db\\MultipleObjectsReturnedException' => $baseDir . '/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php',
8783
'OCP\\AppFramework\\Db\\QBMapper' => $baseDir . '/lib/public/AppFramework/Db/QBMapper.php',
88-
'OCP\\AppFramework\\Db\\Repository' => $baseDir . '/lib/public/AppFramework/Db/Repository.php',
8984
'OCP\\AppFramework\\Db\\SnowflakeAwareEntity' => $baseDir . '/lib/public/AppFramework/Db/SnowflakeAwareEntity.php',
9085
'OCP\\AppFramework\\Db\\TTransactional' => $baseDir . '/lib/public/AppFramework/Db/TTransactional.php',
9186
'OCP\\AppFramework\\Http' => $baseDir . '/lib/public/AppFramework/Http.php',
@@ -151,6 +146,12 @@
151146
'OCP\\AppFramework\\OCS\\OCSForbiddenException' => $baseDir . '/lib/public/AppFramework/OCS/OCSForbiddenException.php',
152147
'OCP\\AppFramework\\OCS\\OCSNotFoundException' => $baseDir . '/lib/public/AppFramework/OCS/OCSNotFoundException.php',
153148
'OCP\\AppFramework\\OCS\\OCSPreconditionFailedException' => $baseDir . '/lib/public/AppFramework/OCS/OCSPreconditionFailedException.php',
149+
'OCP\\AppFramework\\ORM\\Attribute\\Column' => $baseDir . '/lib/public/AppFramework/ORM/Attribute/Column.php',
150+
'OCP\\AppFramework\\ORM\\Attribute\\Entity' => $baseDir . '/lib/public/AppFramework/ORM/Attribute/Entity.php',
151+
'OCP\\AppFramework\\ORM\\Attribute\\Id' => $baseDir . '/lib/public/AppFramework/ORM/Attribute/Id.php',
152+
'OCP\\AppFramework\\ORM\\Attribute\\JoinColumn' => $baseDir . '/lib/public/AppFramework/ORM/Attribute/JoinColumn.php',
153+
'OCP\\AppFramework\\ORM\\Attribute\\OneToOne' => $baseDir . '/lib/public/AppFramework/ORM/Attribute/OneToOne.php',
154+
'OCP\\AppFramework\\ORM\\Repository' => $baseDir . '/lib/public/AppFramework/ORM/Repository.php',
154155
'OCP\\AppFramework\\PublicShareController' => $baseDir . '/lib/public/AppFramework/PublicShareController.php',
155156
'OCP\\AppFramework\\QueryException' => $baseDir . '/lib/public/AppFramework/QueryException.php',
156157
'OCP\\AppFramework\\Services\\IAppConfig' => $baseDir . '/lib/public/AppFramework/Services/IAppConfig.php',
@@ -1138,6 +1139,9 @@
11381139
'OC\\AppFramework\\OCS\\BaseResponse' => $baseDir . '/lib/private/AppFramework/OCS/BaseResponse.php',
11391140
'OC\\AppFramework\\OCS\\V1Response' => $baseDir . '/lib/private/AppFramework/OCS/V1Response.php',
11401141
'OC\\AppFramework\\OCS\\V2Response' => $baseDir . '/lib/private/AppFramework/OCS/V2Response.php',
1142+
'OC\\AppFramework\\ORM\\EntityInfo' => $baseDir . '/lib/private/AppFramework/ORM/EntityInfo.php',
1143+
'OC\\AppFramework\\ORM\\EntityManager' => $baseDir . '/lib/private/AppFramework/ORM/EntityManager.php',
1144+
'OC\\AppFramework\\ORM\\PropertyAttributes' => $baseDir . '/lib/private/AppFramework/ORM/PropertyAttributes.php',
11411145
'OC\\AppFramework\\Routing\\RouteActionHandler' => $baseDir . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
11421146
'OC\\AppFramework\\Routing\\RouteParser' => $baseDir . '/lib/private/AppFramework/Routing/RouteParser.php',
11431147
'OC\\AppFramework\\ScopedPsrLogger' => $baseDir . '/lib/private/AppFramework/ScopedPsrLogger.php',

‎lib/composer/composer/autoload_static.php‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,11 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
117117
'OCP\\AppFramework\\Bootstrap\\IBootstrap' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Bootstrap/IBootstrap.php',
118118
'OCP\\AppFramework\\Bootstrap\\IRegistrationContext' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Bootstrap/IRegistrationContext.php',
119119
'OCP\\AppFramework\\Controller' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Controller.php',
120-
'OCP\\AppFramework\\Db\\Attribute\\Column' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Attribute/Column.php',
121-
'OCP\\AppFramework\\Db\\Attribute\\Entity' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Attribute/Entity.php',
122-
'OCP\\AppFramework\\Db\\Attribute\\Id' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Attribute/Id.php',
123-
'OCP\\AppFramework\\Db\\Attribute\\Table' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Attribute/Table.php',
124120
'OCP\\AppFramework\\Db\\DoesNotExistException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/DoesNotExistException.php',
125121
'OCP\\AppFramework\\Db\\Entity' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Entity.php',
126122
'OCP\\AppFramework\\Db\\IMapperException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/IMapperException.php',
127123
'OCP\\AppFramework\\Db\\MultipleObjectsReturnedException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php',
128124
'OCP\\AppFramework\\Db\\QBMapper' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/QBMapper.php',
129-
'OCP\\AppFramework\\Db\\Repository' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/Repository.php',
130125
'OCP\\AppFramework\\Db\\SnowflakeAwareEntity' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/SnowflakeAwareEntity.php',
131126
'OCP\\AppFramework\\Db\\TTransactional' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/TTransactional.php',
132127
'OCP\\AppFramework\\Http' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http.php',
@@ -192,6 +187,12 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
192187
'OCP\\AppFramework\\OCS\\OCSForbiddenException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/OCS/OCSForbiddenException.php',
193188
'OCP\\AppFramework\\OCS\\OCSNotFoundException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/OCS/OCSNotFoundException.php',
194189
'OCP\\AppFramework\\OCS\\OCSPreconditionFailedException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/OCS/OCSPreconditionFailedException.php',
190+
'OCP\\AppFramework\\ORM\\Attribute\\Column' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Attribute/Column.php',
191+
'OCP\\AppFramework\\ORM\\Attribute\\Entity' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Attribute/Entity.php',
192+
'OCP\\AppFramework\\ORM\\Attribute\\Id' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Attribute/Id.php',
193+
'OCP\\AppFramework\\ORM\\Attribute\\JoinColumn' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Attribute/JoinColumn.php',
194+
'OCP\\AppFramework\\ORM\\Attribute\\OneToOne' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Attribute/OneToOne.php',
195+
'OCP\\AppFramework\\ORM\\Repository' => __DIR__ . '/../../..' . '/lib/public/AppFramework/ORM/Repository.php',
195196
'OCP\\AppFramework\\PublicShareController' => __DIR__ . '/../../..' . '/lib/public/AppFramework/PublicShareController.php',
196197
'OCP\\AppFramework\\QueryException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/QueryException.php',
197198
'OCP\\AppFramework\\Services\\IAppConfig' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Services/IAppConfig.php',
@@ -1179,6 +1180,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
11791180
'OC\\AppFramework\\OCS\\BaseResponse' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/BaseResponse.php',
11801181
'OC\\AppFramework\\OCS\\V1Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V1Response.php',
11811182
'OC\\AppFramework\\OCS\\V2Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V2Response.php',
1183+
'OC\\AppFramework\\ORM\\EntityInfo' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ORM/EntityInfo.php',
1184+
'OC\\AppFramework\\ORM\\EntityManager' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ORM/EntityManager.php',
1185+
'OC\\AppFramework\\ORM\\PropertyAttributes' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ORM/PropertyAttributes.php',
11821186
'OC\\AppFramework\\Routing\\RouteActionHandler' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
11831187
'OC\\AppFramework\\Routing\\RouteParser' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteParser.php',
11841188
'OC\\AppFramework\\ScopedPsrLogger' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ScopedPsrLogger.php',
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
// SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
6+
// SPDX-License-Identifier: AGPL-3.0-or-later
7+
8+
namespace OC\AppFramework\ORM;
9+
10+
use OCP\AppFramework\ORM\Attribute\Column;
11+
use OCP\AppFramework\ORM\Attribute\Entity;
12+
use OCP\AppFramework\ORM\Attribute\Id;
13+
use OCP\AppFramework\ORM\Attribute\JoinColumn;
14+
use OCP\AppFramework\ORM\Attribute\OneToOne;
15+
16+
/**
17+
* @template T
18+
* @internal
19+
*/
20+
class EntityInfo {
21+
public readonly string $tableName;
22+
23+
/** @var array<string, string> */
24+
public array $mappingColumnToTypes = [];
25+
26+
/** @var array<string, string> */
27+
public array $mappingColumnToProperty = [];
28+
29+
/** @var array<string, string> */
30+
public array $mappingPropertyToColumn = [];
31+
32+
/** @var \ReflectionClass<T> */
33+
public readonly \ReflectionClass $reflection;
34+
35+
public ?\ReflectionProperty $idProperty = null;
36+
37+
/**
38+
* @var list<PropertyAttributes> $propertiesAttributes
39+
*/
40+
public array $propertiesAttributes = [];
41+
42+
public function __construct(
43+
public readonly string $entityClass,
44+
) {
45+
$this->reflection = new \ReflectionClass($entityClass);
46+
47+
$entities = $this->reflection->getAttributes(Entity::class, \ReflectionAttribute::IS_INSTANCEOF);
48+
if (count($entities) !== 1) {
49+
throw new \InvalidArgumentException('The given entity is missing or has too many of the required #[Entity] attribute');
50+
}
51+
52+
$this->tableName = $entities[0]->newInstance()->name;
53+
54+
foreach ($this->reflection->getProperties() as $property) {
55+
$attributes = $property->getAttributes();
56+
$propertyAttributes = new PropertyAttributes($property);
57+
58+
foreach ($attributes as $attribute) {
59+
$instance = $attribute->newInstance();
60+
if ($instance instanceof Column) {
61+
$propertyAttributes->column = $instance;
62+
$this->mappingColumnToTypes[$instance->name] = $instance->type;
63+
$this->mappingColumnToProperty[$instance->name] = $property->getName();
64+
$this->mappingPropertyToColumn[$property->getName()] = $instance->name;
65+
} elseif ($instance instanceof Id) {
66+
$propertyAttributes->id = $instance;
67+
$this->idProperty = $property;
68+
} elseif ($instance instanceof OneToOne) {
69+
$propertyAttributes->oneToOne = $instance;
70+
} elseif ($instance instanceof JoinColumn) {
71+
$propertyAttributes->joinColumn = $instance;
72+
}
73+
}
74+
75+
if ($propertyAttributes->id !== null && $propertyAttributes->column === null) {
76+
throw new \RuntimeException($this->entityClass . ' has a Id attribute on ' . $property->getName() . ' but not the corresponding required Column attribute.');
77+
}
78+
79+
$this->propertiesAttributes[] = $propertyAttributes;
80+
}
81+
82+
if ($this->idProperty === null) {
83+
throw new \RuntimeException($this->entityClass . ' does not have a primary key. This is not supported for repositories backed tables.');
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)