On Fri, Apr 04, 2014 at 12:32:10PM +0200, Philippe Bruhat (BooK) wrote:
> On Thu, Apr 03, 2014 at 03:22:56PM +0100, Tim Bunce wrote:
> > > 
> > > 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)

A little research on CPAN brought up modules like String::Sprintf,
String::Print, String::Format or String::Template, but they don't seem
to do exactly what we want.

What about this:

    # using a random name for the class
    my $strfmt = Jagwar->new( template => "dbit1_%(time:%y%m%d%H)_%(pid)_%s" );

    # the extended formats (time and pid) are provided by plugins / roles
    # the one-character formats fallback to sprintf, and require arguments
    my $prefix = $strfmt->sprintf($name);

    # /^dbit1_([0-9]{8})_([1-9][0-9]*)_(.*?)$/
    my $re = $strfmt->regexp;
    my @parts = $strfmt->split($prefix);    # $prefix =~ m/$re/g;

    # this is all just sprintf-like stuff
    my $fmt = $strfmt->format;    # dbit1_%d_%d_s
    $prefix eq sprintf( $fmt, @parts );    # true

    # with some magic attached
    my $time = $strfmt->get( time => $prefix );    # get_time?
    my $pid  = $strfmt->get( pid  => $prefix );    # get_pid?

Actually, maybe $prefix could be an object that stringifies to the string
itselft, and delegates all method calls to the Jagwar object:

    my $prefix = $strfmt->sprintf($name);
    my $re    = $prefix->regexp;        # 
/^dbit1_([0-9]{8})_([1-9][0-9]*)_(.*?)$/
    my @parts = $prefix->split;         # '14040409', '4532', $name
    my $fmt   = $prefix->format;        # "dbit1_%d_%d_s"
    my $time  = $prefix->get('time');   # get_time?
    my $pid   = $prefix->get('pid');    # get_pid?
    $prefix eq sprintf( $fmt, @parts ); # true

    my $table = "$prefix"; # stringifies just fine

Even the sprintf-like format string could get some extra magic, like
validation by a regexp:

    my $strfmt = Jagwar->new( format => 
"dbit1_%(time:%y%m%d%H)_%(pid)_%(s:^\\w+\$)" );

    my $prefix = $strfmt=->sprintf( 'aha!' ); # DIES

Some plugins come to mind, like an md5 plugin: %(md5: ... )

Looking at the above, it becomes clear that we want to be able to nest the
formatters, to be able to give formats like:

    dbit1_%(md5:%(time:%y%m%d%H)_%(pid))_%s

Obviously, with such templates you can only expect regexp, split and format
to understand the top-level formats.

-- 
 Philippe Bruhat (BooK)

 There are two sides to every cause. Do not join one until you know the other.
                                   (Moral from Groo The Wanderer #105 (Epic))

Reply via email to