Warren Young wrote:
> 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
> Even if we did go back on this, we couldn't do it before MySQL++ v4,
> because it'd break the ABI.
Thanks for the history lesson. Early MFC suffered from similar
problems. It wasn't extensible without hacking the source.
> 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.
I will let you know what I find.
>> 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.
OK. Then we are on the same page. My issue was that what you were
describing above is all that it could do. If we decide (and I think
it's reasonable) that that's all we want then it's cool.
>> 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:
I have no problems with the idea, I just didn't know you could do that.
For some reason I thought inserting 0 didn't work either.
>> 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 always believed that too. Fortunately, I'm the only developer on this
project at this time and can exercise free reign. It's really made
things nice. The project was a bit of a mess when I took it over,
random crashes aplenty, and it's been running in production without
non-trivial problems for several months. I attribute part of that
success to systematically cleaning things up and greatly simplifying things.
Actually, since this app was well-encapsulated from the start I had to
make very few changes to move from version 1 last year, to version 2 and
finally to version 3.
>> I did Windows development for many years).
> Oh. I guess you won't like the feature I'm working on next, then,
Reminds me of when I wanted a "tear" utility to snarf a web page from
the command-line about 10 years ago (this was before I knew about wget),
so I figured, "Let's look at the internet stuff in MFC." Turns out they
had a sample program called, coincidentally, "tear". It was something
like 200 lines long.. and in the end all you were really doing was
passing in a URL, opening a file, and dumping the results into it!
Just like OLE code, most of it was meaningless (from the library user's
point of view) cookbook setting up of tons and tons of things you don't
want to know about and shouldn't have to know about. At the time I was
replacing MFC with my own code a piece at a time, pretty much everything
but the GUI stuff, and that I was overloading to make it a little more
useful than a thin wrapper around the Win32 SDK. It was at time that a
friend and me had declared our philosophy of everything should work in 3
And as often as possible, those 3 steps should take no more 3 lines of
code. It pleases me greatly that MySQL++ adheres to the same kind of
simplicity in use.
Then there's RogueWave, which I had to use at another job in the 90s.
The RogueWave DB classes literally had a class for every concept in
basic database querying and access. I don't recall the exact details
but in order to a simple query you had to use a wide variety of objects
like: A DB object, a connection object, a query object, a recordset
object, a record object, a select object, and to make things even more
confusing, the RogueWave developers seemed to be in some contest to see
how many C++ operators they could overload for everyone of these
objects! While operator overloading is an extremely useful feature
(that Java and Tcl are sorely lacking), it is, like most features of
C++, easy to abuse. RogueWave overloaded these multitude of classes in
a way that stretched the limits of reason and ended up firmly in the
region of absurdity. Most of these, of course, were not intuitive at all.
Microsoft's ODBC is, in my opinion, perhaps the best piece of software
technology they ever created, and it was a joy to use, however in order
to do so in a C++ environment, you had the options of using their ADO,
or was it DAO... perhaps best called "DOA", which also required a
tremendous amount of bloat just to do simple things, although unlike
RogueWave, at least it wasn't weird bloat. Over time, I created the
DBConnection class (and derived SQLServerConnection, etc) classes that
looked more than a little like MySQL++ (although an order of magnitude
less sophisticated, and I didn't use the stream stuff). But the key
point was that executing a query was as simple as declaring a connection
object, issuing the connection parameters and issuing a SQL query.
While the 3 step paradigm is perhaps a little too simplistic in case, it
could be replaced with a much looser definition that unfortunately isn't
even met by many, many libraries I've seen:
Using a library should be significantly easier and simpler than doing
the same task without the library.
Or even the more broad constraint that some libraries still managed to fail:
Using a library should be significantly easier and simpler, over time,
than writing your own version of the library from scratch and using that.
A 3rd party Grid control for Windows that had been used in a project I
worked on in the late 90s fell into this category. What I eventually
replaced it with was one my proudest creations. Not only was it easier
to use than the original (whose name I forget) but it was an order of
magnitude more flexible and extensible, which was needed for the app, it
was also much simpler and more flexible than Microsoft's similar offering.
Granted, I haven't used any Microsoft dev tools newer the Visual Studio
6, because none of my clients ever wanted anything newer and I was happy
to remain with VS6 because I really, really liked it (although MFC never
progressed past what I would consider a quickly-knocked-out rough cut).
Perhaps their stuff is better now, but from what I've heard the number
of library calls in the newest toolkits number in the tens of thousands,
and while 10 years ago one could be fluent, if not an expert, in most
areas of Windows development, now it seems real knowledge cannot exceed
more than a small piece of functionality due to the geometrically
increasing complexity of tools, while the actual software coming out of
these tools is increasing, at best, at a linear rate, and frankly has
been fairly static in terms of real usefulness for years.
Wow. I sure can ramble...