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!news2.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Ada DB bindings and APQ Date: Sat, 18 Dec 2004 17:43:57 +0100 Organization: cbb software GmbH Message-ID: <18ns1q1fkc6st.15vfm6brappgj$.dlg@40tude.net> References: <1km3c584awura$.y7djkir1ozya$.dlg@40tude.net> <4KOvd.54$jT5.8@read1.cgocable.net> <5s8i4q5psxsn.ap1vrcl5pf02$.dlg@40tude.net> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: individual.net 7h6Glf9jN+fkgH6iRQy/XQ4CJBlijyiNSA8j8WK+1hBQkHbX4= User-Agent: 40tude_Dialog/2.0.12.1 Xref: g2news1.google.com comp.lang.ada:7051 Date: 2004-12-18T17:43:57+01:00 List-Id: On Wed, 15 Dec 2004 21:53:11 -0500, Warren W. Gay VE3WWG wrote: > Dmitry A. Kazakov wrote: >> On Tue, 14 Dec 2004 23:05:17 -0500, Warren W. Gay VE3WWG wrote: >>>Dmitry A. Kazakov wrote: >>>>Connection could be just a handle to some dynamic-scope connection object >>>>with reference counting. This will solve both the problem of above and >>>>still allow cloning connections. >>> >>>I didn't like the use of handles for database objects. I purposely >>>stuck to using controlled objects, so that they can go out of >>>scope gracefully, be finalized (perhaps committed or rolled back) >>>and then destructed. Handles, like open Ada File_Types, never >>>get that maintenance. >> >> Let's make them derived from Ada.Finalization.Controlled. > > What's the point of that? Why not use the actual object? It > seems like unnecessary indirection and complexity - what > problem are you trying to solve with handles? Dynamic scopes. If user creates these objects on the stack then [s]he is responsible for doing it in a proper order. The only way Ada might help here is to use access discriminants, then Ada accessibility rules will do the work. >> if Root_Connection_Type were limited controlled, derived from >> Object.Entity, then I could create handles just by instantiating >> Object.Handle. Root_Query_Type can hold a handle to its connection. This >> will ensure that the connection will not go away until at least one query >> is alive. > > But why? The objects themselves solve the problem already. How? Either you have one more level of idirection, then you could remove it. >>>>BTW, one could get rid of query type altogether if there would be two >>>>different connection-cloning. One that returns a handle to a new >>>>"connection" (physically just new query) for the same underlying connection >>>>object, another that makes a new connection. >>>> >>>>I do not see much sense in all that levels of types exposed to the user. In >>>>ODBC it is even one more: environment > connection > statement. It is >>>>rather implementation details to me. (Everything is a file (:-)) >>> >>>ODBC is not the only one. Sybase implements an object that >>>also fills this role. I believe that you want to keep the >>>objects well separated by function, and I'll admit that I >>>compromised principle by combining environment & connection. >>>But I think OO design principles are such that you don't >>>want to roll everything into one massive object. >> >> Right, if the functionality differs. But so far there are little or no >> things which can be made with a connection. That is different to ODBC. Also >> ODBC has prepared statements. And that all just does ODBC too complex to >> use. > > Here is food for thought ;-) -- if Sybase and other databases implement > their interface with 2-3 different classes of objects, why is the > APQ design so wrong to do something similar? Sybase interface is a low-level one. If there were an interface to some RISC processor, then probably it would have objects for registers, cache levels etc. It would be very exciting, but annoying for an Ada programmer. > I really can't > see why all the fuss over one object vs two from the user's > perspective. Not everything is a hammer (read File_Type), > and there is room for multi-object designs in modelling > interfaces. There should be a purpose in separating. So far I see none. >>>>Handle --> Query_Object --> Connection_Object >>>> >>>>1. Handle copy (+1 reference count of Query_Object) >>>>2. Light-weight copy: creates new query (+1 reference count of connection) >>>>3. Heavy-weight copy: creates a new query and a new connection >>> >>>When designing an API, I always try to look at the way >>>it is going to be used and why it must exist. I shy away >>>from unnecessary API, unless it is frequently needed (to >>>save or simplify code). >>> >>>So coming back to this, I have to ask, what is the >>>problem that this is intended to solve? >> >> You will get rid of parallel hierarchy of types: >> >> Root_Connection_Type <- MySQL.Connection_Type >> | | >> Root_Query_Type <- MySQL.Query_Type >> >> Ada is unable to provide any consistency here. You can mistakenly use >> PostgreSQL.Query_Type with MySQL.Connection_Type. > > You can compile it, but you'll get an exception when > you try to use Execute with a mismatched paramter. Don't > forget that the connection gets "converted" to the > MySQL.Connection_Type before it can be used, and of > course this will fail if it is a PostgreSQL.Connection_Type. > > So "Ada does provide consistency here", but not at > compile time. It is your implementation which does checks, not Ada. Then the result is that you have replaced one exception with another. The ultimate design goal, in my view, should be that only exception related to failed DB operations might propagate. We should separate soup and flies. >> You can finalize >> connection before a query that depends on it etc. > > That is a risk, but its generally pretty obvious at > runtime when it happens! But if you structure your > code normally, the Connection_Type is declared > at the outermost scope and again, this tends not > to be a problem. That reminds me argumentation of C proponents. (:-)) >>>Doing table names in a portable way is problematic. Some databases >>>are not case sensitive, but they are case sensitive when they come >>>to TABLE names. Others can be configured to force lowercase table >>>names (MySQL IIRC), still others are always case sensitive (Sybase). >>> >>>This is why "case policy" was introduced into APQ 2.2. This is also >>>why it is necessary to distinguish between certain SQL building >>>APIs and other others like Append_Quoted. >>> >>>Believe me, if there was a unified way to do it all, I would have >>>welcomed it. But the reality is a bit more complicated than that ;-) >> >> The method that places a value into a query should simply dispatch on the >> query type. The implementation is then DB specific and will encode the >> value as appropriate for the DB. > > Heh heh, it all sounds very easy ;-) It is easy. MySQL implementation does know how to properly encode values. But if you think that it is not easy, then it is even more so unfair to push that to poor users! (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de