perldbix-classdbicdump

DBIx::Class, dbicdump and table prefix


I have a MySQL (MariaDB) database with some tables inside. All table names have some prefix, like app_author, app_album, app_track (in fact, there are different tables, but an example with author-album-track should be usable here). I use dbicdump to dump my DB structure. The problem is, generated result sets are named AppAuthor, AppAlbum, AppTrack. My defined relations between a table to referenced table are named by columns in those tables, the other way is named by tables.

Let's create some tables to ilustrate this:

create table app_author (
  id int not null,
  name varchar(255),
  primary key(id)
);
create table app_album (
  id int not null,
  name varchar(255),
  author int not null references app_author (id),
  primary key (id)
);
create table app_track (
  id int not null,
  name varchar(255),
  album int not null references app_album (id),
  primary key(id)
);

And example usage in Perl would be like this:

my $album = resultset("AppAlbum")->search(...)->single; # [1]
my $author = $album->author;
for my $track ($album->app_tracks) { # [2]
...
}

My questions:

  1. Is there possibility to tell dbicdump to ignore those "app_" prefixes and create result sets named without it, e.g. Author, Album, Track?

  2. How to automatically create relations without "app_" prefix?

I know I could create my result sets by hand, but then I would need to synchronize DB to my DB model by hand each time I change DB (which is quite often in current stage of application implementation). I would prefer some configuration to dbicdump to automate this, but I was unable to find this in docs.

Currently I use this in my code:

my $PREFIX = "app_";
...
my $album = resultset("${PREFIX}Album")->search(...)

And also in my result set classes generated by dbicdump I always add "correct" relations like this to be able to use $album->tracks:

package MyApp::DB::Result::AppAlbum;
...
# Created by DBIx::Class::Schema::Loader v0.07052 @ 2024-05-21 11:41:20
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:TvdTvR2Iuo++AHLi0SHc3g

sub tracks ($self)
{
    return $self->app_tracks;
}

Thank you for your advices.


Solution

  • Finally I found the working solution. We need 2 files:

    File db_dump.sh to run dbicdump in turn with desired configuration:

    #!/bin/sh
    
    export PERL5LIB=../perl5lib/lib/perl5
    
    ../perl5lib/bin/dbicdump \
        -o config_file=./db_dump.pm \
        -o dump_directory=./lib \
        MyApp::DB \
        dbi:mysql:database=mydb dbuser dbpass \
        '{ quote_char => "`" }'
    

    File db_dump.pm for configuration of dbicdump. I included versions with hashref and subs (my preferred versions):

    {
        constraint => '^(?:user|session|app_.*)$',
        moniker_map => sub {
            my ($table, $moniker, $callable) = @_;
            #return "$table"; # $moniker = $table_name
            $moniker =~ s/^App//;
            return $moniker;
        },
    #    moniker_map => {
    #        app_author => "Author",
    #        app_album  => "Album",
    #        app_track  => "Track",
    #    },
        rel_name_map => sub {
            my ($a, $coderef) = @_;
            return unless $a->{type} eq "has_many";
            $a->{name} =~ s/^app_//;
            return $a->{name};
        },
    #    rel_name_map => {
    #        Author => { # name all changes to Author's relationships
    #            app_albums => "albums",
    #        },
    #        Album => { # name all changes to Album's relationships
    #            app_tracks => "tracks",
    #        },
    #    },
    }
    

    Now run db_dump.sh and all classes are dumped from DB and placed as respective files in ./lib/MyApp/DB/Result/.

    Some random notes:

    For more, read https://metacpan.org/pod/DBIx::Class::Schema::Loader::Base, everything is there. In fact, too much info in there :)