Migration direction has matter!

We often rely on our tools and just deploy new DB versions and move on.

Lets see these simple examples.
Example 1
You have Schema v1 where table's column has the name `X`. At the next Schema v2 instead of it you created column named `Y`.

v1 -> v2
X -> -
- -> Y

So the tool correctly drops the `X` and creates `Y`.
Example 2:
For downgrades it looks the similar:

v2 -> v1
Y -> -
- -> X

Simple! Right??

Example 3
Let's do it in more adv…

Mojolicous: configure plugin's actions

While writing plugins we can do something:

$app->plugin( Auth => {
    user_check =>  sub{
        my( $user ) =  @_;

        # authentication_code_here;
    },
);

But I prefer to keep my sturtup sub clean. Thus I route to controller’s action:

$app->plugin( Auth => { auth_check => 'auth#check' } );

Doing so I need to check in my plugin passed value. Is it sub or shortcut auth#check?

And to simplify checking I implement next route shourtcut

sub register {
    my( $plugin, $app, $conf ) =  @_;

    $app->routes->add_shortcut( xto =>  \&xto );
    ...
    $app->routes->post  ( '/auth' )->xto( $conf->{ auth_check } )
        ->name( 'authenticate' );
}

sub xto {
    my $r =  shift;
    ref $_[0] eq 'CODE'?
        $r->to({ cb => $_[0] }):
        $r->to( @_ );

    return $r;
}

Unfortunately this is not supported by core ->to. I do not know why.

Finally when we create route we want bind it to some action. The callback and controller’s method are both actions: 1

my $cb = $field->{cb};
$self->_callback($c, $cb, $last);
...
_action($app, $c, $cb, $last);

and 2

$self->_controller($c, $field, $last);
my $method = $field->{action};
my $sub = $new->can($method);
...
_action($app, $new, $sub, $last);

Supporting this via ->to interface seems natural, does not?

I discuss this on IRC. kraih was nor against, nor support that. Just not enough votes from other members.

How to pass arguments for Mojolicious filter

Sometimes we are required to check incoming IDs not only for format, but also for existence in DB.

But different IDs we should check through different models.

This pull request tries to add this functionality. If it will be appiled you can do next:

$v->required( 'invoice_id', [ data_exists => 'Invoice' ] );
$v->required( 'order_id', [data_exists => 'Order' ] );

And the fileter:

$v->add_filter( data_exists => sub { data_exists( $app, @_ ) } );

sub data_exists {
    my( $app, $v, $name, $value, $model ) =  @_;

    my $obj =  $app->rows( $model )->find( $value )
       or return ();

    return $obj;
}

If you want your model do advanced decision about its data accessible or not you may pass current context:

$v->required( 'invoice_id', [ data_exists => $c, 'Invoice' ] );

The filter:

sub data_exists {
    my( $v, $name, $value, $c, $model ) =  @_;

    my $obj =  $c->rows( $model )->find( $value )
       or return ();

    return $obj;
}

And somewhere in the model:

sub rows {
    my( $c, $table_name ) = @_;
    ...
    $c->db->relation_ship( $table_name )->search({ user_id => $c->uid });
}

So after validation you are guarantied to have objects which are allowed to access only for current user.

And there is no way to access other objects the user do not own

Soft call operator: ~> (thoughts)

Short presentation of The new Perl debugger

The link of the project

You may Download presentation or view short video

The main feature of new debugger is debugging debugger commands. Yes you may debug itself (reentrance is not limited). This mean you may extend debugger easily. That is possible because of state of each debugger "copy" is saved in special array accessible through $DB::state

To enable debugger debugging (dd) you turn on this state then run command, you want to debug, after that. Example how to enable debugging debugger command 'step over' (n):

DB::state( 'dd', 1 );
n

Besides new debugger you get the new method to debug scripts and may forget about debugging by 'print' statements.

Now you just put special comment: #DBG: EXPR #

my $x =  { a =>  7 };

for( 1 .. 3 ) {
  #DBG:iter $_ #
  $x->{ a }++;
}

#DBG: e $x #

and get extended output while running script under debugger like this:

$ perl -d:DebugHooks::KillPrint            t.pl

1
2
3
{ a => 10 }

You may also limit output by writing the name of expression you are interested in:

$ perl -d:DebugHooks::KillPrint=iter       t.pl

1
2
3