33namespace Tempest \Database \Builder ;
44
55use ReflectionException ;
6+ use Tempest \Database \BelongsTo ;
67use Tempest \Database \Config \DatabaseConfig ;
8+ use Tempest \Database \HasMany ;
79use Tempest \Database \HasOne ;
810use Tempest \Database \Table ;
911use Tempest \Reflection \ClassReflector ;
1214use Tempest \Validation \Validator ;
1315
1416use function Tempest \get ;
17+ use function Tempest \Support \str ;
1518
1619final class ModelInspector
1720{
1821 private ?ClassReflector $ modelClass ;
1922
2023 public function __construct (
2124 private object |string $ model ,
22- ) {
25+ )
26+ {
2327 if ($ this ->model instanceof ClassReflector) {
2428 $ this ->modelClass = $ this ->model ;
2529 } else {
@@ -70,7 +74,7 @@ public function getPropertyValues(): array
7074 continue ;
7175 }
7276
73- if ($ this ->isHasManyRelation ($ property ->getName ()) || $ this ->isHasOneRelation ($ property ->getName ())) {
77+ if ($ this ->getHasMany ($ property ->getName ()) || $ this ->getHasOne ($ property ->getName ())) {
7478 continue ;
7579 }
7680
@@ -82,42 +86,91 @@ public function getPropertyValues(): array
8286 return $ values ;
8387 }
8488
85- public function isHasManyRelation (string $ name ): bool
89+ public function getBelongsTo (string $ name ): ? BelongsTo
8690 {
8791 if (! $ this ->isObjectModel ()) {
88- return false ;
92+ return null ;
93+ }
94+
95+ $ singularizedName = str ($ name )->singularizeLastWord ();
96+
97+ if (! $ singularizedName ->equals ($ name )) {
98+ return $ this ->getBelongsTo ($ singularizedName );
8999 }
90100
91101 if (! $ this ->modelClass ->hasProperty ($ name )) {
92- return false ;
102+ return null ;
93103 }
94104
95105 $ property = $ this ->modelClass ->getProperty ($ name );
96106
97- if ($ property ->getIterableType ()?->isRelation()) {
98- return true ;
107+ if ($ belongsTo = $ property ->getAttribute (BelongsTo::class)) {
108+ return $ belongsTo ;
109+ }
110+
111+ if (! $ property ->getType ()->isRelation ()) {
112+ return null ;
113+ }
114+
115+ if ($ property ->hasAttribute (HasOne::class)) {
116+ return null ;
99117 }
100118
101- return false ;
119+ $ belongsTo = new BelongsTo ($ property ->getName ());
120+ $ belongsTo ->property = $ property ;
121+
122+ return $ belongsTo ;
102123 }
103124
104- public function isHasOneRelation (string $ name ): bool
125+ public function getHasOne (string $ name ): ? HasOne
105126 {
106127 if (! $ this ->isObjectModel ()) {
107- return false ;
128+ return null ;
129+ }
130+
131+ $ singularizedName = str ($ name )->singularizeLastWord ();
132+
133+ if (! $ singularizedName ->equals ($ name )) {
134+ return $ this ->getHasOne ($ singularizedName );
108135 }
109136
110137 if (! $ this ->modelClass ->hasProperty ($ name )) {
111- return false ;
138+ return null ;
112139 }
113140
114141 $ property = $ this ->modelClass ->getProperty ($ name );
115142
116- if ($ property ->hasAttribute (HasOne::class)) {
117- return true ;
143+ if ($ hasOne = $ property ->getAttribute (HasOne::class)) {
144+ return $ hasOne ;
145+ }
146+
147+ return null ;
148+ }
149+
150+ public function getHasMany (string $ name ): ?HasMany
151+ {
152+ if (! $ this ->isObjectModel ()) {
153+ return null ;
154+ }
155+
156+ if (! $ this ->modelClass ->hasProperty ($ name )) {
157+ return null ;
158+ }
159+
160+ $ property = $ this ->modelClass ->getProperty ($ name );
161+
162+ if ($ hasMany = $ property ->getAttribute (HasMany::class)) {
163+ return $ hasMany ;
118164 }
119165
120- return false ;
166+ if (! $ property ->getIterableType ()?->isRelation()) {
167+ return null ;
168+ }
169+
170+ $ hasMany = new HasMany (inversePropertyName: $ property ->getName ());
171+ $ hasMany ->property = $ property ;
172+
173+ return $ hasMany ;
121174 }
122175
123176 public function validate (mixed ...$ data ): void
@@ -159,4 +212,14 @@ public function getName(): string
159212
160213 return $ this ->modelClass ;
161214 }
215+
216+ public function getPrimaryKey (): string
217+ {
218+ return 'id ' ;
219+ }
220+
221+ public function getPrimaryField (): string
222+ {
223+ return $ this ->getTableDefinition ()->name . '. ' . $ this ->getPrimaryKey ();
224+ }
162225}
0 commit comments