44
44
import java .util .List ;
45
45
import java .util .Optional ;
46
46
import java .util .function .IntFunction ;
47
- import java .util .function .Predicate ;
48
47
import java .util .stream .Stream ;
49
48
50
- import org .usf .jquery .core .AggregateFunction ;
51
49
import org .usf .jquery .core .ComparisonExpression ;
52
50
import org .usf .jquery .core .DBColumn ;
53
51
import org .usf .jquery .core .DBFilter ;
68
66
import org .usf .jquery .core .TypedOperator ;
69
67
import org .usf .jquery .core .ViewColumn ;
70
68
import org .usf .jquery .core .ViewJoin ;
71
- import org .usf .jquery .core .WindowFunction ;
72
69
73
70
import lombok .AccessLevel ;
74
71
import lombok .AllArgsConstructor ;
@@ -242,10 +239,10 @@ public DBFilter evalFilter(ViewDecorator td, QueryContext ctx) {
242
239
return evalFilter (td , ctx , emptyList ());
243
240
}
244
241
245
- //[view.]criteria | [view.]column.criteria | [view.]column[.operator]*[.comparator]
246
- public DBFilter evalFilter (ViewDecorator vd , QueryContext ctx , List <RequestEntryChain > values ) { //supply values
242
+ //[view.]criteria | [view.]column.criteria | [view.]column[.operator]*[.comparator][.and|or(comparator)]*
243
+ public DBFilter evalFilter (ViewDecorator vd , QueryContext ctx , List <RequestEntryChain > values ) { //use CD.parser
247
244
var res = chainColumnOperations (vd , ctx , true );
248
- if (res .isEmpty ()) { //not a column
245
+ if (res .isEmpty ()) {
249
246
throw noSuchViewColumnException (this );
250
247
}
251
248
var rc = res .get ();
@@ -307,7 +304,7 @@ private Optional<ViewResource> chainColumnOperations(ViewDecorator td, QueryCont
307
304
if (nonNull (r .col )) {
308
305
var e = r .entry .next ;
309
306
while (nonNull (e )) { //chain until !operator
310
- var o = e .lookupOperation (td , ctx , r .col , null , fn -> true ); //accept all
307
+ var o = e .lookupOperation (td , ctx , r .col , null ); //accept all
311
308
if (o .isEmpty ()) {
312
309
break ;
313
310
}
@@ -318,7 +315,6 @@ private Optional<ViewResource> chainColumnOperations(ViewDecorator td, QueryCont
318
315
: o .get ();
319
316
e = e .next ;
320
317
}
321
-
322
318
} //else view criteria
323
319
return r ;
324
320
});
@@ -331,23 +327,25 @@ private static DBColumn windowColumn(ViewDecorator vd, QueryContext ctx, DBColum
331
327
return new ViewColumn (v , doubleQuote (tag ), null , col .getType ());
332
328
}
333
329
330
+ //view.resource | resource
334
331
private Optional <ViewResource > lookupResource (ViewDecorator vd , QueryContext ctx ) { //do not change priority
335
- if (hasNext ()) { //view.id == column.id
332
+ if (hasNext ()) {
336
333
var rc = currentContext ().lookupRegisteredView (value );
337
334
if (rc .isPresent ()) {
338
335
var res = next .lookupQueryResource (rc .get ()) //declared query first
339
- .or (()-> next .lookupViewResource (vd , ctx , rc .get (), RequestEntryChain :: isWindowFunction ));
336
+ .or (()-> next .lookupViewResource (vd , ctx , rc .get ()));
340
337
if (res .isPresent ()) {
341
338
requireNoArgs ();
342
339
return res ;
343
340
}
344
341
}
345
- }
342
+ } //view.id == column.id
346
343
return ctx .lookupDeclaredColumn (value )
347
344
.map (c -> new ViewResource (requireNoArgs (), null , null , c )) //declared column first
348
- .or (()-> lookupViewResource (vd , ctx , null , fn -> true )); //registered column
345
+ .or (()-> lookupViewResource (vd , ctx , null )); //registered column
349
346
}
350
347
348
+ //query.column
351
349
private Optional <ViewResource > lookupQueryResource (ViewDecorator vd ) {
352
350
if (vd instanceof QueryDecorator qd ) {
353
351
try {
@@ -358,41 +356,45 @@ private Optional<ViewResource> lookupQueryResource(ViewDecorator vd) {
358
356
return empty ();
359
357
}
360
358
361
- //view[.operator|column|criteria]
362
- private Optional <ViewResource > lookupViewResource (ViewDecorator vd , QueryContext ctx , ViewDecorator current , Predicate < TypedOperator > pre ) {
359
+ //view[.operator|column[.criteria] |criteria]
360
+ private Optional <ViewResource > lookupViewResource (ViewDecorator vd , QueryContext ctx , ViewDecorator current ) {
363
361
var cur = requireNonNullElse (current , vd );
364
- return lookupOperation (vd , ctx , null , current , pre )
362
+ return lookupOperation (vd , ctx , null , current )
365
363
.map (col -> new ViewResource (this , cur , null , col ))
366
364
.or (()-> lookupColumnResource (cur ))
367
365
.or (()-> ofNullable (cur .criteria (value )).map (crt -> new ViewResource (this , cur , crt )));
368
366
}
369
367
370
- private Optional <OperationColumn > lookupOperation (ViewDecorator vd , QueryContext ctx , DBColumn col , ViewDecorator current , Predicate <TypedOperator > opr ) {
371
- return lookupOperator (value ).filter (opr ).map (fn -> {
368
+ private Optional <OperationColumn > lookupOperation (ViewDecorator vd , QueryContext ctx , DBColumn col , ViewDecorator current ) {
369
+ var res = lookupOperator (value );
370
+ if (isNull (col ) && nonNull (current )) { //view.[count|rank|rowNumber|danseRank]
371
+ res = res .filter (op -> op .isCountFunction () || op .isWindowFunction ());
372
+ }
373
+ return res .map (fn -> {
372
374
var c = col ;
373
- if (isNull (c ) && isEmpty (args ) && isCountFunction (fn )) {
375
+ if (isNull (c ) && isEmpty (args ) && fn . isCountFunction ()) {
374
376
c = allColumns (requireNonNullElse (current , vd ).view ());
375
377
}
376
378
return fn .operation (toArgs (vd , ctx , c , fn .getParameterSet ()));
377
379
});
378
380
}
379
381
380
- Optional <ViewResource > lookupColumnResource (ViewDecorator td ) {
381
- try {
382
- var res = currentContext (). lookupRegisteredColumn ( value );
383
- if ( res .isPresent ()) {
384
- var cd = res . get ();
382
+ private Optional <ViewResource > lookupColumnResource (ViewDecorator td ) {
383
+ var res = currentContext (). lookupRegisteredColumn ( value );
384
+ if ( res . isPresent ()) {
385
+ var cd = res .get ();
386
+ try {
385
387
var col = td .column (cd ); //throw exception
386
- if (hasNext ()) {
387
- var crt = res . get () .criteria (next .value );
388
+ if (hasNext () && lookupComparator ( next . value ). isEmpty ()) { //!comparator
389
+ var crt = cd .criteria (next .value );
388
390
if (nonNull (crt )) {
389
- return Optional .of (new ViewResource (next , td , cd , col , crt ));
391
+ return Optional .of (new ViewResource (requireNoArgs (). next , td , cd , col , crt ));
390
392
}
391
393
}
392
- return Optional .of (new ViewResource (this , td , cd , col ));
394
+ return Optional .of (new ViewResource (requireNoArgs () , td , cd , col ));
393
395
}
396
+ catch (Exception e ) {/*do not throw exception*/ } //TD specific exception
394
397
}
395
- catch (Exception e ) {/*do not throw exception*/ }
396
398
return empty ();
397
399
}
398
400
@@ -495,16 +497,7 @@ public String toString() {
495
497
}
496
498
return isNull (tag ) ? s : s + ":" + tag ;
497
499
}
498
-
499
- private static boolean isWindowFunction (TypedOperator op ) {
500
- var fn = op .unwrap ();
501
- return fn instanceof WindowFunction || fn instanceof AggregateFunction ; //rank() | sum(col)
502
- }
503
-
504
- private static boolean isCountFunction (TypedOperator fn ) {
505
- return "COUNT" .equals (fn .unwrap ().id ());
506
- }
507
-
500
+
508
501
private static String [] toStringArray (List <RequestEntryChain > entries ) {
509
502
if (!isEmpty (entries )) {
510
503
return entries .stream ()
@@ -540,8 +533,8 @@ static EntrySyntaxException expectedEntryTagException(RequestEntryChain e) {
540
533
static final class ViewResource {
541
534
542
535
private RequestEntryChain entry ;
543
- private ViewDecorator vd ; //optional
544
- private ColumnDecorator cd ; //optional
536
+ private ViewDecorator vd ;
537
+ private ColumnDecorator cd ;
545
538
private DBColumn col ;
546
539
private CriteriaBuilder <DBFilter > viewCrt ;
547
540
private CriteriaBuilder <ComparisonExpression > colCrt ;
@@ -564,7 +557,7 @@ private boolean isCriteria() {
564
557
565
558
@ Override
566
559
public String toString () {
567
- return vd + "." + cd + " => " + entry .toString ();
560
+ return entry .toString ();
568
561
}
569
562
}
570
563
}
0 commit comments