EntityManager::createQueryBuilder()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 4
nc 3
nop 2
1
<?php
2
3
/**
4
 * This file is part of the Kdyby (http://www.kdyby.org)
5
 *
6
 * Copyright (c) 2008 Filip Procházka ([email protected])
7
 *
8
 * For the full copyright and license information, please view the file license.txt that was distributed with this source code.
9
 */
10
11
namespace Kdyby\Doctrine;
12
13
use Doctrine;
14
use Doctrine\DBAL\DriverManager;
15
use Doctrine\ORM\AbstractQuery;
16
use Doctrine\ORM\ORMException;
17
use Doctrine\ORM\Query;
18
use Kdyby;
19
use Kdyby\Doctrine\Diagnostics\EntityManagerUnitOfWorkSnapshotPanel;
20
use Kdyby\Doctrine\QueryObject;
21
use Kdyby\Doctrine\Tools\NonLockingUniqueInserter;
22
use Kdyby\Persistence;
23
use Nette;
24
25
26
27
/**
28
 * @author Filip Procházka <[email protected]>
29
 *
30
 * @method \Kdyby\Doctrine\Connection getConnection()
31
 * @method \Kdyby\Doctrine\Configuration getConfiguration()
32
 * @method \Kdyby\Doctrine\EntityRepository getRepository($entityName)
33
 */
34
class EntityManager extends Doctrine\ORM\EntityManager implements Persistence\QueryExecutor, Persistence\Queryable
35
{
36
37
	use \Kdyby\StrictObjects\Scream;
38
39
	/**
40
	 * @var NonLockingUniqueInserter
41
	 */
42
	private $nonLockingUniqueInserter;
43
44
	/**
45
	 * @var \Kdyby\Doctrine\Diagnostics\EntityManagerUnitOfWorkSnapshotPanel
46
	 */
47
	private $panel;
48
49
50
51
	protected function __construct(Doctrine\DBAL\Connection $conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager)
52
	{
53
		parent::__construct($conn, $config, $eventManager);
54
55
		if ($conn instanceof Kdyby\Doctrine\Connection) {
56
			$conn->bindEntityManager($this);
57
		}
58
	}
59
60
61
62
	/**
63
	 * @internal
64
	 * @param EntityManagerUnitOfWorkSnapshotPanel $panel
65
	 */
66
	public function bindTracyPanel(EntityManagerUnitOfWorkSnapshotPanel $panel)
67
	{
68
		$this->panel = $panel;
69
	}
70
71
72
73
	/**
74
	 * @throws NotSupportedException
75
	 * @return \Kdyby\Doctrine\QueryBuilder
76
	 */
77
	public function createQueryBuilder($alias = NULL, $indexBy = NULL)
78
	{
79
		if ($alias !== NULL || $indexBy !== NULL) {
80
			throw new NotSupportedException('Use EntityRepository for $alias and $indexBy arguments to work.');
81
		}
82
83
		$config = $this->getConfiguration();
84
		if ($config instanceof Configuration) {
85
			$class = $config->getQueryBuilderClassName();
86
			return new $class($this);
87
		}
88
89
		return new QueryBuilder($this);
90
	}
91
92
93
94
	/**
95
	 * @param string|array|null $entityName if given, only entities of this type will get detached
96
	 * @return EntityManager
97
	 */
98
	public function clear($entityName = null)
99
	{
100
		foreach (is_array($entityName) ? $entityName : (func_get_args() + [0 => NULL]) as $item) {
101
			parent::clear($item);
102
		}
103
104
		return $this;
105
	}
106
107
108
109
	/**
110
	 * @param object|array $entity
111
	 * @return EntityManager
112
	 */
113
	public function remove($entity)
114
	{
115
		foreach (is_array($entity) ? $entity : func_get_args() as $item) {
116
			parent::remove($item);
117
		}
118
119
		return $this;
120
	}
121
122
123
124
	/**
125
	 * @param object|array $entity
126
	 * @return EntityManager
127
	 */
128
	public function persist($entity)
129
	{
130
		foreach (is_array($entity) ? $entity : func_get_args() as $item) {
131
			parent::persist($item);
132
		}
133
134
		return $this;
135
	}
136
137
138
139
	/**
140
	 * @param object|array|NULL $entity
141
	 * @return EntityManager
142
	 */
143
	public function flush($entity = null)
144
	{
145
		try {
146
			parent::flush($entity);
147
148
		} catch (\Exception $e) {
149
			if ($this->panel) {
150
				$this->panel->markExceptionOwner($this, $e);
151
			}
152
153
			throw $e;
154
		}
155
156
		return $this;
157
	}
158
159
160
161
	public function close()
162
	{
163
		if ($this->panel) {
164
			$this->panel->snapshotUnitOfWork($this);
165
		}
166
167
		parent::close();
168
	}
169
170
171
172
	/**
173
	 * Tries to persist the given entity and returns FALSE if an unique
174
	 * constaint was violated.
175
	 *
176
	 * Warning: On success you must NOT use the passed entity further
177
	 * in your application. Use the returned one instead!
178
	 *
179
	 * @param mixed $entity
180
	 * @throws \Doctrine\DBAL\DBALException
181
	 * @throws \Exception
182
	 * @return bool|object
183
	 */
184
	public function safePersist($entity)
185
	{
186
		if ($this->nonLockingUniqueInserter === NULL) {
187
			$this->nonLockingUniqueInserter = new NonLockingUniqueInserter($this);
188
		}
189
190
		return $this->nonLockingUniqueInserter->persist($entity);
191
	}
192
193
194
195
	/**
196
	 * @param int $hydrationMode
197
	 * @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
198
	 * @throws \Doctrine\ORM\ORMException
199
	 */
200
	public function newHydrator($hydrationMode)
201
	{
202
		switch ($hydrationMode) {
203
			case Hydration\HashHydrator::NAME:
204
				return new Hydration\HashHydrator($this);
205
206
			default:
207
				return parent::newHydrator($hydrationMode);
208
		}
209
	}
210
211
212
213
	/**
214
	 * Factory method to create EntityManager instances.
215
	 *
216
	 * @param \Doctrine\DBAL\Connection|array $conn
217
	 * @param \Doctrine\ORM\Configuration $config
218
	 * @param \Doctrine\Common\EventManager $eventManager
219
	 * @throws \Doctrine\ORM\ORMException
220
	 * @throws \InvalidArgumentException
221
	 * @throws \Doctrine\ORM\ORMException
222
	 * @return EntityManager
223
	 */
224
	public static function create($conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager = NULL)
225
	{
226
		if (!$config->getMetadataDriverImpl()) {
227
			throw ORMException::missingMappingDriverImpl();
228
		}
229
230
		if (is_array($conn)) {
231
			$connection = DriverManager::getConnection(
232
				$conn, $config, ($eventManager ?: new Doctrine\Common\EventManager())
233
			);
234
		} elseif ($conn instanceof Doctrine\DBAL\Connection) {
235
			if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
236
				throw ORMException::mismatchedEventManager();
237
			}
238
			$connection = $conn;
239
		} else {
240
			throw new \InvalidArgumentException("Invalid connection");
241
		}
242
243
		return new EntityManager($connection, $config, $connection->getEventManager());
244
	}
245
246
247
248
	/****************** Kdyby\Persistence\QueryExecutor *****************/
249
250
251
252
	/**
253
	 * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject
254
	 * @param int $hydrationMode
255
	 * @throws QueryException
256
	 * @return array|\Kdyby\Doctrine\ResultSet
257
	 */
258
	public function fetch(Persistence\Query $queryObject, $hydrationMode = AbstractQuery::HYDRATE_OBJECT)
259
	{
260
		try {
261
			return $queryObject->fetch($this, $hydrationMode);
262
263
		} catch (\Exception $e) {
264
			throw $this->handleQueryException($e, $queryObject);
265
		}
266
	}
267
268
269
270
	/**
271
	 * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject
272
	 *
273
	 * @throws InvalidStateException
274
	 * @throws QueryException
275
	 * @return object|NULL
276
	 */
277
	public function fetchOne(Persistence\Query $queryObject)
278
	{
279
		try {
280
			return $queryObject->fetchOne($this);
281
282
		} catch (Doctrine\ORM\NoResultException $e) {
283
			return NULL;
284
285
		} catch (Doctrine\ORM\NonUniqueResultException $e) { // this should never happen!
286
			throw new InvalidStateException("You have to setup your query calling ->setMaxResult(1).", 0, $e);
287
288
		} catch (\Exception $e) {
289
			throw $this->handleQueryException($e, $queryObject);
290
		}
291
	}
292
293
294
295
	/**
296
	 * @param \Exception $e
297
	 * @param \Kdyby\Persistence\Query $queryObject
298
	 *
299
	 * @throws \Exception
300
	 */
301
	private function handleQueryException(\Exception $e, Persistence\Query $queryObject)
302
	{
303
		$lastQuery = $queryObject instanceof QueryObject ? $queryObject->getLastQuery() : NULL;
304
305
		return new QueryException($e, $lastQuery, '['.get_class($queryObject).'] '.$e->getMessage());
306
	}
307
308
}
309