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:
> 
> > Some logic to assist with table naming and cleanup etc will be
> > developed as part of DBIT and could be extracted. If so, I think it
> > belongs in a separate distro. (Separation of Concerns etc.)
> 
> And if Test::Database only deals with giving out Test::DSN objects, then
> it should not need to care about naming issues (except for file-based
> DSN, but that's a simpler problem).
> 
> Does the logic already exist somewhere as code or module?

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


> >     dbi:DBM:f_dir={CREATE_DATABASE}
> >     dbi:Oracle:sid={CREATE_DATABASE}
> 
> I really like this. The notion of "private database" is both very explicit
> and nicely generic.
> 
> So after having read the config files, Test::Database has:
> - a list of plain DSN
> - a list of DSN that can be used by the private database creation service
>   to produce a DSN on demand (similar to the current driver_dsn)
> 
> I think that the warning you gave above ("the database you get connected
> to may be in active use by other applications, and/or concurrent instances
> of your application, so you need to take appropriate care.") only applies
> to the first kind of DSN.

Yeap. Though distros using Test::Database won't know what kinds of DSN
they'll get so they should assume the worst and be defensive.

> So, for DBD::CSV, a dsn for the private database creation service would
> look like this:
> 
>    dbi:CSV:f_dir={CREATE_DATABASE}
> 
> And following Tux's preferences, it could also be:
> 
>    dbi:CSV:f_dir={CREATE_DATABASE};f_ext=.csv/r
> 
> Now there are plenty of combinations of parameters that make up valid but
> slightly different DSN. I think that Test::Database should only provide
> one of those by default (to avoid combinatorial explosion), to be dropped
> if the configuration happens to provide one of more DSN for that DBD.

I don't follow you here BooK.

> So, for all supported DBD, Test::Database would provide a private
> database factory in the form of a DSN with the {CREATE_DATABASE}
> placeholder. And actually, that's really something that each
> Test::Database::Driver should provide.

Yes, assuming I'm understanding you correctly.


> For the "private databases", we can even provide various levels of privacy
> (as offered by the namespace-providing module), like DSN that are private
> to the project (the namespace is generated using the project top-level
> directory), or to a given test script (the namespace is generated
> using the script full path). This is something that should be part of
> the request done by the test script:
> 
>     # this DSN is expected to not be shared with anything else
>     @handles = Test::Database->handles( privacy_level => 'script' );
> 
>     # this DSN will be shared across test scripts in the same project,
>     # enabling some 000-startup.t to setup some data to be used by later
>     # scripts, for example
>     @handles = Test::Database->handles( privacy_level => 'project' );
> 
> I'm not sure which privacy level is a good default. Probably script-level.

Umm. That might be over-engineering at this stage. 'project' level could
be added later if there's a clear need.


> The best location for private file-based DSN is probably cwd itself,
> under some hidden directory.

Why hidden?

> So a .test-database/ directory at the project level would be the home
> for the project local configuration file, and the various file-based
> private databases created for the project.

Just "test-database" seems fine to me.


It's great to see this moving forwards. Thanks BooK.

Tim.

Reply via email to