jcfiala: (Default)
[personal profile] jcfiala

This is a blog post copied from John's Website - please feel free to join him there and post comments. He has set up openid, so you can post there with your livejournal account using your openid, which is the same as your journal url minus the http://. You can find this entry at http://www.jcfiala.net/blog/2014/08/21/using-doctrine-migrations-without-orm.

Recently I was handed a PHP project at work which already existed but the owner wanted a variety of tweaks and improvements added to it. The project wasn't built with any framework I could name, and although it has a sort of MVC feel to it, is not strictly an MVC project.

One of the first challenges I ran into is that one of my fixes involves changing the structure of a table on the project, and another one involves creating a new table, both changes I wanted to set up in code so they would be moved along by source control. When I'm working in Drupal this is easily handled via hook_update_N, but I figured in this case the thing to do was to figure out something I could add using composer. Some quick looking around on http://www.phptherightway.com/ and Packagist caused me to settle on the 1.x branch of Doctrine Migrations. (The 2.x branch was marked as alpha as I write this, so I didn't want to use it.)

1) Installing with Composer

I'm not going to get into details about Composer, but if you're not familiar with it I suggest taking the time to do it. Here's the composer.json I ended up with when everything was working:

{
    "require": {
        "doctrine/migrations": "1.0.*@dev",
        "symfony/console": "2.6.*@dev",
        "symfony/yaml": "2.4.*@dev"
    },
    "autoload": {
        "psr-4": {"ClientName\\": "src/"}
    }

}

The doctrine/migrations pulls in the migration code (and it's dependencies), the symfony/console adds support to command line control of the migrations which for me was similar to Drupal's drush utility, and the symfony/yaml is needed for yaml config files for the migration. It's not strictly a dependency of doctrine/migrations because you could use other config files (such as xml), but if you're going to use yaml you need this.

2) Create Console.php for handling console commands.

The name of the file doesn't really matter in this case, it just needs to be an executible php file. I started out with this tutorial/introduction, which showed me how the basics fit together. Once this was working I went back and added more commands via $application->add(new ImportCommand);, looking through the migration code directories for the directories Tools/Console/Command and including them. Once this was done, I could enter
%>./console.php list

To get a list of the available doctrine commands.

3) Create migrations-db.php

I went down some false starts here, but I ended up creating a migrations-db.php file which returns the connection information for my database:

<?php
require_once 'dbconfig.php';
return array(
   
'dbname' => DATABASE_NAME,
   
'user' => DATABASE_USER,
   
'password' => DATABASE_PASS,
   
'host' => DATABASE_HOST,
   
'driver' => 'mysqli',
);
?>

As it happens, the already existing dbconfig.php file was populating these constants depending on the environment, so this ended up being pretty short and sweet. This file goes in the same directory as the console.php.

4) Create migrations.yml

This is one of the tasks that tripped me up due to using the 1.0 version of migrations, instead of the (currently alpha) 2.0. The new docs for 2.x say that this should be configuration.yml in one place, and migrations.yml in another. I'm not sure if that's a bug or not... in any case, naming the file to migrations.yml worked fine, and I just went with the defaults:

name: Client Name Migrations
migrations_namespace: DoctrineMigrations
table_name: doctrine_migration_versions
migrations_directory: /src/Migrations/DoctrineMigrations

The src directory is one I created for the new object oriented code that I'm adding to the project. That basically says "this is where we're putting the migration classes."

5) Create a Migration

Once you've got this all working, it's pretty simple from here on out. Create a migration on the command line:

%>./console.php migrations:generate

This will create a neat little file for you, already named and correctly built, with empty up and down functions. Now you can go in and add code in the up function to make the changes you want, and in the down function to undo the changes - so if you're creating a new table in the up function, you would drop it in the down.

The code you write uses the Schema object that is a parameter for the function and Doctrine's database abstraction & access layer (DBAL) to add and remove database objects. You can just use

<?php
$this
->addSql('query');
?>
to make database calls, but the DBAL works just fine.

6) Run the Migration

With that all done, you can now call
%>./console.php migrations:status
to see the waiting migration to run, and when you're ready you can call
%>./console.php migrations:execute [date] to run the migration in question - there's a good amount of info on running and backing out changes if you simply call
%>./console help migrations:execute

And that's that. Getting the code in place and configured properly took some skull-sweat, but once you've got the code to the point where you can generate a new migration file the rest of it is pretty simple to work out.

(I ended up writing another article about migrations.)

April 2017

S M T W T F S
      1
234567 8
910 11121314 15
161718 19202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 27th, 2017 03:42 pm
Powered by Dreamwidth Studios