├── README.md ├── Sqltoci.php └── VERSION /README.md: -------------------------------------------------------------------------------- 1 | # Codeigniter Migrations Generator 2 | 3 | ## Create a Base Migration File from current DB 4 | 5 | Generate CodeIgniter 3.x Migrations from an existing database, including indexes and foreign keys! 6 | When all goes well it will create a file under migrations called 001_create_base.php under your migrations folder 7 | 8 | 9 | ## To use: 10 | 11 | 1: Enable migrations and set version to 1; 12 | 13 | 2: Create and Enable to write migration folder ``application/migrations``; 14 | 15 | 3: Clone repository to your library folder (/application/library); 16 | ``git clone git@github.com:fastworkx/ci_migrations_generator.git`` 17 | 18 | 4: In controller: 19 | 20 | ```php 21 | function make_base(){ 22 | 23 | $this->load->library('ci_migrations_generator/Sqltoci'); 24 | 25 | // All Tables: 26 | 27 | $this->sqltoci->generate(); 28 | 29 | //Single Table: 30 | 31 | $this->sqltoci->generate('table'); 32 | 33 | } 34 | ``` 35 | 36 | 5: You'll get something like this ``applications/migration/001_create_base.php``. 37 | 38 | ```php 39 | dbforge->add_field(array( 47 | 'id' => array( 48 | 'type' => 'VARCHAR', 49 | 'constraint' => 40, 50 | 'null' => FALSE, 51 | 52 | ), 53 | 'ip_address' => array( 54 | 'type' => 'VARCHAR', 55 | 'constraint' => 45, 56 | 'null' => FALSE, 57 | 58 | ), 59 | 'timestamp' => array( 60 | 'type' => 'INT', 61 | 'unsigned' => TRUE, 62 | 'null' => FALSE, 63 | 'default' => '0', 64 | 65 | ), 66 | 'data' => array( 67 | 'type' => 'BLOB', 68 | 'null' => FALSE, 69 | 70 | ), 71 | '`datetime_reg` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ', 72 | )); 73 | 74 | $this->dbforge->create_table("sessions", TRUE); 75 | $this->db->query('ALTER TABLE `sessions` ENGINE = InnoDB'); 76 | )); 77 | 78 | 79 | public function down() { 80 | 81 | ### Drop table sessions ## 82 | $this->dbforge->drop_table("sessions", TRUE); 83 | } 84 | } 85 | ``` 86 | 87 | It's an improve of repository ``liaan/codeigniter_migration_base_generation``; 88 | 89 | -------------------------------------------------------------------------------- /Sqltoci.php: -------------------------------------------------------------------------------- 1 | 12 | * @license Free to use and abuse 13 | * @version 0.1.0 Beta 14 | * 15 | */ 16 | class Sqltoci { 17 | 18 | var $db_user; 19 | var $db_pass; 20 | var $db_host; 21 | var $db_name; 22 | var $email; 23 | var $tables = '*'; 24 | var $newline = '\n'; 25 | var $write_file = true; 26 | var $file_name = ''; 27 | var $file_per_table = true; 28 | var $path = 'migrations'; 29 | var $skip_tables = array(); 30 | var $add_view = false; 31 | 32 | /* 33 | * defaults; 34 | */ 35 | 36 | function __construct($params = null) { 37 | // parent::__construct(); 38 | isset($this->ci) OR $this->ci = get_instance(); 39 | $this->ci->db_master = $this->ci->db; 40 | $this->db_user = $this->ci->db_master->username; 41 | $this->db_pass = $this->ci->db_master->password; 42 | $this->db_host = $this->ci->db_master->hostname; 43 | $this->db_name = $this->ci->db_master->database; 44 | $this->path = APPPATH . $this->path; 45 | if ($params) 46 | $this->init_config($params); 47 | } 48 | 49 | /** 50 | * Init Config if there is any passed 51 | * 52 | * 53 | * @param type $params 54 | */ 55 | function init_config($params = array()) { //apply config 56 | if (count($params) > 0) 57 | { 58 | foreach ($params as $key => $val) 59 | { 60 | if (isset($this->$key)) 61 | { 62 | $this->$key = $val; 63 | } 64 | } 65 | } 66 | } 67 | 68 | /** 69 | * Generate the file. 70 | * 71 | * @param string $tables 72 | * @return boolean|string 73 | */ 74 | function generate($tables = null) { 75 | if ($tables) 76 | $this->tables = $tables; 77 | 78 | $return = ''; 79 | /* open file */ 80 | if ($this->write_file) 81 | { 82 | if (!is_dir($this->path) OR !is_really_writable($this->path)) 83 | { 84 | $msg = "Unable to write migration file: " . $this->path; 85 | log_message('error', $msg); 86 | echo $msg; 87 | return; 88 | } 89 | 90 | if (!$this->file_per_table) 91 | { 92 | $file_path = $this->path . '/' . $this->file_name . '.sql'; 93 | $file = fopen($file_path, 'w+'); 94 | 95 | if (!$file) 96 | { 97 | $msg = "no file"; 98 | log_message('error', $msg); 99 | echo $msg; 100 | return FALSE; 101 | } 102 | } 103 | } 104 | 105 | 106 | // if default, then run all tables, otherwise just do the list provided 107 | if ($this->tables == '*') 108 | { 109 | 110 | $query = $this->ci->db_master->query('SHOW full TABLES FROM ' . $this->ci->db_master->protect_identifiers($this->ci->db_master->database)); 111 | 112 | $retval = array(); 113 | 114 | 115 | if ($query->num_rows() > 0) 116 | { 117 | 118 | foreach ($query->result_array() as $row) 119 | { 120 | 121 | $tablename = 'Tables_in_' . $this->ci->db_master->database; 122 | 123 | if (isset($row[$tablename])) 124 | { 125 | /* check if table in skip arrays, if so, go next */ 126 | if (in_array($row[$tablename], $this->skip_tables)) 127 | continue; 128 | 129 | /* check if views to be migrated */ 130 | if ($this->add_view) 131 | { 132 | ## not implemented ## 133 | //$retval[] = $row[$tablename]; 134 | } else 135 | { 136 | /* skip views */ 137 | if (strtolower($row['Table_type']) == 'view') 138 | { 139 | continue; 140 | } 141 | $retval[] = $row[$tablename]; 142 | } 143 | } 144 | } 145 | } 146 | 147 | $this->tables = array(); 148 | $this->tables = $retval; 149 | } else 150 | { 151 | $this->tables = is_array($tables) ? $tables : explode(',', $tables); 152 | } 153 | 154 | ## if write file, check if we can 155 | if ($this->write_file) 156 | { 157 | 158 | /* make subdir */ 159 | $path = $this->path . '/' . $this->file_name; 160 | 161 | if (!@is_dir($path)) 162 | { 163 | 164 | if (!@mkdir($path, DIR_WRITE_MODE, true)) 165 | { 166 | return FALSE; 167 | } 168 | 169 | @chmod($path, DIR_WRITE_MODE); 170 | } 171 | 172 | if (!is_dir($path) OR !is_really_writable($path)) 173 | { 174 | $msg = "Unable to write backup per table file: " . $path; 175 | log_message('error', $msg); 176 | 177 | return; 178 | } 179 | 180 | //$file_path = $path . '/001_create_' . $table . '.php'; 181 | $file_path = $path . '/001_create_base.php'; 182 | $file = fopen($file_path, 'w+'); 183 | 184 | if (!$file) 185 | { 186 | $msg = 'No File'; 187 | log_message('error', $msg); 188 | echo $msg; 189 | 190 | return FALSE; 191 | } 192 | } 193 | 194 | 195 | $up = ''; 196 | $down = ''; 197 | //loop through tables 198 | foreach ($this->tables as $table) 199 | { 200 | 201 | log_message('debug', print_r($table, true)); 202 | 203 | $q = $this->ci->db_master->query('describe ' . $this->ci->db_master->protect_identifiers($this->ci->db_master->database . '.' . $table)); 204 | // No result means the table name was invalid 205 | if ($q === FALSE) 206 | { 207 | continue; 208 | } 209 | 210 | $columns = $q->result_array(); 211 | 212 | $q = $this->ci->db_master->query(' SHOW TABLE STATUS WHERE Name = \'' . $table . '\''); 213 | $engines = $q->row_array(); 214 | 215 | $key = ''; 216 | $up .= PHP_EOL."\n\t\t" . '## Create Table ' . $table . "\n"; 217 | $up .= "\t\t" . '$this->dbforge->add_field(array('; 218 | 219 | foreach ($columns as $column) 220 | { 221 | $column_type = ''; 222 | $column_constraint = ''; 223 | $column_null = ( $column['Null'] == 'NO' ? 'FALSE' : 'TRUE' ); 224 | $column_default = $column['Default']; 225 | $column_unsigned = FALSE; 226 | $unsigned = 'unsigned'; 227 | 228 | //si tiene constraint 229 | if ( strpos($column['Type'], '(') ) 230 | { 231 | //verificar si tiene 'unsigned' 232 | if( strpos($column['Type'], $unsigned) ) 233 | { 234 | $column_unsigned = $unsigned; 235 | $column['Type'] = substr( $column['Type'], 0, strpos( $column['Type'], ')' ) ); 236 | } 237 | 238 | $column_type = strtoupper( substr($column['Type'], 0, strpos($column['Type'], '(') ) ); 239 | 240 | //si tiene un valores enum o set 241 | if( $column_type == 'ENUM' || $column_type == 'SET' ) 242 | { 243 | //reemplazamos comilla simple por doole 244 | $column['Type'] = str_replace('\'', '"', substr( $column['Type'], strpos( $column['Type'], '(') ) ); 245 | 246 | //concadenamos 247 | $column_type = $column_type.$column['Type']; 248 | $column_constraint = FALSE; 249 | } 250 | else 251 | { 252 | $column['Type'] = substr( $column['Type'], strpos( $column['Type'], '(') + 1 ); 253 | $column_constraint = substr($column['Type'], 0, -1 ); 254 | } 255 | } 256 | else 257 | { 258 | $column_type = strtoupper( $column['Type'] ); 259 | $column_constraint = FALSE; 260 | } 261 | 262 | //si tiene DEAFAULT generar sql texto plano para escapar el strin en caso e.g. CURRENT_TIMESTAMP 263 | if( $column_default == 'CURRENT_TIMESTAMP' ) 264 | { 265 | $up .= PHP_EOL."\t\t\t"."'`$column[Field]` $column[Type] " . ($column['Null'] == 'NO' ? 'NOT NULL' : 'NULL') . 266 | ( 267 | # if its timestamp column, don't '' around default value .... crap way, but should work for now 268 | $column['Default'] ? ' DEFAULT ' . ($column['Type'] == 'timestamp' ? $column['Default'] : '' . $column['Default'] . '') : '' 269 | ) 270 | . " $column[Extra]',"; 271 | } 272 | else 273 | { 274 | $up .= PHP_EOL. 275 | "\t\t\t".'\'' . $column['Field'] . '\' => array('.PHP_EOL. 276 | "\t\t\t\t".'\'type\' => \'' . $column_type . '\','.PHP_EOL. 277 | ( 278 | $column_constraint ? 279 | "\t\t\t\t".'\'constraint\' => ' . $column_constraint . ','.PHP_EOL : 280 | '' 281 | ). 282 | ( 283 | $column_unsigned ? 284 | "\t\t\t\t".'\''.$unsigned.'\' => TRUE,'.PHP_EOL : 285 | '' 286 | ). 287 | "\t\t\t\t".'\'null\' => ' . $column_null . ','.PHP_EOL. 288 | ( 289 | $column_default != NULL ? 290 | "\t\t\t\t".'\'default\' => \'' . $column_default . '\','.PHP_EOL : 291 | '' 292 | ). 293 | ( 294 | $column['Extra'] ? 295 | "\t\t\t\t".'\''.$column['Extra'].'\' => TRUE'.PHP_EOL : 296 | ''.PHP_EOL 297 | ). 298 | "\t\t\t".'),'; 299 | } 300 | 301 | if ($column['Key'] == 'PRI') 302 | $key = "\t\t" . '$this->dbforge->add_key("' . $column['Field'] . '",true);'; 303 | } 304 | 305 | $up .= PHP_EOL."\t\t));". PHP_EOL.$key.PHP_EOL."\t\t" . '$this->dbforge->create_table("' . $table . '", TRUE);' . PHP_EOL; 306 | 307 | if (isset($engines['Engine']) and $engines['Engine']) 308 | $up .= "\t\t" . '$this->db->query(\'ALTER TABLE ' . $this->ci->db_master->protect_identifiers($table) . 309 | ' ENGINE = ' . $engines['Engine']. '\');'; 310 | 311 | 312 | $down .= "\t\t" . '### Drop table ' . $table . ' ##' . "\n"; 313 | $down .= "\t\t" . '$this->dbforge->drop_table("' . $table . '", TRUE);' . "\n"; 314 | 315 | /* clear some mem */ 316 | $q->free_result(); 317 | } 318 | 319 | ### generate the text ## 320 | $return .= 'write_file) 335 | { 336 | fwrite($file, $return); 337 | fclose($file); 338 | echo "Create file migration with success!"; 339 | return true; 340 | } else 341 | { 342 | return $return; 343 | } 344 | } 345 | 346 | } 347 | 348 | ?> 349 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.1.2 --------------------------------------------------------------------------------