Skip to content

Commit

Permalink
Merge pull request #5 from pfilsx/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
pfilsx authored Mar 17, 2023
2 parents 5427a61 + a56c37f commit 2f98dc8
Show file tree
Hide file tree
Showing 12 changed files with 517 additions and 6 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,27 @@ PostgreSQL Doctrine
Description
------------

Provides extended Doctrine DBAL and Doctrine migration classes to allow you to use PostgreSQL
specific features such as [enums](https://www.postgresql.org/docs/current/datatype-enum.html) or JSON(B) with Doctrine.
Provides extended Doctrine and Doctrine migrations PostgreSQL support with
specific features such as [enums](https://www.postgresql.org/docs/current/datatype-enum.html), arrays and aggregate and JSON(B) functions.

Features
--------
* PostgreSQL enums support in DBAL and migrations
* PostgreSQL enums support in DBAL, ORM and migrations
* PHP8 enum support
* Fix creating [default schema in down migrations for pgsql](https://github.com/doctrine/dbal/issues/1110)
* [JSON(B) functions](https://www.postgresql.org/docs/current/functions-json.html) (in progress)
* JSON(B) types based on object models (in progress, requires symfony/serializer)
* [Trait](src/ORM/Trait/ExistsMethodRepositoryTrait.php) for easy use of [SELECT EXISTS(...)](https://www.postgresql.org/docs/current/functions-subquery.html#FUNCTIONS-SUBQUERY-EXISTS) in your entity repositories
* Aggregate functions with filter condition support
* Array types

Requirement
-----------
* PHP ^8.1
* doctrine/dbal ^3.5.1
* doctrine/migrations ^3.5.2
* symfony/serializer >=5.4.* (optional for json models)
* symfony/property-info >=5.4.* (optional)
* symfony/property-info >=5.4.* (optional for json models)

Installation
------------
Expand All @@ -46,14 +48,16 @@ for instructions on how to override the default doctrine classes in your project
Required steps:
1. Register [PostgreSQLDriverMiddleware.php](src/DBAL/Middleware/PostgreSQLDriverMiddleware.php) as driver middleware
2. Register [OrmSchemaProvider.php](src/Migrations/Provider/OrmSchemaProvider.php) as Doctrine\Migrations\Provider\SchemaProvider in Doctrine\Migrations\DependencyFactory
3. Register types and functions on your needs

For Symfony integration see [PostgreSQLDoctrineBundle](https://github.com/pfilsx/PostgreSQLDoctrineBundle)

Documentation
-------------

* [ENUMS](docs/ENUMS.md)
* [Functions](docs/FUNCTIONS-AND-OPERATORS.md)
* [Enums](docs/Enums.md)
* [Functions](docs/Functions-and-Operators.md)
* [Types](docs/Types.md)

License
-------
Expand Down
File renamed without changes.
File renamed without changes.
77 changes: 77 additions & 0 deletions docs/Types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Available types
===============

| PostgreSQL type | Register as | Implementation |
|-----------------|-------------|-----------------------------------------------------------------------------------------|
| _bool | bool[] | [Pfilsx\PostgreSQLDoctrine\DBAL\Type\BooleanArray](../src/DBAL/Type/BooleanArray.php) |
| _int2 | smallint[] | [Pfilsx\PostgreSQLDoctrine\DBAL\Type\SmallIntArray](../src/DBAL/Type/SmallIntArray.php) |
| _int4 | integer[] | [Pfilsx\PostgreSQLDoctrine\DBAL\Type\IntegerArray](../src/DBAL/Type/IntegerArray.php) |
| _int8 | bigint[] | [Pfilsx\PostgreSQLDoctrine\DBAL\Type\BigIntArray](../src/DBAL/Type/BigIntArray.php) |
| _text | text[] | [Pfilsx\PostgreSQLDoctrine\DBAL\Type\TextArray](../src/DBAL/Type/TextArray.php) |

Integration with Doctrine
=========================

```php
<?php

use Doctrine\DBAL\Types\Type;

Type::addType('bool[]', 'Pfilsx\PostgreSQLDoctrine\DBAL\Type\BooleanArray');
Type::addType('smallint[]', 'Pfilsx\PostgreSQLDoctrine\DBAL\Type\SmallIntArray');
Type::addType('integer[]', 'Pfilsx\PostgreSQLDoctrine\DBAL\Type\IntegerArray');
Type::addType('bigint[]', 'Pfilsx\PostgreSQLDoctrine\DBAL\Type\BigIntArray');
Type::addType('text[]', 'Pfilsx\PostgreSQLDoctrine\DBAL\Type\TextArray');

// ...

$platform = $em->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('bool[]','bool[]');
$platform->registerDoctrineTypeMapping('_bool','bool[]');
$platform->registerDoctrineTypeMapping('integer[]','integer[]');
$platform->registerDoctrineTypeMapping('_int4','integer[]');
$platform->registerDoctrineTypeMapping('bigint[]','bigint[]');
$platform->registerDoctrineTypeMapping('_int8','bigint[]');
$platform->registerDoctrineTypeMapping('text[]','text[]');
$platform->registerDoctrineTypeMapping('_text','text[]');
```

Integration with Symfony
=========================
```yaml
# config/packages/doctrine.yaml
doctrine:
dbal:
types:
bool[]: Pfilsx\PostgreSQLDoctrine\DBAL\Type\BooleanArray
smallint[]: Pfilsx\PostgreSQLDoctrine\DBAL\Type\SmallIntArray
integer[]: Pfilsx\PostgreSQLDoctrine\DBAL\Type\IntegerArray
bigint[]: Pfilsx\PostgreSQLDoctrine\DBAL\Type\BigIntArray
text[]: Pfilsx\PostgreSQLDoctrine\DBAL\Type\TextArray

mapping_types:
bool[]: bool[]
_bool: bool[]
smallint[]: smallint[]
_int2: smallint[]
integer[]: integer[]
_int4: integer[]
bigint[]: bigint[]
_int8: bigint[]
text[]: text[]
_text: text[]
# or
connections:
connection_name:
mapping_types:
bool[]: bool[]
_bool: bool[]
smallint[]: smallint[]
_int2: smallint[]
integer[]: integer[]
_int4: integer[]
bigint[]: bigint[]
_int8: bigint[]
text[]: text[]
_text: text[]
```
63 changes: 63 additions & 0 deletions src/DBAL/Type/AbstractArrayType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;
use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;
use Pfilsx\PostgreSQLDoctrine\Tools\ArrayTypeTool;

abstract class AbstractArrayType extends Type
{
/**
* @param array<string, mixed> $column
* @param AbstractPlatform $platform
*
* @throws \Doctrine\DBAL\Exception
*
* @return string
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getDoctrineTypeMapping($this->getName());
}

public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
return null;
}

if (!\is_array($value)) {
throw new ConversionException(\sprintf('Invalid value type. Expected "array", "%s" provided.', \get_debug_type($value)));
}

return ArrayTypeTool::convertPHPArrayToDatabaseArrayString($value, static::getArrayType());
}

/**
* @param mixed $value
* @param AbstractPlatform $platform
*
* @throws ConversionException
*
* @return null|bool[]|int[]|string[]
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?array
{
if ($value === null) {
return null;
}

if (!\is_string($value)) {
throw new ConversionException(\sprintf('Invalid database value type. Expected "string", "%s" provided.', \get_debug_type($value)));
}

return ArrayTypeTool::convertDatabaseArrayStringToPHPArray($value, static::getArrayType());
}

abstract protected static function getArrayType(): ArrayTypeEnum;
}
25 changes: 25 additions & 0 deletions src/DBAL/Type/BigIntArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;

/**
* Implementation of PostgreSql BIGINT[] data type.
*
* @see https://www.postgresql.org/docs/current/arrays.html
*/
class BigIntArray extends AbstractArrayType
{
protected static function getArrayType(): ArrayTypeEnum
{
return ArrayTypeEnum::BigIntArray;
}

public function getName(): string
{
return 'bigint[]';
}
}
25 changes: 25 additions & 0 deletions src/DBAL/Type/BooleanArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;

/**
* Implementation of PostgreSql BOOL[] data type.
*
* @see https://www.postgresql.org/docs/current/arrays.html
*/
class BooleanArray extends AbstractArrayType
{
protected static function getArrayType(): ArrayTypeEnum
{
return ArrayTypeEnum::BooleanArray;
}

public function getName(): string
{
return 'bool[]';
}
}
25 changes: 25 additions & 0 deletions src/DBAL/Type/IntegerArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;

/**
* Implementation of PostgreSql INTEGER[] data type.
*
* @see https://www.postgresql.org/docs/current/arrays.html
*/
class IntegerArray extends AbstractArrayType
{
protected static function getArrayType(): ArrayTypeEnum
{
return ArrayTypeEnum::IntArray;
}

public function getName(): string
{
return 'integer[]';
}
}
25 changes: 25 additions & 0 deletions src/DBAL/Type/SmallIntArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;

/**
* Implementation of PostgreSql SMALLINT[] data type.
*
* @see https://www.postgresql.org/docs/current/arrays.html
*/
class SmallIntArray extends AbstractArrayType
{
protected static function getArrayType(): ArrayTypeEnum
{
return ArrayTypeEnum::SmallIntArray;
}

public function getName(): string
{
return 'smallint[]';
}
}
25 changes: 25 additions & 0 deletions src/DBAL/Type/TextArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\DBAL\Type;

use Pfilsx\PostgreSQLDoctrine\Enum\ArrayTypeEnum;

/**
* Implementation of PostgreSql TEXT[] data type.
*
* @see https://www.postgresql.org/docs/current/arrays.html
*/
class TextArray extends AbstractArrayType
{
protected static function getArrayType(): ArrayTypeEnum
{
return ArrayTypeEnum::TextArray;
}

public function getName(): string
{
return 'text[]';
}
}
14 changes: 14 additions & 0 deletions src/Enum/ArrayTypeEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Pfilsx\PostgreSQLDoctrine\Enum;

enum ArrayTypeEnum: string
{
case SmallIntArray = 'smallint';
case IntArray = 'integer';
case BigIntArray = 'bigint';
case TextArray = 'text';
case BooleanArray = 'boolean';
}
Loading

0 comments on commit 2f98dc8

Please sign in to comment.