Hi Jurgen,

I support the idea behind this API. Let's discuss the shape of it though. 

In DFLib (a completely unrelated library that I am working on), we solved a 
similar problem with a more generic "map(..)" method that performs an arbitrary 
transformation on the object, that can include condition checking:

https://github.com/dflib/dflib/blob/main/dflib/src/main/java/org/dflib/DataFrame.java#L214

So how about this : 

  ObjectSelect.query(A.class).map(q -> c ? q.and(exp) : q);
  ObjectSelect.query(A.class).map(q -> c ? q.and(exp1) : q.and(exp2));

Cheers,
Andrus
 

> On Jul 3, 2024, at 7:32 AM, Jurgen Doll <jur...@ivoryemr.co.za> wrote:
> 
> Hi All
> 
> I really like the fluent style in Cayenne 4.
> 
> However I found that sometimes the fluent style in my code needs to be 
> interrupted if some condition has to be tested before configuring the select 
> any further, which then breaks the nice flow of code.
> 
> So I suggest adding the following API to ObjectSelect and to Expression 
> that'll smooth this over:
> 
> Add to ObjectSelect:
>     /**
>      * Conditionally append/chain the provided operation.
>      * @param condition if true then accept is invoked on the Consumer 
> parameter
>      * @param op provides the ObjectSelect to be modified if condition is true
>      * @return
>      */
>     public ObjectSelect addIf( boolean condition, Consumer> op )
>     {
>         if ( condition ) op.accept( this );
>         return this;
>     }
> Examples from my code base:
>     .addIf( yearRange != null, q -> q.where( APPOINTMENT_DATE.gt( yearRange ) 
> ) )
> 
> 
>     .addIf( includePublic, q -> q.or( createDateRangeExpression( 9999 ) ) )
> 
> 
>     .addIf( withAttachments, q -> q.prefetch( Message.ATTACHMENTS.joint() ) )
> 
> ----------------------
> 
> Add to Expression:
>     /**
>      * Conditionally append the provided operation to the current expression.
>      * @param condition if true then apply is invoked on the UnaryOperator 
> parameter
>      * @param op provides the expression to be modified if condition is true
>      * @return
>      */
>     public Expression addIf( boolean condition, UnaryOperator op )
>     {
>         return (condition) ? op.apply( this ) : this;
>     }
> Examples from my code base:
>     DefaultValue.USER.eq( userId ).andExp( DefaultValue.VALUE.ne( "" ) )
>     .addIf( keyName != null, exp -> exp.andExp( DefaultValue.NAME.eq( keyName 
> ) ) )
> 
> 
>     ExpressionFactory.matchExp( PatientNew.DATE_OF_BIRTH_PROPERTY, dob )
>     .addIf( idNo.length() > 6, exp -> exp.andExp( PatientNew.ID_NO.like( 
> idNo.substring(0,6)+"%" ) ) )
> 
> 
>     User.FIRSTNAME.eq( userParts[0] )
>     .addIf( userParts.length == 2, exp -> exp.andExp( User.SURNAME.eq( 
> userParts[1] ) ) )
> 
> 
>     AppointmentSms.APPOINTMENT_DATE.eq( aptDate )
>     .addIf( marketing, q -> q.andExp( AppointmentSms.MARKETING.eq( true ) ) )
> 
> What do you guys think ?
> 
> I can submit a PR if it passes as a good feature to add.
> The name of the method can be changed if anyone has a better suggestion.
> 
> Thanks, regards
> Jurgen

Reply via email to