ᒨᓴ ᐊᔅᐗᔨᑕ

One thing I have neglected till this time was how to Load in my LSD classes. Up till now, for testing purposes, I have been always hard-codeing my Mongo and SQL LSDs in my code, and it did not matter if they where a Role like this

apply_all_roles( $self, "DA::LSD::SQL");

or a class such as this

use DA_S::LSD::Mongo;
$lsd = DA_S::LSD::Mongo->new(elements=>$self->elements,view=>$self->view);

in the long run I will have have to have some way to get them into my name-space without having to recode my DA each time a new LSD is created.

Nothing new in this, we all have been doing this for years, just have a look in DBI.pm. Fortunately I have been working with the internals of DBI for many years so lets have a look in there.

Now what DBI depends on is getting the DBD driver on the connection as in

$dbh = DBI->connect("dbi:Pg:dbname=$dbname",

where the little bit between the 'dbi:' and ':dbname' is the driver, in the aboce case 'Pg'. What it does under the hood once it has parsed out the driver is

my $driver_class = "DBD::$driver";
eval qq{package
          DBI::_firesafe;         # just in case
          require $driver_class;      # load the driver
    if ($@) {
        my $err = $@;

Now I am not going to go any deeper into what it does lets just say the above checks to see if the DBD driver is in the correct name-space by attempting to require it in a dummy package. It will check and report if it errors and If not it goes along its merry way and sets up all sorts of other objects, such as the driver and statement classes and caches them so DBI does not have to go though the overhead of reloading them each time a connection is used.

Well in the case of DA I will not have a 'connection' sub or alike as I want the user to pass along what they want to connect with and execute on. That leads to some problems; for example for DBI connections there are about 88 DBDs out on CPAN and that list will keep growing so I do not want to keep my code up to date to that list. What I do know is that am 98% sure that all of the DBDs return 'DBI::db' when you do a ref() on a connected DBD handle. So I could try this;

$driver= "DA::LSD::”
if (ref($conn) eq 'DBI::db'){
$driver .= "SQL";

use $driver
my $lsd = $driver->new(elements=>$self->elements,view=>$self->view);

Now what that solves which DLS to select but not which package to load as my DSL writer might choose something else for a package name though one would hope they use the same class path. As well I would have to hard code that if statement for all the differing DLS that may come about so back to square one.

So what to do. I think I will have to take a proactive approach to loading in LSDs. So I am going to make the following arbitrary name-space rules

  1. All DLS files will be in the DA::LSD name-space or folder if you like

  2. Each DSL has to express which type of driver it expects

  3. Only DSL 'pm' files will be loaded

  4. The loaded DSLs should be cached as loading or at least requiring them may take some time.

and then load them as I go along.

Now how to get this to work?

Well at least I know what I am writing about tomorrow.


1 Comment

Very well written, looking forward to the next article.

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations