List:MySQL++« Previous MessageNext Message »
From:Rick Gutleber Date:October 29 2008 2:36pm
Subject:Re: Insert policy design question
View as plain text  
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 
> 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.

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, 
> CreateMysqlppQueryEx2().

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 

1.  Declare
2.  Initialize
3.  Use

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...

Insert policy design questionRick Gutleber27 Oct
Re: Insert policy design questionRick Gutleber27 Oct
  • Re: Insert policy design questionDrew M.27 Oct
    • Re: Insert policy design questionWarren Young27 Oct
      • Re: Insert policy design questionRick Gutleber28 Oct
        • Re: Insert policy design questionWarren Young28 Oct
          • Re: Insert policy design questionRick Gutleber28 Oct
            • Re: Insert policy design questionWarren Young28 Oct
              • Re: Insert policy design questionRick Gutleber28 Oct
                • Re: Insert policy design questionWarren Young28 Oct
                  • Re: Insert policy design questionRick Gutleber29 Oct
                    • SVN down?Rick Gutleber6 Nov
                      • Re: SVN down?Warren Young6 Nov
                  • Query::tellp( )Rick Gutleber29 Oct
                    • Re: Query::tellp( )Warren Young29 Oct
    • Re: Insert policy design questionRick Gutleber27 Oct
      • Re: Insert policy design questionDrew M.28 Oct
        • Re: Insert policy design questionRick Gutleber28 Oct
        • Re: Insert policy design questionWarren Young28 Oct
  • Re: Insert policy design questionWarren Young28 Oct
    • Re: Insert policy design questionRick Gutleber28 Oct