From 1a67270d11dd19c4a5be11f561a4a68f172c51a4 Mon Sep 17 00:00:00 2001 From: Nathaniel Marrin Date: Tue, 14 Oct 2014 15:41:13 -0700 Subject: [PATCH 1/4] Multiple Entity Managers and Connections --- src/Console/DqlCommand.php | 8 +- src/Console/GenerateProxiesCommand.php | 47 +++++----- src/Console/SchemaCreateCommand.php | 26 ++++-- src/Console/SchemaDropCommand.php | 46 ++++----- src/Console/SchemaUpdateCommand.php | 46 ++++----- src/DoctrineUserProvider.php | 10 +- src/IlluminateRegistry.php | 60 ++++++++++++ src/LaravelDoctrineServiceProvider.php | 123 ++++++++++++++++++++----- 8 files changed, 258 insertions(+), 108 deletions(-) create mode 100644 src/IlluminateRegistry.php diff --git a/src/Console/DqlCommand.php b/src/Console/DqlCommand.php index 160a509..eea91a0 100644 --- a/src/Console/DqlCommand.php +++ b/src/Console/DqlCommand.php @@ -1,7 +1,7 @@ entityManager = $entityManager; + $this->entityManager = $registry->getManager(); } public function fire() @@ -53,4 +53,4 @@ protected function getOptions() ['hydrate', null, InputOption::VALUE_OPTIONAL, 'Hydrate type. Available: object, array, scalar, single_scalar, simpleobject'] ]; } -} +} diff --git a/src/Console/GenerateProxiesCommand.php b/src/Console/GenerateProxiesCommand.php index 3de3aa1..5b9c554 100644 --- a/src/Console/GenerateProxiesCommand.php +++ b/src/Console/GenerateProxiesCommand.php @@ -1,7 +1,7 @@ entityManager = $entityManager; + $this->registry = $registry; } public function fire() { $this->info('Starting proxy generation....'); - $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); - if (empty($metadata)) { - $this->error('No metadata found to generate any entities.'); - exit; + foreach ($this->registry->getManagerNames() as $key => $value) { + $manager = $this->registry->getManager($key); + $metadata = $manager->getMetadataFactory()->getAllMetadata(); + if (empty($metadata)) { + $this->error('No metadata found to generate any entities.'); + exit; + } + $directory = $this->laravel['config']['doctrine::doctrine.proxy.directory']; + if ( ! $directory) { + $this->error('The proxy directory has not been set.'); + exit; + } + $this->info('Processing entities:'); + foreach ($metadata as $item) { + $this->line($item->name); + } + $manager->getProxyFactory()->generateProxyClasses($metadata, $directory); + $this->info('Proxies have been created.'); } - $directory = $this->laravel['config']['doctrine::doctrine.proxy.directory']; - if ( ! $directory) { - $this->error('The proxy directory has not been set.'); - exit; - } - $this->info('Processing entities:'); - foreach ($metadata as $item) { - $this->line($item->name); - } - $this->entityManager->getProxyFactory()->generateProxyClasses($metadata, $directory); - $this->info('Proxies have been created.'); } -} +} diff --git a/src/Console/SchemaCreateCommand.php b/src/Console/SchemaCreateCommand.php index 1fd6c6a..d036b0f 100644 --- a/src/Console/SchemaCreateCommand.php +++ b/src/Console/SchemaCreateCommand.php @@ -2,7 +2,7 @@ use Illuminate\Console\Command; use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\ORM\Mapping\ClassMetadataFactory; +use Doctrine\Common\Persistence\ManagerRegistry; use Symfony\Component\Console\Input\InputOption; class SchemaCreateCommand extends Command @@ -29,18 +29,18 @@ class SchemaCreateCommand extends Command private $tool; /** - * The class metadata factory + * The ManagerRegistry * - * @var \Doctrine\ORM\Tools\SchemaTool + * @var \Doctrine\Common\Persistence\ManagerRegistry */ - private $metadata; + private $registry; - public function __construct(SchemaTool $tool, ClassMetadataFactory $metadata) + public function __construct(SchemaTool $tool, ManagerRegistry $registry) { parent::__construct(); $this->tool = $tool; - $this->metadata = $metadata; + $this->registry = $registry; } /** @@ -52,11 +52,17 @@ public function fire() { if ($this->option('sql')) { $this->info('Outputting create query:'.PHP_EOL); - $sql = $this->tool->getCreateSchemaSql($this->metadata->getAllMetadata()); - $this->info(implode(';'.PHP_EOL, $sql)); + foreach ($this->registry->getManagerNames() as $key => $value) { + $manager = $this->registry->getManager($key); + $sql = $this->tool->getCreateSchemaSql($manager->getMetadataFactory()->getAllMetadata()); + $this->info(implode(';'.PHP_EOL, $sql)); + } } else { $this->info('Creating database schema...'); - $this->tool->createSchema($this->metadata->getAllMetadata()); + foreach ($this->registry->getManagerNames() as $key => $value) { + $manager = $this->registry->getManager($key); + $this->tool->createSchema($manager->getMetadataFactory()->getAllMetadata()); + } $this->info('Schema has been created!'); } } @@ -67,4 +73,4 @@ protected function getOptions() ['sql', false, InputOption::VALUE_NONE, 'Dumps SQL query and does not execute creation.'] ]; } -} +} diff --git a/src/Console/SchemaDropCommand.php b/src/Console/SchemaDropCommand.php index 4861b2b..548d06b 100644 --- a/src/Console/SchemaDropCommand.php +++ b/src/Console/SchemaDropCommand.php @@ -1,8 +1,8 @@ -tool = $tool; - $this->metadata = $metadata; + $this->registry = $registry; } /** @@ -50,18 +50,21 @@ public function __construct(SchemaTool $tool, ClassMetadataFactory $metadata) */ public function fire() { - $sql = $this->tool->getDropSchemaSQL($this->metadata->getAllMetadata()); - if (empty($sql)) { - $this->info('Current models do not exist in schema.'); - return; - } - if ($this->option('sql')) { - $this->info('Outputting drop query:'); - $this->info(implode(';' . PHP_EOL, $sql)); - } else { - $this->info('Dropping database schema....'); - $this->tool->dropSchema($this->metadata->getAllMetadata()); - $this->info('Schema has been dropped!'); + foreach ($this->registry->getManagerNames() as $key => $value) { + $manager = $this->registry->getManager($key); + $sql = $this->tool->getDropSchemaSQL($manager->getMetadataFactory()->getAllMetadata()); + if (empty($sql)) { + $this->info('Current models do not exist in schema.'); + continue; + } + if ($this->option('sql')) { + $this->info('Outputting drop query:'); + $this->info(implode(';' . PHP_EOL, $sql)); + } else { + $this->info('Dropping database schema....'); + $this->tool->dropSchema($manager->getMetadataFactory()->getAllMetadata()); + $this->info('Schema has been dropped!'); + } } } @@ -72,4 +75,3 @@ protected function getOptions() ]; } } - diff --git a/src/Console/SchemaUpdateCommand.php b/src/Console/SchemaUpdateCommand.php index 2a10b83..0eaf405 100644 --- a/src/Console/SchemaUpdateCommand.php +++ b/src/Console/SchemaUpdateCommand.php @@ -1,8 +1,8 @@ -tool = $tool; - $this->metadata = $metadata; + $this->registry = $registry; } /** @@ -52,18 +52,21 @@ public function fire() { $this->info('Checking if database needs updating....'); $clean = $this->option('clean'); - $sql = $this->tool->getUpdateSchemaSql($this->metadata->getAllMetadata(), $clean); - if (empty($sql)) { - $this->info('No updates found.'); - return; - } - if ($this->option('sql')) { - $this->info('Outputting update query:'); - $this->info(implode(';' . PHP_EOL, $sql)); - } else { - $this->info('Updating database schema....'); - $this->tool->updateSchema($this->metadata->getAllMetadata()); - $this->info('Schema has been updated!'); + foreach ($this->registry->getManagerNames() as $key => $value) { + $manager = $this->registry->getManager($key); + $sql = $this->tool->getUpdateSchemaSql($manager->getMetadataFactory()->getAllMetadata(), $clean); + if (empty($sql)) { + $this->info('No updates found.'); + continue; + } + if ($this->option('sql')) { + $this->info('Outputting update query:'); + $this->info(implode(';' . PHP_EOL, $sql)); + } else { + $this->info('Updating database schema....'); + $this->tool->updateSchema($this->metadata->getAllMetadata()); + $this->info('Schema has been updated!'); + } } } @@ -75,4 +78,3 @@ protected function getOptions() ]; } } - diff --git a/src/DoctrineUserProvider.php b/src/DoctrineUserProvider.php index 5fed043..b749732 100644 --- a/src/DoctrineUserProvider.php +++ b/src/DoctrineUserProvider.php @@ -1,6 +1,6 @@ hasher = $hasher; - $this->entityManager = $entityManager; + $this->entityManager = $registry->getManager(); $this->entity = $entity; } /** diff --git a/src/IlluminateRegistry.php b/src/IlluminateRegistry.php new file mode 100644 index 0000000..77237f5 --- /dev/null +++ b/src/IlluminateRegistry.php @@ -0,0 +1,60 @@ +container = $container; + parent::__construct('ORM', $connections, $entityManagers, $defaultConnection, $defaultEntityManager, 'Doctrine\ORM\Proxy\Proxy'); + } + + /** + * Fetches/creates the given services. + * A service in this context is connection or a manager instance. + * @param string $name The name of the service. + * @return object The instance of the given service. + */ + protected function getService($name) + { + return $this->container->make($name); + } + + /** + * Resets the given services. + * A service in this context is connection or a manager instance. + * @param string $name The name of the service. + * @return void + */ + protected function resetService($name) + { + return $this->container->bind($name, null); + } + + /** + * Resolves a registered namespace alias to the full namespace. + * This method looks for the alias in all registered object managers. + * @param string $alias The alias. + * @throws ORMException + * @return string The full namespace. + */ + public function getAliasNamespace($alias) + { + foreach (array_keys($this->getManagers()) as $name) { + try { + return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias); + } catch (ORMException $e) { + } + } + + throw ORMException::unknownEntityNamespace($alias); + } +} diff --git a/src/LaravelDoctrineServiceProvider.php b/src/LaravelDoctrineServiceProvider.php index d9ec430..8d0e804 100644 --- a/src/LaravelDoctrineServiceProvider.php +++ b/src/LaravelDoctrineServiceProvider.php @@ -1,6 +1,9 @@ registerConfigurationMapper(); $this->registerCacheManager(); + $this->registerManagerRegistry(); $this->registerEntityManager(); $this->registerClassMetadataFactory(); @@ -76,30 +80,103 @@ public function registerCacheManager() }); } - private function registerEntityManager() + private function createMetadataConfiguration( + array $paths, + $isDevMode = false, + $proxyDir = null, + \Doctrine\Common\Cache\Cache $cache = null, + $useSimpleAnnotationReader = true, + $autoGenerateProxyClasses = false, + $proxyNamespace = null, + $repository = 'Doctrine\ORM\EntityRepository', + $logger = null + ){ + $metadata = Setup::createAnnotationMetadataConfiguration( + $paths, + $isDevMode, + $proxyDir, + $cache, + $useSimpleAnnotationReader + ); + + $metadata->addFilter('trashed', TrashedFilter::class); + $metadata->setAutoGenerateProxyClasses($autoGenerateProxyClasses); + if ($proxyNamespace) { + $metadata->setProxyNamespace($config['proxy']['namespace']); + } + $metadata->setDefaultRepositoryClassName($repository); + $metadata->setSQLLogger($logger); + + return $metadata; + } + + private function mapSingleEntityManager($config, $defaultDatabase){ + if(!isset($config['entity_managers'])) { + $config['entity_managers'] = [ + $defaultDatabase => [ + 'metadata' => $config['metadata'] + ] + ]; + } + + return $config; + } + + private function registerManagerRegistry() { - $this->app->singleton(EntityManager::class, function ($app) { + $this->app->singleton(IlluminateRegistry::class, function ($app) { $config = $app['config']['doctrine::doctrine']; - $metadata = Setup::createAnnotationMetadataConfiguration( - $config['metadata'], - $app['config']['app.debug'], - $config['proxy']['directory'], - $app[CacheManager::class]->getCache($config['cache_provider']), - $config['simple_annotations'] - ); - $metadata->addFilter('trashed', TrashedFilter::class); - $metadata->setAutoGenerateProxyClasses($config['proxy']['auto_generate']); - $metadata->setDefaultRepositoryClassName($config['repository']); - $metadata->setSQLLogger($config['logger']); + $databaseConnections = $app['config']['database']['connections']; + $defaultDatabase = $app['config']['database']['default']; + $proxyNamespace = isset($config['proxy']['namespace']) ? $config['proxy']['namespace'] : null; + + $registryConnections = array(); + $registryManagers = array(); - if (isset($config['proxy']['namespace'])) - $metadata->setProxyNamespace($config['proxy']['namespace']); + $config = $this->mapSingleEntityManager($config, $defaultDatabase); $eventManager = new EventManager; $eventManager->addEventListener(Events::onFlush, new SoftDeletableListener); - $entityManager = EntityManager::create($this->mapLaravelToDoctrineConfig($app['config']), $metadata, $eventManager); - $entityManager->getFilters()->enable('trashed'); - return $entityManager; + + foreach ($config['entity_managers'] as $name => $managerConfig) { + $connectionName = isset($managerConfig['connection']) ? $managerConfig['connection'] : $name; + $cacheProvider = isset($managerConfig['cache_provider']) ? $managerConfig['cache_provider'] : $config['cache_provider']; + $repository = isset($managerConfig['repository']) ? $managerConfig['repository'] : $config['repository']; + $simpleAnnotations = isset($managerConfig['simple_annotations']) ? $managerConfig['simple_annotations'] : $config['simple_annotations']; + $logger = isset($managerConfig['logger']) ? $managerConfig['logger'] : $config['logger']; + + $databaseConfig = $databaseConnections[$connectionName]; + $metadata = $this->createMetadataConfiguration( + $managerConfig['metadata'], + $app['config']['app.debug'], + $config['proxy']['directory'], + $app[CacheManager::class]->getCache($cacheProvider), + $simpleAnnotations, + $config['proxy']['auto_generate'], + $proxyNamespace, + $repository, + $logger + ); + + $connection = DriverManager::getConnection($this->mapLaravelToDoctrineConfig($databaseConfig), $metadata, $eventManager); + $registryConnections[$connectionName] = "doctrine.dbal.{$connectionName}_connection"; + $app->instance($registryConnections[$connectionName], $connection); + + $entityManager = EntityManager::create($connection, $metadata, $eventManager); + $entityManager->getFilters()->enable('trashed'); + $registryManagers[$name] = "doctrine.orm.{$name}_entity_manager"; + $app->instance($registryManagers[$name], $entityManager); + } + + return new IlluminateRegistry($app, $registryConnections, $registryManagers, $defaultDatabase, $defaultDatabase); + }); + $this->app->singleton(ManagerRegistry::class, IlluminateRegistry::class); + } + + private function registerEntityManager() + { + $this->app->singleton(EntityManager::class, function ($app) { + return $app->make(IlluminateRegistry::class)->getManager(); }); $this->app->singleton(EntityManagerInterface::class, EntityManager::class); } @@ -135,19 +212,19 @@ public function provides() ClassMetadataFactory::class, DriverMapper::class, AuthManager::class, + ManagerRegistry::class, + IlluminateRegistry::class, ]; } /** * Map Laravel's to Doctrine's database configuration requirements. - * @param $config + * @param $databaseConfig * @throws \Exception * @return array */ - private function mapLaravelToDoctrineConfig($config) + private function mapLaravelToDoctrineConfig($databaseConfig) { - $default = $config['database.default']; - $connection = $config["database.connections.{$default}"]; - return App::make(DriverMapper::class)->map($connection); + return App::make(DriverMapper::class)->map($databaseConfig); } } From c5f1e307ebaea26585a316cd17902b5df9dab6a1 Mon Sep 17 00:00:00 2001 From: Nathaniel Marrin Date: Mon, 19 Jan 2015 16:16:23 -0800 Subject: [PATCH 2/4] refactored to make it easier to test --- composer.json | 1 + phpunit.xml | 3 + src/IlluminateRegistry.php | 18 ++- src/LaravelDoctrineServiceProvider.php | 133 +++++++++------ .../AbstractDatabaseMappingTest.php | 153 ++++++++++++++++++ .../DatabaseMappingTest.php | 89 ++++++++++ .../Models/User.php | 32 ++++ .../SchemaCreateCommandTest.php | 53 ++++++ 8 files changed, 433 insertions(+), 49 deletions(-) create mode 100644 tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php create mode 100644 tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php create mode 100644 tests/MultipleEntityManagersAndConnections/Models/User.php create mode 100644 tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php diff --git a/composer.json b/composer.json index b895287..eb3464c 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "require": { "php": ">=5.5.0", "illuminate/support": "4.*|5.*", + "illuminate/container": "4.*|5.*", "doctrine/orm": "2.5.*", "doctrine/migrations": "1.*" }, diff --git a/phpunit.xml b/phpunit.xml index afa8d1d..01a41f1 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -14,5 +14,8 @@ ./tests/ + + ./tests/MultipleEntityManagersAndConnections/ + diff --git a/src/IlluminateRegistry.php b/src/IlluminateRegistry.php index 77237f5..b2a06e5 100644 --- a/src/IlluminateRegistry.php +++ b/src/IlluminateRegistry.php @@ -11,10 +11,22 @@ final class IlluminateRegistry extends AbstractManagerRegistry */ private $container; - public function __construct(Container $container, array $connections, array $entityManagers, $defaultConnection, $defaultEntityManager) - { + public function __construct( + Container $container, + array $connections, + array $entityManagers, + $defaultConnection, + $defaultEntityManager + ) { $this->container = $container; - parent::__construct('ORM', $connections, $entityManagers, $defaultConnection, $defaultEntityManager, 'Doctrine\ORM\Proxy\Proxy'); + parent::__construct( + 'ORM', + $connections, + $entityManagers, + $defaultConnection, + $defaultEntityManager, + 'Doctrine\ORM\Proxy\Proxy' + ); } /** diff --git a/src/LaravelDoctrineServiceProvider.php b/src/LaravelDoctrineServiceProvider.php index 8d0e804..dfa7cda 100644 --- a/src/LaravelDoctrineServiceProvider.php +++ b/src/LaravelDoctrineServiceProvider.php @@ -1,7 +1,5 @@ [ 'metadata' => $config['metadata'] @@ -122,53 +125,91 @@ private function mapSingleEntityManager($config, $defaultDatabase){ return $config; } + private function createManagerInstances($config, $databaseConnections, $debug, CacheManager $cacheManager) + { + $registryConnections = []; + $registryManagers = []; + $defaults = ['connection' => null, 'entityManager' => null]; + + $proxyNamespace = isset($config['proxy']['namespace']) ? $config['proxy']['namespace'] : null; + + $eventManager = new EventManager; + $eventManager->addEventListener(Events::onFlush, new SoftDeletableListener); + + foreach ($config['entity_managers'] as $name => $managerConfig) { + $connectionName = isset($managerConfig['connection']) ? $managerConfig['connection'] : $name; + + // skip connection names not defined in Laravel's database configuration + if (!isset($databaseConnections[$connectionName])) { + continue; + } + + if ($connectionName === $config['default_connection']) { + $defaults['connection'] = $connectionName; + $defaults['entityManager'] = $name; + } + + $databaseConfig = $databaseConnections[$connectionName]; + $cacheProvider = isset($managerConfig['cache_provider']) ? $managerConfig['cache_provider'] : $config['cache_provider']; + $repository = isset($managerConfig['repository']) ? $managerConfig['repository'] : $config['repository']; + $simpleAnnotations = isset($managerConfig['simple_annotations']) ? $managerConfig['simple_annotations'] : $config['simple_annotations']; + $logger = isset($managerConfig['logger']) ? $managerConfig['logger'] : $config['logger']; + + $metadata = $this->createMetadataConfiguration( + $managerConfig['metadata'], + $debug, + $config['proxy']['directory'], + $cacheManager->getCache($cacheProvider), + $simpleAnnotations, + $config['proxy']['auto_generate'], + $proxyNamespace, + $repository, + $logger + ); + + $connection = DriverManager::getConnection( + $this->mapLaravelToDoctrineConfig($databaseConfig), + $metadata, + $eventManager + ); + + $registryConnections[$connectionName] = "doctrine.dbal.{$connectionName}_connection"; + + $entityManager = EntityManager::create($connection, $metadata, $eventManager); + $entityManager->getFilters()->enable('trashed'); + $registryManagers[$name] = "doctrine.orm.{$name}_entity_manager"; + + $this->app->instance($registryConnections[$connectionName], $connection); + $this->app->instance($registryManagers[$name], $entityManager); + + } + + return [$registryConnections, $registryManagers, $defaults]; + } + private function registerManagerRegistry() { $this->app->singleton(IlluminateRegistry::class, function ($app) { $config = $app['config']['doctrine::doctrine']; $databaseConnections = $app['config']['database']['connections']; $defaultDatabase = $app['config']['database']['default']; - $proxyNamespace = isset($config['proxy']['namespace']) ? $config['proxy']['namespace'] : null; - - $registryConnections = array(); - $registryManagers = array(); - - $config = $this->mapSingleEntityManager($config, $defaultDatabase); - - $eventManager = new EventManager; - $eventManager->addEventListener(Events::onFlush, new SoftDeletableListener); - - foreach ($config['entity_managers'] as $name => $managerConfig) { - $connectionName = isset($managerConfig['connection']) ? $managerConfig['connection'] : $name; - $cacheProvider = isset($managerConfig['cache_provider']) ? $managerConfig['cache_provider'] : $config['cache_provider']; - $repository = isset($managerConfig['repository']) ? $managerConfig['repository'] : $config['repository']; - $simpleAnnotations = isset($managerConfig['simple_annotations']) ? $managerConfig['simple_annotations'] : $config['simple_annotations']; - $logger = isset($managerConfig['logger']) ? $managerConfig['logger'] : $config['logger']; - - $databaseConfig = $databaseConnections[$connectionName]; - $metadata = $this->createMetadataConfiguration( - $managerConfig['metadata'], - $app['config']['app.debug'], - $config['proxy']['directory'], - $app[CacheManager::class]->getCache($cacheProvider), - $simpleAnnotations, - $config['proxy']['auto_generate'], - $proxyNamespace, - $repository, - $logger - ); - - $connection = DriverManager::getConnection($this->mapLaravelToDoctrineConfig($databaseConfig), $metadata, $eventManager); - $registryConnections[$connectionName] = "doctrine.dbal.{$connectionName}_connection"; - $app->instance($registryConnections[$connectionName], $connection); - - $entityManager = EntityManager::create($connection, $metadata, $eventManager); - $entityManager->getFilters()->enable('trashed'); - $registryManagers[$name] = "doctrine.orm.{$name}_entity_manager"; - $app->instance($registryManagers[$name], $entityManager); - } - return new IlluminateRegistry($app, $registryConnections, $registryManagers, $defaultDatabase, $defaultDatabase); + $config = $this->mapEntityManagers($config, $defaultDatabase); + + list($registryConnections, $registryManagers, $defaults) = $this->createManagerInstances( + $config, + $databaseConnections, + $app['config']['app.debug'], + $app[CacheManager::class] + ); + + return new IlluminateRegistry( + $app, + $registryConnections, + $registryManagers, + $defaults['connection'], + $defaults['entityManager'] + ); }); $this->app->singleton(ManagerRegistry::class, IlluminateRegistry::class); } @@ -225,6 +266,6 @@ public function provides() */ private function mapLaravelToDoctrineConfig($databaseConfig) { - return App::make(DriverMapper::class)->map($databaseConfig); + return $this->app->make(DriverMapper::class)->map($databaseConfig); } } diff --git a/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php b/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php new file mode 100644 index 0000000..800c9e3 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php @@ -0,0 +1,153 @@ +getMethod($name); + $method->setAccessible(true); + return $method->invokeArgs($obj, $args); + } + + public function make($abstract, $parameters = array()) + { + if (isset($this->containerInstances[$abstract])) { + return $this->containerInstances[$abstract]; + } + } + + public function instance($abstract, $instance) + { + $this->containerInstances[$abstract] = $instance; + } + + protected function createCacheManager($cacheConfig) + { + $manager = new CacheManager($cacheConfig); + $manager->add(new ApcProvider); + $manager->add(new MemcacheProvider); + $manager->add(new RedisProvider); + $manager->add(new XcacheProvider); + $manager->add(new NullProvider); + + return $manager; + } + + protected function getLaravelDBConfig() + { + return [ + 'default' => 'mysql', + + 'connections' => array( + 'sqlite' => array( + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + ), + 'mysql' => array( + 'driver' => 'mysql', + 'host' => 'localhost', + 'database' => 'laravel', + 'username' => 'root', + 'password' => 'root', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ), + 'pgsql' => array( + 'driver' => 'pgsql', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', + 'prefix' => '', + 'schema' => 'public', + ), + 'sqlsrv' => array( + 'driver' => 'sqlsrv', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => '', + 'prefix' => '', + ), + ), + ]; + } + + protected function getBasicDoctrineConfiguration() + { + return [ + 'simple_annotations' => false, + + 'metadata' => [ + __DIR__.'/Models', + ], + + 'proxy' => [ + 'auto_generate' => false, + 'directory' => null, + 'namespace' => null + ], + + // Available: null, apc, xcache, redis, memcache + 'cache_provider' => null, + + 'cache' => [ + 'redis' => [ + 'host' => '127.0.0.1', + 'port' => 6379, + 'database' => 1 + ], + 'memcache' => [ + 'host' => '127.0.0.1', + 'port' => 11211 + ] + ], + + 'repository' => 'Doctrine\ORM\EntityRepository', + + 'repositoryFactory' => null, + + 'logger' => null + ]; + } + + public function setUp() + { + $mapper = new DriverMapper; + $mapper->registerMapper(new SqlMapper); + $mapper->registerMapper(new SqliteMapper); + + $this->containerInstances[DriverMapper::class] = $mapper; + + $containerStub = $this->getMock('\Illuminate\Container\Container'); + $containerStub->expects($this->any()) + ->method('make') + ->will($this->returnCallback([$this,'make'])); + $containerStub->expects($this->any()) + ->method('instance') + ->will($this->returnCallback([$this,'instance'])); + $this->sp = new LaravelDoctrineServiceProvider($containerStub); + $this->containerStub = $containerStub; + } +} diff --git a/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php b/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php new file mode 100644 index 0000000..334d052 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php @@ -0,0 +1,89 @@ +getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + $this->assertEquals($laravelDBConfig['default'], $doctrineEntityConfig['default_connection']); + $this->assertArrayHasKey('entity_managers', $doctrineEntityConfig); + $this->assertArrayHasKey($laravelDBConfig['default'], $doctrineEntityConfig['entity_managers']); + $this->assertSame( + $basicDoctrineConfig['metadata'], + $doctrineEntityConfig['entity_managers'][$laravelDBConfig['default']]['metadata'] + ); + } + + + public function testCreateManagerInstances() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $basicDoctrineConfig['default_connection'] = 'pgsql'; + $basicDoctrineConfig['entity_managers'] = [ + 'pgsqlEntityManager' => [ + 'connection' => 'pgsql', + 'metadata' => $basicDoctrineConfig['metadata'] + ] + ]; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers, $defaults) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $this->assertEquals('pgsql', $defaults['connection']); + $this->assertEquals('pgsqlEntityManager', $defaults['entityManager']); + $this->assertArrayHasKey('pgsql', $registryConnections); + $this->assertArrayHasKey('pgsqlEntityManager', $registryManagers); + + } + + public function testUndefinedConnection() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $laravelDBConfig['default'] = 'misconfigure'; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $this->assertArrayNotHasKey('misconfigure', $registryConnections); + } +} diff --git a/tests/MultipleEntityManagersAndConnections/Models/User.php b/tests/MultipleEntityManagersAndConnections/Models/User.php new file mode 100644 index 0000000..0bb9c2e --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/Models/User.php @@ -0,0 +1,32 @@ +name; + } + + public function setName($name) + { + $this->name = $name; + } +} diff --git a/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php b/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php new file mode 100644 index 0000000..7473954 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php @@ -0,0 +1,53 @@ +getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $laravelDBConfig['default'] = 'sqlite'; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers, $defaults) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->containerStub, + $registryConnections, + $registryManagers, + $defaults['connection'], + $defaults['entityManager'] + ); + + foreach ($registry->getManagerNames() as $key => $value) { + $manager = $registry->getManager($key); + $tool = new SchemaTool($manager); + $sql = $tool->getCreateSchemaSql($manager->getMetadataFactory()->getAllMetadata()); + + $this->assertEquals( + 'CREATE TABLE user (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))', + implode(';'.PHP_EOL, $sql) + ); + } + + } +} From d18def87a942c83a9b1d2a48831d06e9afee240b Mon Sep 17 00:00:00 2001 From: Nathaniel Marrin Date: Tue, 20 Jan 2015 17:51:17 -0800 Subject: [PATCH 3/4] Added new tests and fixed errors in commands http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html states that a default entity manager should be created An em option has been added to commands --- composer.json | 3 +- src/Console/GenerateProxiesCommand.php | 48 +++--- src/Console/SchemaCreateCommand.php | 33 ++--- src/Console/SchemaDropCommand.php | 47 +++--- src/Console/SchemaUpdateCommand.php | 43 +++--- src/IlluminateRegistry.php | 8 +- src/LaravelDoctrineServiceProvider.php | 22 +-- .../AbstractDatabaseMappingTest.php | 44 ++---- .../DatabaseMappingTest.php | 47 +++++- .../GenerateProxiesCommandTestOutput.txt | 4 + .../SchemaCreateCommandTestOutput.txt | 3 + .../SchemaDropCommandTestOutput.txt | 2 + .../SchemaUpdateCommandTestOutput.txt | 3 + .../GenerateProxiesCommandTest.php | 121 +++++++++++++++ .../SchemaCreateCommandTest.php | 114 +++++++++++++-- .../SchemaDropCommandTest.php | 137 +++++++++++++++++ .../SchemaUpdateCommandTest.php | 138 ++++++++++++++++++ 17 files changed, 673 insertions(+), 144 deletions(-) create mode 100644 tests/MultipleEntityManagersAndConnections/ExpectedOutput/GenerateProxiesCommandTestOutput.txt create mode 100644 tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaCreateCommandTestOutput.txt create mode 100644 tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaDropCommandTestOutput.txt create mode 100644 tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaUpdateCommandTestOutput.txt create mode 100644 tests/MultipleEntityManagersAndConnections/GenerateProxiesCommandTest.php create mode 100644 tests/MultipleEntityManagersAndConnections/SchemaDropCommandTest.php create mode 100644 tests/MultipleEntityManagersAndConnections/SchemaUpdateCommandTest.php diff --git a/composer.json b/composer.json index eb3464c..37c2fed 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,12 @@ "require": { "php": ">=5.5.0", "illuminate/support": "4.*|5.*", - "illuminate/container": "4.*|5.*", "doctrine/orm": "2.5.*", "doctrine/migrations": "1.*" }, "require-dev": { + "illuminate/container": "4.*|5.*", + "illuminate/console": "4.*|5.*", "mockery/mockery": "dev-master", "phpunit/phpunit": "3.7.*" }, diff --git a/src/Console/GenerateProxiesCommand.php b/src/Console/GenerateProxiesCommand.php index 5b9c554..485a790 100644 --- a/src/Console/GenerateProxiesCommand.php +++ b/src/Console/GenerateProxiesCommand.php @@ -2,6 +2,7 @@ use Illuminate\Console\Command; use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Console\Input\InputOption; class GenerateProxiesCommand extends Command { @@ -36,24 +37,35 @@ public function __construct(ManagerRegistry $registry) public function fire() { $this->info('Starting proxy generation....'); - foreach ($this->registry->getManagerNames() as $key => $value) { - $manager = $this->registry->getManager($key); - $metadata = $manager->getMetadataFactory()->getAllMetadata(); - if (empty($metadata)) { - $this->error('No metadata found to generate any entities.'); - exit; - } - $directory = $this->laravel['config']['doctrine::doctrine.proxy.directory']; - if ( ! $directory) { - $this->error('The proxy directory has not been set.'); - exit; - } - $this->info('Processing entities:'); - foreach ($metadata as $item) { - $this->line($item->name); - } - $manager->getProxyFactory()->generateProxyClasses($metadata, $directory); - $this->info('Proxies have been created.'); + + if ($this->option('em')) { + $manager = $this->registry->getManager($this->option('em')); + } else { + $manager = $this->registry->getManager(); + } + + $metadata = $manager->getMetadataFactory()->getAllMetadata(); + if (empty($metadata)) { + $this->error('No metadata found to generate any entities.'); + exit; + } + $directory = $manager->getConfiguration()->getProxyDir(); + if (! $directory) { + $this->error('The proxy directory has not been set.'); + exit; } + $this->info('Processing entities:'); + foreach ($metadata as $item) { + $this->line($item->name); + } + $manager->getProxyFactory()->generateProxyClasses($metadata, $directory); + $this->info('Proxies have been created.'); + } + + protected function getOptions() + { + return [ + ['em', false, InputOption::VALUE_REQUIRED, 'Sets the entity manager when the default is not desired.'], + ]; } } diff --git a/src/Console/SchemaCreateCommand.php b/src/Console/SchemaCreateCommand.php index d036b0f..55605b9 100644 --- a/src/Console/SchemaCreateCommand.php +++ b/src/Console/SchemaCreateCommand.php @@ -21,13 +21,6 @@ class SchemaCreateCommand extends Command */ protected $description = 'Create database schema from models'; - /** - * The schema tool. - * - * @var \Doctrine\ORM\Tools\SchemaTool - */ - private $tool; - /** * The ManagerRegistry * @@ -35,11 +28,10 @@ class SchemaCreateCommand extends Command */ private $registry; - public function __construct(SchemaTool $tool, ManagerRegistry $registry) + public function __construct(ManagerRegistry $registry) { parent::__construct(); - $this->tool = $tool; $this->registry = $registry; } @@ -50,19 +42,21 @@ public function __construct(SchemaTool $tool, ManagerRegistry $registry) */ public function fire() { + if ($this->option('em')) { + $manager = $this->registry->getManager($this->option('em')); + } else { + $manager = $this->registry->getManager(); + } + + $tool = new SchemaTool($manager); + if ($this->option('sql')) { $this->info('Outputting create query:'.PHP_EOL); - foreach ($this->registry->getManagerNames() as $key => $value) { - $manager = $this->registry->getManager($key); - $sql = $this->tool->getCreateSchemaSql($manager->getMetadataFactory()->getAllMetadata()); - $this->info(implode(';'.PHP_EOL, $sql)); - } + $sql = $tool->getCreateSchemaSql($manager->getMetadataFactory()->getAllMetadata()); + $this->info(implode(';'.PHP_EOL, $sql)); } else { $this->info('Creating database schema...'); - foreach ($this->registry->getManagerNames() as $key => $value) { - $manager = $this->registry->getManager($key); - $this->tool->createSchema($manager->getMetadataFactory()->getAllMetadata()); - } + $tool->createSchema($manager->getMetadataFactory()->getAllMetadata()); $this->info('Schema has been created!'); } } @@ -70,7 +64,8 @@ public function fire() protected function getOptions() { return [ - ['sql', false, InputOption::VALUE_NONE, 'Dumps SQL query and does not execute creation.'] + ['sql', false, InputOption::VALUE_NONE, 'Dumps SQL query and does not execute creation.'], + ['em', false, InputOption::VALUE_REQUIRED, 'Sets the entity manager when the default is not desired.'], ]; } } diff --git a/src/Console/SchemaDropCommand.php b/src/Console/SchemaDropCommand.php index 548d06b..eb90f69 100644 --- a/src/Console/SchemaDropCommand.php +++ b/src/Console/SchemaDropCommand.php @@ -21,13 +21,6 @@ class SchemaDropCommand extends Command */ protected $description = 'Drop database schema'; - /** - * The schema tool. - * - * @var \Doctrine\ORM\Tools\SchemaTool - */ - private $tool; - /** * The ManagerRegistry * @@ -35,11 +28,10 @@ class SchemaDropCommand extends Command */ private $registry; - public function __construct(SchemaTool $tool, ManagerRegistry $registry) + public function __construct(ManagerRegistry $registry) { parent::__construct(); - $this->tool = $tool; $this->registry = $registry; } @@ -50,21 +42,27 @@ public function __construct(SchemaTool $tool, ManagerRegistry $registry) */ public function fire() { - foreach ($this->registry->getManagerNames() as $key => $value) { - $manager = $this->registry->getManager($key); - $sql = $this->tool->getDropSchemaSQL($manager->getMetadataFactory()->getAllMetadata()); - if (empty($sql)) { - $this->info('Current models do not exist in schema.'); - continue; - } - if ($this->option('sql')) { - $this->info('Outputting drop query:'); - $this->info(implode(';' . PHP_EOL, $sql)); - } else { - $this->info('Dropping database schema....'); - $this->tool->dropSchema($manager->getMetadataFactory()->getAllMetadata()); - $this->info('Schema has been dropped!'); - } + if ($this->option('em')) { + $manager = $this->registry->getManager($this->option('em')); + } else { + $manager = $this->registry->getManager(); + } + + $tool = new SchemaTool($manager); + + $sql = $tool->getDropSchemaSQL($manager->getMetadataFactory()->getAllMetadata()); + if (empty($sql)) { + $this->info('Current models do not exist in schema.'); + exit; + } + if ($this->option('sql')) { + $this->info('Outputting drop query:'); + $sql = $tool->getDropSchemaSQL($manager->getMetadataFactory()->getAllMetadata()); + $this->info(implode(';' . PHP_EOL, $sql)); + } else { + $this->info('Dropping database schema....'); + $tool->dropSchema($manager->getMetadataFactory()->getAllMetadata()); + $this->info('Schema has been dropped!'); } } @@ -72,6 +70,7 @@ protected function getOptions() { return [ ['sql', false, InputOption::VALUE_NONE, 'Dumps SQL query and does not execute drop.'], + ['em', false, InputOption::VALUE_REQUIRED, 'Sets the entity manager when the default is not desired.'], ]; } } diff --git a/src/Console/SchemaUpdateCommand.php b/src/Console/SchemaUpdateCommand.php index 0eaf405..3e83eec 100644 --- a/src/Console/SchemaUpdateCommand.php +++ b/src/Console/SchemaUpdateCommand.php @@ -35,11 +35,10 @@ class SchemaUpdateCommand extends Command */ private $registry; - public function __construct(SchemaTool $tool, ManagerRegistry $registry) + public function __construct(ManagerRegistry $registry) { parent::__construct(); - $this->tool = $tool; $this->registry = $registry; } @@ -52,21 +51,28 @@ public function fire() { $this->info('Checking if database needs updating....'); $clean = $this->option('clean'); - foreach ($this->registry->getManagerNames() as $key => $value) { - $manager = $this->registry->getManager($key); - $sql = $this->tool->getUpdateSchemaSql($manager->getMetadataFactory()->getAllMetadata(), $clean); - if (empty($sql)) { - $this->info('No updates found.'); - continue; - } - if ($this->option('sql')) { - $this->info('Outputting update query:'); - $this->info(implode(';' . PHP_EOL, $sql)); - } else { - $this->info('Updating database schema....'); - $this->tool->updateSchema($this->metadata->getAllMetadata()); - $this->info('Schema has been updated!'); - } + + if ($this->option('em')) { + $manager = $this->registry->getManager($this->option('em')); + } else { + $manager = $this->registry->getManager(); + } + + $tool = new SchemaTool($manager); + + $sql = $tool->getUpdateSchemaSql($manager->getMetadataFactory()->getAllMetadata(), $clean); + + if (empty($sql)) { + $this->info('No updates found.'); + exit; + } + if ($this->option('sql')) { + $this->info('Outputting update query:'); + $this->info(implode(';' . PHP_EOL, $sql)); + } else { + $this->info('Updating database schema....'); + $tool->updateSchema($manager->getMetadataFactory()->getAllMetadata()); + $this->info('Schema has been updated!'); } } @@ -74,7 +80,8 @@ protected function getOptions() { return [ ['sql', false, InputOption::VALUE_NONE, 'Dumps SQL query and does not execute update.'], - ['clean', null, InputOption::VALUE_OPTIONAL, 'When using clean model all non-relevant to this metadata assets will be cleared.'] + ['clean', null, InputOption::VALUE_OPTIONAL, 'When using clean model all non-relevant to this metadata assets will be cleared.'], + ['em', false, InputOption::VALUE_REQUIRED, 'Sets the entity manager when the default is not desired.'], ]; } } diff --git a/src/IlluminateRegistry.php b/src/IlluminateRegistry.php index b2a06e5..e47556d 100644 --- a/src/IlluminateRegistry.php +++ b/src/IlluminateRegistry.php @@ -14,17 +14,15 @@ final class IlluminateRegistry extends AbstractManagerRegistry public function __construct( Container $container, array $connections, - array $entityManagers, - $defaultConnection, - $defaultEntityManager + array $entityManagers ) { $this->container = $container; parent::__construct( 'ORM', $connections, $entityManagers, - $defaultConnection, - $defaultEntityManager, + 'default', + 'default', 'Doctrine\ORM\Proxy\Proxy' ); } diff --git a/src/LaravelDoctrineServiceProvider.php b/src/LaravelDoctrineServiceProvider.php index dfa7cda..9f5e5d9 100644 --- a/src/LaravelDoctrineServiceProvider.php +++ b/src/LaravelDoctrineServiceProvider.php @@ -129,7 +129,6 @@ private function createManagerInstances($config, $databaseConnections, $debug, C { $registryConnections = []; $registryManagers = []; - $defaults = ['connection' => null, 'entityManager' => null]; $proxyNamespace = isset($config['proxy']['namespace']) ? $config['proxy']['namespace'] : null; @@ -144,11 +143,6 @@ private function createManagerInstances($config, $databaseConnections, $debug, C continue; } - if ($connectionName === $config['default_connection']) { - $defaults['connection'] = $connectionName; - $defaults['entityManager'] = $name; - } - $databaseConfig = $databaseConnections[$connectionName]; $cacheProvider = isset($managerConfig['cache_provider']) ? $managerConfig['cache_provider'] : $config['cache_provider']; $repository = isset($managerConfig['repository']) ? $managerConfig['repository'] : $config['repository']; @@ -182,9 +176,17 @@ private function createManagerInstances($config, $databaseConnections, $debug, C $this->app->instance($registryConnections[$connectionName], $connection); $this->app->instance($registryManagers[$name], $entityManager); + if ($connectionName === $config['default_connection']) { + $registryConnections['default'] = 'doctrine.dbal.default_connection'; + $registryManagers['default'] = 'doctrine.orm.default_entity_manager'; + + $this->app->instance('doctrine.dbal.default_connection', $connection); + $this->app->instance('doctrine.orm.default_entity_manager', $entityManager); + } + } - return [$registryConnections, $registryManagers, $defaults]; + return [$registryConnections, $registryManagers]; } private function registerManagerRegistry() @@ -196,7 +198,7 @@ private function registerManagerRegistry() $config = $this->mapEntityManagers($config, $defaultDatabase); - list($registryConnections, $registryManagers, $defaults) = $this->createManagerInstances( + list($registryConnections, $registryManagers) = $this->createManagerInstances( $config, $databaseConnections, $app['config']['app.debug'], @@ -206,9 +208,7 @@ private function registerManagerRegistry() return new IlluminateRegistry( $app, $registryConnections, - $registryManagers, - $defaults['connection'], - $defaults['entityManager'] + $registryManagers ); }); $this->app->singleton(ManagerRegistry::class, IlluminateRegistry::class); diff --git a/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php b/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php index 800c9e3..46356fb 100644 --- a/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php +++ b/tests/MultipleEntityManagersAndConnections/AbstractDatabaseMappingTest.php @@ -16,8 +16,7 @@ abstract class AbstractDatabaseMappingTest extends \PHPUnit_Framework_TestCase { protected $sp; - protected $containerStub; - protected $containerInstances = array(); + protected $container; protected function callMethod($obj, $name, array $args) { @@ -27,18 +26,6 @@ protected function callMethod($obj, $name, array $args) return $method->invokeArgs($obj, $args); } - public function make($abstract, $parameters = array()) - { - if (isset($this->containerInstances[$abstract])) { - return $this->containerInstances[$abstract]; - } - } - - public function instance($abstract, $instance) - { - $this->containerInstances[$abstract] = $instance; - } - protected function createCacheManager($cacheConfig) { $manager = new CacheManager($cacheConfig); @@ -100,7 +87,7 @@ protected function getBasicDoctrineConfiguration() 'simple_annotations' => false, 'metadata' => [ - __DIR__.'/Models', + __DIR__.DIRECTORY_SEPARATOR.'Models', ], 'proxy' => [ @@ -134,20 +121,17 @@ protected function getBasicDoctrineConfiguration() public function setUp() { - $mapper = new DriverMapper; - $mapper->registerMapper(new SqlMapper); - $mapper->registerMapper(new SqliteMapper); - - $this->containerInstances[DriverMapper::class] = $mapper; - - $containerStub = $this->getMock('\Illuminate\Container\Container'); - $containerStub->expects($this->any()) - ->method('make') - ->will($this->returnCallback([$this,'make'])); - $containerStub->expects($this->any()) - ->method('instance') - ->will($this->returnCallback([$this,'instance'])); - $this->sp = new LaravelDoctrineServiceProvider($containerStub); - $this->containerStub = $containerStub; + + $container = new Container(); + + $container->bind(DriverMapper::class, function () { + $mapper = new DriverMapper; + $mapper->registerMapper(new SqlMapper); + $mapper->registerMapper(new SqliteMapper); + return $mapper; + }); + + $this->sp = new LaravelDoctrineServiceProvider($container); + $this->container = $container; } } diff --git a/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php b/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php index 334d052..253b50c 100644 --- a/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php +++ b/tests/MultipleEntityManagersAndConnections/DatabaseMappingTest.php @@ -1,5 +1,7 @@ callMethod( + list($registryConnections, $registryManagers) = $this->callMethod( $this->sp, 'createManagerInstances', array( @@ -53,11 +55,50 @@ public function testCreateManagerInstances() ) ); - $this->assertEquals('pgsql', $defaults['connection']); - $this->assertEquals('pgsqlEntityManager', $defaults['entityManager']); $this->assertArrayHasKey('pgsql', $registryConnections); $this->assertArrayHasKey('pgsqlEntityManager', $registryManagers); + } + + public function testRegistryInstances() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $em = $registry->getManager('mysql'); + + $this->assertSame($em, $registry->getManager()); + $this->assertSame($em, $registry->getManager('default')); + $this->assertSame($em, $this->container->make('doctrine.orm.mysql_entity_manager')); + $this->assertSame($em, $this->container->make('doctrine.orm.default_entity_manager')); + $con = $registry->getConnection('mysql'); + $this->assertSame($con, $registry->getConnection()); + $this->assertSame($con, $registry->getConnection('default')); + $this->assertSame($con, $this->container->make('doctrine.dbal.mysql_connection')); + $this->assertSame($con, $this->container->make('doctrine.dbal.default_connection')); } public function testUndefinedConnection() diff --git a/tests/MultipleEntityManagersAndConnections/ExpectedOutput/GenerateProxiesCommandTestOutput.txt b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/GenerateProxiesCommandTestOutput.txt new file mode 100644 index 0000000..68e18ac --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/GenerateProxiesCommandTestOutput.txt @@ -0,0 +1,4 @@ +Starting proxy generation.... +Processing entities: +Tests\MultipleEntityManagersAndConnections\Models\User +Proxies have been created. diff --git a/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaCreateCommandTestOutput.txt b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaCreateCommandTestOutput.txt new file mode 100644 index 0000000..98dd586 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaCreateCommandTestOutput.txt @@ -0,0 +1,3 @@ +Outputting create query: + +CREATE TABLE user (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) diff --git a/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaDropCommandTestOutput.txt b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaDropCommandTestOutput.txt new file mode 100644 index 0000000..ebb11d2 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaDropCommandTestOutput.txt @@ -0,0 +1,2 @@ +Outputting drop query: +DROP TABLE user diff --git a/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaUpdateCommandTestOutput.txt b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaUpdateCommandTestOutput.txt new file mode 100644 index 0000000..ad51d4c --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/ExpectedOutput/SchemaUpdateCommandTestOutput.txt @@ -0,0 +1,3 @@ +Checking if database needs updating.... +Outputting update query: +CREATE TABLE user (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) diff --git a/tests/MultipleEntityManagersAndConnections/GenerateProxiesCommandTest.php b/tests/MultipleEntityManagersAndConnections/GenerateProxiesCommandTest.php new file mode 100644 index 0000000..10af2bd --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/GenerateProxiesCommandTest.php @@ -0,0 +1,121 @@ +expected = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'ExpectedOutput'.DIRECTORY_SEPARATOR.'GenerateProxiesCommandTestOutput.txt'); + } + + public function testDefaultGenerate() + { + + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $laravelDBConfig['default'] = 'sqlite'; + $basicDoctrineConfig['proxy']['directory'] = sys_get_temp_dir(); + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new GenerateProxiesCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput([]); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + } + + public function testSpecificGenerate() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + $basicDoctrineConfig['proxy']['directory'] = sys_get_temp_dir(); + + $basicDoctrineConfig['entity_managers'] = [ + 'pgsql' => [ + 'connection' => 'pgsql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'mysql' => [ + 'connection' => 'mysql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'sqlite' => [ + 'connection' => 'sqlite', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + + ]; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new GenerateProxiesCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--em' => 'sqlite']); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + } +} diff --git a/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php b/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php index 7473954..7a6b7db 100644 --- a/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php +++ b/tests/MultipleEntityManagersAndConnections/SchemaCreateCommandTest.php @@ -2,11 +2,22 @@ use Mitch\LaravelDoctrine\IlluminateRegistry; use Doctrine\ORM\Tools\SchemaTool; +use Mitch\LaravelDoctrine\Console\SchemaCreateCommand; +use Mitch\LaravelDoctrine\Console\SchemaDropCommand; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\BufferedOutput; class SchemaCreateCommandTest extends AbstractDatabaseMappingTest { + protected $expected; - public function testCreateSchemaSql() + public function setup() + { + parent::setup(); + $this->expected = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'ExpectedOutput'.DIRECTORY_SEPARATOR.'SchemaCreateCommandTestOutput.txt'); + } + + public function testDefaultCreate() { $laravelDBConfig = $this->getLaravelDBConfig(); $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); @@ -19,7 +30,7 @@ public function testCreateSchemaSql() array($basicDoctrineConfig, $laravelDBConfig['default']) ); - list($registryConnections, $registryManagers, $defaults) = $this->callMethod( + list($registryConnections, $registryManagers) = $this->callMethod( $this->sp, 'createManagerInstances', array( @@ -31,23 +42,96 @@ public function testCreateSchemaSql() ); $registry = new IlluminateRegistry( - $this->containerStub, + $this->container, $registryConnections, - $registryManagers, - $defaults['connection'], - $defaults['entityManager'] + $registryManagers + ); + + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--sql' => null]); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() ); - foreach ($registry->getManagerNames() as $key => $value) { - $manager = $registry->getManager($key); - $tool = new SchemaTool($manager); - $sql = $tool->getCreateSchemaSql($manager->getMetadataFactory()->getAllMetadata()); + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput([]); + $command->run($input, $output); + + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $command->run($input, $output); + } + + public function testSpecificCreate() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $basicDoctrineConfig['entity_managers'] = [ + 'pgsql' => [ + 'connection' => 'pgsql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'mysql' => [ + 'connection' => 'mysql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'sqlite' => [ + 'connection' => 'sqlite', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + + ]; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--sql' => null, '--em' => 'sqlite']); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); - $this->assertEquals( - 'CREATE TABLE user (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))', - implode(';'.PHP_EOL, $sql) - ); - } + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--em' => 'sqlite']); + $command->run($input, $output); + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $command->run($input, $output); } } diff --git a/tests/MultipleEntityManagersAndConnections/SchemaDropCommandTest.php b/tests/MultipleEntityManagersAndConnections/SchemaDropCommandTest.php new file mode 100644 index 0000000..01c9df5 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/SchemaDropCommandTest.php @@ -0,0 +1,137 @@ +expected = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'ExpectedOutput'.DIRECTORY_SEPARATOR.'SchemaDropCommandTestOutput.txt'); + } + + public function testDefaultDrop() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $laravelDBConfig['default'] = 'sqlite'; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $inputNoOptions = new ArrayInput([]); + $output = new BufferedOutput(); + + $command->run($inputNoOptions, $output); + + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $inputSql = new ArrayInput(['--sql' => null]); + $output = new BufferedOutput(); + + $command->run($inputSql, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + + $command->run($inputNoOptions, $output); + } + + public function testSpecificDrop() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $basicDoctrineConfig['entity_managers'] = [ + 'pgsql' => [ + 'connection' => 'pgsql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'mysql' => [ + 'connection' => 'mysql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'sqlite' => [ + 'connection' => 'sqlite', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + + ]; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new SchemaCreateCommand($registry); + $command->setLaravel($this->container); + $inputNoOptions = new ArrayInput(['--em' => 'sqlite']); + $output = new BufferedOutput(); + + $command->run($inputNoOptions, $output); + + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $inputSql = new ArrayInput(['--sql' => null,'--em' => 'sqlite']); + $output = new BufferedOutput(); + + $command->run($inputSql, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + + $command->run($inputNoOptions, $output); + } +} diff --git a/tests/MultipleEntityManagersAndConnections/SchemaUpdateCommandTest.php b/tests/MultipleEntityManagersAndConnections/SchemaUpdateCommandTest.php new file mode 100644 index 0000000..13d46a0 --- /dev/null +++ b/tests/MultipleEntityManagersAndConnections/SchemaUpdateCommandTest.php @@ -0,0 +1,138 @@ +expected = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'ExpectedOutput'.DIRECTORY_SEPARATOR.'SchemaUpdateCommandTestOutput.txt'); + } + + public function testDefaultUpdate() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $laravelDBConfig['default'] = 'sqlite'; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new SchemaUpdateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--sql' => null]); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + + $command = new SchemaUpdateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput([]); + $command->run($input, $output); + + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $command->run($input, $output); + } + + + public function testSpecificUpdate() + { + $laravelDBConfig = $this->getLaravelDBConfig(); + $basicDoctrineConfig = $this->getBasicDoctrineConfiguration(); + + $basicDoctrineConfig['entity_managers'] = [ + 'pgsql' => [ + 'connection' => 'pgsql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'mysql' => [ + 'connection' => 'mysql', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + 'sqlite' => [ + 'connection' => 'sqlite', + 'metadata' => $basicDoctrineConfig['metadata'] + ], + + ]; + + $doctrineEntityConfig = $this->callMethod( + $this->sp, + 'mapEntityManagers', + array($basicDoctrineConfig, $laravelDBConfig['default']) + ); + + list($registryConnections, $registryManagers) = $this->callMethod( + $this->sp, + 'createManagerInstances', + array( + $doctrineEntityConfig, + $laravelDBConfig['connections'], + false, + $this->createCacheManager($basicDoctrineConfig['cache']) + ) + ); + + $registry = new IlluminateRegistry( + $this->container, + $registryConnections, + $registryManagers + ); + + $command = new SchemaUpdateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--sql' => null, '--em' => 'sqlite']); + $output = new BufferedOutput(); + + $command->run($input, $output); + + $this->assertEquals( + $this->expected, + $output->fetch() + ); + + $command = new SchemaUpdateCommand($registry); + $command->setLaravel($this->container); + $input = new ArrayInput(['--em' => 'sqlite']); + $command->run($input, $output); + + $command = new SchemaDropCommand($registry); + $command->setLaravel($this->container); + $command->run($input, $output); + } +} From e91d9a58ba19743f745aa156c479f431702df721 Mon Sep 17 00:00:00 2001 From: Nathaniel Marrin Date: Mon, 26 Jan 2015 14:08:29 -0800 Subject: [PATCH 4/4] Ref mitchellvanw/laravel-doctrine#58 --- src/LaravelDoctrineServiceProvider.php | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/LaravelDoctrineServiceProvider.php b/src/LaravelDoctrineServiceProvider.php index 9f5e5d9..a34a13a 100644 --- a/src/LaravelDoctrineServiceProvider.php +++ b/src/LaravelDoctrineServiceProvider.php @@ -211,7 +211,7 @@ private function registerManagerRegistry() $registryManagers ); }); - $this->app->singleton(ManagerRegistry::class, IlluminateRegistry::class); + $this->app->alias(IlluminateRegistry::class, ManagerRegistry::class); } private function registerEntityManager() @@ -219,7 +219,7 @@ private function registerEntityManager() $this->app->singleton(EntityManager::class, function ($app) { return $app->make(IlluminateRegistry::class)->getManager(); }); - $this->app->singleton(EntityManagerInterface::class, EntityManager::class); + $this->app->alias(EntityManager::class, EntityManagerInterface::class); } private function registerClassMetadataFactory() @@ -240,24 +240,6 @@ private function extendAuthManager() }); } - /** - * Get the services provided by the provider. - * @return array - */ - public function provides() - { - return [ - CacheManager::class, - EntityManagerInterface::class, - EntityManager::class, - ClassMetadataFactory::class, - DriverMapper::class, - AuthManager::class, - ManagerRegistry::class, - IlluminateRegistry::class, - ]; - } - /** * Map Laravel's to Doctrine's database configuration requirements. * @param $databaseConfig