From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ee0dc912649d50d4 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!news.glorb.com!meganewsservers.com!feeder2.on.meganewsservers.com!feed.cgocable.net!read1.cgocable.net.POSTED!53ab2750!not-for-mail From: "Warren W. Gay VE3WWG" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Ada DB bindings and APQ References: <1km3c584awura$.y7djkir1ozya$.dlg@40tude.net> <4KOvd.54$jT5.8@read1.cgocable.net> <5s8i4q5psxsn.ap1vrcl5pf02$.dlg@40tude.net> <18ns1q1fkc6st.15vfm6brappgj$.dlg@40tude.net> <5w0xd.649$Wt5.249397@read2.cgocable.net> <1tusn81lxo8m0$.67it7z7w00ov.dlg@40tude.net> <1f24uc05urd9n$.1xgzrog11d8pu.dlg@40tude.net> In-Reply-To: <1f24uc05urd9n$.1xgzrog11d8pu.dlg@40tude.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: Date: Mon, 20 Dec 2004 00:33:31 -0500 NNTP-Posting-Host: 24.150.168.167 X-Complaints-To: abuse@cogeco.ca X-Trace: read1.cgocable.net 1103520760 24.150.168.167 (Mon, 20 Dec 2004 00:32:40 EST) NNTP-Posting-Date: Mon, 20 Dec 2004 00:32:40 EST Organization: Cogeco Cable Xref: g2news1.google.com comp.lang.ada:7088 Date: 2004-12-20T00:33:31-05:00 List-Id: Dmitry A. Kazakov wrote: ... >>>> 1. Environment (userid, passwords, ports, address, hostname etc.) >>> >>>You can get all that from a connection object >> >>Again, they have different data items, states and methods. Again, >>you have a 1 to many relationship between environment and >>connections! > > These connections are between implementation objects. There is no reason to > expose these details to the end user. There is, but I give up. You obviously don't like dividing up a problem into reasonable objects. You'd rather have it all in one large mass, which I cannot agree with. Even M$ wouldn't do this for MFC, as you've used for example, later on. We're just going to disagree on this point, and I see no reason to flog this dead horse any longer. ;-) >>>> 2. The connection (methods like connect, disconnect, am I connected) >>> >>>Why should I connect, disconnect etc. From user's perspective, when I >>>create an object it should be usable, immediately. >> >> From a user's perspective, you want "control". You are espousing >>a Microsoft approach where you take control away from the caller, >>and instead tie connection with construction. This is not very >>flexible. > > It is not their approach. At least in MFC. Either because of C++ object > construction model deficiency, or just in order to keep users in awe, but > the result is that anything has Init(). Actually, MFC is one of the things that M$ has done fairly well in my books. I was referring more to the general M$ philosophy that Windoze uses (taking away control). Their API sometimes does this as well IMO, but I am too lazy to cite a specific example. > As a user I don't want to control anything. I just want to use it. Heh, heh, what's the difference? If I _use_ a car, I _am_ controlling it. If I _use_ a can opener, I sure hope I am in control of it! If we can't agree on that, then let's just disagree once again. > Only > when it first works, and there are problems with how it works, then maybe, > but unlikely, I would attune it a bit. > > The major goal of any bindings is to maintain complexity. Correction: _a_ major goal is... but it is by no means the only one. It is only one of several important goals, many of them in conflict requiring a balanced compromise. >>>Introducing Connect, you >>>add complexity and various sources of errors. I can understand where >>>Connect comes from: Ada has no proper constructors with parameters for >>>limited objects. This is the reason for handles (they are non-limited). But >>>your objects are not limited, so there is no reason for creating >>>half-backed objects: >> >>Look, it has nothing to do with Ada or "half baked" objects ("baked" >>is what I think you meant). It is all about control. If we took your >>view, you would never allow a Rewind operation on a file. > > Exactly, because not every device would allow it. It would be a bad design > to allow rewind that throws Use_Error. A proper design would be to derive a > class of files which can be rewound from the base class of files. So Ada's Rewind operation is faulty in your view? C's fseek() is faulty in your view? C'mon now. Really. We're all big boys here, and can figure out when Rewind is proper and when its not. I support Ada and "its ways", but let's not expect a "rubber room" in which we can never do something harmful. If that ever happens, then I think it is probably safe to say that we've wound up at the Asylum. >>You would have to destruct it and recreate it. > > Yes, because the file was a socket! Whether it is a socket or a named pipe, anonymous pipe or microkernel message queue, doesn't matter to the user. That is a physical detail. This detail however, does sometimes poke through to the user, for example, when specifying say the URI for connecting to the database, but otherwise how the connection is made is imaterial (the "how" does put requirements on how the connection is specified, but otherwise the details are not important). But back to the orignal point, why this means that I have to do a construct/destruct just to connect or not? Here's another reason why this requirement is not a good thing (TM): Since (at present) the Connection_Type object includes the connection environment as well, every time you construct the object new, you also have to reconfigure/specify all of that connection information. Now if you add parsing of the URI (instead), it starts to add some significant overhead (admittedly not a lot, compared to the time required to establish a connection - but still this is wasted work being repeated each time). From a design perspective, this is bad, because you unnecessarily repeat processing what need only be done once (many applications only ever deal with one database/schema). This is in fact one argument in favour of the environment object, but let's not flog that horse.. >>An object goes through states, sometimes many of them. I see nothing >>half baked about being connected or not. > > Do not forget separation of implementation and interface. There are logical > and physical states, there are interface and implementation objects. They > need *not* to be same. You are trying to throw everything in one cauldron. No, I disagree. The user need not understand all of the specifics whether they are physical, or Sybase or MySQL specific API issues (APQ hides this ugliness). What the APQ API _does_ support is the simple idea that the user's object is "connected" or "not connected". Where is the cauldron there? If there is any soup, it _is_ in the way that APQ currently includes "environment", when in fact it actually belongs in its own user object (but again, I digress). >>What IS half baked about it >>is that it combines Environment & connection! By putting them in >>one object, I multiply the number of states and methods for a >>combined object. > > These states are of no user interest. I do not need an unconnected > connection. Really, it is like inedible food. If I am using the Booch components (for example), what you are suggesting is that I should not have a Map object, if it is empty ("inedible food"). After all, according to your logic, what can you do with an empty Map object? You would only have a Map object created, when it contains at least one object. But writing code to work this way is more work, and pointless without a special requirement to do so. There is nothing wrong with objects having defined states. Just because an object is empty or disconnected, is not an argument by itself against the existence of the object as you are insisting it is. There might be other requirements that make this a good idea, but this argument by itself does not decide the case IMHO. > If you compare the time required to connect with the time required to > initialize an interface object you will find that the latter is negligible. Time and overhead is not the only factor. At the point where you want to connect to the database, you might not have access to the very parameters that you need to supply (this often happens in GUI callbacks). An unconnected object can preconfigure all of the parameters necessary for a connect operation to be done at some other point in time. By your linking of these two "actions", you now force the user to drag around all of this extra baggage, in order to affect a successful "connect". In effect, you've made the API more difficult for some users. > If you mean a physical communication object, then again it is not user's > responsibility. Normally, it is OS which maintains a pool file descriptors. > Because they are OS's resources. It would be wrong to require from an Ada > application to interfere there. > > Let that be an issue, then most probably it will highly depend on the > target DB type. So the user will have no opportunity to influence it > anyway. It is the responsibility of bindings to internally provide pools of > objects expensive to create. Connections are usually expensive. But APQ doesn't try to mitigate that, since the control over _when_ and the _frequency_ of the connecting operations are under the control of the calling program (as it should be). Users of APQ don't want me deciding this for them. >>>> 3. The query >>> >>>Because Connection has no methods except for a construction function, it >>>can be merged with query >> >>There is a 1 to many relationship between connections and queries! > > In the interface it is 1 to 1. Internally it might be any, why should I > care? Not everything is a hammer. In life we work with many objects as users of objects. OO programming borrows from some of our life experiences. >>>> 4. Blobs >>> >>>Yes. This is a different thing. One will probably need a common base for >>>all types on Ada side with can be stored in DB. Blobs is just on of them. >>>Presumably there also should be DB_Integer, DB_String, DB_Bounded_String >>>etc. >> >>Naw. I prefer to use Ada streams for Blob I/O. > > Alas, but they are not portable. This is indeed a weakness. However, it can be _portable_ if the user uses it that way (for example if he chooses only to write streams of bytes or Stream_Elements). But I'll agree, this has its limitations. >>That way I don't have to force the user to use types that I dream up. > > [ Ada 2005 will finally have multiple inheritance restricted to interfaces. > That will solve the problem without ugly generics. ] I don't see how MI is going to fix this problem, but no matter. > Look, you describe the interface of a DB type and user have to implement > it. Note that it is not you, who forces the user, but a very real thing, > the DB. There *must* be a mapping between DB and user types. Your "dreamed > up" types just embody that mapping. You've missed the point. In Ada I have the choice between using something like Integer or a type that I define: type My_Int is range 0..5; Your approach is to force the user to derive their type from something that APQ provides (or something standard Ada provides). For example, APQ could say that if you write an integer out to a blob that you have to use APQ.Blob_Integer or some such. type My_Int is new APQ.Blob_Integer range 0..5; -- eg But if I were the programmer, I would not like this much, because I'd want to use My_Int instead (maybe it is defined by a 3rd party package). > User-defined type conversions might do it very easy and elegant, but that > is another story. I hate unnecessary use of "conversions". They are a great source of error. This is why APQ goes out of its way to provide generic procedures so that programs don't have to be written with conversions all over the place. It reminds me too much of casting C types all over the place -- it strips the compiler of much of its type safety. -- Warren W. Gay VE3WWG http://home.cogeco.ca/~ve3wwg