You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

161 lines
5.4 KiB

  1. <?php
  2. namespace Kuxin\Console;
  3. use Kuxin\Config;
  4. use Kuxin\Console;
  5. use Kuxin\DI;
  6. use Kuxin\Loader;
  7. class Migrate extends Console
  8. {
  9. protected $path = KX_ROOT . '/app/migrate/';
  10. /**
  11. * @var \Kuxin\Db\Mysql
  12. */
  13. protected $db;
  14. public function init()
  15. {
  16. $this->db = DI::DB();
  17. }
  18. public function up()
  19. {
  20. $silent = isset($this->params['-s']);
  21. if (false === $records = $this->db->fetchAll("select * from migrate")) {
  22. $res = $this->db->execute('CREATE TABLE `migrate` ( `name` varchar(180) NOT NULL,`time` int(11) DEFAULT NULL,PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;');
  23. if ($res) {
  24. $records = [];
  25. } else {
  26. return $this->info('初始化失败');
  27. }
  28. }
  29. $execed = array_column($records, 'name');
  30. $noExec = [];
  31. foreach (scandir($this->path) as $file) {
  32. if ($file == '.' || $file == '..') {
  33. continue;
  34. }
  35. $name = substr($file, 0, -4);
  36. if (!in_array($name, $execed) && is_file($this->path . '/' . $name . '.php')) {
  37. $noExec[] = $name;
  38. }
  39. }
  40. if ($noExec) {
  41. $silent || $this->info('您将执行以下migrate');
  42. $silent || $this->info(PHP_EOL . implode(PHP_EOL, $noExec) . PHP_EOL);
  43. if (Config::get('app.env') == 'production' && !$silent) {
  44. $input = $this->prompt('请输入 yes 来确认执行');
  45. } else {
  46. $input = 'yes';
  47. }
  48. if ($input == 'yes') {
  49. try {
  50. foreach ($noExec as $name) {
  51. $class = Loader::instance('App\\Migrate\\' . $name);
  52. if (is_callable([$class, 'up'])) {
  53. $class->up();
  54. }
  55. $this->db->execute("INSERT INTO `migrate` (`name`, `time`) VALUES ('{$name}', {$_SERVER['REQUEST_TIME']});");
  56. }
  57. $silent || $this->info(PHP_EOL . '本次命令执行成功', 'success');
  58. } catch (\Exception $e) {
  59. $this->info(PHP_EOL . "执行失败: 文件[{$name}] " . $e->getMessage(), 'error');
  60. }
  61. } else {
  62. $silent || $this->info('您取消了本次命令执行', 'warning');
  63. }
  64. } else {
  65. $silent || $this->info('没有要执行的migrate', 'warning');
  66. }
  67. }
  68. public function down()
  69. {
  70. $silent = isset($this->params['-s']);
  71. $maxRow = $this->db->fetch('select time from migrate order by time desc limit 1');
  72. if ($maxRow) {
  73. $maxTime = $maxRow['time'];
  74. $records = $this->db->fetchAll("select name from migrate where time={$maxTime}");
  75. $names = array_column($records, 'name');
  76. $silent || $this->info('您将回滚以下migrate');
  77. $silent || $this->info(PHP_EOL . implode(PHP_EOL, $names) . PHP_EOL);
  78. if (Config::get('app.env') == 'production' && !$silent) {
  79. $input = $this->prompt('请输入 yes 来确认执行');
  80. } else {
  81. $input = 'yes';
  82. }
  83. if ($input == 'yes') {
  84. try {
  85. foreach ($names as $name) {
  86. $class = Loader::instance('App\\Migrate\\' . $name);
  87. if (is_callable([$class, 'down'])) {
  88. $class->down();
  89. }
  90. $this->db->execute("DELETE FROM `migrate` where name='{$name}';");
  91. }
  92. $silent || $this->info(PHP_EOL . '本次命令执行成功', 'success');
  93. } catch (\Exception $e) {
  94. $this->info(PHP_EOL . "执行失败: 文件[{$name}] " . $e->getMessage(), 'error');
  95. }
  96. } else {
  97. $silent || $this->info('您取消了本次命令执行', 'warning');
  98. }
  99. } else {
  100. $silent || $this->info('没有要执行的migrate', 'warning');
  101. }
  102. }
  103. public function create()
  104. {
  105. $tableName = str_replace(['create_', 'insert_', 'alter_', 'delete_'], '', trim($this->params['argv']['2']));
  106. if ($tableName == '') {
  107. return $this->info('please input migrate name', 'error');
  108. }
  109. $name = str_replace([' ', ':', '/', '\\'], '_', trim($this->params['argv']['2']));
  110. $filename = 'kx_' . date('YmdHis_') . $name;
  111. $file = $this->path . $filename . '.php';
  112. $classname = ucfirst($filename);
  113. $content = <<<PHP
  114. <?php
  115. namespace App\Migrate;
  116. use Kuxin\Db\Migrate;
  117. class $classname extends Migrate
  118. {
  119. /**
  120. * 执行修改
  121. * @throws \Exception
  122. */
  123. public function up()
  124. {
  125. \$this->create('{$tableName}',function(){
  126. \$this->addComand("`id` int(10) unsigned NOT NULL AUTO_INCREMENT");
  127. \$this->addComand("PRIMARY KEY (`id`)");
  128. });
  129. }
  130. /**
  131. * 回滚修改
  132. * @throws \Exception
  133. */
  134. public function down()
  135. {
  136. \$this->drop('{$tableName}');
  137. }
  138. }
  139. PHP;
  140. if (!is_dir(dirname($file))) {
  141. mkdir(dirname($file), 0755, true);
  142. }
  143. file_put_contents($file, $content);
  144. $this->info('创建migrate文件 [ ' . $filename . ' ] 成功', 'success');
  145. }
  146. }