ForeignKeyConstraint.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\DBAL\Schema;
  20. use Doctrine\DBAL\Platforms\AbstractPlatform;
  21. /**
  22. * An abstraction class for a foreign key constraint.
  23. *
  24. * @author Benjamin Eberlei <kontakt@beberlei.de>
  25. * @author Steve Müller <st.mueller@dzh-online.de>
  26. * @link www.doctrine-project.org
  27. * @since 2.0
  28. */
  29. class ForeignKeyConstraint extends AbstractAsset implements Constraint
  30. {
  31. /**
  32. * Instance of the referencing table the foreign key constraint is associated with.
  33. *
  34. * @var \Doctrine\DBAL\Schema\Table
  35. */
  36. protected $_localTable;
  37. /**
  38. * Asset identifier instances of the referencing table column names the foreign key constraint is associated with.
  39. * array($columnName => Identifier)
  40. *
  41. * @var Identifier[]
  42. */
  43. protected $_localColumnNames;
  44. /**
  45. * Table or asset identifier instance of the referenced table name the foreign key constraint is associated with.
  46. *
  47. * @var Table|Identifier
  48. */
  49. protected $_foreignTableName;
  50. /**
  51. * Asset identifier instances of the referenced table column names the foreign key constraint is associated with.
  52. * array($columnName => Identifier)
  53. *
  54. * @var Identifier[]
  55. */
  56. protected $_foreignColumnNames;
  57. /**
  58. * @var array Options associated with the foreign key constraint.
  59. */
  60. protected $_options;
  61. /**
  62. * Initializes the foreign key constraint.
  63. *
  64. * @param array $localColumnNames Names of the referencing table columns.
  65. * @param Table|string $foreignTableName Referenced table.
  66. * @param array $foreignColumnNames Names of the referenced table columns.
  67. * @param string|null $name Name of the foreign key constraint.
  68. * @param array $options Options associated with the foreign key constraint.
  69. */
  70. public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = array())
  71. {
  72. $this->_setName($name);
  73. $identifierConstructorCallback = function ($column) {
  74. return new Identifier($column);
  75. };
  76. $this->_localColumnNames = $localColumnNames
  77. ? array_combine($localColumnNames, array_map($identifierConstructorCallback, $localColumnNames))
  78. : array();
  79. if ($foreignTableName instanceof Table) {
  80. $this->_foreignTableName = $foreignTableName;
  81. } else {
  82. $this->_foreignTableName = new Identifier($foreignTableName);
  83. }
  84. $this->_foreignColumnNames = $foreignColumnNames
  85. ? array_combine($foreignColumnNames, array_map($identifierConstructorCallback, $foreignColumnNames))
  86. : array();
  87. $this->_options = $options;
  88. }
  89. /**
  90. * Returns the name of the referencing table
  91. * the foreign key constraint is associated with.
  92. *
  93. * @return string
  94. */
  95. public function getLocalTableName()
  96. {
  97. return $this->_localTable->getName();
  98. }
  99. /**
  100. * Sets the Table instance of the referencing table
  101. * the foreign key constraint is associated with.
  102. *
  103. * @param \Doctrine\DBAL\Schema\Table $table Instance of the referencing table.
  104. *
  105. * @return void
  106. */
  107. public function setLocalTable(Table $table)
  108. {
  109. $this->_localTable = $table;
  110. }
  111. /**
  112. * @return Table
  113. */
  114. public function getLocalTable()
  115. {
  116. return $this->_localTable;
  117. }
  118. /**
  119. * Returns the names of the referencing table columns
  120. * the foreign key constraint is associated with.
  121. *
  122. * @return array
  123. */
  124. public function getLocalColumns()
  125. {
  126. return array_keys($this->_localColumnNames);
  127. }
  128. /**
  129. * Returns the quoted representation of the referencing table column names
  130. * the foreign key constraint is associated with.
  131. *
  132. * But only if they were defined with one or the referencing table column name
  133. * is a keyword reserved by the platform.
  134. * Otherwise the plain unquoted value as inserted is returned.
  135. *
  136. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The platform to use for quotation.
  137. *
  138. * @return array
  139. */
  140. public function getQuotedLocalColumns(AbstractPlatform $platform)
  141. {
  142. $columns = array();
  143. foreach ($this->_localColumnNames as $column) {
  144. $columns[] = $column->getQuotedName($platform);
  145. }
  146. return $columns;
  147. }
  148. /**
  149. * {@inheritdoc}
  150. *
  151. * @see getLocalColumns
  152. */
  153. public function getColumns()
  154. {
  155. return $this->getLocalColumns();
  156. }
  157. /**
  158. * Returns the quoted representation of the referencing table column names
  159. * the foreign key constraint is associated with.
  160. *
  161. * But only if they were defined with one or the referencing table column name
  162. * is a keyword reserved by the platform.
  163. * Otherwise the plain unquoted value as inserted is returned.
  164. *
  165. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The platform to use for quotation.
  166. *
  167. * @see getQuotedLocalColumns
  168. *
  169. * @return array
  170. */
  171. public function getQuotedColumns(AbstractPlatform $platform)
  172. {
  173. return $this->getQuotedLocalColumns($platform);
  174. }
  175. /**
  176. * Returns the name of the referenced table
  177. * the foreign key constraint is associated with.
  178. *
  179. * @return string
  180. */
  181. public function getForeignTableName()
  182. {
  183. return $this->_foreignTableName->getName();
  184. }
  185. /**
  186. * Returns the non-schema qualified foreign table name.
  187. *
  188. * @return string
  189. */
  190. public function getUnqualifiedForeignTableName()
  191. {
  192. $parts = explode(".", $this->_foreignTableName->getName());
  193. return strtolower(end($parts));
  194. }
  195. /**
  196. * Returns the quoted representation of the referenced table name
  197. * the foreign key constraint is associated with.
  198. *
  199. * But only if it was defined with one or the referenced table name
  200. * is a keyword reserved by the platform.
  201. * Otherwise the plain unquoted value as inserted is returned.
  202. *
  203. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The platform to use for quotation.
  204. *
  205. * @return string
  206. */
  207. public function getQuotedForeignTableName(AbstractPlatform $platform)
  208. {
  209. return $this->_foreignTableName->getQuotedName($platform);
  210. }
  211. /**
  212. * Returns the names of the referenced table columns
  213. * the foreign key constraint is associated with.
  214. *
  215. * @return array
  216. */
  217. public function getForeignColumns()
  218. {
  219. return array_keys($this->_foreignColumnNames);
  220. }
  221. /**
  222. * Returns the quoted representation of the referenced table column names
  223. * the foreign key constraint is associated with.
  224. *
  225. * But only if they were defined with one or the referenced table column name
  226. * is a keyword reserved by the platform.
  227. * Otherwise the plain unquoted value as inserted is returned.
  228. *
  229. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The platform to use for quotation.
  230. *
  231. * @return array
  232. */
  233. public function getQuotedForeignColumns(AbstractPlatform $platform)
  234. {
  235. $columns = array();
  236. foreach ($this->_foreignColumnNames as $column) {
  237. $columns[] = $column->getQuotedName($platform);
  238. }
  239. return $columns;
  240. }
  241. /**
  242. * Returns whether or not a given option
  243. * is associated with the foreign key constraint.
  244. *
  245. * @param string $name Name of the option to check.
  246. *
  247. * @return boolean
  248. */
  249. public function hasOption($name)
  250. {
  251. return isset($this->_options[$name]);
  252. }
  253. /**
  254. * Returns an option associated with the foreign key constraint.
  255. *
  256. * @param string $name Name of the option the foreign key constraint is associated with.
  257. *
  258. * @return mixed
  259. */
  260. public function getOption($name)
  261. {
  262. return $this->_options[$name];
  263. }
  264. /**
  265. * Returns the options associated with the foreign key constraint.
  266. *
  267. * @return array
  268. */
  269. public function getOptions()
  270. {
  271. return $this->_options;
  272. }
  273. /**
  274. * Returns the referential action for UPDATE operations
  275. * on the referenced table the foreign key constraint is associated with.
  276. *
  277. * @return string|null
  278. */
  279. public function onUpdate()
  280. {
  281. return $this->onEvent('onUpdate');
  282. }
  283. /**
  284. * Returns the referential action for DELETE operations
  285. * on the referenced table the foreign key constraint is associated with.
  286. *
  287. * @return string|null
  288. */
  289. public function onDelete()
  290. {
  291. return $this->onEvent('onDelete');
  292. }
  293. /**
  294. * Returns the referential action for a given database operation
  295. * on the referenced table the foreign key constraint is associated with.
  296. *
  297. * @param string $event Name of the database operation/event to return the referential action for.
  298. *
  299. * @return string|null
  300. */
  301. private function onEvent($event)
  302. {
  303. if (isset($this->_options[$event])) {
  304. $onEvent = strtoupper($this->_options[$event]);
  305. if ( ! in_array($onEvent, array('NO ACTION', 'RESTRICT'))) {
  306. return $onEvent;
  307. }
  308. }
  309. return false;
  310. }
  311. }