Skip to content

Instantly share code, notes, and snippets.

@Xymanek
Created August 23, 2017 08:17
Show Gist options
  • Save Xymanek/8fbbd127eeeca2c6c15aad6acfd0e07b to your computer and use it in GitHub Desktop.
Save Xymanek/8fbbd127eeeca2c6c15aad6acfd0e07b to your computer and use it in GitHub Desktop.
Symfony multi-tenant database
# Doctrine Configuration
doctrine:
dbal:
types:
uuid_binary: Ramsey\Uuid\Doctrine\UuidBinaryType
uuid_binary_ordered: Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType
chronos_date: Warhuhn\Doctrine\DBAL\Types\ChronosDateType
chronos_datetime: Warhuhn\Doctrine\DBAL\Types\ChronosDateTimeType
chronos_datetimetz: Warhuhn\Doctrine\DBAL\Types\ChronosDateTimeTzType
connections:
default:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: utf8mb4
server_version: 5.7
mapping_types:
uuid_binary: binary
uuid_binary_ordered: binary
data:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
user: "%database_user%"
password: "%database_password%"
charset: utf8mb4
server_version: 5.7
wrapper_class: AppBundle\Doctrine\DataConnectionWrapper
<?php
namespace AppBundle\Doctrine;
use AppBundle\Entity\Organisation;
use Doctrine\DBAL\Connection;
use Acme\Common\DatabaseNameResolver;
class DataConnectionWrapper extends Connection
{
/**
* @var \AppBundle\Entity\Organisation
*/
protected $organisation;
/**
* @var bool
*/
protected $_isConnected = false;
/**
* @return \AppBundle\Entity\Organisation
*/
public function getOrganisation ()
{
return $this->organisation;
}
/**
* @param \AppBundle\Entity\Organisation $organisation
*/
public function setOrganisation (Organisation $organisation = null)
{
if ($this->_isConnected) {
throw new \BadMethodCallException('Cannot switch organisation while connected');
}
$this->organisation = $organisation;
$this->connect();
}
/**
* {@inheritDoc}
*/
public function connect ()
{
if ($this->isConnected()) {
return false;
}
$params = $this->getParams();
if ($this->organisation) {
$params['dbname'] = self::generateDatabaseName($this->organisation);
} else {
unset($params['dbname']);
}
$this->__construct($params, $this->getDriver(), $this->getConfiguration(), $this->getEventManager());
parent::connect();
$this->_isConnected = true;
return true;
}
public static function generateDatabaseName (Organisation $organisation) : string
{
return DatabaseNameResolver::getByOrganisationId($organisation->getId());
}
/**
* {@inheritDoc}
*/
public function isConnected ()
{
return $this->_isConnected;
}
/**
* {@inheritDoc}
*/
public function close ()
{
if ($this->isConnected()) {
parent::close();
$this->_isConnected = false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment