Package org.apache.metamodel.jdbc.dialects

Source Code of org.apache.metamodel.jdbc.dialects.AbstractQueryRewriter

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.metamodel.jdbc.dialects;

import java.util.List;

import org.apache.metamodel.jdbc.JdbcDataContext;
import org.apache.metamodel.query.AbstractQueryClause;
import org.apache.metamodel.query.FilterClause;
import org.apache.metamodel.query.FilterItem;
import org.apache.metamodel.query.FromClause;
import org.apache.metamodel.query.FromItem;
import org.apache.metamodel.query.GroupByClause;
import org.apache.metamodel.query.GroupByItem;
import org.apache.metamodel.query.OperatorType;
import org.apache.metamodel.query.OrderByClause;
import org.apache.metamodel.query.OrderByItem;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.query.SelectClause;
import org.apache.metamodel.query.SelectItem;
import org.apache.metamodel.schema.ColumnType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Abstract implementation of query rewriter. This implementation delegates the
* rewriting of the Query into several subtasks according to the query items to
* be rendered. This makes it easy to overload single methods in order to
* correct syntax quirks.
*/
public abstract class AbstractQueryRewriter implements IQueryRewriter {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    private final JdbcDataContext _dataContext;

    public AbstractQueryRewriter(JdbcDataContext dataContext) {
        _dataContext = dataContext;
    }

    public JdbcDataContext getDataContext() {
        return _dataContext;
    }

    @Override
    public ColumnType getColumnType(int jdbcType, String nativeType, Integer columnSize) {
        return ColumnType.convertColumnType(jdbcType);
    }

    public String rewriteQuery(Query query) {
        query = beforeRewrite(query);

        final StringBuilder sb = new StringBuilder();
        sb.append(rewriteSelectClause(query, query.getSelectClause()));
        sb.append(rewriteFromClause(query, query.getFromClause()));
        sb.append(rewriteWhereClause(query, query.getWhereClause()));
        sb.append(rewriteGroupByClause(query, query.getGroupByClause()));
        sb.append(rewriteHavingClause(query, query.getHavingClause()));
        sb.append(rewriteOrderByClause(query, query.getOrderByClause()));
        return sb.toString();
    }

    public boolean isSchemaIncludedInColumnPaths() {
        return false;
    }

    /**
     * Method to modify query before rewriting begins. Overwrite this method if
     * you want to change parts of the query that are not just rendering
     * related. Cloning the query before modifying is recommended in order to
     * not violate referential integrity of clients (the query is mutable).
     *
     * @param strategy
     * @param query
     * @return the modified query
     */
    protected Query beforeRewrite(Query query) {
        return query;
    }

    @Override
    public String rewriteColumnType(ColumnType columnType) {
        return columnType.toString();
    }

    protected String rewriteOrderByClause(Query query, OrderByClause orderByClause) {
        StringBuilder sb = new StringBuilder();
        if (orderByClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_ORDER_BY);
            List<OrderByItem> items = orderByClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                OrderByItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_COMMA);
                }
                sb.append(rewriteOrderByItem(query, item));
            }
        }
        return sb.toString();
    }

    @Override
    public String rewriteFromItem(FromItem item) {
        return rewriteFromItem(item.getQuery(), item);
    }

    protected String rewriteOrderByItem(Query query, OrderByItem item) {
        return item.toSql(isSchemaIncludedInColumnPaths());
    }

    protected String rewriteHavingClause(Query query, FilterClause havingClause) {
        StringBuilder sb = new StringBuilder();
        if (havingClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_HAVING);
            List<FilterItem> items = havingClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                FilterItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_AND);
                }
                sb.append(rewriteFilterItem(item));
            }
        }
        return sb.toString();
    }

    protected String rewriteGroupByClause(Query query, GroupByClause groupByClause) {
        StringBuilder sb = new StringBuilder();
        if (groupByClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_GROUP_BY);
            List<GroupByItem> items = groupByClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                GroupByItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_COMMA);
                }
                sb.append(rewriteGroupByItem(query, item));
            }
        }
        return sb.toString();
    }

    protected String rewriteGroupByItem(Query query, GroupByItem item) {
        return item.toSql(isSchemaIncludedInColumnPaths());
    }

    protected String rewriteWhereClause(Query query, FilterClause whereClause) {
        StringBuilder sb = new StringBuilder();
        if (whereClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_WHERE);
            List<FilterItem> items = whereClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                FilterItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_AND);
                }
                sb.append(rewriteFilterItem(item));
            }
        }
        return sb.toString();
    }

    @Override
    public String rewriteFilterItem(FilterItem item) {
        if (item.isCompoundFilter()) {
            FilterItem[] childItems = item.getChildItems();
            StringBuilder sb = new StringBuilder();
            sb.append('(');
            for (int i = 0; i < childItems.length; i++) {
                FilterItem child = childItems[i];
                if (i != 0) {
                    sb.append(' ');
                    sb.append(item.getLogicalOperator().toString());
                    sb.append(' ');
                }
                sb.append(rewriteFilterItem(child));
            }
            sb.append(')');
            return sb.toString();
        }

        final String primaryFilterSql = item.toSql(isSchemaIncludedInColumnPaths());

        final OperatorType operator = item.getOperator();
        if (operator == OperatorType.DIFFERENT_FROM) {
            final Object operand = item.getOperand();
            if (operand != null) {
                // special case in SQL where NULL is not treated as a value -
                // see Ticket #1058

                FilterItem isNullFilter = new FilterItem(item.getSelectItem(), OperatorType.EQUALS_TO, null);
                final String secondaryFilterSql = rewriteFilterItem(isNullFilter);

                return '(' + primaryFilterSql + " OR " + secondaryFilterSql + ')';
            }
        }

        return primaryFilterSql;
    }

    protected String rewriteFromClause(Query query, FromClause fromClause) {
        StringBuilder sb = new StringBuilder();
        if (fromClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_FROM);
            List<FromItem> items = fromClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                FromItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_COMMA);
                }
                sb.append(rewriteFromItem(query, item));
            }
        }
        return sb.toString();
    }

    protected String rewriteFromItem(Query query, FromItem item) {
        return item.toSql(isSchemaIncludedInColumnPaths());
    }

    protected String rewriteSelectClause(Query query, SelectClause selectClause) {
        StringBuilder sb = new StringBuilder();
        if (selectClause.getItemCount() > 0) {
            sb.append(AbstractQueryClause.PREFIX_SELECT);
            if (selectClause.isDistinct()) {
                sb.append("DISTINCT ");
            }
            List<SelectItem> items = selectClause.getItems();
            for (int i = 0; i < items.size(); i++) {
                SelectItem item = items.get(i);
                if (i != 0) {
                    sb.append(AbstractQueryClause.DELIM_COMMA);
                }
                sb.append(rewriteSelectItem(query, item));
            }
        }
        return sb.toString();
    }

    protected String rewriteSelectItem(Query query, SelectItem item) {
        return item.toSql(isSchemaIncludedInColumnPaths());
    }
}
TOP

Related Classes of org.apache.metamodel.jdbc.dialects.AbstractQueryRewriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.