PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/RestAPI/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php

https://gitlab.com/martinstti/silex-microframework-rest
PHP | 510 lines | 219 code | 67 blank | 224 comment | 14 complexity | 024abbd6b319be0ef66b164111f5c1ff MD5 | raw file
  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\Schema\Visitor\CreateSchemaSqlCollector;
  21. use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
  22. use Doctrine\DBAL\Schema\Visitor\NamespaceVisitor;
  23. use Doctrine\DBAL\Schema\Visitor\Visitor;
  24. use Doctrine\DBAL\Platforms\AbstractPlatform;
  25. /**
  26. * Object representation of a database schema.
  27. *
  28. * Different vendors have very inconsistent naming with regard to the concept
  29. * of a "schema". Doctrine understands a schema as the entity that conceptually
  30. * wraps a set of database objects such as tables, sequences, indexes and
  31. * foreign keys that belong to each other into a namespace. A Doctrine Schema
  32. * has nothing to do with the "SCHEMA" defined as in PostgreSQL, it is more
  33. * related to the concept of "DATABASE" that exists in MySQL and PostgreSQL.
  34. *
  35. * Every asset in the doctrine schema has a name. A name consists of either a
  36. * namespace.local name pair or just a local unqualified name.
  37. *
  38. * The abstraction layer that covers a PostgreSQL schema is the namespace of an
  39. * database object (asset). A schema can have a name, which will be used as
  40. * default namespace for the unqualified database objects that are created in
  41. * the schema.
  42. *
  43. * In the case of MySQL where cross-database queries are allowed this leads to
  44. * databases being "misinterpreted" as namespaces. This is intentional, however
  45. * the CREATE/DROP SQL visitors will just filter this queries and do not
  46. * execute them. Only the queries for the currently connected database are
  47. * executed.
  48. *
  49. * @link www.doctrine-project.org
  50. * @since 2.0
  51. * @author Benjamin Eberlei <kontakt@beberlei.de>
  52. */
  53. class Schema extends AbstractAsset
  54. {
  55. /**
  56. * The namespaces in this schema.
  57. *
  58. * @var array
  59. */
  60. private $namespaces = array();
  61. /**
  62. * @var \Doctrine\DBAL\Schema\Table[]
  63. */
  64. protected $_tables = array();
  65. /**
  66. * @var \Doctrine\DBAL\Schema\Sequence[]
  67. */
  68. protected $_sequences = array();
  69. /**
  70. * @var \Doctrine\DBAL\Schema\SchemaConfig
  71. */
  72. protected $_schemaConfig = false;
  73. /**
  74. * @param \Doctrine\DBAL\Schema\Table[] $tables
  75. * @param \Doctrine\DBAL\Schema\Sequence[] $sequences
  76. * @param \Doctrine\DBAL\Schema\SchemaConfig $schemaConfig
  77. * @param array $namespaces
  78. */
  79. public function __construct(
  80. array $tables = array(),
  81. array $sequences = array(),
  82. SchemaConfig $schemaConfig = null,
  83. array $namespaces = array()
  84. ) {
  85. if ($schemaConfig == null) {
  86. $schemaConfig = new SchemaConfig();
  87. }
  88. $this->_schemaConfig = $schemaConfig;
  89. $this->_setName($schemaConfig->getName() ?: 'public');
  90. foreach ($namespaces as $namespace) {
  91. $this->createNamespace($namespace);
  92. }
  93. foreach ($tables as $table) {
  94. $this->_addTable($table);
  95. }
  96. foreach ($sequences as $sequence) {
  97. $this->_addSequence($sequence);
  98. }
  99. }
  100. /**
  101. * @return boolean
  102. */
  103. public function hasExplicitForeignKeyIndexes()
  104. {
  105. return $this->_schemaConfig->hasExplicitForeignKeyIndexes();
  106. }
  107. /**
  108. * @param \Doctrine\DBAL\Schema\Table $table
  109. *
  110. * @return void
  111. *
  112. * @throws \Doctrine\DBAL\Schema\SchemaException
  113. */
  114. protected function _addTable(Table $table)
  115. {
  116. $namespaceName = $table->getNamespaceName();
  117. $tableName = $table->getFullQualifiedName($this->getName());
  118. if (isset($this->_tables[$tableName])) {
  119. throw SchemaException::tableAlreadyExists($tableName);
  120. }
  121. if ( ! $table->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) {
  122. $this->createNamespace($namespaceName);
  123. }
  124. $this->_tables[$tableName] = $table;
  125. $table->setSchemaConfig($this->_schemaConfig);
  126. }
  127. /**
  128. * @param \Doctrine\DBAL\Schema\Sequence $sequence
  129. *
  130. * @return void
  131. *
  132. * @throws \Doctrine\DBAL\Schema\SchemaException
  133. */
  134. protected function _addSequence(Sequence $sequence)
  135. {
  136. $namespaceName = $sequence->getNamespaceName();
  137. $seqName = $sequence->getFullQualifiedName($this->getName());
  138. if (isset($this->_sequences[$seqName])) {
  139. throw SchemaException::sequenceAlreadyExists($seqName);
  140. }
  141. if ( ! $sequence->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) {
  142. $this->createNamespace($namespaceName);
  143. }
  144. $this->_sequences[$seqName] = $sequence;
  145. }
  146. /**
  147. * Returns the namespaces of this schema.
  148. *
  149. * @return array A list of namespace names.
  150. */
  151. public function getNamespaces()
  152. {
  153. return $this->namespaces;
  154. }
  155. /**
  156. * Gets all tables of this schema.
  157. *
  158. * @return \Doctrine\DBAL\Schema\Table[]
  159. */
  160. public function getTables()
  161. {
  162. return $this->_tables;
  163. }
  164. /**
  165. * @param string $tableName
  166. *
  167. * @return \Doctrine\DBAL\Schema\Table
  168. *
  169. * @throws \Doctrine\DBAL\Schema\SchemaException
  170. */
  171. public function getTable($tableName)
  172. {
  173. $tableName = $this->getFullQualifiedAssetName($tableName);
  174. if (!isset($this->_tables[$tableName])) {
  175. throw SchemaException::tableDoesNotExist($tableName);
  176. }
  177. return $this->_tables[$tableName];
  178. }
  179. /**
  180. * @param string $name
  181. *
  182. * @return string
  183. */
  184. private function getFullQualifiedAssetName($name)
  185. {
  186. $name = $this->getUnquotedAssetName($name);
  187. if (strpos($name, ".") === false) {
  188. $name = $this->getName() . "." . $name;
  189. }
  190. return strtolower($name);
  191. }
  192. /**
  193. * Returns the unquoted representation of a given asset name.
  194. *
  195. * @param string $assetName Quoted or unquoted representation of an asset name.
  196. *
  197. * @return string
  198. */
  199. private function getUnquotedAssetName($assetName)
  200. {
  201. if ($this->isIdentifierQuoted($assetName)) {
  202. return $this->trimQuotes($assetName);
  203. }
  204. return $assetName;
  205. }
  206. /**
  207. * Does this schema have a namespace with the given name?
  208. *
  209. * @param string $namespaceName
  210. *
  211. * @return boolean
  212. */
  213. public function hasNamespace($namespaceName)
  214. {
  215. $namespaceName = strtolower($this->getUnquotedAssetName($namespaceName));
  216. return isset($this->namespaces[$namespaceName]);
  217. }
  218. /**
  219. * Does this schema have a table with the given name?
  220. *
  221. * @param string $tableName
  222. *
  223. * @return boolean
  224. */
  225. public function hasTable($tableName)
  226. {
  227. $tableName = $this->getFullQualifiedAssetName($tableName);
  228. return isset($this->_tables[$tableName]);
  229. }
  230. /**
  231. * Gets all table names, prefixed with a schema name, even the default one if present.
  232. *
  233. * @return array
  234. */
  235. public function getTableNames()
  236. {
  237. return array_keys($this->_tables);
  238. }
  239. /**
  240. * @param string $sequenceName
  241. *
  242. * @return boolean
  243. */
  244. public function hasSequence($sequenceName)
  245. {
  246. $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
  247. return isset($this->_sequences[$sequenceName]);
  248. }
  249. /**
  250. * @param string $sequenceName
  251. *
  252. * @return \Doctrine\DBAL\Schema\Sequence
  253. *
  254. * @throws \Doctrine\DBAL\Schema\SchemaException
  255. */
  256. public function getSequence($sequenceName)
  257. {
  258. $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
  259. if (!$this->hasSequence($sequenceName)) {
  260. throw SchemaException::sequenceDoesNotExist($sequenceName);
  261. }
  262. return $this->_sequences[$sequenceName];
  263. }
  264. /**
  265. * @return \Doctrine\DBAL\Schema\Sequence[]
  266. */
  267. public function getSequences()
  268. {
  269. return $this->_sequences;
  270. }
  271. /**
  272. * Creates a new namespace.
  273. *
  274. * @param string $namespaceName The name of the namespace to create.
  275. *
  276. * @return \Doctrine\DBAL\Schema\Schema This schema instance.
  277. */
  278. public function createNamespace($namespaceName)
  279. {
  280. $unquotedNamespaceName = strtolower($this->getUnquotedAssetName($namespaceName));
  281. if (isset($this->namespaces[$unquotedNamespaceName])) {
  282. throw SchemaException::namespaceAlreadyExists($unquotedNamespaceName);
  283. }
  284. $this->namespaces[$unquotedNamespaceName] = $namespaceName;
  285. return $this;
  286. }
  287. /**
  288. * Creates a new table.
  289. *
  290. * @param string $tableName
  291. *
  292. * @return \Doctrine\DBAL\Schema\Table
  293. */
  294. public function createTable($tableName)
  295. {
  296. $table = new Table($tableName);
  297. $this->_addTable($table);
  298. foreach ($this->_schemaConfig->getDefaultTableOptions() as $name => $value) {
  299. $table->addOption($name, $value);
  300. }
  301. return $table;
  302. }
  303. /**
  304. * Renames a table.
  305. *
  306. * @param string $oldTableName
  307. * @param string $newTableName
  308. *
  309. * @return \Doctrine\DBAL\Schema\Schema
  310. */
  311. public function renameTable($oldTableName, $newTableName)
  312. {
  313. $table = $this->getTable($oldTableName);
  314. $table->_setName($newTableName);
  315. $this->dropTable($oldTableName);
  316. $this->_addTable($table);
  317. return $this;
  318. }
  319. /**
  320. * Drops a table from the schema.
  321. *
  322. * @param string $tableName
  323. *
  324. * @return \Doctrine\DBAL\Schema\Schema
  325. */
  326. public function dropTable($tableName)
  327. {
  328. $tableName = $this->getFullQualifiedAssetName($tableName);
  329. $this->getTable($tableName);
  330. unset($this->_tables[$tableName]);
  331. return $this;
  332. }
  333. /**
  334. * Creates a new sequence.
  335. *
  336. * @param string $sequenceName
  337. * @param integer $allocationSize
  338. * @param integer $initialValue
  339. *
  340. * @return \Doctrine\DBAL\Schema\Sequence
  341. */
  342. public function createSequence($sequenceName, $allocationSize=1, $initialValue=1)
  343. {
  344. $seq = new Sequence($sequenceName, $allocationSize, $initialValue);
  345. $this->_addSequence($seq);
  346. return $seq;
  347. }
  348. /**
  349. * @param string $sequenceName
  350. *
  351. * @return \Doctrine\DBAL\Schema\Schema
  352. */
  353. public function dropSequence($sequenceName)
  354. {
  355. $sequenceName = $this->getFullQualifiedAssetName($sequenceName);
  356. unset($this->_sequences[$sequenceName]);
  357. return $this;
  358. }
  359. /**
  360. * Returns an array of necessary SQL queries to create the schema on the given platform.
  361. *
  362. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
  363. *
  364. * @return array
  365. */
  366. public function toSql(AbstractPlatform $platform)
  367. {
  368. $sqlCollector = new CreateSchemaSqlCollector($platform);
  369. $this->visit($sqlCollector);
  370. return $sqlCollector->getQueries();
  371. }
  372. /**
  373. * Return an array of necessary SQL queries to drop the schema on the given platform.
  374. *
  375. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
  376. *
  377. * @return array
  378. */
  379. public function toDropSql(AbstractPlatform $platform)
  380. {
  381. $dropSqlCollector = new DropSchemaSqlCollector($platform);
  382. $this->visit($dropSqlCollector);
  383. return $dropSqlCollector->getQueries();
  384. }
  385. /**
  386. * @param \Doctrine\DBAL\Schema\Schema $toSchema
  387. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
  388. *
  389. * @return array
  390. */
  391. public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform)
  392. {
  393. $comparator = new Comparator();
  394. $schemaDiff = $comparator->compare($this, $toSchema);
  395. return $schemaDiff->toSql($platform);
  396. }
  397. /**
  398. * @param \Doctrine\DBAL\Schema\Schema $fromSchema
  399. * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
  400. *
  401. * @return array
  402. */
  403. public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform)
  404. {
  405. $comparator = new Comparator();
  406. $schemaDiff = $comparator->compare($fromSchema, $this);
  407. return $schemaDiff->toSql($platform);
  408. }
  409. /**
  410. * @param \Doctrine\DBAL\Schema\Visitor\Visitor $visitor
  411. *
  412. * @return void
  413. */
  414. public function visit(Visitor $visitor)
  415. {
  416. $visitor->acceptSchema($this);
  417. if ($visitor instanceof NamespaceVisitor) {
  418. foreach ($this->namespaces as $namespace) {
  419. $visitor->acceptNamespace($namespace);
  420. }
  421. }
  422. foreach ($this->_tables as $table) {
  423. $table->visit($visitor);
  424. }
  425. foreach ($this->_sequences as $sequence) {
  426. $sequence->visit($visitor);
  427. }
  428. }
  429. /**
  430. * Cloning a Schema triggers a deep clone of all related assets.
  431. *
  432. * @return void
  433. */
  434. public function __clone()
  435. {
  436. foreach ($this->_tables as $k => $table) {
  437. $this->_tables[$k] = clone $table;
  438. }
  439. foreach ($this->_sequences as $k => $sequence) {
  440. $this->_sequences[$k] = clone $sequence;
  441. }
  442. }
  443. }