├── .gitignore ├── .semver ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Config └── Migration │ ├── 001_init_migrations.php │ ├── 002_convert_version_to_class_names.php │ └── 003_increase_class_name_length.php ├── Console └── Command │ ├── MigrationShell.php │ ├── MigrationsShell.php │ └── Templates │ └── migration.ctp ├── Docs ├── Documentation │ ├── Examples.md │ ├── Generate-Migrations-Without-DB-Interaction.md │ ├── Installation.md │ ├── Migrations.md │ ├── Overview.md │ └── Pre-Migration-Checks.md ├── Home.md └── Tutorials │ └── Quick-Start.md ├── LICENSE.txt ├── Lib ├── CakeMigration.php ├── Migration │ ├── PrecheckBase.php │ ├── PrecheckCondition.php │ └── PrecheckException.php ├── MigrationVersion.php └── Panel │ └── MigrationsPanel.php ├── Locale ├── deu │ └── LC_MESSAGES │ │ └── migrations.po ├── fre │ └── LC_MESSAGES │ │ └── migrations.po ├── ita │ └── LC_MESSAGES │ │ └── migrations.po ├── migrations.pot ├── por │ └── LC_MESSAGES │ │ └── migrations.po └── spa │ └── LC_MESSAGES │ └── migrations.po ├── Model └── SchemaMigration.php ├── README.md ├── Test ├── Case │ ├── AllMigrationsTest.php │ ├── Console │ │ └── Command │ │ │ └── MigrationShellTest.php │ └── Lib │ │ ├── Migration │ │ └── PrecheckConditionTest.php │ │ ├── MigrationVersionTest.php │ │ └── Model │ │ └── CakeMigrationTest.php ├── Fixture │ ├── SchemaMigrationsFixture.php │ ├── test_migration.txt │ ├── test_migration_add_fields_from_cli.txt │ ├── test_migration_create_table_from_cli.txt │ ├── test_migration_drop_table_from_cli.txt │ └── test_migration_remove_fields_from_cli.txt └── test_app │ └── Plugin │ ├── TestMigrationPlugin │ └── Config │ │ ├── Migration │ │ ├── 001_schema_dump.php │ │ ├── 002_another_migration_plugin_test_migration.php │ │ ├── blank_file.php │ │ └── map.php │ │ └── Schema │ │ └── Schema.php │ ├── TestMigrationPlugin2 │ └── empty │ ├── TestMigrationPlugin3 │ └── Config │ │ └── Migration │ │ └── map.php │ └── TestMigrationPlugin4 │ └── Config │ └── Schema │ └── schema.php ├── View └── Elements │ └── migrations_panel.ctp └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | # User specific & automatically generated files # 2 | ################################################# 3 | *.mo 4 | 5 | # IDE and editor specific files # 6 | ################################# 7 | .idea 8 | 9 | # OS generated files # 10 | ###################### 11 | .DS_Store 12 | .DS_Store? 13 | ._* 14 | .Spotlight-V100 15 | .Trashes 16 | Icon? 17 | ehthumbs.db 18 | Thumbs.db -------------------------------------------------------------------------------- /.semver: -------------------------------------------------------------------------------- 1 | --- 2 | :major: 2 3 | :minor: 6 4 | :patch: 0 5 | :special: '' 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.2 5 | - 7.3 6 | env: 7 | global: 8 | - PLUGIN_NAME=Migrations 9 | - DB=mysql 10 | - MYSQL_CREATE_DB="mysql -e 'create database cakephp_test CHARACTER SET utf8 COLLATE utf8_general_ci;'" 11 | - REQUIRE="phpunit/phpunit:3.7.31" 12 | 13 | matrix: 14 | - DB=mysql CAKE_VERSION=2.10 15 | 16 | matrix: 17 | include: 18 | - php: 7.2 19 | env: 20 | - CAKE_VERSION=2.10 21 | - php: 7.3 22 | env: 23 | - CAKE_VERSION=2.10 24 | before_script: 25 | - git clone https://github.com/steinkel/travis.git --depth 1 ../travis 26 | - ../travis/before_script.sh 27 | - if [ "$PHPCS" != 1 ]; then 28 | echo " 29 | require_once APP . DS . 'vendor' . DS . 'phpunit' . DS . 'phpunit' . DS . 'PHPUnit' . DS . 'Autoload.php'; 30 | " >> ../cakephp/app/Config/bootstrap.php; 31 | fi 32 | 33 | script: 34 | - ../travis/script.sh 35 | 36 | after_success: 37 | - ../travis/after_success.sh 38 | 39 | notifications: 40 | email: false 41 | 42 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | Release 2.5.1 5 | ------------- 6 | 7 | * [955e10b3](https://github.com/CakeDC/migrations/commit/955e10b3) fix phpdo 8 | * [7d9b053](https://github.com/CakeDC/migrations/commit/7d9b053a6) Missing note about the schema/database comparison. 9 | * [7b47ae3](https://github.com/CakeDC/migrations/commit/7b47ae3) Updating the docs. 10 | * [a59d1d1](https://github.com/CakeDC/migrations/commit/a59d1d1) Fix missing return statements. 11 | * [9363915](https://github.com/CakeDC/migrations/commit/9363915) Migration name check. 12 | * [263c739](https://github.com/CakeDC/migrations/commit/263c739) New preview options. 13 | * [0a4dc0b](https://github.com/CakeDC/migrations/commit/0a4dc0b) Fix missing translation domain. 14 | * [dfbed18](https://github.com/CakeDC/migrations/commit/dfbed18) New name param. 15 | 16 | 17 | Release 2.5.0 18 | ------------- 19 | 20 | * [ff07928](https://github.com/cakedc/migrations/commit/ff07928) adding unit test to skip feature 21 | * [be0922a](https://github.com/cakedc/migrations/commit/be0922a) adding skip migration feature, updating the documentation 22 | * [cb3281f](https://github.com/cakedc/migrations/commit/cb3281f) update docs re --compare parameter 23 | 24 | **Note:** The release **2.4.2** was created wrong, there we have new features too, not only bugfixes and improvements. 25 | 26 | Release 2.4.2 27 | ------------- 28 | 29 | * Bugfixes and doc improvements 30 | 31 | Release 2.4.1 32 | ------------- 33 | 34 | * Bugfix/Improvement release 35 | 36 | Release 2.4.0 37 | ------------- 38 | 39 | * [43228df](https://github.com/cakedc/migrations/commit/43228df) Code standard fix 40 | * [4352ed8](https://github.com/cakedc/migrations/commit/4352ed8) Changed method comment to a clearer comment 41 | * [25d7181](https://github.com/cakedc/migrations/commit/25d7181) Changed uses of the ConnectionManager class to static 42 | * [9a56814](https://github.com/cakedc/migrations/commit/9a56814) Fixed method comments 43 | * [2ee4c1e](https://github.com/cakedc/migrations/commit/2ee4c1e) Changed call of enumConnectionObjects to static 44 | * [caf1730](https://github.com/cakedc/migrations/commit/caf1730) Correct definition of the connection manager class uses 45 | * [193ed70](https://github.com/cakedc/migrations/commit/193ed70) Fixed code formating 46 | * [283590a](https://github.com/cakedc/migrations/commit/283590a) Fixed console input message that asks migrationConnection 47 | * [1909320](https://github.com/cakedc/migrations/commit/1909320) Added test case to check migrationConnection shell parameter 48 | * [b60fa05](https://github.com/cakedc/migrations/commit/b60fa05) Fixed array syntax in model uses 49 | * [9237949](https://github.com/cakedc/migrations/commit/9237949) Validate migrateConnection argument when a custom connection is set 50 | * [6374acc](https://github.com/cakedc/migrations/commit/6374acc) Added example to set a specific datasource on run 51 | 52 | Release 2.3.6 53 | ------------- 54 | 55 | * [1489496](https://github.com/cakedc/migrations/commit/1489496) Revert "fixing unit tests" to pass tests in travis env 56 | * [ebf6bc6](https://github.com/cakedc/migrations/commit/ebf6bc6) using minor for travis CakePHP 57 | * [517a810](https://github.com/cakedc/migrations/commit/517a810) updating travis 58 | * [180fe03](https://github.com/cakedc/migrations/commit/180fe03) fixed class condition after some changes done in Inflector::camelize in 2.6.6 59 | * [27d5afb](https://github.com/cakedc/migrations/commit/27d5afb) fixing unit tests 60 | 61 | Release 2.3.6 62 | ------------- 63 | 64 | https://github.com/CakeDC/migrations/tree/2.3.6 65 | 66 | * [ccac5a3](https://github.com/cakedc/migrations/commit/ccac5a3) Update translation files 67 | * [bca17ea](https://github.com/cakedc/migrations/commit/bca17ea) Show prompt for marking as successful when failure 68 | * [18aa020](https://github.com/cakedc/migrations/commit/18aa020) crlf to lf 69 | * [db96c9e](https://github.com/cakedc/migrations/commit/db96c9e) Grammatical corrections for generate command 70 | * [cc7b03a](https://github.com/cakedc/migrations/commit/cc7b03a) Fix CS issues 71 | * [942eab0](https://github.com/cakedc/migrations/commit/942eab0) Fix grammar in console output 72 | * [89ddfc1](https://github.com/cakedc/migrations/commit/89ddfc1) Tidy up unlinking in tests 73 | * [894f736](https://github.com/cakedc/migrations/commit/894f736) Fix for incorrect naming of all plugin migrations 74 | 75 | Release 2.3.5 76 | ------------- 77 | 78 | https://github.com/CakeDC/migrations/tree/2.3.5 79 | 80 | * [69e6136](https://github.com/cakedc/migrations/commit/69e6136) Add translations for new/missing strings 81 | * [c98ecdd](https://github.com/cakedc/migrations/commit/c98ecdd) Exit shell if comparing schema.php and nothing has changed 82 | 83 | Release 2.3.4 84 | ------------- 85 | 86 | https://github.com/CakeDC/migrations/tree/2.3.4 87 | 88 | * [94a7fe9](https://github.com/cakedc/migrations/commit/94a7fe9) Removed cakephp dependency from composer.json 89 | 90 | Release 2.3.3 91 | ------------- 92 | 93 | https://github.com/CakeDC/migrations/tree/2.3.3 94 | 95 | * [14a3cc4](https://github.com/cakedc/migrations/commit/14a3cc4) Bump minimum required CakePHP version to 2.5.4 (refs [#184](https://github.com/CakeDC/migrations/issues/184)) 96 | * [f6f3490](https://github.com/cakedc/migrations/commit/f6f3490) CS: Changed doc block "boolean" to "bool" 97 | * [b6c579c](https://github.com/cakedc/migrations/commit/b6c579c) Fixes Schema/app.php issue. 98 | * [749e634](https://github.com/cakedc/migrations/commit/749e634) Improved logic for schema class name detection. 99 | * [9ef51fd](https://github.com/cakedc/migrations/commit/9ef51fd) Adds an option for specifying the Schema class name. 100 | 101 | Release 2.3.2 102 | ------------- 103 | 104 | https://github.com/CakeDC/migrations/tree/2.3.2 105 | 106 | * [d3a3af7](https://github.com/cakedc/migrations/commit/d3a3af7) Fix CS in generated migrations (remove comma from param name in docblock) 107 | * [abc4c92](https://github.com/cakedc/migrations/commit/abc4c92) Fix CS in generated migrations (remove trailing comma from drop_field array) 108 | * [c952119](https://github.com/cakedc/migrations/commit/c952119) Fix migration generation when only indexes are changed (closes [#189](https://github.com/CakeDC/migrations/issues/189)) 109 | * [6386cd0](https://github.com/cakedc/migrations/commit/6386cd0) Removed else clause 110 | * [735401f](https://github.com/cakedc/migrations/commit/735401f) Added preview description when generating preview migration class 111 | * [4526828](https://github.com/cakedc/migrations/commit/4526828) Output entered description into $description in generated migration class 112 | * [4ffb6bf](https://github.com/cakedc/migrations/commit/4ffb6bf) Removed redundant and seemingly superfluous migration template 113 | * [ca982f6](https://github.com/cakedc/migrations/commit/ca982f6) Refs [#140](https://github.com/CakeDC/migrations/issues/140) Fixing the dry run output in other places as well 114 | * [d6cc1fa](https://github.com/cakedc/migrations/commit/d6cc1fa) Fixing [#140](https://github.com/CakeDC/migrations/issues/140) Migration run dry is not equal to run in real 115 | * [dcdbb20](https://github.com/cakedc/migrations/commit/dcdbb20) Update CHANGELOG.md 116 | * [cca5544](https://github.com/cakedc/migrations/commit/cca5544) Removed disabled translations in PO files 117 | * [72c3abc](https://github.com/cakedc/migrations/commit/72c3abc) Removed superfluous translation call 118 | * [409de07](https://github.com/cakedc/migrations/commit/409de07) Added .idea to .gitignore 119 | * [7de581c](https://github.com/cakedc/migrations/commit/7de581c) Set up some .gitignore rules 120 | * [c31eca8](https://github.com/cakedc/migrations/commit/c31eca8) Updated PO file headers from POT file 121 | * [d9a7ea3](https://github.com/cakedc/migrations/commit/d9a7ea3) Improved POT file header 122 | * [92158ab](https://github.com/cakedc/migrations/commit/92158ab) Updated spa locale from POT file 123 | * [4554b23](https://github.com/cakedc/migrations/commit/4554b23) Updated por locale from POT file 124 | * [7b9d383](https://github.com/cakedc/migrations/commit/7b9d383) Updated ita locale from POT file 125 | * [5acffda](https://github.com/cakedc/migrations/commit/5acffda) Updated fre locale from POT file 126 | * [af97e06](https://github.com/cakedc/migrations/commit/af97e06) Updated deu locale from POT file 127 | * [a33853c](https://github.com/cakedc/migrations/commit/a33853c) Regenerated migrations.pot file 128 | * [e830bc3](https://github.com/cakedc/migrations/commit/e830bc3) Made the migration shell messages more clear by adding quotes and the word table 129 | * [bc4bbe6](https://github.com/cakedc/migrations/commit/bc4bbe6) Fixing the class name generation in MigrationShell::_getSchema() 130 | 131 | Release 2.3.1 132 | ------------- 133 | 134 | https://github.com/CakeDC/migrations/tree/2.3.1 135 | 136 | * [117e958](https://github.com/cakedc/migrations/commit/117e958) Updating the Installation.md 137 | * [71acf74](https://github.com/cakedc/migrations/commit/71acf74) Adding in the load statement to be added in to bootstrap 138 | * [a1467a5](https://github.com/cakedc/migrations/commit/a1467a5) Fix the doc blocks 139 | 140 | Release 2.3.0 141 | ------------- 142 | 143 | https://github.com/CakeDC/migrations/tree/2.3.0 144 | 145 | * [12c0f80](https://github.com/CakeDC/migrations/commit/12c0f80) Updating the required CakePHP version in the documentation 146 | * [3f1da70](https://github.com/CakeDC/migrations/commit/3f1da70) Adding documentation for the columns 147 | * [0d2a76c](https://github.com/CakeDC/migrations/commit/0d2a76c) Updating a test file 148 | * [7dec605](https://github.com/CakeDC/migrations/commit/7dec605) Fix reversal of Hash::extract and Set::extract arguments (woops) 149 | * [2e48fd5](https://github.com/CakeDC/migrations/commit/2e48fd5) Updating Travis 150 | * [0244df4](https://github.com/CakeDC/migrations/commit/0244df4) Adding CONTRIBUTING.md 151 | * [8c0c9d8](https://github.com/CakeDC/migrations/commit/8c0c9d8) Update deprecated Set calls to use Hash 152 | * [d548d3e](https://github.com/CakeDC/migrations/commit/d548d3e) Updating the documentation for generating migrations via CLI without DB 153 | * [4bdc354](https://github.com/CakeDC/migrations/commit/4bdc354) Updating the documentation for creating migrations interactive via CLI 154 | * [838a106](https://github.com/CakeDC/migrations/commit/838a106) Adding documentation for the new generate migrations without DB interaction via CLI feature 155 | * [c52d7cb](https://github.com/CakeDC/migrations/commit/c52d7cb) Simplifying MigrationShellTest::testMigrationStatus 156 | * [f8f4acc](https://github.com/CakeDC/migrations/commit/f8f4acc) Fixing testGenerateComparison 157 | * [70fa569](https://github.com/CakeDC/migrations/commit/70fa569) Adjust database setup in travis.yml 158 | * [7c89dae](https://github.com/CakeDC/migrations/commit/7c89dae) Update travis.yml to test with php 5.5 and more cake versions 159 | * [93f5943](https://github.com/CakeDC/migrations/commit/93f5943) Implement code & test for 'add fields' from cli arguments 160 | * [76bb49c](https://github.com/CakeDC/migrations/commit/76bb49c) Implement code & test for 'remove fields' from cli arguments 161 | * [c577686](https://github.com/CakeDC/migrations/commit/c577686) Refactor & implement test for 'create table' and 'drop table' from cli arguments 162 | * [0baf125](https://github.com/CakeDC/migrations/commit/0baf125) Fix whitespace coding standards 163 | * [491a14b](https://github.com/CakeDC/migrations/commit/491a14b) Refactor - break up 80+ line method 164 | * [28d7eae](https://github.com/CakeDC/migrations/commit/28d7eae) Fix failing test - testRun 165 | * [ebb794c](https://github.com/CakeDC/migrations/commit/ebb794c) Fix failing test - testGenerateDump 166 | * [14cdc86](https://github.com/CakeDC/migrations/commit/14cdc86) Add ability to generate migration files without db interaction from CLI 167 | * [c52d7cb](https://github.com/CakeDC/migrations/commit/c52d7cb) Simplifying MigrationShellTest::testMigrationStatus 168 | * [f8f4acc](https://github.com/CakeDC/migrations/commit/f8f4acc) Fixing testGenerateComparison 169 | * [fb154ba](https://github.com/CakeDC/migrations/commit/fb154ba) Updating deprecated phpunit method names 170 | * [891d531](https://github.com/CakeDC/migrations/commit/891d531) Updating deprecated phpunit method calls 171 | * [8745815](https://github.com/CakeDC/migrations/commit/8745815) Fixing MigrationShellTest::testGenerateDump() 172 | * [22e8e75](https://github.com/CakeDC/migrations/commit/22e8e75) Fixing MigrationVersionTest::testRun() 173 | * [6f2e0ef](https://github.com/CakeDC/migrations/commit/6f2e0ef) Update MigrationShell.php 174 | * [8995d27](https://github.com/CakeDC/migrations/commit/8995d27) Prevent undefined index error rather than masking the actual error 175 | * [c4bfe0c](https://github.com/CakeDC/migrations/commit/c4bfe0c) Changing the test_migration.txt file to reflect the changes in the migration generation 176 | * [2095306](https://github.com/CakeDC/migrations/commit/2095306) Fixing tests, removed a return; where it should not be and corrected an assert 177 | * [d772fc7](https://github.com/CakeDC/migrations/commit/d772fc7) Fix broken test in Model CakeMigrationTest. An exception is thrown when you try to create an index withf231417 fix setUp for tests and assert english as language 178 | * [830fb76](https://github.com/CakeDC/migrations/commit/830fb76) Coding standards 179 | * [4c79e60](https://github.com/CakeDC/migrations/commit/4c79e60) Remove unnecessary code 180 | * [c745fe0](https://github.com/CakeDC/migrations/commit/c745fe0) Cleanup and coding standards 181 | * [58aa7ee](https://github.com/CakeDC/migrations/commit/58aa7ee) Removing legacy reset/restore methods and array key 182 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | This repository follows the [CakeDC Plugin Standard](http://cakedc.com/plugin-standard). If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](http://cakedc.com/contribution-guidelines) for detailed instructions. 5 | -------------------------------------------------------------------------------- /Config/Migration/001_init_migrations.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'create_table' => array( 19 | 'schema_migrations' => array( 20 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 21 | 'class' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 33), 22 | 'type' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 50), 23 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 24 | 'indexes' => array( 25 | 'PRIMARY' => array('column' => 'id', 'unique' => 1) 26 | ) 27 | ) 28 | ) 29 | ), 30 | 'down' => array( 31 | 'drop_table' => array( 32 | 'schema_migrations' 33 | ) 34 | ) 35 | ); 36 | 37 | /** 38 | * Before migration callback 39 | * 40 | * @param string $direction Direction of migration process (up or down) 41 | * @return bool Should process continue 42 | */ 43 | public function before($direction) { 44 | return true; 45 | } 46 | 47 | /** 48 | * After migration callback 49 | * 50 | * @param string $direction Direction of migration process (up or down) 51 | * @return bool Should process continue 52 | */ 53 | public function after($direction) { 54 | return true; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Config/Migration/002_convert_version_to_class_names.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'alter_field' => array( 19 | 'schema_migrations' => array( 20 | 'version' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 33, 'name' => 'class') 21 | ) 22 | ) 23 | ), 24 | 'down' => array( 25 | 'alter_field' => array( 26 | 'schema_migrations' => array( 27 | 'class' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'name' => 'version') 28 | ) 29 | ) 30 | ) 31 | ); 32 | 33 | /** 34 | * Records to be migrated 35 | * 36 | * @var array 37 | */ 38 | public $records = array(); 39 | 40 | /** 41 | * Mappings to the records 42 | * 43 | * @var array 44 | */ 45 | public $mappings = array(); 46 | 47 | /** 48 | * Before migration callback 49 | * 50 | * @param string $direction Direction of migration process (up or down) 51 | * @return bool Should process continue 52 | * @throws InternalErrorException 53 | */ 54 | public function before($direction) { 55 | if ($direction === 'down') { 56 | throw new InternalErrorException(__d('migrations', 'Sorry, I can\'t downgrade. Why would you want that anyways?')); 57 | } 58 | 59 | $this->records = $this->Version->Version->find('all'); 60 | 61 | $this->needsUpgrade(); 62 | $this->checkPlugins(); 63 | $this->checkRecords(); 64 | 65 | return true; 66 | } 67 | 68 | /** 69 | * After migration callback 70 | * 71 | * @param string $direction Direction of migration process (up or down) 72 | * @return bool Should process continue 73 | */ 74 | public function after($direction) { 75 | $this->upgradeRecords(); 76 | 77 | return true; 78 | } 79 | 80 | /** 81 | * Check if it needs upgrade or not 82 | * 83 | * @return void 84 | */ 85 | public function needsUpgrade() { 86 | $schema = $this->Version->Version->schema(); 87 | 88 | // Needs upgrade 89 | if (isset($schema['version'])) { 90 | return; 91 | } 92 | 93 | // Do not need, 001 already set it as string 94 | // Unset actions, records and mappings, so it wont try again 95 | $this->migration = array( 96 | 'up' => array(), 97 | 'down' => array() 98 | ); 99 | $this->records = array(); 100 | $this->mappings = array(); 101 | } 102 | 103 | /** 104 | * Check if every plugin is loaded/reachable, we need access to them 105 | * 106 | * @throws MissingPluginException 107 | * @return void 108 | */ 109 | public function checkPlugins() { 110 | $types = Hash::extract($this->records, '{n}.' . $this->Version->Version->alias . '.type'); 111 | $types = $plugins = array_unique($types); 112 | 113 | // Remove app from it 114 | $index = array_search('app', $plugins); 115 | if ($index !== false) { 116 | unset($plugins[$index]); 117 | } 118 | 119 | // Try to load them 120 | CakePlugin::load($plugins); 121 | } 122 | 123 | /** 124 | * Check if the version is present in the mappings 125 | * 126 | * @throws RuntimeException MigrationVersionException 127 | * @return void 128 | */ 129 | public function checkRecords() { 130 | foreach ($this->records as $record) { 131 | $type = $record[$this->Version->Version->alias]['type']; 132 | $version = $record[$this->Version->Version->alias]['version']; 133 | 134 | if (!isset($this->mappings[$type])) { 135 | $this->mappings[$type] = $this->Version->getMapping($type); 136 | } 137 | 138 | // Existing mapping 139 | if (empty($this->mappings[$type][$version])) { 140 | throw new RuntimeException(sprintf( 141 | 'Not able to match version `%d` in `%s`. Make sure every migration applied to the database is present on the filesystem.', 142 | $version, $type 143 | )); 144 | } 145 | 146 | // Migration file and class present? If not, will throw an exception 147 | $info = $this->mappings[$type][$version]; 148 | $migration = $this->Version->getMigration($info['name'], $info['class'], $type); 149 | unset($migration); 150 | } 151 | } 152 | 153 | /** 154 | * Upgrade records, setting version as class name 155 | * 156 | * @return void 157 | */ 158 | public function upgradeRecords() { 159 | foreach ($this->records as $record) { 160 | $type = $record[$this->Version->Version->alias]['type']; 161 | $version = $record[$this->Version->Version->alias]['version']; 162 | 163 | $mapping = $this->mappings[$type]; 164 | $migration = $mapping[$version]; 165 | 166 | $this->Version->Version->id = $record[$this->Version->Version->alias]['id']; 167 | $this->Version->Version->saveField('class', $migration['class']); 168 | } 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /Config/Migration/003_increase_class_name_length.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'alter_field' => array( 19 | 'schema_migrations' => array( 20 | 'class' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 255, 'name' => 'class') 21 | ) 22 | ) 23 | ), 24 | 'down' => array( 25 | 'alter_field' => array( 26 | 'schema_migrations' => array( 27 | 'class' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 33, 'name' => 'class') 28 | ) 29 | ) 30 | ) 31 | ); 32 | 33 | /** 34 | * Before migration callback 35 | * 36 | * @param string $direction Direction of migration process (up or down) 37 | * @return bool Should process continue 38 | */ 39 | public function before($direction) { 40 | return true; 41 | } 42 | 43 | /** 44 | * After migration callback 45 | * 46 | * @param string $direction Direction of migration process (up or down) 47 | * @return bool Should process continue 48 | */ 49 | public function after($direction) { 50 | return true; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Console/Command/MigrationsShell.php: -------------------------------------------------------------------------------- 1 | 13 | class extends CakeMigration { 14 | 15 | /** 16 | * Migration description 17 | * 18 | * @var string 19 | */ 20 | public $description = ''; 21 | 22 | /** 23 | * Actions to be performed 24 | * 25 | * @var array $migration 26 | */ 27 | public $migration = array( 28 | 29 | ); 30 | 31 | /** 32 | * Before migration callback 33 | * 34 | * @param string $direction Direction of migration process (up or down) 35 | * @return bool Should process continue 36 | */ 37 | public function before($direction) { 38 | return true; 39 | } 40 | 41 | /** 42 | * After migration callback 43 | * 44 | * @param string $direction Direction of migration process (up or down) 45 | * @return bool Should process continue 46 | */ 47 | public function after($direction) { 48 | return true; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Docs/Documentation/Examples.md: -------------------------------------------------------------------------------- 1 | Examples 2 | ======== 3 | 4 | Generate a Migration File 5 | ------------------------- 6 | 7 | Creating a new migration file. 8 | 9 | ``` 10 | cake Migrations.migration generate 11 | ``` 12 | 13 | If you want specify the migration name you can use ```--name``` parameter. 14 | 15 | ``` 16 | cake Migrations.migration generate --name 'the migration name' 17 | ``` 18 | 19 | If you want import all tables regardless if it has a model or not you can use ```-f``` (force) parameter. 20 | 21 | ``` 22 | cake Migrations.migration generate -f 23 | ``` 24 | 25 | If you want to force the comparison between schema file and database you can use ```--compare``` parameter. 26 | 27 | ``` 28 | cake Migrations.migration generate --compare 29 | ``` 30 | 31 | **Note:** *The comparison can be made on a double-handed path. Between the (modified) schema and the database, and also 32 | between the (modified) database and the schema.* 33 | 34 | If you want to show the migration preview you can use ```--preview``` parameter. 35 | 36 | ``` 37 | cake Migrations.migration generate --preview 38 | ``` 39 | 40 | If you want to prevent the migration preview you can use ```--no-preview``` parameter. 41 | 42 | ``` 43 | cake Migrations.migration generate --no-preview 44 | ``` 45 | 46 | Running All Pending Migrations 47 | ----------------------------- 48 | 49 | Get all pending changes into your database run. 50 | 51 | ``` 52 | cake Migrations.migration run all 53 | ``` 54 | 55 | Resetting Your Database 56 | ----------------------- 57 | 58 | Reset your database to the initial state of your first migration run. 59 | 60 | ``` 61 | cake Migrations.migration run reset 62 | ``` 63 | 64 | Downgrade to Previous Version 65 | ----------------------------- 66 | 67 | Downgrades your database to the previous migration. 68 | 69 | ``` 70 | cake Migrations.migration run down 71 | ``` 72 | 73 | Upgrade to Next Version 74 | ----------------------- 75 | 76 | Applies the next migration to your database. 77 | 78 | ``` 79 | cake Migrations.migration run up 80 | ``` 81 | 82 | Running Migrations for Plugins 83 | ------------------------------ 84 | 85 | Running a migration of a plugin you can use the plugin option. 86 | 87 | ``` 88 | cake Migrations.migration run all --plugin Users 89 | ``` 90 | 91 | Getting the Status of Available/Applied Migrations 92 | -------------------------------------------------- 93 | 94 | Gets the status of all migrations. 95 | 96 | ``` 97 | cake Migrations.migration status 98 | ``` 99 | 100 | Adding a specific datasource 101 | -------------------------------------------------- 102 | 103 | Will set the datasource and will run the migrations in this datasource. 104 | 105 | ``` 106 | cake Migrations.migration run --connection my_data_source 107 | ``` 108 | 109 | Skipping certain migrations 110 | -------------------------------------------------- 111 | 112 | Will skip one migration. 113 | 114 | ``` 115 | cake Migrations.migration run all --skip 1458963215_articles_table 116 | ``` 117 | 118 | You can skip many migrations using comma to separate, for example. 119 | 120 | ``` 121 | cake Migrations.migration run all --skip 1458963215_articles_table,1457412585_users_table 122 | ``` 123 | 124 | Remember this migrations will be set as executed. 125 | 126 | Jumping to certain migrations 127 | -------------------------------------------------- 128 | 129 | If you want to jump to a certain migration, you can use ```--jump-to``` or ```-j``` + migration name as in the example below. 130 | 131 | ``` 132 | cake Migrations.migration run all -j 1458963215_articles_table 133 | ``` 134 | 135 | Remember all migrations before this will be set as executed. 136 | -------------------------------------------------------------------------------- /Docs/Documentation/Generate-Migrations-Without-DB-Interaction.md: -------------------------------------------------------------------------------- 1 | Generate Migrations Without DB Interaction 2 | ========================================== 3 | 4 | This functionality only works when arguments are passed to the command `cake Migrations.migration generate`. 5 | 6 | This commit adds the ability to perform commands such as the following: 7 | 8 | ``` 9 | app/Console/cake Migrations.migration generate create_users id:primary_key name:string created modified 10 | ``` 11 | 12 | ``` 13 | app/Console/cake Migrations.migration generate alter_users name:string:index 14 | ``` 15 | 16 | ``` 17 | app/Console/cake Migrations.migration generate drop_users 18 | ``` 19 | 20 | ``` 21 | app/Console/cake Migrations.migration generate add_taxonomic_stuff_to_posts category:string tags:string 22 | ``` 23 | 24 | ``` 25 | app/Console/cake Migrations.migration generate remove_taxonomic_stuff_from_posts category tags 26 | ``` 27 | 28 | The above commands would: 29 | 30 | * Create a users table with the fields ["id", "name", "created", "modified"]. A single primary key index would exist on "id", and the "created" and "modified" fields would default to "datetime", as per *CakePHP* conventions. Since the type is specified on "name", it is a string. 31 | * Add an index to the "name" column in the "users" table. 32 | * Drop the users table. 33 | * Add "category" and "tags" fields to the "posts" table. 34 | * Remove "category" and "tags" fields from the "posts" table. 35 | 36 | Due to the conventions, not all schema changes can be performed via these shell commands. 37 | 38 | Migration names can follow any of the following regex patterns: 39 | 40 | * **create_table** `/^(create)_(.*)/`: Creates the specified table. 41 | * **drop_table** `/^(drop)_(.*)/`: Drops the specified table. Ignores specified field arguments. 42 | * **add_field** `/^(add)_.*_(?:to)_(.*)/`: Adds fields to the specified table. 43 | * **remove_field** `/^(remove)_.*_(?:from)_(.*)/`: Removes fields from the specified table. 44 | * **alter_table** `/^(alter)_(.*)/` : Alters the specified table. The **alter_table** command can be used as an alias for **create_table** and **add_field**. 45 | 46 | Migration names are used as migration class names, and thus may collide with other migrations if the class names are not unique. In this case, it may be necessary to manually override the name at a later date, or simply change the name you are specifying. 47 | 48 | Fields are verified via the following regular expression: 49 | 50 | ``` 51 | /^(\w*)(?::(\w*))?(?::(\w*))?(?::(\w*))?/ 52 | ``` 53 | 54 | These follow the format: 55 | 56 | ``` 57 | field:fieldType:indexType:indexName 58 | ``` 59 | 60 | For instance, the following are all valid ways of specifying the primary key "id": 61 | 62 | * `id:primary_key` 63 | * `id:primary_key:primary` 64 | * `id:integer:primary` 65 | * `id:integer:primary:ID_INDEX` 66 | 67 | Field types are specific to the database connection in use specified by the `--connection` argument ("default" by default). Thus, valid **Postgres** field types include "inet" and "number", while for **MySQL** the fieldType would be ignored. 68 | 69 | There are some heuristics to choosing field types when left unspecified or set to an invalid value: 70 | 71 | * **id:** integer 72 | * **created / modified / updated:** datetime 73 | * **default:** string 74 | 75 | Lengths for certain columns are also defaulted: 76 | 77 | * **string:** 255 78 | * **integer:** 11 79 | * **biginteger:** 20 -------------------------------------------------------------------------------- /Docs/Documentation/Installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | To install the plugin, place the files in a directory labelled "Migrations/" in your "app/Plugin/" directory. 5 | 6 | Then, include the following line in your `app/Config/bootstrap.php` to load the plugin in your application. 7 | 8 | ``` 9 | CakePlugin::load('Migrations'); 10 | ``` 11 | 12 | Git Submodule 13 | ------------- 14 | 15 | If you're using git for version control, you may want to add the **Migrations** plugin as a submodule on your repository. To do so, run the following command from the base of your repository: 16 | 17 | ``` 18 | git submodule add git@github.com:CakeDC/migrations.git app/Plugin/Migrations 19 | ``` 20 | 21 | After doing so, you will see the submodule in your changes pending, plus the file ".gitmodules". Simply commit and push to your repository. 22 | 23 | To initialize the submodule(s) run the following command: 24 | 25 | ``` 26 | git submodule update --init --recursive 27 | ``` 28 | 29 | To retreive the latest updates to the plugin, assuming you're using the "master" branch, go to "app/Plugin/Migrations" and run the following command: 30 | 31 | ``` 32 | git pull origin master 33 | ``` 34 | 35 | If you're using another branch, just change "master" for the branch you are currently using. 36 | 37 | If any updates are added, go back to the base of your own repository, commit and push your changes. This will update your repository to point to the latest updates to the plugin. 38 | 39 | Composer 40 | -------- 41 | 42 | To install the plugin with the [Composer dependency manager](https://getcomposer.org/), run the following from your CakePHP project's ROOT directory (where the ``composer.json`` file is located): 43 | 44 | ``` 45 | php composer.phar require cakedc/migrations "~2.4.0" 46 | ``` 47 | -------------------------------------------------------------------------------- /Docs/Documentation/Migrations.md: -------------------------------------------------------------------------------- 1 | Migrations 2 | ========== 3 | 4 | Auto-Migration Files 5 | -------------------- 6 | 7 | Once you've generated your first migration you'll probably want to do more changes to your database. To simplify the generation of new migrations you can perform schema diffs. For this, follow these steps: 8 | 9 | 1. Generate your first migration (if you haven't generated it yet) 10 | 2. Generate a schema file with ```cake schema generate``` command 11 | 3. Do the required changes to your database using your favorite tool 12 | 4. Generate a new migration file by running ```cake Migrations.migration generate``` 13 | 14 | Manually Creating Migration Files 15 | --------------------------------- 16 | 17 | If you prefer full control over your changes, or don't want to mess with *SQL*, you have the option to manually create your migration files. First create a blank migration with the following command: 18 | 19 | ``` 20 | cake Migrations.migration generate 21 | ``` 22 | 23 | Skip the comparison of the current database to the existing schema if asked or force comparing using ```--compare``` parameter. Then, open the newly created file under ```app/Config/Migrations```, then fill the file with the following migration directives. 24 | 25 | Column Keys 26 | ----------- 27 | 28 | The **Migrations** plugin works on top of the *CakePHP* Model layer, so you can use all of the features that are supported by the framework to describe columns. See the section on [columns](http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html#columns) for a complete list of all possible options. 29 | 30 | Create Table 31 | ------------ 32 | 33 | The ```create_table``` directive is used for the creation of new tables in your database. Note that the **Migrations** plugin will generate errors if the specified table already exists in the database. The ```drop_table``` and ```rename_table``` directives exist to deal with existing tables before proceeding with table creation. 34 | 35 | ```php 36 | 'create_table' => array( 37 | 'categories' => array( 38 | 'id' => array( 39 | 'type' =>'string', 40 | 'null' => false, 41 | 'default' => null, 42 | 'length' => 36, 43 | 'key' => 'primary' 44 | ), 45 | 'name' => array( 46 | 'type' =>'string', 47 | 'null' => false, 48 | 'default' => null 49 | ), 50 | 'indexes' => array( 51 | 'PRIMARY' => array( 52 | 'column' => 'id', 53 | 'unique' => 1 54 | ) 55 | ) 56 | ), 57 | 'emails' => array( 58 | 'id' => array( 59 | 'type' => 'string', 60 | 'length ' => 36, 61 | 'null' => false, 62 | 'key' => 'primary' 63 | ), 64 | 'data' => array( 65 | 'type' => 'text', 66 | 'null' => false, 67 | 'default' => null 68 | ), 69 | 'sent' => array( 70 | 'type' => 'boolean', 71 | 'null' => false, 72 | 'default' => '0' 73 | ), 74 | 'error' => array( 75 | 'type' => 'text', 76 | 'default' => null 77 | ), 78 | 'created' => array( 79 | 'type' => 'datetime' 80 | ), 81 | 'modified' => array( 82 | 'type' => 'datetime' 83 | ), 84 | 'indexes' => array( 85 | 'PRIMARY' => array( 86 | 'column' => 'id', 87 | 'unique' => 1 88 | ) 89 | ) 90 | ) 91 | ); 92 | ``` 93 | 94 | Drop Table 95 | ---------- 96 | 97 | The ```drop_table``` directive is used for removing tables from the schema. 98 | 99 | ```php 100 | 'drop_table' => array( 101 | 'categories', 102 | 'emails' 103 | ) 104 | ``` 105 | 106 | Rename Table 107 | ------------ 108 | 109 | The ```rename_table``` directive changes the name of a table in the database. 110 | 111 | ```php 112 | 'rename_table' => array( 113 | 'categories' => 'groups', 114 | 'emails' => 'email_addresses' 115 | ) 116 | ``` 117 | 118 | Create Field 119 | ------------ 120 | 121 | The ```create_field``` directive is used to add fields to an existing table in the schema. Note that Migrations will generate errors if the specified field already exists in the table. The ```drop_field```, ```rename_field``` and ```alter_field``` directives exist to deal with existing fields before proceeding with field addition. 122 | 123 | ```php 124 | 'create_field' => array( 125 | 'categories' => array( 126 | 'created' => array( 127 | 'type' => 'datetime' 128 | ), 129 | 'modified' => array( 130 | 'type' => 'datetime' 131 | ) 132 | ) 133 | ) 134 | ``` 135 | 136 | Drop Field 137 | ---------- 138 | 139 | The ```drop_field``` directive is used for removing fields from existing tables in the schema. 140 | 141 | ```php 142 | 'drop_field' => array( 143 | 'categories' => array( 144 | 'created', 145 | 'modified' 146 | ), 147 | 'emails' => array( 148 | 'error' 149 | ) 150 | ) 151 | ``` 152 | 153 | Alter Field 154 | ----------- 155 | 156 | The ```alter_field``` directive changes the field properties in an existing table. Note that partial table specifications are passed, which is a subset of a full array of table data. These are the fields that are to be modified as part of the operation. If you wish to leave some fields untouched, simply exclude them from the ```table``` key for the ```alter_field``` operation. 157 | 158 | ```php 159 | 'alter_field' => array( 160 | 'categories' => array( 161 | 'name' => array( 162 | 'length' => 11 163 | ) 164 | ) 165 | ) 166 | ``` 167 | 168 | Rename Field 169 | ------------ 170 | 171 | The ```rename_field``` directive changes the name of a field on a specified table in the database. 172 | 173 | ```php 174 | 'rename_field' => array( 175 | 'categories' => array( 176 | 'name' => 'title' 177 | ), 178 | 'emails' => array( 179 | 'error' => 'error_code', 180 | 'modified' => 'updated' 181 | ) 182 | ) 183 | ``` 184 | 185 | Alter Index 186 | ----------- 187 | 188 | In order to add a new index to an existing field, you need to pass the index definition in an array. 189 | 190 | ```php 191 | 'create_field' => array( 192 | 'posts' => array( 193 | 'indexes' => array( 194 | 'UNIQUE_TITLE' => array( 195 | 'column' => 'title', 196 | 'unique' => true 197 | ) 198 | ) 199 | ) 200 | ) 201 | ``` 202 | 203 | Likewise, if you want to drop an index. 204 | 205 | ```php 206 | 'drop_field' => array( 207 | 'posts' => array( 208 | 'indexes' => array( 209 | 'UNIQUE_TITLE' 210 | ) 211 | ) 212 | ) 213 | ``` 214 | 215 | Callbacks 216 | --------- 217 | 218 | You can make use of callbacks in order to execute extra operations, for example, to fill tables with predefined data. You can even use the shell to ask the user for data that is going to be inserted. 219 | 220 | **Example 1:** Create table statuses and fill it with some default data. 221 | 222 | ```php 223 | public $migration = array( 224 | 'up' => array( 225 | 'create_table' => array( 226 | 'statuses' => array( 227 | 'id' => array( 228 | 'type' => 'string', 229 | 'length' => 36, 230 | 'null' => false, 231 | 'key' => 'primary' 232 | ), 233 | 'name' => array( 234 | 'type' => 'text', 235 | 'null' => false, 236 | 'default' => null 237 | ) 238 | ) 239 | ) 240 | ), 241 | 'down' => array( 242 | 'drop_table' => array('statuses') 243 | ) 244 | ); 245 | 246 | public function after($direction) { 247 | $Status = ClassRegistry::init('Status'); 248 | if ($direction === 'up') { 249 | // add 2 records to statues table 250 | $data[0]['Status']['id'] = '59a6a2c0-2368-11e2-81c1-0800200c9a66'; 251 | $data[0]['Status']['name'] = 'Published'; 252 | $data[1]['Status']['id'] = '59a6a2c1-2368-11e2-81c1-0800200c9a67'; 253 | $data[1]['Status']['name'] = 'Unpublished'; 254 | $Status->create(); 255 | if ($Status->saveAll($data)) { 256 | $this->callback->out('statuses table has been initialized'); 257 | } 258 | } elseif ($direction === 'down') { 259 | // do more work here 260 | } 261 | return true; 262 | } 263 | ``` 264 | 265 | **Example 2:** Prompt the user to insert data. 266 | 267 | ```php 268 | public $migration = array( 269 | 'up' => array( 270 | 'create_table' => array( 271 | 'statuses' => array( 272 | 'id' => array( 273 | 'type' => 'string', 274 | 'length' => 36, 275 | 'null' => false, 276 | 'key' => 'primary' 277 | ), 278 | 'name' => array( 279 | 'type' => 'text', 280 | 'null' => false, 281 | 'default' => null 282 | ) 283 | ) 284 | ) 285 | ), 286 | 'down' => array( 287 | 'drop_table' => array( 288 | 'statuses' 289 | ) 290 | ) 291 | ); 292 | 293 | public function after($direction) { 294 | $Status = ClassRegistry::init('Status'); 295 | if ($direction === 'up') { 296 | $this->callback->out('Please enter a default status below:'); 297 | $data['Status']['name'] = $this->callback->in('What is the name of the default status?'); 298 | $Status->create(); 299 | if ($Status->save($data)){ 300 | $this->callback->out('statuses table has been initialized'); 301 | } 302 | } elseif ($direction === 'down') { 303 | // do more work here 304 | } 305 | return true; 306 | } 307 | ``` 308 | -------------------------------------------------------------------------------- /Docs/Documentation/Overview.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | As an application is developed, changes to the database may be required, and managing that in teams can get extremely difficult. The **Migrations** plugin enables you to share and coordinate database changes in an iterative manner, removing the complexity of handling these changes. 5 | 6 | * **Console:** The console script allows you to run migrations up and down. 7 | * **Installation:** Migrations can also be run programmatically via an installer script. 8 | * **ORM:** The **Migrations** plugin makes use of the *CakePHP* ORM and supports all databases provided by the framework. 9 | 10 | Support 11 | ------- 12 | 13 | For bugs and feature requests, please use the [issues](https://github.com/CakeDC/migrations/issues) section of this repository. 14 | 15 | Commercial support is also available, [contact us](http://cakedc.com/contact) for more information. 16 | 17 | Contributing 18 | ------------ 19 | 20 | If you'd like to contribute new features, enhancements or bug fixes to the plugin, just read our [Contribution Guidelines](http://cakedc.com/plugins) for detailed instructions. 21 | 22 | License 23 | ------- 24 | 25 | Copyright 2007-2014 Cake Development Corporation (CakeDC). All rights reserved. 26 | 27 | Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Redistributions of the source code included in this repository must retain the copyright notice found in each file. 28 | -------------------------------------------------------------------------------- /Docs/Documentation/Pre-Migration-Checks.md: -------------------------------------------------------------------------------- 1 | Pre-Migration Checks 2 | ==================== 3 | 4 | The migration system supports two checking modes: *exception-based* and *condition-based*. 5 | 6 | The main difference is that exceptions will make the migration shell fail hard, while the *condition-based* check is a more graceful way to check for possible problems with a migration before exceptions even occur. 7 | 8 | If the database has already applied some modifications and you try to execute the same migration again, then the migration system will throw an exception. This is the *exception-based* mode for the migrations system, which is the default mode. 9 | 10 | The *condition-based* mode works differently. When the system is running a migration it checks that it's possible to apply the migration on the current database structure. For example, when creating a table, if it already exists, it will stop before applying the migration. 11 | 12 | Another example is dropping a field, where the pre-migration check will detect if the table and field exists 13 | and, if not, won't apply the migration. 14 | 15 | To enable *condition-based* mode use ```--precheck Migrations.PrecheckCondition``` with the migration shell. 16 | 17 | Customized Pre-Migration Checks 18 | ------------------------------- 19 | 20 | It's also possible to implement custom pre-checks. Your custom pre-check class must extend the 21 | [PrecheckBase](../../Lib/Migration/PrecheckBase.php) class from the plugin. You must also put your class in ```app/Lib/Migration/.php``` or inside a plugin. 22 | 23 | To run your class use ```--precheck YourPrecheckClass```, or to load it from another plugin simply following the dot notation, for example ```--precheck YourPlugin.YourPrecheckClass```. 24 | 25 | Migration Shell Return Codes 26 | ---------------------------- 27 | 28 | If you're scripting against the migration shell, it's useful to keep in mind the possible return codes: 29 | 30 | * 0 = Success 31 | * 1 = No migrations available 32 | * 2 = Not a valid migration version 33 | -------------------------------------------------------------------------------- /Docs/Home.md: -------------------------------------------------------------------------------- 1 | Home 2 | ==== 3 | 4 | This **Migrations** plugin enables developers to quickly and easily manage and migrate between database schema versions. 5 | 6 | Requirements 7 | ------------ 8 | 9 | * CakePHP 2.5+ (We recomment latest 2.x) 10 | * PHP 5.3.0+ (We recommend php 7+) 11 | 12 | Documentation 13 | ------------- 14 | 15 | * [Overview](Documentation/Overview.md) 16 | * [Installation](Documentation/Installation.md) 17 | * [Examples](Documentation/Examples.md) 18 | * [Migrations](Documentation/Migrations.md) 19 | * [Pre-Migration Checks](Documentation/Pre-Migration-Checks.md) 20 | * [Generate Migrations Without DB Interaction](Documentation/Generate-Migrations-Without-DB-Interaction.md) 21 | 22 | Tutorials 23 | --------- 24 | 25 | * [Quick Start](Tutorials/Quick-Start.md) 26 | -------------------------------------------------------------------------------- /Docs/Tutorials/Quick-Start.md: -------------------------------------------------------------------------------- 1 | Quick Start 2 | =========== 3 | 4 | This quick start guide will help you get ready to use the **Migrations** plugin with your application. 5 | 6 | Usage 7 | ----- 8 | 9 | Run ```Console/cake Migrations.migration run all -p Migrations``` to initialize the ```schema_migrations``` table. 10 | 11 | Generating your First Migration 12 | ------------------------------- 13 | 14 | The first step to adding migrations to an existing database is to import the database's structure into a format the **Migrations** plugin can work with. Namely, a migration file. To create your *first* migration file run the following command: 15 | 16 | ``` 17 | cake Migrations.migration generate 18 | ``` 19 | 20 | Follow the script and answer the questions. This will generate a new file containing a database structure snapshot using the internal **Migrations** plugin syntax. If you want to import all of your tables, regardless if it has a model or not, you can use ```-f``` (force) parameter while running the command. 21 | 22 | ``` 23 | cake Migrations.migration generate -f 24 | ``` 25 | 26 | Running Migrations 27 | ------------------ 28 | 29 | After generating or being supplied with a set of migrations, you can process them to change the state of your database. 30 | 31 | This is the crux of the **Migrations** plugin, allowing the migration of schemas up and down the migration chain, 32 | offering flexibility and easy management of your schema and data states. 33 | 34 | This will run the next not yet applied migration: 35 | 36 | ``` 37 | cake Migrations.migration run up 38 | ``` 39 | 40 | This will revert the last applied migration: 41 | 42 | ``` 43 | cake Migrations.migration run down 44 | ``` 45 | 46 | This will run all migrations that are found: 47 | 48 | ``` 49 | cake Migrations.migration run all 50 | ``` -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2007 - 2014, Cake Development Corporation 4 | 1785 E. Sahara Avenue, Suite 490-423 5 | Las Vegas, Nevada 89104 6 | http://cakedc.com 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Lib/CakeMigration.php: -------------------------------------------------------------------------------- 1 | array(), 54 | 'down' => array() 55 | ); 56 | 57 | /** 58 | * Running direction 59 | * 60 | * @var string $direction 61 | */ 62 | public $direction = null; 63 | 64 | /** 65 | * Connection used 66 | * 67 | * @var string 68 | */ 69 | public $connection = 'default'; 70 | 71 | /** 72 | * DataSource used 73 | * 74 | * @var DboSource 75 | */ 76 | public $db = null; 77 | 78 | /** 79 | * MigrationVersion instance 80 | * 81 | * @var MigrationVersion 82 | */ 83 | public $Version = null; 84 | 85 | /** 86 | * CakeSchema instance 87 | * 88 | * @var CakeSchema 89 | */ 90 | public $Schema = null; 91 | 92 | /** 93 | * Callback class that will be called before/after every action 94 | * 95 | * @var object 96 | */ 97 | public $callback = null; 98 | 99 | /** 100 | * Precheck object executed before db updated 101 | * 102 | * @var PrecheckBase 103 | */ 104 | public $Precheck = null; 105 | 106 | /** 107 | * Should the run be dry or not. 108 | * 109 | * If try, the SQL will be outputted to screen rather than 110 | * applied to the database 111 | * 112 | * @var bool 113 | */ 114 | public $dry = false; 115 | 116 | /** 117 | * Log of SQL queries generated 118 | * 119 | * This is used for dry run 120 | * 121 | * @var array 122 | */ 123 | public $log = array(); 124 | 125 | /** 126 | * Before migration callback 127 | * 128 | * @param string $direction Direction of migration process (up or down) 129 | * @return bool Should process continue 130 | */ 131 | public function before($direction) { 132 | return true; 133 | } 134 | 135 | /** 136 | * After migration callback 137 | * 138 | * @param string $direction Direction of migration process (up or down) 139 | * @return bool Should process continue 140 | */ 141 | public function after($direction) { 142 | return true; 143 | } 144 | 145 | /** 146 | * Log a dry run SQL query 147 | * 148 | * @param string $sql SQL query 149 | * @return void 150 | */ 151 | public function logQuery($sql) { 152 | $this->log[] = $sql; 153 | } 154 | 155 | /** 156 | * Get the SQL query log 157 | * 158 | * @return array 159 | */ 160 | public function getQueryLog() { 161 | return $this->log; 162 | } 163 | 164 | /** 165 | * Constructor 166 | * 167 | * @param array $options optional load object properties 168 | * @throws MigrationException 169 | */ 170 | public function __construct($options = array()) { 171 | parent::__construct(); 172 | 173 | if (!isset($options['dry'])) { 174 | $options['dry'] = false; 175 | } 176 | 177 | $this->dry = $options['dry']; 178 | 179 | if (!empty($options['up'])) { 180 | $this->migration['up'] = $options['up']; 181 | } 182 | if (!empty($options['down'])) { 183 | $this->migration['down'] = $options['down']; 184 | } 185 | 186 | $allowed = array('connection', 'callback'); 187 | 188 | foreach ($allowed as $variable) { 189 | if (!empty($options[$variable])) { 190 | $this->{$variable} = $options[$variable]; 191 | } 192 | } 193 | 194 | if (empty($options['precheck'])) { 195 | App::uses('PrecheckException', 'Migrations.Lib/Migration'); 196 | $this->Precheck = new PrecheckException(); 197 | } else { 198 | list($plugin, $class) = pluginSplit($options['precheck'], true); 199 | $class = Inflector::camelize($class); 200 | App::uses($class, $plugin . 'Lib/Migration'); 201 | if (!class_exists($class)) { 202 | throw new MigrationException($this, sprintf( 203 | __d('migrations', 'Migration precheck class (%s) could not be loaded.'), $options['precheck'] 204 | ), E_USER_NOTICE); 205 | } 206 | 207 | $this->Precheck = new $class(); 208 | 209 | if (!is_a($this->Precheck, 'PrecheckBase')) { 210 | throw new MigrationException($this, sprintf( 211 | __d('migrations', 'Migration precheck class (%s) is not a valid precheck class.'), $class 212 | ), E_USER_NOTICE); 213 | } 214 | } 215 | } 216 | 217 | /** 218 | * Run migration 219 | * 220 | * @param string $direction Direction of migration process (up or down) 221 | * @return bool Status of the process 222 | * @throws MigrationException 223 | */ 224 | public function run($direction) { 225 | if (!in_array($direction, array('up', 'down'))) { 226 | throw new MigrationException($this, sprintf( 227 | __d('migrations', 'Migration direction (%s) is not one of valid directions.'), $direction 228 | ), E_USER_NOTICE); 229 | } 230 | $this->direction = $direction; 231 | 232 | $null = null; 233 | $this->db = ConnectionManager::getDataSource($this->connection); 234 | $this->db->cacheSources = false; 235 | $this->db->begin($null); 236 | $this->Schema = new CakeSchema(array('connection' => $this->connection)); 237 | 238 | try { 239 | $this->_invokeCallbacks('beforeMigration', $direction); 240 | $result = $this->_run(); 241 | $this->_clearCache(); 242 | $this->_invokeCallbacks('afterMigration', $direction); 243 | 244 | if (!$result) { 245 | return false; 246 | } 247 | } catch (Exception $e) { 248 | $this->db->rollback($null); 249 | throw $e; 250 | } 251 | 252 | return $this->db->commit($null); 253 | } 254 | 255 | /** 256 | * Run migration commands 257 | * 258 | * @return void 259 | * @throws MigrationException 260 | */ 261 | protected function _run() { 262 | $result = true; 263 | //force the order of migration types 264 | uksort($this->migration[$this->direction], array($this, 'migration_order')); 265 | foreach ($this->migration[$this->direction] as $type => $info) { 266 | switch ($type) { 267 | case 'create_table': 268 | $methodName = '_createTable'; 269 | break; 270 | case 'drop_table': 271 | $methodName = '_dropTable'; 272 | break; 273 | case 'rename_table': 274 | $methodName = '_renameTable'; 275 | break; 276 | case 'create_field': 277 | $type = 'add'; 278 | $methodName = '_alterTable'; 279 | break; 280 | case 'drop_field': 281 | $type = 'drop'; 282 | $methodName = '_alterTable'; 283 | break; 284 | case 'alter_field': 285 | $type = 'change'; 286 | $methodName = '_alterTable'; 287 | break; 288 | case 'rename_field': 289 | $type = 'rename'; 290 | $methodName = '_alterTable'; 291 | break; 292 | default: 293 | $message = __d('migrations', 'Migration action type (%s) is not one of valid actions type.', $type); 294 | throw new MigrationException($this, $message, E_USER_NOTICE); 295 | } 296 | 297 | try { 298 | $result = $this->{$methodName}($type, $info); 299 | } catch (Exception $e) { 300 | throw new MigrationException($this, $e->getMessage()); 301 | } 302 | } 303 | return $result; 304 | } 305 | 306 | /** 307 | * Comparison method for sorting migration types 308 | * 309 | * @param string $a Type 310 | * @param string $b Type 311 | * @return int Comparison value 312 | */ 313 | protected function migration_order($a, $b) { 314 | $order = array('drop_table', 'rename_table', 'create_table', 'drop_field', 'rename_field', 'alter_field', 'create_field'); 315 | return array_search($a, $order) - array_search($b, $order); 316 | } 317 | 318 | /** 319 | * Create Table method 320 | * 321 | * @param string $type Type of operation to be done, in this case 'create_table' 322 | * @param array $tables List of tables to be created 323 | * @return bool Return true in case of success, otherwise false 324 | * @throws MigrationException 325 | */ 326 | protected function _createTable($type, $tables) { 327 | foreach ($tables as $table => $fields) { 328 | if ($this->_invokePrecheck('beforeAction', 'create_table', array('table' => $table))) { 329 | $this->Schema->tables = array($table => $fields); 330 | $this->_invokeCallbacks('beforeAction', 'create_table', array('table' => $table)); 331 | try { 332 | $sql = $this->db->createSchema($this->Schema); 333 | 334 | if ($this->dry) { 335 | $this->logQuery($sql); 336 | continue; 337 | } 338 | 339 | $this->db->execute($sql); 340 | } catch (Exception $exception) { 341 | throw new MigrationException($this, __d('migrations', 'SQL Error: %s', $exception->getMessage())); 342 | } 343 | } 344 | 345 | $this->_invokeCallbacks('afterAction', 'create_table', array('table' => $table)); 346 | } 347 | return true; 348 | } 349 | 350 | /** 351 | * Drop Table method 352 | * 353 | * @param string $type Type of operation to be done, in this case 'drop_table' 354 | * @param array $tables List of tables to be dropped 355 | * @return bool Return true in case of success, otherwise false 356 | * @throws MigrationException 357 | */ 358 | protected function _dropTable($type, $tables) { 359 | foreach ($tables as $table) { 360 | $this->Schema->tables = array($table => array()); 361 | if ($this->_invokePrecheck('beforeAction', 'drop_table', array('table' => $table))) { 362 | $this->_invokeCallbacks('beforeAction', 'drop_table', array('table' => $table)); 363 | 364 | $sql = $this->db->dropSchema($this->Schema); 365 | if ($this->dry) { 366 | $this->logQuery($sql); 367 | continue; 368 | } 369 | 370 | if (@$this->db->execute($sql) === false) { 371 | throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s'), $this->db->error)); 372 | } 373 | $this->_invokeCallbacks('afterAction', 'drop_table', array('table' => $table)); 374 | } 375 | } 376 | return true; 377 | } 378 | 379 | /** 380 | * Rename Table method 381 | * 382 | * @param string $type Type of operation to be done, this case 'rename_table' 383 | * @param array $tables List of tables to be renamed 384 | * @return bool Return true in case of success, otherwise false 385 | * @throws MigrationException 386 | */ 387 | protected function _renameTable($type, $tables) { 388 | foreach ($tables as $oldName => $newName) { 389 | if ($this->_invokePrecheck('beforeAction', 'rename_table', array('old_name' => $oldName, 'new_name' => $newName))) { 390 | $sql = 'ALTER TABLE ' . $this->db->fullTableName($oldName) . ' RENAME TO ' . $this->db->fullTableName($newName, true, false) . ';'; 391 | 392 | if ($this->dry) { 393 | $this->logQuery($sql); 394 | continue; 395 | } 396 | 397 | $this->_invokeCallbacks('beforeAction', 'rename_table', array('old_name' => $oldName, 'new_name' => $newName)); 398 | if (@$this->db->execute($sql) === false) { 399 | throw new MigrationException($this, __d('migrations', 'SQL Error: %s', $this->db->error)); 400 | } 401 | $this->_invokeCallbacks('afterAction', 'rename_table', array('old_name' => $oldName, 'new_name' => $newName)); 402 | } 403 | } 404 | return true; 405 | } 406 | 407 | /** 408 | * Alter Table method 409 | * 410 | * @param string $type Type of operation to be done 411 | * @param array $tables List of tables and fields 412 | * @return bool Return true in case of success, otherwise false 413 | * @throws MigrationException 414 | */ 415 | protected function _alterTable($type, $tables) { 416 | foreach ($tables as $table => $fields) { 417 | $indexes = array(); 418 | if (isset($fields['indexes'])) { 419 | $indexes = $fields['indexes']; 420 | unset($fields['indexes']); 421 | } 422 | 423 | if ($type === 'drop') { 424 | $this->_alterIndexes($indexes, $type, $table); 425 | } 426 | 427 | foreach ($fields as $field => $col) { 428 | $model = new Model(array('table' => $table, 'ds' => $this->connection)); 429 | $tableFields = $this->db->describe($model); 430 | $tableFields['indexes'] = $this->db->index($model); 431 | $tableFields['tableParameters'] = $this->db->readTableParameters($this->db->fullTableName($model, false, false)); 432 | 433 | if ($type === 'drop') { 434 | $field = $col; 435 | } 436 | 437 | if ($type === 'rename') { 438 | $data = array('table' => $table, 'old_name' => $field, 'new_name' => $col); 439 | } else { 440 | $data = array('table' => $table, 'field' => $field); 441 | } 442 | $callbackData = $data; 443 | 444 | if ($this->_invokePrecheck('beforeAction', $type . '_field', $data)) { 445 | switch ($type) { 446 | case 'add': 447 | $sql = $this->db->alterSchema(array( 448 | $table => array('add' => array($field => $col)) 449 | )); 450 | break; 451 | case 'drop': 452 | $sql = $this->db->alterSchema(array( 453 | $table => array('drop' => array($field => array())) 454 | )); 455 | break; 456 | case 'change': 457 | if (!isset($col['type']) || $col['type'] == $tableFields[$field]['type']) { 458 | $def = array_merge($tableFields[$field], $col); 459 | } else { 460 | $def = $col; 461 | } 462 | if (!empty($def['length']) && !empty($col['type']) && (substr($col['type'], 0, 4) === 'date' || substr($col['type'], 0, 4) === 'time')) { 463 | $def['length'] = null; 464 | } 465 | $sql = $this->db->alterSchema(array( 466 | $table => array('change' => array($field => $def)) 467 | )); 468 | break; 469 | case 'rename': 470 | $data = array(); 471 | if (array_key_exists($field, $tableFields)) { 472 | $data = $tableFields[$field]; 473 | } 474 | $sql = $this->db->alterSchema(array( 475 | $table => array('change' => array($field => array_merge($data, array('name' => $col)))) 476 | )); 477 | break; 478 | } 479 | 480 | if ($this->dry) { 481 | $this->logQuery($sql); 482 | continue; 483 | } 484 | 485 | $this->_invokeCallbacks('beforeAction', $type . '_field', $callbackData); 486 | if (@$this->db->execute($sql) === false) { 487 | throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s'), $this->db->error)); 488 | } 489 | $this->_invokeCallbacks('afterAction', $type . '_field', $callbackData); 490 | } 491 | } 492 | 493 | if ($type !== 'drop') { 494 | $this->_alterIndexes($indexes, $type, $table); 495 | } 496 | } 497 | return true; 498 | } 499 | 500 | /** 501 | * Alter Indexes method 502 | * 503 | * @param array $indexes List of indexes 504 | * @param string $type Type of operation to be done 505 | * @param string $table table name 506 | * @throws MigrationException 507 | * @return void 508 | */ 509 | protected function _alterIndexes($indexes, $type, $table) { 510 | foreach ($indexes as $key => $index) { 511 | if (is_numeric($key)) { 512 | $key = $index; 513 | $index = array(); 514 | } 515 | $sql = $this->db->alterSchema(array( 516 | $table => array($type => array('indexes' => array($key => $index))) 517 | )); 518 | 519 | if ($this->dry) { 520 | $this->logQuery($sql); 521 | continue; 522 | } 523 | 524 | if ($this->_invokePrecheck('beforeAction', $type . '_index', array('table' => $table, 'index' => $key))) { 525 | $this->_invokeCallbacks('beforeAction', $type . '_index', array('table' => $table, 'index' => $key)); 526 | if (@$this->db->execute($sql) === false) { 527 | throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s'), $this->db->error)); 528 | } 529 | } 530 | $this->_invokeCallbacks('afterAction', $type . '_index', array('table' => $table, 'index' => $key)); 531 | } 532 | } 533 | 534 | /** 535 | * This method will invoke the before/afterAction callbacks, it is good when 536 | * you need track every action. 537 | * 538 | * @param string $callback Callback name, beforeMigration, beforeAction, afterAction 539 | * or afterMigration. 540 | * @param string $type Type of action. i.e: create_table, drop_table, etc. 541 | * Or also can be the direction, for before and after Migration callbacks 542 | * @param array $data Data to send to the callback 543 | * @return void 544 | * @throws MigrationException 545 | */ 546 | protected function _invokeCallbacks($callback, $type, $data = array()) { 547 | if ($this->dry) { 548 | return true; 549 | } 550 | 551 | if ($this->callback !== null && method_exists($this->callback, $callback)) { 552 | if ($callback === 'beforeMigration' || $callback === 'afterMigration') { 553 | $this->callback->{$callback}($this, $type); 554 | } else { 555 | $this->callback->{$callback}($this, $type, $data); 556 | } 557 | } 558 | if ($callback === 'beforeMigration' || $callback === 'afterMigration') { 559 | $callback = str_replace('Migration', '', $callback); 560 | if ($this->{$callback}($type)) { 561 | return; 562 | } 563 | 564 | throw new MigrationException($this, sprintf( 565 | __d('migrations', 'Interrupted when running "%s" callback.'), $callback 566 | ), E_USER_NOTICE); 567 | } 568 | } 569 | 570 | /** 571 | * This method will invoke the before/afterAction callbacks, it is good when 572 | * you need track every action. 573 | * 574 | * @param string $callback Callback name, beforeMigration, beforeAction or afterMigration. 575 | * @param string $type Type of action (e.g. create_table, drop_table, etc.) 576 | * Also can be the direction (before/after) for Migration callbacks 577 | * @param array $data Data to send to the callback 578 | * @return bool 579 | */ 580 | protected function _invokePrecheck($callback, $type, $data = array()) { 581 | if ($this->dry) { 582 | return true; 583 | } 584 | 585 | if ($callback === 'beforeAction') { 586 | return $this->Precheck->{$callback}($this, $type, $data); 587 | } 588 | return false; 589 | } 590 | 591 | /** 592 | * Clear all caches present related to models 593 | * 594 | * Before the 'after' callback method be called is needed to clear all caches. 595 | * Without it any model operations will use cached data instead of real/modified 596 | * data. 597 | * 598 | * @return void 599 | */ 600 | protected function _clearCache() { 601 | // Clear the cache 602 | DboSource::$methodCache = array(); 603 | $keys = Cache::configured(); 604 | foreach ($keys as $key) { 605 | Cache::clear(false, $key); 606 | } 607 | ClassRegistry::flush(); 608 | 609 | // Refresh the model, in case something changed 610 | if ($this->Version instanceof MigrationVersion) { 611 | $this->Version->initVersion(); 612 | } 613 | } 614 | 615 | /** 616 | * Generate a instance of model for given options 617 | * 618 | * @param string $name Model name to be initialized 619 | * @param string $table Table name to be initialized 620 | * @param array $options Model constructor options 621 | * @return Model 622 | */ 623 | public function generateModel($name, $table = null, $options = array()) { 624 | if (empty($table)) { 625 | $table = Inflector::tableize($name); 626 | } 627 | $defaults = array( 628 | 'name' => $name, 'table' => $table, 'ds' => $this->connection 629 | ); 630 | $options = array_merge($defaults, $options); 631 | 632 | return new AppModel($options); 633 | } 634 | 635 | } 636 | 637 | /** 638 | * Exception used when something goes wrong on migrations 639 | */ 640 | class MigrationException extends Exception { 641 | 642 | /** 643 | * Reference to the Migration being processed on time the error ocurred 644 | * @var CakeMigration 645 | */ 646 | public $Migration; 647 | 648 | /** 649 | * Constructor 650 | * 651 | * @param CakeMigration $Migration Reference to the Migration 652 | * @param string $message Message explaining the error 653 | * @param int $code Error code 654 | * @return \MigrationException 655 | */ 656 | public function __construct($Migration, $message = '', $code = 0) { 657 | parent::__construct($message, $code); 658 | $this->Migration = $Migration; 659 | } 660 | } 661 | -------------------------------------------------------------------------------- /Lib/Migration/PrecheckBase.php: -------------------------------------------------------------------------------- 1 | _migration->db->cacheSources = false; 63 | $tables = $this->_migration->db->listSources(); 64 | return in_array($this->_migration->db->fullTableName($table, false, false), $tables); 65 | } 66 | 67 | /** 68 | * Check that field exists. 69 | * 70 | * @param string $table Table to look for 71 | * @param string $field Field to look for 72 | * @return bool 73 | */ 74 | public function fieldExists($table, $field) { 75 | if (!$this->tableExists($table)) { 76 | return false; 77 | } 78 | $fields = $this->_migration->db->describe($table); 79 | return !empty($fields[$field]); 80 | } 81 | 82 | /** 83 | * Before action precheck callback. 84 | * 85 | * @param CakeMigration $migration Migration to perform 86 | * @param string $type Type of action being performed 87 | * @param array $data Data passed to action 88 | * @throws MigrationException 89 | * @return bool 90 | */ 91 | public function beforeAction($migration, $type, $data) { 92 | $this->_migration = $migration; 93 | switch ($type) { 94 | case 'create_table': 95 | return $this->checkCreateTable($data['table']); 96 | case 'drop_table': 97 | return $this->checkDropTable($data['table']); 98 | case 'rename_table': 99 | return $this->checkCreateTable($data['new_name']) && $this->checkDropTable($data['old_name']); 100 | case 'add_field': 101 | return $this->checkAddField($data['table'], $data['field']); 102 | case 'drop_field': 103 | return $this->checkDropField($data['table'], $data['field']); 104 | case 'change_field': 105 | return true; 106 | case 'rename_field': 107 | return $this->checkAddField($data['table'], $data['new_name']) && $this->checkDropField($data['table'], $data['old_name']); 108 | case 'add_index': 109 | case 'drop_index': 110 | return true; 111 | default: 112 | throw new MigrationException($this->_migration, sprintf( 113 | __d('migrations', 'Migration action type (%s) is not one of valid actions type.'), $type 114 | ), E_USER_NOTICE); 115 | } 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /Lib/Migration/PrecheckCondition.php: -------------------------------------------------------------------------------- 1 | tableExists($table); 24 | } 25 | 26 | /** 27 | * Perform check before table create. 28 | * 29 | * @param string $table Table to look for 30 | * @return bool 31 | */ 32 | public function checkCreateTable($table) { 33 | return !$this->tableExists($table); 34 | } 35 | 36 | /** 37 | * Perform check before field drop. 38 | * 39 | * @param string $table Table to look for 40 | * @param string $field Field to look for 41 | * @return bool 42 | */ 43 | public function checkDropField($table, $field) { 44 | return $this->tableExists($table) && $this->fieldExists($table, $field); 45 | } 46 | 47 | /** 48 | * Perform check before field create. 49 | * 50 | * @param string $table Table to look for 51 | * @param string $field Field to look for 52 | * @return bool 53 | */ 54 | public function checkAddField($table, $field) { 55 | return $this->tableExists($table) && !$this->fieldExists($table, $field); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Lib/Migration/PrecheckException.php: -------------------------------------------------------------------------------- 1 | tableExists($table)) { 25 | throw new MigrationException($this->_migration, 26 | __d('migrations', 'Table "%s" does not exist in database.', $this->_migration->db->fullTableName($table, false, false)) 27 | ); 28 | } 29 | return true; 30 | } 31 | 32 | /** 33 | * Check if table already exists. 34 | * 35 | * @param string $table Table to look for 36 | * @throws MigrationException 37 | * @return bool 38 | */ 39 | public function checkCreateTable($table) { 40 | if ($this->tableExists($table)) { 41 | throw new MigrationException($this->_migration, 42 | __d('migrations', 'Table "%s" already exists in database.', $this->_migration->db->fullTableName($table, false, false)) 43 | ); 44 | } 45 | return true; 46 | } 47 | 48 | /** 49 | * Perform check before field drop. 50 | * 51 | * @param string $table Table to look in 52 | * @param string $field Field to look for 53 | * @throws MigrationException 54 | * @return bool 55 | */ 56 | public function checkDropField($table, $field) { 57 | if ($this->tableExists($table) && !$this->fieldExists($table, $field)) { 58 | throw new MigrationException($this->_migration, sprintf( 59 | __d('migrations', 'Field "%s" does not exist in "%s".'), $field, $table 60 | )); 61 | } 62 | return true; 63 | } 64 | 65 | /** 66 | * Perform check before field create. 67 | * 68 | * @param string $table Table to look in 69 | * @param string $field Field to look for 70 | * @throws MigrationException 71 | * @return bool 72 | */ 73 | public function checkAddField($table, $field) { 74 | if ($this->tableExists($table) && $this->fieldExists($table, $field)) { 75 | throw new MigrationException($this->_migration, sprintf( 76 | __d('migrations', 'Field "%s" already exists in "%s".'), $field, $table 77 | )); 78 | } 79 | return true; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Lib/MigrationVersion.php: -------------------------------------------------------------------------------- 1 | connection = $options['connection']; 102 | } 103 | 104 | if (!empty($options['precheck'])) { 105 | $this->precheck = $options['precheck']; 106 | } 107 | 108 | if (!empty($options['migrationConnection'])) { 109 | $this->migrationConnection = $options['migrationConnection']; 110 | } 111 | 112 | if (!empty($options['skip'])) { 113 | $this->skip = $options['skip']; 114 | } 115 | 116 | if (!empty($options['jumpTo'])) { 117 | $this->jumpTo = $options['jumpTo']; 118 | } 119 | 120 | if (!isset($options['dry'])) { 121 | $options['dry'] = false; 122 | } 123 | 124 | $this->dry = $options['dry']; 125 | $this->initVersion(); 126 | 127 | if (!isset($options['autoinit']) || $options['autoinit'] !== false) { 128 | $this->_initMigrations(); 129 | } 130 | } 131 | 132 | /** 133 | * Get a new SchemaMigration instance 134 | * 135 | * @return void 136 | */ 137 | public function initVersion() { 138 | $this->Version = ClassRegistry::init(array( 139 | 'class' => 'Migrations.SchemaMigration', 140 | 'ds' => $this->connection 141 | )); 142 | $this->Version->setDataSource($this->connection); 143 | } 144 | 145 | /** 146 | * Get last version for given type 147 | * 148 | * @param string $type Can be 'app' or a plugin name 149 | * @return int Last version migrated 150 | */ 151 | public function getVersion($type) { 152 | $mapping = $this->getMapping($type); 153 | if ($mapping !== false) { 154 | krsort($mapping); 155 | 156 | foreach ($mapping as $version => $info) { 157 | if ($info['migrated'] !== null) { 158 | return $version; 159 | } 160 | } 161 | } 162 | return 0; 163 | } 164 | 165 | /** 166 | * Set current version for given type 167 | * 168 | * @param int $version Current version 169 | * @param string $type Can be 'app' or a plugin name 170 | * @param bool $migrated If true, will add the record to the database 171 | * If false, will remove the record from the database 172 | * @return bool 173 | */ 174 | public function setVersion($version, $type, $migrated = true) { 175 | if ($this->dry) { 176 | return true; 177 | } 178 | 179 | if ($type !== 'app') { 180 | $type = Inflector::camelize($type); 181 | } 182 | $mapping = $this->getMapping($type); 183 | 184 | // For BC, 002 was not applied yet. 185 | $bc = ($this->Version->schema('class') === null); 186 | $field = $bc ? 'version' : 'class'; 187 | $value = $bc ? $version : $mapping[$version]['class']; 188 | if ($migrated) { 189 | $this->Version->create(); 190 | $result = $this->Version->save(array( 191 | $field => $value, 'type' => $type 192 | )); 193 | } else { 194 | $conditions = array( 195 | $this->Version->alias . '.' . $field => $value, 196 | $this->Version->alias . '.type' => $type 197 | ); 198 | $result = $this->Version->deleteAll($conditions); 199 | } 200 | 201 | // Clear mapping cache 202 | unset($this->_mapping[$type]); 203 | 204 | return $result; 205 | } 206 | 207 | /** 208 | * Get mapping for the given type 209 | * 210 | * @param string $type Can be 'app' or a plugin name 211 | * @param bool $cache Whether to return the cached value or not 212 | * @return mixed False in case of no file found or empty mapping, array with mapping 213 | */ 214 | public function getMapping($type, $cache = true) { 215 | if ($type !== 'app') { 216 | $type = Inflector::camelize($type); 217 | } 218 | 219 | if ($cache && !empty($this->_mapping[$type])) { 220 | return $this->_mapping[$type]; 221 | } 222 | $mapping = $this->_enumerateMigrations($type); 223 | if (empty($mapping)) { 224 | return false; 225 | } 226 | 227 | $migrated = $this->Version->find('all', array( 228 | 'conditions' => array( 229 | 'OR' => array( 230 | array($this->Version->alias . '.type' => Inflector::underscore($type)), 231 | array($this->Version->alias . '.type' => $type), 232 | ) 233 | ), 234 | 'recursive' => -1, 235 | )); 236 | 237 | // For BC, 002 was not applied yet. 238 | $bc = ($this->Version->schema('class') === null); 239 | if ($bc) { 240 | $migrated = Hash::combine($migrated, '{n}.' . $this->Version->alias . '.version', '{n}.' . $this->Version->alias . '.created'); 241 | } else { 242 | $migrated = Hash::combine($migrated, '{n}.' . $this->Version->alias . '.class', '{n}.' . $this->Version->alias . '.created'); 243 | } 244 | 245 | $bcMapping = array(); 246 | if ($type === 'Migrations') { 247 | $bcMapping = array( 248 | 'InitMigrations' => 'M4af6e0f0a1284147a0b100ca58157726', 249 | 'ConvertVersionToClassNames' => 'M4ec50d1f7a284842b1b770fdcbdd56cb', 250 | ); 251 | } 252 | 253 | ksort($mapping); 254 | foreach ($mapping as $version => $migration) { 255 | list($name, $class) = each($migration); 256 | 257 | $mapping[$version] = array( 258 | 'version' => $version, 'name' => $name, 'class' => $class, 259 | 'type' => $type, 'migrated' => null 260 | ); 261 | 262 | if ($bc) { 263 | if (isset($migrated[$version])) { 264 | $mapping[$version]['migrated'] = $migrated[$version]; 265 | } 266 | } else { 267 | if (isset($migrated[$class])) { 268 | $mapping[$version]['migrated'] = $migrated[$class]; 269 | } elseif (isset($bcMapping[$class]) && !empty($migrated[$bcMapping[$class]])) { 270 | $mapping[$version]['migrated'] = $migrated[$bcMapping[$class]]; 271 | } 272 | } 273 | } 274 | 275 | $this->_mapping[$type] = $mapping; 276 | return $mapping; 277 | } 278 | 279 | /** 280 | * Load and make a instance of the migration 281 | * 282 | * @param string $name File name where migration resides 283 | * @param string $class Migration class name 284 | * @param string $type Can be 'app' or a plugin name 285 | * @param array $options Extra options to send to CakeMigration class 286 | * @return bool|CakeMigration False in case of no file found, instance of the migration 287 | * @throws MigrationVersionException 288 | */ 289 | public function getMigration($name, $class, $type, $options = array()) { 290 | if (!class_exists($class) && (!$this->_loadFile($name, $type) || !class_exists($class))) { 291 | throw new MigrationVersionException(sprintf( 292 | __d('migrations', 'Class `%1$s` not found on file `%2$s` for %3$s.'), 293 | $class, $name . '.php', (($type === 'app') ? 'Application' : Inflector::camelize($type) . ' Plugin') 294 | )); 295 | } 296 | 297 | $defaults = array( 298 | 'precheck' => $this->precheck); 299 | 300 | if (!empty($this->migrationConnection)) { 301 | $defaults['connection'] = $this->migrationConnection; 302 | } 303 | 304 | $options = array_merge($defaults, $options); 305 | return new $class($options); 306 | } 307 | 308 | /** 309 | * Run the migrations 310 | * 311 | * Options: 312 | * - `direction` - Direction to run 313 | * - `version` - Until what version want migrate to 314 | * 315 | * @param array $options An array with options. 316 | * @return bool 317 | * @throws Exception 318 | */ 319 | public function run($options) { 320 | $targetVersion = $latestVersion = $this->getVersion($options['type']); 321 | $mapping = $this->getMapping($options['type'], false); 322 | 323 | $direction = 'up'; 324 | if (!empty($options['direction'])) { 325 | $direction = $options['direction']; 326 | } 327 | 328 | if (isset($options['version'])) { 329 | $targetVersion = $options['version']; 330 | $direction = ($targetVersion < $latestVersion) ? 'down' : $direction; 331 | if (isset($mapping[$targetVersion]) && empty($mapping[$targetVersion]['migrated'])) { 332 | $direction = 'up'; 333 | } 334 | } 335 | 336 | if (!empty($this->skip) && is_string($this->skip)) { 337 | $this->skip = explode(',', trim($this->skip)); 338 | } 339 | 340 | if ($direction === 'up' && !isset($options['version'])) { 341 | $keys = array_keys($mapping); 342 | $flipped = array_flip($keys); 343 | $next = $flipped[$targetVersion + 1]; 344 | $targetVersion = $keys[$next]; 345 | } 346 | 347 | if ($direction === 'down') { 348 | krsort($mapping); 349 | } 350 | 351 | 352 | foreach ($mapping as $version => $info) { 353 | if (($direction === 'up' && $version > $targetVersion) 354 | || ($direction === 'down' && $version < $targetVersion)) { 355 | break; 356 | } elseif (($direction === 'up' && $info['migrated'] === null) 357 | || ($direction === 'down' && $info['migrated'] !== null)) { 358 | $type = $info['type']; 359 | 360 | $jumpVersion = $this->getVersionByName($mapping); 361 | if ($version < $jumpVersion) { 362 | $this->jump($version, $type); 363 | continue; 364 | } 365 | 366 | if (in_array($mapping[$version]['name'], $this->skip)) { 367 | $this->setVersion($version, $type); 368 | continue; 369 | } 370 | 371 | $migration = $this->getMigration($info['name'], $info['class'], $type, $options); 372 | $migration->Version = $this; 373 | $migration->info = $info; 374 | 375 | try { 376 | $result = $migration->run($direction, $options); 377 | $this->log[$info['name']] = $migration->getQueryLog(); 378 | } catch (MigrationException $migrationException){ 379 | throw $migrationException; // throw to MigrationShell::_execute 380 | } catch (Exception $exception) { 381 | $mapping = $this->getMapping($options['type']); 382 | if (isset($mapping[$latestVersion]['version'])) { 383 | $latestVersionName = '#' . 384 | sprintf("%'.03d", $mapping[$latestVersion]['version']) . ' ' . 385 | $mapping[$latestVersion]['name']; 386 | } else { 387 | $latestVersionName = null; 388 | } 389 | $errorMessage = __d('migrations', "There was an error during a migration. \n The error was: '%s' \n You must resolve the issue manually and try again.", $exception->getMessage(), $latestVersionName); 390 | return $errorMessage; 391 | } 392 | 393 | $this->setVersion($version, $type, ($direction === 'up')); 394 | } 395 | } 396 | 397 | if (isset($result)) { 398 | return $result; 399 | } 400 | return true; 401 | } 402 | 403 | /** 404 | * Jump to a certain migration and mark the preceding migrations as executed. 405 | * 406 | * @param array $version Version of a migration to jump to. 407 | * @param array $type migration type 408 | * @return void 409 | */ 410 | public function jump($version, $type) { 411 | $this->setVersion($version, $type); 412 | } 413 | 414 | /** 415 | * Will return a version based in the migration name 416 | * 417 | * @param array $mapping mapping of all migrations. 418 | * @return bool|string 419 | */ 420 | public function getVersionByName($mapping) { 421 | $version = false; 422 | foreach ($mapping as $key => $info) { 423 | if ($mapping[$key]['name'] == $this->jumpTo) { 424 | $version = $key; 425 | } 426 | } 427 | 428 | return $version; 429 | } 430 | 431 | /** 432 | * Initialize the migrations schema and keep it up-to-date 433 | * 434 | * @return void 435 | */ 436 | protected function _initMigrations() { 437 | /** @var DboSource $db */ 438 | $db = ConnectionManager::getDataSource($this->connection); 439 | if (!in_array($db->fullTableName('schema_migrations', false, false), $db->listSources())) { 440 | $map = $this->_enumerateMigrations('migrations'); 441 | 442 | list($name, $class) = each($map[1]); 443 | $migration = $this->getMigration($name, $class, 'Migrations'); 444 | $migration->run('up'); 445 | $this->setVersion(1, 'Migrations'); 446 | } 447 | 448 | $mapping = $this->getMapping('Migrations'); 449 | if (count($mapping) > 1) { 450 | end($mapping); 451 | $this->run(array( 452 | 'version' => key($mapping), 453 | 'type' => 'Migrations' 454 | )); 455 | } 456 | } 457 | 458 | /** 459 | * Load a file based on name and type 460 | * 461 | * @param string $name File name to be loaded 462 | * @param string $type Can be 'app' or a plugin name 463 | * @return mixed Throw an exception in case of no file found, array with mapping 464 | * @throws MigrationVersionException 465 | */ 466 | protected function _loadFile($name, $type) { 467 | $path = APP . 'Config' . DS . 'Migration' . DS; 468 | if ($type !== 'app') { 469 | $path = CakePlugin::path(Inflector::camelize($type)) . 'Config' . DS . 'Migration' . DS; 470 | } 471 | 472 | if (!file_exists($path . $name . '.php')) { 473 | throw new MigrationVersionException(sprintf( 474 | __d('migrations', 'File `%1$s` not found in the %2$s.'), 475 | $name . '.php', (($type === 'app') ? 'Application' : Inflector::camelize($type) . ' Plugin') 476 | )); 477 | } 478 | 479 | include $path . $name . '.php'; 480 | return true; 481 | } 482 | 483 | /** 484 | * Returns a map of all available migrations for a type (app or plugin) 485 | * 486 | * @param string $type Can be 'app' or a plugin name 487 | * @return array containing a list of migration versions ordered by filename 488 | */ 489 | protected function _enumerateMigrations($type) { 490 | $map = $this->_enumerateNewMigrations($type); 491 | $oldMap = $this->_enumerateOldMigrations($type); 492 | foreach ($oldMap as $k => $v) { 493 | $map[$k] = $oldMap[$k]; 494 | } 495 | return $map; 496 | } 497 | 498 | /** 499 | * Returns a map of all available migrations for a type (app or plugin) using inflection 500 | * 501 | * @param string $type Can be 'app' or a plugin name 502 | * @return array containing a list of migration versions ordered by filename 503 | */ 504 | protected function _enumerateNewMigrations($type) { 505 | $mapping = array(); 506 | $path = APP . 'Config' . DS . 'Migration' . DS; 507 | if ($type !== 'app') { 508 | $path = CakePlugin::path(Inflector::camelize($type)) . 'Config' . DS . 'Migration' . DS; 509 | } 510 | if (!file_exists($path)) { 511 | return $mapping; 512 | } 513 | $folder = new Folder($path); 514 | foreach ($folder->find('.*?\.php', true) as $file) { 515 | $parts = explode('_', $file); 516 | $version = array_shift($parts); 517 | $className = implode('_', $parts); 518 | if ($version > 0 && strlen($className) > 0) { 519 | $mapping[(int)$version] = array(substr($file, 0, -4) => Inflector::camelize(substr($className, 0, -4))); 520 | } 521 | } 522 | return $mapping; 523 | } 524 | 525 | /** 526 | * Returns a map of all available migrations for a type (app or plugin) using regular expressions 527 | * 528 | * @param string $type Can be 'app' or a plugin name 529 | * @return array containing a list of migration versions ordered by filename 530 | */ 531 | protected function _enumerateOldMigrations($type) { 532 | $mapping = array(); 533 | $path = APP . 'Config' . DS . 'Migration' . DS; 534 | if ($type !== 'app') { 535 | $path = CakePlugin::path(Inflector::camelize($type)) . 'Config' . DS . 'Migration' . DS; 536 | } 537 | if (!file_exists($path)) { 538 | return $mapping; 539 | } 540 | $folder = new Folder($path); 541 | foreach ($folder->find('.*?\.php', true) as $file) { 542 | $parts = explode('_', $file); 543 | $version = array_shift($parts); 544 | $className = implode('_', $parts); 545 | if ($version > 0 && strlen($className) > 0) { 546 | $contents = file_get_contents($path . $file); 547 | if (preg_match("/class\s([\w]+)\sextends/", $contents, $matches)) { 548 | $mapping[(int)$version] = array(substr($file, 0, -4) => $matches[1]); 549 | } 550 | } 551 | } 552 | return $mapping; 553 | } 554 | } 555 | 556 | /** 557 | * Usually used when migrations file/class or map files are not found 558 | */ 559 | class MigrationVersionException extends Exception { 560 | 561 | } 562 | 563 | -------------------------------------------------------------------------------- /Lib/Panel/MigrationsPanel.php: -------------------------------------------------------------------------------- 1 | array( 22 | * 'panels' => array('Migrations.migrations') 23 | * )); 24 | * @@@ 25 | */ 26 | class MigrationsPanel extends DebugPanel { 27 | 28 | /** 29 | * Title 30 | * 31 | * @var string 32 | */ 33 | public $title = 'Migrations'; 34 | 35 | /** 36 | * Element name 37 | * 38 | * @var string 39 | */ 40 | public $elementName = 'migrations_panel'; 41 | 42 | /** 43 | * Plugin name 44 | * 45 | * @var string 46 | */ 47 | public $plugin = 'migrations'; 48 | 49 | /** 50 | * Output buffer 51 | * 52 | * @var string 53 | */ 54 | public $output = ''; 55 | 56 | /** 57 | * BeforeRender Callback 58 | * 59 | * @param Controller $controller Current controller 60 | * @return array 61 | */ 62 | public function beforeRender(Controller $controller) { 63 | $v = new MigrationVersion(); 64 | $map = $migrations = array(); 65 | 66 | $migrations = Hash::merge(array('app'), CakePlugin::loaded()); 67 | foreach ($migrations as $plugin) { 68 | try { 69 | $map[$plugin] = array( 70 | 'map' => $v->getMapping($plugin), 71 | 'current' => $v->getVersion($plugin) 72 | ); 73 | } catch (MigrationVersionException $e) { 74 | // Skip if we get an error. 75 | } 76 | } 77 | return $map; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Locale/deu/LC_MESSAGES/migrations.po: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: CakePHP Migrations Plugin\n" 14 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 15 | "PO-Revision-Date: 2015-03-09 17:41-0000\n" 16 | "Last-Translator: Chris Burke \n" 17 | "Language-Team: Cake Development Corporation \n" 18 | "Language: de_DE\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=(n!=1);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.7.4\n" 25 | 26 | #: Config/Migration/002_convert_version_to_class_names.php:56 27 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 28 | msgstr "Leider kann ich nicht downgraden. Warum wollen Sie dies überhaupt tun?" 29 | 30 | #: Console/Command/MigrationShell.php:75 31 | msgid "Cake Migration Shell" 32 | msgstr "Cake Migrations Shell" 33 | 34 | #: Console/Command/MigrationShell.php:108 35 | #, fuzzy 36 | msgid "Creating table \":table\"." 37 | msgstr "Erstelle Tabelle \":table\"." 38 | 39 | #: Console/Command/MigrationShell.php:109 40 | #, fuzzy 41 | msgid "Dropping table \":table\"." 42 | msgstr "Verwerfe Tabelle \":table\"." 43 | 44 | #: Console/Command/MigrationShell.php:110 45 | #, fuzzy 46 | msgid "Renaming table \":old_name\" to \":new_name\"." 47 | msgstr "Benenne tabelle \":old_name\" um zu \":new_name\"." 48 | 49 | #: Console/Command/MigrationShell.php:111 50 | #, fuzzy 51 | msgid "Adding field \":field\" to table \":table\"." 52 | msgstr "Füge Feld \":field\" zu \":table hinzu\"." 53 | 54 | #: Console/Command/MigrationShell.php:112 55 | #, fuzzy 56 | msgid "Dropping field \":field\" from table \":table\"." 57 | msgstr "Verwerfe Feld \":field\" in Tabelle \":table\"." 58 | 59 | #: Console/Command/MigrationShell.php:113 60 | #, fuzzy 61 | msgid "Changing field \":field\" from table \":table\"." 62 | msgstr "Ändere Feld \":field\" in Tabelle \":table\"." 63 | 64 | #: Console/Command/MigrationShell.php:114 65 | #, fuzzy 66 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 67 | msgstr "Benenne Feld \":old_name\" um zu \":new_name\" in Tabelle \":table\"." 68 | 69 | #: Console/Command/MigrationShell.php:115 70 | #, fuzzy 71 | msgid "Adding index \":index\" to table \":table\"." 72 | msgstr "Füge index \":index\" zu \":table\" hinzu." 73 | 74 | #: Console/Command/MigrationShell.php:116 75 | #, fuzzy 76 | msgid "Dropping index \":index\" from table \":table\"." 77 | msgstr "Verwerfe index \":index\" von \":table\"." 78 | 79 | #: Console/Command/MigrationShell.php:195 80 | msgid "No migrations available." 81 | msgstr "Keine Migrationen verfügbar." 82 | 83 | #: Console/Command/MigrationShell.php:225 84 | msgid "Running migrations:" 85 | msgstr "Führe Migrationen aus:" 86 | 87 | #: Console/Command/MigrationShell.php:237 88 | msgid "Migration will run dry, no database changes will be made" 89 | msgstr "" 90 | "Migration führt einen Trockentest durch. Es werden keine Änderungen an der " 91 | "Datenbank vorgenommen." 92 | 93 | #: Console/Command/MigrationShell.php:246 94 | msgid "All migrations have completed." 95 | msgstr "Alle Migrationen wurden durchgeführt." 96 | 97 | #: Console/Command/MigrationShell.php:264 98 | msgid "An error occurred when processing the migration:" 99 | msgstr "Es trat ein Fehler während der Durchführung der Migration auf:" 100 | 101 | #: Console/Command/MigrationShell.php:265 102 | msgid "Migration: %s" 103 | msgstr "Migration: %s" 104 | 105 | #: Console/Command/MigrationShell.php:266 106 | msgid "Error: %s" 107 | msgstr "Error: %s" 108 | 109 | #: Console/Command/MigrationShell.php:270 110 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 111 | msgstr "Wollen Sie die Migration als erfolgreich markieren? [y]Ja oder [a]bbrechen" 112 | 113 | #: Console/Command/MigrationShell.php:326;346;373 114 | msgid "Not a valid migration version." 115 | msgstr "Dies ist keine gültige Migrationsversion" 116 | 117 | #: Console/Command/MigrationShell.php:354 118 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 119 | msgstr "" 120 | "Bitte wählen Sie zu welcher Version sie migrieren wollen. [q] um zu beenden oder " 121 | "[c] zum aufräumen." 122 | 123 | #: Console/Command/MigrationShell.php:400 124 | msgid "Do you want to compare the schema.php file to the database?" 125 | msgstr "Möchten Sie die schema.php Datei mit der Datenbank vergleichen?" 126 | 127 | #: Console/Command/MigrationShell.php:405 128 | msgid "No database changes detected." 129 | msgstr "Keine Datenbankänderungen erkannt." 130 | 131 | #: Console/Command/MigrationShell.php:411 132 | msgid "Do you want to generate a dump from the current database?" 133 | msgstr "Möchten Sie einen Dump von der aktuellen Datenbank generieren?" 134 | 135 | #: Console/Command/MigrationShell.php:422 136 | #, fuzzy 137 | msgid "Do you want to update the schema.php file?" 138 | msgstr "Möchten Sie die schema.php Datei aktualisieren?" 139 | 140 | #: Console/Command/MigrationShell.php:439 141 | msgid "Comparing schema.php to the database..." 142 | msgstr "Vergleiche schema.php mit der Datenbank..." 143 | 144 | #: Console/Command/MigrationShell.php:459 145 | #, fuzzy 146 | msgid "Generating migration from commandline arguments..." 147 | msgstr "Generiere Migration anhand der Kommandozeilenparameter..." 148 | 149 | #: Console/Command/MigrationShell.php:487;842 150 | msgid "Invalid argument" 151 | msgstr "Üngültiger Parameter" 152 | 153 | #: Console/Command/MigrationShell.php:487 154 | #, fuzzy 155 | msgid "" 156 | "Migration name (%s) is invalid. It cannot be used to generate a migration from " 157 | "the CLI." 158 | msgstr "" 159 | "Der Migrations Name (%s) is ungültig. Er darf nur alphanumerische Zeichen " 160 | "enthalten." 161 | 162 | #: Console/Command/MigrationShell.php:515 163 | msgid "Generating dump from the current database..." 164 | msgstr "Generiere Dump von aktueller Datenbank..." 165 | 166 | #: Console/Command/MigrationShell.php:537 167 | #, fuzzy 168 | msgid "Do you want to preview the file before generation?" 169 | msgstr "Möchten Sie die schema.php Datei mit der Datenbank vergleichen?" 170 | 171 | #: Console/Command/MigrationShell.php:547 172 | msgid "Generating Migration..." 173 | msgstr "Generiere Migration..." 174 | 175 | #: Console/Command/MigrationShell.php:556 176 | msgid "Done." 177 | msgstr "Fertig." 178 | 179 | #: Console/Command/MigrationShell.php:566 180 | msgid "Please enter the descriptive name of the migration to generate:" 181 | msgstr "" 182 | "Bitte geben Sie einen deskriptiven Namen für die zu generierende Migration ein." 183 | 184 | #: Console/Command/MigrationShell.php:569 185 | #, fuzzy 186 | msgid "" 187 | "Migration name (%s) is invalid. It must only contain alphanumeric characters and " 188 | "start with a letter." 189 | msgstr "" 190 | "Der Migrations Name (%s) is ungültig. Er darf nur alphanumerische Zeichen " 191 | "enthalten." 192 | 193 | #: Console/Command/MigrationShell.php:572 194 | #, fuzzy 195 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 196 | msgstr "" 197 | "Der Migrations Name (%s) is ungültig. Er darf nur alphanumerische Zeichen " 198 | "enthalten." 199 | 200 | #: Console/Command/MigrationShell.php:608 201 | msgid "Current version:" 202 | msgstr "Aktuelle Version:" 203 | 204 | #: Console/Command/MigrationShell.php:613 205 | msgid "None applied." 206 | msgstr "Nicht angewandt." 207 | 208 | #: Console/Command/MigrationShell.php:616 209 | msgid "Latest version:" 210 | msgstr "Letzte Version:" 211 | 212 | #: Console/Command/MigrationShell.php:640 213 | msgid "Current migration version:" 214 | msgstr "Aktuelle Migrations Version:" 215 | 216 | #: Console/Command/MigrationShell.php:645 217 | msgid "Available migrations:" 218 | msgstr "Verfügbare Migrationen:" 219 | 220 | #: Console/Command/MigrationShell.php:651 221 | msgid "applied" 222 | msgstr "angewandt" 223 | 224 | #: Console/Command/MigrationShell.php:653 225 | msgid "not applied" 226 | msgstr "nicht angewandt" 227 | 228 | #: Console/Command/MigrationShell.php:842 229 | msgid "Missing required argument 'name' for migration" 230 | msgstr "Fehlende erforderliche Argument 'name' für die Migration" 231 | 232 | #: Lib/CakeMigration.php:205 233 | msgid "Migration precheck class (%s) could not be loaded." 234 | msgstr "Migration Vorprüfung Klasse (%s) konnte nicht geladen werden." 235 | 236 | #: Lib/CakeMigration.php:213 237 | #, fuzzy 238 | msgid "Migration precheck class (%s) is not a valid precheck class." 239 | msgstr "Die Migrationsrichtung (%s) ist keine gültige Richtung." 240 | 241 | #: Lib/CakeMigration.php:229 242 | msgid "Migration direction (%s) is not one of valid directions." 243 | msgstr "Die Migrationsrichtung (%s) ist keine gültige Richtung." 244 | 245 | #: Lib/CakeMigration.php:295 Lib/Migration/PrecheckBase.php:113 246 | msgid "Migration action type (%s) is not one of valid actions type." 247 | msgstr "Der Aktionstyp (%s) der Migration ist kein gültiger Aktionstyp." 248 | 249 | #: Lib/CakeMigration.php:343;373;401;489;529 250 | msgid "SQL Error: %s" 251 | msgstr "SQL Error: %s" 252 | 253 | #: Lib/CakeMigration.php:567 254 | msgid "Interrupted when running \"%s\" callback." 255 | msgstr "Unterbrechung" 256 | 257 | #: Lib/MigrationVersion.php:273 258 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 259 | msgstr "Klasse `%1$s` nicht gefunden in Datei `%2$s` für %3$s." 260 | 261 | #: Lib/MigrationVersion.php:410 262 | msgid "File `%1$s` not found in the %2$s." 263 | msgstr "Datei `%1$s` nicht gefunden in %2$s." 264 | 265 | #: Lib/Migration/PrecheckException.php:26 266 | msgid "Table \"%s\" does not exist in database." 267 | msgstr "Die Tabelle \"%s\" existiert nicht in der Datenbank." 268 | 269 | #: Lib/Migration/PrecheckException.php:42 270 | msgid "Table \"%s\" already exists in database." 271 | msgstr "Die Tabelle \"%s\" existiert bereits in der Datenbank." 272 | 273 | #: Lib/Migration/PrecheckException.php:59 274 | msgid "Field \"%s\" does not exist in \"%s\"." 275 | msgstr "Das Feld \"%s\" existiert nicht in der Tabelle \"%s\" ." 276 | 277 | #: Lib/Migration/PrecheckException.php:76 278 | msgid "Field \"%s\" already exists in \"%s\"." 279 | msgstr "Das Feld \"%s\" existiert bereits in der Tabelle \"%s\" ." 280 | 281 | #: View/Elements/migrations_panel.ctp:12 282 | #, fuzzy 283 | msgid "Migration Status" 284 | msgstr "Migrationsstatus" 285 | -------------------------------------------------------------------------------- /Locale/fre/LC_MESSAGES/migrations.po: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: CakePHP Migrations Plugin\n" 14 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 15 | "PO-Revision-Date: \n" 16 | "Last-Translator: Chris Burke \n" 17 | "Language-Team: Cake Development Corporation \n" 18 | "Language: fr\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=(n!=1);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.7.4\n" 25 | 26 | #: Config/Migration/002_convert_version_to_class_names.php:56 27 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 28 | msgstr "" 29 | "Désolé, je ne peux pas rétrograder. Pourquoi voudriez-vous que de toute façon?" 30 | 31 | #: Console/Command/MigrationShell.php:75 32 | msgid "Cake Migration Shell" 33 | msgstr "Cake Migration Shell" 34 | 35 | #: Console/Command/MigrationShell.php:108 36 | #, fuzzy 37 | msgid "Creating table \":table\"." 38 | msgstr "Création de la table :table." 39 | 40 | #: Console/Command/MigrationShell.php:109 41 | #, fuzzy 42 | msgid "Dropping table \":table\"." 43 | msgstr "Suppression de la table :table." 44 | 45 | #: Console/Command/MigrationShell.php:110 46 | #, fuzzy 47 | msgid "Renaming table \":old_name\" to \":new_name\"." 48 | msgstr "Renommage de la table :old_name en :new_name." 49 | 50 | #: Console/Command/MigrationShell.php:111 51 | #, fuzzy 52 | msgid "Adding field \":field\" to table \":table\"." 53 | msgstr "Ajout du champ :field à :table." 54 | 55 | #: Console/Command/MigrationShell.php:112 56 | #, fuzzy 57 | msgid "Dropping field \":field\" from table \":table\"." 58 | msgstr "Suppression du champ :field de :table." 59 | 60 | #: Console/Command/MigrationShell.php:113 61 | #, fuzzy 62 | msgid "Changing field \":field\" from table \":table\"." 63 | msgstr "Modification du champ :field de :table." 64 | 65 | #: Console/Command/MigrationShell.php:114 66 | #, fuzzy 67 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 68 | msgstr "Renommage du champ :old_name en :new_name dans :table." 69 | 70 | #: Console/Command/MigrationShell.php:115 71 | #, fuzzy 72 | msgid "Adding index \":index\" to table \":table\"." 73 | msgstr "Ajout de l'index :index à :table." 74 | 75 | #: Console/Command/MigrationShell.php:116 76 | #, fuzzy 77 | msgid "Dropping index \":index\" from table \":table\"." 78 | msgstr "Suppression de l'index :index de :table." 79 | 80 | #: Console/Command/MigrationShell.php:195 81 | msgid "No migrations available." 82 | msgstr "Aucune migration disponible." 83 | 84 | #: Console/Command/MigrationShell.php:225 85 | msgid "Running migrations:" 86 | msgstr "Exécution des migrations :" 87 | 88 | #: Console/Command/MigrationShell.php:237 89 | msgid "Migration will run dry, no database changes will be made" 90 | msgstr "" 91 | "Migration va fonctionner à sec, pas de changement de base de données seront " 92 | "effectués" 93 | 94 | #: Console/Command/MigrationShell.php:246 95 | msgid "All migrations have completed." 96 | msgstr "Toutes les migrations ont été exécutées." 97 | 98 | #: Console/Command/MigrationShell.php:264 99 | msgid "An error occurred when processing the migration:" 100 | msgstr "Une erreur est apparue lors de l'exécution de la migration :" 101 | 102 | #: Console/Command/MigrationShell.php:265 103 | msgid "Migration: %s" 104 | msgstr "Migration : %s" 105 | 106 | #: Console/Command/MigrationShell.php:266 107 | msgid "Error: %s" 108 | msgstr "Erreur : %s" 109 | 110 | #: Console/Command/MigrationShell.php:270 111 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 112 | msgstr "Voulez-vous marquer la migration réussie ? [y] oui ou [a]vorter." 113 | 114 | #: Console/Command/MigrationShell.php:326;346;373 115 | msgid "Not a valid migration version." 116 | msgstr "Version de migration invalide." 117 | 118 | #: Console/Command/MigrationShell.php:354 119 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 120 | msgstr "" 121 | "Veuillez choisir la version vers laquelle vous souhaitez migrer. [q]uitter ou [c] " 122 | "pour nettoyer" 123 | 124 | #: Console/Command/MigrationShell.php:400 125 | msgid "Do you want to compare the schema.php file to the database?" 126 | msgstr "Voulez vous comparer le fichier schema.php à la base de données ?" 127 | 128 | #: Console/Command/MigrationShell.php:405 129 | msgid "No database changes detected." 130 | msgstr "Aucun changement de base de données détectées." 131 | 132 | #: Console/Command/MigrationShell.php:411 133 | msgid "Do you want to generate a dump from the current database?" 134 | msgstr "Voulez vous générer un dump de votre base de données actuelle ?" 135 | 136 | #: Console/Command/MigrationShell.php:422 137 | #, fuzzy 138 | msgid "Do you want to update the schema.php file?" 139 | msgstr "Voulez vous comparer le fichier schema.php à la base de données ?" 140 | 141 | #: Console/Command/MigrationShell.php:439 142 | msgid "Comparing schema.php to the database..." 143 | msgstr "Comparaison de schema.php à la base de données ..." 144 | 145 | #: Console/Command/MigrationShell.php:459 146 | #, fuzzy 147 | msgid "Generating migration from commandline arguments..." 148 | msgstr "Génération de la Migration ..." 149 | 150 | #: Console/Command/MigrationShell.php:487;842 151 | msgid "Invalid argument" 152 | msgstr "Invalid argument" 153 | 154 | #: Console/Command/MigrationShell.php:487 155 | #, fuzzy 156 | msgid "" 157 | "Migration name (%s) is invalid. It cannot be used to generate a migration from " 158 | "the CLI." 159 | msgstr "" 160 | "Le nom de la Migration (%s) est invalide. Il ne doit contenir que des caractères " 161 | "alphanumériques." 162 | 163 | #: Console/Command/MigrationShell.php:515 164 | msgid "Generating dump from the current database..." 165 | msgstr "Génération d'un dump de la base de données actuelle ..." 166 | 167 | #: Console/Command/MigrationShell.php:537 168 | #, fuzzy 169 | msgid "Do you want to preview the file before generation?" 170 | msgstr "Voulez vous comparer le fichier schema.php à la base de données ?" 171 | 172 | #: Console/Command/MigrationShell.php:547 173 | msgid "Generating Migration..." 174 | msgstr "Génération de la Migration ..." 175 | 176 | #: Console/Command/MigrationShell.php:556 177 | msgid "Done." 178 | msgstr "Exécuté." 179 | 180 | #: Console/Command/MigrationShell.php:566 181 | msgid "Please enter the descriptive name of the migration to generate:" 182 | msgstr "Veuillez entrer le nom décrivant la migration à générer :" 183 | 184 | #: Console/Command/MigrationShell.php:569 185 | #, fuzzy 186 | msgid "" 187 | "Migration name (%s) is invalid. It must only contain alphanumeric characters and " 188 | "start with a letter." 189 | msgstr "" 190 | "Le nom de la Migration (%s) est invalide. Il ne doit contenir que des caractères " 191 | "alphanumériques." 192 | 193 | #: Console/Command/MigrationShell.php:572 194 | #, fuzzy 195 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 196 | msgstr "" 197 | "Le nom de la Migration (%s) est invalide. Il ne doit contenir que des caractères " 198 | "alphanumériques." 199 | 200 | #: Console/Command/MigrationShell.php:608 201 | msgid "Current version:" 202 | msgstr "Version actuelle :" 203 | 204 | #: Console/Command/MigrationShell.php:613 205 | msgid "None applied." 206 | msgstr "Aucune appliquée." 207 | 208 | #: Console/Command/MigrationShell.php:616 209 | msgid "Latest version:" 210 | msgstr "Dernière version :" 211 | 212 | #: Console/Command/MigrationShell.php:640 213 | msgid "Current migration version:" 214 | msgstr "Version actuelle de la Migration :" 215 | 216 | #: Console/Command/MigrationShell.php:645 217 | msgid "Available migrations:" 218 | msgstr "Migrations disponibles :" 219 | 220 | #: Console/Command/MigrationShell.php:651 221 | msgid "applied" 222 | msgstr "appliquée" 223 | 224 | #: Console/Command/MigrationShell.php:653 225 | msgid "not applied" 226 | msgstr "non appliquée" 227 | 228 | #: Console/Command/MigrationShell.php:842 229 | msgid "Missing required argument 'name' for migration" 230 | msgstr "Nécessaire argument 'nom' de la migration manquant" 231 | 232 | #: Lib/CakeMigration.php:205 233 | msgid "Migration precheck class (%s) could not be loaded." 234 | msgstr "Migration classe de précontrôle (%s) n'a pas pu être chargé." 235 | 236 | #: Lib/CakeMigration.php:213 237 | #, fuzzy 238 | msgid "Migration precheck class (%s) is not a valid precheck class." 239 | msgstr "" 240 | "La direction de la Migration (%s) ne fait pas partie des directions valides." 241 | 242 | #: Lib/CakeMigration.php:229 243 | msgid "Migration direction (%s) is not one of valid directions." 244 | msgstr "" 245 | "La direction de la Migration (%s) ne fait pas partie des directions valides." 246 | 247 | #: Lib/CakeMigration.php:295 Lib/Migration/PrecheckBase.php:113 248 | msgid "Migration action type (%s) is not one of valid actions type." 249 | msgstr "" 250 | "Le type d'action de la Migration (%s) ne fait pas partie des type d'actions " 251 | "valides." 252 | 253 | #: Lib/CakeMigration.php:343;373;401;489;529 254 | msgid "SQL Error: %s" 255 | msgstr "Erreur SQL : %s" 256 | 257 | #: Lib/CakeMigration.php:567 258 | msgid "Interrupted when running \"%s\" callback." 259 | msgstr "Interrompu lors de l'exécution du callback \"%s\"." 260 | 261 | #: Lib/MigrationVersion.php:273 262 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 263 | msgstr "Classe `%1$s` introuvable dans le fichier `%2$s` pour %3$s." 264 | 265 | #: Lib/MigrationVersion.php:410 266 | msgid "File `%1$s` not found in the %2$s." 267 | msgstr "Fichier `%1$s` introuvable dans %2$s." 268 | 269 | #: Lib/Migration/PrecheckException.php:26 270 | msgid "Table \"%s\" does not exist in database." 271 | msgstr "La table \"%s\" n'existe pas dans la base de données." 272 | 273 | #: Lib/Migration/PrecheckException.php:42 274 | msgid "Table \"%s\" already exists in database." 275 | msgstr "La table \"%s\" existe déjà dans la base de données." 276 | 277 | #: Lib/Migration/PrecheckException.php:59 278 | msgid "Field \"%s\" does not exist in \"%s\"." 279 | msgstr "Le champ \"%s\" n'existe pas dans \"%s\"." 280 | 281 | #: Lib/Migration/PrecheckException.php:76 282 | msgid "Field \"%s\" already exists in \"%s\"." 283 | msgstr "Le champ \"%s\" existe déjà dans \"%s\"." 284 | 285 | #: View/Elements/migrations_panel.ctp:12 286 | #, fuzzy 287 | msgid "Migration Status" 288 | msgstr "Migration : %s" 289 | -------------------------------------------------------------------------------- /Locale/ita/LC_MESSAGES/migrations.po: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: CakePHP Migrations Plugin\n" 14 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 15 | "PO-Revision-Date: 2015-03-09 17:40-0000\n" 16 | "Last-Translator: Chris Burke \n" 17 | "Language-Team: Cake Development Corporation \n" 18 | "Language: it\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.7.4\n" 25 | 26 | #: Config/Migration/002_convert_version_to_class_names.php:56 27 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 28 | msgstr "" 29 | "Mi dispiace, non posso effettuare il downgrade. Perché si vuole che in ogni modo?" 30 | 31 | #: Console/Command/MigrationShell.php:75 32 | msgid "Cake Migration Shell" 33 | msgstr "Cake Migration Shell" 34 | 35 | #: Console/Command/MigrationShell.php:108 36 | #, fuzzy 37 | msgid "Creating table \":table\"." 38 | msgstr "Creazione della tabella :table." 39 | 40 | #: Console/Command/MigrationShell.php:109 41 | #, fuzzy 42 | msgid "Dropping table \":table\"." 43 | msgstr "Rimozione tabella :table." 44 | 45 | #: Console/Command/MigrationShell.php:110 46 | #, fuzzy 47 | msgid "Renaming table \":old_name\" to \":new_name\"." 48 | msgstr "Rinomina della tabella :old_name in :new_name." 49 | 50 | #: Console/Command/MigrationShell.php:111 51 | #, fuzzy 52 | msgid "Adding field \":field\" to table \":table\"." 53 | msgstr "Aggiunta del campo :field a :table." 54 | 55 | #: Console/Command/MigrationShell.php:112 56 | #, fuzzy 57 | msgid "Dropping field \":field\" from table \":table\"." 58 | msgstr "Rimozione del campo :field da :table." 59 | 60 | #: Console/Command/MigrationShell.php:113 61 | #, fuzzy 62 | msgid "Changing field \":field\" from table \":table\"." 63 | msgstr "Cambiamento campo :field da :table." 64 | 65 | #: Console/Command/MigrationShell.php:114 66 | #, fuzzy 67 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 68 | msgstr "Rinomina del campo :old_name a :new_name su :table." 69 | 70 | #: Console/Command/MigrationShell.php:115 71 | #, fuzzy 72 | msgid "Adding index \":index\" to table \":table\"." 73 | msgstr "Aggiunta indice :index a :table." 74 | 75 | #: Console/Command/MigrationShell.php:116 76 | #, fuzzy 77 | msgid "Dropping index \":index\" from table \":table\"." 78 | msgstr "Rimozione indice :index da :table." 79 | 80 | #: Console/Command/MigrationShell.php:195 81 | msgid "No migrations available." 82 | msgstr "Nessuna migrazione disponibile." 83 | 84 | #: Console/Command/MigrationShell.php:225 85 | msgid "Running migrations:" 86 | msgstr "Esecuzione delle migrazioni:" 87 | 88 | #: Console/Command/MigrationShell.php:237 89 | msgid "Migration will run dry, no database changes will be made" 90 | msgstr "" 91 | "La migrazione verrà eseguito a secco, saranno apportate modifiche di database" 92 | 93 | #: Console/Command/MigrationShell.php:246 94 | msgid "All migrations have completed." 95 | msgstr "Tutte le migrazioni sono state completate." 96 | 97 | #: Console/Command/MigrationShell.php:264 98 | msgid "An error occurred when processing the migration:" 99 | msgstr "Si è verificato un errore nell'esecuzione della migrazione:" 100 | 101 | #: Console/Command/MigrationShell.php:265 102 | msgid "Migration: %s" 103 | msgstr "Migrazione: %s" 104 | 105 | #: Console/Command/MigrationShell.php:266 106 | msgid "Error: %s" 107 | msgstr "Errore: %s" 108 | 109 | #: Console/Command/MigrationShell.php:270 110 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 111 | msgstr "Vuoi segnare la migrazione di successo ?. [y] SI o [a]bortire." 112 | 113 | #: Console/Command/MigrationShell.php:326;346;373 114 | msgid "Not a valid migration version." 115 | msgstr "Versione di migrazione non valida." 116 | 117 | #: Console/Command/MigrationShell.php:354 118 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 119 | msgstr "" 120 | "Per favore, scegliere la versione alla quale si desidera migrare. [q] per uscire " 121 | "o [c] per pulire." 122 | 123 | #: Console/Command/MigrationShell.php:400 124 | msgid "Do you want to compare the schema.php file to the database?" 125 | msgstr "Vuoi comparare il file schema.php col database?" 126 | 127 | #: Console/Command/MigrationShell.php:405 128 | msgid "No database changes detected." 129 | msgstr "Nessuna modifica del database rilevato." 130 | 131 | #: Console/Command/MigrationShell.php:411 132 | msgid "Do you want to generate a dump from the current database?" 133 | msgstr "Vuoi generare un dump del database corrente?" 134 | 135 | #: Console/Command/MigrationShell.php:422 136 | #, fuzzy 137 | msgid "Do you want to update the schema.php file?" 138 | msgstr "Vuoi comparare il file schema.php col database?" 139 | 140 | #: Console/Command/MigrationShell.php:439 141 | msgid "Comparing schema.php to the database..." 142 | msgstr "Comparazione di schema.php col database..." 143 | 144 | #: Console/Command/MigrationShell.php:459 145 | #, fuzzy 146 | msgid "Generating migration from commandline arguments..." 147 | msgstr "Generazione delle Migrazioni..." 148 | 149 | #: Console/Command/MigrationShell.php:487;842 150 | msgid "Invalid argument" 151 | msgstr "Argomento non valido" 152 | 153 | #: Console/Command/MigrationShell.php:487 154 | #, fuzzy 155 | msgid "" 156 | "Migration name (%s) is invalid. It cannot be used to generate a migration from " 157 | "the CLI." 158 | msgstr "" 159 | "Il nome (%s) per la migrazione non è valido. Deve contenere solo caratteri " 160 | "alfanumerici." 161 | 162 | #: Console/Command/MigrationShell.php:515 163 | msgid "Generating dump from the current database..." 164 | msgstr "Generazione dump del database corrente..." 165 | 166 | #: Console/Command/MigrationShell.php:537 167 | #, fuzzy 168 | msgid "Do you want to preview the file before generation?" 169 | msgstr "Vuoi comparare il file schema.php col database?" 170 | 171 | #: Console/Command/MigrationShell.php:547 172 | msgid "Generating Migration..." 173 | msgstr "Generazione delle Migrazioni..." 174 | 175 | #: Console/Command/MigrationShell.php:556 176 | msgid "Done." 177 | msgstr "Fatto." 178 | 179 | #: Console/Command/MigrationShell.php:566 180 | msgid "Please enter the descriptive name of the migration to generate:" 181 | msgstr "Per favore inserire il nome descrittivo della migrazione da generare:" 182 | 183 | #: Console/Command/MigrationShell.php:569 184 | #, fuzzy 185 | msgid "" 186 | "Migration name (%s) is invalid. It must only contain alphanumeric characters and " 187 | "start with a letter." 188 | msgstr "" 189 | "Il nome (%s) per la migrazione non è valido. Deve contenere solo caratteri " 190 | "alfanumerici." 191 | 192 | #: Console/Command/MigrationShell.php:572 193 | #, fuzzy 194 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 195 | msgstr "" 196 | "Il nome (%s) per la migrazione non è valido. Deve contenere solo caratteri " 197 | "alfanumerici." 198 | 199 | #: Console/Command/MigrationShell.php:608 200 | msgid "Current version:" 201 | msgstr "Versione corrente:" 202 | 203 | #: Console/Command/MigrationShell.php:613 204 | msgid "None applied." 205 | msgstr "Nessuna applicata." 206 | 207 | #: Console/Command/MigrationShell.php:616 208 | msgid "Latest version:" 209 | msgstr "Versione più recente:" 210 | 211 | #: Console/Command/MigrationShell.php:640 212 | msgid "Current migration version:" 213 | msgstr "Versione della migrazione corrente:" 214 | 215 | #: Console/Command/MigrationShell.php:645 216 | msgid "Available migrations:" 217 | msgstr "Migrazioni disponibili:" 218 | 219 | #: Console/Command/MigrationShell.php:651 220 | msgid "applied" 221 | msgstr "applicato" 222 | 223 | #: Console/Command/MigrationShell.php:653 224 | msgid "not applied" 225 | msgstr "non applicato" 226 | 227 | #: Console/Command/MigrationShell.php:842 228 | msgid "Missing required argument 'name' for migration" 229 | msgstr "Mancante richiesta argomento 'nome' per la migrazione" 230 | 231 | #: Lib/CakeMigration.php:205 232 | msgid "Migration precheck class (%s) could not be loaded." 233 | msgstr "Migrazione classe controllo preliminare (%s) non ha potuto essere caricato." 234 | 235 | #: Lib/CakeMigration.php:213 236 | #, fuzzy 237 | msgid "Migration precheck class (%s) is not a valid precheck class." 238 | msgstr "La direzione di migrazione (%s) non è una delle direzioni valide." 239 | 240 | #: Lib/CakeMigration.php:229 241 | msgid "Migration direction (%s) is not one of valid directions." 242 | msgstr "La direzione di migrazione (%s) non è una delle direzioni valide." 243 | 244 | #: Lib/CakeMigration.php:295 Lib/Migration/PrecheckBase.php:113 245 | msgid "Migration action type (%s) is not one of valid actions type." 246 | msgstr "Il tipo di azione (%s) non è un tipo di azione valido." 247 | 248 | #: Lib/CakeMigration.php:343;373;401;489;529 249 | msgid "SQL Error: %s" 250 | msgstr "Errore SQL: %s" 251 | 252 | #: Lib/CakeMigration.php:567 253 | msgid "Interrupted when running \"%s\" callback." 254 | msgstr "Interrotto durante l'esecuzione della callback \"%s\"." 255 | 256 | #: Lib/MigrationVersion.php:273 257 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 258 | msgstr "Classe `%1$s` non trovata nel file `%2$s` per %3$s." 259 | 260 | #: Lib/MigrationVersion.php:410 261 | msgid "File `%1$s` not found in the %2$s." 262 | msgstr "File `%1$s` non trovato in %2$s." 263 | 264 | #: Lib/Migration/PrecheckException.php:26 265 | msgid "Table \"%s\" does not exist in database." 266 | msgstr "La tabella \"%s\" non esiste nel database." 267 | 268 | #: Lib/Migration/PrecheckException.php:42 269 | msgid "Table \"%s\" already exists in database." 270 | msgstr "La tabella \"%s\" esiste già nel database." 271 | 272 | #: Lib/Migration/PrecheckException.php:59 273 | msgid "Field \"%s\" does not exist in \"%s\"." 274 | msgstr "il campo \"%s\" non esiste in \"%s\"." 275 | 276 | #: Lib/Migration/PrecheckException.php:76 277 | msgid "Field \"%s\" already exists in \"%s\"." 278 | msgstr "il campo \"%s\" esiste già in \"%s\"." 279 | 280 | #: View/Elements/migrations_panel.ctp:12 281 | #, fuzzy 282 | msgid "Migration Status" 283 | msgstr "Migrazione: %s" 284 | -------------------------------------------------------------------------------- /Locale/migrations.pot: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | #, fuzzy 12 | msgid "" 13 | msgstr "" 14 | "Project-Id-Version: CakePHP Migrations Plugin\n" 15 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 16 | "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" 17 | "Last-Translator: NAME \n" 18 | "Language-Team: Cake Development Corporation \n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=(n!=1);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | 25 | #: Config/Migration/002_convert_version_to_class_names.php:56 26 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 27 | msgstr "" 28 | 29 | #: Console/Command/MigrationShell.php:75 30 | msgid "Cake Migration Shell" 31 | msgstr "" 32 | 33 | #: Console/Command/MigrationShell.php:108 34 | msgid "Creating table \":table\"." 35 | msgstr "" 36 | 37 | #: Console/Command/MigrationShell.php:109 38 | msgid "Dropping table \":table\"." 39 | msgstr "" 40 | 41 | #: Console/Command/MigrationShell.php:110 42 | msgid "Renaming table \":old_name\" to \":new_name\"." 43 | msgstr "" 44 | 45 | #: Console/Command/MigrationShell.php:111 46 | msgid "Adding field \":field\" to table \":table\"." 47 | msgstr "" 48 | 49 | #: Console/Command/MigrationShell.php:112 50 | msgid "Dropping field \":field\" from table \":table\"." 51 | msgstr "" 52 | 53 | #: Console/Command/MigrationShell.php:113 54 | msgid "Changing field \":field\" from table \":table\"." 55 | msgstr "" 56 | 57 | #: Console/Command/MigrationShell.php:114 58 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 59 | msgstr "" 60 | 61 | #: Console/Command/MigrationShell.php:115 62 | msgid "Adding index \":index\" to table \":table\"." 63 | msgstr "" 64 | 65 | #: Console/Command/MigrationShell.php:116 66 | msgid "Dropping index \":index\" from table \":table\"." 67 | msgstr "" 68 | 69 | #: Console/Command/MigrationShell.php:195 70 | msgid "No migrations available." 71 | msgstr "" 72 | 73 | #: Console/Command/MigrationShell.php:225 74 | msgid "Running migrations:" 75 | msgstr "" 76 | 77 | #: Console/Command/MigrationShell.php:237 78 | msgid "Migration will run dry, no database changes will be made" 79 | msgstr "" 80 | 81 | #: Console/Command/MigrationShell.php:246 82 | msgid "All migrations have completed." 83 | msgstr "" 84 | 85 | #: Console/Command/MigrationShell.php:264 86 | msgid "An error occurred when processing the migration:" 87 | msgstr "" 88 | 89 | #: Console/Command/MigrationShell.php:265 90 | msgid "Migration: %s" 91 | msgstr "" 92 | 93 | #: Console/Command/MigrationShell.php:266 94 | msgid "Error: %s" 95 | msgstr "" 96 | 97 | #: Console/Command/MigrationShell.php:270 98 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 99 | msgstr "" 100 | 101 | #: Console/Command/MigrationShell.php:326;346;373 102 | msgid "Not a valid migration version." 103 | msgstr "" 104 | 105 | #: Console/Command/MigrationShell.php:354 106 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 107 | msgstr "" 108 | 109 | #: Console/Command/MigrationShell.php:400 110 | msgid "Do you want to compare the schema.php file to the database?" 111 | msgstr "" 112 | 113 | #: Console/Command/MigrationShell.php:405 114 | msgid "No database changes detected." 115 | msgstr "" 116 | 117 | #: Console/Command/MigrationShell.php:411 118 | msgid "Do you want to generate a dump from the current database?" 119 | msgstr "" 120 | 121 | #: Console/Command/MigrationShell.php:422 122 | msgid "Do you want to update the schema.php file?" 123 | msgstr "" 124 | 125 | #: Console/Command/MigrationShell.php:439 126 | msgid "Comparing schema.php to the database..." 127 | msgstr "" 128 | 129 | #: Console/Command/MigrationShell.php:459 130 | msgid "Generating migration from commandline arguments..." 131 | msgstr "" 132 | 133 | #: Console/Command/MigrationShell.php:487;842 134 | msgid "Invalid argument" 135 | msgstr "" 136 | 137 | #: Console/Command/MigrationShell.php:487 138 | msgid "Migration name (%s) is invalid. It cannot be used to generate a migration from the CLI." 139 | msgstr "" 140 | 141 | #: Console/Command/MigrationShell.php:515 142 | msgid "Generating dump from the current database..." 143 | msgstr "" 144 | 145 | #: Console/Command/MigrationShell.php:537 146 | msgid "Do you want to preview the file before generation?" 147 | msgstr "" 148 | 149 | #: Console/Command/MigrationShell.php:547 150 | msgid "Generating Migration..." 151 | msgstr "" 152 | 153 | #: Console/Command/MigrationShell.php:556 154 | msgid "Done." 155 | msgstr "" 156 | 157 | #: Console/Command/MigrationShell.php:566 158 | msgid "Please enter the descriptive name of the migration to generate:" 159 | msgstr "" 160 | 161 | #: Console/Command/MigrationShell.php:569 162 | msgid "Migration name (%s) is invalid. It must only contain alphanumeric characters and start with a letter." 163 | msgstr "" 164 | 165 | #: Console/Command/MigrationShell.php:572 166 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 167 | msgstr "" 168 | 169 | #: Console/Command/MigrationShell.php:608 170 | msgid "Current version:" 171 | msgstr "" 172 | 173 | #: Console/Command/MigrationShell.php:613 174 | msgid "None applied." 175 | msgstr "" 176 | 177 | #: Console/Command/MigrationShell.php:616 178 | msgid "Latest version:" 179 | msgstr "" 180 | 181 | #: Console/Command/MigrationShell.php:640 182 | msgid "Current migration version:" 183 | msgstr "" 184 | 185 | #: Console/Command/MigrationShell.php:645 186 | msgid "Available migrations:" 187 | msgstr "" 188 | 189 | #: Console/Command/MigrationShell.php:651 190 | msgid "applied" 191 | msgstr "" 192 | 193 | #: Console/Command/MigrationShell.php:653 194 | msgid "not applied" 195 | msgstr "" 196 | 197 | #: Console/Command/MigrationShell.php:842 198 | msgid "Missing required argument 'name' for migration" 199 | msgstr "" 200 | 201 | #: Lib/CakeMigration.php:205 202 | msgid "Migration precheck class (%s) could not be loaded." 203 | msgstr "" 204 | 205 | #: Lib/CakeMigration.php:213 206 | msgid "Migration precheck class (%s) is not a valid precheck class." 207 | msgstr "" 208 | 209 | #: Lib/CakeMigration.php:229 210 | msgid "Migration direction (%s) is not one of valid directions." 211 | msgstr "" 212 | 213 | #: Lib/CakeMigration.php:295 214 | #: Lib/Migration/PrecheckBase.php:113 215 | msgid "Migration action type (%s) is not one of valid actions type." 216 | msgstr "" 217 | 218 | #: Lib/CakeMigration.php:343;373;401;489;529 219 | msgid "SQL Error: %s" 220 | msgstr "" 221 | 222 | #: Lib/CakeMigration.php:567 223 | msgid "Interrupted when running \"%s\" callback." 224 | msgstr "" 225 | 226 | #: Lib/MigrationVersion.php:273 227 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 228 | msgstr "" 229 | 230 | #: Lib/MigrationVersion.php:410 231 | msgid "File `%1$s` not found in the %2$s." 232 | msgstr "" 233 | 234 | #: Lib/Migration/PrecheckException.php:26 235 | msgid "Table \"%s\" does not exist in database." 236 | msgstr "" 237 | 238 | #: Lib/Migration/PrecheckException.php:42 239 | msgid "Table \"%s\" already exists in database." 240 | msgstr "" 241 | 242 | #: Lib/Migration/PrecheckException.php:59 243 | msgid "Field \"%s\" does not exist in \"%s\"." 244 | msgstr "" 245 | 246 | #: Lib/Migration/PrecheckException.php:76 247 | msgid "Field \"%s\" already exists in \"%s\"." 248 | msgstr "" 249 | 250 | #: View/Elements/migrations_panel.ctp:12 251 | msgid "Migration Status" 252 | msgstr "" 253 | 254 | -------------------------------------------------------------------------------- /Locale/por/LC_MESSAGES/migrations.po: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: CakePHP Migrations Plugin\n" 14 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 15 | "PO-Revision-Date: 2015-03-09 17:39-0000\n" 16 | "Last-Translator: Chris Burke \n" 17 | "Language-Team: Cake Development Corporation \n" 18 | "Language: pt_BR\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=(n!=1);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.7.4\n" 25 | 26 | #: Config/Migration/002_convert_version_to_class_names.php:56 27 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 28 | msgstr "" 29 | "Desculpe, eu não posso fazer o downgrade. Por que você quer que de qualquer " 30 | "maneira?" 31 | 32 | #: Console/Command/MigrationShell.php:75 33 | msgid "Cake Migration Shell" 34 | msgstr "Cake Migration Shell" 35 | 36 | #: Console/Command/MigrationShell.php:108 37 | #, fuzzy 38 | msgid "Creating table \":table\"." 39 | msgstr "Criando tabela :table." 40 | 41 | #: Console/Command/MigrationShell.php:109 42 | #, fuzzy 43 | msgid "Dropping table \":table\"." 44 | msgstr "Removindo tabela :table." 45 | 46 | #: Console/Command/MigrationShell.php:110 47 | #, fuzzy 48 | msgid "Renaming table \":old_name\" to \":new_name\"." 49 | msgstr "Renomeando tabela :old_name para :new_name." 50 | 51 | #: Console/Command/MigrationShell.php:111 52 | #, fuzzy 53 | msgid "Adding field \":field\" to table \":table\"." 54 | msgstr "Adicionando coluna :field para :table." 55 | 56 | #: Console/Command/MigrationShell.php:112 57 | #, fuzzy 58 | msgid "Dropping field \":field\" from table \":table\"." 59 | msgstr "Removendo coluna :field de :table." 60 | 61 | #: Console/Command/MigrationShell.php:113 62 | #, fuzzy 63 | msgid "Changing field \":field\" from table \":table\"." 64 | msgstr "Alterando coluna :field de :table." 65 | 66 | #: Console/Command/MigrationShell.php:114 67 | #, fuzzy 68 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 69 | msgstr "Renomeando coluna :old_name para :new_name em :table." 70 | 71 | #: Console/Command/MigrationShell.php:115 72 | #, fuzzy 73 | msgid "Adding index \":index\" to table \":table\"." 74 | msgstr "Adicionar chave :index para :table." 75 | 76 | #: Console/Command/MigrationShell.php:116 77 | #, fuzzy 78 | msgid "Dropping index \":index\" from table \":table\"." 79 | msgstr "Removendo chave :index de :table." 80 | 81 | #: Console/Command/MigrationShell.php:195 82 | msgid "No migrations available." 83 | msgstr "Nenhuma migração disponível." 84 | 85 | #: Console/Command/MigrationShell.php:225 86 | msgid "Running migrations:" 87 | msgstr "Rodando migrações:" 88 | 89 | #: Console/Command/MigrationShell.php:237 90 | msgid "Migration will run dry, no database changes will be made" 91 | msgstr "Migração secará, sem alterações de banco de dados será feita" 92 | 93 | #: Console/Command/MigrationShell.php:246 94 | msgid "All migrations have completed." 95 | msgstr "Todas as migrações foram completas." 96 | 97 | #: Console/Command/MigrationShell.php:264 98 | msgid "An error occurred when processing the migration:" 99 | msgstr "Aconteceu um erro enquanto processava a migração:" 100 | 101 | #: Console/Command/MigrationShell.php:265 102 | msgid "Migration: %s" 103 | msgstr "Migração: %s" 104 | 105 | #: Console/Command/MigrationShell.php:266 106 | msgid "Error: %s" 107 | msgstr "Erro: %s" 108 | 109 | #: Console/Command/MigrationShell.php:270 110 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 111 | msgstr "Você quer marcar a migração tão bem sucedido ?. [y] sim ou [a]bortar." 112 | 113 | #: Console/Command/MigrationShell.php:326;346;373 114 | msgid "Not a valid migration version." 115 | msgstr "Não é uma versão de migração válida," 116 | 117 | #: Console/Command/MigrationShell.php:354 118 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 119 | msgstr "Por favor, escolha para qual versão você deseja migrar. [q]uit ou [c]lean." 120 | 121 | #: Console/Command/MigrationShell.php:400 122 | msgid "Do you want to compare the schema.php file to the database?" 123 | msgstr "Você deseja comparar o arquivo schema.php com o banco de dados?" 124 | 125 | #: Console/Command/MigrationShell.php:405 126 | msgid "No database changes detected." 127 | msgstr "" 128 | 129 | #: Console/Command/MigrationShell.php:411 130 | msgid "Do you want to generate a dump from the current database?" 131 | msgstr "Você deseja gerar um dump do banco de dados atual?" 132 | 133 | #: Console/Command/MigrationShell.php:422 134 | #, fuzzy 135 | msgid "Do you want to update the schema.php file?" 136 | msgstr "Você deseja comparar o arquivo schema.php com o banco de dados?" 137 | 138 | #: Console/Command/MigrationShell.php:439 139 | msgid "Comparing schema.php to the database..." 140 | msgstr "Comparando schema.php com o banco de dados..." 141 | 142 | #: Console/Command/MigrationShell.php:459 143 | msgid "Generating migration from commandline arguments..." 144 | msgstr "Gerando migração de argumentos de linha de comando ..." 145 | 146 | #: Console/Command/MigrationShell.php:487;842 147 | msgid "Invalid argument" 148 | msgstr "Invalid argument" 149 | 150 | #: Console/Command/MigrationShell.php:487 151 | #, fuzzy 152 | msgid "" 153 | "Migration name (%s) is invalid. It cannot be used to generate a migration from " 154 | "the CLI." 155 | msgstr "" 156 | "Nome de Migração (%s) inválida. Ele deve conter apenas caracteres alfanuméricos." 157 | 158 | #: Console/Command/MigrationShell.php:515 159 | msgid "Generating dump from the current database..." 160 | msgstr "Gerando dump do banco de dados atual..." 161 | 162 | #: Console/Command/MigrationShell.php:537 163 | #, fuzzy 164 | msgid "Do you want to preview the file before generation?" 165 | msgstr "Você deseja comparar o arquivo schema.php com o banco de dados?" 166 | 167 | #: Console/Command/MigrationShell.php:547 168 | msgid "Generating Migration..." 169 | msgstr "Gerando Migração..." 170 | 171 | #: Console/Command/MigrationShell.php:556 172 | msgid "Done." 173 | msgstr "Feito." 174 | 175 | #: Console/Command/MigrationShell.php:566 176 | msgid "Please enter the descriptive name of the migration to generate:" 177 | msgstr "Por favor entre com um nome descritivo para a migração a ser gerada:" 178 | 179 | #: Console/Command/MigrationShell.php:569 180 | #, fuzzy 181 | msgid "" 182 | "Migration name (%s) is invalid. It must only contain alphanumeric characters and " 183 | "start with a letter." 184 | msgstr "" 185 | "Nome de Migração (%s) inválida. Ele deve conter apenas caracteres alfanuméricos." 186 | 187 | #: Console/Command/MigrationShell.php:572 188 | #, fuzzy 189 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 190 | msgstr "" 191 | "Nome de Migração (%s) inválida. Ele deve conter apenas caracteres alfanuméricos." 192 | 193 | #: Console/Command/MigrationShell.php:608 194 | msgid "Current version:" 195 | msgstr "Versão atual:" 196 | 197 | #: Console/Command/MigrationShell.php:613 198 | msgid "None applied." 199 | msgstr "Nenhuma aplicada." 200 | 201 | #: Console/Command/MigrationShell.php:616 202 | msgid "Latest version:" 203 | msgstr "Última versão:" 204 | 205 | #: Console/Command/MigrationShell.php:640 206 | msgid "Current migration version:" 207 | msgstr "Versão de Migração atual:" 208 | 209 | #: Console/Command/MigrationShell.php:645 210 | msgid "Available migrations:" 211 | msgstr "Migrações disponíveis:" 212 | 213 | #: Console/Command/MigrationShell.php:651 214 | msgid "applied" 215 | msgstr "aplicada" 216 | 217 | #: Console/Command/MigrationShell.php:653 218 | msgid "not applied" 219 | msgstr "não aplicada" 220 | 221 | #: Console/Command/MigrationShell.php:842 222 | msgid "Missing required argument 'name' for migration" 223 | msgstr "Faltando exigido argumento 'nome' para migração" 224 | 225 | #: Lib/CakeMigration.php:205 226 | msgid "Migration precheck class (%s) could not be loaded." 227 | msgstr "Migração classe pré-verificação (%s) não pôde ser carregado." 228 | 229 | #: Lib/CakeMigration.php:213 230 | #, fuzzy 231 | msgid "Migration precheck class (%s) is not a valid precheck class." 232 | msgstr "Direção da Migração (%s) não é uma das direções válidas." 233 | 234 | #: Lib/CakeMigration.php:229 235 | msgid "Migration direction (%s) is not one of valid directions." 236 | msgstr "Direção da Migração (%s) não é uma das direções válidas." 237 | 238 | #: Lib/CakeMigration.php:295 Lib/Migration/PrecheckBase.php:113 239 | msgid "Migration action type (%s) is not one of valid actions type." 240 | msgstr "Tipo de ação (%s) da Migração não é um dos tipos de ações válidos." 241 | 242 | #: Lib/CakeMigration.php:343;373;401;489;529 243 | msgid "SQL Error: %s" 244 | msgstr "Erro SQL: %s" 245 | 246 | #: Lib/CakeMigration.php:567 247 | msgid "Interrupted when running \"%s\" callback." 248 | msgstr "Interrompido enquanto rodava o callback \"%s\"." 249 | 250 | #: Lib/MigrationVersion.php:273 251 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 252 | msgstr "Classe `%1$s` não encontrado no arquivo `%2$s` para %3$s." 253 | 254 | #: Lib/MigrationVersion.php:410 255 | msgid "File `%1$s` not found in the %2$s." 256 | msgstr "Arquivo `%1$s` não encontrada no %2$s." 257 | 258 | #: Lib/Migration/PrecheckException.php:26 259 | msgid "Table \"%s\" does not exist in database." 260 | msgstr "Table \"%s\" não existe no banco de dados." 261 | 262 | #: Lib/Migration/PrecheckException.php:42 263 | msgid "Table \"%s\" already exists in database." 264 | msgstr "Tabela \"%s\" já existe no banco de dados." 265 | 266 | #: Lib/Migration/PrecheckException.php:59 267 | msgid "Field \"%s\" does not exist in \"%s\"." 268 | msgstr "Coluna \"%s\" não existe em \"%s\"." 269 | 270 | #: Lib/Migration/PrecheckException.php:76 271 | msgid "Field \"%s\" already exists in \"%s\"." 272 | msgstr "Coluna \"%s\" já existe em \"%s\"." 273 | 274 | #: View/Elements/migrations_panel.ctp:12 275 | #, fuzzy 276 | msgid "Migration Status" 277 | msgstr "Migração: %s" 278 | -------------------------------------------------------------------------------- /Locale/spa/LC_MESSAGES/migrations.po: -------------------------------------------------------------------------------- 1 | # LANGUAGE translation of the CakePHP Migrations plugin 2 | # 3 | # Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 4 | # 5 | # Licensed under The MIT License 6 | # Redistributions of files must retain the above copyright notice. 7 | # 8 | # @copyright Copyright 2010 - 2014, Cake Development Corporation (http://cakedc.com) 9 | # @license MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | # 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: CakePHP Migrations Plugin\n" 14 | "POT-Creation-Date: 2015-03-09 17:36+0000\n" 15 | "PO-Revision-Date: 2015-03-09 17:39-0000\n" 16 | "Last-Translator: Chris Burke \n" 17 | "Language-Team: Cake Development Corporation \n" 18 | "Language: es\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=utf-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Plural-Forms: nplurals=2; plural=(n!=1);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.7.4\n" 25 | 26 | #: Config/Migration/002_convert_version_to_class_names.php:56 27 | msgid "Sorry, I can't downgrade. Why would you want that anyways?" 28 | msgstr "Lo siento, no puedo retroceder. ¿Por qué quieres que de todos modos?" 29 | 30 | #: Console/Command/MigrationShell.php:75 31 | msgid "Cake Migration Shell" 32 | msgstr "Consola de Migración Cake" 33 | 34 | #: Console/Command/MigrationShell.php:108 35 | #, fuzzy 36 | msgid "Creating table \":table\"." 37 | msgstr "Creando tabla :table" 38 | 39 | #: Console/Command/MigrationShell.php:109 40 | #, fuzzy 41 | msgid "Dropping table \":table\"." 42 | msgstr "Eliminando tabla :table" 43 | 44 | #: Console/Command/MigrationShell.php:110 45 | #, fuzzy 46 | msgid "Renaming table \":old_name\" to \":new_name\"." 47 | msgstr "Renombrando tabla :table" 48 | 49 | #: Console/Command/MigrationShell.php:111 50 | #, fuzzy 51 | msgid "Adding field \":field\" to table \":table\"." 52 | msgstr "Agregando campo :field a :table" 53 | 54 | #: Console/Command/MigrationShell.php:112 55 | #, fuzzy 56 | msgid "Dropping field \":field\" from table \":table\"." 57 | msgstr "Eliminando campo :field de :table" 58 | 59 | #: Console/Command/MigrationShell.php:113 60 | #, fuzzy 61 | msgid "Changing field \":field\" from table \":table\"." 62 | msgstr "Cambiando campo :field de :table" 63 | 64 | #: Console/Command/MigrationShell.php:114 65 | #, fuzzy 66 | msgid "Renaming field \":old_name\" to \":new_name\" on table \":table\"." 67 | msgstr "Renombrando campo :old_name a :new_name en :table" 68 | 69 | #: Console/Command/MigrationShell.php:115 70 | #, fuzzy 71 | msgid "Adding index \":index\" to table \":table\"." 72 | msgstr "Agregando índice :index a :table" 73 | 74 | #: Console/Command/MigrationShell.php:116 75 | #, fuzzy 76 | msgid "Dropping index \":index\" from table \":table\"." 77 | msgstr "Eliminando índice :index de :table" 78 | 79 | #: Console/Command/MigrationShell.php:195 80 | msgid "No migrations available." 81 | msgstr "No hay migraciones disponibles" 82 | 83 | #: Console/Command/MigrationShell.php:225 84 | msgid "Running migrations:" 85 | msgstr "Ejecutando migraciones:" 86 | 87 | #: Console/Command/MigrationShell.php:237 88 | msgid "Migration will run dry, no database changes will be made" 89 | msgstr "La migración se secará, no se harán cambios de base de datos" 90 | 91 | #: Console/Command/MigrationShell.php:246 92 | msgid "All migrations have completed." 93 | msgstr "Todas las migraciones han sido completadas" 94 | 95 | #: Console/Command/MigrationShell.php:264 96 | msgid "An error occurred when processing the migration:" 97 | msgstr "Un error ha ocurrido al procesar la migración:" 98 | 99 | #: Console/Command/MigrationShell.php:265 100 | msgid "Migration: %s" 101 | msgstr "Migración: %s" 102 | 103 | #: Console/Command/MigrationShell.php:266 104 | msgid "Error: %s" 105 | msgstr "Error: %s" 106 | 107 | #: Console/Command/MigrationShell.php:270 108 | msgid "Do you want to mark the migration as successful?. [y]es or [a]bort." 109 | msgstr "¿Quieres marcar la migración como un éxito? [y] SÍ o [a]bortar." 110 | 111 | #: Console/Command/MigrationShell.php:326;346;373 112 | msgid "Not a valid migration version." 113 | msgstr "No es una versión de migración válida" 114 | 115 | #: Console/Command/MigrationShell.php:354 116 | msgid "Please choose which version you want to migrate to. [q]uit or [c]lean." 117 | msgstr "" 118 | "Por favor, escoge la versión a lo cual deseas migrar. [q] salir o [c] limpiar" 119 | 120 | #: Console/Command/MigrationShell.php:400 121 | msgid "Do you want to compare the schema.php file to the database?" 122 | msgstr "¿Desea comparar el archivo schema.php a la base de datos?" 123 | 124 | #: Console/Command/MigrationShell.php:405 125 | msgid "No database changes detected." 126 | msgstr "No hay cambios de base de datos detectados." 127 | 128 | #: Console/Command/MigrationShell.php:411 129 | msgid "Do you want to generate a dump from the current database?" 130 | msgstr "¿Desea generar un volcado completo de la estructura de su base de datos?" 131 | 132 | #: Console/Command/MigrationShell.php:422 133 | #, fuzzy 134 | msgid "Do you want to update the schema.php file?" 135 | msgstr "¿Desea comparar el archivo schema.php a la base de datos?" 136 | 137 | #: Console/Command/MigrationShell.php:439 138 | msgid "Comparing schema.php to the database..." 139 | msgstr "Comparando schema.php con la base de datos..." 140 | 141 | #: Console/Command/MigrationShell.php:459 142 | #, fuzzy 143 | msgid "Generating migration from commandline arguments..." 144 | msgstr "Generando migración" 145 | 146 | #: Console/Command/MigrationShell.php:487;842 147 | msgid "Invalid argument" 148 | msgstr "Argumento no válido" 149 | 150 | #: Console/Command/MigrationShell.php:487 151 | #, fuzzy 152 | msgid "" 153 | "Migration name (%s) is invalid. It cannot be used to generate a migration from " 154 | "the CLI." 155 | msgstr "" 156 | "El nombre de migración (%s) no es válido. SOlo puede contenter carateres " 157 | "alfanuméricos" 158 | 159 | #: Console/Command/MigrationShell.php:515 160 | msgid "Generating dump from the current database..." 161 | msgstr "Generando volcado de la base de datos actual" 162 | 163 | #: Console/Command/MigrationShell.php:537 164 | #, fuzzy 165 | msgid "Do you want to preview the file before generation?" 166 | msgstr "¿Desea comparar el archivo schema.php a la base de datos?" 167 | 168 | #: Console/Command/MigrationShell.php:547 169 | msgid "Generating Migration..." 170 | msgstr "Generando migración" 171 | 172 | #: Console/Command/MigrationShell.php:556 173 | msgid "Done." 174 | msgstr "Listo." 175 | 176 | #: Console/Command/MigrationShell.php:566 177 | msgid "Please enter the descriptive name of the migration to generate:" 178 | msgstr "Por favor ingrese el nombre descriptivo de la migración a generar:" 179 | 180 | #: Console/Command/MigrationShell.php:569 181 | #, fuzzy 182 | msgid "" 183 | "Migration name (%s) is invalid. It must only contain alphanumeric characters and " 184 | "start with a letter." 185 | msgstr "" 186 | "El nombre de migración (%s) no es válido. SOlo puede contenter carateres " 187 | "alfanuméricos" 188 | 189 | #: Console/Command/MigrationShell.php:572 190 | #, fuzzy 191 | msgid "Migration name (%s) is invalid. It cannot be longer than 255 characters." 192 | msgstr "" 193 | "El nombre de migración (%s) no es válido. SOlo puede contenter carateres " 194 | "alfanuméricos" 195 | 196 | #: Console/Command/MigrationShell.php:608 197 | msgid "Current version:" 198 | msgstr "Versión Actual:" 199 | 200 | #: Console/Command/MigrationShell.php:613 201 | msgid "None applied." 202 | msgstr "Ninguna aplicada." 203 | 204 | #: Console/Command/MigrationShell.php:616 205 | msgid "Latest version:" 206 | msgstr "Última versión:" 207 | 208 | #: Console/Command/MigrationShell.php:640 209 | msgid "Current migration version:" 210 | msgstr "Versión de migración actual:" 211 | 212 | #: Console/Command/MigrationShell.php:645 213 | msgid "Available migrations:" 214 | msgstr "Migraciones disponibles:" 215 | 216 | #: Console/Command/MigrationShell.php:651 217 | msgid "applied" 218 | msgstr "applicada" 219 | 220 | #: Console/Command/MigrationShell.php:653 221 | msgid "not applied" 222 | msgstr "no aplicada" 223 | 224 | #: Console/Command/MigrationShell.php:842 225 | msgid "Missing required argument 'name' for migration" 226 | msgstr "Missing requerido argumento 'nombre' para la migración" 227 | 228 | #: Lib/CakeMigration.php:205 229 | msgid "Migration precheck class (%s) could not be loaded." 230 | msgstr "Clase de comprobación previa Migraciones (%s) no se pudo cargar." 231 | 232 | #: Lib/CakeMigration.php:213 233 | #, fuzzy 234 | msgid "Migration precheck class (%s) is not a valid precheck class." 235 | msgstr "Dirección (%s) de migración no es válida" 236 | 237 | #: Lib/CakeMigration.php:229 238 | msgid "Migration direction (%s) is not one of valid directions." 239 | msgstr "Dirección (%s) de migración no es válida" 240 | 241 | #: Lib/CakeMigration.php:295 Lib/Migration/PrecheckBase.php:113 242 | msgid "Migration action type (%s) is not one of valid actions type." 243 | msgstr "Acción de tipo %s no es una acción válida" 244 | 245 | #: Lib/CakeMigration.php:343;373;401;489;529 246 | msgid "SQL Error: %s" 247 | msgstr "Error SQL: %s" 248 | 249 | #: Lib/CakeMigration.php:567 250 | msgid "Interrupted when running \"%s\" callback." 251 | msgstr "Iterrumpido al llamar la función \"%s\"" 252 | 253 | #: Lib/MigrationVersion.php:273 254 | msgid "Class `%1$s` not found on file `%2$s` for %3$s." 255 | msgstr "Clase`%1$s` no encontrada en archivo `%2$s` para %3$s." 256 | 257 | #: Lib/MigrationVersion.php:410 258 | msgid "File `%1$s` not found in the %2$s." 259 | msgstr "Archivo`%1$s` no encontrado en %2$s." 260 | 261 | #: Lib/Migration/PrecheckException.php:26 262 | msgid "Table \"%s\" does not exist in database." 263 | msgstr "La tabla \"%s\" no existe en la base de datos." 264 | 265 | #: Lib/Migration/PrecheckException.php:42 266 | msgid "Table \"%s\" already exists in database." 267 | msgstr "La tabla \"%s\" ya existe en la base de datos." 268 | 269 | #: Lib/Migration/PrecheckException.php:59 270 | msgid "Field \"%s\" does not exist in \"%s\"." 271 | msgstr "El campo \"%s\" no existe en \"%s\"." 272 | 273 | #: Lib/Migration/PrecheckException.php:76 274 | msgid "Field \"%s\" already exists in \"%s\"." 275 | msgstr "El campo \"%s\" ya existe en \"%s\"." 276 | 277 | #: View/Elements/migrations_panel.ctp:12 278 | #, fuzzy 279 | msgid "Migration Status" 280 | msgstr "Migración: %s" 281 | -------------------------------------------------------------------------------- /Model/SchemaMigration.php: -------------------------------------------------------------------------------- 1 | addTestFile($basePath . 'Lib' . DS . 'MigrationVersionTest.php'); 26 | $suite->addTestFile($basePath . 'Lib' . DS . 'Model' . DS . 'CakeMigrationTest.php'); 27 | $suite->addTestFile($basePath . 'Lib' . DS . 'Migration' . DS . 'PrecheckConditionTest.php'); 28 | 29 | // Console 30 | $suite->addTestFile($basePath . 'Console' . DS . 'Command' . DS . 'MigrationShellTest.php'); 31 | 32 | return $suite; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /Test/Case/Lib/Migration/PrecheckConditionTest.php: -------------------------------------------------------------------------------- 1 | db = ConnectionManager::getDataSource($this->connection); 32 | $this->db->cacheSources = false; 33 | } 34 | 35 | } 36 | 37 | class PrecheckConditionTest extends CakeTestCase { 38 | 39 | /** 40 | * Fixtures property 41 | * 42 | * @var array 43 | */ 44 | public $fixtures = array( 45 | 'core.user', 46 | 'core.post'); 47 | 48 | /** 49 | * AutoFixtures property 50 | * 51 | * @var array 52 | */ 53 | public $autoFixtures = false; 54 | 55 | /** 56 | * @var DboSource 57 | */ 58 | public $db; 59 | 60 | /** 61 | * Tables property 62 | * 63 | * @var array 64 | */ 65 | public $tables = array( 66 | 'users' => array( 67 | 'id' => array('type' => 'integer', 'key' => 'primary'), 68 | 'user' => array('type' => 'string', 'null' => false), 69 | 'password' => array('type' => 'string', 'null' => false), 70 | 'created' => 'datetime', 71 | 'updated' => 'datetime' 72 | ), 73 | 'posts' => array( 74 | 'id' => array('type' => 'integer', 'key' => 'primary'), 75 | 'author_id' => array('type' => 'integer', 'null' => false), 76 | 'title' => array('type' => 'string', 'null' => false), 77 | 'body' => 'text', 78 | 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'), 79 | 'created' => 'datetime', 80 | 'updated' => 'datetime' 81 | ) 82 | ); 83 | 84 | /** 85 | * TestCreateTable method 86 | * 87 | * @return void 88 | */ 89 | public function testCreateDropTable() { 90 | $Migration = new TestPrecheckCakeMigration(array( 91 | 'up' => array('create_table' => array( 92 | 'migration_posts' => $this->tables['posts'], 93 | 'migration_users' => $this->tables['users'])), 94 | 'down' => array( 95 | 'drop_table' => array('migration_posts', 'migration_users')), 96 | 'precheck' => 'Migrations.PrecheckCondition' 97 | )); 98 | $Migration->initDb(); 99 | 100 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'create_table', array('table' => $this->db->fullTableName('migration_posts', false, false)))); 101 | 102 | $sources = $this->db->listSources(); 103 | $this->assertFalse(in_array($this->db->fullTableName('migration_user', false, false), $sources)); 104 | $this->assertFalse(in_array($this->db->fullTableName('migration_posts', false, false), $sources)); 105 | $this->assertTrue($Migration->run('up')); 106 | $sources = $this->db->listSources(); 107 | $this->assertTrue(in_array($this->db->fullTableName('migration_users', false, false), $sources)); 108 | $this->assertTrue(in_array($this->db->fullTableName('migration_posts', false, false), $sources)); 109 | 110 | // successful second run as precheck skip execution 111 | try { 112 | $Migration->run('up'); 113 | } catch (MigrationException $e) { 114 | $this->fail('Exception triggered'); 115 | } 116 | 117 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'create_table', array('table' => $this->db->fullTableName('migration_posts', false, false)))); 118 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'drop_table', array('table' => $this->db->fullTableName('migration_posts', false, false)))); 119 | 120 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'create_table', array('table' => $this->db->fullTableName('no_table', false, false)))); 121 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'drop_table', array('table' => $this->db->fullTableName('no_table', false, false)))); 122 | 123 | $this->assertTrue($Migration->run('down')); 124 | $sources = $this->db->listSources(); 125 | $this->assertFalse(in_array($this->db->fullTableName('migration_users', false, false), $sources)); 126 | $this->assertFalse(in_array($this->db->fullTableName('migration_posts', false, false), $sources)); 127 | } 128 | 129 | /** 130 | * TestRenameTable method 131 | * 132 | * @return void 133 | */ 134 | public function testRenameTable() { 135 | $this->loadFixtures('User', 'Post'); 136 | 137 | $Migration = new TestPrecheckCakeMigration(array( 138 | 'up' => array( 139 | 'rename_table' => array('posts' => 'renamed_posts')), 140 | 'down' => array( 141 | 'rename_table' => array('renamed_posts' => 'posts')), 142 | 'precheck' => 'Migrations.PrecheckCondition' 143 | )); 144 | $Migration->initDb(); 145 | 146 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_table', array( 147 | 'old_name' => $this->db->fullTableName('posts', false, false), 148 | 'new_name' => $this->db->fullTableName('renamed_posts', false, false), 149 | ))); 150 | 151 | $sources = $this->db->listSources(); 152 | $this->assertTrue(in_array($this->db->fullTableName('posts', false, false), $sources)); 153 | $this->assertFalse(in_array($this->db->fullTableName('renamed_posts', false, false), $sources)); 154 | 155 | $this->assertTrue($Migration->run('up')); 156 | $sources = $this->db->listSources(); 157 | $this->assertFalse(in_array($this->db->fullTableName('posts', false, false), $sources)); 158 | $this->assertTrue(in_array($this->db->fullTableName('renamed_posts', false, false), $sources)); 159 | 160 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'rename_table', array( 161 | 'old_name' => $this->db->fullTableName('posts', false, false), 162 | 'new_name' => $this->db->fullTableName('renamed_posts', false, false), 163 | ))); 164 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_table', array( 165 | 'old_name' => $this->db->fullTableName('renamed_posts', false, false), 166 | 'new_name' => $this->db->fullTableName('posts', false, false), 167 | ))); 168 | 169 | try { 170 | $Migration->run('up'); 171 | } catch (MigrationException $e) { 172 | $this->fail('Exception triggered: ' . $e->getMessage()); 173 | } 174 | 175 | $this->assertTrue($Migration->run('down')); 176 | 177 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'rename_table', array( 178 | 'old_name' => $this->db->fullTableName('renamed_posts', false, false), 179 | 'new_name' => $this->db->fullTableName('posts', false, false), 180 | ))); 181 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_table', array( 182 | 'old_name' => $this->db->fullTableName('posts', false, false), 183 | 'new_name' => $this->db->fullTableName('renamed_posts', false, false), 184 | ))); 185 | 186 | $sources = $this->db->listSources(); 187 | $this->assertTrue(in_array($this->db->fullTableName('posts', false, false), $sources)); 188 | $this->assertFalse(in_array($this->db->fullTableName('renamed_posts', false, false), $sources)); 189 | } 190 | 191 | /** 192 | * TestCreateDropField method 193 | * 194 | * @return void 195 | */ 196 | public function testCreateDropField() { 197 | $this->loadFixtures('User', 'Post'); 198 | $model = new Model(array('table' => 'posts', 'ds' => 'test')); 199 | 200 | $Migration = new TestPrecheckCakeMigration(array( 201 | 'up' => array( 202 | 'create_field' => array( 203 | 'posts' => array('views' => array('type' => 'integer', 'null' => false)) 204 | ) 205 | ), 206 | 'down' => array( 207 | 'drop_field' => array('posts' => array('views')) 208 | ), 209 | 'precheck' => 'Migrations.PrecheckCondition' 210 | )); 211 | $Migration->initDb(); 212 | 213 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'add_field', array( 214 | 'table' => $this->db->fullTableName('posts', false, false), 215 | 'field' => 'views'))); 216 | 217 | $fields = $this->db->describe($model); 218 | $this->assertFalse(isset($fields['views'])); 219 | 220 | $this->assertTrue($Migration->run('up')); 221 | $fields = $this->db->describe($model); 222 | $this->assertTrue(isset($fields['views'])); 223 | 224 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'add_field', array( 225 | 'table' => $this->db->fullTableName('posts', false, false), 226 | 'field' => 'views'))); 227 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'drop_field', array( 228 | 'table' => $this->db->fullTableName('posts', false, false), 229 | 'field' => 'views'))); 230 | 231 | try { 232 | $Migration->run('up'); 233 | } catch (MigrationException $e) { 234 | $this->fail('Exception triggered: ' . $e->getMessage()); 235 | } 236 | 237 | $this->assertTrue($Migration->run('down')); 238 | $fields = $this->db->describe($model); 239 | $this->assertFalse(isset($fields['views'])); 240 | 241 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'add_field', array( 242 | 'table' => $this->db->fullTableName('posts', false, false), 243 | 'field' => 'views'))); 244 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'drop_field', array( 245 | 'table' => $this->db->fullTableName('posts', false, false), 246 | 'field' => 'views'))); 247 | 248 | try { 249 | $Migration->run('down'); 250 | } catch (MigrationException $e) { 251 | $this->fail('Exception triggered: ' . $e->getMessage()); 252 | } 253 | } 254 | 255 | /** 256 | * TestAlterField method 257 | * @return void 258 | */ 259 | public function testAlterField() { 260 | $this->loadFixtures('User', 'Post'); 261 | $Model = new Model(array('table' => 'posts', 'ds' => 'test')); 262 | 263 | $Migration = new TestPrecheckCakeMigration(array( 264 | 'up' => array( 265 | 'alter_field' => array( 266 | 'posts' => array('published' => array('default' => 'Y')) 267 | ) 268 | ), 269 | 'down' => array( 270 | 'alter_field' => array( 271 | 'posts' => array('published' => array('default' => 'N')) 272 | ) 273 | ), 274 | 'precheck' => 'Migrations.PrecheckCondition')); 275 | $Migration->initDb(); 276 | 277 | $fields = $this->db->describe($Model); 278 | $this->assertEquals($fields['published']['default'], 'N'); 279 | 280 | $this->assertTrue($Migration->run('up')); 281 | $fields = $this->db->describe($Model); 282 | $this->assertEquals($fields['published']['default'], 'Y'); 283 | 284 | try { 285 | $Migration->migration['up']['alter_field']['posts']['inexistent'] = array('default' => 'N'); 286 | $Migration->run('up'); 287 | $this->fail('No expectation triggered'); 288 | $this->setExpectedException('MigrationException'); 289 | } catch (MigrationException $e) { 290 | $this->assertEquals('Undefined index: inexistent', $e->getMessage()); 291 | } 292 | 293 | $this->assertTrue($Migration->run('down')); 294 | $fields = $this->db->describe($Model); 295 | $this->assertEquals($fields['published']['default'], 'N'); 296 | } 297 | 298 | /** 299 | * TestRenameField method 300 | * 301 | * @return void 302 | */ 303 | public function testRenameField() { 304 | $this->loadFixtures('User', 'Post'); 305 | $Model = new Model(array('table' => 'posts', 'ds' => 'test')); 306 | 307 | $Migration = new TestPrecheckCakeMigration(array( 308 | 'up' => array( 309 | 'rename_field' => array( 310 | 'posts' => array( 311 | 'updated' => 'renamed_updated'))), 312 | 'down' => array( 313 | 'rename_field' => array( 314 | 'posts' => array( 315 | 'renamed_updated' => 'updated'))), 316 | 'precheck' => 'Migrations.PrecheckCondition')); 317 | $Migration->initDb(); 318 | 319 | $fields = $this->db->describe($Model); 320 | $this->assertTrue(isset($fields['updated'])); 321 | $this->assertFalse(isset($fields['renamed_updated'])); 322 | 323 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_field', array( 324 | 'table' => $this->db->fullTableName('posts', false, false), 325 | 'old_name' => 'updated', 326 | 'new_name' => 'renamed_updated'))); 327 | 328 | $this->assertTrue($Migration->run('up')); 329 | $fields = $this->db->describe($Model); 330 | $this->assertFalse(isset($fields['updated'])); 331 | $this->assertTrue(isset($fields['renamed_updated'])); 332 | 333 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'rename_field', array( 334 | 'table' => $this->db->fullTableName('posts', false, false), 335 | 'old_name' => 'updated', 336 | 'new_name' => 'renamed_updated'))); 337 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_field', array( 338 | 'table' => $this->db->fullTableName('posts', false, false), 339 | 'old_name' => 'renamed_updated', 340 | 'new_name' => 'updated'))); 341 | 342 | try { 343 | $Migration->run('up'); 344 | } catch (MigrationException $e) { 345 | $this->fail('Exception triggered ' . $e->getMessage()); 346 | } 347 | 348 | $this->assertTrue($Migration->run('down')); 349 | $fields = $this->db->describe($Model); 350 | $this->assertTrue(isset($fields['updated'])); 351 | $this->assertFalse(isset($fields['renamed_updated'])); 352 | 353 | $this->assertTrue($Migration->Precheck->beforeAction($Migration, 'rename_field', array( 354 | 'table' => $this->db->fullTableName('posts', false, false), 355 | 'old_name' => 'updated', 356 | 'new_name' => 'renamed_updated'))); 357 | $this->assertFalse($Migration->Precheck->beforeAction($Migration, 'rename_field', array( 358 | 'table' => $this->db->fullTableName('posts', false, false), 359 | 'old_name' => 'renamed_updated', 360 | 'new_name' => 'updated'))); 361 | 362 | try { 363 | $Migration->run('down'); 364 | } catch (MigrationException $e) { 365 | $this->fail('Exception triggered ' . $e->getMessage()); 366 | } 367 | } 368 | 369 | } 370 | -------------------------------------------------------------------------------- /Test/Case/Lib/MigrationVersionTest.php: -------------------------------------------------------------------------------- 1 | Version = new MigrationVersion(array( 42 | 'connection' => 'test', 43 | 'autoinit' => false 44 | )); 45 | 46 | App::build(array('plugins' => CakePlugin::path('Migrations') . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)); 47 | Configure::write('Config.language', 'en'); 48 | } 49 | 50 | /** 51 | * TearDown method 52 | * 53 | * @return void 54 | */ 55 | public function tearDown() { 56 | unset($this->Version, $this->plugins); 57 | 58 | parent::tearDown(); 59 | } 60 | 61 | /** 62 | * Test __construct method with no existing migrations table 63 | * 64 | * @return void 65 | */ 66 | public function testInitialTableCreation() { 67 | $db = ConnectionManager::getDataSource('test'); 68 | $db->cacheSources = false; 69 | $Schema = new CakeSchema(array('connection' => 'test')); 70 | $Schema->tables = array('schema_migrations' => array()); 71 | 72 | $db->execute($db->dropSchema($Schema)); 73 | $this->assertFalse(in_array($db->fullTableName('schema_migrations', false, false), $db->listSources())); 74 | 75 | $this->Version = new MigrationVersion(array('connection' => 'test', 'migrationConnection' => 'test')); 76 | $this->assertTrue(in_array($db->fullTableName('schema_migrations', false, false), $db->listSources())); 77 | } 78 | 79 | /** 80 | * TestGetMapping method 81 | * 82 | * @return void 83 | */ 84 | public function testGetMapping() { 85 | CakePlugin::load('TestMigrationPlugin'); 86 | $result = $this->Version->getMapping('test_migration_plugin'); 87 | $expected = array( 88 | 1 => array( 89 | 'version' => 1, 90 | 'name' => '001_schema_dump', 91 | 'class' => 'M4af6d40056b04408808500cb58157726', 92 | 'type' => 'TestMigrationPlugin', 93 | 'migrated' => null 94 | ), 95 | 2 => array( 96 | 'version' => 2, 97 | 'name' => '002_another_migration_plugin_test_migration', 98 | 'class' => 'AnotherMigrationPluginTestMigration', 99 | 'type' => 'TestMigrationPlugin', 100 | 'migrated' => null 101 | ) 102 | ); 103 | $this->assertEquals($result, $expected); 104 | 105 | $result = $this->Version->getMapping('migrations'); 106 | $expected = array( 107 | 1 => array( 108 | 'version' => 1, 109 | 'name' => '001_init_migrations', 110 | 'class' => 'InitMigrations', 111 | 'type' => 'Migrations', 112 | 'migrated' => '2009-11-10 00:55:34' 113 | ), 114 | 2 => array( 115 | 'version' => 2, 116 | 'name' => '002_convert_version_to_class_names', 117 | 'class' => 'ConvertVersionToClassNames', 118 | 'type' => 'Migrations', 119 | 'migrated' => '2011-11-18 13:53:32' 120 | ), 121 | 3 => array( 122 | 'version' => 3, 123 | 'name' => '003_increase_class_name_length', 124 | 'class' => 'IncreaseClassNameLength', 125 | 'type' => 'Migrations', 126 | 'migrated' => null 127 | ) 128 | ); 129 | $this->assertEquals($result, $expected); 130 | } 131 | 132 | /** 133 | * TestGetMigration method 134 | * 135 | * @return void 136 | */ 137 | public function testGetMigration() { 138 | try { 139 | $this->Version->getMigration('inexistent_migration', 'InexistentMigration', 'test_migration_plugin'); 140 | $this->fail('No exception triggered'); 141 | } catch (MigrationVersionException $e) { 142 | $this->assertEquals('File `inexistent_migration.php` not found in the TestMigrationPlugin Plugin.', $e->getMessage()); 143 | } 144 | 145 | try { 146 | $this->Version->getMigration('blank_file', 'BlankFile', 'test_migration_plugin'); 147 | $this->fail('No exception triggered'); 148 | } catch (MigrationVersionException $e) { 149 | $this->assertEquals('Class `BlankFile` not found on file `blank_file.php` for TestMigrationPlugin Plugin.', $e->getMessage()); 150 | } 151 | 152 | $result = $this->Version->getMigration('001_schema_dump', 'M4af6d40056b04408808500cb58157726', 'test_migration_plugin'); 153 | $this->assertInstanceOf('M4af6d40056b04408808500cb58157726', $result); 154 | $this->assertEquals($result->description, 'Version 001 (schema dump) of TestMigrationPlugin'); 155 | 156 | // Calling twice to check if it will not try to redeclare the class 157 | $result = $this->Version->getMigration('001_schema_dump', 'M4af6d40056b04408808500cb58157726', 'test_migration_plugin'); 158 | $this->assertInstanceOf('M4af6d40056b04408808500cb58157726', $result); 159 | $this->assertEquals($result->description, 'Version 001 (schema dump) of TestMigrationPlugin'); 160 | } 161 | 162 | /** 163 | * TestSetGetVersion method 164 | * 165 | * @return void 166 | */ 167 | public function testSetGetVersion() { 168 | $this->Version = $this->getMock('MigrationVersion', array('getMapping'), array(array('connection' => 'test'))); 169 | 170 | // Checking current 171 | $this->Version->expects($this->at(0))->method('getMapping')->will($this->returnValue($this->_mapping())); 172 | $result = $this->Version->getVersion('inexistent_plugin'); 173 | $expected = 0; 174 | $this->assertEquals($result, $expected); 175 | 176 | // Setting as 1 177 | $this->Version->expects($this->at(0))->method('getMapping')->will($this->returnValue($this->_mapping())); 178 | $this->Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 1))); 179 | $setResult = $this->Version->setVersion(1, 'inexistent_plugin'); 180 | $this->assertTrue(!empty($setResult)); 181 | $result = $this->Version->getVersion('inexistent_plugin'); 182 | $expected = 1; 183 | $this->assertEquals($result, $expected); 184 | 185 | // Setting as 2 186 | $this->Version->expects($this->at(0))->method('getMapping')->will($this->returnValue($this->_mapping(1, 1))); 187 | $this->Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 2))); 188 | $setResult = $this->Version->setVersion(2, 'inexistent_plugin'); 189 | $this->assertTrue(!empty($setResult)); 190 | $result = $this->Version->getVersion('inexistent_plugin'); 191 | $expected = 2; 192 | $this->assertEquals($result, $expected); 193 | 194 | // Setting as 1 195 | $this->Version->expects($this->at(0))->method('getMapping')->will($this->returnValue($this->_mapping(1, 2))); 196 | $this->Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 1))); 197 | $setResult = $this->Version->setVersion(2, 'inexistent_plugin', false); 198 | $this->assertTrue(!empty($setResult)); 199 | $result = $this->Version->getVersion('inexistent_plugin'); 200 | $expected = 1; 201 | $this->assertEquals($result, $expected); 202 | } 203 | 204 | /** 205 | * TestRun method 206 | * 207 | * @return void 208 | */ 209 | public function testRun() { 210 | $options = array( 211 | 'connection' => 'test', 212 | 'migrationConnection' => 'test', 213 | 'autoinit' => false 214 | ); 215 | 216 | $Version = $this->getMock('MigrationVersion', 217 | array('getMapping', 'getMigration', 'getVersion', 'setVersion'), 218 | array($options), 219 | 'TestMigrationVersionMockMigrationVersion' 220 | ); 221 | 222 | $CakeMigration = new CakeMigration($options); 223 | 224 | $Version->expects($this->any()) 225 | ->method('getMigration') 226 | ->will($this->returnValue($CakeMigration)); 227 | 228 | $Version->Version = ClassRegistry::init(array( 229 | 'class' => 'schema_migrations', 230 | 'ds' => 'test' 231 | )); 232 | 233 | // direction => up 234 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(0)); 235 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping())); 236 | $Version->expects($this->at(3))->method('setVersion')->with(1, 'mocks', true); 237 | 238 | $this->assertTrue($Version->run(array('direction' => 'up', 'type' => 'mocks'))); 239 | 240 | // direction => down 241 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(1)); 242 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 1))); 243 | $Version->expects($this->at(3))->method('setVersion')->with(1, 'mocks', false); 244 | 245 | $this->assertTrue($Version->run(array('direction' => 'down', 'type' => 'mocks'))); 246 | 247 | // direction => up 248 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(3)); 249 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 3))); 250 | $Version->expects($this->at(3))->method('setVersion')->with(4, 'mocks', true); 251 | 252 | $this->assertTrue($Version->run(array('direction' => 'up', 'type' => 'mocks'))); 253 | 254 | // direction => down 255 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(4)); 256 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 4))); 257 | $Version->expects($this->at(3))->method('setVersion')->with(4, 'mocks', false); 258 | 259 | $this->assertTrue($Version->run(array('direction' => 'down', 'type' => 'mocks'))); 260 | 261 | // version => 7 262 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(3)); 263 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 3))); 264 | $Version->expects($this->at(3))->method('setVersion')->with(4, 'mocks', true); 265 | $Version->expects($this->at(5))->method('setVersion')->with(5, 'mocks', true); 266 | $Version->expects($this->at(7))->method('setVersion')->with(6, 'mocks', true); 267 | $Version->expects($this->at(9))->method('setVersion')->with(7, 'mocks', true); 268 | 269 | $this->assertTrue($Version->run(array('version' => 7, 'type' => 'mocks'))); 270 | 271 | // version => 3 272 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(7)); 273 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 7))); 274 | $Version->expects($this->at(3))->method('setVersion')->with(7, 'mocks', false); 275 | $Version->expects($this->at(5))->method('setVersion')->with(6, 'mocks', false); 276 | $Version->expects($this->at(7))->method('setVersion')->with(5, 'mocks', false); 277 | $Version->expects($this->at(9))->method('setVersion')->with(4, 'mocks', false); 278 | 279 | $this->assertTrue($Version->run(array('version' => 3, 'type' => 'mocks'))); 280 | 281 | // version => 10 (top version) 282 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(3)); 283 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 3))); 284 | $Version->expects($this->at(3))->method('setVersion')->with(4, 'mocks', true); 285 | $Version->expects($this->at(5))->method('setVersion')->with(5, 'mocks', true); 286 | $Version->expects($this->at(7))->method('setVersion')->with(6, 'mocks', true); 287 | $Version->expects($this->at(9))->method('setVersion')->with(7, 'mocks', true); 288 | $Version->expects($this->at(11))->method('setVersion')->with(8, 'mocks', true); 289 | $Version->expects($this->at(13))->method('setVersion')->with(9, 'mocks', true); 290 | $Version->expects($this->at(15))->method('setVersion')->with(10, 'mocks', true); 291 | 292 | $this->assertTrue($Version->run(array('version' => 10, 'type' => 'mocks'))); 293 | 294 | // version => 0 (run down all migrations) 295 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(10)); 296 | $Version->expects($this->at(1))->method('getMapping')->will($this->returnValue($this->_mapping(1, 10))); 297 | $Version->expects($this->at(3))->method('setVersion')->with(10, 'mocks', false); 298 | $Version->expects($this->at(5))->method('setVersion')->with(9, 'mocks', false); 299 | $Version->expects($this->at(7))->method('setVersion')->with(8, 'mocks', false); 300 | $Version->expects($this->at(9))->method('setVersion')->with(7, 'mocks', false); 301 | $Version->expects($this->at(11))->method('setVersion')->with(6, 'mocks', false); 302 | $Version->expects($this->at(13))->method('setVersion')->with(5, 'mocks', false); 303 | $Version->expects($this->at(15))->method('setVersion')->with(4, 'mocks', false); 304 | $Version->expects($this->at(17))->method('setVersion')->with(3, 'mocks', false); 305 | $Version->expects($this->at(19))->method('setVersion')->with(2, 'mocks', false); 306 | $Version->expects($this->at(21))->method('setVersion')->with(1, 'mocks', false); 307 | 308 | $this->assertTrue($Version->run(array('version' => 0, 'type' => 'mocks'))); 309 | } 310 | 311 | /** 312 | * TestRunWithJump method 313 | * 314 | * @return void 315 | */ 316 | public function testRunWithJump() { 317 | $options = array( 318 | 'connection' => 'test', 319 | 'autoinit' => false, 320 | 'jumpTo' => '003_schema_dump' 321 | ); 322 | 323 | $Version = $this->getMock('MigrationVersion', 324 | array('getMapping', 'getMigration', 'getVersion', 'jump'), 325 | array($options), 326 | 'TestMigrationVersionMockMigrationVersions' 327 | ); 328 | 329 | $CakeMigration = new CakeMigration($options); 330 | 331 | $Version->expects($this->any()) 332 | ->method('getMigration') 333 | ->will($this->returnValue($CakeMigration)); 334 | 335 | $Version->Version = ClassRegistry::init(array( 336 | 'class' => 'schema_migrations', 337 | 'ds' => 'test' 338 | )); 339 | 340 | $Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(9)); 341 | $Version->expects($this->exactly(2))->method('jump'); 342 | $Version->expects($this->any())->method('getMapping')->will($this->returnValue($this->_mapping())); 343 | 344 | $this->assertTrue($Version->run(array('direction' => 'up', 'type' => 'mocks'))); 345 | 346 | $migrations = $Version->Version->find('count', array( 347 | 'conditions' => array( 348 | 'type' => 'mocks' 349 | ) 350 | )); 351 | 352 | $this->assertEquals(8, $migrations); 353 | } 354 | 355 | /** 356 | * TestGetVersionByName method 357 | * 358 | * @return void 359 | */ 360 | public function testGetVersionByName() { 361 | $Version = new MigrationVersion(array( 362 | 'jumpTo' => '007_schema_dump' 363 | )); 364 | 365 | $result = $Version->getVersionByName($this->_mapping()); 366 | $this->assertEquals(7, $result); 367 | 368 | $Version = new MigrationVersion(array( 369 | 'jumpTo' => '00_schema_dump' 370 | )); 371 | 372 | $result = $Version->getVersionByName($this->_mapping()); 373 | $this->assertFalse($result); 374 | } 375 | 376 | /** 377 | * _mapping method 378 | * 379 | * @param int $start 380 | * @param int $end 381 | * @return array 382 | */ 383 | protected function _mapping($start = 0, $end = 0) { 384 | $mapping = array(); 385 | for ($i = 1; $i <= 10; $i++) { 386 | $mapping[$i] = array( 387 | 'version' => $i, 388 | 'name' => "00{$i}_schema_dump", 389 | 'class' => 'M4af9d151e1484b74ad9d007058157726', 390 | 'type' => 'mocks', 'migrated' => null 391 | ); 392 | if ($i >= $start && $i <= $end) { 393 | $mapping[$i]['migrated'] = CakeTime::nice(); 394 | } 395 | } 396 | 397 | return $mapping; 398 | } 399 | } 400 | -------------------------------------------------------------------------------- /Test/Fixture/SchemaMigrationsFixture.php: -------------------------------------------------------------------------------- 1 | array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 19 | 'class' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 33), 20 | 'type' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 50), 21 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 22 | 'indexes' => array( 23 | 'PRIMARY' => array('column' => 'id', 'unique' => 1) 24 | ) 25 | ); 26 | 27 | /** 28 | * @var array 29 | */ 30 | public $records = array( 31 | array('id' => '1', 'class' => 'InitMigrations', 'type' => 'migrations', 'created' => '2009-11-10 00:55:34'), 32 | array('id' => '2', 'class' => 'ConvertVersionToClassNames', 'type' => 'migrations', 'created' => '2011-11-18 13:53:32') 33 | ); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Test/Fixture/test_migration.txt: -------------------------------------------------------------------------------- 1 | public $migration = array( 2 | 'up' => array( 3 | 'create_table' => array( 4 | 'articles' => array( 5 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 6 | 'user_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), 7 | 'title' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 8 | 'body' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 9 | 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 10 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 11 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 12 | 'indexes' => array( 13 | 'PRIMARY' => array('column' => 'id', 'unique' => 1), 14 | ), 15 | 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'), 16 | ), 17 | 'posts' => array( 18 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 19 | 'author_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false), 20 | 'title' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 21 | 'body' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 22 | 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 23 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 24 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 25 | 'indexes' => array( 26 | 'PRIMARY' => array('column' => 'id', 'unique' => 1), 27 | ), 28 | 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'), 29 | ), 30 | 'users' => array( 31 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 32 | 'user' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 33 | 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 34 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 35 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 36 | 'indexes' => array( 37 | 'PRIMARY' => array('column' => 'id', 'unique' => 1), 38 | ), 39 | 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MEMORY'), 40 | ), 41 | ), 42 | ), 43 | 'down' => array( 44 | 'drop_table' => array( 45 | 'articles', 'posts', 'users' 46 | ), 47 | ), 48 | ); -------------------------------------------------------------------------------- /Test/Fixture/test_migration_add_fields_from_cli.txt: -------------------------------------------------------------------------------- 1 | public $migration = array( 2 | 'up' => array( 3 | 'create_field' => array( 4 | 'products' => array( 5 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 6 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 7 | 'modified' => array('type' => 'datetime', 'null' => false, 'default' => null), 8 | 'name' => array('type' => 'string', 'null' => false, 'default' => null), 9 | 'description' => array('type' => 'text', 'null' => false, 'default' => null), 10 | 'in_stock' => array('type' => 'boolean', 'null' => false, 'default' => null), 11 | 'price' => array('type' => 'float', 'null' => false, 'default' => null), 12 | 'stock_count' => array('type' => 'integer', 'null' => false, 'default' => null), 13 | 'indexes' => array( 14 | 'PRIMARY' => array('column' => 'id', 'unique' => true), 15 | ), 16 | ), 17 | ), 18 | ), 19 | 'down' => array( 20 | 'drop_field' => array( 21 | 'products' => array('id', 'created', 'modified', 'name', 'description', 'in_stock', 'price', 'stock_count'), 22 | ), 23 | ), 24 | ); -------------------------------------------------------------------------------- /Test/Fixture/test_migration_create_table_from_cli.txt: -------------------------------------------------------------------------------- 1 | public $migration = array( 2 | 'up' => array( 3 | 'create_table' => array( 4 | 'products' => array( 5 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 6 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 7 | 'modified' => array('type' => 'datetime', 'null' => false, 'default' => null), 8 | 'name' => array('type' => 'string', 'null' => false, 'default' => null), 9 | 'description' => array('type' => 'text', 'null' => false, 'default' => null), 10 | 'in_stock' => array('type' => 'boolean', 'null' => false, 'default' => null), 11 | 'price' => array('type' => 'float', 'null' => false, 'default' => null), 12 | 'stock_count' => array('type' => 'integer', 'null' => false, 'default' => null), 13 | 'indexes' => array( 14 | 'PRIMARY' => array('column' => 'id', 'unique' => true), 15 | ), 16 | ), 17 | ), 18 | ), 19 | 'down' => array( 20 | 'drop_table' => array( 21 | 'products' 22 | ), 23 | ), 24 | ); -------------------------------------------------------------------------------- /Test/Fixture/test_migration_drop_table_from_cli.txt: -------------------------------------------------------------------------------- 1 | public $migration = array( 2 | 'up' => array( 3 | 'drop_table' => array( 4 | 'products' 5 | ), 6 | ), 7 | 'down' => array( 8 | ), 9 | ); -------------------------------------------------------------------------------- /Test/Fixture/test_migration_remove_fields_from_cli.txt: -------------------------------------------------------------------------------- 1 | public $migration = array( 2 | 'up' => array( 3 | 'drop_field' => array( 4 | 'products' => array('name', 'description'), 5 | ), 6 | ), 7 | 'down' => array( 8 | ), 9 | ); -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin/Config/Migration/001_schema_dump.php: -------------------------------------------------------------------------------- 1 | array(), 18 | 'down' => array() 19 | ); 20 | 21 | /** 22 | * Before migration callback 23 | * 24 | * @param string $direction Direction of migration process (up or down) 25 | * @return bool Should process continue 26 | */ 27 | public function before($direction) { 28 | return true; 29 | } 30 | 31 | /** 32 | * After migration callback 33 | * 34 | * @param string $direction Direction of migration process (up or down) 35 | * @return bool Should process continue 36 | */ 37 | public function after($direction) { 38 | return true; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin/Config/Migration/002_another_migration_plugin_test_migration.php: -------------------------------------------------------------------------------- 1 | array(), 18 | 'down' => array() 19 | ); 20 | 21 | /** 22 | * Before migration callback 23 | * 24 | * @param string $direction Direction of migration process (up or down) 25 | * @return bool Should process continue 26 | */ 27 | public function before($direction) { 28 | return true; 29 | } 30 | 31 | /** 32 | * After migration callback 33 | * 34 | * @param string $direction Direction of migration process (up or down) 35 | * @return bool Should process continue 36 | */ 37 | public function after($direction) { 38 | return true; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin/Config/Migration/blank_file.php: -------------------------------------------------------------------------------- 1 | array('001_schema_dump' => 'M4af6d40056b04408808500cb58157726') 4 | ); -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin/Config/Schema/Schema.php: -------------------------------------------------------------------------------- 1 | array('type' => 'integer', 'key' => 'primary'), 16 | 'user_id' => array('type' => 'integer', 'null' => false), 17 | 'title' => array('type' => 'string', 'null' => false), 18 | 'slug' => array('type' => 'string', 'null' => false), 19 | 'body' => array('type' => 'text', 'null' => true, 'default' => null), 20 | 'published' => array('type' => 'string', 'null' => true, 'length' => 1, 'default' => 'N'), 21 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 22 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 23 | 'indexes' => array( 24 | 'PRIMARY' => array('column' => 'id', 'unique' => true) 25 | ) 26 | ); 27 | 28 | public $schema_migrations = array( 29 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 30 | 'version' => array('type' => 'integer', 'null' => false, 'default' => null), 31 | 'type' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 50), 32 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 33 | 'indexes' => array( 34 | 'PRIMARY' => array('column' => 'id', 'unique' => 1) 35 | ) 36 | ); 37 | 38 | } -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin2/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CakeDC/migrations/988730b04933d5f14bc09e808654ffd32b720c63/Test/test_app/Plugin/TestMigrationPlugin2/empty -------------------------------------------------------------------------------- /Test/test_app/Plugin/TestMigrationPlugin3/Config/Migration/map.php: -------------------------------------------------------------------------------- 1 | array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 16 | 'user_id' => array('type' => 'integer', 'null' => true, 'default' => null), 17 | 'title' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 18 | 'slug' => array('type' => 'string', 'null' => false), 19 | 'body' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 20 | 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 21 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 22 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 23 | 'indexes' => array( 24 | 'PRIMARY' => array('column' => 'id', 'unique' => true) 25 | ), 26 | ); 27 | 28 | public $posts = array( 29 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 30 | 'author_id' => array('type' => 'integer', 'null' => false, 'default' => null), 31 | 'title' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 32 | 'charset' => 'utf8'), 33 | 'body' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 34 | 'charset' => 'utf8'), 35 | 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1, 36 | 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), 37 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 38 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 39 | 'indexes' => array( 40 | 'PRIMARY' => array('column' => 'id', 'unique' => 1), 41 | ), 42 | ); 43 | 44 | public $users = array( 45 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 46 | 'user' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 47 | 'charset' => 'utf8'), 48 | 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 49 | 'charset' => 'utf8'), 50 | 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 51 | 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), 52 | 'indexes' => array( 53 | 'PRIMARY' => array('column' => 'id', 'unique' => 1), 54 | ), 55 | ); 56 | 57 | public $schema_migrations = array( 58 | 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'), 59 | 'version' => array('type' => 'integer', 'null' => false, 'default' => null), 60 | 'type' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 50), 61 | 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), 62 | 'indexes' => array( 63 | 'PRIMARY' => array('column' => 'id', 'unique' => 1) 64 | ) 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /View/Elements/migrations_panel.ctp: -------------------------------------------------------------------------------- 1 | 12 |

13 |
14 | 15 | Toggle Applied migrations 16 | 17 | $migration) { 19 | if (empty($migration['map'])) { 20 | continue; 21 | } 22 | $migration = array_reverse($migration); 23 | ?> 24 |
25 |

26 | $info) { 28 | if (empty($info['migrated'])) { 29 | $status = array( 30 | 'color' => '#fcc', 31 | 'image' => 'http://cakephp.org/img/test-fail-icon.png'); 32 | } else { 33 | $status = array( 34 | 'color' => '#cfc', 35 | 'image' => 'http://cakephp.org/img/test-pass-icon.png'); 36 | } 37 | ?> 38 |
39 | 40 |
41 | 45 |
46 | 111 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cakedc/migrations", 3 | "description": "Migrations Plugin for CakePHP", 4 | "type": "cakephp-plugin", 5 | "keywords": ["cakephp","migrations"], 6 | "homepage": "http://cakedc.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Cake Development Corporation", 11 | "email": "team@cakedc.com", 12 | "homepage": "http://cakedc.com" 13 | } 14 | ], 15 | "support": { 16 | "email": "team@cakedc.com", 17 | "issues": "https://github.com/CakeDC/migrations/issues", 18 | "forum": "http://stackoverflow.com/tags/cakedc", 19 | "wiki": "https://github.com/CakeDC/migrations/blob/master/Docs/Home.md", 20 | "irc": "irc://irc.freenode.org/cakephp", 21 | "source": "https://github.com/CakeDC/migrations" 22 | }, 23 | "require": { 24 | "php": ">=5.6.0", 25 | "composer/installers": "*" 26 | } 27 | } 28 | --------------------------------------------------------------------------------