فهرست منبع

add schema handling to PHP ↔ DB converters

phpdevcommunity 3 هفته پیش
والد
کامیت
7314737073

+ 2 - 2
README.md

@@ -21,7 +21,7 @@ PaperORM is available via **Composer** and installs in seconds.
 
 ### 📦 Via Composer (recommended)
 ```bash
-composer require phpdevcommunity/paper-orm:1.0.19-alpha
+composer require phpdevcommunity/paper-orm:1.0.20-alpha
 ```  
 
 ### 🔧 Minimal Configuration
@@ -257,7 +257,7 @@ PaperORM est disponible via **Composer** et s'installe en quelques secondes.
 
 ### 📦 Via Composer (recommandé)
 ```bash
-composer require phpdevcommunity/paper-orm:1.0.19-alpha
+composer require phpdevcommunity/paper-orm:1.0.20-alpha
 ```  
 
 ### 🔧 Configuration minimale

+ 3 - 1
src/Hydrator/AbstractEntityHydrator.php

@@ -8,9 +8,11 @@ use PhpDevCommunity\PaperORM\Mapper\ColumnMapper;
 use PhpDevCommunity\PaperORM\Mapping\Column\JoinColumn;
 use PhpDevCommunity\PaperORM\Mapping\OneToMany;
 use PhpDevCommunity\PaperORM\Proxy\ProxyInterface;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
 
 abstract class AbstractEntityHydrator
 {
+    abstract protected function getSchema(): SchemaInterface;
     abstract protected function instantiate(string $class, array $data): object;
 
     /**
@@ -82,7 +84,7 @@ abstract class AbstractEntityHydrator
                 continue;
             }
 
-            $property->setValue($object, $column->convertToPHP($value));
+            $property->setValue($object, $column->convertToPHP($value, $this->getSchema()));
         }
 
         if ($object instanceof ProxyInterface) {

+ 6 - 3
src/Hydrator/ArrayHydrator.php

@@ -9,13 +9,16 @@ use PhpDevCommunity\PaperORM\Entity\EntityInterface;
 use PhpDevCommunity\PaperORM\Mapper\ColumnMapper;
 use PhpDevCommunity\PaperORM\Mapping\Column\JoinColumn;
 use PhpDevCommunity\PaperORM\Mapping\OneToMany;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
 use ReflectionClass;
 
 final class ArrayHydrator
 {
+    private SchemaInterface $schema;
 
-    public function __construct()
+    public function __construct(SchemaInterface $schema)
     {
+        $this->schema = $schema;
     }
 
     public function hydrate(string $object, array $data): array
@@ -64,9 +67,9 @@ final class ArrayHydrator
                 unset($storage);
                 continue;
             }
-            $value =  $column->convertToPHP($value);
+            $value =  $column->convertToPHP($value, $this->schema);
             if ($value instanceof \DateTimeInterface) {
-                $value = $column->convertToDatabase($value);
+                $value = $column->convertToDatabase($value, $this->schema);
             }
             $result[$propertyName] = $value;
         }

+ 9 - 1
src/Hydrator/EntityHydrator.php

@@ -12,15 +12,18 @@ use PhpDevCommunity\PaperORM\Mapping\Column\JoinColumn;
 use PhpDevCommunity\PaperORM\Mapping\OneToMany;
 use PhpDevCommunity\PaperORM\Proxy\ProxyFactory;
 use PhpDevCommunity\PaperORM\Proxy\ProxyInterface;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
 use ReflectionClass;
 
 final class EntityHydrator extends AbstractEntityHydrator
 {
     private EntityMemcachedCache $cache;
+    private SchemaInterface $schema;
 
-    public function __construct(EntityMemcachedCache $cache)
+    public function __construct(SchemaInterface $schema, EntityMemcachedCache $cache)
     {
         $this->cache = $cache;
+        $this->schema = $schema;
     }
 
     protected function instantiate(string $class, array $data): object
@@ -33,5 +36,10 @@ final class EntityHydrator extends AbstractEntityHydrator
 
         return $object;
     }
+
+    protected function getSchema(): SchemaInterface
+    {
+        return $this->schema;
+    }
 }
 

+ 14 - 0
src/Hydrator/ReadOnlyEntityHydrator.php

@@ -2,10 +2,24 @@
 
 namespace PhpDevCommunity\PaperORM\Hydrator;
 
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
+
 final class ReadOnlyEntityHydrator extends AbstractEntityHydrator
 {
+
+    private SchemaInterface $schema;
+
+    public function __construct(SchemaInterface $schema)
+    {
+        $this->schema = $schema;
+    }
     protected function instantiate(string $class, array $data): object
     {
         return new $class();
     }
+
+    protected function getSchema(): SchemaInterface
+    {
+        return $this->schema;
+    }
 }

+ 5 - 9
src/Mapping/Column/Column.php

@@ -3,6 +3,7 @@
 namespace PhpDevCommunity\PaperORM\Mapping\Column;
 
 use PhpDevCommunity\PaperORM\Mapping\Index;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
 use PhpDevCommunity\PaperORM\Tools\NamingStrategy;
 use PhpDevCommunity\PaperORM\Types\StringType;
 use PhpDevCommunity\PaperORM\Types\Type;
@@ -114,11 +115,6 @@ abstract class Column
         return $this->defaultValue;
     }
 
-    public function getDefaultValueToDatabase()
-    {
-        return $this->convertToDatabase($this->getDefaultValue());
-    }
-
 
     /**
      * Converts a value to its corresponding database representation.
@@ -127,11 +123,11 @@ abstract class Column
      * @return mixed The converted value.
      * @throws \ReflectionException
      */
-    final function convertToDatabase($value)
+    final function convertToDatabase($value, SchemaInterface $schema)
     {
         $type = $this->getType();
         if (is_subclass_of($type, Type::class)) {
-            $value = TypeFactory::create($type)->convertToDatabase($value);
+            $value = TypeFactory::create($schema, $type)->convertToDatabase($value);
         }
         return $value;
     }
@@ -143,11 +139,11 @@ abstract class Column
      * @return mixed The converted PHP value.
      * @throws \ReflectionException
      */
-    final function convertToPHP($value)
+    final function convertToPHP($value, SchemaInterface $schema)
     {
         $type = $this->getType();
         if (is_subclass_of($type, Type::class)) {
-            $value = TypeFactory::create($type)->convertToPHP($value);
+            $value = TypeFactory::create($schema, $type)->convertToPHP($value);
         }
         return $value;
     }

+ 3 - 3
src/Persistence/EntityPersistence.php

@@ -58,7 +58,7 @@ class EntityPersistence
         $qb = QueryBuilder::insert($schema->quote($tableName));
 
         $values = [];
-        foreach ((new SerializerToDb($entity))->serialize() as $key => $value) {
+        foreach ((new SerializerToDb($entity, $schema))->serialize() as $key => $value) {
             $qb->setValue($schema->quote($key), ":$key");
             $values[$key] = $value;
         }
@@ -67,7 +67,7 @@ class EntityPersistence
         $lastInsertId = $conn->getPdo()->lastInsertId();
         if ($rows > 0) {
             $primaryKeyColumn = ColumnMapper::getPrimaryKeyColumnName($entity);
-            (new ReadOnlyEntityHydrator())->hydrate($entity, [$primaryKeyColumn => $lastInsertId]);
+            (new ReadOnlyEntityHydrator($schema))->hydrate($entity, [$primaryKeyColumn => $lastInsertId]);
             $this->managed->attach($entity);
             if ($this->dispatcher) {
                 $this->dispatcher->dispatch(new PostCreateEvent($this->em, $entity));
@@ -113,7 +113,7 @@ class EntityPersistence
             );
 
         $values = [];
-        foreach ((new SerializerToDb($entity))->serialize($propertiesModified) as $key => $value) {
+        foreach ((new SerializerToDb($entity, $schema))->serialize($propertiesModified) as $key => $value) {
             $qb->set($schema->quote($key), ":$key");
             $values[$key] = $value;
         }

+ 3 - 3
src/Query/QueryBuilder.php

@@ -472,11 +472,11 @@ final class QueryBuilder
     private function hydrate(array $data, string $hydrationMode): array
     {
         if ($hydrationMode === self::HYDRATE_OBJECT) {
-            $hydrator = new EntityHydrator($this->cache);
+            $hydrator = new EntityHydrator($this->schema, $this->cache);
         } elseif ($hydrationMode === self::HYDRATE_OBJECT_READONLY) {
-            $hydrator = new ReadOnlyEntityHydrator();
+            $hydrator = new ReadOnlyEntityHydrator($this->schema);
         } else {
-            $hydrator = new ArrayHydrator();
+            $hydrator = new ArrayHydrator($this->schema);
         }
         $collection = [];
         foreach ($data as $item) {

+ 7 - 4
src/Serializer/SerializerToArray.php

@@ -6,16 +6,20 @@ use LogicException;
 use PhpDevCommunity\PaperORM\Mapper\ColumnMapper;
 use PhpDevCommunity\PaperORM\Mapping\Column\DateTimeColumn;
 use PhpDevCommunity\PaperORM\Mapping\Column\JoinColumn;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
 use ReflectionClass;
 use ReflectionException;
 
 final class SerializerToArray
 {
     private object $entity;
+    private SchemaInterface $schema;
 
-    public function __construct(object $entity)
+
+    public function __construct(object $entity, SchemaInterface $schema)
     {
         $this->entity = $entity;
+        $this->schema = $schema;
     }
 
     public function serialize(): array
@@ -48,12 +52,12 @@ final class SerializerToArray
             }
 
             if ($column instanceof DateTimeColumn) {
-                $data[$propertyName] = $column->convertToDatabase($value);
+                $data[$propertyName] = $column->convertToDatabase($value, $this->schema);
                 continue;
             }
 
             if ($column instanceof JoinColumn) {
-                $data[$propertyName] = (new self($value))->serialize();
+                $data[$propertyName] = (new self($value, $this->schema))->serialize();
                 continue;
             }
 
@@ -62,5 +66,4 @@ final class SerializerToArray
         }
         return $data;
     }
-
 }

+ 14 - 7
src/Serializer/SerializerToDb.php

@@ -3,9 +3,13 @@
 namespace PhpDevCommunity\PaperORM\Serializer;
 
 
+use InvalidArgumentException;
 use PhpDevCommunity\PaperORM\Entity\EntityInterface;
 use PhpDevCommunity\PaperORM\Mapper\ColumnMapper;
 use PhpDevCommunity\PaperORM\Mapping\Column\JoinColumn;
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
+use ReflectionClass;
+use ReflectionException;
 
 final class SerializerToDb
 {
@@ -14,16 +18,19 @@ final class SerializerToDb
      */
     private object $entity;
 
-    public function __construct(object $entity)
+    private SchemaInterface $schema;
+
+    public function __construct(object $entity, SchemaInterface $schema)
     {
         $this->entity = $entity;
+        $this->schema = $schema;
     }
 
-    public function serialize(array $columnsToSerialize = [] ): array
+    public function serialize(array $columnsToSerialize = []): array
     {
         $entity = $this->entity;
         $columns = ColumnMapper::getColumns(get_class($entity));
-        $reflection = new \ReflectionClass($entity);
+        $reflection = new ReflectionClass($entity);
         $dbData = [];
         foreach ($columns as $column) {
             if (!empty($columnsToSerialize) && !in_array($column->getProperty(), $columnsToSerialize)) {
@@ -33,11 +40,11 @@ final class SerializerToDb
             try {
                 if (false !== ($reflectionParent = $reflection->getParentClass()) && $reflectionParent->hasProperty($column->getProperty())) {
                     $property = $reflectionParent->getProperty($column->getProperty());
-                }else {
+                } else {
                     $property = $reflection->getProperty($column->getProperty());
                 }
-            }    catch (\ReflectionException $e) {
-                throw new \InvalidArgumentException("Property {$column->getProperty()} not found in class " . get_class($entity));
+            } catch (ReflectionException $e) {
+                throw new InvalidArgumentException("Property {$column->getProperty()} not found in class " . get_class($entity));
             }
 
             $property->setAccessible(true);
@@ -49,7 +56,7 @@ final class SerializerToDb
                 }
             }
 
-            $dbData[$key] = $column->convertToDatabase($value) ;
+            $dbData[$key] = $column->convertToDatabase($value,$this->schema);
 
         }
         return $dbData;

+ 4 - 4
src/Types/DateTimeType.php

@@ -9,26 +9,26 @@ use LogicException;
 final class DateTimeType extends Type
 {
 
-    public function convertToDatabase($value, string $format = 'Y-m-d H:i:s'): ?string
+    public function convertToDatabase($value): ?string
     {
         if ($value === null) {
             return null;
         }
 
         if ($value instanceof DateTimeInterface) {
-            return $value->format($format);
+            return $value->format($this->getSchema()->getDateTimeFormatString());
         }
 
         throw new LogicException('Could not convert PHP value "' . $value . '" to ' . self::class);
     }
 
-    public function convertToPHP($value, string $format = 'Y-m-d H:i:s'): ?DateTimeInterface
+    public function convertToPHP($value): ?DateTimeInterface
     {
         if ($value === null || $value instanceof DateTimeInterface) {
             return $value;
         }
 
-        $date = DateTime::createFromFormat($format, $value);
+        $date = DateTime::createFromFormat($this->getSchema()->getDateTimeFormatString(), $value);
         if (!$date instanceof DateTimeInterface) {
             throw new LogicException('Could not convert database value "' . $value . '" to ' . self::class);
         }

+ 4 - 4
src/Types/DateType.php

@@ -5,26 +5,26 @@ namespace PhpDevCommunity\PaperORM\Types;
 final class DateType extends Type
 {
 
-    public function convertToDatabase($value, string $format = 'Y-m-d'): ?string
+    public function convertToDatabase($value): ?string
     {
         if ($value === null) {
             return null;
         }
 
         if ($value instanceof \DateTimeInterface) {
-            return $value->format($format);
+            return $value->format($this->getSchema()->getDateFormatString());
         }
 
         throw new \LogicException('Could not convert PHP value "' . $value . '" to ' . self::class);
     }
 
-    public function convertToPHP($value, string $format = 'Y-m-d'): ?\DateTimeInterface
+    public function convertToPHP($value): ?\DateTimeInterface
     {
         if ($value === null || $value instanceof \DateTimeInterface) {
             return $value;
         }
 
-        $date = \DateTime::createFromFormat($format,$value);
+        $date = \DateTime::createFromFormat($this->getSchema()->getDateFormatString(),$value);
         if (!$date instanceof \DateTimeInterface) {
             throw new \LogicException('Could not convert database value "' . $value . '" to ' . self::class);
         }

+ 12 - 1
src/Types/Type.php

@@ -2,10 +2,15 @@
 
 namespace PhpDevCommunity\PaperORM\Types;
 
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
+
 abstract class Type
 {
-    final public function __construct()
+    private SchemaInterface $schema;
+
+    final public function __construct(SchemaInterface $schema)
     {
+        $this->schema = $schema;
     }
 
     /**
@@ -20,4 +25,10 @@ abstract class Type
      */
     abstract public function convertToPHP($value);
 
+
+    final protected function getSchema(): SchemaInterface
+    {
+        return $this->schema;
+    }
+
 }

+ 5 - 2
src/Types/TypeFactory.php

@@ -2,16 +2,19 @@
 
 namespace PhpDevCommunity\PaperORM\Types;
 
+use PhpDevCommunity\PaperORM\Schema\SchemaInterface;
+
 final class TypeFactory
 {
     /**
+     * @param SchemaInterface $schema
      * @param string $typeClass
      * @return Type
      * @throws \ReflectionException
      */
-    public static function create(string $typeClass): Type
+    public static function create(SchemaInterface $schema, string $typeClass): Type
     {
-        $type = (new \ReflectionClass($typeClass))->newInstance();
+        $type = (new \ReflectionClass($typeClass))->newInstance($schema);
         if (!$type instanceof Type) {
             throw new \InvalidArgumentException($typeClass. ' must be an instance of '.Type::class);
         }