---
name: "Catmandu::DirectoryIndex"
section: "3pm"
platform: "linux"
package: "libcatmandu-filestore-perl"
version: "1.16-3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Catmandu::DirectoryIndex"
---

# Catmandu::DirectoryIndex(3pm)

A base role to store relations between id's and directories

## NAME

Catmandu::DirectoryIndex - A base role to store relations between id's and directories

## SYNOPSIS

```
    package MyDirectory;
    use Moo;
    use File::Spec;
    use File:Basename;
    use Path::Tiny qw(path);
    with "Catmandu::DirectoryIndex";
    # translate id to directory
    sub _to_path {
        my ( $self, $id ) = @_;
        File::Spec->catdir( $self->base_dir(), $id );
    }
    sub get {
        my ( $self, $id ) = @_;
        my $path = $self->_to_path( $id );
        is_string( $path ) && -d $path ? { _id => $id, _path => $path } : undef;
    }
    sub add {
        my ( $self, $id ) = @_;
        my $path = $self->_to_path( $id );
        path( $path )->mkpath unless -d $path;
        { _id => $id, _path => $path };
    }
    sub delete {
        my ( $self, $id ) = @_;
        my $path = $self->_to_path( $id );
        if ( is_string( $path ) && -d $path ) {
            path( $path )->remove_tree();
        }
    }
    sub delete_all {
        path( $_[0]->base_dir )->remove_tree({ keep_root => 1 });
    }
    # return a generator that returns list of records, that maps _id and _path
    sub generator {
        my $self = $_[0];
        return sub {
            state $records;
            if ( !defined( $records ) ) {
                $records = [];
                opendir my $dh, $self->base_dir() or die($!);
                while( my $entry = readdir( $dh ) ){
                    if ( -d $entry ) {
                        push @$records, {
                            _id => $entry,
                            _path => File::Spec->catfile( $self->base_dir, $entry )
                        };
                    }
                }
                closedir $dh;
            }
            shift( @$records );
        };
    }
    package main;
    my $p = MyDirectory->new( base_dir => "/tmp" );
    Catmandu->store->bag->each(sub {
        my $r = $_[0];
        my $mapping = $p->get( $r->{_id} ) || $p->add( $r->{_id} );
        say $id . " => " . $mapping->{path};
    });
```

## CLASS METHODS AVAILABLE

### new( base\_dir =\> $base\_dir )

- base\_dir

  The base directory where the files are stored. Required

## METHODS AVAILABLE

- base\_dir

  ## METHODS TO IMPLEMENT

Implementors must implement these methods

- add( $id ) : $mapping

  \* Accepts `$id` as string

  \* Translates `$id` to directory path

  \* Creates directory if necessary

  \* Returns HASH with keys `"_id"` and `"_path"`

  This method should throw an Catmandu::Error when it detects an invalid id.

  It should either return the mapping or throw an error.

- get( $id ) : $mapping

  \* Accepts `$id` as string

  \* Translates `$id` to directory path

  \* Returns HASH with keys `"_id"` and `"_path"`, if a path exists for `$id`

  This method should throw an Catmandu::Error when it detects an invalid id.

  Difference with method "add":

  \* no directory created

  \* no mapping returned if no existing directory could be found

- delete ( $id )

  \* Accepts id as string

  \* Translates id to directory

  \* Removes directory if it exists

  \* Do other internal cleanup actions if any required

  This method should throw an Catmandu::Error when at failure.

- **delete\_all()**

  \* Deletes files/directories in base\_dir. Please keep the base\_dir.

  \* Do other internal cleanup actions if any required

  This method should throw an Catmandu::Error when at failure.

- **generator()**

  Inherited requirement from Catmandu::Iterable:

  \* return function reference

  \* every call to this function must return the next directory entry in the index as a HASH with keys `"_id"` and `"path"`

## INHERITED METHODS

This Catmandu::DirectoryIndex inherits:

- Catmandu::Iterable

  So all functions from Catmandu::Iterable are available to these objects.

## SEE ALSO

Catmandu::Store::File::Simple , Catmandu::DirectoryIndex::UUID , Catmandu::DirectoryIndex::Number , Catmandu::DirectoryIndex::Map
