PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/propel/propel1/generator/lib/util/PropelMigrationManager.php

https://gitlab.com/Isaki/le331.fr
PHP | 369 lines | 250 code | 50 blank | 69 comment | 13 complexity | 31ce8f4887196b47a27c09d0322b346e 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__) . '/../model/Table.php';
  10. require_once dirname(__FILE__) . '/../model/Column.php';
  11. require_once dirname(__FILE__) . '/PropelSQLParser.php';
  12. require_once dirname(__FILE__) . '/../../../runtime/lib/Propel.php';
  13. /**
  14. * Service class for preparing and executing migrations
  15. *
  16. * @author François Zaninotto
  17. * @version $Revision$
  18. * @package propel.generator.util
  19. */
  20. class PropelMigrationManager
  21. {
  22. protected $connections;
  23. protected $pdoConnections = array();
  24. protected $migrationTable = 'propel_migration';
  25. protected $migrationDir;
  26. /**
  27. * Set the database connection settings
  28. *
  29. * @param array $connections
  30. */
  31. public function setConnections($connections)
  32. {
  33. $this->connections = $connections;
  34. }
  35. /**
  36. * Get the database connection settings
  37. *
  38. * @return array
  39. */
  40. public function getConnections()
  41. {
  42. return $this->connections;
  43. }
  44. public function getConnection($datasource)
  45. {
  46. if (!isset($this->connections[$datasource])) {
  47. throw new InvalidArgumentException(sprintf('Unknown datasource "%s"', $datasource));
  48. }
  49. return $this->connections[$datasource];
  50. }
  51. public function getPdoConnection($datasource)
  52. {
  53. if (!isset($this->pdoConnections[$datasource])) {
  54. $buildConnection = $this->getConnection($datasource);
  55. $buildConnection['dsn'] = str_replace("@DB@", $datasource, $buildConnection['dsn']);
  56. $this->pdoConnections[$datasource] = Propel::initConnection($buildConnection, $datasource);
  57. }
  58. return $this->pdoConnections[$datasource];
  59. }
  60. public function getPlatform($datasource)
  61. {
  62. $params = $this->getConnection($datasource);
  63. $adapter = $params['adapter'];
  64. $adapterClass = ucfirst($adapter) . 'Platform';
  65. require_once sprintf('%s/../platform/%s.php',
  66. dirname(__FILE__),
  67. $adapterClass
  68. );
  69. return new $adapterClass();
  70. }
  71. /**
  72. * Set the migration table name
  73. *
  74. * @param string $migrationTable
  75. */
  76. public function setMigrationTable($migrationTable)
  77. {
  78. $this->migrationTable = $migrationTable;
  79. }
  80. /**
  81. * get the migration table name
  82. *
  83. * @return string
  84. */
  85. public function getMigrationTable()
  86. {
  87. return $this->migrationTable;
  88. }
  89. /**
  90. * Set the path to the migration classes
  91. *
  92. * @param string $migrationDir
  93. */
  94. public function setMigrationDir($migrationDir)
  95. {
  96. $this->migrationDir = $migrationDir;
  97. }
  98. /**
  99. * Get the path to the migration classes
  100. *
  101. * @return string
  102. */
  103. public function getMigrationDir()
  104. {
  105. return $this->migrationDir;
  106. }
  107. public function getOldestDatabaseVersion()
  108. {
  109. if (!$connections = $this->getConnections()) {
  110. throw new Exception('You must define database connection settings in a buildtime-conf.xml file to use migrations');
  111. }
  112. $oldestMigrationTimestamp = null;
  113. $migrationTimestamps = array();
  114. foreach ($connections as $name => $params) {
  115. $pdo = $this->getPdoConnection($name);
  116. $sql = sprintf('SELECT version FROM %s', $this->getMigrationTable());
  117. try {
  118. $stmt = $pdo->prepare($sql);
  119. $stmt->execute();
  120. if ($migrationTimestamp = $stmt->fetchColumn()) {
  121. $migrationTimestamps[$name] = $migrationTimestamp;
  122. }
  123. } catch (PDOException $e) {
  124. $this->createMigrationTable($name);
  125. $oldestMigrationTimestamp = 0;
  126. }
  127. }
  128. if ($oldestMigrationTimestamp === null && $migrationTimestamps) {
  129. sort($migrationTimestamps);
  130. $oldestMigrationTimestamp = array_shift($migrationTimestamps);
  131. }
  132. return $oldestMigrationTimestamp;
  133. }
  134. public function migrationTableExists($datasource)
  135. {
  136. $pdo = $this->getPdoConnection($datasource);
  137. $sql = sprintf('SELECT version FROM %s', $this->getMigrationTable());
  138. $stmt = $pdo->prepare($sql);
  139. try {
  140. $stmt->execute();
  141. return true;
  142. } catch (PDOException $e) {
  143. return false;
  144. }
  145. }
  146. public function createMigrationTable($datasource)
  147. {
  148. $platform = $this->getPlatform($datasource);
  149. // modelize the table
  150. $database = new Database($datasource);
  151. $database->setPlatform($platform);
  152. $table = new Table($this->getMigrationTable());
  153. $database->addTable($table);
  154. $column = new Column('version');
  155. $column->getDomain()->copy($platform->getDomainForType('INTEGER'));
  156. $column->setDefaultValue(0);
  157. $table->addColumn($column);
  158. // insert the table into the database
  159. $statements = $platform->getAddTableDDL($table);
  160. $pdo = $this->getPdoConnection($datasource);
  161. $res = PropelSQLParser::executeString($statements, $pdo);
  162. if (!$res) {
  163. throw new Exception(sprintf('Unable to create migration table in datasource "%s"', $datasource));
  164. }
  165. }
  166. public function updateLatestMigrationTimestamp($datasource, $timestamp)
  167. {
  168. $platform = $this->getPlatform($datasource);
  169. $pdo = $this->getPdoConnection($datasource);
  170. $sql = sprintf('DELETE FROM %s', $this->getMigrationTable());
  171. $pdo->beginTransaction();
  172. $stmt = $pdo->prepare($sql);
  173. $stmt->execute();
  174. $sql = sprintf('INSERT INTO %s (%s) VALUES (?)',
  175. $this->getMigrationTable(),
  176. $platform->quoteIdentifier('version')
  177. );
  178. $stmt = $pdo->prepare($sql);
  179. $stmt->bindParam(1, $timestamp, PDO::PARAM_INT);
  180. $stmt->execute();
  181. $pdo->commit();
  182. }
  183. public function getMigrationTimestamps()
  184. {
  185. $path = $this->getMigrationDir();
  186. $migrationTimestamps = array();
  187. if (is_dir($path)) {
  188. $files = scandir($path);
  189. foreach ($files as $file) {
  190. if (preg_match('/^PropelMigration_(\d+)\.php$/', $file, $matches)) {
  191. $migrationTimestamps[] = (integer) $matches[1];
  192. }
  193. }
  194. }
  195. return $migrationTimestamps;
  196. }
  197. public function getValidMigrationTimestamps()
  198. {
  199. $oldestMigrationTimestamp = $this->getOldestDatabaseVersion();
  200. $migrationTimestamps = $this->getMigrationTimestamps();
  201. // removing already executed migrations
  202. foreach ($migrationTimestamps as $key => $timestamp) {
  203. if ($timestamp <= $oldestMigrationTimestamp) {
  204. unset($migrationTimestamps[$key]);
  205. }
  206. }
  207. sort($migrationTimestamps);
  208. return $migrationTimestamps;
  209. }
  210. public function hasPendingMigrations()
  211. {
  212. return array() !== $this->getValidMigrationTimestamps();
  213. }
  214. public function getAlreadyExecutedMigrationTimestamps()
  215. {
  216. $oldestMigrationTimestamp = $this->getOldestDatabaseVersion();
  217. $migrationTimestamps = $this->getMigrationTimestamps();
  218. // removing already executed migrations
  219. foreach ($migrationTimestamps as $key => $timestamp) {
  220. if ($timestamp > $oldestMigrationTimestamp) {
  221. unset($migrationTimestamps[$key]);
  222. }
  223. }
  224. sort($migrationTimestamps);
  225. return $migrationTimestamps;
  226. }
  227. public function getFirstUpMigrationTimestamp()
  228. {
  229. $validTimestamps = $this->getValidMigrationTimestamps();
  230. return array_shift($validTimestamps);
  231. }
  232. public function getFirstDownMigrationTimestamp()
  233. {
  234. return $this->getOldestDatabaseVersion();
  235. }
  236. public static function getMigrationClassName($timestamp)
  237. {
  238. return sprintf('PropelMigration_%d', $timestamp);
  239. }
  240. public function getMigrationObject($timestamp)
  241. {
  242. $className = $this->getMigrationClassName($timestamp);
  243. require_once sprintf('%s/%s.php',
  244. $this->getMigrationDir(),
  245. $className
  246. );
  247. return new $className();
  248. }
  249. public function getMigrationClassBody($migrationsUp, $migrationsDown, $timestamp)
  250. {
  251. $timeInWords = date('Y-m-d H:i:s', $timestamp);
  252. $migrationAuthor = ($author = $this->getUser()) ? 'by ' . $author : '';
  253. $migrationClassName = $this->getMigrationClassName($timestamp);
  254. $migrationUpString = var_export($migrationsUp, true);
  255. $migrationDownString = var_export($migrationsDown, true);
  256. $migrationClassBody = <<<EOP
  257. <?php
  258. /**
  259. * Data object containing the SQL and PHP code to migrate the database
  260. * up to version $timestamp.
  261. * Generated on $timeInWords $migrationAuthor
  262. */
  263. class $migrationClassName
  264. {
  265. public function preUp(\$manager)
  266. {
  267. // add the pre-migration code here
  268. }
  269. public function postUp(\$manager)
  270. {
  271. // add the post-migration code here
  272. }
  273. public function preDown(\$manager)
  274. {
  275. // add the pre-migration code here
  276. }
  277. public function postDown(\$manager)
  278. {
  279. // add the post-migration code here
  280. }
  281. /**
  282. * Get the SQL statements for the Up migration
  283. *
  284. * @return array list of the SQL strings to execute for the Up migration
  285. * the keys being the datasources
  286. */
  287. public function getUpSQL()
  288. {
  289. return $migrationUpString;
  290. }
  291. /**
  292. * Get the SQL statements for the Down migration
  293. *
  294. * @return array list of the SQL strings to execute for the Down migration
  295. * the keys being the datasources
  296. */
  297. public function getDownSQL()
  298. {
  299. return $migrationDownString;
  300. }
  301. }
  302. EOP;
  303. return $migrationClassBody;
  304. }
  305. public static function getMigrationFileName($timestamp)
  306. {
  307. return sprintf('%s.php', self::getMigrationClassName($timestamp));
  308. }
  309. public static function getUser()
  310. {
  311. if (function_exists('posix_getuid')) {
  312. $currentUser = posix_getpwuid(posix_getuid());
  313. if (isset($currentUser['name'])) {
  314. return $currentUser['name'];
  315. }
  316. }
  317. return '';
  318. }
  319. }