├── AppUtility.php ├── Module.php ├── README.md ├── assets └── MigrationAsset.php ├── console └── MigrateController.php ├── controllers └── DefaultController.php ├── models └── MigrationUtility.php ├── static ├── migration.css └── migration.js └── views ├── default └── index.php └── migration.php /AppUtility.php: -------------------------------------------------------------------------------- 1 | array = self::objectToArray($array); 27 | switch (strtolower($databaseType)) { 28 | case "mssql": 29 | self::runMsSql(); 30 | break; 31 | case "mysql": 32 | self::runMySql(); 33 | break; 34 | case "sqlite": 35 | self::runSqlite(); 36 | break; 37 | case "pgsql": 38 | self::runPgSql(); 39 | break; 40 | } 41 | } 42 | 43 | private function objectToArray($array_in) 44 | { 45 | $array = array(); 46 | if (is_object($array_in)) { 47 | return self::objectToArray(get_object_vars($array_in)); 48 | } else { 49 | if (is_array($array_in)) { 50 | foreach ($array_in as $key => $value) { 51 | if (is_object($value)) { 52 | $array[$key] = self::objectToArray($value); 53 | } elseif (is_array($value)) { 54 | $array[$key] = self::objectToArray($value); 55 | } else { 56 | $array[$key] = $value; 57 | } 58 | } 59 | } 60 | } 61 | 62 | return $array; 63 | } 64 | 65 | private function runMsSql() 66 | { 67 | if (isset($this->array['dbType'])) 68 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . strtoupper($this->array['dbType']) . ""; 69 | if (isset($this->array['autoIncrement'])) 70 | $this->string .= ($this->array['autoIncrement']) ? ' IDENTITY' : ''; 71 | if (isset($this->array['allowNull'])) 72 | $this->string .= ($this->array['allowNull']) ? ' NULL' : ' NOT NULL'; 73 | if (isset($this->array['defaultValue'])) 74 | $this->string .= (empty($this->array['defaultValue'])) ? '' : " DEFAULT \'{$this->array['defaultValue']}\'"; 75 | 76 | } 77 | 78 | private function runMySql() 79 | { 80 | if (isset($this->array['dbType'])) { 81 | if (strpos($this->array['dbType'], 'enum') !== FALSE) { 82 | $this->array['dbType'] = str_replace('enum', 'ENUM', $this->array['dbType']); 83 | $this->array['dbType'] = str_replace("'", "\\'", $this->array['dbType']); 84 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . $this->array['dbType'] . ""; 85 | } elseif (strpos($this->array['dbType'], 'set') !== FALSE) { 86 | $this->array['dbType'] = str_replace('set', 'SET', $this->array['dbType']); 87 | $this->array['dbType'] = str_replace("'", "\\'", $this->array['dbType']); 88 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . $this->array['dbType'] . ""; 89 | } else { 90 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . strtoupper($this->array['dbType']) . ""; 91 | } 92 | } 93 | if (isset($this->array['allowNull'])) 94 | $this->string .= ($this->array['allowNull']) ? ' NULL' : ' NOT NULL'; 95 | if (isset($this->array['autoIncrement'])) 96 | $this->string .= ($this->array['autoIncrement']) ? ' AUTO_INCREMENT' : ''; 97 | if (isset($this->array['defaultValue'])) 98 | if (!is_array($this->array['defaultValue'])) { 99 | //0 is int 100 | if(is_int($this->array['defaultValue'])||!empty($this->array['defaultValue'])) 101 | { 102 | $this->string .= " DEFAULT \'{$this->array['defaultValue']}\'"; 103 | } 104 | } else { 105 | $this->string .= (empty($this->array['defaultValue'])) ? '' : " DEFAULT " . $this->array['defaultValue']['expression'] . " "; 106 | } 107 | } 108 | 109 | private function runSqlite() 110 | { 111 | if (isset($this->array['dbType'])) 112 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . strtoupper($this->array['dbType']) . ""; 113 | if (isset($this->array['allowNull'])) 114 | $this->string .= ($this->array['allowNull']) ? ' NULL' : ' NOT NULL'; 115 | if (isset($this->array['autoIncrement'])) 116 | $this->string .= ($this->array['autoIncrement']) ? ' AUTOINCREMENT' : ''; 117 | if (isset($this->array['defaultValue'])) 118 | $this->string .= (empty($this->array['defaultValue'])) ? '' : " DEFAULT \'{$this->array['defaultValue']}\'"; 119 | 120 | } 121 | 122 | private function runPgSql() 123 | { 124 | if (isset($this->array['dbType'])) 125 | $this->string .= $this->Tab . "'{$this->array['name']}' => '" . strtoupper($this->array['dbType']) . ""; 126 | if (isset($this->array['autoIncrement'])) 127 | $this->string .= ($this->array['autoIncrement']) ? ' SERIAL' : ''; 128 | if (isset($this->array['allowNull'])) 129 | $this->string .= ($this->array['allowNull']) ? ' NULL' : ' NOT NULL'; 130 | if (isset($this->array['defaultValue'])) 131 | $this->string .= (empty($this->array['defaultValue'])) ? '' : " DEFAULT \'{$this->array['defaultValue']}\'"; 132 | 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'migration' => [ 10 | 'class' => 'migration\Module', 11 | ] 12 | ], 13 | 'aliases' => [ 14 | '@migration' => '@backend/modules/migration', 15 | ], 16 | ``` 17 | 18 | 3.在你的后台访问 http://yourdomain/migration 19 | 20 | 演示地址: http://www.51siyuan.cn/admin/migration 21 | 22 | 演示账号 `demo` 密码 `111111` 23 | 24 | 25 | 26 | 命令行使用方法 27 | 28 | 1.在`console/config/main.php` 添加如下配置 29 | ``` 30 | 'controllerMap' => [ 31 | 'migrate' => [ 32 | 'class' => 'backend\modules\migration\console\MigrateController', 33 | 'useTablePrefix' => true, 34 | 'migrationPath' => '@console/migrations', 35 | ], 36 | ], 37 | ``` 38 | 39 | 2.`php yii migrate/dump` 40 | 41 | o了 42 | -------------------------------------------------------------------------------- /assets/MigrationAsset.php: -------------------------------------------------------------------------------- 1 | array_keys(MigrationUtility::getTableNames()), 34 | 'tableDatas' => array_keys(MigrationUtility::getTableNames()), 35 | 'migrationPath' => $this->migrationPath 36 | ]; 37 | if ($model->load($data, '')) { 38 | 39 | if (!empty($model->tableSchemas)) { 40 | list ($up, $down) = $this->generalTableSchemas($model->tableSchemas, $model->tableOption); 41 | $upStr->outputStringArray = array_merge($upStr->outputStringArray, $up->outputStringArray); 42 | $downStr->outputStringArray = array_merge($downStr->outputStringArray, $down->outputStringArray); 43 | } 44 | 45 | if (! empty($model->tableDatas)) { 46 | list ($up, $down) = $this->generalTableDatas($model->tableDatas); 47 | $upStr->outputStringArray = array_merge($upStr->outputStringArray, $up->outputStringArray); 48 | $downStr->outputStringArray = array_merge($downStr->outputStringArray, $down->outputStringArray); 49 | } 50 | 51 | $path = Yii::getAlias($model->migrationPath); 52 | if (!is_dir($path)) { 53 | FileHelper::createDirectory($path); 54 | } 55 | 56 | $name = 'm' . gmdate('ymd_His') . '_' . $model->migrationName; 57 | $file = $path . DIRECTORY_SEPARATOR . $name . '.php'; 58 | 59 | $content = $this->renderFile(Yii::getAlias("@backend/modules/migration/views/migration.php"), [ 60 | 'className' => $name, 61 | 'up' => $upStr->output(), 62 | 'down' => $downStr->output() 63 | ]); 64 | file_put_contents($file, $content); 65 | $this->stdout('成功生成迁移文件 ' . $file, Console::FG_GREEN); 66 | } 67 | } 68 | 69 | public function getTableName($name) 70 | { 71 | $prefix = \Yii::$app->db->tablePrefix; 72 | 73 | return str_replace($prefix, '', $name); 74 | } 75 | 76 | public function generalTableSchemas($tables, $tableOption) 77 | { 78 | $initialTabLevel = 0; 79 | $upStr = new OutputString([ 80 | 'tabLevel' => $initialTabLevel 81 | ]); 82 | 83 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 84 | $upStr->addStr(' '); 85 | foreach ($tables as $table) { 86 | $upStr->tabLevel = $initialTabLevel; 87 | 88 | $tablePrepared = $this->getTableName($table); 89 | 90 | // 添加表结构 91 | $upStr->addStr('$this->createTable(\'{{%' . $tablePrepared . '}}\', ['); 92 | $upStr->tabLevel ++; 93 | $tableSchema = \Yii::$app->db->getTableSchema($table); 94 | 95 | foreach ($tableSchema->columns as $column) { 96 | $appUtility = new AppUtility($column); 97 | $upStr->addStr($appUtility->string . "',"); 98 | } 99 | if (! empty($tableSchema->primaryKey)) { 100 | $upStr->addStr("'PRIMARY KEY (`" . implode("`,`", $tableSchema->primaryKey) . "`)'"); 101 | } 102 | 103 | $upStr->tabLevel --; 104 | $upStr->addStr('], "' . $tableOption . '");'); 105 | 106 | 107 | // 添加索引 108 | $tableIndexes = Yii::$app->db->createCommand('SHOW INDEX FROM `' . $table . '`')->queryAll(); 109 | $indexs = []; 110 | foreach ($tableIndexes as $item) { 111 | if ($item['Key_name'] == 'PRIMARY') { 112 | continue; 113 | } 114 | if (! isset($indexs[$item["Key_name"]])) { 115 | $indexs[$item["Key_name"]] = []; 116 | $indexs[$item["Key_name"]]["unique"] = ($item['Non_unique']) ? 0 : 1; 117 | } 118 | $indexs[$item["Key_name"]]["columns"][] = $item['Column_name']; 119 | } 120 | 121 | if (! empty($indexs)) { 122 | $upStr->addStr(' '); 123 | } 124 | 125 | foreach ($indexs as $index => $item) { 126 | $str = '$this->createIndex(\'' . $index . '\',\'{{%' . $tablePrepared . '}}\',\'' . implode(', ', $item['columns']) . '\',' . $item['unique'] . ');'; 127 | $upStr->addStr($str); 128 | } 129 | 130 | $upStr->addStr(' '); 131 | } 132 | 133 | //添加外键 134 | $sql = "SELECT tb1.CONSTRAINT_NAME, tb1.TABLE_NAME, tb1.COLUMN_NAME, 135 | tb1.REFERENCED_TABLE_NAME, tb1.REFERENCED_COLUMN_NAME, tb2.MATCH_OPTION, 136 | 137 | tb2.UPDATE_RULE, tb2.DELETE_RULE 138 | 139 | FROM information_schema.KEY_COLUMN_USAGE AS tb1 140 | INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS AS tb2 ON 141 | tb1.CONSTRAINT_NAME = tb2.CONSTRAINT_NAME AND tb1.CONSTRAINT_SCHEMA = tb2.CONSTRAINT_SCHEMA 142 | WHERE TABLE_SCHEMA = DATABASE() 143 | AND REFERENCED_TABLE_SCHEMA = DATABASE() AND REFERENCED_COLUMN_NAME IS NOT NULL"; 144 | $foreignKeys = Yii::$app->db->createCommand($sql)->queryAll(); 145 | foreach ($foreignKeys as $fk) 146 | { 147 | $str = '$this->addForeignKey('; 148 | $str .= '\'' . $fk['CONSTRAINT_NAME'] . '\', '; 149 | $str .= '\'{{%' . $this->getTableName($fk['TABLE_NAME']) . '}}\', '; 150 | $str .= '\'' . $fk['COLUMN_NAME'] . '\', '; 151 | $str .= '\'{{%' . $this->getTableName($fk['REFERENCED_TABLE_NAME']) . '}}\', '; 152 | $str .= '\'' . $fk['REFERENCED_COLUMN_NAME'] . '\', '; 153 | $str .= '\'' . $fk['DELETE_RULE'] . '\', '; 154 | $str .= '\'' . $fk['UPDATE_RULE'] . '\' '; 155 | $str .= ');'; 156 | $upStr->addStr($str); 157 | } 158 | 159 | 160 | $upStr->addStr(' '); 161 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 162 | 163 | $downStr = new OutputString(); 164 | /* DROP TABLE */ 165 | $downStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 166 | foreach ($tables as $table) { 167 | if (! empty($table)) { 168 | $downStr->addStr('$this->dropTable(\'{{%' . $tablePrepared . '}}\');'); 169 | } 170 | } 171 | $downStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 172 | 173 | return [ 174 | $upStr, 175 | $downStr 176 | ]; 177 | } 178 | 179 | public function generalTableDatas($tables) 180 | { 181 | $initialTabLevel = 0; 182 | $upStr = new OutputString([ 183 | 'tabLevel' => $initialTabLevel 184 | ]); 185 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 186 | $upStr->addStr(' '); 187 | foreach ($tables as $table) { 188 | 189 | $tablePrepared = $this->getTableName($table); 190 | 191 | $upStr->addStr('/* Table ' . $table . ' */'); 192 | $tableSchema = \Yii::$app->db->getTableSchema($table); 193 | $data = Yii::$app->db->createCommand('SELECT * FROM `' . $table . '`')->queryAll(); 194 | $out = '$this->batchInsert(\'{{%' . $tablePrepared . '}}\',['; 195 | foreach ($tableSchema->columns as $column) { 196 | $out .= "'" . $column->name . "',"; 197 | } 198 | $out = rtrim($out, ',') . '],['; 199 | foreach ($data as $row) { 200 | $out .= '['; 201 | foreach ($row as $field) { 202 | if ($field === null) { 203 | $out .= "null,"; 204 | } else { 205 | $out .= "'" . addcslashes($field, "'") . "',"; 206 | } 207 | } 208 | $out = rtrim($out, ',') . "],\n"; 209 | } 210 | $out = rtrim($out, ',') . ']);'; 211 | $upStr->addStr($out); 212 | $upStr->addStr(' '); 213 | } 214 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 215 | $downStr = new OutputString(); 216 | return [ 217 | $upStr, 218 | $downStr 219 | ]; 220 | } 221 | } 222 | 223 | /** 224 | * Class OutputString 225 | * 226 | * @author Nils Lindentals 227 | * 228 | * @package c006\utility\migration\controllers 229 | */ 230 | class OutputString extends Object 231 | { 232 | 233 | /** 234 | * 235 | * @var string 236 | */ 237 | public $nw = "\n"; 238 | 239 | /** 240 | * 241 | * @var string 242 | */ 243 | public $tab = "\t"; 244 | 245 | /** 246 | * 247 | * @var string 248 | */ 249 | public $outputStringArray = array(); 250 | 251 | /** 252 | * 253 | * @var int 254 | */ 255 | public $tabLevel = 0; 256 | 257 | /** 258 | * Adds string to output string array with "tab" prefix 259 | * 260 | * @var string $str 261 | */ 262 | public function addStr($str) 263 | { 264 | $str = str_replace($this->tab, '', $str); 265 | $this->outputStringArray[] = str_repeat($this->tab, $this->tabLevel) . $str; 266 | } 267 | 268 | /** 269 | * Returns string output 270 | */ 271 | public function output() 272 | { 273 | return implode($this->nw, $this->outputStringArray); 274 | } 275 | } -------------------------------------------------------------------------------- /controllers/DefaultController.php: -------------------------------------------------------------------------------- 1 | load(\Yii::$app->getRequest() 31 | ->post())) { 32 | 33 | if (! empty($model->tableSchemas)) { 34 | list ($up, $down) = $this->generalTableSchemas($model->tableSchemas, $model->tableOption); 35 | $upStr->outputStringArray = array_merge($upStr->outputStringArray, $up->outputStringArray); 36 | $downStr->outputStringArray = array_merge($downStr->outputStringArray, $down->outputStringArray); 37 | } 38 | 39 | if (! empty($model->tableDatas)) { 40 | list ($up, $down) = $this->generalTableDatas($model->tableDatas); 41 | $upStr->outputStringArray = array_merge($upStr->outputStringArray, $up->outputStringArray); 42 | $downStr->outputStringArray = array_merge($downStr->outputStringArray, $down->outputStringArray); 43 | } 44 | 45 | $path = Yii::getAlias($model->migrationPath); 46 | if (! is_dir($path)) { 47 | FileHelper::createDirectory($path); 48 | } 49 | 50 | $name = 'm' . gmdate('ymd_His') . '_' . $model->migrationName; 51 | $file = $path . DIRECTORY_SEPARATOR . $name . '.php'; 52 | 53 | $content = $this->renderFile(Yii::getAlias("@backend/modules/migration/views/migration.php"), [ 54 | 'className' => $name, 55 | 'up' => $upStr->output(), 56 | 'down' => $downStr->output() 57 | ]); 58 | file_put_contents($file, $content); 59 | Yii::$app->session->setFlash("success", "迁移成功,保存在" . $file); 60 | } 61 | 62 | if ($model->migrationPath == null) { 63 | $model->migrationPath = $this->module->migrationPath; 64 | } 65 | 66 | return $this->render('index', [ 67 | 'model' => $model 68 | ]); 69 | } 70 | 71 | public function getTableName($name) 72 | { 73 | $prefix = \Yii::$app->db->tablePrefix; 74 | 75 | return str_replace($prefix, '', $name); 76 | } 77 | 78 | public function generalTableSchemas($tables, $tableOption) 79 | { 80 | $initialTabLevel = 0; 81 | $upStr = new OutputString([ 82 | 'tabLevel' => $initialTabLevel 83 | ]); 84 | 85 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 86 | $upStr->addStr(' '); 87 | foreach ($tables as $table) { 88 | $upStr->tabLevel = $initialTabLevel; 89 | 90 | $tablePrepared = $this->getTableName($table); 91 | 92 | // 添加表结构 93 | $upStr->addStr('$this->createTable(\'{{%' . $tablePrepared . '}}\', ['); 94 | $upStr->tabLevel ++; 95 | $tableSchema = \Yii::$app->db->getTableSchema($table); 96 | 97 | foreach ($tableSchema->columns as $column) { 98 | $appUtility = new AppUtility($column); 99 | $upStr->addStr($appUtility->string . "',"); 100 | } 101 | if (! empty($tableSchema->primaryKey)) { 102 | $upStr->addStr("'PRIMARY KEY (`" . implode("`,`", $tableSchema->primaryKey) . "`)'"); 103 | } 104 | 105 | $upStr->tabLevel --; 106 | $upStr->addStr('], "' . $tableOption . '");'); 107 | 108 | 109 | // 添加索引 110 | $tableIndexes = Yii::$app->db->createCommand('SHOW INDEX FROM `' . $table . '`')->queryAll(); 111 | $indexs = []; 112 | foreach ($tableIndexes as $item) { 113 | if ($item['Key_name'] == 'PRIMARY') { 114 | continue; 115 | } 116 | if (! isset($indexs[$item["Key_name"]])) { 117 | $indexs[$item["Key_name"]] = []; 118 | $indexs[$item["Key_name"]]["unique"] = ($item['Non_unique']) ? 0 : 1; 119 | } 120 | $indexs[$item["Key_name"]]["columns"][] = $item['Column_name']; 121 | } 122 | 123 | if (! empty($indexs)) { 124 | $upStr->addStr(' '); 125 | } 126 | 127 | foreach ($indexs as $index => $item) { 128 | $str = '$this->createIndex(\'' . $index . '\',\'{{%' . $tablePrepared . '}}\',\'' . implode(', ', $item['columns']) . '\',' . $item['unique'] . ');'; 129 | $upStr->addStr($str); 130 | } 131 | 132 | $upStr->addStr(' '); 133 | } 134 | 135 | //添加外键 136 | $sql = "SELECT tb1.CONSTRAINT_NAME, tb1.TABLE_NAME, tb1.COLUMN_NAME, 137 | tb1.REFERENCED_TABLE_NAME, tb1.REFERENCED_COLUMN_NAME, tb2.MATCH_OPTION, 138 | 139 | tb2.UPDATE_RULE, tb2.DELETE_RULE 140 | 141 | FROM information_schema.KEY_COLUMN_USAGE AS tb1 142 | INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS AS tb2 ON 143 | tb1.CONSTRAINT_NAME = tb2.CONSTRAINT_NAME AND tb1.CONSTRAINT_SCHEMA = tb2.CONSTRAINT_SCHEMA 144 | WHERE TABLE_SCHEMA = DATABASE() 145 | AND REFERENCED_TABLE_SCHEMA = DATABASE() AND REFERENCED_COLUMN_NAME IS NOT NULL"; 146 | $foreignKeys = Yii::$app->db->createCommand($sql)->queryAll(); 147 | foreach ($foreignKeys as $fk) 148 | { 149 | $str = '$this->addForeignKey('; 150 | $str .= '\'' . $fk['CONSTRAINT_NAME'] . '\', '; 151 | $str .= '\'{{%' . $this->getTableName($fk['TABLE_NAME']) . '}}\', '; 152 | $str .= '\'' . $fk['COLUMN_NAME'] . '\', '; 153 | $str .= '\'{{%' . $this->getTableName($fk['REFERENCED_TABLE_NAME']) . '}}\', '; 154 | $str .= '\'' . $fk['REFERENCED_COLUMN_NAME'] . '\', '; 155 | $str .= '\'' . $fk['DELETE_RULE'] . '\', '; 156 | $str .= '\'' . $fk['UPDATE_RULE'] . '\' '; 157 | $str .= ');'; 158 | $upStr->addStr($str); 159 | } 160 | 161 | 162 | $upStr->addStr(' '); 163 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 164 | 165 | $downStr = new OutputString(); 166 | /* DROP TABLE */ 167 | $downStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 168 | foreach ($tables as $table) { 169 | if (! empty($table)) { 170 | $downStr->addStr('$this->dropTable(\'{{%' . $tablePrepared . '}}\');'); 171 | } 172 | } 173 | $downStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 174 | 175 | return [ 176 | $upStr, 177 | $downStr 178 | ]; 179 | } 180 | 181 | public function generalTableDatas($tables) 182 | { 183 | $initialTabLevel = 0; 184 | $upStr = new OutputString([ 185 | 'tabLevel' => $initialTabLevel 186 | ]); 187 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 0\');'); 188 | $upStr->addStr(' '); 189 | foreach ($tables as $table) { 190 | 191 | $tablePrepared = $this->getTableName($table); 192 | 193 | $upStr->addStr('/* Table ' . $table . ' */'); 194 | $tableSchema = \Yii::$app->db->getTableSchema($table); 195 | $data = Yii::$app->db->createCommand('SELECT * FROM `' . $table . '`')->queryAll(); 196 | $out = '$this->batchInsert(\'{{%' . $tablePrepared . '}}\',['; 197 | foreach ($tableSchema->columns as $column) { 198 | $out .= "'" . $column->name . "',"; 199 | } 200 | $out = rtrim($out, ',') . '],['; 201 | foreach ($data as $row) { 202 | $out .= '['; 203 | foreach ($row as $field) { 204 | if ($field === null) { 205 | $out .= "null,"; 206 | } else { 207 | $out .= "'" . addcslashes($field, "'") . "',"; 208 | } 209 | } 210 | $out = rtrim($out, ',') . "],\n"; 211 | } 212 | $out = rtrim($out, ',') . ']);'; 213 | $upStr->addStr($out); 214 | $upStr->addStr(' '); 215 | } 216 | $upStr->addStr('$this->execute(\'SET foreign_key_checks = 1;\');'); 217 | $downStr = new OutputString(); 218 | return [ 219 | $upStr, 220 | $downStr 221 | ]; 222 | } 223 | } 224 | 225 | /** 226 | * Class OutputString 227 | * 228 | * @author Nils Lindentals 229 | * 230 | * @package c006\utility\migration\controllers 231 | */ 232 | class OutputString extends Object 233 | { 234 | 235 | /** 236 | * 237 | * @var string 238 | */ 239 | public $nw = "\n"; 240 | 241 | /** 242 | * 243 | * @var string 244 | */ 245 | public $tab = "\t"; 246 | 247 | /** 248 | * 249 | * @var string 250 | */ 251 | public $outputStringArray = array(); 252 | 253 | /** 254 | * 255 | * @var int 256 | */ 257 | public $tabLevel = 0; 258 | 259 | /** 260 | * Adds string to output string array with "tab" prefix 261 | * 262 | * @var string $str 263 | */ 264 | public function addStr($str) 265 | { 266 | $str = str_replace($this->tab, '', $str); 267 | $this->outputStringArray[] = str_repeat($this->tab, $this->tabLevel) . $str; 268 | } 269 | 270 | /** 271 | * Returns string output 272 | */ 273 | public function output() 274 | { 275 | return implode($this->nw, $this->outputStringArray); 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /models/MigrationUtility.php: -------------------------------------------------------------------------------- 1 | db->getSchema()->getTableNames('', TRUE); 35 | return array_combine($tables,$tables); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /static/migration.css: -------------------------------------------------------------------------------- 1 | .title { 2 | display : block; 3 | font-size : 2em; 4 | margin-top : 20px; 5 | color : #e7ad24; 6 | } 7 | 8 | label[for=migrationutility-databasetables] { 9 | display : block; 10 | } 11 | 12 | .inline-elements { 13 | display : table; 14 | width : 100%; 15 | } 16 | 17 | .inline-elements > div { 18 | display : table-cell; 19 | vertical-align : top; 20 | } 21 | 22 | .inline-elements > div:first-of-type { 23 | width : 30%; 24 | } 25 | 26 | .inline-elements > div:last-of-type { 27 | width : 70%; 28 | } 29 | 30 | .inline-elements select { 31 | min-width : 100%; 32 | } 33 | 34 | .inline-elements input { 35 | min-width : 100%; 36 | } 37 | 38 | .button-style { 39 | display : inline-block; 40 | padding : 2px 10px; 41 | margin : 0; 42 | margin-left : 20px; 43 | 44 | font-size : 0.9em; 45 | font-weight : normal; 46 | 47 | background-color : rgba(155, 202, 242, 0.56); 48 | -webkit-border-radius : 5px; 49 | -moz-border-radius : 5px; 50 | border-radius : 5px; 51 | 52 | cursor : pointer; 53 | } 54 | -------------------------------------------------------------------------------- /static/migration.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $(".select-all").on("click",function() { 3 | var box = $(this).closest('.form-group') 4 | 5 | var selectall = box.data("selectall"); 6 | 7 | if(selectall == true) 8 | { 9 | box.find("input:checkbox").prop("checked",false); 10 | box.data("selectall",false); 11 | } 12 | else 13 | { 14 | box.find("input:checkbox").prop("checked",true); 15 | box.data("selectall",true); 16 | } 17 | }); 18 | 19 | 20 | 21 | }); -------------------------------------------------------------------------------- /views/default/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('backend', '迁移'); 14 | ?> 15 | 'form-submit']); ?> 16 |
17 |
18 | field($model, 'migrationName')->textInput()?> 19 | field($model, 'migrationPath')->textInput()?> 20 | field($model, 'tableOption')->textInput()?> 21 |
22 |
23 | 24 | field($model, "tableSchemas")->checkboxList(MigrationUtility::getTableNames())->label("迁移表结构")->hint(Html::a("全选",'javascript:void(0)',['class'=>"select-all"]))?> 25 | field($model, "tableDatas")->checkboxList(MigrationUtility::getTableNames())->label("迁移表数据")->hint(Html::a("全选",'javascript:void(0)',['class'=>"select-all"]))?> 26 | 27 |
28 | 'btn btn-primary btn-block ', 'name' => 'button-submit', 'id' => 'button-submit'])?> 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /views/migration.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | use yii\db\Migration; 12 | 13 | class extends Migration 14 | { 15 | public function up() 16 | { 17 | 18 | } 19 | 20 | public function down() 21 | { 22 | 23 | 24 | 25 | 26 | echo " cannot be reverted.\n"; 27 | 28 | } 29 | 30 | /* 31 | // Use safeUp/safeDown to run migration code within a transaction 32 | public function safeUp() 33 | { 34 | } 35 | 36 | public function safeDown() 37 | { 38 | } 39 | */ 40 | } 41 | --------------------------------------------------------------------------------