PageRenderTime 29ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/generator/lib/platform/DefaultPlatform.php

https://github.com/1989gaurav/Propel
PHP | 1129 lines | 700 code | 105 blank | 324 comment | 49 complexity | 4767f6145084c6f5cc71057609eabd9e MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/PropelPlatformInterface.php';
  10. require_once dirname(__FILE__) . '/../model/Column.php';
  11. require_once dirname(__FILE__) . '/../model/Table.php';
  12. require_once dirname(__FILE__) . '/../model/Domain.php';
  13. require_once dirname(__FILE__) . '/../model/PropelTypes.php';
  14. /**
  15. * Default implementation for the Platform interface.
  16. *
  17. * @author Martin Poeschl <mpoeschl@marmot.at> (Torque)
  18. * @version $Revision$
  19. * @package propel.generator.platform
  20. */
  21. class DefaultPlatform implements PropelPlatformInterface
  22. {
  23. /**
  24. * Mapping from Propel types to Domain objects.
  25. *
  26. * @var array
  27. */
  28. protected $schemaDomainMap;
  29. /**
  30. * @var PDO Database connection.
  31. */
  32. protected $con;
  33. /**
  34. * @var boolean whether the identifier quoting is enabled
  35. */
  36. protected $isIdentifierQuotingEnabled = true;
  37. /**
  38. * Default constructor.
  39. * @param PDO $con Optional database connection to use in this platform.
  40. */
  41. public function __construct(PDO $con = null)
  42. {
  43. if ($con) $this->setConnection($con);
  44. $this->initialize();
  45. }
  46. /**
  47. * Set the database connection to use for this Platform class.
  48. * @param PDO $con Database connection to use in this platform.
  49. */
  50. public function setConnection(PDO $con = null)
  51. {
  52. $this->con = $con;
  53. }
  54. /**
  55. * Returns the database connection to use for this Platform class.
  56. * @return PDO The database connection or NULL if none has been set.
  57. */
  58. public function getConnection()
  59. {
  60. return $this->con;
  61. }
  62. /**
  63. * Sets the GeneratorConfig to use in the parsing.
  64. *
  65. * @param GeneratorConfig $config
  66. */
  67. public function setGeneratorConfig(GeneratorConfig $config)
  68. {
  69. // do nothing by default
  70. }
  71. /**
  72. * Gets a specific propel (renamed) property from the build.
  73. *
  74. * @param string $name
  75. * @return mixed
  76. */
  77. protected function getBuildProperty($name)
  78. {
  79. if ($this->generatorConfig !== null) {
  80. return $this->generatorConfig->getBuildProperty($name);
  81. }
  82. return null;
  83. }
  84. /**
  85. * Initialize the type -> Domain mapping.
  86. */
  87. protected function initialize()
  88. {
  89. $this->schemaDomainMap = array();
  90. foreach (PropelTypes::getPropelTypes() as $type) {
  91. $this->schemaDomainMap[$type] = new Domain($type);
  92. }
  93. // BU_* no longer needed, so map these to the DATE/TIMESTAMP domains
  94. $this->schemaDomainMap[PropelTypes::BU_DATE] = new Domain(PropelTypes::DATE);
  95. $this->schemaDomainMap[PropelTypes::BU_TIMESTAMP] = new Domain(PropelTypes::TIMESTAMP);
  96. // Boolean is a bit special, since typically it must be mapped to INT type.
  97. $this->schemaDomainMap[PropelTypes::BOOLEAN] = new Domain(PropelTypes::BOOLEAN, "INTEGER");
  98. }
  99. /**
  100. * Adds a mapping entry for specified Domain.
  101. * @param Domain $domain
  102. */
  103. protected function setSchemaDomainMapping(Domain $domain)
  104. {
  105. $this->schemaDomainMap[$domain->getType()] = $domain;
  106. }
  107. /**
  108. * Returns the short name of the database type that this platform represents.
  109. * For example MysqlPlatform->getDatabaseType() returns 'mysql'.
  110. * @return string
  111. */
  112. public function getDatabaseType()
  113. {
  114. $clazz = get_class($this);
  115. $pos = strpos($clazz, 'Platform');
  116. return strtolower(substr($clazz,0,$pos));
  117. }
  118. /**
  119. * Returns the max column length supported by the db.
  120. *
  121. * @return int The max column length
  122. */
  123. public function getMaxColumnNameLength()
  124. {
  125. return 64;
  126. }
  127. /**
  128. * Returns the native IdMethod (sequence|identity)
  129. *
  130. * @return string The native IdMethod (PropelPlatformInterface:IDENTITY, PropelPlatformInterface::SEQUENCE).
  131. */
  132. public function getNativeIdMethod()
  133. {
  134. return PropelPlatformInterface::IDENTITY;
  135. }
  136. /**
  137. * Returns the db specific domain for a propelType.
  138. *
  139. * @param string $propelType the Propel type name.
  140. * @return Domain The db specific domain.
  141. */
  142. public function getDomainForType($propelType)
  143. {
  144. if (!isset($this->schemaDomainMap[$propelType])) {
  145. throw new EngineException("Cannot map unknown Propel type " . var_export($propelType, true) . " to native database type.");
  146. }
  147. return $this->schemaDomainMap[$propelType];
  148. }
  149. /**
  150. * @return string The RDBMS-specific SQL fragment for <code>NULL</code>
  151. * or <code>NOT NULL</code>.
  152. */
  153. public function getNullString($notNull)
  154. {
  155. return ($notNull ? "NOT NULL" : "");
  156. }
  157. /**
  158. * @return The RDBMS-specific SQL fragment for autoincrement.
  159. */
  160. public function getAutoIncrement()
  161. {
  162. return "IDENTITY";
  163. }
  164. /**
  165. * Gets the name to use for creating a sequence for a table.
  166. *
  167. * This will create a new name or use one specified in an id-method-parameter
  168. * tag, if specified.
  169. *
  170. * @param Table $table
  171. *
  172. * @return string Sequence name for this table.
  173. */
  174. public function getSequenceName(Table $table)
  175. {
  176. static $longNamesMap = array();
  177. $result = null;
  178. if ($table->getIdMethod() == IDMethod::NATIVE) {
  179. $idMethodParams = $table->getIdMethodParameters();
  180. $maxIdentifierLength = $this->getMaxColumnNameLength();
  181. if (empty($idMethodParams)) {
  182. if (strlen($table->getName() . "_SEQ") > $maxIdentifierLength) {
  183. if (!isset($longNamesMap[$table->getName()])) {
  184. $longNamesMap[$table->getName()] = strval(count($longNamesMap) + 1);
  185. }
  186. $result = substr($table->getName(), 0, $maxIdentifierLength - strlen("_SEQ_" . $longNamesMap[$table->getName()])) . "_SEQ_" . $longNamesMap[$table->getName()];
  187. }
  188. else {
  189. $result = substr($table->getName(), 0, $maxIdentifierLength -4) . "_SEQ";
  190. }
  191. } else {
  192. $result = substr($idMethodParams[0]->getValue(), 0, $maxIdentifierLength);
  193. }
  194. }
  195. return $result;
  196. }
  197. /**
  198. * Builds the DDL SQL to add the tables of a database
  199. * together with index and foreign keys
  200. *
  201. * @return string
  202. */
  203. public function getAddTablesDDL(Database $database)
  204. {
  205. $ret = $this->getBeginDDL();
  206. foreach ($database->getTablesForSql() as $table) {
  207. $ret .= $this->getCommentBlockDDL($table->getName());
  208. $ret .= $this->getDropTableDDL($table);
  209. $ret .= $this->getAddTableDDL($table);
  210. $ret .= $this->getAddIndicesDDL($table);
  211. $ret .= $this->getAddForeignKeysDDL($table);
  212. }
  213. $ret .= $this->getEndDDL();
  214. return $ret;
  215. }
  216. /**
  217. * Gets the requests to execute at the beginning of a DDL file
  218. *
  219. * @return string
  220. */
  221. public function getBeginDDL()
  222. {
  223. }
  224. /**
  225. * Gets the requests to execute at the end of a DDL file
  226. *
  227. * @return string
  228. */
  229. public function getEndDDL()
  230. {
  231. }
  232. /**
  233. * Builds the DDL SQL to drop a table
  234. * @return string
  235. */
  236. public function getDropTableDDL(Table $table)
  237. {
  238. return "
  239. DROP TABLE " . $this->quoteIdentifier($table->getName()) . ";
  240. ";
  241. }
  242. /**
  243. * Builds the DDL SQL to add a table
  244. * without index and foreign keys
  245. *
  246. * @return string
  247. */
  248. public function getAddTableDDL(Table $table)
  249. {
  250. $tableDescription = $table->hasDescription() ? $this->getCommentLineDDL($table->getDescription()) : '';
  251. $lines = array();
  252. foreach ($table->getColumns() as $column) {
  253. $lines[] = $this->getColumnDDL($column);
  254. }
  255. if ($table->hasPrimaryKey()) {
  256. $lines[] = $this->getPrimaryKeyDDL($table);
  257. }
  258. foreach ($table->getUnices() as $unique) {
  259. $lines[] = $this->getUniqueDDL($unique);
  260. }
  261. $sep = ",
  262. ";
  263. $pattern = "
  264. %sCREATE TABLE %s
  265. (
  266. %s
  267. );
  268. ";
  269. return sprintf($pattern,
  270. $tableDescription,
  271. $this->quoteIdentifier($table->getName()),
  272. implode($sep, $lines)
  273. );
  274. }
  275. /**
  276. * Builds the DDL SQL for a Column object.
  277. * @return string
  278. */
  279. public function getColumnDDL(Column $col)
  280. {
  281. $domain = $col->getDomain();
  282. $ddl = array($this->quoteIdentifier($col->getName()));
  283. $sqlType = $domain->getSqlType();
  284. if ($this->hasSize($sqlType) && $col->isDefaultSqlType($this)) {
  285. $ddl []= $sqlType . $domain->printSize();
  286. } else {
  287. $ddl []= $sqlType;
  288. }
  289. if ($default = $this->getColumnDefaultValueDDL($col)) {
  290. $ddl []= $default;
  291. }
  292. if ($notNull = $this->getNullString($col->isNotNull())) {
  293. $ddl []= $notNull;
  294. }
  295. if ($autoIncrement = $col->getAutoIncrementString()) {
  296. $ddl []= $autoIncrement;
  297. }
  298. return implode(' ', $ddl);
  299. }
  300. /**
  301. * Returns the SQL for the default value of a Column object
  302. * @return string
  303. */
  304. public function getColumnDefaultValueDDL(Column $col)
  305. {
  306. $default = '';
  307. $defaultValue = $col->getDefaultValue();
  308. if ($defaultValue !== null) {
  309. $default .= 'DEFAULT ';
  310. if ($defaultValue->isExpression()) {
  311. $default .= $defaultValue->getValue();
  312. } else {
  313. if ($col->isTextType()) {
  314. $default .= $this->quote($defaultValue->getValue());
  315. } elseif ($col->getType() == PropelTypes::BOOLEAN || $col->getType() == PropelTypes::BOOLEAN_EMU) {
  316. $default .= $this->getBooleanString($defaultValue->getValue());
  317. } elseif ($col->getType() == PropelTypes::ENUM) {
  318. $default .= array_search($defaultValue->getValue(), $col->getValueSet());
  319. } else {
  320. $default .= $defaultValue->getValue();
  321. }
  322. }
  323. }
  324. return $default;
  325. }
  326. /**
  327. * Creates a delimiter-delimited string list of column names, quoted using quoteIdentifier().
  328. * @example
  329. * <code>
  330. * echo $platform->getColumnListDDL(array('foo', 'bar');
  331. * // '"foo","bar"'
  332. * </code>
  333. * @param array Column[] or string[]
  334. * @param string $delim The delimiter to use in separating the column names.
  335. *
  336. * @return string
  337. */
  338. public function getColumnListDDL($columns, $delimiter = ',')
  339. {
  340. $list = array();
  341. foreach ($columns as $column) {
  342. if ($column instanceof Column) {
  343. $column = $column->getName();
  344. }
  345. $list[] = $this->quoteIdentifier($column);
  346. }
  347. return implode($delimiter, $list);
  348. }
  349. /**
  350. * Returns the name of a table primary key
  351. * @return string
  352. */
  353. public function getPrimaryKeyName(Table $table)
  354. {
  355. $tableName = $table->getCommonName();
  356. return $tableName . '_PK';
  357. }
  358. /**
  359. * Returns the SQL for the primary key of a Table object
  360. * @return string
  361. */
  362. public function getPrimaryKeyDDL(Table $table)
  363. {
  364. if ($table->hasPrimaryKey()) {
  365. return 'PRIMARY KEY (' . $this->getColumnListDDL($table->getPrimaryKey()) . ')';
  366. }
  367. }
  368. /**
  369. * Builds the DDL SQL to drop the primary key of a table.
  370. *
  371. * @param Table $table
  372. * @return string
  373. */
  374. public function getDropPrimaryKeyDDL(Table $table)
  375. {
  376. $pattern = "
  377. ALTER TABLE %s DROP CONSTRAINT %s;
  378. ";
  379. return sprintf($pattern,
  380. $this->quoteIdentifier($table->getName()),
  381. $this->quoteIdentifier($this->getPrimaryKeyName($table))
  382. );
  383. }
  384. /**
  385. * Builds the DDL SQL to add the primary key of a table.
  386. *
  387. * @param Table $table
  388. * @return string
  389. */
  390. public function getAddPrimaryKeyDDL(Table $table)
  391. {
  392. $pattern = "
  393. ALTER TABLE %s ADD %s;
  394. ";
  395. return sprintf($pattern,
  396. $this->quoteIdentifier($table->getName()),
  397. $this->getPrimaryKeyDDL($table)
  398. );
  399. }
  400. /**
  401. * Builds the DDL SQL to add the indices of a table.
  402. *
  403. * @param Table $table
  404. * @return string
  405. */
  406. public function getAddIndicesDDL(Table $table)
  407. {
  408. $ret = '';
  409. foreach ($table->getIndices() as $fk) {
  410. $ret .= $this->getAddIndexDDL($fk);
  411. }
  412. return $ret;
  413. }
  414. /**
  415. * Builds the DDL SQL to add an Index.
  416. *
  417. * @param Index $index
  418. * @return string
  419. */
  420. public function getAddIndexDDL(Index $index)
  421. {
  422. $pattern = "
  423. CREATE %sINDEX %s ON %s (%s);
  424. ";
  425. return sprintf($pattern,
  426. $index->getIsUnique() ? 'UNIQUE ' : '',
  427. $this->quoteIdentifier($index->getName()),
  428. $this->quoteIdentifier($index->getTable()->getName()),
  429. $this->getColumnListDDL($index->getColumns())
  430. );
  431. }
  432. /**
  433. * Builds the DDL SQL to drop an Index.
  434. *
  435. * @param Index $index
  436. * @return string
  437. */
  438. public function getDropIndexDDL(Index $index)
  439. {
  440. $pattern = "
  441. DROP INDEX %s;
  442. ";
  443. return sprintf($pattern,
  444. $this->quoteIdentifier($index->getName())
  445. );
  446. }
  447. /**
  448. * Builds the DDL SQL for an Index object.
  449. *
  450. * @param Index $index
  451. * @return string
  452. */
  453. public function getIndexDDL(Index $index)
  454. {
  455. return sprintf('%sINDEX %s (%s)',
  456. $index->getIsUnique() ? 'UNIQUE ' : '',
  457. $this->quoteIdentifier($index->getName()),
  458. $this->getColumnListDDL($index->getColumns())
  459. );
  460. }
  461. /**
  462. * Builds the DDL SQL for a Unique constraint object.
  463. *
  464. * @param Unique $unique
  465. * @return string
  466. */
  467. public function getUniqueDDL(Unique $unique)
  468. {
  469. return sprintf('UNIQUE (%s)' , $this->getColumnListDDL($unique->getColumns()));
  470. }
  471. /**
  472. * Builds the DDL SQL to add the foreign keys of a table.
  473. *
  474. * @param Table $table
  475. * @return string
  476. */
  477. public function getAddForeignKeysDDL(Table $table)
  478. {
  479. $ret = '';
  480. foreach ($table->getForeignKeys() as $fk) {
  481. $ret .= $this->getAddForeignKeyDDL($fk);
  482. }
  483. return $ret;
  484. }
  485. /**
  486. * Builds the DDL SQL to add a foreign key.
  487. *
  488. * @param ForeignKey $fk
  489. * @return string
  490. */
  491. public function getAddForeignKeyDDL(ForeignKey $fk)
  492. {
  493. if ($fk->isSkipSql()) {
  494. return;
  495. }
  496. $pattern = "
  497. ALTER TABLE %s ADD %s;
  498. ";
  499. return sprintf($pattern,
  500. $this->quoteIdentifier($fk->getTable()->getName()),
  501. $this->getForeignKeyDDL($fk)
  502. );
  503. }
  504. /**
  505. * Builds the DDL SQL to drop a foreign key.
  506. *
  507. * @param ForeignKey $fk
  508. * @return string
  509. */
  510. public function getDropForeignKeyDDL(ForeignKey $fk)
  511. {
  512. if ($fk->isSkipSql()) {
  513. return;
  514. }
  515. $pattern = "
  516. ALTER TABLE %s DROP CONSTRAINT %s;
  517. ";
  518. return sprintf($pattern,
  519. $this->quoteIdentifier($fk->getTable()->getName()),
  520. $this->quoteIdentifier($fk->getName())
  521. );
  522. }
  523. /**
  524. * Builds the DDL SQL for a ForeignKey object.
  525. * @return string
  526. */
  527. public function getForeignKeyDDL(ForeignKey $fk)
  528. {
  529. if ($fk->isSkipSql()) {
  530. return;
  531. }
  532. $pattern = "CONSTRAINT %s
  533. FOREIGN KEY (%s)
  534. REFERENCES %s (%s)";
  535. $script = sprintf($pattern,
  536. $this->quoteIdentifier($fk->getName()),
  537. $this->getColumnListDDL($fk->getLocalColumns()),
  538. $this->quoteIdentifier($fk->getForeignTableName()),
  539. $this->getColumnListDDL($fk->getForeignColumns())
  540. );
  541. if ($fk->hasOnUpdate()) {
  542. $script .= "
  543. ON UPDATE " . $fk->getOnUpdate();
  544. }
  545. if ($fk->hasOnDelete()) {
  546. $script .= "
  547. ON DELETE " . $fk->getOnDelete();
  548. }
  549. return $script;
  550. }
  551. public function getCommentLineDDL($comment)
  552. {
  553. $pattern = "-- %s
  554. ";
  555. return sprintf($pattern, $comment);
  556. }
  557. public function getCommentBlockDDL($comment)
  558. {
  559. $pattern = "
  560. -----------------------------------------------------------------------
  561. -- %s
  562. -----------------------------------------------------------------------
  563. ";
  564. return sprintf($pattern, $comment);
  565. }
  566. /**
  567. * Builds the DDL SQL to modify a database
  568. * based on a PropelDatabaseDiff instance
  569. *
  570. * @return string
  571. */
  572. public function getModifyDatabaseDDL(PropelDatabaseDiff $databaseDiff)
  573. {
  574. $ret = $this->getBeginDDL();
  575. foreach ($databaseDiff->getRemovedTables() as $table) {
  576. $ret .= $this->getDropTableDDL($table);
  577. }
  578. foreach ($databaseDiff->getRenamedTables() as $fromTableName => $toTableName) {
  579. $ret .= $this->getRenameTableDDL($fromTableName, $toTableName);
  580. }
  581. foreach ($databaseDiff->getAddedTables() as $table) {
  582. $ret .= $this->getAddTableDDL($table);
  583. $ret .= $this->getAddIndicesDDL($table);
  584. }
  585. foreach ($databaseDiff->getModifiedTables() as $tableDiff) {
  586. $ret .= $this->getModifyTableDDL($tableDiff);
  587. }
  588. foreach ($databaseDiff->getAddedTables() as $table) {
  589. $ret .= $this->getAddForeignKeysDDL($table);
  590. }
  591. $ret .= $this->getEndDDL();
  592. return $ret;
  593. }
  594. /**
  595. * Builds the DDL SQL to rename a table
  596. * @return string
  597. */
  598. public function getRenameTableDDL($fromTableName, $toTableName)
  599. {
  600. $pattern = "
  601. ALTER TABLE %s RENAME TO %s;
  602. ";
  603. return sprintf($pattern,
  604. $this->quoteIdentifier($fromTableName),
  605. $this->quoteIdentifier($toTableName)
  606. );
  607. }
  608. /**
  609. * Builds the DDL SQL to alter a table
  610. * based on a PropelTableDiff instance
  611. *
  612. * @return string
  613. */
  614. public function getModifyTableDDL(PropelTableDiff $tableDiff)
  615. {
  616. $ret = '';
  617. // drop indices, foreign keys
  618. if ($tableDiff->hasModifiedPk()) {
  619. $ret .= $this->getDropPrimaryKeyDDL($tableDiff->getFromTable());
  620. }
  621. foreach ($tableDiff->getRemovedFks() as $fk) {
  622. $ret .= $this->getDropForeignKeyDDL($fk);
  623. }
  624. foreach ($tableDiff->getModifiedFks() as $fkName => $fkModification) {
  625. list($fromFk, $toFk) = $fkModification;
  626. $ret .= $this->getDropForeignKeyDDL($fromFk);
  627. }
  628. foreach ($tableDiff->getRemovedIndices() as $index) {
  629. $ret .= $this->getDropIndexDDL($index);
  630. }
  631. foreach ($tableDiff->getModifiedIndices() as $indexName => $indexModification) {
  632. list($fromIndex, $toIndex) = $indexModification;
  633. $ret .= $this->getDropIndexDDL($fromIndex);
  634. }
  635. // alter table structure
  636. foreach ($tableDiff->getRenamedColumns() as $columnRenaming) {
  637. $ret .= $this->getRenameColumnDDL($columnRenaming[0], $columnRenaming[1]);
  638. }
  639. if ($modifiedColumns = $tableDiff->getModifiedColumns()) {
  640. $ret .= $this->getModifyColumnsDDL($modifiedColumns);
  641. }
  642. if ($addedColumns = $tableDiff->getAddedColumns()) {
  643. $ret .= $this->getAddColumnsDDL($addedColumns);
  644. }
  645. foreach ($tableDiff->getRemovedColumns() as $column) {
  646. $ret .= $this->getRemoveColumnDDL($column);
  647. }
  648. // add new indices and foreign keys
  649. if ($tableDiff->hasModifiedPk()) {
  650. $ret .= $this->getAddPrimaryKeyDDL($tableDiff->getToTable());
  651. }
  652. foreach ($tableDiff->getModifiedIndices() as $indexName => $indexModification) {
  653. list($fromIndex, $toIndex) = $indexModification;
  654. $ret .= $this->getAddIndexDDL($toIndex);
  655. }
  656. foreach ($tableDiff->getAddedIndices() as $index) {
  657. $ret .= $this->getAddIndexDDL($index);
  658. }
  659. foreach ($tableDiff->getModifiedFks() as $fkName => $fkModification) {
  660. list($fromFk, $toFk) = $fkModification;
  661. $ret .= $this->getAddForeignKeyDDL($toFk);
  662. }
  663. foreach ($tableDiff->getAddedFks() as $fk) {
  664. $ret .= $this->getAddForeignKeyDDL($fk);
  665. }
  666. return $ret;
  667. }
  668. /**
  669. * Builds the DDL SQL to alter a table
  670. * based on a PropelTableDiff instance
  671. *
  672. * @return string
  673. */
  674. public function getModifyTableColumnsDDL(PropelTableDiff $tableDiff)
  675. {
  676. $ret = '';
  677. foreach ($tableDiff->getRemovedColumns() as $column) {
  678. $ret .= $this->getRemoveColumnDDL($column);
  679. }
  680. foreach ($tableDiff->getRenamedColumns() as $columnRenaming) {
  681. $ret .= $this->getRenameColumnDDL($columnRenaming[0], $columnRenaming[1]);
  682. }
  683. if ($modifiedColumns = $tableDiff->getModifiedColumns()) {
  684. $ret .= $this->getModifyColumnsDDL($modifiedColumns);
  685. }
  686. if ($addedColumns = $tableDiff->getAddedColumns()) {
  687. $ret .= $this->getAddColumnsDDL($addedColumns);
  688. }
  689. return $ret;
  690. }
  691. /**
  692. * Builds the DDL SQL to alter a table's primary key
  693. * based on a PropelTableDiff instance
  694. *
  695. * @return string
  696. */
  697. public function getModifyTablePrimaryKeyDDL(PropelTableDiff $tableDiff)
  698. {
  699. $ret = '';
  700. if ($tableDiff->hasModifiedPk()) {
  701. $ret .= $this->getDropPrimaryKeyDDL($tableDiff->getFromTable());
  702. $ret .= $this->getAddPrimaryKeyDDL($tableDiff->getToTable());
  703. }
  704. return $ret;
  705. }
  706. /**
  707. * Builds the DDL SQL to alter a table's indices
  708. * based on a PropelTableDiff instance
  709. *
  710. * @return string
  711. */
  712. public function getModifyTableIndicesDDL(PropelTableDiff $tableDiff)
  713. {
  714. $ret = '';
  715. foreach ($tableDiff->getRemovedIndices() as $index) {
  716. $ret .= $this->getDropIndexDDL($index);
  717. }
  718. foreach ($tableDiff->getAddedIndices() as $index) {
  719. $ret .= $this->getAddIndexDDL($index);
  720. }
  721. foreach ($tableDiff->getModifiedIndices() as $indexName => $indexModification) {
  722. list($fromIndex, $toIndex) = $indexModification;
  723. $ret .= $this->getDropIndexDDL($fromIndex);
  724. $ret .= $this->getAddIndexDDL($toIndex);
  725. }
  726. return $ret;
  727. }
  728. /**
  729. * Builds the DDL SQL to alter a table's foreign keys
  730. * based on a PropelTableDiff instance
  731. *
  732. * @return string
  733. */
  734. public function getModifyTableForeignKeysDDL(PropelTableDiff $tableDiff)
  735. {
  736. $ret = '';
  737. foreach ($tableDiff->getRemovedFks() as $fk) {
  738. $ret .= $this->getDropForeignKeyDDL($fk);
  739. }
  740. foreach ($tableDiff->getAddedFks() as $fk) {
  741. $ret .= $this->getAddForeignKeyDDL($fk);
  742. }
  743. foreach ($tableDiff->getModifiedFks() as $fkName => $fkModification) {
  744. list($fromFk, $toFk) = $fkModification;
  745. $ret .= $this->getDropForeignKeyDDL($fromFk);
  746. $ret .= $this->getAddForeignKeyDDL($toFk);
  747. }
  748. return $ret;
  749. }
  750. /**
  751. * Builds the DDL SQL to remove a column
  752. *
  753. * @return string
  754. */
  755. public function getRemoveColumnDDL(Column $column)
  756. {
  757. $pattern = "
  758. ALTER TABLE %s DROP COLUMN %s;
  759. ";
  760. return sprintf($pattern,
  761. $this->quoteIdentifier($column->getTable()->getName()),
  762. $this->quoteIdentifier($column->getName())
  763. );
  764. }
  765. /**
  766. * Builds the DDL SQL to rename a column
  767. * @return string
  768. */
  769. public function getRenameColumnDDL($fromColumn, $toColumn)
  770. {
  771. $pattern = "
  772. ALTER TABLE %s RENAME COLUMN %s TO %s;
  773. ";
  774. return sprintf($pattern,
  775. $this->quoteIdentifier($fromColumn->getTable()->getName()),
  776. $this->quoteIdentifier($fromColumn->getName()),
  777. $this->quoteIdentifier($toColumn->getName())
  778. );
  779. }
  780. /**
  781. * Builds the DDL SQL to modify a column
  782. *
  783. * @return string
  784. */
  785. public function getModifyColumnDDL(PropelColumnDiff $columnDiff)
  786. {
  787. $toColumn = $columnDiff->getToColumn();
  788. $pattern = "
  789. ALTER TABLE %s MODIFY %s;
  790. ";
  791. return sprintf($pattern,
  792. $this->quoteIdentifier($toColumn->getTable()->getName()),
  793. $this->getColumnDDL($toColumn)
  794. );
  795. }
  796. /**
  797. * Builds the DDL SQL to modify a list of columns
  798. *
  799. * @return string
  800. */
  801. public function getModifyColumnsDDL($columnDiffs)
  802. {
  803. $lines = array();
  804. $tableName = null;
  805. foreach ($columnDiffs as $columnDiff) {
  806. $toColumn = $columnDiff->getToColumn();
  807. if (null === $tableName) {
  808. $tableName = $toColumn->getTable()->getName();
  809. }
  810. $lines []= $this->getColumnDDL($toColumn);
  811. }
  812. $sep = ",
  813. ";
  814. $pattern = "
  815. ALTER TABLE %s MODIFY
  816. (
  817. %s
  818. );
  819. ";
  820. return sprintf($pattern,
  821. $this->quoteIdentifier($tableName),
  822. implode($sep, $lines)
  823. );
  824. }
  825. /**
  826. * Builds the DDL SQL to remove a column
  827. *
  828. * @return string
  829. */
  830. public function getAddColumnDDL(Column $column)
  831. {
  832. $pattern = "
  833. ALTER TABLE %s ADD %s;
  834. ";
  835. return sprintf($pattern,
  836. $this->quoteIdentifier($column->getTable()->getName()),
  837. $this->getColumnDDL($column)
  838. );
  839. }
  840. /**
  841. * Builds the DDL SQL to remove a list of columns
  842. *
  843. * @return string
  844. */
  845. public function getAddColumnsDDL($columns)
  846. {
  847. $lines = array();
  848. $tableName = null;
  849. foreach ($columns as $column) {
  850. if (null === $tableName) {
  851. $tableName = $column->getTable()->getName();
  852. }
  853. $lines []= $this->getColumnDDL($column);
  854. }
  855. $sep = ",
  856. ";
  857. $pattern = "
  858. ALTER TABLE %s ADD
  859. (
  860. %s
  861. );
  862. ";
  863. return sprintf($pattern,
  864. $this->quoteIdentifier($tableName),
  865. implode($sep, $lines)
  866. );
  867. }
  868. /**
  869. * Returns if the RDBMS-specific SQL type has a size attribute.
  870. *
  871. * @param string $sqlType the SQL type
  872. * @return boolean True if the type has a size attribute
  873. */
  874. public function hasSize($sqlType)
  875. {
  876. return true;
  877. }
  878. /**
  879. * Returns if the RDBMS-specific SQL type has a scale attribute.
  880. *
  881. * @param string $sqlType the SQL type
  882. * @return boolean True if the type has a scale attribute
  883. */
  884. public function hasScale($sqlType)
  885. {
  886. return true;
  887. }
  888. /**
  889. * Quote and escape needed characters in the string for unerlying RDBMS.
  890. * @param string $text
  891. * @return string
  892. */
  893. public function quote($text)
  894. {
  895. if ($con = $this->getConnection()) {
  896. return $con->quote($text);
  897. } else {
  898. return "'" . $this->disconnectedEscapeText($text) . "'";
  899. }
  900. }
  901. /**
  902. * Method to escape text when no connection has been set.
  903. *
  904. * The subclasses can implement this using string replacement functions
  905. * or native DB methods.
  906. *
  907. * @param string $text Text that needs to be escaped.
  908. * @return string
  909. */
  910. protected function disconnectedEscapeText($text)
  911. {
  912. return str_replace("'", "''", $text);
  913. }
  914. /**
  915. * Quotes identifiers used in database SQL.
  916. * @param string $text
  917. * @return string Quoted identifier.
  918. */
  919. public function quoteIdentifier($text)
  920. {
  921. return $this->isIdentifierQuotingEnabled ? '"' . strtr($text, array('.' => '"."')) . '"' : $text;
  922. }
  923. public function setIdentifierQuoting($enabled = true)
  924. {
  925. $this->isIdentifierQuotingEnabled = $enabled;
  926. }
  927. public function getIdentifierQuoting()
  928. {
  929. return $this->isIdentifierQuotingEnabled;
  930. }
  931. /**
  932. * Whether RDBMS supports native ON DELETE triggers (e.g. ON DELETE CASCADE).
  933. * @return boolean
  934. */
  935. public function supportsNativeDeleteTrigger()
  936. {
  937. return false;
  938. }
  939. /**
  940. * Whether RDBMS supports INSERT null values in autoincremented primary keys
  941. * @return boolean
  942. */
  943. public function supportsInsertNullPk()
  944. {
  945. return true;
  946. }
  947. /**
  948. * Whether the underlying PDO driver for this platform returns BLOB columns as streams (instead of strings).
  949. * @return boolean
  950. */
  951. public function hasStreamBlobImpl()
  952. {
  953. return false;
  954. }
  955. /**
  956. * @see Platform::supportsSchemas()
  957. */
  958. public function supportsSchemas()
  959. {
  960. return false;
  961. }
  962. /**
  963. * @see Platform::supportsMigrations()
  964. */
  965. public function supportsMigrations()
  966. {
  967. return true;
  968. }
  969. public function supportsVarcharWithoutSize()
  970. {
  971. return false;
  972. }
  973. /**
  974. * Returns the boolean value for the RDBMS.
  975. *
  976. * This value should match the boolean value that is set
  977. * when using Propel's PreparedStatement::setBoolean().
  978. *
  979. * This function is used to set default column values when building
  980. * SQL.
  981. *
  982. * @param mixed $tf A boolean or string representation of boolean ('y', 'true').
  983. * @return mixed
  984. */
  985. public function getBooleanString($b)
  986. {
  987. $b = ($b === true || strtolower($b) === 'true' || $b === 1 || $b === '1' || strtolower($b) === 'y' || strtolower($b) === 'yes');
  988. return ($b ? '1' : '0');
  989. }
  990. /**
  991. * Gets the preferred timestamp formatter for setting date/time values.
  992. * @return string
  993. */
  994. public function getTimestampFormatter()
  995. {
  996. return 'Y-m-d H:i:s';
  997. }
  998. /**
  999. * Gets the preferred time formatter for setting date/time values.
  1000. * @return string
  1001. */
  1002. public function getTimeFormatter()
  1003. {
  1004. return 'H:i:s';
  1005. }
  1006. /**
  1007. * Gets the preferred date formatter for setting date/time values.
  1008. * @return string
  1009. */
  1010. public function getDateFormatter()
  1011. {
  1012. return 'Y-m-d';
  1013. }
  1014. }