On Thursday 17 May 2001 09:24, you wrote:
> On Wednesday, May 16, 2001, at 11:46  PM, Fedor Karpelevitch wrote:
> > On Wednesday 16 May 2001 16:45, you wrote:
> >> Eric Dobbs <[EMAIL PROTECTED]> writes:
> >>> Select, Update and Delete all have a where clause in common, but
> >>> Insert and Update both have a need to set columns to values, so
> >>> I think they belong together too.  Particularly because I think
> >>> there is a need to support "INSERT OR UPDATE ...".
> >>>
> >>> So maybe we need to create two interfaces here -- one that defines
> >>> methods related to the where clause, and one that defines methods
> >>> related to assigning values to columns.
> >>
> >> Yes, using two interfaces is definitely the Right Thing.
> >
> > I agree here, but my concern is that if you get into multiple
> > inheritance
> > thing you can no longer inherit implementation... Something to think
> > about
> > here....
>
> Yep, inheriting implementation would be nice.  So I put all the
> functionality for SELECT, INSERT, UPDATE and DELETE together in my
> first suggestion.  When I was extending that to create Select,
> Insert, Update, and Delete objects, my first draft was to make
> Query an abstract class and make the others subclasses.  Where
> there were methods in Query that were inappropriate for Insert, I
> would override the inappropriate methods and maybe throw an
> exception.  The whole point was to be able to inherit
> implementation while providing an API that reads well.  This
> inheritance convenience comes at the expense of having objects
> totally specialized to their task.

hm,hmm.... I do not like providing an API and not implementing it.... It's 
just not right... I am not sure how it can be done better.... I don't have a 
solid opinion here yet.
>
> >>> Select, and Delete would implement only the "where" interface.
> >>> Update would implement both "where" and "set column" interfaces.
> >>> Insert would implement only the "set column" interface.  I don't
> >>> know how to name those interfaces.
> >
> > sounds good, but see above...
> >
> >> So we need a Clause interface and a ColumnMap interface (interface
> >> names negotiable, just tossing out suggestions).
> >
> > I am not sure what Clause interface would mean. I do not see what
> > different
> > clauses have in common....
> > And I am not sure what you mean by ColumnMap interface, is that Eric's
> > "set
> > column"?
>
> I take Dan's suggestion to be names for the two interfaces I suggested.
> I think Where interface would be more specific,

I am still in doubt what Clase (Where) interface function would be...

> and maybe ColumnValueMap.

maybe

>
> >>>> BTW both Statement & Condition implement SQLCode interface which only
> >>>> contains toSQL metod.
> >>
> >> I really don't like the toSQL() method for a class which implements a
> >> SQLCode interface.  I would prefer that the standard toString() method
> >> be part of the SQLCode interface, and that toString() be used in place
> >> of toSQL().  Yes, the returned value *is* plenty readable.
> >
> > the reason for toSQL is not readablity (I withdrew that one), but these
> > two
> > things:
> >
> > 1) if you use toString() you end up with LOTS of String concatenation.
> > toSQL
> > returns StringStackBuffer instead. look at the code.
> > 2) toSQL takes DB as parameter ( sig is toSQL(DBdb)) so it has the
> > ability to
> > produce DB-specific SQL if needed.
>
> I like both of those reasons.  I like being able to pass in a DB object.
> I'm not sure StringStackBuffer is the right choice for the return type.

I think it is :-) It saves a lot of string concatenation. StringBuffer would 
not help much in this case.... In fact current Criteria & friends use 
StringStackBuffer and I found that reasonable.

> With a StringStackBuffer you can do .toString("/").  That's reasonable to
> do with a StringStackBuffer, but not reasonable for the SQL we want out.

In our case we'd use .toString() as there is no need for a separator.

> I think I would prefer a StringBuffer.  In which case I'd prefer a method
> named toStringBuffer(DB db).

I think using StringBuffer would be less efficient than StringStackBuffer as 
you would still have to coipy a lot of strings back and forth. I would name 
the method toStringStackBuffer if it was not that long and scary...

>
> >>>> i think adding .and() and .or() methods as described above will make
> >>>> you happy?
> >>>
> >>> Not yet.  I think what is bothering me about this model
> >>> is the use of objects to represent the comparisons.  I
> >>> don't think an equals operator should be represented as
> >>> an object unto itself.  Same for the rest of the logical
> >>> comparison operators.
> >>
> >> I frown on the extra objects that will be instantiated unnecessarily,
> >
> > I do not think I instantiate anything _extra_ here versus method-based
> > approach, because in that case you still need to put _some_ object into
> > your
> > list of conditions, be that Criterion or eanything else. So I think it
> > is
> > just as bad/good. I do not see any problem with that - objects are
> > pretty
> > light.
>
> Every place in the API you propose that has new XYZ() is instantiating
> an object.  By contrast, this latest suggestion I've offered...
>
> > new Comparison().equals(col,val).or().equals(col2,val2)

but how do you implement .equals() method? You will have to instanciate 
_some_ object to add to your list of conditions, won't you? That's what I 
meant... So there should be just as much object instantiation... am I wrong?


>
> ...the Comparison object is instantiated only once.  All of the methods
> would modify that Comparison instance and return a reference to it.
> The only place where another instance would be created is when nested
> groups are needed in the comparison.  That might look like this:
> new Comparison().equals(col,val).and(
>      new Comparison().equals(col2,val2).or().equals(col2,val3))
> which would create SQL like this:
> COL=VAL AND (COL2=VAL2 OR COL2=VAL3)
>
> With your model the equivalent SQL would need something like this:
> new And(new Equals(col,val),
>      new Or(new Equals(col2,val2), new Equals(col2,val3)))

so the only difference is _where_ in the code object is created, but the 
number should be the same....

On a side note, .equals is a bad name for the method as it looks like an 
overload for Object.equals(Object) method, but it has a completely different 
semantics which is confusing and is not good.

>
> Two instances in the former, four instances in the latter.  Instantiating
> objects is not light, otherwise there wouldn't be any need for the cool
> caching service.  I think the methods approach would offer better
> performance and I still think it reads better.

see above....

>
> >> though the interfaces do make for nice Java code.  However, this is
> >> code that will be called over and over again, so performance is an
> >> issue.
> >
> > btw in my opinion the better design allows for cleaner reuse of
> > Query/Condition objects (they are thread-safe too) so you will be able
> > to
> > save a lot of the calls etc...
> >
> >>> I'm thinking of another alternative that would use
> >>> methods instead of objects.  Like these: .equals(col,val),
> >>> .greaterThan(col,val), .in(col,val[]), .notIn(col,val[])
> >>
> >> I am not adverse to this idea.  It will certainly perform much better
> >> than possibly excessive object instantiation.
> >
> > again, i am afraid you'll have to create just as many objects. This
> > approach,
> > however is less flexible. The main reason I made everything an object
> > implementing Condition is that And and Or accepts conditions as members
> > which
> > in turn may be And's and Or's thjis way allowing clean way to create
> > conditions of any complexity. Also code duplication is virtual zero.

WBR, Fedor

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to