comp.lang.ada
 help / color / mirror / Atom feed
From: "Warren W. Gay VE3WWG" <ve3wwg@NoSpam.cogeco.ca>
Subject: Re: Ada DB bindings and APQ
Date: Mon, 20 Dec 2004 00:33:31 -0500
Date: 2004-12-20T00:33:31-05:00	[thread overview]
Message-ID: <Yttxd.834$jT5.675@read1.cgocable.net> (raw)
In-Reply-To: <1f24uc05urd9n$.1xgzrog11d8pu.dlg@40tude.net>

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



  reply	other threads:[~2004-12-20  5:33 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-12 17:42 Ada DB bindings and APQ Dmitry A. Kazakov
2004-12-14  7:25 ` Warren W. Gay VE3WWG
2004-12-14 17:37   ` Dmitry A. Kazakov
2004-12-14 18:29     ` Georg Bauhaus
2004-12-14 19:45       ` Dmitry A. Kazakov
2004-12-14 21:06         ` Georg Bauhaus
2004-12-15  8:19           ` Ole-Hjalmar Kristensen
2004-12-15 17:20           ` Dmitry A. Kazakov
2004-12-16 13:28             ` Georg Bauhaus
2004-12-17 13:23               ` Dmitry A. Kazakov
2004-12-14 23:26         ` Brian May
2004-12-15 17:43           ` Dmitry A. Kazakov
2004-12-15 21:54             ` Brian May
2004-12-15  4:05     ` Warren W. Gay VE3WWG
2004-12-15 18:26       ` Dmitry A. Kazakov
2004-12-16  2:53         ` Warren W. Gay VE3WWG
2004-12-18 16:43           ` Dmitry A. Kazakov
2004-12-18 20:36             ` Warren W. Gay VE3WWG
2004-12-18 22:21               ` Dmitry A. Kazakov
2004-12-19  0:53                 ` Warren W. Gay VE3WWG
2004-12-19 12:21                   ` Dmitry A. Kazakov
2004-12-20  5:33                     ` Warren W. Gay VE3WWG [this message]
2004-12-20 20:01                       ` Dmitry A. Kazakov
2004-12-20 20:54                         ` Warren W. Gay VE3WWG
2004-12-14 22:40   ` Brian May
2004-12-15  3:23     ` Warren W. Gay VE3WWG
2004-12-15 15:01       ` Georg Bauhaus
2004-12-17  4:31         ` Brian May
2004-12-15 10:48   ` Brian May
2004-12-16  1:40     ` Brian May
2004-12-16  3:10       ` Warren W. Gay VE3WWG
2004-12-17  4:55         ` Brian May
2004-12-17 11:13           ` Warren W. Gay VE3WWG
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox