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