Greg,

I've tried to add some background to explain where these changes came from. I 
know Merijn has replied already. Personally, I don't need any extra space for 
DBD only level tracing as I now mostly use flags but I have no objection to 
Merijn adding it.

On 09/02/11 02:53, Greg Sabino Mullane wrote:
> 
>> Apparently some DBDs only want DBD tracing and not DBI tracing so 
>> trace level is no good as it always includes DBI tracing. I think you 
>> were talking about reserving some space for DBDs only - perhaps you 
>> could remind us - the idea being settings (or a setting) which outputs 
>> DBD tracing but not DBI tracing.
> 
> Not sure if this has been covered upthread, but DBD::Pg makes heavy 
> use of tracing flags;

Then you are ok since you can set a flag specific to DBD::Pg and get only that 
tracing and not trace level tracing. Few DBDs use trace flags and in fact few 
DBDs use DBIc_TRACE macro at all and mostly examine the trace level directly.

> I'm not sure what you mean by trace level 
> being no good for DBD but not DBI output. If DBD::Pg, this is 
> as simple as:

Trace level is no good to get DBD only tracing since level 1 and 2 is for DBI 
and anything after that is DBD. To get DBD tracing with trace level you'd have 
to set level 3 at least and that would give you DBI level 1 and 2 plus DBD 
level 3. Some people (Merijn, John) wanted only DBD tracing and implemented 
dbd_verbose. Tux asked when I was going to implement odbc_verbose on #dbi and 
when I looked it had been implemented as a separate flag in their DBDs and 
therefore an extra check was required every time you thought you wanted to 
trace. I didn't like that.

In addition, at the LPW speaking to Tim I mentioned I had implemented some 
trace flags in DBD::ODBC which were probably generic in nature and agreed to 
add them to DBI. Whilst I was there I thought I could sort the trace DBD only 
issue out as well by adding a DBD trace flag.
 
> $dbh->trace('pglibpq'); ## as one example
> 
> We even have a specific flag for all DBD-specific and non-DBI output:
> 
> $dbh->trace('DBD');

Which is now duplicated in DBI for all DBDs. I see you implemented that as set 
all my trace flags if DBD set
 
        sub parse_trace_flag {
                my ($class, $flag) = @_;
                return (0x7FFFFF00 - 0x08000000) if $flag eq 'DBD'; ## all but 
the prefix

I didn't realise you did that and although I can see why it means you've added 
a flag with an uppercase name which is reserved for DBI. I'm not sure you'll 
ever see DBD in your parse_trace_flags after 1.617 so you'll need to do 
something similar to what I did (below) in addition to keeping what you already 
have (above) to cover older DBIs before 1.617.
 
> Also, can you elaborate more on what things the CON and ENC will 
> output? I'm wondering how similar the CON is to the DBD::Pg's 
> 'pglogin' flag:

Ok. DBD::ODBC had a flag called odbc_connection which only output connection 
specific tracing. In ODBC, a lot happens at connect time and often something 
happens at connect time which has an affect later. Sometimes all I needed from 
people was connect tracing so I added the flag. All I've done to DBI is added a 
CON flag which is documented as 

  trace connection process

>   =item pglogin
> 
>   Outputs a message showing the connection string right before a new 
>   database connection is attempted, a message when the connection 
>   was successful, and a message right after the database has been 
>   disconnected. Also output if trace level is 5 or greater.
> 
> 

Sounds the same to me.

The ENC flag is for encoding tracing. In DBD::ODBC it was/is called 
odbc_unicode and Tim suggested encoding was better. It is documented as:

  trace encoding (unicode translations etc)

ok, not a great description. In ODBC there are 2 different APIs for ANSI and 
Unicode and DBD::ODBC has to do a lot of translation of UCS2 to UTF-8 and vice 
versa. Also because the API is different, different functions are called and 
this is purely dependent on whether the Perl strings (say to 
SQLDriverConnect/SQLPrepare etc) are UTF-8 encoded or whether the data 
retrieved from the database is UCS2 or not. I use the ENC flag to trace 
encoding specific places.

Since it sounds like you already use flags you could (if you wish) do what I 
did (as I was already using flags) which is something like this:

/* DBI defines the following but not until 1.617 so we replicate here for now */
/* will remove when DBD::ODBC requires 1.617 or above */
#ifndef DBIf_TRACE_SQL
# define DBIf_TRACE_SQL 0x00000100
#endif
#ifndef DBIf_TRACE_CON
# define DBIf_TRACE_CON 0x00000200
#endif
#ifndef DBIf_TRACE_ENC
# define DBIf_TRACE_ENC 0x00000400
#endif
#ifndef DBIf_TRACE_DBD
# define DBIf_TRACE_DBD 0x00000800
#endif
#ifndef DBIf_TRACE_TXN
# define DBIf_TRACE_DBD 0x000001000
#endif

/* combined DBI trace connection and encoding flags with DBD::ODBC ones */
/* Historically DBD::ODBC had 2 flags before they were made DBI ones */
/* DBI used to only have SQL flag */
#define UNICODE_TRACING (0x02000000|DBIf_TRACE_ENC|DBIf_TRACE_DBD)
#define CONNECTION_TRACING (0x04000000|DBIf_TRACE_CON|DBIf_TRACE_DBD)
#define DBD_TRACING DBIf_TRACE_DBD
#define TRANSACTION_TRACING (DBIf_TRACE_TXN|DBIf_TRACE_DBD)
#define SQL_TRACING (DBIf_TRACE_SQL|DBIf_TRACE_DBD)

So my flags were odbc_connection 0x04000000 and odbc_unicode 0x02000000. I 
simply combine my flags with DBI's new ones for the similar purpose and 
DBIc_TRACE does all the work for me. DBI already had SQL flag. In addition, I 
or DBIf_TRACE_DBD in to ensure I get all my tracing when the DBD flag is set.

So for connection tracing I do:

  if (DBIc_TRACE(imp_dbh, CONNECTION_TRACING, 0, 3))

which will trace if:

o DBI's CON flag is set
o odbc_connection flag is set
o DBI's DBD flag i set
o trace level is > 3

I could have been even more specific with that 0 to say only trace if any of 
the flags are set if level is also over N but I don't care for that.

Also, Tim made some changes to stop some DBI tracing at startup when only flags 
are set so we achieved the goal of DBD-only tracing with adding any new 
mechanism and now just need to persuade more DBD authors to use DBIc_TRACE 
instead of what more do which is

        if (DBIS->debug >= 2 || dbd_verbose >= 3 ) {

Hope this answers your queries.

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to