From: Warren Young Date: October 28 2008 10:50pm Subject: Re: Insert policy design question List-Archive: http://lists.mysql.com/plusplus/8097 Message-Id: <4907973C.9070504@etr-usa.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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().