The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

DBIx::Class::TopoSort - The addition of topological sorting to DBIx::Class

SYNOPSIS

Within your schema class:

__PACKAGE__->load_components('TopoSort');

Later:

my $schema = Your::App::Schema->connect(...);
my @toposorted_sourcenames = $schema->toposort();

If you have a cycle in your relationships

my @toposorted_sourcenames = $schema->toposort(
    skip => {
        Artist => [qw/ first_album /],
    },
);

Alternately:

my @toposorted_sourcenames = DBIx::Class::TopoSort->toposort($schema);

DESCRIPTION

This adds a method to DBIx::Class::Schema which returns the full list of sources (similar to "sources" in DBIx::Class::Schema) in topological-sorted order.

TOPOLOGICAL SORT

A topological sort of the tables returns the list of tables such that any table with a foreign key relationship appears after any table it has a foreign key relationship to.

METHODS

This class is not instantiable nor does it provide any methods of its own. All methods are added to the DBIx::Class::Schema class and are callable on objects instantiated of that class.

toposort

This is sugar for:

$self->toposort_graph(@_)->toposort();

Calling this method multiple times may return the list of source names in different order. Each order will conform to the gurantee described in the section on TOPOLOGICAL SORT.

This method will throw an error if there are any cycles in your tables. You will need to specify the skip parameter (described below) to break those cycles.

toposort (Class method)

Alternately, if you do not wish to use TopoSort as a component, you can call it as a class method on this class. The toposort() method is smart enough to distinguish.

Note: toposort_graph() does not distinguish - it assumes it will be called with the $schema object passed in.

toposort_graph

This returns a Graph object with a vertex for every source and an edge for every foreign key relationship.

It takes the following parameters.

skip

This describes the list of relationships that should be ignored by the toposort algorithm. This is generally used if you have cycles in your schema (though it could possibly be useful in other ways, I guess). The value is a hashref. The keys of this hashref are source names and the values are arrays of relationship names.

skip => {
    Artist => [ qw/ first_album / ],
},
add_dependencies

This is the opposite of skip. Instead of removing connections between sources, this adds them. Unlike skip, you don't specify the relationship. Instead, you just specify that the child depends on the parent.

add_dependencies => {
    Album => 'Artist',
},

If you want to add multiple dependencies from one child, you can provide an array of new parents as so:

add_dependencies => {
    Album => [ 'Artist', 'Studio' ],
},

Adding dependencies for multiple tables looks like this:

add_dependencies => {
    Album => 'Artist',
    Artist => 'Producer',
},

The child and parent sources must exist or errors will be thrown. Adding a dependency that already exists is a no-op.

detect_cycle

If this is true, then "find_a_cycle" in Graph will be called and, if a cycle is found, this will die detailing the cycle found.

This is useful because the "toposort" in Graph method dies with a cyclic graph, but doesn't tell you what any of the cycles are that killed it.

NOTE: Finding cycles can be expensive. Don't do this on a regular basis.

enable_toposort_memoize (Class method)

This will "memoize" in Memoize the "toposort" function. By default, it uses a normalizer function that concatenates the following (in order):

  • The PID of this process

  • The class of the schema

  • The canonicalized JSON of any options provided.

You may pass in a different function if you need to.

disable_toposort_memoize (Class method)

This will disable any memoize on "toposort". Unlike "unmemoize" in Memoize, this will not croak if you haven't already memoized.

SEE ALSO

"toposort" in Graph

AUTHOR

  • Rob Kinyon <rob.kinyon@gmail.com>

CONTRIBUTIONS

Contributions have been generously donated by ZipRecruiter.

LICENSE

Copyright (c) 2013 Rob Kinyon. All Rights Reserved. This is free software, you may use it and distribute it under the same terms as Perl itself.