66use Tempest \Database \BelongsTo ;
77use Tempest \Database \Config \DatabaseConfig ;
88use Tempest \Database \Eager ;
9+ use Tempest \Database \Exceptions \ModelDidNotHavePrimaryColumn ;
10+ use Tempest \Database \Exceptions \ModelHadMultiplePrimaryColumns ;
911use Tempest \Database \HasMany ;
1012use Tempest \Database \HasOne ;
11- use Tempest \Database \Id ;
13+ use Tempest \Database \PrimaryKey ;
1214use Tempest \Database \Relation ;
1315use Tempest \Database \Table ;
1416use Tempest \Database \Virtual ;
2123use Tempest \Validation \SkipValidation ;
2224use Tempest \Validation \Validator ;
2325
24- use function Tempest \Database \model ;
26+ use function Tempest \Database \inspect ;
2527use function Tempest \get ;
2628use function Tempest \Support \arr ;
2729use function Tempest \Support \str ;
@@ -292,7 +294,7 @@ public function resolveRelations(string $relationString, string $parent = ''): a
292294
293295 unset($ relationNames [0 ]);
294296
295- $ relationModel = model ($ currentRelation );
297+ $ relationModel = inspect ($ currentRelation );
296298
297299 $ newRelationString = implode ('. ' , $ relationNames );
298300 $ currentRelation ->setParent ($ parent );
@@ -334,7 +336,7 @@ public function resolveEagerRelations(string $parent = ''): array
334336 $ currentRelationName ,
335337 ), '. ' );
336338
337- foreach (model ($ currentRelation )->resolveEagerRelations ($ newParent ) as $ name => $ nestedEagerRelation ) {
339+ foreach (inspect ($ currentRelation )->resolveEagerRelations ($ newParent ) as $ name => $ nestedEagerRelation ) {
338340 $ relations [$ name ] = $ nestedEagerRelation ;
339341 }
340342 }
@@ -357,6 +359,10 @@ public function validate(mixed ...$data): void
357359 continue ;
358360 }
359361
362+ if ($ property ->getType ()->getName () === PrimaryKey::class) {
363+ continue ;
364+ }
365+
360366 $ failingRulesForProperty = $ this ->validator ->validateValueForProperty (
361367 $ property ,
362368 $ value ,
@@ -381,17 +387,45 @@ public function getName(): string
381387 return $ this ->instance ;
382388 }
383389
384- public function getPrimaryFieldName (): string
390+ public function getQualifiedPrimaryKey (): ? string
385391 {
386- return $ this ->getTableDefinition ()->name . '. ' . $ this ->getPrimaryKey ();
392+ $ primaryKey = $ this ->getPrimaryKey ();
393+
394+ return $ primaryKey !== null
395+ ? ($ this ->getTableDefinition ()->name . '. ' . $ primaryKey )
396+ : null ;
387397 }
388398
389- public function getPrimaryKey (): string
399+ public function getPrimaryKey (): ? string
390400 {
391- return 'id ' ;
401+ return $ this ->getPrimaryKeyProperty ()?->getName();
402+ }
403+
404+ public function hasPrimaryKey (): bool
405+ {
406+ return $ this ->getPrimaryKeyProperty () !== null ;
407+ }
408+
409+ public function getPrimaryKeyProperty (): ?PropertyReflector
410+ {
411+ if (! $ this ->isObjectModel ()) {
412+ return null ;
413+ }
414+
415+ $ primaryKeys = arr ($ this ->reflector ->getProperties ())
416+ ->filter (fn (PropertyReflector $ property ) => $ property ->getType ()->matches (PrimaryKey::class));
417+
418+ return match ($ primaryKeys ->count ()) {
419+ 0 => null ,
420+ 1 => $ primaryKeys ->first (),
421+ default => throw ModelHadMultiplePrimaryColumns::found (
422+ model: $ this ->model ,
423+ properties: $ primaryKeys ->map (fn (PropertyReflector $ property ) => $ property ->getName ())->toArray (),
424+ ),
425+ };
392426 }
393427
394- public function getPrimaryKeyValue (): ?Id
428+ public function getPrimaryKeyValue (): ?PrimaryKey
395429 {
396430 if (! $ this ->isObjectModel ()) {
397431 return null ;
@@ -401,6 +435,16 @@ public function getPrimaryKeyValue(): ?Id
401435 return null ;
402436 }
403437
404- return $ this ->instance ->{$ this ->getPrimaryKey ()};
438+ $ primaryKeyProperty = $ this ->getPrimaryKeyProperty ();
439+
440+ if ($ primaryKeyProperty === null ) {
441+ return null ;
442+ }
443+
444+ if (! $ primaryKeyProperty ->isInitialized ($ this ->instance )) {
445+ return null ;
446+ }
447+
448+ return $ primaryKeyProperty ->getValue ($ this ->instance );
405449 }
406450}
0 commit comments