Hi everybody,
I am now trying to implement from scratch the expression package in
order to provide better support for "advanced" expressions and better
extendibility. At the moment I have done just the basic layout of the
interfaces / classes needed to support in memory evaluation, but I have
already a few ideas on how to implement the SQL generation too.
Before going further, I would like to collect some comments of the way
that expressions should behave on complex situations like the one
expressed below:
Example: let's take the structure described above and add a "User"
entity.
Item <-->> Bid <<--> User
The "Bid" has a to-one relationship to the "User" entity ("to_user");
the "User" entity has a to-many relationship to the "Bid" entity
("to_bids").
In this scenario, you could be interested in defining many expressions;
some examples:
1- "all items that have bids done by User_A and User_B"
2- "all items that have bids done by User whose gender is "male" and
whose address is in the United States.
From an SQL point of view, this two expressions translates to two very
different queries:
The first expression should translate to something like:
select t0.id_item, t0....
from item t0, bid t1, bid t2, user t3, user t4
where t0.id_item = t1.id_item
and t1.id_user = t3.id_user
and t3.id_user = <id User_A>
and t0.id_item = t2.id_item
and t2.id_user = t3.id_user
and t3.id_user = <id User_B>
While the second expression should translate to something like:
select t0.id_item, t0....
from item t0, bid t1, user t3
where t0.id_item = t1.id_item
and t1.id_user = t3.id_user
and t3.gender = "male"
and t3.state = "United States"
The whole SQL thing should be hidden by the library itself. But how
should I code these two differente situation in the application?
Let's start from the sencond expression, where the questions are
simpler.
I think anybody could agree that the following code looks quite right:
genderExpression = new KeyValueExpression("to_bids.to_user.gender",
OperatorSelector.Equal, "male");
stateExpression = new KeyValueExpression("to_bids.to_user.state",
OperatorSelector.Equal, "United States");
fullExpression = new AndExpression(genderExpression, stateExpression);
query = new SelectQuery(Item.class, fullExpression);
result = dataContext.performQuery(query);
(even if the code look right, any comments are more than welcome).
Now, let's look back at the first example. Here I can see more
reasonable options.
First take:
userAExpression = new KeyValueExpression("to_bids.to_user",
OperatorSelector.Equal, UserA);
userBExpression = new KeyValueExpression("to_bids.to_user",
OperatorSelector.Equal, UserB);
fullExpression = new AndExpression(userAExpression, userBExpression);
query = new SelectQuery(Item.class, fullExpression);
result = dataContext.performQuery(query);
Second take:
users = new Vector();
users.add(User_A);
users.add(User_B);
expression = new MatchAllValuesExpression("to_bids.to_user", users);
query = new SelectQuery(Item.class, expression);
result = dataContext.performQuery(query);
In the first take, all the logic of whether to split the relationship
must be coded in the AndExpression, even if I fear that a certain level
of heuristic (as a certain level of guess) will come into action when
the thing gets more tough.
On the second take, the semantic is chosen by the developer instead of
the framework and the code of the framework could be much simpler.
Any suggestion on this idea to restructure the expressions based on
their semantic, instead on their attribute (as they are now)?
Do you like the way the code looks like?
Thanks for the attention.
Giulio Cesare Solaroli
This archive was generated by hypermail 2.0.0 : Tue Oct 21 2003 - 04:28:51 EDT