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))