Saturday, 4 July 2015

How to become a Strehler developer

Strehler is a strange package to develope. It's easy to install from repository and use, but while you are just writing it you have to arrange many tricks to be confortable with the work. For example, Strehler needs a Dancer2 site to run, something the respository doesn't contain.

In this little tutorial I'll try to explain how to setup an environment to become a Strehler developer, because Strehler needs you, as any of the packages published on CPAN. It's a very basic tutorial, useful for beginners too.

I hope it will help.

The repository

You probably already have a sandbox created in one of the many ways available for perl development. I'm still a fan of the good'ol local::lib but it's good to use also, for example, perlbrew. Your sandbox has to be active during Strehler development and you have to put in it Dancer2
cpanm --notest Dancer2
But NOT Strehler. After installing Dancer2 most of the library useful to work with Strehler will be in place, but probably you'll need something more, libraries specific to Strehler work. Just install them in your sandbox the same way using cpanm when running the code point out their absence..

You'll surely need:

All this packages are in the requirements of Strehler package and would come automatically installing Strehler for CPAN. Installing them manually is the cleanest way to obtain them, but you can try some trick, like installing Strehler and then deleting it from repository, keeping all its dependencies.

The code

Just pull down all the source from the git repository in a directory you like
git pull git@github.com:cym0n/strehler.git 
Downloading the repository you'll have a directory named $GITURL/src/lib and one named $GITURL/src/script. These two directories will come useful soon.

The environment

Now that you have Strehler code it's easy to modify it and manage changes using git. Less obvious how to use this code and see it working. We just need to customize a little the environment. Open a file named strehler-devel and put in it
alias perl="perl -I$GITURL/src/lib"
alias strehler="perl -I$GITURL/src/lib $GITURL/src/script/strehler"
When the file is ok source it.
source strehler-devel

Testing site

All Strehler power is now available, coming directly from the git repository on your machine. Now you can easly create a testing site with Strehler onboard using strehler script itself.
strehler demo 
Just run it as
perl bin/app.pl 
to see Strehler and (eventually) your modifications in action.


Monday, 9 February 2015

Manipulating databases

Database management is something very difficult to do, because databases are strange things created by strange people and database are also many, each of them doing things the way they think better. There'ra no two databases that thinks the same way.

When I wrote strehler initdb command I was quite impressed by the deploy function of DBIx::Class::Schema that worked like magic , creating databases as I want, But creating a database from zero is an easy task, changing an existing one, possibly without DROP TABLE commands that trash data is more interesting.

There're packages that do exactly this, like DBIx::Class::Schema::Versioned, but they have a static management. You build your database, you give a version to your schema. You change your database, you give another version and something calculate the diff. It's good, but I was looking for something more dynamic.

Why doesn't a dynamic way to change database exist? Because, obviously, changing a database dynamically is a bad idea in many cases, you should have control on it, but I wasn't thinking about a CMS that change databases through a web interface, I just wanted to do it as a script, to embed it in my strehler script.
And I want to cver just the easy case where I add brand new tables, no modifications to the existing ones.

My first option was starting from schema. I took my existing DBIx::Class::Schema, I added my tables to it with register method and then I tried a new deploy, turning off the DROP TABLE option. Result was good but... DBIC gave me back a bunch of error about existing tables that it cannot create again, so the output of the operation was really dirty.

Problem is that noone considered the concept of deploying just a table and, for me, deploying a schema containing only new tables wasn't enough, because this way all the foreign keys to old tables wouldn't be created.

Solution I found is dirty but... it works and, for now, I didn't find a way to break it. Starting point is the same of the precedent case: take DBIx::Class::Schema and add new tables to it registering DBIx::Classes. Then there's some dirty work you have to do by yourself.

A step back: deploy function in DBIx::Class::Schema starts from your schema, create queries from it considering the target database and then execute them. The tool that extract queries from yout classes is SQL::Translator and you can use it also without DBIx::Schema::Class deploy function.

You can run SQL::Translator on your original schema, obtaining a list of queries to create it. Then you can run it on you database modified using register function. Considering that you're just adding tables you'll have a new array with same queries from before and a couple of new ones.

Deploying new tables only is about calculating the diff between these two arrays and run just it on your DBIC connector... with little tricks to avoid running queries in wrong order.

If you want to see an implementation of this little hack you can see it in Strehler::Element::Role::Maintainer.