Drew M. wrote:
>
> My original thinking was simply to replace an obscure exception with
> one that was a little more informative. If your ssqls structure and
> table (or query) didn't match, I think this would be hard to track
> down unless the code threw an exception.
This I did perceive, but I think making the library resilient in the
face of DB schema changes makes more sense than making it complain.
Neither crashes nor exceptions -- no matter how helpfully worded their
error text -- are a good response to the database changing out from
under the program. In my experience, the most common such "problem" is
just a new column being added, so the app should just cruise right on,
ignoring the new column, doing what it always did with the subset of
columns it already knows about.
I wish we could make it optional, so the B&D types can get "fail hard"
behavior if they want it, but the only way I can think of to do that is
through the OptionalExceptions mechanism, but I think you'd have to turn
off the flag too early in a lot of cases to make it desirable. Consider
Query::storein(): many things happen before it starts translating data
from Row form to SSQLS, and you might want exceptions for failures here
but not in the translation.
We can solve this in SSQLS v2, where we can set a flag on the SSQLS
itself to control such behavior.
> - $popul .= " s->I$j = row.at(O$j).conv(T$j());";
> - $popul .= "\n" unless $j == $i;
> + $popul .= " if( (*i) == s->names[O$j]) {\n";
> + $popul .= " s->I$j = row[(*i).c_str()].conv(T$j());\n";
> + $popul .= " continue;\n";
> + $popul .= " }\n";
I guess this patch is against 2.3.2? I didn't try it, but it seems
reasonable if so. In fact, I think it's the only way it could work in
2.3.2 if you wish to keep the ABI intact. If anyone wants this behavior
in 2.3.2, they should apply this.
I had this feature in mind for v3.0, though, where the core of it can be
done much more simply due to recent changes in Row:
Index: lib/custom.pl
===================================================================
--- lib/custom.pl (revision 1988)
+++ lib/custom.pl (working copy)
@@ -57,6 +57,7 @@
#ifndef MYSQLPP_CUSTOM_H
#define MYSQLPP_CUSTOM_H
+#include "noexceptions.h"
#include "sql_types.h"
#include <string>
@@ -295,7 +296,7 @@
$parm_simple2c_b .= ", " unless $j == $i;
$defs .= " T$j I$j;";
$defs .= "\n" unless $j == $i;
- $popul .= " s->I$j = row.at(O$j).conv(T$j());";
+ $popul .= " s->I$j = row[N$j].conv(T$j());";
$popul .= "\n" unless $j == $i;
$names .= " N$j ";
$names .= ",\n" unless $j == $i;
@@ -846,6 +847,7 @@
template <mysqlpp::sql_dummy_type dummy>
void populate_##NAME (NAME *s, const mysqlpp::Row &row) {
+ mysqlpp::NoExceptions ignore_schema_mismatches(row);
$popul
}
That last change is the key: Row::operator[](const char*) used to throw
an exception unconditionally when you indexed it on a field that doesn't
exist. Now it's optional, allowing the code to just go right on
truckin' if there's a schema mismatch.
There were a bunch of ancillary changes required due to heretofore
unrecognized limitations in MySQL++, plus some side things I needed to
tackle for completeness. Say 'svn diff -r1989:1991' if you want to see
the whole story.
Thanks anyway for your effort. The patch directed me to the right area
of the code.