Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^2: DBD::Mock and DBD-specific attributes

by dragonchild (Archbishop)
on Aug 16, 2004 at 18:26 UTC ( [id://383398]=note: print w/replies, xml ) Need Help??


in reply to Re: DBD::Mock and DBD-specific attributes
in thread DBD::Mock and DBD-specific attributes

Regardless of how it works under the hood, if I set an attribute to $x, then ask for that attribute back, I should get $x, unless the docs indicate that the given attribute does something based on $x.

Plus, in looking under the hood, DBD::Mock::db::STORE() calls to SUPER::STORE if it doesn't know about the attribute. From what I can discern (and from what I think DBI::DBD says), the attribute and value should be stored in the tied hash.

Now, an interesting possibility to add to DBD::Mock would be an 'is_mocking' attribute in the connection parameters. So, I might want to say something like:

my $dbh = DBI->connect( 'dbi:Mock:is_mocking=mysql', '', '' ) or die $ +DBI::errstr;

And, there would be a DBD::Mock::mysql that would do the right thing with mysql_insertid (or DBD::Mock::Oracle with an ora_* attribute, etc.)

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

I shouldn't have to say this, but any code, unless otherwise stated, is untested

Replies are listed 'Best First'.
Re^3: DBD::Mock and DBD-specific attributes
by tilly (Archbishop) on Aug 16, 2004 at 20:20 UTC
    If I am writing unit tests and I've misspelled the name of the attribute, I'd hope that my mistake would get caught.

    I'd suggest that any kind of 'is_mocking' attribute would know which attributes that module is supposed to support, and warn you about using unsupported attributes.

      That's why I would strongly suggest the usage of something like DBD::Mock::mysql and the like. More in another reply in this thread.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re^3: DBD::Mock and DBD-specific attributes
by stvn (Monsignor) on Aug 16, 2004 at 18:53 UTC

    After looking more closely at the source of DBD::Mock, I agree, it should work as you expect. After reading DBI::DBD I am convinced it should work as you expect. However, it does not. The really weird part of course is that it seems to works for other attributes like PrintError, RaiseError, etc. I am trying to figure it out right now, I will keep you updated.

    UPDATE
    Found this in the trace output:

    $h->{'mysql_insertid'}=10 ignored for invalid driver-specific attribut +e
    So it seems that DBI will skip over driver specific attributes. According to line 1554 of DBI.xs, only those attributes that start with 'private_', 'dbi_' or 'dbd_' are allowed, all others are ignored. However, this seems to contradict what it says in DBI::DBD
    The DBI will actually store and fetch driver-specific attributes (with all lowercase names) without warning or error, so there's actually no need to implement driver-specific any code in your FETCH and STORE methods unless you need extra logic/checks, beyond getting or setting the value.
    Hmmmm.

    -stvn
      The really weird part of course is that it seems to works for other attributes like PrintError, RaiseError,

      Upper-cased attribute names are reserved by DBI and should be passed by the driver to DBI for storing and fetching.

      Lower-cased attribute names should start with *a* recognized prefix, not necessarily the prefix of the driver in question. Lower-cased attribute names that are not a recognized prefix (e.g. mock_ or mysql_ or csv_ are recognized) should never be used.

      And I agree with your previous post that DBD::Mock is a special case so you may want to allow unknown attribute names (though still they aboslutely should have a known prefix).

      Other replies in this thread seem to indicate that lowercase attributes will not be handled unless they have the correct prefix. So, what about adding a check in the two STORE/FETCH subs in DBD::Mock to say "If I don't know about this attribute, but it is in lowercase, I'll store/fetch it for you."?

      I went ahead and added this code to my copy and it passed my tests, though you'll probably want to design it a little better than my hackish solution. Specifically, doing a reset on the $dbh should probably delete all the added-on attributes. Plus, I would still like to see a way of mocking a given DBD.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

        Specifically, doing a reset on the $dbh should probably delete all the added-on attributes.

        What do you mean by a 'reset'? Are you refering to the 'mock_clear_history' attribute?

        Plus, I would still like to see a way of mocking a given DBD.

        Well one of the things I know lachoy was trying to do was to keep DBD::Mock in a single file, so that it would be easy for other authors to include in their modules (and not have as an external dependency). So I would be hesitatant to start going to crazy with DBD::Mock::MySQL, DBD::Mock::Oracle, etc. if I can avoid it. However, that said, my experience with anything other than DBD::mysql and DBD::Pg is limited so I am not aware of how different other DBD's can be. If you have any suggestions/insight into this I would love to hear it.

        -stvn

        What might be useful is if you passed information via connect() to tell DBD::Mock what type of database handle it should emulate, like:

        my $dbh = DBI->connect( 'DBI:Mock:mysql', ... ); my $dbh = DBI->connect( 'DBI:Mock:Pg', ... );

        It probably wouldn't be hard to collect a list of valid attributes for each driver and store/return only these, throwing an exception on all others. That's something anyone can do, not just the driver author...

        But it's all in stvn's hands now :-)

        Chris
        M-x auto-bs-mode

Re^3: DBD::Mock and DBD-specific attributes
by jZed (Prior) on Aug 16, 2004 at 18:33 UTC
    Regardless of how it works under the hood, if I set an attribute to $x, then ask for that attribute back, I should get $x, unless the docs indicate that the given attribute does something based on $x.
    No, not with databse handle attributes AFAIK. DBI leaves the handling of all lower_cased handle attributes (method attributes are a different thing) to the drivers. If you set an attribute that the driver doesn't know about, the driver shouldn't be expected to give it back to you. In fact, the driver probably shouldn't allow you to set it. stvn you might consider adding code to ::db::STORE that dies if someone tries to set an unknown attribute.
      stvn you might consider adding code to ::db::STORE that dies if someone tries to set an unknown attribute

      I would agree with you in the context of a normal DBD, but with DBD::Mock, the ability to catch and store driver specific attributes is probably a feature more than it is a bug. I am still thinking about the best way to handle this.

      -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://383398]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-20 01:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found