Hi! DBI currently supports 3 functions to retrieve diagnostic
informations

https://metacpan.org/pod/DBI#err
https://metacpan.org/pod/DBI#errstr
https://metacpan.org/pod/DBI#state

which return the last one database native code, message and SQLSTATE.
Plus there warning or note information is indicated by zero native code
or by empty string in native code.

This API has two big limitations:

1) It does not support providing database native code for warnings and
   note informations.

2) It does not support providing more warnings, errors or note
   informations.

It most cases database native code is what application can "parse" and
decide how to handle it. So absence of database native code for warnings
or note informations can be a problem -- as currently DBI application
needs to parse string message from $dbh->errstr.

Also databases can return more warnings or note informations for the
last executed call. For this case DBI defines API for errstr just as:

"The returned string may contain multiple messages separated by newline
characters."

So it is harder for DBI application to parse multi warnings. And there
is not information for which warning is value from $dbh->state.



Based on above two limitations I would like to propose a new API for
diagnostic messages (errors, warnings and note / success with
information).

New method call "get_diagnostics()" for all DBI handles. It would
return array of diagnostics member. Each diagnostic member would contain
reference to array with 4 members: type, native code, message, sqlstate.

Type can be non-zero for errors, zero for warnings and empty string for
notes / success with information. Like what $dbh->err now returns.

Native code is native database code, same what $dbh->err returns for
errors. But for warnings and notes it would also contain database native
code, not just false value

Message and sqlstate would return $dbh->errstr and $dbh->state.

Example of usage:

  my @array = $dbh->get_diagnostics();
  foreach (@array) {
    my ($type, $code, $message, $sqlstate) = @{$_};
    if ($type) {
      print "Error $code ($sqlstate): $message\n";
    } elsif ($type eq '0') {
      print "Warning $code ($sqlstate): $message\n";
    } else {
      # Process success with information message
    }
  }

What do you think about it?

Reply via email to