AbstractAsset.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. * The abstract asset allows to reset the name of all assets without publishing this to the public userland.
  23. *
  24. * This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
  25. * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure
  26. *
  27. * @link www.doctrine-project.org
  28. * @since 2.0
  29. * @author Benjamin Eberlei <kontakt@beberlei.de>
  30. */
  31. abstract class AbstractAsset
  32. {
  33. /**
  34. * @var string
  35. */
  36. protected $_name;
  37. /**
  38. * Namespace of the asset. If none isset the default namespace is assumed.
  39. *
  40. * @var string|null
  41. */
  42. protected $_namespace = null;
  43. /**
  44. * @var boolean
  45. */
  46. protected $_quoted = false;
  47. /**
  48. * Sets the name of this asset.
  49. *
  50. * @param string $name
  51. *
  52. * @return void
  53. */
  54. protected function _setName($name)
  55. {
  56. if ($this->isIdentifierQuoted($name)) {
  57. $this->_quoted = true;
  58. $name = $this->trimQuotes($name);
  59. }
  60. if (strpos($name, ".") !== false) {
  61. $parts = explode(".", $name);
  62. $this->_namespace = $parts[0];
  63. $name = $parts[1];
  64. }
  65. $this->_name = $name;
  66. }
  67. /**
  68. * Is this asset in the default namespace?
  69. *
  70. * @param string $defaultNamespaceName
  71. *
  72. * @return boolean
  73. */
  74. public function isInDefaultNamespace($defaultNamespaceName)
  75. {
  76. return $this->_namespace == $defaultNamespaceName || $this->_namespace === null;
  77. }
  78. /**
  79. * Gets the namespace name of this asset.
  80. *
  81. * If NULL is returned this means the default namespace is used.
  82. *
  83. * @return string|null
  84. */
  85. public function getNamespaceName()
  86. {
  87. return $this->_namespace;
  88. }
  89. /**
  90. * The shortest name is stripped of the default namespace. All other
  91. * namespaced elements are returned as full-qualified names.
  92. *
  93. * @param string
  94. *
  95. * @return string
  96. */
  97. public function getShortestName($defaultNamespaceName)
  98. {
  99. $shortestName = $this->getName();
  100. if ($this->_namespace == $defaultNamespaceName) {
  101. $shortestName = $this->_name;
  102. }
  103. return strtolower($shortestName);
  104. }
  105. /**
  106. * The normalized name is full-qualified and lowerspaced. Lowerspacing is
  107. * actually wrong, but we have to do it to keep our sanity. If you are
  108. * using database objects that only differentiate in the casing (FOO vs
  109. * Foo) then you will NOT be able to use Doctrine Schema abstraction.
  110. *
  111. * Every non-namespaced element is prefixed with the default namespace
  112. * name which is passed as argument to this method.
  113. *
  114. * @param string $defaultNamespaceName
  115. *
  116. * @return string
  117. */
  118. public function getFullQualifiedName($defaultNamespaceName)
  119. {
  120. $name = $this->getName();
  121. if ( ! $this->_namespace) {
  122. $name = $defaultNamespaceName . "." . $name;
  123. }
  124. return strtolower($name);
  125. }
  126. /**
  127. * Checks if this asset's name is quoted.
  128. *
  129. * @return boolean
  130. */
  131. public function isQuoted()
  132. {
  133. return $this->_quoted;
  134. }
  135. /**
  136. * Checks if this identifier is quoted.
  137. *
  138. * @param string $identifier
  139. *
  140. * @return boolean
  141. */
  142. protected function isIdentifierQuoted($identifier)
  143. {
  144. return (isset($identifier[0]) && ($identifier[0] == '`' || $identifier[0] == '"'));
  145. }
  146. /**
  147. * Trim quotes from the identifier.
  148. *
  149. * @param string $identifier
  150. *
  151. * @return string
  152. */
  153. protected function trimQuotes($identifier)
  154. {
  155. return str_replace(array('`', '"'), '', $identifier);
  156. }
  157. /**
  158. * Returns the name of this schema asset.
  159. *
  160. * @return string
  161. */
  162. public function getName()
  163. {
  164. if ($this->_namespace) {
  165. return $this->_namespace . "." . $this->_name;
  166. }
  167. return $this->_name;
  168. }
  169. /**
  170. * Gets the quoted representation of this asset but only if it was defined with one. Otherwise
  171. * return the plain unquoted value as inserted.
  172. *
  173. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
  174. *
  175. * @return string
  176. */
  177. public function getQuotedName(AbstractPlatform $platform)
  178. {
  179. $keywords = $platform->getReservedKeywordsList();
  180. $parts = explode(".", $this->getName());
  181. foreach ($parts as $k => $v) {
  182. $parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
  183. }
  184. return implode(".", $parts);
  185. }
  186. /**
  187. * Generates an identifier from a list of column names obeying a certain string length.
  188. *
  189. * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
  190. * however building idents automatically for foreign keys, composite keys or such can easily create
  191. * very long names.
  192. *
  193. * @param array $columnNames
  194. * @param string $prefix
  195. * @param integer $maxSize
  196. *
  197. * @return string
  198. */
  199. protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30)
  200. {
  201. $hash = implode("", array_map(function($column) {
  202. return dechex(crc32($column));
  203. }, $columnNames));
  204. return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize);
  205. }
  206. }