Package com.impetus.client.cassandra.query

Source Code of com.impetus.client.cassandra.query.CassandraEntityReader

/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
*  *
*  * 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.impetus.client.cassandra.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.cassandra.thrift.IndexClause;
import org.apache.cassandra.thrift.IndexExpression;
import org.apache.cassandra.thrift.IndexOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.impetus.client.cassandra.CassandraClientBase;
import com.impetus.kundera.Constants;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.ClientBase;
import com.impetus.kundera.client.EnhanceEntity;
import com.impetus.kundera.db.SearchResult;
import com.impetus.kundera.metadata.MetadataUtils;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.persistence.AbstractEntityReader;
import com.impetus.kundera.persistence.EntityManagerFactoryImpl.KunderaMetadata;
import com.impetus.kundera.persistence.EntityReader;
import com.impetus.kundera.query.KunderaQuery;
import com.impetus.kundera.query.QueryHandlerException;

/**
* The Class CassandraEntityReader.
*
* @author vivek.mishra
*/
public class CassandraEntityReader extends AbstractEntityReader implements EntityReader
{
    private static final String MIN_ = "min";

    private static final String MAX_ = "max";

    /** The conditions. */
    private Map<Boolean, List<IndexClause>> conditions = new HashMap<Boolean, List<IndexClause>>();

    /** The log. */
    private static Logger log = LoggerFactory.getLogger(CassandraEntityReader.class);

    /**
     * Instantiates a new cassandra entity reader.
     *
     * @param luceneQuery
     *            the lucene query
     */
    public CassandraEntityReader(KunderaQuery kunderaQuery, final KunderaMetadata kunderaMetadata)
    {
        super(kunderaMetadata);
        this.kunderaQuery = kunderaQuery;
    }

    /**
     * Instantiates a new cassandra entity reader.
     */
    public CassandraEntityReader(final KunderaMetadata kunderaMetadata)
    {
        super(kunderaMetadata);
    }

    @Override
    public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client)
    {
        return super.findById(primaryKey, m, client);
    }

    /**
     * Method responsible for reading back entity and relations using secondary
     * indexes(if it holds any relation), else retrieve row keys using lucene.
     *
     * @param m
     *            entity meta data
     * @param relationNames
     *            relation names
     * @param isParent
     *            if entity is not holding any relation.
     * @param client
     *            client instance
     * @return list of wrapped enhance entities.
     */

    @Override
    public List<EnhanceEntity> populateRelation(EntityMetadata m, Client client, int maxResults)
    {
        if (log.isInfoEnabled())
        {
            log.info("On populate relation via JPQL");
        }
        List<EnhanceEntity> ls = null;
        List<String> relationNames = m.getRelationNames();
        boolean isParent = m.isParent();

        boolean isRowKeyQuery = conditions != null ? conditions.keySet().iterator().next() : false;

        // If Query is not for find by range.
        if (!isRowKeyQuery)
        {
            // If holding associations.
            if (!isParent)
            {
                // In case need to use secondary indexes.
                if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata()))
                {
                    ls = ((CassandraClientBase) client).find(m, relationNames, this.conditions.get(isRowKeyQuery),
                            maxResults, null);
                }
                else
                {
                    // prepare lucene query and find.
                    Set<String> rSet = fetchDataFromLucene(m.getEntityClazz(), client);

                    try
                    {
                        ls = (List<EnhanceEntity>) ((CassandraClientBase) client).find(m.getEntityClazz(),
                                relationNames, true, m, rSet.toArray(new String[] {}));
                    }
                    catch (Exception e)
                    {
                        log.error("Error while executing handleAssociation for cassandra, Caused by: ", e);
                        throw new QueryHandlerException(e);
                    }
                }
            }
            else
            {
                if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata()))
                {
                    // in case need to search on secondry columns and it is not
                    // set
                    // to true!
                    ls = ((CassandraClientBase) client).find(this.conditions.get(isRowKeyQuery), m, true,
                            m.getRelationNames(), maxResults, null);
                }
                else
                {
                    ls = onAssociationUsingLucene(m, client, ls);
                }
            }
        }
        else
        {
            ls = handleFindByRange(m, client, ls, conditions, isRowKeyQuery, null, maxResults);
        }
        return ls;
    }

    /**
     * Handle find by range.
     *
     * @param m
     *            the m
     * @param client
     *            the client
     * @param result
     *            the result
     * @param ixClause
     *            the ix clause
     * @param isRowKeyQuery
     *            the is row key query
     * @param columns
     * @return the list
     */
    public List handleFindByRange(EntityMetadata m, Client client, List result,
            Map<Boolean, List<IndexClause>> ixClause, boolean isRowKeyQuery, List<String> columns, int maxResults)
    {
        List<IndexExpression> expressions = ixClause.get(isRowKeyQuery).get(0).getExpressions();

        if (expressions == null)
        {
            return null;
        }

        Map<String, byte[]> rowKeys = getRowKeyValue(expressions,
                ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName());

        byte[] minValue = rowKeys.get(MIN_);
        byte[] maxVal = rowKeys.get(MAX_);

        try
        {
            result = ((CassandraClientBase) client).findByRange(minValue, maxVal, m, m.getRelationNames() != null
                    && !m.getRelationNames().isEmpty(), m.getRelationNames(), columns, expressions, maxResults);
        }
        catch (Exception e)
        {
            log.error("Error while executing find by range, Caused by: ", e);
            throw new QueryHandlerException(e);
        }
        return result;
    }

    public List<EnhanceEntity> readFromIndexTable(EntityMetadata m, Client client,
            Map<Boolean, List<IndexClause>> indexClauseMap)
    {
        List<SearchResult> searchResults = new ArrayList<SearchResult>();
        List<Object> primaryKeys = new ArrayList<Object>();

        String columnFamilyName = m.getTableName() + Constants.INDEX_TABLE_SUFFIX;
        searchResults = ((CassandraClientBase) client).searchInInvertedIndex(columnFamilyName, m, indexClauseMap);

        Map<String, String> embeddedColumns = new HashMap<String, String>();
        for (SearchResult searchResult : searchResults)
        {
            if (searchResult.getEmbeddedColumnValues() != null)
            {
                for (String embeddedColVal : searchResult.getEmbeddedColumnValues())
                {
                    if (embeddedColVal != null)
                    {
                        StringBuilder strBuilder = new StringBuilder(embeddedColVal);
                        strBuilder.append("|");
                        strBuilder.append(searchResult.getPrimaryKey().toString());
                        embeddedColumns.put(strBuilder.toString(), searchResult.getPrimaryKey().toString());
                    }
                }
            }
        }
        List<EnhanceEntity> enhanceEntityList = new ArrayList<EnhanceEntity>();
        if (embeddedColumns != null && !embeddedColumns.isEmpty())
        {
            enhanceEntityList = client.find(m.getEntityClazz(), embeddedColumns);
        }
        else
        {
            for (SearchResult searchResult : searchResults)
            {
                primaryKeys.add(searchResult.getPrimaryKey());
            }
            enhanceEntityList = (List<EnhanceEntity>) ((CassandraClientBase) client).find(m.getEntityClazz(),
                    m.getRelationNames(), true, m, primaryKeys.toArray(new String[] {}));
        }

        return enhanceEntityList;
    }

    /**
     * Method to set indexcluase conditions.
     *
     * @param conditions
     *            index conditions.
     */
    public void setConditions(Map<Boolean, List<IndexClause>> conditions)
    {
        this.conditions = conditions;
    }

    /**
     * Returns list of row keys. First element will be min value and second will
     * be major value.
     *
     * @param expressions
     * @param primaryKeyName
     * @return
     */
    Map<String, byte[]> getRowKeyValue(List<IndexExpression> expressions, String primaryKeyName)
    {
        Map<String, byte[]> rowKeys = new HashMap<String, byte[]>();

        List<IndexExpression> rowExpressions = new ArrayList<IndexExpression>();

        if (expressions != null)
        {
            for (IndexExpression e : expressions)
            {
                if (primaryKeyName.equals(new String(e.getColumn_name())))
                {
                    IndexOperator operator = e.op;
                    if (operator.equals(IndexOperator.LTE) || operator.equals(IndexOperator.LT))
                    {
                        rowKeys.put(MAX_, e.getValue());
                        rowExpressions.add(e);
                    }
                    else if (operator.equals(IndexOperator.GTE) || operator.equals(IndexOperator.GT))
                    {
                        rowKeys.put(MIN_, e.getValue());
                        rowExpressions.add(e);
                    }
                    else if (operator.equals(IndexOperator.EQ))
                    {
                        rowKeys.put(MAX_, e.getValue());
                        rowKeys.put(MIN_, e.getValue());
                        rowExpressions.add(e);
                    }
                }
            }
            expressions.removeAll(rowExpressions);
        }
        return rowKeys;
    }
}
TOP

Related Classes of com.impetus.client.cassandra.query.CassandraEntityReader

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.