After some further research I've created my own package with support of some additional functions and datatypes for PostgreSql 9.4 on Laravel and Symfony.
Here is a working solution for my initial question (see original instructions from https://bitbucket.org/martin_georgiev/postgresql-for-doctrine.git ):
The steps below are based on Laravel 5 integration with FoxxMD's fork of mitchellvanw/laravel-doctrine.
- Register the functions and datatype mappings:
# Usually part of config/doctrine.php
<?php
return [
'entity_managers' => [
'name_of_your_entity_manager' => [
'dql' => [
'string_functions' => [
// Array data types related functions
'ALL' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All',
'ANY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any',
'ARRAY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Arr',
'ARRAY_APPEND' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend',
'ARE_OVERLAPING_EACH_OTHER' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAreOverlapingEachOther',
'ARRAY_CARDINALITY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCardinality',
'ARRAY_CAT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCat',
'ARRAY_PREPEND' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayPrepend',
'ARRAY_REMOVE' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayRemove',
'ARRAY_REPLACE' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayReplace',
'ARRAY_TO_STRING' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayToString',
'STRING_TO_ARRAY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StringToArray',
// Functions and operators used by both array and json(-b) data types
'CONTAINS' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Contains',
'IS_CONTAINED_BY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\IsContainedBy',
// Json(-b) data type related functions and operators
'JSON_GET_FIELD' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetField',
'JSON_GET_FIELD_AS_TEXT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsText',
'JSON_GET_OBJECT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObject',
'JSON_GET_OBJECT_AS_TEXT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObjectAsText',
'JSONB_ARRAY_ELEMENTS' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElements',
'JSONB_ARRAY_ELEMENTS_TEXT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElementsText',
'JSONB_ARRAY_LENGTH' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayLength',
'JSONB_EACH' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEach',
'JSONB_EACH_TEXT' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEachText',
'JSONB_EXISTS' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectKeys',
'JSONB_OBJECT_KEYS' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbExists',
// Basic text search related functions and operators
'TO_TSQUERY' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsquery',
'TO_TSVECTOR' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsvector',
'TSMATCH' => 'MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsmatch',
],
],
'mapping_types' => [
'jsonb' => 'jsonb',
'_jsonb' => 'jsonb[]',
'jsonb[]' => 'jsonb[]',
],
- Add EventSubscriber for Doctrine
<?php
namespace Acme\Handlers\Events;
use Doctrine\Common\EventSubscriber as Subscriber;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Types\Type;
class DoctrineEventSubscriber implements Subscriber
{
/**
* @return array
*/
public function getSubscribedEvents()
{
return [
Events::postConnect,
];
}
/**
* @param ConnectionEventArgs $args
* @throws DBALException
*/
public function postConnect(ConnectionEventArgs $args)
{
Type::addType('jsonb', "\MartinGeorgiev\Doctrine\DBAL\Types\Jsonb");
Type::addType('jsonb[]', "\MartinGeorgiev\Doctrine\DBAL\Types\JsonbArray");
}
}
- Add the EventSubscriber for Doctrine to a ServiceProvider
<?php
namespace Acme\Providers;
use Config;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Doctrine\Common\Persistence\ManagerRegistry as DoctrineManagerRegistry;
use Acme\Handlers\Events\DoctrineEventSubscriber;
/**
* Class EventServiceProvider
* @package Quantum\Providers
*/
class EventServiceProvider extends ServiceProvider
{
/**
* Register Doctrine Events as well.
*/
public function register()
{
$this->registerDoctrineEvents();
$this->registerDoctrineTypeMapping();
}
/**
* Register any other events for your application.
* @param DispatcherContract $events
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
}
/**
* Register Doctrine events.
*/
private function registerDoctrineEvents()
{
$eventManager = $this->registry()->getConnection()->getEventManager();
$eventManager->addEventSubscriber(new DoctrineEventSubscriber);
}
/**
* Register any custom Doctrine type mappings
*/
private function registerDoctrineTypeMapping()
{
$databasePlatform = $this->registry()->getConnection()->getDatabasePlatform();
$entityManagers = Config::get('doctrine.entity_managers');
foreach ($entityManagers as $entityManager) {
if (array_key_exists('mapping_types', $entityManager)) {
foreach ($entityManager['mapping_types'] as $dbType => $doctrineName) {
$databasePlatform->registerDoctrineTypeMapping($dbType, $doctrineName);
}
}
}
}
/**
* Get the entity manager registry
* @return DoctrineManagerRegistry
*/
function registry()
{
return app(DoctrineManagerRegistry::class);
}
}