Advanced Queries
The query mechanism
As you already know from Basic Operations, queries to a database are done by creating a
ABEL will by default load an object completely, meaning all objects that can be reached by following references will be loaded as well (see also Dealing with References).
Criteria
You can filter your query results by setting criteria in the query object, using feature
Predefined Criteria
When using a predefined criterion you pick an attribute name, an operator and a value. During a read operation, ABEL checks the attribute value of the freshly retrieved object against the value set in the criterion, and filters away objects that don't satisfy the criterion.
Most of the supported operators are pretty self-describing (see class
You can only use attributes that are strings or numbers, but not every type of attribute supports every other operator. Valid combinations for each type are:
- Strings: =, like
- Any numeric value: =, <, <=, >, >=
- Booleans: =
Note that for performance reasons it is usually better to use predefined criteria, because they can be compiled to SQL and hence the result can be filtered in the database.
Agent Criteria
An agent criterion will filter the objects according to the result of an agent applied to them.
The criterion is initialized with an agent of type
Creating criteria objects
The criteria instances are best created using the
The main features of the class are the following:
class
PS_CRITERION_FACTORY
create
default_create
feature -- Creating a criterion
new_criterion alias "()" (tuple: TUPLE [ANY]): PS_CRITERION
-- Creates a new criterion according to a `tuple'
-- containing either a single PREDICATE or three
-- values of type [STRING, STRING, ANY].
new_agent (a_predicate: PREDICATE [TUPLE [ANY]]): PS_CRITERION
-- Creates an agent criterion.
new_predefined (object_attribute: STRING; operator: STRING; value: ANY): PS_CRITERION
-- Creates a predefined criterion.
feature -- Operators
equals: STRING = "="
greater: STRING = ">"
greater_equal: STRING = ">="
less: STRING = "<"
less_equal: STRING = "<="
like_string: STRING = "like"
end
Assuming you have an object
- The "traditional" way
-
factory.new_agent (agent an_agent) -
factory.new_predefined (an_attr_name, an_operator, a_val)
-
- The "syntactic sugar" way
-
factory (an_attr_name, an_operator, a_value) -
factory (agent an_agent)
-
create_criteria_traditional : PS_CRITERION
-- Create a new criteria using the traditional approach.
do
-- for predefined criteria
Result:= factory.new_predefined ("age", factory.less, 5)
-- for agent criteria
Result := factory.new_agent (agent age_more_than (?, 5))
end
create_criteria_parenthesis : PS_CRITERION
-- Create a new criteria using parenthesis alias.
do
-- for predefined criteria
Result:= factory ("age", factory.less, 5)
-- for agent criteria
Result := factory (agent age_more_than (?, 5))
end
age_more_than (person: PERSON; age: INTEGER): BOOLEAN
-- An example agent
do
Result:= person.age > age
end
Combining criteria
You can combine multiple criterion objects by using the standard Eiffel logical operators. For example, if you want to search for a person called "Albo Bitossi" with
composite_search_criterion : PS_CRITERION
-- Combining criterion objects.
local
first_name_criterion: PS_CRITERION
last_name_criterion: PS_CRITERION
age_criterion: PS_CRITERION
do
first_name_criterion:= factory ("first_name", factory.equals, "Albo")
last_name_criterion := factory ("last_name", factory.equals, "Bitossi")
age_criterion := factory (agent age_more_than (?, 20))
Result := first_name_criterion and last_name_criterion and not age_criterion
-- Shorter version:
Result := factory ("first_name", "=", "Albo")
and factory ("last_name", "=", "Bitossi")
and not factory (agent age_more_than (?, 20))
end
ABEL supports the three standard logical operators