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>():