Doctrine ODM Выбор базы данных во время выполнения

Я хочу использовать доктрину ODM для своего проекта, и у меня была идея создать отдельную базу данных для каждого из моих клиентов. Я хочу иметь возможность управлять клиентами во время выполнения через мой API. Мой вопрос сейчас:

Когда я настраиваю доктрину ODM, мне нужно установить настройки базы данных в моем файле settings.yml, но я хочу иметь возможность выбирать базу данных во время выполнения. У меня будет одна основная база данных со всеми моими коллекциями приборов и клиентским индексом, чтобы знать, какую базу данных выбрать, но в этих клиентских базах данных будут специфические для клиента вещи. Каждый класс Document будет по-прежнему связан с коллекцией, как в обычной ситуации, но затем в другой базе данных.

Есть ли способ выбрать базу данных для класса документа во время выполнения?

Допустим, я иду на www.myproject.com/client1/item/list
Я перечислю каждый элемент в коллекции dbclient1.Items, и если я зайду на www.myproject.com/client2/item/list, я перечислю все элементы в коллекции dbclient2.Items.

Я надеюсь, что ясно дал понять, чего я хочу достичь здесь … Я ничего не мог найти по этому поводу, но я думаю, что было бы странно, если бы я был первым человеком, который задал вопрос об этом … Должно быть, были люди до меня с той же идеей не так ли?

1

Решение

Есть ли способ выбрать базу данных для класса документа во время выполнения?

Да, вы можете позвонить $dm->getConfiguration()->setDefaultDb('some_db_name') каждый раз, когда вам нужно изменить базу данных, но это может привести к неожиданному поведению, когда запись вступает в игру.

Исходя из моего опыта (и нескольких лет практики в мультитенантных приложениях), самый пуленепробиваемый способ — это создавать отдельные экземпляры DocumentManager за каждый контекст. Вы можете достичь этого, имея один DocumentManager обычно настраивается с вашими параметрами, но никогда не используется напрямую — вместо этого вам нужен класс, который будет управлять его экземплярами, например:

use Doctrine\ODM\MongoDB\DocumentManager;

class DocumentManagerFactory
{
/**
* DocumentManager created by Symfony.
*
* @var DocumentManager
*/
private $defaultDocumentManager;

/**
* All DocumentManagers created by Factory so far.
*
* @var DocumentManager[]
*/
private $instances = array();

public function __construct(DocumentManager $dm)
{
$this->defaultDocumentManager = $dm;
}

public function createFor(Context $ctx)
{
$databaseName = $ctx->getDatabaseName();
if (isset($this->instances[$databaseName])) {
return $this->instances[$databaseName];
}
$configuration = clone $this->defaultDocumentManager->getConfiguration();
$configuration->setDefaultDB($databaseName);
return $this->instances[$databaseName] = DocumentManager::create(
$this->defaultDocumentManager->getConnection(),
$configuration,
$this->defaultDocumentManager->getEventManager()
);
}
}

Благодаря такому подходу документы из нескольких баз данных никогда не будут управляться одним DocumentManagerу вас есть один класс, отвечающий за вмешательство с сохранением конфигурации ODM и рамочного подхода (подписчики событий и др. одинаковы для каждого DocumentManager).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]