Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Can DBI modify queries on the fly?

by kyle (Abbot)
on Feb 17, 2009 at 22:42 UTC ( #744583=perlquestion: print w/ replies, xml ) Need Help??
kyle has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to modify queries that are going to the database in a programmatic way without modifying code throughout the whole application. Specifically, I want to put call stack information in a SQL comment so that they'll show up in the DB's logs. This means I can't use some external proxy to modify the queries because it won't know what line of code the query came from.

Is this possible? Is it easy to do with a DBI subclass or some such? Is a module to do this already written?

Comment on Can DBI modify queries on the fly?
Re: Can DBI modify queries on the fly?
by jfroebe (Vicar) on Feb 17, 2009 at 22:58 UTC

    Check out SQL Library. It will allow you to easily keep your SQL code in another file that you can modify at will.

    Another option is to use the Perl debugger to replace the query strings.

    Jason L. Froebe

    Blog, Tech Blog

      I want to modify the queries of a running application so that what's passed to the database includes a comment that tells where in the Perl code the request originated. SQL::Library (or Data::Phrasebook) is a nice idea, but it solves a completely different problem.

      Likewise, I don't want to step through my code in the debugger and modify queries by hand. Rather, this is a tedious task that I think the computer should do for me. More to the point, I can't sit at the debugger in production.

        Understood. I would advise strongly against doing this in production though. Most DBMSs will have a performance penalty for writing to the errorlog (or any external file). But... it's your code/server.

        Jason L. Froebe

        Blog, Tech Blog

        I want to modify the queries of a running application so that what's passed to the database includes a comment that tells where in the Perl code the request originated.
        Well, there is such a thing as an SQL comment, and for at least some databases (e.g. MySQL), I believe the comments get logged along with the SQL. (There was one occasion where I solved a problem like this with screwed-up capitalization, e.g. changing "SELECT" to "SeLECT", "SElECT", "SELeCT"...).

        Have you looked at the "TRACING" features listed in the DBI docs? That at least can be turned on dynamically, though if the docs are up-to-date, I infer that it doesn't have SQL logging yet:

        Curently the DBI only defines two trace flags: ALL - turn on all DBI and driver flags (not recommended) SQL - trace SQL statements executed (not yet implemented)

        Update: actually, I bet that turning on trace level 1 is pretty close to what you're asking for. It will echo your prepare statements (including the SQL), and label them with line number and file of your code:

        $dbh->trace(1, $trace_log_file);

Re: Can DBI modify queries on the fly?
by ikegami (Pope) on Feb 17, 2009 at 23:14 UTC
    Writing a DBD that proxies/wraps the real DBD sounds more appropriate to me.

      I wonder if using Log4Perl wouldn't be better in the long run. It'll mean a bit of coding to write the plugin to write the info to the database errorlog via a query but once created, it should be a simple thing.

      Jason L. Froebe

      Blog, Tech Blog

        I muled over this, and I still can't figure what Log4perl (note the lowercase 'p') and error logs have to do with the OP's question. Do you know more about what the OP is attempting to do than he is telling us?

        I'm just very blind X_X

      DBD::Proxy would be a good place to start. It might be as simple as making a copy of it, and replacing the prepare() function with one that adds a SQL comment to queries.
Re: Can DBI modify queries on the fly?
by perrin (Chancellor) on Feb 17, 2009 at 23:42 UTC

      Wow, I wish that were more documented. I haven't tried it yet, but I suspect that will work great. My main concern comes from this line of the tests:

      is ref $attr, 'HASH', 'param modified by callback - not recommended!';

      Modifying params by callback is exactly what I want to do. So why is it not recommended? I'm guessing this means that the solution I eventually come up with will stop working at some point in the future, but I guess I'll curse that bridge when I come to it.

        That refers to modifying @_ only, not modifying copies of what's in @_ or SQL placeholders
Re: Can DBI modify queries on the fly? (solution)
by kyle (Abbot) on Feb 18, 2009 at 19:16 UTC
Re: Can DBI modify queries on the fly?
by kyle (Abbot) on Oct 14, 2009 at 18:41 UTC

    Here's a solution that doesn't use the callback mechanism, so it works with older versions of DBI. To use it, give it as the RootClass to DBI->connect. Since we were already using DBIx::ContextualFetch there, the code below uses that as its base, but it's not otherwise required.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://744583]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (8)
As of 2014-07-30 12:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (231 votes), past polls