/protected/components/ezcomponents/DatabaseSchema/src/handlers/common_sql_writer.php

https://github.com/kamarulismail/kamarul-playground · PHP · 342 lines · 141 code · 41 blank · 160 comment · 6 complexity · f93fbf1e25a0ae751298d6edf8834248 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcDbSchemaCommonSqlWriter class.
  4. *
  5. * @package DatabaseSchema
  6. * @version 1.4.4
  7. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. */
  10. /**
  11. * An abstract class that implements some common functionality required by
  12. * multiple database backends.
  13. *
  14. * @package DatabaseSchema
  15. * @version 1.4.4
  16. */
  17. abstract class ezcDbSchemaCommonSqlWriter implements ezcDbSchemaDbWriter, ezcDbSchemaDiffDbWriter
  18. {
  19. /**
  20. * Stores a list of queries that is generated by the various Database writing backends.
  21. *
  22. * @var array(string)
  23. */
  24. protected $queries;
  25. /**
  26. * Stores the schema definition where the generators operate on.
  27. *
  28. * @var ezcDbSchema
  29. */
  30. protected $schema;
  31. /**
  32. * Returns what type of schema writer this class implements.
  33. *
  34. * This method always returns ezcDbSchema::DATABASE
  35. *
  36. * @return int
  37. */
  38. public function getWriterType()
  39. {
  40. return ezcDbSchema::DATABASE;
  41. }
  42. /**
  43. * Creates the tables contained in $schema in the database that is related to $db
  44. *
  45. * This method takes the table definitions from $schema and will create the
  46. * tables according to this definition in the database that is references
  47. * by the $db handler. If tables with the same name as contained in the
  48. * definitions already exist they will be removed and recreated with the
  49. * new definition.
  50. *
  51. * @param ezcDbHandler $db
  52. * @param ezcDbSchema $dbSchema
  53. */
  54. public function saveToDb( ezcDbHandler $db, ezcDbSchema $dbSchema )
  55. {
  56. $db->beginTransaction();
  57. foreach ( $this->convertToDDL( $dbSchema ) as $query )
  58. {
  59. if ( $this->isQueryAllowed( $db, $query ) )
  60. {
  61. $db->exec( $query );
  62. }
  63. }
  64. $db->commit();
  65. }
  66. /**
  67. * Returns an array with SQL DDL statements that creates the database definition in $dbSchema
  68. *
  69. * Converts the schema definition contained in $dbSchema to DDL SQL. This
  70. * SQL can be used to create tables in an existing database according to
  71. * the definition. The SQL queries are returned as an array.
  72. *
  73. * @param ezcDbSchema $dbSchema
  74. * @return array(string)
  75. */
  76. public function convertToDDL( ezcDbSchema $dbSchema )
  77. {
  78. $this->schema = $dbSchema->getSchema();
  79. // reset queries
  80. $this->queries = array();
  81. $this->context = array();
  82. $this->generateSchemaAsSql();
  83. return $this->queries;
  84. }
  85. /**
  86. * Checks if the query is allowed.
  87. *
  88. * Perform testing if table exist for DROP TABLE query
  89. * to avoid stoping execution while try to drop not existent table.
  90. *
  91. * @param ezcDbHandler $db
  92. * @param string $query
  93. *
  94. * @return boolean
  95. */
  96. public function isQueryAllowed( ezcDbHandler $db, $query )
  97. {
  98. return true;
  99. }
  100. /**
  101. * Creates SQL DDL statements from a schema definitin.
  102. *
  103. * Loops over the tables in the schema definition in $this->schema and
  104. * creates SQL SSL statements for this which it stores internally into the
  105. * $this->queries array.
  106. */
  107. protected function generateSchemaAsSql()
  108. {
  109. $prefix = ezcDbSchema::$options->tableNamePrefix;
  110. foreach ( $this->schema as $tableName => $tableDefinition )
  111. {
  112. $this->generateDropTableSql( $prefix . $tableName );
  113. $this->generateCreateTableSql( $prefix . $tableName, $tableDefinition );
  114. }
  115. }
  116. /**
  117. * Returns a "CREATE TABLE" SQL statement part for the table $tableName.
  118. *
  119. * @param string $tableName
  120. * @return string
  121. */
  122. protected function generateCreateTableSqlStatement( $tableName )
  123. {
  124. return "CREATE TABLE $tableName";
  125. }
  126. /**
  127. * Adds a "create table" query for the table $tableName with definition $tableDefinition to the internal list of queries.
  128. *
  129. * @param string $tableName
  130. * @param ezcDbSchemaTable $tableDefinition
  131. */
  132. protected function generateCreateTableSql( $tableName, ezcDbSchemaTable $tableDefinition )
  133. {
  134. $sql = $this->generateCreateTableSqlStatement( $tableName );
  135. $sql .= " (\n";
  136. // dump fields
  137. $fieldsSQL = array();
  138. foreach ( $tableDefinition->fields as $fieldName => $fieldDefinition )
  139. {
  140. $fieldsSQL[] = "\t" . $this->generateFieldSql( $fieldName, $fieldDefinition );
  141. }
  142. $sql .= join( ",\n", $fieldsSQL );
  143. $sql .= "\n)";
  144. $this->queries[] = $sql;
  145. // dump indexes
  146. foreach ( $tableDefinition->indexes as $indexName => $indexDefinition)
  147. {
  148. $fieldsSQL[] = $this->generateAddIndexSql( $tableName, $indexName, $indexDefinition );
  149. }
  150. }
  151. /**
  152. * Returns an appropriate default value for $type with $value.
  153. *
  154. * @param string $type
  155. * @param mixed $value
  156. * @return string
  157. */
  158. protected function generateDefault( $type, $value )
  159. {
  160. switch ( $type )
  161. {
  162. case 'boolean':
  163. return ( $value && $value != 'false' ) ? 'true' : 'false';
  164. case 'integer':
  165. return (int) $value;
  166. case 'float':
  167. case 'decimal':
  168. return (float) $value;
  169. case 'timestamp':
  170. return (int) $value;
  171. default:
  172. return "'$value'";
  173. }
  174. }
  175. /**
  176. * Generates queries to upgrade an existing database with the changes stored in $this->diffSchema.
  177. *
  178. * This method generates queries to migrate a database to a new version
  179. * with the changes that are stored in the $this->diffSchema property. It
  180. * will call different subfunctions for the different types of changes, and
  181. * those functions will add queries to the internal list of queries that is
  182. * stored in $this->queries.
  183. */
  184. protected function generateDiffSchemaAsSql()
  185. {
  186. foreach ( $this->diffSchema->changedTables as $tableName => $tableDiff )
  187. {
  188. $this->generateDiffSchemaTableAsSql( $tableName, $tableDiff );
  189. }
  190. foreach ( $this->diffSchema->newTables as $tableName => $tableDef )
  191. {
  192. $this->generateCreateTableSql( $tableName, $tableDef );
  193. }
  194. foreach ( $this->diffSchema->removedTables as $tableName => $dummy )
  195. {
  196. $this->generateDropTableSql( $tableName );
  197. }
  198. }
  199. /**
  200. * Generates queries to upgrade a the table $tableName with the differences in $tableDiff.
  201. *
  202. * This method generates queries to migrate a table to a new version
  203. * with the changes that are stored in the $tableDiff property. It
  204. * will call different subfunctions for the different types of changes, and
  205. * those functions will add queries to the internal list of queries that is
  206. * stored in $this->queries.
  207. *
  208. * @param string $tableName
  209. * @param ezcDbSchemaTableDiff $tableDiff
  210. */
  211. protected function generateDiffSchemaTableAsSql( $tableName, ezcDbSchemaTableDiff $tableDiff )
  212. {
  213. foreach ( $tableDiff->removedIndexes as $indexName => $isRemoved )
  214. {
  215. if ( $isRemoved )
  216. {
  217. $this->generateDropIndexSql( $tableName, $indexName );
  218. }
  219. }
  220. foreach ( $tableDiff->changedIndexes as $indexName => $indexDefinition )
  221. {
  222. $this->generateDropIndexSql( $tableName, $indexName );
  223. }
  224. foreach ( $tableDiff->removedFields as $fieldName => $isRemoved )
  225. {
  226. if ( $isRemoved )
  227. {
  228. $this->generateDropFieldSql( $tableName, $fieldName );
  229. }
  230. }
  231. foreach ( $tableDiff->changedFields as $fieldName => $fieldDefinition )
  232. {
  233. $this->generateChangeFieldSql( $tableName, $fieldName, $fieldDefinition );
  234. }
  235. foreach ( $tableDiff->addedFields as $fieldName => $fieldDefinition )
  236. {
  237. $this->generateAddFieldSql( $tableName, $fieldName, $fieldDefinition );
  238. }
  239. foreach ( $tableDiff->changedIndexes as $indexName => $indexDefinition )
  240. {
  241. $this->generateAddIndexSql( $tableName, $indexName, $indexDefinition );
  242. }
  243. foreach ( $tableDiff->addedIndexes as $indexName => $indexDefinition )
  244. {
  245. $this->generateAddIndexSql( $tableName, $indexName, $indexDefinition );
  246. }
  247. }
  248. /**
  249. * Adds a "drop table" query for the table $tableName to the internal list of queries.
  250. *
  251. * @param string $tableName
  252. */
  253. protected abstract function generateDropTableSql( $tableName );
  254. /**
  255. * Returns a column definition for $fieldName with definition $fieldDefinition.
  256. *
  257. * @param string $fieldName
  258. * @param ezcDbSchemaField $fieldDefinition
  259. * @return string
  260. */
  261. protected abstract function generateFieldSql( $fieldName, ezcDbSchemaField $fieldDefinition );
  262. /**
  263. * Adds a "alter table" query to add the field $fieldName to $tableName with the definition $fieldDefinition.
  264. *
  265. * @param string $tableName
  266. * @param string $fieldName
  267. * @param ezcDbSchemaField $fieldDefinition
  268. */
  269. protected abstract function generateAddFieldSql( $tableName, $fieldName, ezcDbSchemaField $fieldDefinition );
  270. /**
  271. * Adds a "alter table" query to change the field $fieldName to $tableName with the definition $fieldDefinition.
  272. *
  273. * @param string $tableName
  274. * @param string $fieldName
  275. * @param ezcDbSchemaField $fieldDefinition
  276. */
  277. protected abstract function generateChangeFieldSql( $tableName, $fieldName, ezcDbSchemaField $fieldDefinition );
  278. /**
  279. * Adds a "alter table" query to drop the field $fieldName from $tableName.
  280. *
  281. * @param string $tableName
  282. * @param string $fieldName
  283. */
  284. protected abstract function generateDropFieldSql( $tableName, $fieldName );
  285. /**
  286. * Adds a "alter table" query to add the index $indexName to the table $tableName with definition $indexDefinition to the internal list of queries
  287. *
  288. * @param string $tableName
  289. * @param string $indexName
  290. * @param ezcDbSchemaIndex $indexDefinition
  291. */
  292. protected abstract function generateAddIndexSql( $tableName, $indexName, ezcDbSchemaIndex $indexDefinition );
  293. /**
  294. * Adds a "alter table" query to remote the index $indexName from the table $tableName to the internal list of queries.
  295. *
  296. * @param string $tableName
  297. * @param string $indexName
  298. */
  299. protected abstract function generateDropIndexSql( $tableName, $indexName );
  300. }
  301. ?>