Author: timbo
Date: Fri Feb 13 15:43:16 2004
New Revision: 57

Modified:
   dbi/trunk/DBI.xs
   dbi/trunk/DBIXS.h
   dbi/trunk/lib/DBI/DBD.pm
Log:
Add and document an interface to set_err() logic for drivers.


Modified: dbi/trunk/DBI.xs
==============================================================================
--- dbi/trunk/DBI.xs    (original)
+++ dbi/trunk/DBI.xs    Fri Feb 13 15:43:16 2004
@@ -70,7 +70,7 @@
 static int        dbih_set_attr_k  _((SV *h, SV *keysv, int dbikey, SV *valuesv));
 static SV        *dbih_get_attr_k  _((SV *h, SV *keysv, int dbikey));
 
-static int      set_err_char   _((SV *h, imp_xxh_t *imp_xxh, char *err, char *errstr, 
char *state, char *method));
+static int      set_err_char   _((SV *h, imp_xxh_t *imp_xxh, char *err_c, IV err_i, 
char *errstr, char *state, char *method));
 static int     set_err_sv      _((SV *h, imp_xxh_t *imp_xxh, SV *err, SV *errstr, SV 
*state, SV *method));
 static int     quote_type _((int sql_type, int p, int s, int *base_type, void *v));
 static int     dbi_hash _((char *string, long i));
@@ -241,6 +241,9 @@
     DBIS->neat_svpv   = neatsvpv;
     DBIS->bind_as_num = quote_type;
     DBIS->hash        = dbi_hash;
+    DBIS->set_err_sv  = set_err_sv;
+    DBIS->set_err_char= set_err_char;
+
 
     /* Remember the last handle used. BEWARE! Sneaky stuff here!       */
     /* We want a handle reference but we don't want to increment       */
@@ -393,12 +396,18 @@
 
 
 static int
-set_err_char(SV *h, imp_xxh_t *imp_xxh, char *err, char *errstr, char *state, char 
*method)
+set_err_char(SV *h, imp_xxh_t *imp_xxh, char *err_c, IV err_i, char *errstr, char 
*state, char *method)
 {
-    SV *err_sv    = (strEQ(err,"1")) ? &sv_yes : sv_2mortal(newSVpvn(err, 
strlen(err)));
-    SV *errstr_sv = sv_2mortal(newSVpvn(errstr, strlen(errstr)));
-    SV *state_sv  = (state && *state)   ? sv_2mortal(newSVpvn(state,  strlen(state))) 
 : &sv_undef;
-    SV *method_sv = (method && *method) ? sv_2mortal(newSVpvn(method, 
strlen(method))) : &sv_undef;
+    char err_buf[28];
+    SV *err_sv, *errstr_sv, *state_sv, *method_sv;
+    if (!err_c) {
+       sprintf(err_buf, "%ld", (long)err_i);
+       err_c = &err_buf[0];
+    }
+    err_sv    = (strEQ(err_c,"1")) ? &sv_yes : sv_2mortal(newSVpvn(err_c, 
strlen(err_c)));
+    errstr_sv = sv_2mortal(newSVpvn(errstr, strlen(errstr)));
+    state_sv  = (state  && *state)  ? sv_2mortal(newSVpvn(state,  strlen(state)))  : 
&sv_undef;
+    method_sv = (method && *method) ? sv_2mortal(newSVpvn(method, strlen(method))) : 
&sv_undef;
     return set_err_sv(h, imp_xxh, err_sv, errstr_sv, state_sv, method_sv);
 }
 
@@ -3096,7 +3105,7 @@
                    if (pln != idx) {
                        char buf[99];
                        sprintf(buf, "preparse found placeholder :%d out of sequence, 
expected :%d", pln, idx);
-                       set_err_char(dbh, imp_xxh, "1", buf, 0, "preparse");
+                       set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
                        return &sv_undef;
                    }
                   while(isDIGIT(*src)) src++;
@@ -3127,7 +3136,7 @@
        if (laststyle && style != laststyle) {
            char buf[99];
            sprintf(buf, "preparse found mixed placeholder styles (%s / %s)", style, 
laststyle);
-           set_err_char(dbh, imp_xxh, "1", buf, 0, "preparse");
+           set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
             return &sv_undef;
         }
        laststyle = style;
@@ -3138,19 +3147,19 @@
     switch (in_quote)
     {
     case '\'':
-           set_err_char(dbh, imp_xxh, "1", "preparse found unterminated single-quoted 
string", 0, "preparse");
+           set_err_char(dbh, imp_xxh, "1", 1, "preparse found unterminated 
single-quoted string", 0, "preparse");
            break;
     case '\"':
-           set_err_char(dbh, imp_xxh, "1", "preparse found unterminated double-quoted 
string", 0, "preparse");
+           set_err_char(dbh, imp_xxh, "1", 1, "preparse found unterminated 
double-quoted string", 0, "preparse");
            break;
     }
     switch (in_comment)
     {
     case DBIpp_L_BRACE:
-           set_err_char(dbh, imp_xxh, "1", "preparse found unterminated bracketed 
{...} comment", 0, "preparse");
+           set_err_char(dbh, imp_xxh, "1", 1, "preparse found unterminated bracketed 
{...} comment", 0, "preparse");
            break;
     case '/':
-           set_err_char(dbh, imp_xxh, "1", "preparse found unterminated bracketed 
C-style comment", 0, "preparse");
+           set_err_char(dbh, imp_xxh, "1", 1, "preparse found unterminated bracketed 
C-style comment", 0, "preparse");
            break;
     }
 
@@ -3601,7 +3610,7 @@
     if (DBIc_TYPE(imp_xxh) <= DBIt_DB && DBIc_CACHED_KIDS((imp_dbh_t*)imp_xxh))
        clear_cached_kids(h, imp_xxh, "take_imp_data", DBIc_DEBUGIV(imp_xxh));
     if (DBIc_KIDS(imp_xxh)) {  /* safety check, may be relaxed later to 
DBIc_ACTIVE_KIDS */
-       set_err_char(h, imp_xxh, "1", "Can't take_imp_data from handle while it still 
has kids", 0, "take_imp_data");
+       set_err_char(h, imp_xxh, "1", 1, "Can't take_imp_data from handle while it 
still has kids", 0, "take_imp_data");
        XSRETURN(0);
     }
     dbih_getcom2(h, &mg);      /* get the MAGIC so we can change it    */

Modified: dbi/trunk/DBIXS.h
==============================================================================
--- dbi/trunk/DBIXS.h   (original)
+++ dbi/trunk/DBIXS.h   Fri Feb 13 15:43:16 2004
@@ -329,8 +329,7 @@
 
 /* --- Event Support (VERY LIABLE TO CHANGE) --- */
 
-/* #define DBIh_EVENTx(h,t,a1,a2) (DBIS->event((h), (t), (a1), (a2))) */
-#define DBIh_EVENTx(h,t,a1,a2) /* deprecated */ &PL_sv_no
+#define DBIh_EVENTx(h,t,a1,a2) /* deprecated XXX */ &PL_sv_no
 #define DBIh_EVENT0(h,t)       DBIh_EVENTx((h), (t), &PL_sv_undef, &PL_sv_undef)
 #define DBIh_EVENT1(h,t, a1)   DBIh_EVENTx((h), (t), (a1),         &PL_sv_undef)
 #define DBIh_EVENT2(h,t, a1,a2)        DBIh_EVENTx((h), (t), (a1),         (a2))
@@ -341,6 +340,11 @@
 #define DBEVENT_event  "DBEVENT"
 #define UNKNOWN_event  "UNKNOWN"
 
+#define DBIh_SET_ERR_SV(h,i, err, errstr, state, method) \
+       (DBIc_DBISTATE(i)->set_err_sv(h,i, err, errstr, state, method))
+#define DBIh_SET_ERR_CHAR(h,i, err_c, err_i, errstr, state, method) \
+       (DBIc_DBISTATE(i)->set_err_char(h,i, err_c, err_i, errstr, state, method))
+
 
 /* --- Handy Macros --- */
 
@@ -389,9 +393,10 @@
     PerlInterpreter * thr_owner;       /* thread that owns this dbistate       */
 
     int         (*logmsg)      _((imp_xxh_t *imp_xxh, char *fmt, ...));
-    int         (*set_err)     _((imp_xxh_t *imp_xxh, char *fmt, ...));
+    int         (*set_err_sv)  _((SV *h, imp_xxh_t *imp_xxh, SV   *err, SV   *errstr, 
SV   *state, SV   *method));
+    int         (*set_err_char) _((SV *h, imp_xxh_t *imp_xxh, char *err, IV err_i, 
char *errstr, char *state, char *method));
 
-    void *pad2[7];
+    void *pad2[6];
 };
 
 /* macros for backwards compatibility */

Modified: dbi/trunk/lib/DBI/DBD.pm
==============================================================================
--- dbi/trunk/lib/DBI/DBD.pm    (original)
+++ dbi/trunk/lib/DBI/DBD.pm    Fri Feb 13 15:43:16 2004
@@ -2091,23 +2091,44 @@
 a pointer to your private handle pointer. You may cast this to
 to I<imp_drh_t>, I<imp_dbh_t> or I<imp_sth_t>.
 
-  SV *errstr = DBIc_ERRSTR(imp_xxh);
-  sv_setiv(DBIc_ERR(imp_xxh), (IV)rc);  /* set err early        */
-  sv_setpv(errstr, what);
+To record the error correctly, equivalent to the set_err() method,
+use one of the DBIh_SET_ERR_CHAR(...) or DBIh_SET_ERR_SV(...) macros,
+which were added in DBI 1.41:
 
-If your database supports SQLSTATE, you should also set the SQLSTATE value; for 
example,
-DBD::Informix includes the line:
+  DBIh_SET_ERR_SV(h, imp_xxh, err, errstr, state, method);
+  DBIh_SET_ERR_CHAR(h, imp_xxh, err_c, err_i, errstr, state, method);
 
-  sv_setpv(DBIc_STATE(imp_xxh), SQLSTATE);
+For DBIh_SET_ERR_SV the err, errstr, state, and method parameters are SV*.
+For DBIh_SET_ERR_CHAR the err_c, errstr, state, method are char*.
+The err_i parameter is an IV that's used instead of err_c is err_c is Null.
+The method parameter can be ignored.
 
-Note the use of the macros DBIc_ERRSTR and DBIc_ERR for accessing the
-handles error string and error code.
+The DBIh_SET_ERR_CHAR macro is usually the simplest to use when you
+just have an integer error code and an error message string:
+
+  DBIh_SET_ERR_CHAR(h, imp_xxh, Nullch, rc, what, Nullch, Nullch);
+
+As you can see, any parameters that aren't relevant to you can be Null.
+
+To make drivers compatible with DBI < 1.41 you can use this:
+
+#ifndef DBIh_SET_ERR_CHAR
+#define DBIh_SET_ERR_CHAR(h, imp_xxh, err_c, err_i, errstr, state, method) \
+       sv_setiv(DBIc_ERR(imp_xxh), err_i); \
+       sv_setpv(DBIc_STATE(imp_xxh), state); \
+       sv_setpv(DBIc_ERRSTR(imp_xxh), errstr)
+#endif
+
+and pass Null for the err_c and method parameters.
 
 The (obsolete) macros such as DBIh_EVENT2 should be removed from drivers.
+
 The names I<dbis> and I<DBIS>, which were used in previous versions of this document,
 should be replaced with the C<DBIc_STATE(imp_xxh)> macro.
+
 The name DBILOGFP, which was also used in previous  versions of this document, should 
be
 replaced by DBIc_LOGPIO(imp_xxh).
+
 Your code should not call the C C<E<lt>stdio.hE<gt>> I/O functions; you should either 
use
 C<PerlIO_printf>() as shown, or standard Perl functions such as C<warn>():
 

Reply via email to