/* * Copyright 2011, Mysema Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mysema.query.sql; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.google.common.collect.ImmutableList; import com.mysema.query.types.Expression; import com.mysema.query.types.MutableExpressionBase; import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.TemplateFactory; import com.mysema.query.types.Visitor; import com.mysema.query.types.expr.ComparableExpressionBase; import com.mysema.query.types.expr.SimpleExpression; import com.mysema.query.types.template.SimpleTemplate; /** * @author tiwe * * @param */ public class WindowFirstLast extends MutableExpressionBase { private static final long serialVersionUID = 4107262569593794721L; private static final String ORDER_BY = "order by "; private final List> orderBy = new ArrayList>(); private volatile SimpleExpression value; private final Expression target; private final boolean first; public WindowFirstLast(WindowOver target, boolean first) { super(target.getType()); this.target = target; this.first = first; } @Override public R accept(Visitor v, C context) { return getValue().accept(v, context); } public WindowFirstLast orderBy(ComparableExpressionBase orderBy) { value = null; this.orderBy.add(orderBy.asc()); return this; } public WindowFirstLast orderBy(ComparableExpressionBase... orderBy) { value = null; for (ComparableExpressionBase e : orderBy) { this.orderBy.add(e.asc()); } return this; } public WindowFirstLast orderBy(OrderSpecifier orderBy) { value = null; this.orderBy.add(orderBy); return this; } public WindowFirstLast orderBy(OrderSpecifier... orderBy) { value = null; this.orderBy.addAll(Arrays.asList(orderBy)); return this; } SimpleExpression getValue() { if (value == null) { if (orderBy.isEmpty()) { // TODO this check should be static throw new IllegalStateException("No order by arguments given"); } ImmutableList.Builder> args = ImmutableList.builder(); StringBuilder builder = new StringBuilder(); builder.append("{0} keep (dense_rank "); args.add(target); builder.append(first ? "first " : "last "); builder.append(ORDER_BY); boolean first = true; int size = 1; for (OrderSpecifier expr : orderBy) { if (!first) { builder.append(", "); } builder.append("{" + size + "}"); if (!expr.isAscending()) { builder.append(" desc"); } args.add(expr.getTarget()); size++; first = false; } builder.append(")"); value = new SimpleTemplate( target.getType(), TemplateFactory.DEFAULT.create(builder.toString()), args.build()); } return value; } public WindowFunction over() { return new WindowFunction(getValue()); } }