Nettrine, doctrine a table prefix listener

pilarik31
Člen | 4
+
0
-

Ahoj,

řešil jste prosím někdo implementaci Nettrine, Doctrine, a TablePrefixListener?
Zkoušel jsem se inspirovat zde

Jde mi o to, aby mi Doctrina do databáze sám doplňoval prefix tj. např. „ns_“ pro všechny tabulky.

Děkuji,
Honza

Gappa
Nette Blogger | 199
+
+2
-

Na tohle by mohlo stačit použít vlastní naming strategy:

Extendnout standardní a přetížit metodu classToTableName a tam udělat něco takového:

namespace My\Custom;

use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;

class CustomNamingStrategy extends UnderscoreNamingStrategy
{
	function classToTableName($className) {
		return 'ns_' . parent::classToTableName($className);
	}
}

Následně zaregistrovat:

nettrine.orm:
	configuration:
		namingStrategy: My\Custom\NamingStrategy

Kde nettrine.orm je tato extension:

  • Nettrine\ORM\DI\OrmExtension

Těch strategií je více:

Snad jsem to napsal správně :)

Editoval Gappa (30. 1. 8:09)

pilarik31
Člen | 4
+
+1
-

Ahoj,

podařilo se mi to dle tvých instrukcí hned napoprvé opravit. :)

Mockrát děkuji.

Petr Parolek
Člen | 455
+
0
-

Kdysi kdesi jsem našel na internetu a použil:

<?php declare(strict_types = 1);

namespace App\Model;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Mapping\ClassMetadataInfo;

final class TablePrefixSubscriber implements EventSubscriber
{

	/** @var string */
	public $prefix = '';

	public function __construct(string $prefix)
	{
		$this->prefix = $prefix;
	}

	public function getSubscribedEvents(): array
	{
		return ['loadClassMetadata'];
	}

	public function loadClassMetadata(LoadClassMetadataEventArgs $args): void
	{
		$classMetadata = $args->getClassMetadata();

		if (strlen($this->prefix) > 0) {
			// Only add the prefixes to our own entities.
			//if (FALSE !== strpos($classMetadata->namespace, 'Some\Namespace\Part')) {
			// Do not re-apply the prefix when the table is already prefixed
			if (strpos($classMetadata->getTableName(), $this->prefix) === false) {
				$tableName = $this->prefix . $classMetadata->getTableName();
				$classMetadata->setPrimaryTable(['name' => $tableName]);
			}

			foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
				if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide'] === true) {
					$mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name'];

					// Do not re-apply the prefix when the association is already prefixed
					if (strpos($mappedTableName, $this->prefix) !== false) {
						continue;
					}

					$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
				}
			}
		}
	}

}

a registrace do DI:

services:
	subscriber1:
		create: App\Model\TablePrefixSubscriber('foo_')
		tags: [nettrine.subscriber]
Petr Parolek
Člen | 455
+
0
-

Gappa napsal(a):

Na tohle by mohlo stačit použít vlastní naming strategy:

Extendnout standardní a přetížit metodu `classToTableName˙ a tam udělat něco takového:

namespace My\Custom;

use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;

class CustomNamingStrategy extends UnderscoreNamingStrategy
{
	function classToTableName($className) {
		return 'ns_' . parent::classToTableName($className);
	}
}

Následně zaregistrovat:

nettrine.orm:
	configuration:
		namingStrategy: My\Custom\NamingStrategy

Kde nettrine.orm je tato extension:

  • Nettrine\ORM\DI\OrmExtension

Těch strategií je více:

Snad jsem to napsal správně :)

Super, koukám, že to jde i jednoduššeji. Takže tohle taky funguje, jak má?

Gappa
Nette Blogger | 199
+
0
-

Super, koukám, že to jde i jednoduššeji. Takže tohle taky funguje, jak má?

Pro mé použití ano (změna názvu tabulek, i joinovacích), zbytek musíš otestovat sám :)

Editoval Gappa (11. 3. 2021 20:51)