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

/www/application/modules/shop/classes/propel/generator/lib/platform/MysqlPlatform.php

https://github.com/kelios/imshop
PHP | 547 lines | 380 code | 57 blank | 110 comment | 51 complexity | 5ea6fe8227f052dd00a115705daa9a0e 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__) . '/DefaultPlatform.php';
  10. /**
  11. * MySql PropelPlatformInterface implementation.
  12. *
  13. * @author Hans Lellelid <hans@xmpl.org> (Propel)
  14. * @author Martin Poeschl <mpoeschl@marmot.at> (Torque)
  15. * @version $Revision: 1991 $
  16. * @package propel.generator.platform
  17. */
  18. class MysqlPlatform extends DefaultPlatform
  19. {
  20. protected $tableEngineKeyword = 'ENGINE';
  21. protected $defaultTableEngine = 'InnoDB';
  22. /**
  23. * Initializes db specific domain mapping.
  24. */
  25. protected function initialize()
  26. {
  27. parent::initialize();
  28. $this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "TINYINT"));
  29. $this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL"));
  30. $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT"));
  31. $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB"));
  32. $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB"));
  33. $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB"));
  34. $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB"));
  35. $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
  36. $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME"));
  37. }
  38. /**
  39. * Setter for the tableEngineKeyword property
  40. *
  41. * @param string $tableEngineKeyword
  42. */
  43. function setTableEngineKeyword($tableEngineKeyword)
  44. {
  45. $this->tableEngineKeyword = $tableEngineKeyword;
  46. }
  47. /**
  48. * Getter for the tableEngineKeyword property
  49. *
  50. * @return string
  51. */
  52. function getTableEngineKeyword()
  53. {
  54. return $this->tableEngineKeyword;
  55. }
  56. /**
  57. * Setter for the defaultTableEngine property
  58. *
  59. * @param string $defaultTableEngine
  60. */
  61. function setDefaultTableEngine($defaultTableEngine)
  62. {
  63. $this->defaultTableEngine = $defaultTableEngine;
  64. }
  65. /**
  66. * Getter for the defaultTableEngine property
  67. *
  68. * @return string
  69. */
  70. function getDefaultTableEngine()
  71. {
  72. return $this->defaultTableEngine;
  73. }
  74. public function getAutoIncrement()
  75. {
  76. return "AUTO_INCREMENT";
  77. }
  78. public function getMaxColumnNameLength()
  79. {
  80. return 64;
  81. }
  82. public function supportsNativeDeleteTrigger()
  83. {
  84. $usingInnoDB = false;
  85. if (class_exists('DataModelBuilder', false)) {
  86. $usingInnoDB = strtolower($this->getBuildProperty('mysqlTableType')) == 'innodb';
  87. }
  88. return $usingInnoDB || false;
  89. }
  90. public function getAddTablesDDL(Database $database)
  91. {
  92. $ret = $this->getBeginDDL();
  93. foreach ($database->getTablesForSql() as $table) {
  94. $ret .= $this->getCommentBlockDDL($table->getName());
  95. $ret .= $this->getDropTableDDL($table);
  96. $ret .= $this->getAddTableDDL($table);
  97. }
  98. $ret .= $this->getEndDDL();
  99. return $ret;
  100. }
  101. public function getBeginDDL()
  102. {
  103. return "
  104. # This is a fix for InnoDB in MySQL >= 4.1.x
  105. # It \"suspends judgement\" for fkey relationships until are tables are set.
  106. SET FOREIGN_KEY_CHECKS = 0;
  107. ";
  108. }
  109. public function getEndDDL()
  110. {
  111. return "
  112. # This restores the fkey checks, after having unset them earlier
  113. SET FOREIGN_KEY_CHECKS = 1;
  114. ";
  115. }
  116. public function getAddTableDDL(Table $table)
  117. {
  118. $lines = array();
  119. foreach ($table->getColumns() as $column) {
  120. $lines[] = $this->getColumnDDL($column);
  121. }
  122. if ($table->hasPrimaryKey()) {
  123. $lines[] = $this->getPrimaryKeyDDL($table);
  124. }
  125. foreach ($table->getUnices() as $unique) {
  126. $lines[] = $this->getUniqueDDL($unique);
  127. }
  128. foreach ($table->getIndices() as $index ) {
  129. $lines[] = $this->getIndexDDL($index);
  130. }
  131. foreach ($table->getForeignKeys() as $foreignKey) {
  132. $lines[] = str_replace("
  133. ", "
  134. ", $this->getForeignKeyDDL($foreignKey));
  135. }
  136. $vendorSpecific = $table->getVendorInfoForType('mysql');
  137. if ($vendorSpecific->hasParameter('Type')) {
  138. $mysqlTableType = $vendorSpecific->getParameter('Type');
  139. } elseif ($vendorSpecific->hasParameter('Engine')) {
  140. $mysqlTableType = $vendorSpecific->getParameter('Engine');
  141. } else {
  142. $mysqlTableType = $this->getDefaultTableEngine();
  143. }
  144. $tableOptions = $this->getTableOptions($table);
  145. if ($table->getDescription()) {
  146. $tableOptions []= 'COMMENT=' . $this->quote($table->getDescription());
  147. }
  148. $tableOptions = $tableOptions ? ' ' . implode(' ', $tableOptions) : '';
  149. $sep = ",
  150. ";
  151. $pattern = "
  152. CREATE TABLE %s
  153. (
  154. %s
  155. ) %s=%s%s;
  156. ";
  157. return sprintf($pattern,
  158. $this->quoteIdentifier($table->getName()),
  159. implode($sep, $lines),
  160. $this->getTableEngineKeyword(),
  161. $mysqlTableType,
  162. $tableOptions
  163. );
  164. }
  165. protected function getTableOptions(Table $table)
  166. {
  167. $dbVI = $table->getDatabase()->getVendorInfoForType('mysql');
  168. $tableVI = $table->getVendorInfoForType('mysql');
  169. $vi = $dbVI->getMergedVendorInfo($tableVI);
  170. $tableOptions = array();
  171. $supportedOptions = array(
  172. 'Charset' => 'CHARACTER SET',
  173. 'Collate' => 'COLLATE',
  174. 'Checksum' => 'CHECKSUM',
  175. 'Pack_Keys' => 'PACK_KEYS',
  176. 'Delay_key_write' => 'DELAY_KEY_WRITE',
  177. );
  178. foreach ($supportedOptions as $name => $sqlName) {
  179. if ($vi->hasParameter($name)) {
  180. $tableOptions []= sprintf('%s=%s',
  181. $sqlName,
  182. $this->quote($vi->getParameter($name))
  183. );
  184. }
  185. }
  186. return $tableOptions;
  187. }
  188. public function getDropTableDDL(Table $table)
  189. {
  190. return "
  191. DROP TABLE IF EXISTS " . $this->quoteIdentifier($table->getName()) . ";
  192. ";
  193. }
  194. public function getColumnDDL(Column $col)
  195. {
  196. $domain = $col->getDomain();
  197. $sqlType = $domain->getSqlType();
  198. $notNullString = $this->getNullString($col->isNotNull());
  199. $defaultSetting = $this->getColumnDefaultValueDDL($col);
  200. // Special handling of TIMESTAMP/DATETIME types ...
  201. // See: http://propel.phpdb.org/trac/ticket/538
  202. if ($sqlType == 'DATETIME') {
  203. $def = $domain->getDefaultValue();
  204. if ($def && $def->isExpression()) { // DATETIME values can only have constant expressions
  205. $sqlType = 'TIMESTAMP';
  206. }
  207. } elseif ($sqlType == 'DATE') {
  208. $def = $domain->getDefaultValue();
  209. if ($def && $def->isExpression()) {
  210. throw new EngineException("DATE columns cannot have default *expressions* in MySQL.");
  211. }
  212. } elseif ($sqlType == 'TEXT' || $sqlType == 'BLOB') {
  213. if ($domain->getDefaultValue()) {
  214. throw new EngineException("BLOB and TEXT columns cannot have DEFAULT values. in MySQL.");
  215. }
  216. }
  217. $ddl = array($this->quoteIdentifier($col->getName()));
  218. if ($this->hasSize($sqlType)) {
  219. $ddl []= $sqlType . $domain->printSize();
  220. } else {
  221. $ddl []= $sqlType;
  222. }
  223. if ($sqlType == 'TIMESTAMP') {
  224. if ($notNullString == '') {
  225. $notNullString = 'NULL';
  226. }
  227. if ($defaultSetting == '' && $notNullString == 'NOT NULL') {
  228. $defaultSetting = 'DEFAULT CURRENT_TIMESTAMP';
  229. }
  230. if ($notNullString) {
  231. $ddl []= $notNullString;
  232. }
  233. if ($defaultSetting) {
  234. $ddl []= $defaultSetting;
  235. }
  236. } else {
  237. if ($defaultSetting) {
  238. $ddl []= $defaultSetting;
  239. }
  240. if ($notNullString) {
  241. $ddl []= $notNullString;
  242. }
  243. }
  244. if ($autoIncrement = $col->getAutoIncrementString()) {
  245. $ddl []= $autoIncrement;
  246. }
  247. $colinfo = $col->getVendorInfoForType($this->getDatabaseType());
  248. if ($colinfo->hasParameter('Charset')) {
  249. $ddl []= 'CHARACTER SET '. $this->quote($colinfo->getParameter('Charset'));
  250. }
  251. if ($colinfo->hasParameter('Collation')) {
  252. $ddl []= 'COLLATE '. $this->quote($colinfo->getParameter('Collation'));
  253. } elseif ($colinfo->hasParameter('Collate')) {
  254. $ddl []= 'COLLATE '. $this->quote($colinfo->getParameter('Collate'));
  255. }
  256. if ($col->getDescription()) {
  257. $ddl []= 'COMMENT ' . $this->quote($col->getDescription());
  258. }
  259. return implode(' ', $ddl);
  260. }
  261. /**
  262. * Creates a comma-separated list of column names for the index.
  263. * For MySQL unique indexes there is the option of specifying size, so we cannot simply use
  264. * the getColumnsList() method.
  265. * @param Index $index
  266. * @return string
  267. */
  268. protected function getIndexColumnListDDL(Index $index)
  269. {
  270. $list = array();
  271. foreach ($index->getColumns() as $col) {
  272. $list[] = $this->quoteIdentifier($col) . ($index->hasColumnSize($col) ? '(' . $index->getColumnSize($col) . ')' : '');
  273. }
  274. return implode(', ', $list);
  275. }
  276. /**
  277. * Builds the DDL SQL to drop the primary key of a table.
  278. *
  279. * @param Table $table
  280. * @return string
  281. */
  282. public function getDropPrimaryKeyDDL(Table $table)
  283. {
  284. $pattern = "
  285. ALTER TABLE %s DROP PRIMARY KEY;
  286. ";
  287. return sprintf($pattern,
  288. $this->quoteIdentifier($table->getName())
  289. );
  290. }
  291. /**
  292. * Builds the DDL SQL to add an Index.
  293. *
  294. * @param Index $index
  295. * @return string
  296. */
  297. public function getAddIndexDDL(Index $index)
  298. {
  299. $pattern = "
  300. CREATE %sINDEX %s ON %s (%s);
  301. ";
  302. return sprintf($pattern,
  303. $this->getIndexType($index),
  304. $this->quoteIdentifier($index->getName()),
  305. $this->quoteIdentifier($index->getTable()->getName()),
  306. $this->getColumnListDDL($index->getColumns())
  307. );
  308. }
  309. /**
  310. * Builds the DDL SQL to drop an Index.
  311. *
  312. * @param Index $index
  313. * @return string
  314. */
  315. public function getDropIndexDDL(Index $index)
  316. {
  317. $pattern = "
  318. DROP INDEX %s ON %s;
  319. ";
  320. return sprintf($pattern,
  321. $this->quoteIdentifier($index->getName()),
  322. $this->quoteIdentifier($index->getTable()->getName())
  323. );
  324. }
  325. /**
  326. * Builds the DDL SQL for an Index object.
  327. * @return string
  328. */
  329. public function getIndexDDL(Index $index)
  330. {
  331. return sprintf('%sINDEX %s (%s)',
  332. $this->getIndexType($index),
  333. $this->quoteIdentifier($index->getName()),
  334. $this->getIndexColumnListDDL($index)
  335. );
  336. }
  337. protected function getIndexType(Index $index)
  338. {
  339. $type = '';
  340. $vendorInfo = $index->getVendorInfoForType($this->getDatabaseType());
  341. if ($vendorInfo && $vendorInfo->getParameter('Index_type')) {
  342. $type = $vendorInfo->getParameter('Index_type') . ' ';
  343. } elseif ($index->getIsUnique()) {
  344. $type = 'UNIQUE ';
  345. }
  346. return $type;
  347. }
  348. public function getUniqueDDL(Unique $unique)
  349. {
  350. return sprintf('UNIQUE INDEX %s (%s)',
  351. $this->quoteIdentifier($unique->getName()),
  352. $this->getIndexColumnListDDL($unique)
  353. );
  354. }
  355. public function getDropForeignKeyDDL(ForeignKey $fk)
  356. {
  357. $pattern = "
  358. ALTER TABLE %s DROP FOREIGN KEY %s;
  359. ";
  360. return sprintf($pattern,
  361. $this->quoteIdentifier($fk->getTable()->getName()),
  362. $this->quoteIdentifier($fk->getName())
  363. );
  364. }
  365. /**
  366. * Builds the DDL SQL to modify a database
  367. * based on a PropelDatabaseDiff instance
  368. *
  369. * @return string
  370. */
  371. public function getModifyDatabaseDDL(PropelDatabaseDiff $databaseDiff)
  372. {
  373. $ret = $this->getBeginDDL();
  374. foreach ($databaseDiff->getRemovedTables() as $table) {
  375. $ret .= $this->getDropTableDDL($table);
  376. }
  377. foreach ($databaseDiff->getRenamedTables() as $fromTableName => $toTableName) {
  378. $ret .= $this->getRenameTableDDL($fromTableName, $toTableName);
  379. }
  380. foreach ($databaseDiff->getModifiedTables() as $tableDiff) {
  381. $ret .= $this->getModifyTableDDL($tableDiff);
  382. }
  383. foreach ($databaseDiff->getAddedTables() as $table) {
  384. $ret .= $this->getAddTableDDL($table);
  385. }
  386. $ret .= $this->getEndDDL();
  387. return $ret;
  388. }
  389. /**
  390. * Builds the DDL SQL to rename a table
  391. * @return string
  392. */
  393. public function getRenameTableDDL($fromTableName, $toTableName)
  394. {
  395. $pattern = "
  396. RENAME TABLE %s TO %s;
  397. ";
  398. return sprintf($pattern,
  399. $this->quoteIdentifier($fromTableName),
  400. $this->quoteIdentifier($toTableName)
  401. );
  402. }
  403. /**
  404. * Builds the DDL SQL to remove a column
  405. *
  406. * @return string
  407. */
  408. public function getRemoveColumnDDL(Column $column)
  409. {
  410. $pattern = "
  411. ALTER TABLE %s DROP %s;
  412. ";
  413. return sprintf($pattern,
  414. $this->quoteIdentifier($column->getTable()->getName()),
  415. $this->quoteIdentifier($column->getName())
  416. );
  417. }
  418. /**
  419. * Builds the DDL SQL to rename a column
  420. * @return string
  421. */
  422. public function getRenameColumnDDL($fromColumn, $toColumn)
  423. {
  424. return $this->getChangeColumnDDL($fromColumn, $toColumn);
  425. }
  426. /**
  427. * Builds the DDL SQL to modify a column
  428. *
  429. * @return string
  430. */
  431. public function getModifyColumnDDL(PropelColumnDiff $columnDiff)
  432. {
  433. return $this->getChangeColumnDDL($columnDiff->getFromColumn(), $columnDiff->getToColumn());
  434. }
  435. /**
  436. * Builds the DDL SQL to change a column
  437. * @return string
  438. */
  439. public function getChangeColumnDDL($fromColumn, $toColumn)
  440. {
  441. $pattern = "
  442. ALTER TABLE %s CHANGE %s %s;
  443. ";
  444. return sprintf($pattern,
  445. $this->quoteIdentifier($fromColumn->getTable()->getName()),
  446. $this->quoteIdentifier($fromColumn->getName()),
  447. $this->getColumnDDL($toColumn)
  448. );
  449. }
  450. /**
  451. * Builds the DDL SQL to modify a list of columns
  452. *
  453. * @return string
  454. */
  455. public function getModifyColumnsDDL($columnDiffs)
  456. {
  457. $ret = '';
  458. foreach ($columnDiffs as $columnDiff) {
  459. $ret .= $this->getModifyColumnDDL($columnDiff);
  460. }
  461. return $ret;
  462. }
  463. public function hasSize($sqlType)
  464. {
  465. return !("MEDIUMTEXT" == $sqlType || "LONGTEXT" == $sqlType
  466. || "BLOB" == $sqlType || "MEDIUMBLOB" == $sqlType
  467. || "LONGBLOB" == $sqlType);
  468. }
  469. /**
  470. * Escape the string for RDBMS.
  471. * @param string $text
  472. * @return string
  473. */
  474. public function disconnectedEscapeText($text)
  475. {
  476. if (function_exists('mysql_escape_string')) {
  477. return mysql_escape_string($text);
  478. } else {
  479. return addslashes($text);
  480. }
  481. }
  482. public function quoteIdentifier($text)
  483. {
  484. return $this->isIdentifierQuotingEnabled ? '`' . $text . '`' : $text;
  485. }
  486. public function getTimestampFormatter()
  487. {
  488. return 'Y-m-d H:i:s';
  489. }
  490. }