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

/yii/framework/db/CDbMigration.php

https://github.com/joshuaswarren/weatherhub
PHP | 387 lines | 177 code | 23 blank | 187 comment | 4 complexity | 4b447bc004356addf3dd8391d587fe7b MD5 | raw file
  1. <?php
  2. /**
  3. * CMysqlSchema class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CDbMigration is the base class for representing a database migration.
  12. *
  13. * CDbMigration is designed to be used together with the "yiic migrate" command.
  14. *
  15. * Each child class of CDbMigration represents an individual database migration which
  16. * is identified by the child class name.
  17. *
  18. * Within each migration, the {@link up} method contains the logic for "upgrading"
  19. * the database used in an application; while the {@link down} method contains "downgrading"
  20. * logic. The "yiic migrate" command manages all available migrations in an application.
  21. *
  22. * CDbMigration provides a set of convenient methods for manipulating database data and schema.
  23. * For example, the {@link insert} method can be used to easily insert a row of data into
  24. * a database table; the {@link createTable} method can be used to create a database table.
  25. * Compared with the same methods in {@link CDbCommand}, these methods will display extra
  26. * information showing the method parameters and execution time, which may be useful when
  27. * applying migrations.
  28. *
  29. * @author Qiang Xue <qiang.xue@gmail.com>
  30. * @version $Id: CDbMigration.php 3218 2011-05-13 00:06:44Z alexander.makarow $
  31. * @package system.db
  32. * @since 1.1.6
  33. */
  34. abstract class CDbMigration extends CComponent
  35. {
  36. private $_db;
  37. /**
  38. * This method contains the logic to be executed when applying this migration.
  39. * Child classes may implement this method to provide actual migration logic.
  40. * @return boolean
  41. */
  42. public function up()
  43. {
  44. $transaction=$this->getDbConnection()->beginTransaction();
  45. try
  46. {
  47. if($this->safeUp()===false)
  48. {
  49. $transaction->rollBack();
  50. return false;
  51. }
  52. $transaction->commit();
  53. }
  54. catch(Exception $e)
  55. {
  56. echo "Exception: ".$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
  57. echo $e->getTraceAsString()."\n";
  58. $transaction->rollBack();
  59. return false;
  60. }
  61. }
  62. /**
  63. * This method contains the logic to be executed when removing this migration.
  64. * The default implementation throws an exception indicating the migration cannot be removed.
  65. * Child classes may override this method if the corresponding migrations can be removed.
  66. * @return boolean
  67. */
  68. public function down()
  69. {
  70. $transaction=$this->getDbConnection()->beginTransaction();
  71. try
  72. {
  73. if($this->safeDown()===false)
  74. {
  75. $transaction->rollBack();
  76. return false;
  77. }
  78. $transaction->commit();
  79. }
  80. catch(Exception $e)
  81. {
  82. echo "Exception: ".$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
  83. echo $e->getTraceAsString()."\n";
  84. $transaction->rollBack();
  85. return false;
  86. }
  87. }
  88. /**
  89. * This method contains the logic to be executed when applying this migration.
  90. * This method differs from {@link up} in that the DB logic implemented here will
  91. * be enclosed within a DB transaction.
  92. * Child classes may implement this method instead of {@link up} if the DB logic
  93. * needs to be within a transaction.
  94. * @return boolean
  95. * @since 1.1.7
  96. */
  97. public function safeUp()
  98. {
  99. }
  100. /**
  101. * This method contains the logic to be executed when removing this migration.
  102. * This method differs from {@link down} in that the DB logic implemented here will
  103. * be enclosed within a DB transaction.
  104. * Child classes may implement this method instead of {@link up} if the DB logic
  105. * needs to be within a transaction.
  106. * @return boolean
  107. * @since 1.1.7
  108. */
  109. public function safeDown()
  110. {
  111. }
  112. /**
  113. * Returns the currently active database connection.
  114. * By default, the 'db' application component will be returned and activated.
  115. * You can call {@link setDbConnection} to switch to a different database connection.
  116. * Methods such as {@link insert}, {@link createTable} will use this database connection
  117. * to perform DB queries.
  118. * @return CDbConnection the currently active database connection
  119. */
  120. public function getDbConnection()
  121. {
  122. if($this->_db===null)
  123. {
  124. $this->_db=Yii::app()->getComponent('db');
  125. if(!$this->_db instanceof CDbConnection)
  126. throw new CException(Yii::t('yii', 'The "db" application component must be configured to be a CDbConnection object.'));
  127. }
  128. return $this->_db;
  129. }
  130. /**
  131. * Sets the currently active database connection.
  132. * The database connection will be used by the methods such as {@link insert}, {@link createTable}.
  133. * @param CDbConnection $db the database connection component
  134. */
  135. public function setDbConnection($db)
  136. {
  137. $this->_db=$db;
  138. }
  139. /**
  140. * Executes a SQL statement.
  141. * This method executes the specified SQL statement using {@link dbConnection}.
  142. * @param string $sql the SQL statement to be executed
  143. * @param array $params input parameters (name=>value) for the SQL execution. See {@link CDbCommand::execute} for more details.
  144. * @since 1.1.7
  145. */
  146. public function execute($sql, $params=array())
  147. {
  148. echo " > execute SQL: $sql ...";
  149. $time=microtime(true);
  150. $this->getDbConnection()->createCommand($sql)->execute($params);
  151. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  152. }
  153. /**
  154. * Creates and executes an INSERT SQL statement.
  155. * The method will properly escape the column names, and bind the values to be inserted.
  156. * @param string $table the table that new rows will be inserted into.
  157. * @param array $columns the column data (name=>value) to be inserted into the table.
  158. */
  159. public function insert($table, $columns)
  160. {
  161. echo " > insert into $table ...";
  162. $time=microtime(true);
  163. $this->getDbConnection()->createCommand()->insert($table, $columns);
  164. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  165. }
  166. /**
  167. * Creates and executes an UPDATE SQL statement.
  168. * The method will properly escape the column names and bind the values to be updated.
  169. * @param string $table the table to be updated.
  170. * @param array $columns the column data (name=>value) to be updated.
  171. * @param mixed $conditions the conditions that will be put in the WHERE part. Please
  172. * refer to {@link CDbCommand::where} on how to specify conditions.
  173. * @param array $params the parameters to be bound to the query.
  174. */
  175. public function update($table, $columns, $conditions='', $params=array())
  176. {
  177. echo " > update $table ...";
  178. $time=microtime(true);
  179. $this->getDbConnection()->createCommand()->update($table, $columns, $conditions, $params);
  180. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  181. }
  182. /**
  183. * Creates and executes a DELETE SQL statement.
  184. * @param string $table the table where the data will be deleted from.
  185. * @param mixed $conditions the conditions that will be put in the WHERE part. Please
  186. * refer to {@link CDbCommand::where} on how to specify conditions.
  187. * @param array $params the parameters to be bound to the query.
  188. */
  189. public function delete($table, $conditions='', $params=array())
  190. {
  191. echo " > delete from $table ...";
  192. $time=microtime(true);
  193. $this->getDbConnection()->createCommand()->delete($table, $conditions, $params);
  194. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  195. }
  196. /**
  197. * Builds and executes a SQL statement for creating a new DB table.
  198. *
  199. * The columns in the new table should be specified as name-definition pairs (e.g. 'name'=>'string'),
  200. * where name stands for a column name which will be properly quoted by the method, and definition
  201. * stands for the column type which can contain an abstract DB type.
  202. * The {@link getColumnType} method will be invoked to convert any abstract type into a physical one.
  203. *
  204. * If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly
  205. * inserted into the generated SQL.
  206. *
  207. * @param string $table the name of the table to be created. The name will be properly quoted by the method.
  208. * @param array $columns the columns (name=>definition) in the new table.
  209. * @param string $options additional SQL fragment that will be appended to the generated SQL.
  210. */
  211. public function createTable($table, $columns, $options=null)
  212. {
  213. echo " > create table $table ...";
  214. $time=microtime(true);
  215. $this->getDbConnection()->createCommand()->createTable($table, $columns, $options);
  216. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  217. }
  218. /**
  219. * Builds and executes a SQL statement for renaming a DB table.
  220. * @param string $table the table to be renamed. The name will be properly quoted by the method.
  221. * @param string $newName the new table name. The name will be properly quoted by the method.
  222. */
  223. public function renameTable($table, $newName)
  224. {
  225. echo " > rename table $table to $newName ...";
  226. $time=microtime(true);
  227. $this->getDbConnection()->createCommand()->renameTable($table, $newName);
  228. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  229. }
  230. /**
  231. * Builds and executes a SQL statement for dropping a DB table.
  232. * @param string $table the table to be dropped. The name will be properly quoted by the method.
  233. */
  234. public function dropTable($table)
  235. {
  236. echo " > drop table $table ...";
  237. $time=microtime(true);
  238. $this->getDbConnection()->createCommand()->dropTable($table);
  239. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  240. }
  241. /**
  242. * Builds and executes a SQL statement for truncating a DB table.
  243. * @param string $table the table to be truncated. The name will be properly quoted by the method.
  244. */
  245. public function truncateTable($table)
  246. {
  247. echo " > truncate table $table ...";
  248. $time=microtime(true);
  249. $this->getDbConnection()->createCommand()->truncateTable($table);
  250. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  251. }
  252. /**
  253. * Builds and executes a SQL statement for adding a new DB column.
  254. * @param string $table the table that the new column will be added to. The table name will be properly quoted by the method.
  255. * @param string $column the name of the new column. The name will be properly quoted by the method.
  256. * @param string $type the column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
  257. * into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
  258. * For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
  259. */
  260. public function addColumn($table, $column, $type)
  261. {
  262. echo " > add column $column $type to table $table ...";
  263. $time=microtime(true);
  264. $this->getDbConnection()->createCommand()->addColumn($table, $column, $type);
  265. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  266. }
  267. /**
  268. * Builds and executes a SQL statement for dropping a DB column.
  269. * @param string $table the table whose column is to be dropped. The name will be properly quoted by the method.
  270. * @param string $column the name of the column to be dropped. The name will be properly quoted by the method.
  271. */
  272. public function dropColumn($table, $column)
  273. {
  274. echo " > drop column $column from table $table ...";
  275. $time=microtime(true);
  276. $this->getDbConnection()->createCommand()->dropColumn($table, $column);
  277. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  278. }
  279. /**
  280. * Builds and executes a SQL statement for renaming a column.
  281. * @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
  282. * @param string $name the old name of the column. The name will be properly quoted by the method.
  283. * @param string $newName the new name of the column. The name will be properly quoted by the method.
  284. */
  285. public function renameColumn($table, $name, $newName)
  286. {
  287. echo " > rename column $name in table $table to $newName ...";
  288. $time=microtime(true);
  289. $this->getDbConnection()->createCommand()->renameColumn($table, $name, $newName);
  290. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  291. }
  292. /**
  293. * Builds and executes a SQL statement for changing the definition of a column.
  294. * @param string $table the table whose column is to be changed. The table name will be properly quoted by the method.
  295. * @param string $column the name of the column to be changed. The name will be properly quoted by the method.
  296. * @param string $type the new column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
  297. * into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
  298. * For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
  299. */
  300. public function alterColumn($table, $column, $type)
  301. {
  302. echo " > alter column $column in table $table to $type ...";
  303. $time=microtime(true);
  304. $this->getDbConnection()->createCommand()->alterColumn($table, $column, $type);
  305. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  306. }
  307. /**
  308. * Builds a SQL statement for adding a foreign key constraint to an existing table.
  309. * The method will properly quote the table and column names.
  310. * @param string $name the name of the foreign key constraint.
  311. * @param string $table the table that the foreign key constraint will be added to.
  312. * @param string $columns the name of the column to that the constraint will be added on. If there are multiple columns, separate them with commas.
  313. * @param string $refTable the table that the foreign key references to.
  314. * @param string $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas.
  315. * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
  316. * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
  317. */
  318. public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete=null, $update=null)
  319. {
  320. echo " > add foreign key $name: $table ($columns) references $refTable ($refColumns) ...";
  321. $time=microtime(true);
  322. $this->getDbConnection()->createCommand()->addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete, $update);
  323. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  324. }
  325. /**
  326. * Builds a SQL statement for dropping a foreign key constraint.
  327. * @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
  328. * @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
  329. */
  330. public function dropForeignKey($name, $table)
  331. {
  332. echo " > drop foreign key $name from table $table ...";
  333. $time=microtime(true);
  334. $this->getDbConnection()->createCommand()->dropForeignKey($name, $table);
  335. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  336. }
  337. /**
  338. * Builds and executes a SQL statement for creating a new index.
  339. * @param string $name the name of the index. The name will be properly quoted by the method.
  340. * @param string $table the table that the new index will be created for. The table name will be properly quoted by the method.
  341. * @param string $column the column(s) that should be included in the index. If there are multiple columns, please separate them
  342. * by commas. The column names will be properly quoted by the method.
  343. * @param boolean $unique whether to add UNIQUE constraint on the created index.
  344. */
  345. public function createIndex($name, $table, $column, $unique=false)
  346. {
  347. echo " > create".($unique ? ' unique':'')." index $name on $table ($column) ...";
  348. $time=microtime(true);
  349. $this->getDbConnection()->createCommand()->createIndex($name, $table, $column, $unique);
  350. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  351. }
  352. /**
  353. * Builds and executes a SQL statement for dropping an index.
  354. * @param string $name the name of the index to be dropped. The name will be properly quoted by the method.
  355. * @param string $table the table whose index is to be dropped. The name will be properly quoted by the method.
  356. */
  357. public function dropIndex($name, $table)
  358. {
  359. echo " > drop index $name ...";
  360. $time=microtime(true);
  361. $this->getDbConnection()->createCommand()->dropIndex($name, $table);
  362. echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
  363. }
  364. }