Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catalyst & Perl - Generate models in runtime

I'm working on an application that will generate database tables on runtime. I'm using Catalyst with DBIC and I need that when a new table is generated a new ResultSet is generated. This new ResultSet has to be added as a Catalyst Model so I can $c->model('DB::NewFoo') but I need this to happen at runtime.

The table generation and ResultSet generation is not the problem, what I need is to add in runtime those newly generated ResultSet to the Model so I can call them in further requests.

So far my idea is to make a Class that controls the DBI::Class::Schema, gives accessor methods and provide a method to update and reload the Schema in runtime. I would like a different idea which uses Catalyst itself.

Thanks for all the help you can give.

like image 298
Wang Avatar asked Nov 02 '22 03:11

Wang


1 Answers

This isn't perfect, but it worked for us.

If you overload the model method inside your MyApp.pm file to look something like this:

 sub model {
    my ($self, $model, @rest) = @_;

    if (my ($rs) = $model =~ m/^DB::(.+)$/) {
       $self->model('DB')->schema->resultset($rs)
    } else {
       return $self->next::method($model, @rest);
    }
 }

and then put something like this in your Schema.pm:

 use List::Util 'first';
 sub resultset {
    my ($self, $rs) = @_;
    unless (first { $_ eq $rs } $self->sources) {
       eval "require MyApp::Schema::NonDefaultResult::$rs";
       $self->register_class("$rs", "MyApp::Schema::NonDefaultResult::$rs");
    }
    return $self->next::method($rs);
 }

The gist is that now if you ask for a resultset that isn't loaded it gets loaded at runtime from some other namespace (as you might want to still load many other results at compile time.)

We've been using this for years for a set of hundreds of generated tables and it's worked well.

like image 131
Frew Schmidt Avatar answered Nov 13 '22 02:11

Frew Schmidt