cayenne-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nikita Timofeev <ntimof...@objectstyle.com>
Subject Re: Property expressions, Was: API for aggregate and non aggregate SQL functions
Date Tue, 10 Jan 2017 09:03:09 GMT
On Tue, Jan 10, 2017 at 5:27 AM, Aristedes Maniatis <ari@maniatis.org> wrote:
> On 9/1/17 8:45pm, Nikita Timofeev wrote:
>>> Could that syntax above could be cleaner like:
>>>
>>>    Property<Integer> nameLength = Artist.ARTIST_NAME.function(Expression.SQL_LENGTH)
>>>
>>> or is that just going to result in a whole lot of clutter in the class?
>>>
>> Such methods will create too much coupling between properties and
>> functions, I'm afraid,
>> as Property class would know about all SQL functions and their arguments.
>
>
> I'm not convinced that all the SQL specific code would land in the Property class. That
would be a wrapper to the factory methods elsewhere.
>
> I'm not sure the enum approach above is the cleanest, but some shorter simpler API which
still gives us the correct Property<Integer> generics would be nice.

It's not a specific SQL code I don't like to see there, but a bunch of
methods that doesn't seem to be very popular:

public Property<String> substring(int length) {
    return Property.create(FunctionExpressionFactory.substringExp(getExpression(),
length, 0), String.class);
}

public Property<String> substring(int length, int offset) {
    return Property.create(FunctionExpressionFactory.substringExp(getExpression(),
length, offset), String.class);
}

public Property<E> sum() {
    return Property.create(FunctionExpressionFactory.sumExp(getExpression()),
getType());
}

public Property<Integer> length() {
    return Property.create(FunctionExpressionFactory.lengthExp(getExpression()),
Integer.class);
}

The single function() method is better though. And I can imagine this
way of creating properties:

Property<Long> paintingCount =
Artist.PAINTING_ARRAY.function(PropertyCreator.COUNT);

where PropertyCreator.COUNT is something like this:

public interface PropertyCreator<T> {
    PropertyCreator<Long> COUNT = new PropertyCreator<Long>() {
        public Property<Long> create(Property<?> property) {
            return
Property.create(FunctionExpressionFactory.countExp(property.getExpression()),
Long.class);
        }
    };

    Property<T> create(Property<?> property);
}

But there is a big problem with properties' types with
Property.function(...) approach (either with enum or with this
Creator).
While some functions like SUM() (along with MIN, MAX,AVG) depend on
original property type, others like COUNT or LENGTH have constant
return type.
So for now I don't see any solution good enough for all cases: we
would end up either with bunch of methods duplicating expression
factory or without proper type checking.

-- 
Best regards,
Nikita Timofeev

Mime
View raw message