1 | <?php |
||
32 | class NonLockingUniqueInserter extends Nette\Object |
||
33 | { |
||
34 | |||
35 | /** |
||
36 | * @var \Kdyby\Doctrine\EntityManager |
||
37 | */ |
||
38 | private $em; |
||
39 | |||
40 | /** |
||
41 | * @var \Kdyby\Doctrine\Connection |
||
42 | */ |
||
43 | private $db; |
||
44 | |||
45 | /** |
||
46 | * @var \Doctrine\DBAL\Platforms\AbstractPlatform |
||
47 | */ |
||
48 | private $platform; |
||
49 | |||
50 | /** |
||
51 | * @var \Doctrine\ORM\Mapping\QuoteStrategy |
||
52 | */ |
||
53 | private $quotes; |
||
54 | |||
55 | /** |
||
56 | * @var \Doctrine\ORM\UnitOfWork |
||
57 | */ |
||
58 | private $uow; |
||
59 | |||
60 | |||
61 | |||
62 | /** |
||
63 | * @param EntityManager $em |
||
64 | */ |
||
65 | public function __construct(EntityManager $em) |
||
73 | |||
74 | |||
75 | |||
76 | /** |
||
77 | * When entity have columns for required associations, this will fail. |
||
78 | * Calls $em->flush(). |
||
79 | * |
||
80 | * Warning: You must NOT use the passed entity further in your application. |
||
81 | * Use the returned one instead! |
||
82 | * |
||
83 | * @todo fix error codes! PDO is returning database-specific codes |
||
84 | * |
||
85 | * @param object $entity |
||
86 | * @throws \Doctrine\DBAL\DBALException |
||
87 | * @throws \Exception |
||
88 | * @return bool|object |
||
89 | */ |
||
90 | public function persist($entity) |
||
91 | { |
||
92 | $this->db->beginTransaction(); |
||
93 | |||
94 | try { |
||
95 | $persisted = $this->doInsert($entity); |
||
96 | $this->db->commit(); |
||
97 | |||
98 | return $persisted; |
||
99 | |||
100 | } catch (Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) { |
||
|
|||
101 | $this->db->rollback(); |
||
102 | |||
103 | return FALSE; |
||
104 | |||
105 | } catch (Kdyby\Doctrine\DuplicateEntryException $e) { |
||
106 | $this->db->rollback(); |
||
107 | |||
108 | return FALSE; |
||
109 | |||
110 | } catch (DBALException $e) { |
||
111 | $this->db->rollback(); |
||
112 | |||
113 | if ($this->isUniqueConstraintViolation($e)) { |
||
114 | return FALSE; |
||
115 | } |
||
116 | |||
117 | throw $this->db->resolveException($e); |
||
118 | |||
119 | } catch (\Exception $e) { |
||
120 | $this->db->rollback(); |
||
121 | throw $e; |
||
122 | |||
123 | } catch (\Throwable $e) { |
||
124 | $this->db->rollback(); |
||
125 | throw $e; |
||
126 | } |
||
127 | } |
||
128 | |||
129 | |||
130 | |||
131 | private function doInsert($entity) |
||
132 | { |
||
133 | // get entity metadata |
||
134 | $meta = $this->em->getClassMetadata(get_class($entity)); |
||
135 | |||
136 | // fields that have to be inserted |
||
137 | $fields = $this->getFieldsWithValues($meta, $entity); |
||
138 | // associations that have to be inserted |
||
139 | $associations = $this->getAssociationsWithValues($meta, $entity); |
||
140 | // discriminator column |
||
141 | $discriminator = $this->getDiscriminatorColumn($meta); |
||
142 | |||
143 | // prepare statement && execute |
||
144 | $this->prepareInsert($meta, array_merge($fields, $associations, $discriminator))->execute(); |
||
145 | |||
146 | // assign ID to entity |
||
147 | if ($idGen = $meta->idGenerator) { |
||
148 | if ($idGen->isPostInsertGenerator()) { |
||
149 | $id = $idGen->generate($this->em, $entity); |
||
150 | $identifierFields = $meta->getIdentifierFieldNames(); |
||
151 | $meta->setFieldValue($entity, reset($identifierFields), $id); |
||
152 | } |
||
153 | } |
||
154 | |||
155 | // entity is now safely inserted to database, merge now |
||
156 | $merged = $this->em->merge($entity); |
||
157 | $this->em->flush([$merged]); |
||
158 | |||
159 | // when you merge entity, you get a new reference |
||
160 | return $merged; |
||
161 | } |
||
162 | |||
163 | |||
164 | |||
165 | private function prepareInsert(ClassMetadata $meta, array $data) |
||
188 | |||
189 | |||
190 | |||
191 | /** |
||
192 | * @param \Exception|\PDOException $e |
||
193 | * @return bool |
||
194 | */ |
||
195 | private function isUniqueConstraintViolation($e) |
||
207 | |||
208 | |||
209 | |||
210 | private function getFieldsWithValues(ClassMetadata $meta, $entity) |
||
225 | |||
226 | |||
227 | |||
228 | private function getAssociationsWithValues(ClassMetadata $meta, $entity) |
||
273 | |||
274 | |||
275 | |||
276 | private function getDiscriminatorColumn(ClassMetadata $meta) |
||
292 | |||
293 | } |
||
294 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.