databaseParams = $databaseParams; $this->metadata = $metadata; $this->eventDispatcher = $eventDispatcher; $this->entityFactory = $entityFactory; $this->repositoryFactory = $repositoryFactory; $this->mapperFactory = $mapperFactory; $this->pdoProvider = $pdoProvider; if (!$this->databaseParams->getPlatform()) { throw new RuntimeException("No 'platform' parameter."); } $valueAccessorFactory = new ValueAccessorFactory( $valueFactoryFactory, $attributeExtractorFactory, $eventDispatcher ); $this->entityFactory->setEntityManager($this); $this->entityFactory->setValueAccessorFactory($valueAccessorFactory); $this->initQueryComposer(); $this->sqlExecutor = new SqlExecutor($this->pdoProvider->get()); $this->queryExecutor = new QueryExecutor($this->sqlExecutor, $this->queryComposer); $this->queryBuilder = new QueryBuilder(); $this->collectionFactory = new CollectionFactory($this); $this->transactionManager = new TransactionManager($this->pdoProvider->get(), $this->queryComposer); $this->initLocker(); } private function initQueryComposer(): void { $platform = $this->databaseParams->getPlatform(); $className = 'Espo\\ORM\\QueryComposer\\' . ucfirst($platform) . 'QueryComposer'; if (!class_exists($className)) { throw new RuntimeException("Query composer for '{$platform}' platform does not exits."); } $this->queryComposer = new $className($this->pdoProvider->get(), $this->entityFactory, $this->metadata); } private function initLocker(): void { $platform = $this->databaseParams->getPlatform(); $className = 'Espo\\ORM\\Locker\\' . ucfirst($platform) . 'Locker'; if (!class_exists($className)) { $className = BaseLocker::class; } $this->locker = new $className($this->pdoProvider->get(), $this->queryComposer, $this->transactionManager); } /** * @todo Remove in v7.0. * @deprecated */ public function getQuery(): QueryComposer { return $this->queryComposer; } public function getQueryComposer(): QueryComposer { return $this->queryComposer; } public function getTransactionManager(): TransactionManager { return $this->transactionManager; } public function getLocker(): Locker { return $this->locker; } /** * Get a Mapper. */ public function getMapper(string $name = self::RDB_MAPPER_NAME): Mapper { if (!array_key_exists($name, $this->mappers)) { $this->loadMapper($name); } return $this->mappers[$name]; } private function loadMapper(string $name): void { if ($name === self::RDB_MAPPER_NAME) { $className = $this->getRDBMapperClassName(); $this->mappers[$name] = new $className( $this->pdoProvider->get(), $this->entityFactory, $this->collectionFactory, $this->getQueryComposer(), $this->metadata, $this->sqlExecutor ); return; } if (!$this->mapperFactory) { throw new RuntimeException("Could not create mapper '{$name}'. No mapper factory."); } $this->mappers[$name] = $this->mapperFactory->create($name); } private function getRDBMapperClassName(): string { $platform = $this->databaseParams->getPlatform(); $className = 'Espo\\ORM\\Mapper\\' . ucfirst($platform) . 'Mapper'; if (!class_exists($className)) { throw new RuntimeException("Mapper for '{$platform}' does not exist."); } return $className; } /** * Get an entity. If $id is null, a new entity instance is created. * If an entity with a specified ID does not exist, then NULL is returned. */ public function getEntity(string $entityType, ?string $id = null): ?Entity { if (!$this->hasRepository($entityType)) { throw new RuntimeException("ORM: Repository '{$entityType}' does not exist."); } if ($id === null) { return $this->getRepository($entityType)->getNew(); } return $this->getRepository($entityType)->getById($id); } /** * Create a new entity instance (w/o storing to DB). */ public function getNewEntity(string $entityType): Entity { return $this->getEntity($entityType); } /** * Get an entity by ID. If an entity does not exist, NULL is returned. */ public function getEntityById(string $entityType, string $id): ?Entity { return $this->getEntity($entityType, $id); } /** * Store an entity. * * @return void * @todo Change return type to void in v6.3. */ public function saveEntity(Entity $entity, array $options = []) { $entityType = $entity->getEntityType(); $this->getRepository($entityType)->save($entity, $options); return $entity->id; } /** * Mark an entity as deleted (in database). */ public function removeEntity(Entity $entity, array $options = []): void { $entityType = $entity->getEntityType(); $this->getRepository($entityType)->remove($entity, $options); } /** * Create entity (and store to database). * * @param StdClass|array $data Entity attributes. */ public function createEntity(string $entityType, $data = [], array $options = []): Entity { $entity = $this->getEntity($entityType); $entity->set($data); $this->saveEntity($entity, $options); return $entity; } /** * Check whether a repository for a specific entity type exist. */ public function hasRepository(string $entityType): bool { return $this->getMetadata()->has($entityType); } /** * Get a repository for a specific entity type. */ public function getRepository(string $entityType): Repository { if (!$this->hasRepository($entityType)) { throw new RuntimeException("Repository '{$entityType}' does not exist."); } if (!array_key_exists($entityType, $this->repositoryHash)) { $this->repositoryHash[$entityType] = $this->repositoryFactory->create($entityType); } return $this->repositoryHash[$entityType]; } /** * Get an RDB repository for a specific entity type. */ public function getRDBRepository(string $entityType): RDBRepository { $repository = $this->getRepository($entityType); if (!$repository instanceof RDBRepository) { throw new RuntimeException("Repository '{$entityType}' is not RDB."); } return $repository; } /** * Get metadata definitions. */ public function getDefs(): Defs { return $this->metadata->getDefs(); } /** * Get a query builder. */ public function getQueryBuilder(): QueryBuilder { return $this->queryBuilder; } /** * Get metadata. */ public function getMetadata(): Metadata { return $this->metadata; } /** * @deprecated */ public function getPDO(): PDO { return $this->pdoProvider->get(); } /** * @deprecated Use `getCollectionFactory`. */ public function createCollection(?string $entityType = null, array $data = []): EntityCollection { return $this->collectionFactory->create($entityType, $data); } public function getEntityFactory(): EntityFactory { return $this->entityFactory; } public function getCollectionFactory(): CollectionFactory { return $this->collectionFactory; } /** * Get a Query Executor. */ public function getQueryExecutor(): QueryExecutor { return $this->queryExecutor; } /** * Get SQL Executor. */ public function getSqlExecutor(): SqlExecutor { return $this->sqlExecutor; } }