Rick Gutleber wrote:
> maybe you could derive Query from that....
We've been down that road before in MySQL++ v1, and it caused a lot of
portability problems. Few of the classes in the C++ Standard Library
work well as base classes. This is intentional; note the lack of
virtual functions. Some of it's also due to underspecification in the
standard, with so much left up to the implementor.
In v2, we changed Query from deriving from stringstream to deriving from
ostream. That interface is a lot simpler, so there are fewer implicit
promises for it to keep. Even that hasn't been problem-free; see the
ifdef ugliness in the definition of the Query ctors in lib/query.cpp.
Even if we did go back on this, we couldn't do it before MySQL++ v4,
because it'd break the ABI.
It occurs to me that Query::tellp() *does* exist, but it's not clear to
me that it does anything useful. It might be up to the ostream
derivative to implement this. You might look into that, though...I
could be wrong. It may indeed tell you how many bytes are in the
streambuf, which is what you needed to know.
> But this raises a bit of a problem because the less the policy object
> actually does the more you have do things that serve no purpose except
> to tell the policy what you're doing.
The only thing the policy object should control is how many VALUES()
clauses go into a query. Pseudocode:
0. If transactions allowed, BEGIN
1a. If more records to process, set up query: INSERT INTO...
1b. If not, goto 4
2a. Can I insert another VALUES clause? If yes, goto 3.
2b. If no, submit query, reset stringbuf, and goto 1
3. Insert VALUES clause into stream, and goto 2a.
4. If transactions allowed, COMMIT
The policy object answers the questions posed by 0, 2a, and 4. The
tricky bit is figuring out what to pass it so the various object types
can answer the question. I'm thinking you pass it a Row or SSQLS and
the current size of the query in bytes.
>> That won't
>> work on Query itself, though, because it no longer is-an ostream.
Just to clarify, this is wrong. I was thinking we changed from
stringstream as a parent class to no parent at all, and that it just
implemented the ostream interface instead of deriving from it.
Then again, if tellp() doesn't work, one could argue that Query is
indeed not-an ostream.
>> Just set them to NULL in the container, which tells MySQL to make
>> up a value instead of use what was passed in.
>
> I've run into this before. You would have to make the auto-increment
> field null-able in the SSQLS declaration, which I hadn't done
> because it wasn't a null-able field
MySQL accepts NULL for AUTO_INCREMENT fields, so from that perspective,
the field *is* nullable. The DB engine doesn't actually store NULL, and
a test for id.is_null is always false, so I do see your point, but I
don't see a practical problem with it.
If you still can't bring yourself to mark the field as nullable,
inserting 0 also works, by default in MySQL at least:
http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#id2567097
> MySQL++ is one of the few 3rd party
> libraries I've ever used in 20+ years that actually seems to have had
> some serious thought put into its design, interface, and even
> philosophy.
Thanks! Having someone with taste controlling checkins helps, I
suppose, but it's not enough. You also have to be willing to blow up
the library interface and rebuild it every major version. The userman's
breakages chapter is sufficient testimony that this isn't without its
unfortunate side effects.
> I did Windows development for many years).
Oh. I guess you won't like the feature I'm working on next, then,
CreateMysqlppQueryEx2().