> > > > Another option is that Test::Database could provide a function that
> > > > returns a unique prefix for a given script, so that the test script
> > > > can use that when creating the tables. That would provide isolated
> > > > "namespaces", and then we don't have to deal with locking directly.
> > > > With that namespace, we can even let Test::Database do things like
> > > > "drop all tables in that namespace".
> > > 
> > > That's the approach DBIT is taking. There's a basic start in here:
> > > https://github.com/perl5-dbi/DBI-Test/blob/master/sandbox/tim/lib/DBI/Test/FixtureProvider/GenericBase.pm#L49
> > > I'd be very happy to see that factored out into a separate distro.
> > > I'd rather it wasn't shipped within Test-Database though as I think it
> > > has wider uses.
> > 
> > OK. Do you have a name in mind already? The namespace:: top-level seems
> > to be mostly about Perl namespaces.
> > 
> > It seems to me that it's something that should have various "strategies"
> > to generate a "namespace". Like, which character set is available,
> > are there any length limits, that kind of thing. The constraints are
> > different for table names, database names, etc.
> > 
> > And I'll expand by just copying and pasting the comments from
> > DBI::Test::FixtureProvider::GenericBase:
> > 
> >     # could also provide methods to:
> >     # - supply a regex that matches the get_dbit_temp_name name
> >     # - parse a get_dbit_temp_name to extract especially the yymmddhh
> >     # - drop all get_dbit_temp_name tables older than N hours (0=all)
> 
> I think all that's needed, at least for now, is something like:
> 
>     $np = NameProvider->new(style => 'basic', prefix => 'dbit');
>     $name = $np->generate_new_name;
>     my @names = grep { $np->is_generated_name($_) } @names;
>     $regex = $np->get_generated_name_regex;
>     $hash = $np->parse_generated_name($name); # eg to get date etc
> 
> I expect the format that DBIT is planning to use (see link above) would
> suffice for all the databases we're currently targeting.
> (Test::Database could support alternative providers via a config option
> to set the name of the style, and/or the name of the provider class.)
> 
> I'll do some prototype work and start a new thread with a more concrete
> proposal, including a class name :)

Sorry for the delay BooK. Here's a more concrete proposal for a
Data::ShortNameProvider module.

The module description would be something like:

    Create short names that encode a timestamp and a fixed prefix in a
    format that's unlikely to match normal names.
    
    A typical use-case would be the creation of database table names or
    file names in situations where you need to minimize the risk of
    clashing with existing items.

    The generated names can be detected and parsed to extract the
    timestamp.


Create a name provider:

    $np = Data::ShortNameProvider->new(
        style => 'Basic', # eg a subclass to allow alternative providers
        prefix => 'dbit',
        timestamp_format => 'YYMMDD',
        max_name_length => 32, # croak if a longer name is generated
    );


Generate a shortname:

    $name = $np->generate_new_name('foo'); # eg returns "dbit1_140513__foo"

The 'Basic' format would be: $prefix $version _ $timestamp __ $name.


Parse a generated shortname:

    $hash = $np->parse_generated_name($name); # eg to get date etc

%$hash would contain something like

    {
        version => 1, # version of the Basic format
        timestamp_string => '140513',
        timestamp_epoch => 1400017536,
        name => 'foo'
    }

or else undef if $name could not be parsed as a Basic style short name.


Check if a string is parsable:

    my @names = grep { $np->is_generated_name($_) } @names;

A faster check than calling parse_generated_name would be (eg it would
skip calculating timestamp_epoch).


I don't see a need to expose a method that returns a regex, as I'd
originally proposed. Best to keep that encapsulated.

I think parse_generated_name() and is_generated_name() should be strict
about matching only names that generate_new_name() would have generated
for the same attributes to new(). E.g. the specific timestamp_format.

Tim.

Reply via email to